Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc

Issue 99933002: [NaCl SDK] nacl_io: implement getaddrinfo() (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
diff --git a/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc b/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
index 9d79e1c5a55502f7f07786048b7231c5bfea9b1f..c3dceb0d5cdf45e54d008f42b089f1af7e93c4f9 100644
--- a/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
+++ b/native_client_sdk/src/tests/nacl_io_test/host_resolver_test.cc
@@ -18,13 +18,56 @@ namespace {
class HostResolverTest : public ::testing::Test {
public:
- HostResolverTest() : pepper_(NULL) {}
+ HostResolverTest() {}
+
+ void SetUp() {
+ ki_init(NULL);
+ }
+
+ void TearDown() {
+ ki_uninit();
+ }
+};
+
+#define FAKE_HOSTNAME "example.com"
+#define FAKE_IP 0x01020304
+
+class FakeHostResolverTest : public ::testing::Test {
+ public:
+ FakeHostResolverTest() : pepper_(NULL), fake_resolver_(NULL) {}
void SetUp() {
pepper_ = new FakePepperInterface();
+ fake_resolver_ = static_cast<FakeHostResolverInterface*>(
+ pepper_->GetHostResolverInterface());
+
+ // Seed the fake resolver with some data
+ fake_resolver_->fake_hostname = FAKE_HOSTNAME;
+ AddFakeAddress(AF_INET);
+
ki_init_interface(NULL, pepper_);
}
+ void AddFakeAddress(int family) {
+ if (family == AF_INET) {
+ int address_count = fake_resolver_->fake_addresses_v4.size();
+ // Each new address we add is FAKE_IP incremented by 1
+ // each time to be unique.
+ sockaddr_in fake_addr;
+ fake_addr.sin_family = family;
+ fake_addr.sin_addr.s_addr = htonl(FAKE_IP + address_count);
+ fake_resolver_->fake_addresses_v4.push_back(fake_addr);
+ } else if (family == AF_INET6) {
+ sockaddr_in6 fake_addr;
+ fake_addr.sin6_family = family;
+ int address_count = fake_resolver_->fake_addresses_v6.size();
+ for (uint8_t i = 0; i < 16; i++) {
+ fake_addr.sin6_addr.s6_addr[i] = i + address_count;
+ }
+ fake_resolver_->fake_addresses_v6.push_back(fake_addr);
+ }
+ }
+
void TearDown() {
ki_uninit();
pepper_ = NULL;
@@ -32,13 +75,241 @@ class HostResolverTest : public ::testing::Test {
protected:
FakePepperInterface* pepper_;
+ FakeHostResolverInterface* fake_resolver_;
};
} // namespace
+#define NULL_INFO ((struct addrinfo*)NULL)
+#define NULL_ADDR ((struct sockaddr*)NULL)
#define NULL_HOST (static_cast<hostent*>(NULL))
-TEST_F(HostResolverTest, GethostbynameNumeric) {
+TEST_F(HostResolverTest, Getaddrinfo_Numeric) {
+ struct addrinfo* ai = NULL;
+ struct sockaddr_in* in;
+ struct addrinfo hints;
+
+ // Numberic only
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+
+ uint32_t expected_addr = htonl(0x01020304);
+ ASSERT_EQ(0, ki_getaddrinfo("1.2.3.4", NULL, &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ ASSERT_EQ(AF_INET, ai->ai_family);
+ ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
+ in = (struct sockaddr_in*)ai->ai_addr;
+ ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
+ ASSERT_EQ(NULL_INFO, ai->ai_next);
+
+ ki_freeaddrinfo(ai);
+}
+
+TEST_F(HostResolverTest, Getaddrinfo_MissingPPAPI) {
+ // Verify that full lookups fail due to lack of PPAPI interfaces
+ struct addrinfo* ai = NULL;
+ ASSERT_EQ(EAI_SYSTEM, ki_getaddrinfo("google.com", NULL, NULL, &ai));
+}
+
+TEST_F(HostResolverTest, Getaddrinfo_Passive) {
+ struct addrinfo* ai = NULL;
+ struct sockaddr_in* in;
+ struct sockaddr_in6* in6;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+
+ uint32_t expected_port = htons(22);
+ in_addr_t expected_addr = htonl(INADDR_ANY);
+ in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
+
+ // AI_PASSIVE means that the returned address will be a wildcard
+ // address suitable for binding and listening. This should not
+ // hit PPAPI at all, so we don't need fakes.
+ hints.ai_family = AF_INET;
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_DGRAM;
+ ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ ASSERT_EQ(NULL_INFO, ai->ai_next);
+ in = (struct sockaddr_in*)ai->ai_addr;
+ ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
+ ASSERT_EQ(expected_port, in->sin_port);
+ ASSERT_EQ(AF_INET, in->sin_family);
+ ki_freeaddrinfo(ai);
+
+ // Same test with AF_INET6
+ hints.ai_family = AF_INET6;
+ ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ ASSERT_EQ(NULL_INFO, ai->ai_next);
+ in6 = (struct sockaddr_in6*)ai->ai_addr;
+ ASSERT_EQ(expected_port, in6->sin6_port);
+ ASSERT_EQ(AF_INET6, in6->sin6_family);
+ ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
+ &expected_addr6,
+ sizeof(expected_addr6)));
+ ki_freeaddrinfo(ai);
+}
+
+TEST_F(HostResolverTest, Getaddrinfo_Passive_Any) {
+ // Similar to Getaddrinfo_Passive but don't set
+ // ai_family in the hints, so we should get muplitple
+ // results back for the different families.
+ struct addrinfo* ai = NULL;
+ struct sockaddr_in* in;
+ struct sockaddr_in6* in6;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+
+ uint32_t expected_port = htons(22);
+ in_addr_t expected_addr = htonl(INADDR_ANY);
+ in6_addr expected_addr6 = IN6ADDR_ANY_INIT;
+
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_socktype = SOCK_DGRAM;
+ ASSERT_EQ(0, ki_getaddrinfo(NULL, "22", &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+ int count = 0;
+ bool got_v4 = false;
+ bool got_v6 = false;
+ while (ai) {
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ switch (ai->ai_addr->sa_family) {
+ case AF_INET:
+ in = (struct sockaddr_in*)ai->ai_addr;
+ ASSERT_EQ(expected_port, in->sin_port);
+ ASSERT_EQ(AF_INET, in->sin_family);
+ ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
+ got_v4 = true;
+ break;
+ case AF_INET6:
+ in6 = (struct sockaddr_in6*)ai->ai_addr;
+ ASSERT_EQ(expected_port, in6->sin6_port);
+ ASSERT_EQ(AF_INET6, in6->sin6_family);
+ ASSERT_EQ(0, memcmp(in6->sin6_addr.s6_addr,
+ &expected_addr6,
+ sizeof(expected_addr6)));
+ got_v6 = true;
+ break;
+ default:
+ ASSERT_TRUE(false) << "Unknown address type: " << ai->ai_addr;
+ break;
+ }
+ ai = ai->ai_next;
+ count++;
+ }
+
+ ASSERT_EQ(2, count);
+ ASSERT_TRUE(got_v4);
+ ASSERT_TRUE(got_v6);
+}
+
+TEST_F(FakeHostResolverTest, Getaddrinfo_Lookup) {
+ struct addrinfo* ai = NULL;
+ struct sockaddr_in* in;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+
+ in_addr_t expected_addr = htonl(FAKE_IP);
+
+ // Lookup the fake hostname using getaddrinfo
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_STREAM;
+ ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ ASSERT_EQ(AF_INET, ai->ai_family);
+ ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
+ in = (struct sockaddr_in*)ai->ai_addr;
+ ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
+ ASSERT_EQ(NULL_INFO, ai->ai_next);
+
+ ki_freeaddrinfo(ai);
+}
+
+TEST_F(FakeHostResolverTest, Getaddrinfo_Multi) {
+ struct addrinfo* ai = NULL;
+ struct addrinfo hints;
+ memset(&hints, 0, sizeof(hints));
+
+ // Add four fake address on top of the initial one
+ // that the fixture creates.
+ AddFakeAddress(AF_INET);
+ AddFakeAddress(AF_INET);
+ AddFakeAddress(AF_INET6);
+ AddFakeAddress(AF_INET6);
+
+ hints.ai_socktype = SOCK_STREAM;
+
+ // First we test with AF_INET
+ hints.ai_family = AF_INET;
+ ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+
+ // We expect to be returned 3 AF_INET address with
+ // address FAKE_IP, FAKE_IP+1 and FAKE_IP+2, since that
+ // is that the fake was seeded with.
+ uint32_t expected_addr = htonl(FAKE_IP);
+ int count = 0;
+ struct addrinfo* current = ai;
+ while (current != NULL) {
+ ASSERT_NE(NULL_ADDR, current->ai_addr);
+ ASSERT_EQ(AF_INET, current->ai_family);
+ ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
+ sockaddr_in* in = (sockaddr_in*)current->ai_addr;
+ ASSERT_EQ(expected_addr, in->sin_addr.s_addr);
+ expected_addr += htonl(1);
+ current = current->ai_next;
+ count++;
+ }
+ ASSERT_EQ(3, count);
+ ki_freeaddrinfo(ai);
+
+ // Same test but with AF_INET6
+ hints.ai_family = AF_INET6;
+ ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+
+ count = 0;
+ current = ai;
+ while (current != NULL) {
+ ASSERT_NE(NULL_ADDR, current->ai_addr);
+ ASSERT_EQ(AF_INET6, current->ai_family);
+ ASSERT_EQ(SOCK_STREAM, current->ai_socktype);
+ sockaddr_in6* in = (sockaddr_in6*)current->ai_addr;
+ for (int i = 0; i < 16; i++) {
+ ASSERT_EQ(i + count, in->sin6_addr.s6_addr[i]);
+ }
+ current = current->ai_next;
+ count++;
+ }
+ ASSERT_EQ(2, count);
+ ki_freeaddrinfo(ai);
+
+ // Same test but with AF_UNSPEC. Here we expect to get
+ // 5 address back: 3 * v4 and 2 * v6.
+ hints.ai_family = AF_UNSPEC;
+ ASSERT_EQ(0, ki_getaddrinfo(FAKE_HOSTNAME, NULL, &hints, &ai));
+ ASSERT_NE(NULL_INFO, ai);
+
+ count = 0;
+ current = ai;
+ while (current != NULL) {
+ ASSERT_NE(NULL_ADDR, ai->ai_addr);
+ ASSERT_EQ(SOCK_STREAM, ai->ai_socktype);
+ current = current->ai_next;
+ count++;
+ }
+ ASSERT_EQ(5, count);
+
+ ki_freeaddrinfo(ai);
+}
+
+TEST_F(FakeHostResolverTest, Gethostbyname) {
hostent* host = ki_gethostbyname(FAKE_HOSTNAME);
// Verify the returned hostent structure
@@ -53,3 +324,40 @@ TEST_F(HostResolverTest, GethostbynameNumeric) {
in_addr_t exptected_addr = htonl(FAKE_IP);
ASSERT_EQ(exptected_addr, *addr_list[0]);
}
+
+TEST_F(FakeHostResolverTest, Gethostbyname_Failure) {
+ hostent* host = ki_gethostbyname("nosuchhost.com");
+ ASSERT_EQ(NULL_HOST, host);
+ ASSERT_EQ(HOST_NOT_FOUND, h_errno);
+}
+
+// Looking up purely numeric hostnames should work without PPAPI
+// so we don't need the fakes for this test
+TEST_F(HostResolverTest, Gethostbyname_Numeric) {
+ struct hostent* host = ki_gethostbyname("8.8.8.8");
+
+ // Verify the returned hostent structure
+ ASSERT_NE(NULL_HOST, host);
+ ASSERT_EQ(AF_INET, host->h_addrtype);
+ ASSERT_EQ(sizeof(in_addr_t), host->h_length);
+ ASSERT_STREQ("8.8.8.8", host->h_name);
+
+ in_addr_t** addr_list = reinterpret_cast<in_addr_t**>(host->h_addr_list);
+ ASSERT_NE(reinterpret_cast<in_addr_t**>(NULL), addr_list);
+ ASSERT_EQ(NULL, addr_list[1]);
+ ASSERT_EQ(inet_addr("8.8.8.8"), *addr_list[0]);
+}
+
+// These utility functions are only used for newlib (glibc provides its own
+// implementations of these functions).
+#if !defined(__GLIBC__)
+
+TEST(SocketUtilityFunctions, Hstrerror) {
+ EXPECT_STREQ("Unknown error in gethostbyname: 2718.", hstrerror(2718));
+}
+
+TEST(SocketUtilityFunctions, Gai_Strerror) {
+ EXPECT_STREQ("Unknown error in getaddrinfo: 2719.", gai_strerror(2719));
+}
+
+#endif // !defined(__GLIBC__)

Powered by Google App Engine
This is Rietveld 408576698