Eliminate port server env var, force its use always, consolidate code

pull/9769/head
Craig Tiller 8 years ago
parent 13e185419c
commit cba864bfbe
  1. 8
      CMakeLists.txt
  2. 8
      Makefile
  3. 4
      build.yaml
  4. 3
      test/core/util/BUILD
  5. 52
      test/core/util/port.c
  6. 256
      test/core/util/port_posix.c
  7. 10
      test/core/util/port_server_client.c
  8. 7
      test/core/util/port_server_client.h
  9. 247
      test/core/util/port_windows.c
  10. 4
      tools/run_tests/generated/sources_and_headers.json
  11. 15
      tools/run_tests/python_utils/start_port_server.py
  12. 15
      tools/run_tests/run_microbenchmark.py
  13. 4
      tools/run_tests/run_tests.py
  14. 44
      tools/run_tests/start_port_server.py
  15. 6
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
  16. 8
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
  17. 6
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
  18. 8
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters

@ -1428,10 +1428,8 @@ add_library(grpc_test_util
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
@ -1637,10 +1635,8 @@ add_library(grpc_test_util_unsecure
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
)

@ -3264,10 +3264,8 @@ LIBGRPC_TEST_UTIL_SRC = \
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 \
@ -3466,10 +3464,8 @@ LIBGRPC_TEST_UTIL_UNSECURE_SRC = \
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 \

@ -610,10 +610,8 @@ filegroups:
- 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:

@ -51,9 +51,8 @@ cc_library(
"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",

@ -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 @@ 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++) {
@ -64,24 +70,16 @@ static int free_chosen_port(int port) {
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 @@ static void chose_port(int port) {
}
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 */

@ -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 */

@ -74,7 +74,7 @@ static void freed_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
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 @@ void grpc_free_port_using_server(char *server, int port) {
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 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg,
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 @@ int grpc_pick_port_using_server(char *server) {
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);

@ -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

@ -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 */

@ -7811,12 +7811,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",

@ -38,7 +38,10 @@ import time
import jobset
import socket
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
@ -55,19 +58,22 @@ def start_port_server(port_server_port):
running = False
if running:
current_version = int(subprocess.check_output(
[sys.executable, os.path.abspath('tools/run_tests/python_utils/port_server.py'),
[sys.executable,
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
'dump_version']))
print('my port server is version %d' % current_version)
running = (version >= current_version)
if not running:
print('port_server version mismatch: killing the old one')
urllib.request.urlopen('http://localhost:%d/quitquitquit' % port_server_port).read()
urllib.request.urlopen('http://localhost:%d/quitquitquit' %
port_server_port).read()
time.sleep(1)
if not running:
fd, logfile = tempfile.mkstemp()
os.close(fd)
print('starting port_server, with log file %s' % logfile)
args = [sys.executable, os.path.abspath('tools/run_tests/python_utils/port_server.py'),
args = [sys.executable,
os.path.abspath('tools/run_tests/python_utils/port_server.py'),
'-p', '%d' % port_server_port, '-l', logfile]
env = dict(os.environ)
env['BUILD_ID'] = 'pleaseDontKillMeJenkins'
@ -127,4 +133,3 @@ def start_port_server(port_server_port):
traceback.print_exc()
port_server.kill()
raise

@ -44,8 +44,7 @@ os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../..'))
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 = ''
@ -108,8 +107,7 @@ def collect_latency(bm_name, args):
if len(benchmarks) >= min(4, 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 = []
@ -117,8 +115,7 @@ def collect_latency(bm_name, args):
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())
@ -154,8 +151,7 @@ def collect_perf(bm_name, args):
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 = []
@ -163,8 +159,7 @@ def collect_perf(bm_name, args):
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())

@ -1437,8 +1437,7 @@ def _build_and_run(
# 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:
@ -1481,7 +1480,6 @@ def _build_and_run(
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()):

@ -0,0 +1,44 @@
#!/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()

@ -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">

@ -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>

@ -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">

@ -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>

Loading…
Cancel
Save