diff options
author | 2017-03-09 11:16:25 -0800 | |
---|---|---|
committer | 2017-03-09 11:16:25 -0800 | |
commit | b3eee5c8c7edb9d3f1c727fdaf801933e9ef4797 (patch) | |
tree | db7aa08608e112258734797d266689ed670a1349 /test/core | |
parent | ffe4f5e0840c1879e974b2463384b0a461bba468 (diff) | |
parent | eb064ec7b81b60c5e1eb47d6124d0c05056b3097 (diff) |
Merge branch 'master' of https://github.com/grpc/grpc into to-grpc-err-is-human
Diffstat (limited to 'test/core')
29 files changed, 337 insertions, 617 deletions
diff --git a/test/core/census/BUILD b/test/core/census/BUILD index 9ec48bdfe2..49680ab91f 100644 --- a/test/core/census/BUILD +++ b/test/core/census/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "context_test", srcs = ["context_test.c"], diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD index 42cb468485..c6590465f1 100644 --- a/test/core/channel/BUILD +++ b/test/core/channel/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "channel_args_test", srcs = ["channel_args_test.c"], diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c new file mode 100644 index 0000000000..37dd0fba52 --- /dev/null +++ b/test/core/client_channel/parse_address_test.c @@ -0,0 +1,116 @@ +/* + * + * 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. + * + */ + +#include "src/core/ext/client_channel/parse_address.h" +#include "src/core/lib/iomgr/sockaddr.h" + +#include <string.h> +#ifdef GRPC_HAVE_UNIX_SOCKET +#include <sys/un.h> +#endif + +#include <grpc/support/log.h> + +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/socket_utils.h" +#include "test/core/util/test_config.h" + +#ifdef GRPC_HAVE_UNIX_SOCKET + +static void test_parse_unix(const char *uri_text, const char *pathname) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + + GPR_ASSERT(1 == parse_unix(uri, &addr)); + struct sockaddr_un *addr_un = (struct sockaddr_un *)addr.addr; + GPR_ASSERT(AF_UNIX == addr_un->sun_family); + GPR_ASSERT(0 == strcmp(addr_un->sun_path, pathname)); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +#else /* GRPC_HAVE_UNIX_SOCKET */ + +static void test_parse_unix(const char *uri_text, const char *pathname) {} + +#endif /* GRPC_HAVE_UNIX_SOCKET */ + +static void test_parse_ipv4(const char *uri_text, const char *host, + unsigned short port) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + char ntop_buf[INET_ADDRSTRLEN]; + + GPR_ASSERT(1 == parse_ipv4(uri, &addr)); + struct sockaddr_in *addr_in = (struct sockaddr_in *)addr.addr; + GPR_ASSERT(AF_INET == addr_in->sin_family); + GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET, &addr_in->sin_addr, ntop_buf, + sizeof(ntop_buf))); + GPR_ASSERT(0 == strcmp(ntop_buf, host)); + GPR_ASSERT(ntohs(addr_in->sin_port) == port); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_parse_ipv6(const char *uri_text, const char *host, + unsigned short port, uint32_t scope_id) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); + grpc_resolved_address addr; + char ntop_buf[INET6_ADDRSTRLEN]; + + GPR_ASSERT(1 == parse_ipv6(uri, &addr)); + struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)addr.addr; + GPR_ASSERT(AF_INET6 == addr_in6->sin6_family); + GPR_ASSERT(NULL != grpc_inet_ntop(AF_INET6, &addr_in6->sin6_addr, ntop_buf, + sizeof(ntop_buf))); + GPR_ASSERT(0 == strcmp(ntop_buf, host)); + GPR_ASSERT(ntohs(addr_in6->sin6_port) == port); + GPR_ASSERT(addr_in6->sin6_scope_id == scope_id); + + grpc_uri_destroy(uri); + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + test_parse_unix("unix:/path/name", "/path/name"); + test_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345); + test_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0); + test_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2); +} diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c index 3e3401165c..187757d5b3 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -69,7 +69,7 @@ static grpc_error *my_resolve_address(const char *name, const char *addr, static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx, const char *name) { grpc_resolver_factory *factory = grpc_resolver_factory_lookup("dns"); - grpc_uri *uri = grpc_uri_parse(name, 0); + grpc_uri *uri = grpc_uri_parse(exec_ctx, name, 0); GPR_ASSERT(uri); grpc_resolver_args args; memset(&args, 0, sizeof(args)); diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c index 9dd5aed091..919a85d58f 100644 --- a/test/core/client_channel/resolvers/dns_resolver_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_test.c @@ -43,7 +43,7 @@ static grpc_combiner *g_combiner; static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -61,7 +61,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c index 68831ab7c7..bc4f02c339 100644 --- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c @@ -57,7 +57,7 @@ void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { static void test_succeeds(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be valid for '%s'", string, @@ -84,7 +84,7 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { static void test_fails(grpc_resolver_factory *factory, const char *string) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - grpc_uri *uri = grpc_uri_parse(string, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, string, 0); grpc_resolver_args args; grpc_resolver *resolver; gpr_log(GPR_DEBUG, "test: '%s' should be invalid for '%s'", string, diff --git a/test/core/client_channel/uri_fuzzer_test.c b/test/core/client_channel/uri_fuzzer_test.c index d2e3fb40ea..baadd4fc65 100644 --- a/test/core/client_channel/uri_fuzzer_test.c +++ b/test/core/client_channel/uri_fuzzer_test.c @@ -38,6 +38,7 @@ #include <grpc/support/alloc.h> #include "src/core/ext/client_channel/uri_parser.h" +#include "src/core/lib/iomgr/exec_ctx.h" bool squelch = true; bool leak_check = true; @@ -47,10 +48,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memcpy(s, data, size); s[size] = 0; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_uri *x; - if ((x = grpc_uri_parse(s, 1))) { + if ((x = grpc_uri_parse(&exec_ctx, s, 1))) { grpc_uri_destroy(x); } + grpc_exec_ctx_finish(&exec_ctx); gpr_free(s); return 0; } diff --git a/test/core/client_channel/uri_parser_test.c b/test/core/client_channel/uri_parser_test.c index 5f32d3270c..8a127f72eb 100644 --- a/test/core/client_channel/uri_parser_test.c +++ b/test/core/client_channel/uri_parser_test.c @@ -37,29 +37,35 @@ #include <grpc/support/log.h> +#include "src/core/lib/iomgr/exec_ctx.h" #include "test/core/util/test_config.h" static void test_succeeds(const char *uri_text, const char *scheme, const char *authority, const char *path, const char *query, const char *fragment) { - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp(scheme, uri->scheme)); GPR_ASSERT(0 == strcmp(authority, uri->authority)); GPR_ASSERT(0 == strcmp(path, uri->path)); GPR_ASSERT(0 == strcmp(query, uri->query)); GPR_ASSERT(0 == strcmp(fragment, uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } static void test_fails(const char *uri_text) { - GPR_ASSERT(NULL == grpc_uri_parse(uri_text, 0)); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GPR_ASSERT(NULL == grpc_uri_parse(&exec_ctx, uri_text, 0)); + grpc_exec_ctx_finish(&exec_ctx); } static void test_query_parts() { { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path?a&b=B&c=&#frag"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -86,12 +92,14 @@ static void test_query_parts() { GPR_ASSERT(NULL == grpc_uri_get_query_arg(uri, "")); GPR_ASSERT(0 == strcmp("frag", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* test the current behavior of multiple query part values */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://auth/path?foo=bar=baz&foobar=="; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -103,12 +111,14 @@ static void test_query_parts() { GPR_ASSERT(0 == strcmp("bar", grpc_uri_get_query_arg(uri, "foo"))); GPR_ASSERT(0 == strcmp("", grpc_uri_get_query_arg(uri, "foobar"))); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } { /* empty query */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; const char *uri_text = "http://foo/path"; - grpc_uri *uri = grpc_uri_parse(uri_text, 0); + grpc_uri *uri = grpc_uri_parse(&exec_ctx, uri_text, 0); GPR_ASSERT(uri); GPR_ASSERT(0 == strcmp("http", uri->scheme)); @@ -119,6 +129,7 @@ static void test_query_parts() { GPR_ASSERT(NULL == uri->query_parts); GPR_ASSERT(NULL == uri->query_parts_values); GPR_ASSERT(0 == strcmp("", uri->fragment)); + grpc_exec_ctx_finish(&exec_ctx); grpc_uri_destroy(uri); } } @@ -142,6 +153,8 @@ int main(int argc, char **argv) { test_succeeds("http:?legit#twice", "http", "", "", "legit", "twice"); test_succeeds("http://foo?bar#lol?", "http", "foo", "", "bar", "lol?"); test_succeeds("http://foo?bar#lol?/", "http", "foo", "", "bar", "lol?/"); + test_succeeds("ipv6:[2001:db8::1%252]:12345", "ipv6", "", + "[2001:db8::1%2]:12345", "", ""); test_fails("xyz"); test_fails("http:?dangling-pct-%0"); diff --git a/test/core/compression/BUILD b/test/core/compression/BUILD index a243a72029..9ddb4c52b4 100644 --- a/test/core/compression/BUILD +++ b/test/core/compression/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "algorithm_test", srcs = ["algorithm_test.c"], diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD index a40fb8e083..0cef7aa01d 100644 --- a/test/core/end2end/BUILD +++ b/test/core/end2end/BUILD @@ -63,8 +63,8 @@ cc_library( cc_library( name = 'http_proxy', - hdrs = ['fixtures/http_proxy.h'], - srcs = ['fixtures/http_proxy.c'], + hdrs = ['fixtures/http_proxy_fixture.h'], + srcs = ['fixtures/http_proxy_fixture.c'], copts = ['-std=c99'], deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'] ) diff --git a/test/core/end2end/fixtures/h2_http_proxy.c b/test/core/end2end/fixtures/h2_http_proxy.c index 44b223664a..55c65fa70e 100644 --- a/test/core/end2end/fixtures/h2_http_proxy.c +++ b/test/core/end2end/fixtures/h2_http_proxy.c @@ -49,7 +49,7 @@ #include "src/core/lib/support/env.h" #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/server.h" -#include "test/core/end2end/fixtures/http_proxy.h" +#include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy_fixture.c index 9ccb1263ee..bcd1c9914b 100644 --- a/test/core/end2end/fixtures/http_proxy.c +++ b/test/core/end2end/fixtures/http_proxy_fixture.c @@ -31,7 +31,7 @@ * */ -#include "test/core/end2end/fixtures/http_proxy.h" +#include "test/core/end2end/fixtures/http_proxy_fixture.h" #include "src/core/lib/iomgr/sockaddr.h" diff --git a/test/core/end2end/fixtures/http_proxy.h b/test/core/end2end/fixtures/http_proxy_fixture.h index cd47b432af..cd47b432af 100644 --- a/test/core/end2end/fixtures/http_proxy.h +++ b/test/core/end2end/fixtures/http_proxy_fixture.h diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 Binary files differnew file mode 100644 index 0000000000..49c02c2f12 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6520142139752448 diff --git a/test/core/fling/fling_stream_test.c b/test/core/fling/fling_stream_test.c index 7e4daaa84f..948659ab2f 100644 --- a/test/core/fling/fling_stream_test.c +++ b/test/core/fling/fling_stream_test.c @@ -31,22 +31,13 @@ * */ -#ifndef _POSIX_SOURCE -#define _POSIX_SOURCE -#endif - -#include <assert.h> -#include <signal.h> #include <stdio.h> -#include <stdlib.h> #include <string.h> -#include <sys/types.h> -#include <sys/wait.h> -#include <unistd.h> #include <grpc/support/alloc.h> #include <grpc/support/host_port.h> #include <grpc/support/string_util.h> +#include <grpc/support/subprocess.h> #include "src/core/lib/support/string.h" #include "test/core/util/port.h" @@ -57,10 +48,7 @@ int main(int argc, char **argv) { int port = grpc_pick_unused_port_or_die(); char *args[10]; int status; - pid_t svr, cli; - /* seed rng with pid, so we don't end up with the same random numbers as a - concurrently running test binary */ - srand((unsigned)getpid()); + gpr_subprocess *svr, *cli; /* figure out where we are */ if (lslash) { memcpy(root, me, (size_t)(lslash - me)); @@ -69,45 +57,38 @@ int main(int argc, char **argv) { strcpy(root, "."); } /* start the server */ - svr = fork(); - if (svr == 0) { - gpr_asprintf(&args[0], "%s/fling_server", root); - args[1] = "--bind"; - gpr_join_host_port(&args[2], "::", port); - args[3] = "--no-secure"; - args[4] = 0; - execv(args[0], args); + gpr_asprintf(&args[0], "%s/fling_server%s", root, + gpr_subprocess_binary_extension()); + args[1] = "--bind"; + gpr_join_host_port(&args[2], "::", port); + args[3] = "--no-secure"; + svr = gpr_subprocess_create(4, (const char **)args); + gpr_free(args[0]); + gpr_free(args[2]); - gpr_free(args[0]); - gpr_free(args[2]); - return 1; - } - /* wait a little */ - sleep(2); /* start the client */ - cli = fork(); - if (cli == 0) { - gpr_asprintf(&args[0], "%s/fling_client", root); - args[1] = "--target"; - gpr_join_host_port(&args[2], "127.0.0.1", port); - args[3] = "--scenario=ping-pong-stream"; - args[4] = "--no-secure"; - args[5] = 0; - execv(args[0], args); + gpr_asprintf(&args[0], "%s/fling_client%s", root, + gpr_subprocess_binary_extension()); + args[1] = "--target"; + gpr_join_host_port(&args[2], "127.0.0.1", port); + args[3] = "--scenario=ping-pong-stream"; + args[4] = "--no-secure"; + args[5] = 0; + cli = gpr_subprocess_create(6, (const char **)args); + gpr_free(args[0]); + gpr_free(args[2]); - gpr_free(args[0]); - gpr_free(args[2]); - return 1; - } /* wait for completion */ printf("waiting for client\n"); - if (waitpid(cli, &status, 0) == -1) return 2; - if (!WIFEXITED(status)) return 4; - if (WEXITSTATUS(status)) return WEXITSTATUS(status); - printf("waiting for server\n"); - kill(svr, SIGINT); - if (waitpid(svr, &status, 0) == -1) return 2; - if (!WIFEXITED(status)) return 4; - if (WEXITSTATUS(status)) return WEXITSTATUS(status); - return 0; + if ((status = gpr_subprocess_join(cli))) { + gpr_subprocess_destroy(cli); + gpr_subprocess_destroy(svr); + return status; + } + gpr_subprocess_destroy(cli); + + gpr_subprocess_interrupt(svr); + status = gpr_subprocess_join(svr); + gpr_subprocess_destroy(svr); + return status; } diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD index 864e0db00b..eb8f3a9beb 100644 --- a/test/core/handshake/BUILD +++ b/test/core/handshake/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "client_ssl", srcs = ["client_ssl.c"], diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c index 8569c697fe..70a6c323e5 100644 --- a/test/core/iomgr/sockaddr_utils_test.c +++ b/test/core/iomgr/sockaddr_utils_test.c @@ -70,6 +70,12 @@ static grpc_resolved_address make_addr6(const uint8_t *data, size_t data_len) { return resolved_addr6; } +static void set_addr6_scope_id(grpc_resolved_address *addr, uint32_t scope_id) { + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr->addr; + GPR_ASSERT(addr6->sin6_family == AF_INET6); + addr6->sin6_scope_id = scope_id; +} + static const uint8_t kMapped[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff, 192, 0, 2, 1}; @@ -222,6 +228,16 @@ static void test_sockaddr_to_string(void) { expect_sockaddr_str("[2001:db8::1]:12345", &input6, 1); expect_sockaddr_uri("ipv6:[2001:db8::1]:12345", &input6); + set_addr6_scope_id(&input6, 2); + expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 0); + expect_sockaddr_str("[2001:db8::1%252]:12345", &input6, 1); + expect_sockaddr_uri("ipv6:[2001:db8::1%252]:12345", &input6); + + set_addr6_scope_id(&input6, 101); + expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 0); + expect_sockaddr_str("[2001:db8::1%25101]:12345", &input6, 1); + expect_sockaddr_uri("ipv6:[2001:db8::1%25101]:12345", &input6); + input6 = make_addr6(kMapped, sizeof(kMapped)); expect_sockaddr_str("[::ffff:192.0.2.1]:12345", &input6, 0); expect_sockaddr_str("192.0.2.1:12345", &input6, 1); diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index efadddc011..6e514324a5 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -454,7 +454,8 @@ int main(int argc, char **argv) { const grpc_channel_args channel_args = {1, chan_args}; struct ifaddrs *ifa = NULL; struct ifaddrs *ifa_it; - test_addrs dst_addrs; + // Zalloc dst_addrs to avoid oversized frames. + test_addrs *dst_addrs = gpr_zalloc(sizeof(*dst_addrs)); grpc_test_init(argc, argv); grpc_init(); g_pollset = gpr_zalloc(grpc_pollset_size()); @@ -469,24 +470,25 @@ int main(int argc, char **argv) { gpr_log(GPR_ERROR, "getifaddrs: %s", strerror(errno)); return EXIT_FAILURE; } - dst_addrs.naddrs = 0; - for (ifa_it = ifa; ifa_it != NULL && dst_addrs.naddrs < MAX_ADDRS; + dst_addrs->naddrs = 0; + for (ifa_it = ifa; ifa_it != NULL && dst_addrs->naddrs < MAX_ADDRS; ifa_it = ifa_it->ifa_next) { if (ifa_it->ifa_addr == NULL) { continue; } else if (ifa_it->ifa_addr->sa_family == AF_INET) { - dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in); + dst_addrs->addrs[dst_addrs->naddrs].addr.len = sizeof(struct sockaddr_in); } else if (ifa_it->ifa_addr->sa_family == AF_INET6) { - dst_addrs.addrs[dst_addrs.naddrs].addr.len = sizeof(struct sockaddr_in6); + dst_addrs->addrs[dst_addrs->naddrs].addr.len = + sizeof(struct sockaddr_in6); } else { continue; } - memcpy(dst_addrs.addrs[dst_addrs.naddrs].addr.addr, ifa_it->ifa_addr, - dst_addrs.addrs[dst_addrs.naddrs].addr.len); + memcpy(dst_addrs->addrs[dst_addrs->naddrs].addr.addr, ifa_it->ifa_addr, + dst_addrs->addrs[dst_addrs->naddrs].addr.len); GPR_ASSERT( - grpc_sockaddr_set_port(&dst_addrs.addrs[dst_addrs.naddrs].addr, 0)); - test_addr_init_str(&dst_addrs.addrs[dst_addrs.naddrs]); - ++dst_addrs.naddrs; + grpc_sockaddr_set_port(&dst_addrs->addrs[dst_addrs->naddrs].addr, 0)); + test_addr_init_str(&dst_addrs->addrs[dst_addrs->naddrs]); + ++dst_addrs->naddrs; } freeifaddrs(ifa); ifa = NULL; @@ -495,20 +497,21 @@ int main(int argc, char **argv) { test_connect(1, NULL, NULL, false); test_connect(10, NULL, NULL, false); - /* Set dst_addrs.addrs[i].len=0 for dst_addrs that are unreachable with a "::" - listener. */ - test_connect(1, NULL, &dst_addrs, true); + /* Set dst_addrs->addrs[i].len=0 for dst_addrs that are unreachable with a + "::" listener. */ + test_connect(1, NULL, dst_addrs, true); /* Test connect(2) with dst_addrs. */ - test_connect(1, &channel_args, &dst_addrs, false); + test_connect(1, &channel_args, dst_addrs, false); /* Test connect(2) with dst_addrs. */ - test_connect(10, &channel_args, &dst_addrs, false); + test_connect(10, &channel_args, dst_addrs, false); grpc_closure_init(&destroyed, destroy_pollset, g_pollset, grpc_schedule_on_exec_ctx); grpc_pollset_shutdown(&exec_ctx, g_pollset, &destroyed); grpc_exec_ctx_finish(&exec_ctx); grpc_shutdown(); + gpr_free(dst_addrs); gpr_free(g_pollset); return EXIT_SUCCESS; } diff --git a/test/core/slice/percent_encoding_test.c b/test/core/slice/percent_encoding_test.c index 222e695fd4..89f8154955 100644 --- a/test/core/slice/percent_encoding_test.c +++ b/test/core/slice/percent_encoding_test.c @@ -146,6 +146,7 @@ int main(int argc, char **argv) { TEST_VECTOR("\x0f", "%0F", grpc_url_percent_encoding_unreserved_bytes); TEST_VECTOR("\xff", "%FF", grpc_url_percent_encoding_unreserved_bytes); TEST_VECTOR("\xee", "%EE", grpc_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("%2", "%252", grpc_url_percent_encoding_unreserved_bytes); TEST_NONCONFORMANT_VECTOR("%", "%", grpc_url_percent_encoding_unreserved_bytes); TEST_NONCONFORMANT_VECTOR("%A", "%A", diff --git a/test/core/support/BUILD b/test/core/support/BUILD index 08cee1441b..3183510db9 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "alloc_test", srcs = ["alloc_test.c"], diff --git a/test/core/surface/BUILD b/test/core/surface/BUILD index c158413122..3d5e26ced3 100644 --- a/test/core/surface/BUILD +++ b/test/core/surface/BUILD @@ -27,6 +27,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +licenses(["notice"]) # 3-clause BSD + cc_test( name = "alarm_test", srcs = ["alarm_test.c"], diff --git a/test/core/transport/BUILD b/test/core/transport/BUILD index 865b0c26ef..08b2fd3332 100644 --- a/test/core/transport/BUILD +++ b/test/core/transport/BUILD @@ -65,6 +65,13 @@ cc_test( ) cc_test( + name = "stream_owned_slice_test", + srcs = ["stream_owned_slice_test.c"], + deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], + copts = ['-std=c99'] +) + +cc_test( name = "timeout_encoding_test", srcs = ["timeout_encoding_test.c"], deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"], diff --git a/test/core/transport/stream_owned_slice_test.c b/test/core/transport/stream_owned_slice_test.c new file mode 100644 index 0000000000..97ba1083f3 --- /dev/null +++ b/test/core/transport/stream_owned_slice_test.c @@ -0,0 +1,58 @@ +/* + * + * 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. + * + */ + +#include "src/core/lib/transport/transport.h" + +#include "test/core/util/test_config.h" + +#include <grpc/support/log.h> + +static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + uint8_t buffer[] = "abc123"; + grpc_stream_refcount r; + GRPC_STREAM_REF_INIT(&r, 1, do_nothing, NULL, "test"); + GPR_ASSERT(r.refs.count == 1); + grpc_slice slice = + grpc_slice_from_stream_owned_buffer(&r, buffer, sizeof(buffer)); + GPR_ASSERT(GRPC_SLICE_START_PTR(slice) == buffer); + GPR_ASSERT(GRPC_SLICE_LENGTH(slice) == sizeof(buffer)); + GPR_ASSERT(r.refs.count == 2); + grpc_slice_unref(slice); + GPR_ASSERT(r.refs.count == 1); + + return 0; +} diff --git a/test/core/util/BUILD b/test/core/util/BUILD index 5c90f1db44..e6d0d247db 100644 --- a/test/core/util/BUILD +++ b/test/core/util/BUILD @@ -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", diff --git a/test/core/util/port_uv.c b/test/core/util/port.c index 0c9c0d87d6..da1ed4e052 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 @@ 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 */ diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c deleted file mode 100644 index 4a42e4c702..0000000000 --- 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 f7d723a7d2..38054dd1e7 100644 --- a/test/core/util/port_server_client.c +++ b/test/core/util/port_server_client.c @@ -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; @@ -162,6 +162,15 @@ static void got_port_from_server(grpc_exec_ctx *exec_ctx, void *arg, if (failed) { grpc_httpcli_request req; memset(&req, 0, sizeof(req)); + if (pr->retries >= 5) { + gpr_mu_lock(pr->mu); + pr->port = 0; + GRPC_LOG_IF_ERROR( + "pollset_kick", + grpc_pollset_kick(grpc_polling_entity_pollset(&pr->pops), NULL)); + gpr_mu_unlock(pr->mu); + return; + } GPR_ASSERT(pr->retries < 10); gpr_sleep_until(gpr_time_add( gpr_now(GPR_CLOCK_REALTIME), @@ -198,7 +207,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 +224,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); diff --git a/test/core/util/port_server_client.h b/test/core/util/port_server_client.h index 437006495c..70471ecb8a 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 0c50a46644..0000000000 --- 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 */ |