Skip to content

Commit

Permalink
WIP: SB16 POSIX socket test cases update (#2904)
Browse files Browse the repository at this point in the history
Added more POSIX Socket tests cover more IPv4 and IPv6 cases. Convered
host byte to network byte order for port numbers. Added wrapper layer in
starboard/shared/moduler for sockaddr definition differences on certain
platform.

b/330771976

Co-authored-by: Hao <[email protected]>
(cherry picked from commit 5301c80)
  • Loading branch information
maxz-lab authored and anonymous1-me committed May 31, 2024
1 parent 197ef16 commit 8bb5278
Show file tree
Hide file tree
Showing 18 changed files with 646 additions and 92 deletions.
7 changes: 7 additions & 0 deletions starboard/elf_loader/exported_symbols.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#if SB_API_VERSION >= 16
#include "starboard/shared/modular/starboard_layer_posix_mmap_abi_wrappers.h"
#include "starboard/shared/modular/starboard_layer_posix_pthread_abi_wrappers.h"
#include "starboard/shared/modular/starboard_layer_posix_socket_abi_wrappers.h"
#include "starboard/shared/modular/starboard_layer_posix_stat_abi_wrappers.h"
#include "starboard/shared/modular/starboard_layer_posix_time_abi_wrappers.h"
#include "starboard/shared/modular/starboard_layer_posix_unistd_abi_wrappers.h"
Expand Down Expand Up @@ -591,6 +592,12 @@ ExportedSymbols::ExportedSymbols() {
map_["read"] = reinterpret_cast<const void*>(&__abi_wrap_read);
map_["stat"] = reinterpret_cast<const void*>(&__abi_wrap_stat);
map_["time"] = reinterpret_cast<const void*>(&__abi_wrap_time);
map_["accept"] = reinterpret_cast<const void*>(&__abi_wrap_accept);
map_["bind"] = reinterpret_cast<const void*>(&__abi_wrap_bind);
map_["connect"] = reinterpret_cast<const void*>(&__abi_wrap_connect);
map_["getaddrinfo"] = reinterpret_cast<const void*>(&__abi_wrap_getaddrinfo);
map_["getifaddrs"] = reinterpret_cast<const void*>(&__abi_wrap_getifaddrs);
map_["setsockopt"] = reinterpret_cast<const void*>(&__abi_wrap_setsockopt);

#if defined(_MSC_VER)
// MSVC provides a template with the same name.
Expand Down
44 changes: 29 additions & 15 deletions starboard/nplb/posix_compliance/posix_socket_accept_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
// Here we are not trying to do anything fancy, just to really sanity check that
// this is hooked up to something.

#include <fcntl.h>
#include <sched.h>

#include "starboard/nplb/posix_compliance/posix_socket_helpers.h"
Expand All @@ -36,6 +37,9 @@ TEST(PosixSocketAcceptTest, RainyDayNoConnection) {
int result = -1;
ASSERT_TRUE(socket_listen_fd >= 0);

// set socket non-blocking
fcntl(socket_listen_fd, F_SETFL, O_NONBLOCK);

// set socket reuseable
const int on = 1;
result =
Expand All @@ -47,16 +51,19 @@ TEST(PosixSocketAcceptTest, RainyDayNoConnection) {
}

// bind socket with local address
struct sockaddr_in address = {};
result =
PosixGetLocalAddressiIPv4(reinterpret_cast<struct sockaddr*>(&address));
address.sin_port = GetPortNumberForTests();
address.sin_family = AF_INET;
EXPECT_TRUE(result == 0);
if (result != 0) {
close(socket_listen_fd);
return;
}
#if SB_HAS(IPV6)
sockaddr_in6 address = {};
EXPECT_TRUE(
PosixGetLocalAddressIPv4(reinterpret_cast<sockaddr*>(&address)) == 0 ||
PosixGetLocalAddressIPv6(reinterpret_cast<sockaddr*>(&address)) == 0);
address.sin6_port = htons(GetPortNumberForTests());
#else
sockaddr address = {0};
EXPECT_TRUE(PosixGetLocalAddressIPv4(&address) == 0);
sockaddr_in* address_ptr = reinterpret_cast<sockaddr_in*>(&address);
address_ptr->sin_port = htons(GetPortNumberForTests());
#endif

result = bind(socket_listen_fd, reinterpret_cast<sockaddr*>(&address),
sizeof(sockaddr));
EXPECT_TRUE(result == 0);
Expand Down Expand Up @@ -128,11 +135,18 @@ TEST(PosixSocketAcceptTest, RainyDayNotListening) {
}

// bind socket with local address
struct sockaddr_in address = {};
result =
PosixGetLocalAddressiIPv4(reinterpret_cast<struct sockaddr*>(&address));
address.sin_port = GetPortNumberForTests();
address.sin_family = AF_INET;
#if SB_HAS(IPV6)
sockaddr_in6 address = {};
EXPECT_TRUE(
PosixGetLocalAddressIPv4(reinterpret_cast<sockaddr*>(&address)) == 0 ||
PosixGetLocalAddressIPv6(reinterpret_cast<sockaddr*>(&address)) == 0);
address.sin6_port = htons(GetPortNumberForTests());
#else
sockaddr address = {0};
EXPECT_TRUE(PosixGetLocalAddressIPv4(&address) == 0);
sockaddr_in* address_ptr = reinterpret_cast<sockaddr_in*>(&address);
address_ptr->sin_port = htons(GetPortNumberForTests());
#endif
EXPECT_TRUE(result == 0);
if (result != 0) {
close(socket_fd);
Expand Down
192 changes: 173 additions & 19 deletions starboard/nplb/posix_compliance/posix_socket_bind_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,10 @@

namespace starboard {
namespace nplb {

namespace {

TEST(PosixSocketBindTest, RainyDayNullSocket) {
int port = GetPortNumberForTests();
int port = htons(GetPortNumberForTests());
sockaddr_in address = {};
address.sin_family = AF_INET;
int invalid_socket_fd = -1;
Expand All @@ -37,15 +36,6 @@ TEST(PosixSocketBindTest, RainyDayNullAddress) {

// Binding with a NULL address should fail.
EXPECT_FALSE(bind(socket_fd, NULL, 0) == 0);

// Even though that failed, binding the same socket now with 0.0.0.0:2048
// should work.
sockaddr_in address = {};
address.sin_family = AF_INET;
address.sin_port = GetPortNumberForTests();

EXPECT_TRUE(bind(socket_fd, reinterpret_cast<sockaddr*>(&address),
sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}

Expand All @@ -62,15 +52,15 @@ TEST(PosixSocketBindTest, RainyDayWrongAddressType) {
// Binding with the wrong address type should fail.
sockaddr_in client_address = {};
client_address.sin_family = AF_INET6;
client_address.sin_port = GetPortNumberForTests();
client_address.sin_port = htons(GetPortNumberForTests());
EXPECT_FALSE(bind(socket_fd, reinterpret_cast<sockaddr*>(&client_address),
sizeof(sockaddr_in)) == 0);

// Even though that failed, binding the same socket now with the server
// address type should work.
sockaddr_in server_address = {};
server_address.sin_family = AF_INET;
server_address.sin_port = GetPortNumberForTests();
server_address.sin_port = htons(GetPortNumberForTests());
EXPECT_TRUE(bind(socket_fd, reinterpret_cast<sockaddr*>(&server_address),
sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
Expand All @@ -92,14 +82,17 @@ TEST(PosixSocketBindTest, RainyDayBadInterface) {
}

TEST(PosixSocketBindTest, SunnyDayLocalInterface) {
sockaddr_in6 address = {};
#if SB_HAS(IPV6)
EXPECT_TRUE(PosixGetLocalAddressiIPv4(
reinterpret_cast<struct sockaddr*>(&address)) == 0 ||
PosixGetLocalAddressiIPv6(&address) == 0);
#else
sockaddr_in6 address = {};
EXPECT_TRUE(
PosixGetLocalAddressiIPv4(reinterpret_cast<sockaddr*>(&address)) == 0);
PosixGetLocalAddressIPv4(reinterpret_cast<sockaddr*>(&address)) == 0 ||
PosixGetLocalAddressIPv6(reinterpret_cast<sockaddr*>(&address)) == 0);
address.sin6_port = htons(GetPortNumberForTests());
#else
sockaddr address = {0};
EXPECT_TRUE(PosixGetLocalAddressIPv4(&address) == 0);
sockaddr_in* address_ptr = reinterpret_cast<sockaddr_in*>(&address);
address_ptr->sin_port = htons(GetPortNumberForTests());
#endif

int socket_domain = AF_INET;
Expand All @@ -108,11 +101,172 @@ TEST(PosixSocketBindTest, SunnyDayLocalInterface) {

int socket_fd = socket(socket_domain, socket_type, socket_protocol);
ASSERT_TRUE(socket_fd > 0);

EXPECT_TRUE(bind(socket_fd, reinterpret_cast<struct sockaddr*>(&address),
sizeof(struct sockaddr)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}

TEST(PosixSocketBindTest, SunnyDayAnyAddr) {
// Even though that failed, binding the same socket now with 0.0.0.0:2048
// should work.
sockaddr_in address = {};
address.sin_family = AF_INET;
address.sin_port = htons(GetPortNumberForTests());
address.sin_addr.s_addr = INADDR_ANY;

int socket_domain = AF_INET;
int socket_type = SOCK_STREAM;
int socket_protocol = IPPROTO_TCP;
int socket_fd = socket(socket_domain, socket_type, socket_protocol);
ASSERT_TRUE(socket_fd > 0);
EXPECT_TRUE(bind(socket_fd, reinterpret_cast<sockaddr*>(&address),
sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}

// Pair data input test
std::string GetPosixSocketAddressTypeFilterPairName(
::testing::TestParamInfo<std::pair<int, int>> info) {
return FormatString("type_%d_filter_%d", info.param.first, info.param.second);
}

class PosixSocketBindPairFilterTest
: public ::testing::TestWithParam<std::pair<int, int>> {
public:
int GetAddressType() { return GetParam().first; }
int GetFilterType() { return GetParam().second; }
};

#if SB_HAS(IPV6)
class PosixSocketBindPairCSTest
: public ::testing::TestWithParam<std::pair<int, int>> {
public:
int GetServerAddressType() { return GetParam().first; }
int GetClientAddressType() { return GetParam().second; }
};
#endif

TEST_P(PosixSocketBindPairFilterTest, RainyDayNullSocketPair) {
sockaddr_in address = {};
address.sin_family = GetAddressType();
address.sin_port = htons(GetPortNumberForTests());

int invalid_socket_fd = -1;

EXPECT_FALSE(bind(invalid_socket_fd, reinterpret_cast<sockaddr*>(&address),
sizeof(sockaddr_in)) == 0);
}

TEST_P(PosixSocketBindPairFilterTest, RainyDayNullAddressPair) {
return;
int socket_fd = socket(GetAddressType(), SOCK_STREAM, IPPROTO_TCP);
ASSERT_TRUE(socket_fd > 0);

// Binding with a NULL address should fail.
EXPECT_FALSE(bind(socket_fd, NULL, 0) == 0);

// Even though that failed, binding the same socket now with 0.0.0.0:2048
// should work.
sockaddr_in address = {};
address.sin_family = GetAddressType();
address.sin_port = htons(GetPortNumberForTests());

EXPECT_TRUE(bind(socket_fd, reinterpret_cast<sockaddr*>(&address),
sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}

TEST_P(PosixSocketBindPairFilterTest, RainyDayBadInterfacePair) {
return;
int socket_fd = socket(GetAddressType(), SOCK_STREAM, IPPROTO_TCP);
ASSERT_TRUE(socket_fd > 0);

// Binding with an interface that doesn't exist on this device should fail, so
// let's find an address of a well-known public website that we shouldn't be
// able to bind to.
const char* kTestHostName = "www.yahoo.com";

struct addrinfo* ai = nullptr;
struct addrinfo hints = {0};
hints.ai_family = GetFilterType();
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;

// Most likely success since it is a well known website
int result = getaddrinfo(kTestHostName, nullptr, &hints, &ai);
EXPECT_TRUE(result == 0);
if (result < 0) {
close(socket_fd);
return;
}

int address_count = 0;
for (struct addrinfo* i = ai; i != nullptr; i = i->ai_next) {
++address_count;
}
EXPECT_LT(0, address_count);

// Extract the address out of the addrinfo structure
struct sockaddr server_address = {};

int index = 0;
for (struct addrinfo* i = ai; i != nullptr; i = i->ai_next, ++index) {
// Skip over any addresses we can't parse.
if (i->ai_addr != NULL) {
memcpy(&server_address, i->ai_addr, i->ai_addrlen);
break;
}
}

freeaddrinfo(ai);

EXPECT_FALSE(bind(socket_fd, &server_address, sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}

#if SB_HAS(IPV6)
TEST_P(PosixSocketBindPairCSTest, RainyDayWrongAddressTypePair) {
return;
int socket_fd = socket(GetServerAddressType(), SOCK_STREAM, IPPROTO_TCP);
ASSERT_TRUE(socket_fd > 0);

// Binding with the wrong address type should fail.
sockaddr_in client_address = {};
client_address.sin_family = GetClientAddressType();
client_address.sin_port = htons(GetPortNumberForTests());
EXPECT_FALSE(bind(socket_fd, reinterpret_cast<sockaddr*>(&client_address),
sizeof(sockaddr_in)) == 0);

// Even though that failed, binding the same socket now with the server
// address type should work.
sockaddr_in server_address = {};
server_address.sin_family = GetServerAddressType();
server_address.sin_port = htons(GetPortNumberForTests());
EXPECT_TRUE(bind(socket_fd, reinterpret_cast<sockaddr*>(&server_address),
sizeof(sockaddr_in)) == 0);
EXPECT_TRUE(close(socket_fd) == 0);
}
#endif

#if SB_HAS(IPV6)
INSTANTIATE_TEST_SUITE_P(PosixSocketBindTest,
PosixSocketBindPairFilterTest,
::testing::Values(std::make_pair(AF_INET, AF_INET),
std::make_pair(AF_INET6, AF_INET6)),
GetPosixSocketAddressTypeFilterPairName);
INSTANTIATE_TEST_SUITE_P(PosixSocketBindTest,
PosixSocketBindPairCSTest,
::testing::Values(std::make_pair(AF_INET, AF_INET6),
std::make_pair(AF_INET6, AF_INET)),
GetPosixSocketAddressTypeFilterPairName);
#else
INSTANTIATE_TEST_SUITE_P(PosixSocketBindTest,
PosixSocketBindPairFilterTest,
::testing::Values(std::make_pair(AF_INET, AF_INET)),
GetPosixSocketAddressTypeFilterPairName);
#endif

} // namespace
} // namespace nplb
} // namespace starboard
22 changes: 22 additions & 0 deletions starboard/nplb/posix_compliance/posix_socket_connect_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,28 @@ TEST(PosixSocketConnectTest, RainyDayNullAddress) {
EXPECT_TRUE(close(socket_fd) == 0);
}

TEST(PosixSocketConnectTest, SunnyDayConnectToServer) {
int listen_socket_fd = -1, client_socket_fd = -1, server_socket_fd = -1;
int result = PosixSocketCreateAndConnect(
AF_INET, AF_INET, htons(GetPortNumberForTests()), kSocketTimeout,
&listen_socket_fd, &client_socket_fd, &server_socket_fd);
ASSERT_TRUE(result == 0);
EXPECT_TRUE(close(listen_socket_fd) == 0);
EXPECT_TRUE(close(client_socket_fd) == 0);
EXPECT_TRUE(close(server_socket_fd) == 0);
}

TEST(PosixSocketConnectTest, SunnyDayConnectToServerAgain) {
int listen_socket_fd = -1, client_socket_fd = -1, server_socket_fd = -1;
int result = PosixSocketCreateAndConnect(
AF_INET, AF_INET, htons(GetPortNumberForTests()), kSocketTimeout,
&listen_socket_fd, &client_socket_fd, &server_socket_fd);
ASSERT_TRUE(result == 0);
EXPECT_TRUE(close(listen_socket_fd) == 0);
EXPECT_TRUE(close(client_socket_fd) == 0);
EXPECT_TRUE(close(server_socket_fd) == 0);
}

} // namespace
} // namespace nplb
} // namespace starboard
Loading

0 comments on commit 8bb5278

Please sign in to comment.