aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--test/core/end2end/dualstack_socket_test.c5
-rw-r--r--test/core/util/port.h10
-rw-r--r--test/core/util/port_posix.c26
-rw-r--r--test/core/util/port_windows.c26
-rw-r--r--test/cpp/end2end/async_end2end_test.cc6
5 files changed, 69 insertions, 4 deletions
diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c
index 81f76ea79c..202fb3b6a8 100644
--- a/test/core/end2end/dualstack_socket_test.c
+++ b/test/core/end2end/dualstack_socket_test.c
@@ -88,9 +88,11 @@ void test_connect(const char *server_host, const char *client_host, int port,
int was_cancelled = 2;
grpc_call_details call_details;
char *peer;
+ int picked_port = 0;
if (port == 0) {
port = grpc_pick_unused_port_or_die();
+ picked_port = 1;
}
gpr_join_host_port(&server_hostport, server_host, port);
@@ -263,6 +265,9 @@ void test_connect(const char *server_host, const char *client_host, int port,
grpc_call_details_destroy(&call_details);
gpr_free(details);
+ if (picked_port) {
+ grpc_recycle_unused_port(port);
+ }
}
int external_dns_works(const char *host) {
diff --git a/test/core/util/port.h b/test/core/util/port.h
index 93788bcab2..faeabbae9b 100644
--- a/test/core/util/port.h
+++ b/test/core/util/port.h
@@ -40,10 +40,16 @@ extern "C" {
/* pick a port number that is currently unused by either tcp or udp. return
0 on failure. */
-int grpc_pick_unused_port();
+int grpc_pick_unused_port(void);
/* pick a port number that is currently unused by either tcp or udp. abort
on failure. */
-int grpc_pick_unused_port_or_die();
+int grpc_pick_unused_port_or_die(void);
+
+/* Return a port which was previously returned by grpc_pick_unused_port().
+ * Implementations of grpc_pick_unused_port() backed by a portserver may limit
+ * the total number of ports available; this lets a binary return its allocated
+ * ports back to the server if it is going to allocate a large number. */
+void grpc_recycle_unused_port(int port);
#ifdef __cplusplus
}
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
index eabd62fafc..f13960156f 100644
--- a/test/core/util/port_posix.c
+++ b/test/core/util/port_posix.c
@@ -68,6 +68,30 @@ static int has_port_been_chosen(int port) {
return 0;
}
+static int free_chosen_port(int port) {
+ size_t i;
+ int found = 0;
+ size_t found_at = 0;
+ char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
+ /* Find the port and erase it from the list, then tell the server it can be
+ freed. */
+ for (i = 0; i < num_chosen_ports; i++) {
+ if (chosen_ports[i] == port) {
+ GPR_ASSERT(found == 0);
+ found = 1;
+ found_at = i;
+ }
+ }
+ if (found) {
+ chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
+ num_chosen_ports--;
+ if (env) {
+ grpc_free_port_using_server(env, port);
+ }
+ }
+ return found;
+}
+
static void free_chosen_ports(void) {
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
@@ -210,4 +234,6 @@ int grpc_pick_unused_port_or_die(void) {
return port;
}
+void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
+
#endif /* GPR_POSIX_SOCKET && GRPC_TEST_PICK_PORT */
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
index 154d607ec7..9023719675 100644
--- a/test/core/util/port_windows.c
+++ b/test/core/util/port_windows.c
@@ -71,6 +71,30 @@ static int has_port_been_chosen(int port) {
return 0;
}
+static int free_chosen_port(int port) {
+ size_t i;
+ int found = 0;
+ size_t found_at = 0;
+ char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
+ if (env != NULL) {
+ /* Find the port and erase it from the list, then tell the server it can be
+ freed. */
+ for (i = 0; i < num_chosen_ports; i++) {
+ if (chosen_ports[i] == port) {
+ GPR_ASSERT(found == 0);
+ found = 1;
+ found_at = i;
+ }
+ }
+ if (found) {
+ chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
+ grpc_free_port_using_server(env, port);
+ num_chosen_ports--;
+ }
+ }
+ return found;
+}
+
static void free_chosen_ports(void) {
char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
if (env != NULL) {
@@ -216,4 +240,6 @@ int grpc_pick_unused_port_or_die(void) {
return port;
}
+void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
+
#endif /* GPR_WINSOCK_SOCKET && GRPC_TEST_PICK_PORT */
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index e0649bd694..45f5eb1ddd 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -245,8 +245,8 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
void SetUp() GRPC_OVERRIDE {
poll_overrider_.reset(new PollingOverrider(!GetParam().disable_blocking));
- int port = grpc_pick_unused_port_or_die();
- server_address_ << "localhost:" << port;
+ port_ = grpc_pick_unused_port_or_die();
+ server_address_ << "localhost:" << port_;
// Setup server
ServerBuilder builder;
@@ -274,6 +274,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
;
poll_overrider_.reset();
gpr_tls_set(&g_is_async_end2end_test, 0);
+ grpc_recycle_unused_port(port_);
}
void ResetStub() {
@@ -325,6 +326,7 @@ class AsyncEnd2endTest : public ::testing::TestWithParam<TestScenario> {
std::unique_ptr<Server> server_;
grpc::testing::EchoTestService::AsyncService service_;
std::ostringstream server_address_;
+ int port_;
std::unique_ptr<PollingOverrider> poll_overrider_;
};