Merge github.com:grpc/grpc into always-use-port-server
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 82cf852..efa7973 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1446,10 +1446,8 @@
test/core/util/mock_endpoint.c
test/core/util/parse_hexstring.c
test/core/util/passthru_endpoint.c
- test/core/util/port_posix.c
+ test/core/util/port.c
test/core/util/port_server_client.c
- test/core/util/port_uv.c
- test/core/util/port_windows.c
test/core/util/slice_splitter.c
test/core/util/trickle_endpoint.c
src/core/lib/channel/channel_args.c
@@ -1655,10 +1653,8 @@
test/core/util/mock_endpoint.c
test/core/util/parse_hexstring.c
test/core/util/passthru_endpoint.c
- test/core/util/port_posix.c
+ test/core/util/port.c
test/core/util/port_server_client.c
- test/core/util/port_uv.c
- test/core/util/port_windows.c
test/core/util/slice_splitter.c
test/core/util/trickle_endpoint.c
)
diff --git a/Makefile b/Makefile
index 153d534..98285ca 100644
--- a/Makefile
+++ b/Makefile
@@ -3315,10 +3315,8 @@
test/core/util/mock_endpoint.c \
test/core/util/parse_hexstring.c \
test/core/util/passthru_endpoint.c \
- test/core/util/port_posix.c \
+ test/core/util/port.c \
test/core/util/port_server_client.c \
- test/core/util/port_uv.c \
- test/core/util/port_windows.c \
test/core/util/slice_splitter.c \
test/core/util/trickle_endpoint.c \
src/core/lib/channel/channel_args.c \
@@ -3517,10 +3515,8 @@
test/core/util/mock_endpoint.c \
test/core/util/parse_hexstring.c \
test/core/util/passthru_endpoint.c \
- test/core/util/port_posix.c \
+ test/core/util/port.c \
test/core/util/port_server_client.c \
- test/core/util/port_uv.c \
- test/core/util/port_windows.c \
test/core/util/slice_splitter.c \
test/core/util/trickle_endpoint.c \
diff --git a/build.yaml b/build.yaml
index 09d5824..dc4d095 100644
--- a/build.yaml
+++ b/build.yaml
@@ -610,10 +610,8 @@
- test/core/util/mock_endpoint.c
- test/core/util/parse_hexstring.c
- test/core/util/passthru_endpoint.c
- - test/core/util/port_posix.c
+ - test/core/util/port.c
- test/core/util/port_server_client.c
- - test/core/util/port_uv.c
- - test/core/util/port_windows.c
- test/core/util/slice_splitter.c
- test/core/util/trickle_endpoint.c
deps:
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index 5c90f1d..e6d0d24 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -51,9 +51,8 @@
"mock_endpoint.c",
"parse_hexstring.c",
"passthru_endpoint.c",
- "port_posix.c",
+ "port.c",
"port_server_client.c",
- "port_windows.c",
"reconnect_server.c",
"slice_splitter.c",
"test_tcp_server.c",
diff --git a/test/core/util/port_uv.c b/test/core/util/port.c
similarity index 78%
rename from test/core/util/port_uv.c
rename to test/core/util/port.c
index 0c9c0d8..da1ed4e 100644
--- a/test/core/util/port_uv.c
+++ b/test/core/util/port.c
@@ -33,17 +33,24 @@
#include "src/core/lib/iomgr/port.h"
#include "test/core/util/test_config.h"
-#if defined(GRPC_UV) && defined(GRPC_TEST_PICK_PORT)
+#if defined(GRPC_TEST_PICK_PORT)
+#include "test/core/util/port.h"
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
-#include "src/core/lib/support/env.h"
-#include "test/core/util/port.h"
+#include "src/core/lib/http/httpcli.h"
+#include "src/core/lib/iomgr/resolve_address.h"
+#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "test/core/util/port_server_client.h"
-// Almost everything in this file has been copied from port_posix.c
-
static int *chosen_ports = NULL;
static size_t num_chosen_ports = 0;
@@ -51,7 +58,6 @@
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++) {
@@ -64,24 +70,16 @@
if (found) {
chosen_ports[found_at] = chosen_ports[num_chosen_ports - 1];
num_chosen_ports--;
- if (env) {
- grpc_free_port_using_server(env, port);
- }
+ grpc_free_port_using_server(port);
}
- gpr_free(env);
return found;
}
static void free_chosen_ports(void) {
- char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
- if (env != NULL) {
- size_t i;
- for (i = 0; i < num_chosen_ports; i++) {
- grpc_free_port_using_server(env, chosen_ports[i]);
- }
- gpr_free(env);
+ size_t i;
+ for (i = 0; i < num_chosen_ports; i++) {
+ grpc_free_port_using_server(chosen_ports[i]);
}
-
gpr_free(chosen_ports);
}
@@ -95,23 +93,27 @@
}
int grpc_pick_unused_port(void) {
- // Currently only works with the port server
- char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
- GPR_ASSERT(env);
- int port = grpc_pick_port_using_server(env);
- gpr_free(env);
+ int port = grpc_pick_port_using_server();
if (port != 0) {
chose_port(port);
}
+
return port;
}
int grpc_pick_unused_port_or_die(void) {
int port = grpc_pick_unused_port();
- GPR_ASSERT(port > 0);
+ if (port == 0) {
+ fprintf(stderr,
+ "gRPC tests require a helper port server to allocate ports used \n"
+ "during the test.\n\n"
+ "This server is not currently running.\n\n"
+ "To start it, run tools/run_tests/start_port_server.py\n\n");
+ exit(1);
+ }
return port;
}
void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
-#endif /* GRPC_UV && GRPC_TEST_PICK_PORT */
+#endif /* GRPC_TEST_PICK_PORT */
diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c
deleted file mode 100644
index 4a42e4c..0000000
--- a/test/core/util/port_posix.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/iomgr/port.h"
-#include "test/core/util/test_config.h"
-#if defined(GRPC_POSIX_SOCKET) && defined(GRPC_TEST_PICK_PORT)
-
-#include "test/core/util/port.h"
-
-#include <errno.h>
-#include <netinet/in.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-#include <grpc/support/string_util.h>
-
-#include "src/core/lib/http/httpcli.h"
-#include "src/core/lib/iomgr/resolve_address.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/env.h"
-#include "test/core/util/port_server_client.h"
-
-#define NUM_RANDOM_PORTS_TO_PICK 100
-
-static int *chosen_ports = NULL;
-static size_t num_chosen_ports = 0;
-
-static int has_port_been_chosen(int port) {
- size_t i;
- for (i = 0; i < num_chosen_ports; i++) {
- if (chosen_ports[i] == port) {
- return 1;
- }
- }
- 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);
- }
- }
- gpr_free(env);
- return found;
-}
-
-static void free_chosen_ports(void) {
- char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
- if (env != NULL) {
- size_t i;
- for (i = 0; i < num_chosen_ports; i++) {
- grpc_free_port_using_server(env, chosen_ports[i]);
- }
- gpr_free(env);
- }
-
- gpr_free(chosen_ports);
-}
-
-static void chose_port(int port) {
- if (chosen_ports == NULL) {
- atexit(free_chosen_ports);
- }
- num_chosen_ports++;
- chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports);
- chosen_ports[num_chosen_ports - 1] = port;
-}
-
-static bool is_port_available(int *port, bool is_tcp) {
- GPR_ASSERT(*port >= 0);
- GPR_ASSERT(*port <= 65535);
-
- /* For a port to be considered available, the kernel must support
- at least one of (IPv6, IPv4), and the port must be available
- on each supported family. */
- bool got_socket = false;
- for (int is_ipv6 = 1; is_ipv6 >= 0; is_ipv6--) {
- const int fd =
- socket(is_ipv6 ? AF_INET6 : AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM,
- is_tcp ? IPPROTO_TCP : 0);
- if (fd >= 0) {
- got_socket = true;
- } else {
- continue;
- }
-
- /* Reuseaddr lets us start up a server immediately after it exits */
- const int one = 1;
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) < 0) {
- gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
- close(fd);
- return false;
- }
-
- /* Try binding to port */
- grpc_resolved_address addr;
- if (is_ipv6) {
- grpc_sockaddr_make_wildcard6(*port, &addr); /* [::]:port */
- } else {
- grpc_sockaddr_make_wildcard4(*port, &addr); /* 0.0.0.0:port */
- }
- if (bind(fd, (struct sockaddr *)addr.addr, (socklen_t)addr.len) < 0) {
- gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
- close(fd);
- return false;
- }
-
- /* Get the bound port number */
- if (getsockname(fd, (struct sockaddr *)addr.addr, (socklen_t *)&addr.len) <
- 0) {
- gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
- close(fd);
- return false;
- }
- GPR_ASSERT(addr.len <= sizeof(addr.addr));
- const int actual_port = grpc_sockaddr_get_port(&addr);
- GPR_ASSERT(actual_port > 0);
- if (*port == 0) {
- *port = actual_port;
- } else {
- GPR_ASSERT(*port == actual_port);
- }
-
- close(fd);
- }
- if (!got_socket) {
- gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
- return false;
- }
- return true;
-}
-
-int grpc_pick_unused_port(void) {
- /* We repeatedly pick a port and then see whether or not it is
- available for use both as a TCP socket and a UDP socket. First, we
- pick a random large port number. For subsequent
- iterations, we bind to an anonymous port and let the OS pick the
- port number. The random port picking reduces the probability of
- races with other processes on kernels that want to reuse the same
- port numbers over and over. */
-
- /* In alternating iterations we trial UDP ports before TCP ports UDP
- ports -- it could be the case that this machine has been using up
- UDP ports and they are scarcer. */
-
- /* Type of port to first pick in next iteration */
- bool is_tcp = true;
- int trial = 0;
-
- char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
- if (env) {
- int port = grpc_pick_port_using_server(env);
- gpr_free(env);
- if (port != 0) {
- chose_port(port);
- }
- return port;
- }
-
- for (;;) {
- int port;
- trial++;
- if (trial == 1) {
- port = getpid() % (65536 - 30000) + 30000;
- } else if (trial <= NUM_RANDOM_PORTS_TO_PICK) {
- port = rand() % (65536 - 30000) + 30000;
- } else {
- port = 0;
- }
-
- if (has_port_been_chosen(port)) {
- continue;
- }
-
- if (!is_port_available(&port, is_tcp)) {
- continue;
- }
-
- GPR_ASSERT(port > 0);
- /* Check that the port # is free for the other type of socket also */
- if (!is_port_available(&port, !is_tcp)) {
- /* In the next iteration trial to bind to the other type first
- because perhaps it is more rare. */
- is_tcp = !is_tcp;
- continue;
- }
-
- chose_port(port);
- return port;
- }
-
- /* The port iterator reached the end without finding a suitable port. */
- return 0;
-}
-
-int grpc_pick_unused_port_or_die(void) {
- int port = grpc_pick_unused_port();
- GPR_ASSERT(port > 0);
- return port;
-}
-
-void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
-
-#endif /* GRPC_POSIX_SOCKET && GRPC_TEST_PICK_PORT */
diff --git a/test/core/util/port_server_client.c b/test/core/util/port_server_client.c
index f7d723a..a851d01 100644
--- a/test/core/util/port_server_client.c
+++ b/test/core/util/port_server_client.c
@@ -74,7 +74,7 @@
gpr_mu_unlock(pr->mu);
}
-void grpc_free_port_using_server(char *server, int port) {
+void grpc_free_port_using_server(int port) {
grpc_httpcli_context context;
grpc_httpcli_request req;
grpc_httpcli_response rsp;
@@ -95,7 +95,7 @@
shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
grpc_schedule_on_exec_ctx);
- req.host = server;
+ req.host = GRPC_PORT_SERVER_ADDRESS;
gpr_asprintf(&path, "/drop/%d", port);
req.http.path = path;
@@ -198,7 +198,7 @@
gpr_mu_unlock(pr->mu);
}
-int grpc_pick_port_using_server(char *server) {
+int grpc_pick_port_using_server(void) {
grpc_httpcli_context context;
grpc_httpcli_request req;
portreq pr;
@@ -215,10 +215,10 @@
shutdown_closure = grpc_closure_create(destroy_pops_and_shutdown, &pr.pops,
grpc_schedule_on_exec_ctx);
pr.port = -1;
- pr.server = server;
+ pr.server = GRPC_PORT_SERVER_ADDRESS;
pr.ctx = &context;
- req.host = server;
+ req.host = GRPC_PORT_SERVER_ADDRESS;
req.http.path = "/get";
grpc_httpcli_context_init(&context);
diff --git a/test/core/util/port_server_client.h b/test/core/util/port_server_client.h
index 4370064..70471ec 100644
--- a/test/core/util/port_server_client.h
+++ b/test/core/util/port_server_client.h
@@ -36,7 +36,10 @@
// C interface to port_server.py
-int grpc_pick_port_using_server(char *server);
-void grpc_free_port_using_server(char *server, int port);
+// must be synchronized with tools/run_tests/python_utils/start_port_server.py
+#define GRPC_PORT_SERVER_ADDRESS "localhost:32766"
+
+int grpc_pick_port_using_server(void);
+void grpc_free_port_using_server(int port);
#endif // GRPC_TEST_CORE_UTIL_PORT_SERVER_CLIENT_H
diff --git a/test/core/util/port_windows.c b/test/core/util/port_windows.c
deleted file mode 100644
index 0c50a46..0000000
--- a/test/core/util/port_windows.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
- *
- * Copyright 2015, Google Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include "src/core/lib/iomgr/port.h"
-#include "test/core/util/test_config.h"
-#if defined(GRPC_WINSOCK_SOCKET) && defined(GRPC_TEST_PICK_PORT)
-
-#include "src/core/lib/iomgr/sockaddr.h"
-
-#include "test/core/util/port.h"
-
-#include <errno.h>
-#include <process.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <grpc/grpc.h>
-#include <grpc/support/alloc.h>
-#include <grpc/support/log.h>
-
-#include "src/core/lib/http/httpcli.h"
-#include "src/core/lib/iomgr/sockaddr_utils.h"
-#include "src/core/lib/support/env.h"
-#include "test/core/util/port_server_client.h"
-
-#if GPR_GETPID_IN_UNISTD_H
-#include <sys/unistd.h>
-static int _getpid() { return getpid(); }
-#endif
-
-#define NUM_RANDOM_PORTS_TO_PICK 100
-
-static int *chosen_ports = NULL;
-static size_t num_chosen_ports = 0;
-
-static int has_port_been_chosen(int port) {
- size_t i;
- for (i = 0; i < num_chosen_ports; i++) {
- if (chosen_ports[i] == port) {
- return 1;
- }
- }
- 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) {
- size_t i;
- for (i = 0; i < num_chosen_ports; i++) {
- grpc_free_port_using_server(env, chosen_ports[i]);
- }
- gpr_free(env);
- }
-
- gpr_free(chosen_ports);
-}
-
-static void chose_port(int port) {
- if (chosen_ports == NULL) {
- atexit(free_chosen_ports);
- }
- num_chosen_ports++;
- chosen_ports = gpr_realloc(chosen_ports, sizeof(int) * num_chosen_ports);
- chosen_ports[num_chosen_ports - 1] = port;
-}
-
-static int is_port_available(int *port, int is_tcp) {
- const int proto = is_tcp ? IPPROTO_TCP : 0;
- const SOCKET fd = socket(AF_INET, is_tcp ? SOCK_STREAM : SOCK_DGRAM, proto);
- int one = 1;
- struct sockaddr_in addr;
- socklen_t alen = sizeof(addr);
- int actual_port;
-
- GPR_ASSERT(*port >= 0);
- GPR_ASSERT(*port <= 65535);
- if (INVALID_SOCKET == fd) {
- gpr_log(GPR_ERROR, "socket() failed: %s", strerror(errno));
- return 0;
- }
-
- /* Reuseaddr lets us start up a server immediately after it exits */
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char *)&one,
- sizeof(one)) < 0) {
- gpr_log(GPR_ERROR, "setsockopt() failed: %s", strerror(errno));
- closesocket(fd);
- return 0;
- }
-
- /* Try binding to port */
- addr.sin_family = AF_INET;
- addr.sin_addr.s_addr = INADDR_ANY;
- addr.sin_port = htons((u_short)*port);
- if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
- gpr_log(GPR_DEBUG, "bind(port=%d) failed: %s", *port, strerror(errno));
- closesocket(fd);
- return 0;
- }
-
- /* Get the bound port number */
- if (getsockname(fd, (struct sockaddr *)&addr, &alen) < 0) {
- gpr_log(GPR_ERROR, "getsockname() failed: %s", strerror(errno));
- closesocket(fd);
- return 0;
- }
- GPR_ASSERT(alen <= (socklen_t)sizeof(addr));
- actual_port = ntohs(addr.sin_port);
- GPR_ASSERT(actual_port > 0);
- if (*port == 0) {
- *port = actual_port;
- } else {
- GPR_ASSERT(*port == actual_port);
- }
-
- closesocket(fd);
- return 1;
-}
-
-int grpc_pick_unused_port(void) {
- /* We repeatedly pick a port and then see whether or not it is
- available for use both as a TCP socket and a UDP socket. First, we
- pick a random large port number. For subsequent
- iterations, we bind to an anonymous port and let the OS pick the
- port number. The random port picking reduces the probability of
- races with other processes on kernels that want to reuse the same
- port numbers over and over. */
-
- /* In alternating iterations we trial UDP ports before TCP ports UDP
- ports -- it could be the case that this machine has been using up
- UDP ports and they are scarcer. */
-
- /* Type of port to first pick in next iteration */
- int is_tcp = 1;
- int trial = 0;
-
- char *env = gpr_getenv("GRPC_TEST_PORT_SERVER");
- if (env) {
- int port = grpc_pick_port_using_server(env);
- gpr_free(env);
- if (port != 0) {
- return port;
- }
- }
-
- for (;;) {
- int port;
- trial++;
- if (trial == 1) {
- port = _getpid() % (65536 - 30000) + 30000;
- } else if (trial <= NUM_RANDOM_PORTS_TO_PICK) {
- port = rand() % (65536 - 30000) + 30000;
- } else {
- port = 0;
- }
-
- if (has_port_been_chosen(port)) {
- continue;
- }
-
- if (!is_port_available(&port, is_tcp)) {
- continue;
- }
-
- GPR_ASSERT(port > 0);
- /* Check that the port # is free for the other type of socket also */
- if (!is_port_available(&port, !is_tcp)) {
- /* In the next iteration trial to bind to the other type first
- because perhaps it is more rare. */
- is_tcp = !is_tcp;
- continue;
- }
-
- /* TODO(ctiller): consider caching this port in some structure, to avoid
- handing it out again */
-
- chose_port(port);
- return port;
- }
-
- /* The port iterator reached the end without finding a suitable port. */
- return 0;
-}
-
-int grpc_pick_unused_port_or_die(void) {
- int port = grpc_pick_unused_port();
- GPR_ASSERT(port > 0);
- return port;
-}
-
-void grpc_recycle_unused_port(int port) { GPR_ASSERT(free_chosen_port(port)); }
-
-#endif /* GRPC_WINSOCK_SOCKET && GRPC_TEST_PICK_PORT */
diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json
index 1172eaf..03acb45 100644
--- a/tools/run_tests/generated/sources_and_headers.json
+++ b/tools/run_tests/generated/sources_and_headers.json
@@ -7935,12 +7935,10 @@
"test/core/util/parse_hexstring.h",
"test/core/util/passthru_endpoint.c",
"test/core/util/passthru_endpoint.h",
+ "test/core/util/port.c",
"test/core/util/port.h",
- "test/core/util/port_posix.c",
"test/core/util/port_server_client.c",
"test/core/util/port_server_client.h",
- "test/core/util/port_uv.c",
- "test/core/util/port_windows.c",
"test/core/util/slice_splitter.c",
"test/core/util/slice_splitter.h",
"test/core/util/trickle_endpoint.c",
diff --git a/tools/run_tests/python_utils/start_port_server.py b/tools/run_tests/python_utils/start_port_server.py
index 4c9f6aa..deb7354 100644
--- a/tools/run_tests/python_utils/start_port_server.py
+++ b/tools/run_tests/python_utils/start_port_server.py
@@ -40,7 +40,10 @@
import time
-def start_port_server(port_server_port):
+# must be synchronized with test/core/utils/port_server_client.h
+_PORT_SERVER_PORT = 32766
+
+def start_port_server():
# check if a compatible port server is running
# if incompatible (version mismatch) ==> start a new one
# if not running ==> start a new one
@@ -48,7 +51,7 @@
try:
version = int(
urllib.request.urlopen(
- 'http://localhost:%d/version_number' % port_server_port,
+ 'http://localhost:%d/version_number' % _PORT_SERVER_PORT,
timeout=10).read())
logging.info('detected port server running version %d', version)
running = True
@@ -67,7 +70,7 @@
if not running:
logging.info('port_server version mismatch: killing the old one')
urllib.request.urlopen('http://localhost:%d/quitquitquit' %
- port_server_port).read()
+ _PORT_SERVER_PORT).read()
time.sleep(1)
if not running:
fd, logfile = tempfile.mkstemp()
@@ -76,7 +79,7 @@
args = [
sys.executable,
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
- '-p', '%d' % port_server_port, '-l', logfile
+ '-p', '%d' % _PORT_SERVER_PORT, '-l', logfile
]
env = dict(os.environ)
env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
@@ -107,7 +110,7 @@
time.sleep(1)
try:
urllib.request.urlopen(
- 'http://localhost:%d/get' % port_server_port,
+ 'http://localhost:%d/get' % _PORT_SERVER_PORT,
timeout=1).read()
logging.info(
'last ditch attempt to contact port server succeeded')
@@ -119,7 +122,7 @@
print(port_log)
sys.exit(1)
try:
- port_server_url = 'http://localhost:%d/get' % port_server_port
+ port_server_url = 'http://localhost:%d/get' % _PORT_SERVER_PORT
urllib.request.urlopen(port_server_url, timeout=1).read()
logging.info('port server is up and ready')
break
diff --git a/tools/run_tests/run_microbenchmark.py b/tools/run_tests/run_microbenchmark.py
index 4307906..2c66fa9 100755
--- a/tools/run_tests/run_microbenchmark.py
+++ b/tools/run_tests/run_microbenchmark.py
@@ -44,8 +44,7 @@
if not os.path.exists('reports'):
os.makedirs('reports')
-port_server_port = 32766
-start_port_server.start_port_server(port_server_port)
+start_port_server.start_port_server()
def fnize(s):
out = ''
@@ -110,8 +109,7 @@
if len(benchmarks) >= min(16, multiprocessing.cpu_count()):
# run up to half the cpu count: each benchmark can use up to two cores
# (one for the microbenchmark, one for the data flush)
- jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2),
- add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
+ jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2))
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
benchmarks = []
@@ -119,8 +117,7 @@
cleanup = []
# run the remaining benchmarks that weren't flushed
if len(benchmarks):
- jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2),
- add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
+ jobset.run(benchmarks, maxjobs=max(1, multiprocessing.cpu_count()/2))
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
@@ -156,8 +153,7 @@
if len(benchmarks) >= 20:
# run up to half the cpu count: each benchmark can use up to two cores
# (one for the microbenchmark, one for the data flush)
- jobset.run(benchmarks, maxjobs=1,
- add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
+ jobset.run(benchmarks, maxjobs=1)
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
benchmarks = []
@@ -165,8 +161,7 @@
cleanup = []
# run the remaining benchmarks that weren't flushed
if len(benchmarks):
- jobset.run(benchmarks, maxjobs=1,
- add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port})
+ jobset.run(benchmarks, maxjobs=1)
jobset.run(profile_analysis, maxjobs=multiprocessing.cpu_count())
jobset.run(cleanup, maxjobs=multiprocessing.cpu_count())
diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py
index 9e9af59..118609c 100755
--- a/tools/run_tests/run_tests.py
+++ b/tools/run_tests/run_tests.py
@@ -1451,8 +1451,7 @@
# start antagonists
antagonists = [subprocess.Popen(['tools/run_tests/python_utils/antagonist.py'])
for _ in range(0, args.antagonists)]
- port_server_port = 32766
- start_port_server.start_port_server(port_server_port)
+ start_port_server.start_port_server()
resultset = None
num_test_failures = 0
try:
@@ -1495,7 +1494,6 @@
all_runs, check_cancelled, newline_on_success=newline_on_success,
travis=args.travis, maxjobs=args.jobs,
stop_on_failure=args.stop_on_failure,
- add_env={'GRPC_TEST_PORT_SERVER': 'localhost:%d' % port_server_port},
quiet_success=args.quiet_success)
if resultset:
for k, v in sorted(resultset.items()):
diff --git a/tools/run_tests/start_port_server.py b/tools/run_tests/start_port_server.py
new file mode 100755
index 0000000..e33ac12
--- /dev/null
+++ b/tools/run_tests/start_port_server.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+"""
+Wrapper around port server starting code.
+
+Used by developers who wish to run individual C/C++ tests outside of the
+run_tests.py infrastructure.
+
+The path to this file is called out in test/core/util/port.c, and printed as
+an error message to users.
+"""
+
+import python_utils.start_port_server as start_port_server
+
+start_port_server.start_port_server()
+
+print "Port server started successfully"
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
index 6d4b4f7..d08ceb6 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
@@ -335,14 +335,10 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\passthru_endpoint.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
+ <ClCompile Include="$(SolutionDir)\..\test\core\util\port.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_uv.c">
- </ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\trickle_endpoint.c">
diff --git a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
index 5444f6f..3beaa80 100644
--- a/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
@@ -49,18 +49,12 @@
<ClCompile Include="$(SolutionDir)\..\test\core\util\passthru_endpoint.c">
<Filter>test\core\util</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
+ <ClCompile Include="$(SolutionDir)\..\test\core\util\port.c">
<Filter>test\core\util</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
<Filter>test\core\util</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_uv.c">
- <Filter>test\core\util</Filter>
- </ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
- <Filter>test\core\util</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
<Filter>test\core\util</Filter>
</ClCompile>
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
index 1ea6465..5a58cae 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
@@ -186,14 +186,10 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\passthru_endpoint.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
+ <ClCompile Include="$(SolutionDir)\..\test\core\util\port.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_uv.c">
- </ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\trickle_endpoint.c">
diff --git a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
index e2ad88c..88c875c 100644
--- a/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
+++ b/vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters
@@ -34,18 +34,12 @@
<ClCompile Include="$(SolutionDir)\..\test\core\util\passthru_endpoint.c">
<Filter>test\core\util</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_posix.c">
+ <ClCompile Include="$(SolutionDir)\..\test\core\util\port.c">
<Filter>test\core\util</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\port_server_client.c">
<Filter>test\core\util</Filter>
</ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_uv.c">
- <Filter>test\core\util</Filter>
- </ClCompile>
- <ClCompile Include="$(SolutionDir)\..\test\core\util\port_windows.c">
- <Filter>test\core\util</Filter>
- </ClCompile>
<ClCompile Include="$(SolutionDir)\..\test\core\util\slice_splitter.c">
<Filter>test\core\util</Filter>
</ClCompile>