Merge github.com:grpc/grpc into lto

pull/9932/head
Craig Tiller 8 years ago
commit 36281f950a
  1. 8
      CMakeLists.txt
  2. 8
      Makefile
  3. 4
      build.yaml
  4. 2
      composer.json
  5. 2
      examples/php/composer.json
  6. 2
      gRPC-Core.podspec
  7. 42
      package.xml
  8. 4
      src/core/lib/http/parser.c
  9. 4
      src/cpp/server/health/default_health_check_service.cc
  10. 2
      src/php/README.md
  11. 2
      src/php/composer.json
  12. 2
      templates/composer.json.template
  13. 2
      templates/gRPC-Core.podspec.template
  14. 42
      templates/package.xml.template
  15. 2
      templates/src/php/composer.json.template
  16. 3
      test/core/util/BUILD
  17. 52
      test/core/util/port.c
  18. 256
      test/core/util/port_posix.c
  19. 10
      test/core/util/port_server_client.c
  20. 7
      test/core/util/port_server_client.h
  21. 247
      test/core/util/port_windows.c
  22. 4
      tools/run_tests/generated/sources_and_headers.json
  23. 15
      tools/run_tests/python_utils/start_port_server.py
  24. 49
      tools/run_tests/run_microbenchmark.py
  25. 4
      tools/run_tests/run_tests.py
  26. 46
      tools/run_tests/start_port_server.py
  27. 6
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj
  28. 8
      vsprojects/vcxproj/grpc_test_util/grpc_test_util.vcxproj.filters
  29. 6
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj
  30. 8
      vsprojects/vcxproj/grpc_test_util_unsecure/grpc_test_util_unsecure.vcxproj.filters

@ -1447,10 +1447,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
@ -1656,10 +1654,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
)

@ -3329,10 +3329,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 \
@ -3531,10 +3529,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 \

@ -611,10 +611,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:

@ -7,7 +7,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -2,7 +2,7 @@
"name": "grpc/grpc-demo",
"description": "gRPC example for PHP",
"require": {
"grpc/grpc": "v1.1.0"
"grpc/grpc": "^v1.1.0"
},
"autoload": {
"psr-4": {

@ -917,7 +917,7 @@ Pod::Spec.new do |s|
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port.c',
'test/core/util/port_server_client.{c,h}'
end
end

@ -10,7 +10,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-01-13</date>
<date>2017-03-01</date>
<time>16:06:07</time>
<version>
<release>1.2.0dev</release>
@ -22,8 +22,8 @@
</stability>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -1276,8 +1276,8 @@ Update to wrap gRPC C Core version 0.10.0
</release>
<release>
<version>
<release>1.1.0dev</release>
<api>1.1.0dev</api>
<release>1.1.0RC1</release>
<api>1.1.0RC1</api>
</version>
<stability>
<release>beta</release>
@ -1290,5 +1290,37 @@ Update to wrap gRPC C Core version 0.10.0
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2017-01-31</date>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.2.0RC1</release>
<api>1.2.0RC1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2017-03-01</date>
<license>BSD</license>
<notes>
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
</release>
</changelog>
</package>

@ -284,9 +284,9 @@ static grpc_error *addbyte(grpc_http_parser *parser, uint8_t byte,
case GRPC_HTTP_HEADERS:
if (parser->cur_line_length >= GRPC_HTTP_PARSER_MAX_HEADER_LENGTH) {
if (grpc_http1_trace)
gpr_log(GPR_ERROR, "HTTP client max line length (%d) exceeded",
gpr_log(GPR_ERROR, "HTTP header max line length (%d) exceeded",
GRPC_HTTP_PARSER_MAX_HEADER_LENGTH);
return GRPC_ERROR_NONE;
return GRPC_ERROR_CREATE("HTTP header max line length exceeded");
}
parser->cur_line[parser->cur_line_length] = byte;
parser->cur_line_length++;

@ -63,7 +63,9 @@ Status DefaultHealthCheckService::HealthCheckServiceImpl::Check(
ServerContext* context, const ByteBuffer* request, ByteBuffer* response) {
// Decode request.
std::vector<Slice> slices;
request->Dump(&slices);
if (!request->Dump(&slices).ok()) {
return Status(StatusCode::INVALID_ARGUMENT, "");
}
uint8_t* request_bytes = nullptr;
bool request_bytes_owned = false;
size_t request_size = 0;

@ -158,7 +158,7 @@ $ composer install
### Protobuf compiler
Again if you don't have it already, you need to install the protobuf compiler
`protoc`, version 3.2.0+.
`protoc`, version 3.1.0+ (the newer the better).
If `protoc` hasn't been installed, you can download the `protoc` binaries from
[the protocol buffers Github repository](https://github.com/google/protobuf/releases).

@ -5,7 +5,7 @@
"version": "1.2.0",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -9,7 +9,7 @@
"license": "BSD-3-Clause",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

@ -191,7 +191,7 @@
'test/core/util/debugger_macros.c',
'test/core/util/test_config.{c,h}',
'test/core/util/port.h',
'test/core/util/port_posix.c',
'test/core/util/port.c',
'test/core/util/port_server_client.{c,h}'
end
end

@ -12,7 +12,7 @@
<email>grpc-packages@google.com</email>
<active>yes</active>
</lead>
<date>2017-01-13</date>
<date>2017-03-01</date>
<time>16:06:07</time>
<version>
<release>${settings.php_version.php()}</release>
@ -24,8 +24,8 @@
</stability>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
<contents>
<dir baseinstalldir="/" name="/">
@ -312,8 +312,8 @@
</release>
<release>
<version>
<release>1.1.0dev</release>
<api>1.1.0dev</api>
<release>1.1.0RC1</release>
<api>1.1.0RC1</api>
</version>
<stability>
<release>beta</release>
@ -326,5 +326,37 @@
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.1.0</release>
<api>1.1.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2017-01-31</date>
<license>BSD</license>
<notes>
- PHP Proto3 adoption #8179
- Various bug fixes
</notes>
</release>
<release>
<version>
<release>1.2.0RC1</release>
<api>1.2.0RC1</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
</stability>
<date>2017-03-01</date>
<license>BSD</license>
<notes>
- Added arg info macros #9751
- Updated codegen to be consistent with protobuf #9492
</notes>
</release>
</changelog>
</package>

@ -7,7 +7,7 @@
"version": "${settings.php_version.php_composer()}",
"require": {
"php": ">=5.5.0",
"google/protobuf": "v3.1.0"
"google/protobuf": "^v3.1.0"
},
"require-dev": {
"google/auth": "v0.9"

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

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

@ -40,7 +40,10 @@ import tempfile
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 @@ def start_port_server(port_server_port):
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 @@ def start_port_server(port_server_port):
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 @@ def start_port_server(port_server_port):
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 @@ def start_port_server(port_server_port):
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 @@ def start_port_server(port_server_port):
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

@ -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 = ''
@ -110,8 +109,7 @@ def collect_latency(bm_name, args):
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 @@ 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())
@ -156,8 +153,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 = []
@ -165,17 +161,16 @@ 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())
def run_summary(cfg):
def run_summary(bm_name, cfg, base_json_name):
subprocess.check_call(
['make', bm_name,
'CONFIG=%s' % cfg, '-j', '%d' % multiprocessing.cpu_count()])
cmd = ['bins/%s/%s' % (cfg, bm_name),
'--benchmark_out=out.%s.json' % cfg,
'--benchmark_out=%s.%s.json' % (base_json_name, cfg),
'--benchmark_out_format=json']
if args.summary_time is not None:
cmd += ['--benchmark_min_time=%d' % args.summary_time]
@ -183,9 +178,9 @@ def run_summary(cfg):
def collect_summary(bm_name, args):
heading('Summary: %s [no counters]' % bm_name)
text(run_summary('lto'))
text(run_summary(bm_name, 'lto', 'out'))
heading('Summary: %s [with counters]' % bm_name)
text(run_summary('counters'))
text(run_summary(bm_name, 'counters', 'out'))
if args.bigquery_upload:
with open('out.csv', 'w') as f:
f.write(subprocess.check_output(['tools/profiling/microbenchmarks/bm2bq.py', 'out.counters.json', 'out.opt.json']))
@ -200,7 +195,7 @@ collectors = {
argp = argparse.ArgumentParser(description='Collect data from microbenchmarks')
argp.add_argument('-c', '--collect',
choices=sorted(collectors.keys()),
nargs='+',
nargs='*',
default=sorted(collectors.keys()),
help='Which collectors should be run against each benchmark')
argp.add_argument('-b', '--benchmarks',
@ -214,6 +209,10 @@ argp.add_argument('-b', '--benchmarks',
nargs='+',
type=str,
help='Which microbenchmarks should be run')
argp.add_argument('--diff_perf',
default=None,
type=str,
help='Diff microbenchmarks against this git revision')
argp.add_argument('--bigquery_upload',
default=False,
action='store_const',
@ -228,6 +227,26 @@ args = argp.parse_args()
for bm_name in args.benchmarks:
for collect in args.collect:
collectors[collect](bm_name, args)
if args.diff_perf:
for bm_name in args.benchmarks:
run_summary(bm_name, 'lto', '%s.new' % bm_name)
where_am_i = subprocess.check_output(['git', 'rev-parse', '--abbrev-ref', 'HEAD']).strip()
subprocess.check_call(['git', 'checkout', args.diff_perf])
comparables = []
subprocess.check_call(['make', 'clean'])
try:
for bm_name in args.benchmarks:
try:
run_summary(bm_name, 'lto', '%s.old' % bm_name)
comparables.append(bm_name)
except subprocess.CalledProcessError, e:
pass
finally:
subprocess.check_call(['git', 'checkout', where_am_i])
for bm_name in comparables:
subprocess.check_call(['third_party/benchmark/tools/compare_bench.py',
'%s.new.opt.json' % bm_name,
'%s.old.opt.json' % bm_name])
index_html += "</body>\n</html>\n"
with open('reports/index.html', 'w') as f:

@ -1451,8 +1451,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:
@ -1495,7 +1494,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,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"

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