Skip to content

Commit

Permalink
SB16 POSIX socket test cases update
Browse files Browse the repository at this point in the history
Added POSIX Socket tests cover more IPv4 and IPv6 cases.
Converting port numbers from host byte order to network byte order.
And some special treatments for PS5:
  Added a wrapper layer in starboard/shared/moduler to take care of
  the sockaddr definition differences on certain platform.
  Use a different port number after each use.

b/330771976
  • Loading branch information
maxz-lab committed Apr 12, 2024
1 parent 7798507 commit 155b4a7
Show file tree
Hide file tree
Showing 18 changed files with 693 additions and 89 deletions.
10 changes: 10 additions & 0 deletions starboard/elf_loader/exported_symbols.cc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,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"
#endif // SB_API_VERSION >= 16
Expand Down Expand Up @@ -517,6 +518,15 @@ ExportedSymbols::ExportedSymbols() {
reinterpret_cast<const void*>(&__abi_wrap_pthread_self);
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_socket_accept);
map_["bind"] = reinterpret_cast<const void*>(&__abi_wrap_socket_bind);
map_["connect"] = reinterpret_cast<const void*>(&__abi_wrap_socket_connect);
map_["getaddrinfo"] =
reinterpret_cast<const void*>(&__abi_wrap_socket_getaddrinfo);
map_["getifaddrs"] =
reinterpret_cast<const void*>(&__abi_wrap_socket_getifaddrs);
map_["setsockopt"] =
reinterpret_cast<const void*>(&__abi_wrap_socket_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 "starboard/nplb/posix_compliance/posix_socket_helpers.h"

namespace starboard {
Expand All @@ -32,6 +33,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 @@ -43,16 +47,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 @@ -124,11 +131,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
196 changes: 177 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,176 @@ 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

// This is to use NULL in asserts, which otherwise complain about long
// vs. pointer type.
const void* kNull = NULL;

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 155b4a7

Please sign in to comment.