diff options
Diffstat (limited to 'test/core')
72 files changed, 1517 insertions, 699 deletions
diff --git a/test/core/census/BUILD b/test/core/census/BUILD new file mode 100644 index 0000000000..49680ab91f --- /dev/null +++ b/test/core/census/BUILD @@ -0,0 +1,93 @@ +# Copyright 2016, 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. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "context_test", + srcs = ["context_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "mlog_test", + srcs = ["mlog_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "resource_test", + srcs = ["resource_test.c"], + copts = ["-std=c99"], + data = [ + ":data/resource_empty_name.pb", + ":data/resource_full.pb", + ":data/resource_minimal_good.pb", + ":data/resource_no_name.pb", + ":data/resource_no_numerator.pb", + ":data/resource_no_unit.pb", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "trace_context_test", + srcs = ["trace_context_test.c"], + copts = ["-std=c99"], + data = [ + ":data/context_empty.pb", + ":data/context_full.pb", + ":data/context_no_span_options.pb", + ":data/context_span_only.pb", + ":data/context_trace_only.pb", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/channel/BUILD b/test/core/channel/BUILD new file mode 100644 index 0000000000..c6590465f1 --- /dev/null +++ b/test/core/channel/BUILD @@ -0,0 +1,54 @@ +# Copyright 2016, 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. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "channel_args_test", + srcs = ["channel_args_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "channel_stack_test", + srcs = ["channel_stack_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 76bb57346c..af551c4928 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -68,7 +68,7 @@ static void channel_destroy_func(grpc_exec_ctx *exec_ctx, static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_final_info *final_info, - void *ignored) { + grpc_closure *ignored) { ++*(int *)(elem->channel_data); } @@ -139,10 +139,16 @@ static void test_create_channel_stack(void) { GPR_ASSERT(*channel_data == 0); call_stack = gpr_malloc(channel_stack->call_stack_size); - grpc_error *error = - grpc_call_stack_init(&exec_ctx, channel_stack, 1, free_call, call_stack, - NULL, NULL, path, gpr_now(GPR_CLOCK_MONOTONIC), - gpr_inf_future(GPR_CLOCK_MONOTONIC), call_stack); + const grpc_call_element_args args = { + .call_stack = call_stack, + .server_transport_data = NULL, + .context = NULL, + .path = path, + .start_time = gpr_now(GPR_CLOCK_MONOTONIC), + .deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC), + .arena = NULL}; + grpc_error *error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, + free_call, call_stack, &args); GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(call_stack->count == 1); call_elem = grpc_call_stack_element(call_stack, 0); 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 475b02f6e8..7eeabfbe5d 100644 --- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c @@ -73,7 +73,7 @@ static void my_resolve_address(grpc_exec_ctx *exec_ctx, 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 new file mode 100644 index 0000000000..9ddb4c52b4 --- /dev/null +++ b/test/core/compression/BUILD @@ -0,0 +1,66 @@ +# Copyright 2016, 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. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "algorithm_test", + srcs = ["algorithm_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "compression_test", + srcs = ["compression_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "message_compress_test", + srcs = ["message_compress_test.c"], + copts = ["-std=c99"], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) 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/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index fdfa31b5fb..b351bdee27 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -89,6 +89,8 @@ extern void idempotent_request(grpc_end2end_test_config config); extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); +extern void keepalive_timeout(grpc_end2end_test_config config); +extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); extern void load_reporting_hook(grpc_end2end_test_config config); @@ -168,6 +170,7 @@ void grpc_end2end_tests_pre_init(void) { hpack_size_pre_init(); idempotent_request_pre_init(); invoke_large_request_pre_init(); + keepalive_timeout_pre_init(); large_metadata_pre_init(); load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); @@ -225,6 +228,7 @@ void grpc_end2end_tests(int argc, char **argv, hpack_size(config); idempotent_request(config); invoke_large_request(config); + keepalive_timeout(config); large_metadata(config); load_reporting_hook(config); max_concurrent_streams(config); @@ -343,6 +347,10 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); continue; } + if (0 == strcmp("keepalive_timeout", argv[i])) { + keepalive_timeout(config); + continue; + } if (0 == strcmp("large_metadata", argv[i])) { large_metadata(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index f529d6a899..199c09ec96 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -91,6 +91,8 @@ extern void idempotent_request(grpc_end2end_test_config config); extern void idempotent_request_pre_init(void); extern void invoke_large_request(grpc_end2end_test_config config); extern void invoke_large_request_pre_init(void); +extern void keepalive_timeout(grpc_end2end_test_config config); +extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); extern void load_reporting_hook(grpc_end2end_test_config config); @@ -171,6 +173,7 @@ void grpc_end2end_tests_pre_init(void) { hpack_size_pre_init(); idempotent_request_pre_init(); invoke_large_request_pre_init(); + keepalive_timeout_pre_init(); large_metadata_pre_init(); load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); @@ -229,6 +232,7 @@ void grpc_end2end_tests(int argc, char **argv, hpack_size(config); idempotent_request(config); invoke_large_request(config); + keepalive_timeout(config); large_metadata(config); load_reporting_hook(config); max_concurrent_streams(config); @@ -351,6 +355,10 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); continue; } + if (0 == strcmp("keepalive_timeout", argv[i])) { + keepalive_timeout(config); + continue; + } if (0 == strcmp("large_metadata", argv[i])) { large_metadata(config); continue; diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h index cb0afd9cd9..cdb26a67e9 100644 --- a/test/core/end2end/end2end_tests.h +++ b/test/core/end2end/end2end_tests.h @@ -39,12 +39,15 @@ typedef struct grpc_end2end_test_fixture grpc_end2end_test_fixture; typedef struct grpc_end2end_test_config grpc_end2end_test_config; +/* Test feature flags. */ #define FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION 1 #define FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION 2 #define FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS 4 #define FEATURE_MASK_SUPPORTS_REQUEST_PROXYING 8 #define FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL 16 #define FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER 32 +#define FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER 64 +#define FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE 128 #define FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check" @@ -56,8 +59,12 @@ struct grpc_end2end_test_fixture { }; struct grpc_end2end_test_config { + /* A descriptive name for this test fixture. */ const char *name; + + /* Which features are supported by this fixture. See feature flags above. */ uint32_t feature_mask; + grpc_end2end_test_fixture (*create_fixture)(grpc_channel_args *client_args, grpc_channel_args *server_args); void (*init_client)(grpc_end2end_test_fixture *f, 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 2682ea0e7b..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" @@ -454,7 +454,7 @@ grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(void) { GPR_ASSERT(error == GRPC_ERROR_NONE); GPR_ASSERT(port == proxy_port); // Start server. - proxy->pollset = gpr_malloc(grpc_pollset_size()); + proxy->pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(proxy->pollset, &proxy->mu); grpc_tcp_server_start(&exec_ctx, proxy->server, &proxy->pollset, 1, on_accept, proxy); 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-5834320218423296 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296 Binary files differnew file mode 100644 index 0000000000..65cc6a2209 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5834320218423296 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/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 5071299545..0c749537e6 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -119,6 +119,7 @@ END2END_TESTS = { 'high_initial_seqno': default_test_options, 'idempotent_request': default_test_options, 'invoke_large_request': default_test_options, + 'keepalive_timeout': default_test_options._replace(proxyable=False), 'large_metadata': default_test_options, 'max_concurrent_streams': default_test_options._replace(proxyable=False), 'max_message_length': default_test_options, diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 95c06de73f..431c6995ba 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -106,6 +106,7 @@ END2END_TESTS = { 'high_initial_seqno': test_options(), 'idempotent_request': test_options(), 'invoke_large_request': test_options(), + 'keepalive_timeout': test_options(proxyable=False), 'large_metadata': test_options(), 'max_concurrent_streams': test_options(proxyable=False), 'max_message_length': test_options(), diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index d2d6e82d57..65216cf19d 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -213,7 +213,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_final_info *final_info, - void *and_free_memory) {} + grpc_closure *ignored) {} static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index 25e606556d..c968f30b3b 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -236,7 +236,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, static void destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_final_info *final_info, - void *and_free_memory) {} + grpc_closure *ignored) {} static grpc_error *init_channel_elem(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, diff --git a/test/core/end2end/tests/filter_latency.c b/test/core/end2end/tests/filter_latency.c index d05e9e79a1..2428c92a42 100644 --- a/test/core/end2end/tests/filter_latency.c +++ b/test/core/end2end/tests/filter_latency.c @@ -267,7 +267,7 @@ static grpc_error *init_call_elem(grpc_exec_ctx *exec_ctx, static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_final_info *final_info, - void *and_free_memory) { + grpc_closure *ignored) { gpr_mu_lock(&g_mu); g_client_latency = final_info->stats.latency; gpr_mu_unlock(&g_mu); @@ -276,7 +276,7 @@ static void client_destroy_call_elem(grpc_exec_ctx *exec_ctx, static void server_destroy_call_elem(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, const grpc_call_final_info *final_info, - void *and_free_memory) { + grpc_closure *ignored) { gpr_mu_lock(&g_mu); g_server_latency = final_info->stats.latency; gpr_mu_unlock(&g_mu); diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c new file mode 100644 index 0000000000..4296be3619 --- /dev/null +++ b/test/core/end2end/tests/keepalive_timeout.c @@ -0,0 +1,240 @@ +/* + * + * 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 "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include <grpc/support/useful.h> +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/support/env.h" +#include "test/core/end2end/cq_verifier.h" + +static void *tag(intptr_t t) { return (void *)t; } + +static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, + const char *test_name, + grpc_channel_args *client_args, + grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + gpr_log(GPR_INFO, "%s/%s", test_name, config.name); + f = config.create_fixture(client_args, server_args); + config.init_server(&f, server_args); + config.init_client(&f, client_args); + return f; +} + +static gpr_timespec n_seconds_time(int n) { + return grpc_timeout_seconds_to_deadline(n); +} + +static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } + +static void drain_cq(grpc_completion_queue *cq) { + grpc_event ev; + do { + ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000)); + GPR_ASSERT( + grpc_completion_queue_pluck(f->cq, tag(1000), five_seconds_time(), NULL) + .type == GRPC_OP_COMPLETE); + grpc_server_destroy(f->server); + f->server = NULL; +} + +static void shutdown_client(grpc_end2end_test_fixture *f) { + if (!f->client) return; + grpc_channel_destroy(f->client); + f->client = NULL; +} + +static void end_test(grpc_end2end_test_fixture *f) { + shutdown_server(f); + shutdown_client(f); + + grpc_completion_queue_shutdown(f->cq); + drain_cq(f->cq); + grpc_completion_queue_destroy(f->cq); +} + +/* Client sends a request, server replies with a payload, then waits for the + keepalive watchdog timeouts before returning status. */ +static void test_keepalive_timeout(grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + grpc_slice response_payload_slice = + grpc_slice_from_copied_string("hello world"); + grpc_byte_buffer *response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + + grpc_arg keepalive_args[2]; + keepalive_args[0].type = GRPC_ARG_INTEGER; + keepalive_args[0].key = GRPC_ARG_HTTP2_KEEPALIVE_TIME; + keepalive_args[0].value.integer = 2; + keepalive_args[1].type = GRPC_ARG_INTEGER; + keepalive_args[1].key = GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT; + keepalive_args[1].value.integer = 0; + + grpc_channel_args *client_args = NULL; + client_args = grpc_channel_args_copy_and_add(client_args, keepalive_args, 2); + + grpc_end2end_test_fixture f = + begin_test(config, "keepalive_timeout", client_args, NULL); + cq_verifier *cqv = cq_verifier_create(f.cq); + grpc_op ops[6]; + grpc_op *op; + grpc_metadata_array initial_metadata_recv; + grpc_metadata_array trailing_metadata_recv; + grpc_metadata_array request_metadata_recv; + grpc_byte_buffer *response_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + grpc_slice details; + + c = grpc_channel_create_call( + f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + grpc_slice_from_static_string("/foo"), + get_host_override_slice("foo.test.google.fr:1234", config), deadline, + NULL); + GPR_ASSERT(c); + + grpc_metadata_array_init(&initial_metadata_recv); + grpc_metadata_array_init(&trailing_metadata_recv); + grpc_metadata_array_init(&request_metadata_recv); + grpc_call_details_init(&call_details); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message.recv_message = &response_payload_recv; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( + f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101))); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message.send_message = response_payload; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + cq_verify(cqv); + + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; + op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; + op->data.recv_status_on_client.status = &status; + op->data.recv_status_on_client.status_details = &details; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + cq_verify(cqv); + + char *details_str = grpc_slice_to_c_string(details); + char *method_str = grpc_slice_to_c_string(call_details.method); + GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); + GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout")); + GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); + validate_host_override_string("foo.test.google.fr:1234", call_details.host, + config); + + gpr_free(details_str); + gpr_free(method_str); + + grpc_slice_unref(details); + grpc_metadata_array_destroy(&initial_metadata_recv); + grpc_metadata_array_destroy(&trailing_metadata_recv); + grpc_metadata_array_destroy(&request_metadata_recv); + grpc_call_details_destroy(&call_details); + + grpc_call_destroy(c); + grpc_call_destroy(s); + + cq_verifier_destroy(cqv); + + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(response_payload_recv); + + if (client_args != NULL) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_channel_args_destroy(&exec_ctx, client_args); + grpc_exec_ctx_finish(&exec_ctx); + } + + end_test(&f); + config.tear_down_data(&f); +} + +void keepalive_timeout(grpc_end2end_test_config config) { + test_keepalive_timeout(config); +} + +void keepalive_timeout_pre_init(void) {} diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c index 7540ce93a1..d7a4106459 100644 --- a/test/core/end2end/tests/network_status_change.c +++ b/test/core/end2end/tests/network_status_change.c @@ -240,6 +240,10 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { } void network_status_change(grpc_end2end_test_config config) { + if (config.feature_mask & + FEATURE_MASK_DOES_NOT_SUPPORT_NETWORK_STATUS_CHANGE) { + return; + } test_invoke_network_status_change(config); } diff --git a/test/core/end2end/tests/resource_quota_server.c b/test/core/end2end/tests/resource_quota_server.c index 4f9ed7a3a1..db26b4480e 100644 --- a/test/core/end2end/tests/resource_quota_server.c +++ b/test/core/end2end/tests/resource_quota_server.c @@ -113,6 +113,10 @@ static grpc_slice generate_random_slice() { } void resource_quota_server(grpc_end2end_test_config config) { + if (config.feature_mask & + FEATURE_MASK_DOES_NOT_SUPPORT_RESOURCE_QUOTA_SERVER) { + return; + } grpc_resource_quota *resource_quota = grpc_resource_quota_create("test_server"); grpc_resource_quota_resize(resource_quota, 5 * 1024 * 1024); diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c index 42055907c8..2b9c404b15 100644 --- a/test/core/end2end/tests/streaming_error_response.c +++ b/test/core/end2end/tests/streaming_error_response.c @@ -31,6 +31,9 @@ * */ +/** \file Verify that status ordering rules are obeyed. + \ref doc/status_ordering.md */ + #include "test/core/end2end/end2end_tests.h" #include <stdio.h> 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 new file mode 100644 index 0000000000..eb8f3a9beb --- /dev/null +++ b/test/core/handshake/BUILD @@ -0,0 +1,64 @@ +# 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. + +licenses(["notice"]) # 3-clause BSD + +cc_test( + name = "client_ssl", + srcs = ["client_ssl.c"], + copts = ["-std=c99"], + data = [ + "//src/core/lib/tsi/test_creds:ca.pem", + "//src/core/lib/tsi/test_creds:server1.key", + "//src/core/lib/tsi/test_creds:server1.pem", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +cc_test( + name = "server_ssl", + srcs = ["server_ssl.c"], + copts = ["-std=c99"], + data = [ + "//src/core/lib/tsi/test_creds:ca.pem", + "//src/core/lib/tsi/test_creds:server1.key", + "//src/core/lib/tsi/test_creds:server1.pem", + ], + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c index a5cfd166cb..d3b45c4505 100644 --- a/test/core/http/httpcli_test.c +++ b/test/core/http/httpcli_test.c @@ -202,7 +202,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); grpc_init(); grpc_httpcli_context_init(&g_context); - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &g_mu); g_pops = grpc_polling_entity_create_from_pollset(pollset); diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c index c6a40aed4b..acc94091f4 100644 --- a/test/core/http/httpscli_test.c +++ b/test/core/http/httpscli_test.c @@ -205,7 +205,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); grpc_init(); grpc_httpcli_context_init(&g_context); - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &g_mu); g_pops = grpc_polling_entity_create_from_pollset(pollset); diff --git a/test/core/iomgr/endpoint_pair_test.c b/test/core/iomgr/endpoint_pair_test.c index f02171f2ef..4b98ef257e 100644 --- a/test/core/iomgr/endpoint_pair_test.c +++ b/test/core/iomgr/endpoint_pair_test.c @@ -78,7 +78,7 @@ int main(int argc, char **argv) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_test_init(argc, argv); grpc_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); grpc_endpoint_tests(configs[0], g_pollset, g_mu); grpc_closure_init(&destroyed, destroy_pollset, g_pollset, diff --git a/test/core/iomgr/error_test.c b/test/core/iomgr/error_test.c new file mode 100644 index 0000000000..2a6b1b17fd --- /dev/null +++ b/test/core/iomgr/error_test.c @@ -0,0 +1,219 @@ +/* + * + * 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/iomgr/error.h" + +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/thd.h> +#include <grpc/support/useful.h> + +#include <string.h> + +#include "test/core/util/test_config.h" + +static void test_set_get_int() { + grpc_error* error = GRPC_ERROR_CREATE("Test"); + GPR_ASSERT(error); + intptr_t i = 0; + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_FILE_LINE, &i)); + GPR_ASSERT(i); // line set will never be 0 + GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); + GPR_ASSERT(!grpc_error_get_int(error, GRPC_ERROR_INT_SIZE, &i)); + + intptr_t errnumber = 314; + error = grpc_error_set_int(error, GRPC_ERROR_INT_ERRNO, errnumber); + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); + GPR_ASSERT(i == errnumber); + + intptr_t http = 2; + error = grpc_error_set_int(error, GRPC_ERROR_INT_HTTP2_ERROR, http); + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_HTTP2_ERROR, &i)); + GPR_ASSERT(i == http); + + GRPC_ERROR_UNREF(error); +} + +static void test_set_get_str() { + grpc_error* error = GRPC_ERROR_CREATE("Test"); + + GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL)); + GPR_ASSERT(!grpc_error_get_str(error, GRPC_ERROR_STR_TSI_ERROR)); + + const char* c = grpc_error_get_str(error, GRPC_ERROR_STR_FILE); + GPR_ASSERT(c); + GPR_ASSERT(strstr(c, "error_test.c")); // __FILE__ expands differently on + // Windows. All should at least + // contain error_test.c + + c = grpc_error_get_str(error, GRPC_ERROR_STR_DESCRIPTION); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "Test")); + + error = + grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "longer message"); + c = grpc_error_get_str(error, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "longer message")); + + GRPC_ERROR_UNREF(error); +} + +static void test_copy_and_unref() { + // error1 has one ref + grpc_error* error1 = grpc_error_set_str( + GRPC_ERROR_CREATE("Test"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + const char* c = grpc_error_get_str(error1, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "message")); + + // error 1 has two refs + GRPC_ERROR_REF(error1); + // this gives error3 a ref to the new error, and decrements error1 to one ref + grpc_error* error3 = + grpc_error_set_str(error1, GRPC_ERROR_STR_SYSCALL, "syscall"); + GPR_ASSERT(error3 != error1); // should not be the same because of extra ref + c = grpc_error_get_str(error3, GRPC_ERROR_STR_GRPC_MESSAGE); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "message")); + + // error 1 should not have a syscall but 3 should + GPR_ASSERT(!grpc_error_get_str(error1, GRPC_ERROR_STR_SYSCALL)); + c = grpc_error_get_str(error3, GRPC_ERROR_STR_SYSCALL); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, "syscall")); + + GRPC_ERROR_UNREF(error1); + GRPC_ERROR_UNREF(error3); +} + +static void test_create_referencing() { + grpc_error* child = grpc_error_set_str( + GRPC_ERROR_CREATE("Child"), GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", &child, 1); + GPR_ASSERT(parent); + + GRPC_ERROR_UNREF(child); + GRPC_ERROR_UNREF(parent); +} + +static void test_create_referencing_many() { + grpc_error* children[3]; + children[0] = grpc_error_set_str(GRPC_ERROR_CREATE("Child1"), + GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + children[1] = grpc_error_set_int(GRPC_ERROR_CREATE("Child2"), + GRPC_ERROR_INT_HTTP2_ERROR, 5); + children[2] = grpc_error_set_str(GRPC_ERROR_CREATE("Child3"), + GRPC_ERROR_STR_GRPC_MESSAGE, "message 3"); + + grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", children, 3); + GPR_ASSERT(parent); + + for (size_t i = 0; i < 3; ++i) { + GRPC_ERROR_UNREF(children[i]); + } + GRPC_ERROR_UNREF(parent); +} + +static void print_error_string() { + grpc_error* error = + grpc_error_set_int(GRPC_ERROR_CREATE("Error"), GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNIMPLEMENTED); + error = grpc_error_set_int(error, GRPC_ERROR_INT_SIZE, 666); + error = grpc_error_set_str(error, GRPC_ERROR_STR_GRPC_MESSAGE, "message"); + // gpr_log(GPR_DEBUG, "%s", grpc_error_string(error)); + GRPC_ERROR_UNREF(error); +} + +static void print_error_string_reference() { + grpc_error* children[2]; + children[0] = grpc_error_set_str( + grpc_error_set_int(GRPC_ERROR_CREATE("1"), GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_UNIMPLEMENTED), + GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 1"); + children[1] = grpc_error_set_str( + grpc_error_set_int(GRPC_ERROR_CREATE("2sd"), GRPC_ERROR_INT_GRPC_STATUS, + GRPC_STATUS_INTERNAL), + GRPC_ERROR_STR_GRPC_MESSAGE, "message for child 2"); + + grpc_error* parent = GRPC_ERROR_CREATE_REFERENCING("Parent", children, 2); + + gpr_log(GPR_DEBUG, "%s", grpc_error_string(parent)); + + for (size_t i = 0; i < 2; ++i) { + GRPC_ERROR_UNREF(children[i]); + } + GRPC_ERROR_UNREF(parent); +} + +static void test_os_error() { + int fake_errno = 5; + const char* syscall = "syscall name"; + grpc_error* error = GRPC_OS_ERROR(fake_errno, syscall); + + intptr_t i = 0; + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_ERRNO, &i)); + GPR_ASSERT(i == fake_errno); + + const char* c = grpc_error_get_str(error, GRPC_ERROR_STR_SYSCALL); + GPR_ASSERT(c); + GPR_ASSERT(!strcmp(c, syscall)); + GRPC_ERROR_UNREF(error); +} + +static void test_special() { + grpc_error* error = GRPC_ERROR_NONE; + error = grpc_error_add_child(error, GRPC_ERROR_CREATE("test child")); + intptr_t i; + GPR_ASSERT(grpc_error_get_int(error, GRPC_ERROR_INT_GRPC_STATUS, &i)); + GPR_ASSERT(i == GRPC_STATUS_OK); + GRPC_ERROR_UNREF(error); +} + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + grpc_init(); + test_set_get_int(); + test_set_get_str(); + test_copy_and_unref(); + print_error_string(); + print_error_string_reference(); + test_os_error(); + test_create_referencing(); + test_create_referencing_many(); + test_special(); + grpc_shutdown(); + + return 0; +} diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c index 5b05ea3338..4ec959995b 100644 --- a/test/core/iomgr/ev_epoll_linux_test.c +++ b/test/core/iomgr/ev_epoll_linux_test.c @@ -104,7 +104,7 @@ static void test_fd_cleanup(grpc_exec_ctx *exec_ctx, test_fd *tfds, static void test_pollset_init(test_pollset *pollsets, int num_pollsets) { int i; for (i = 0; i < num_pollsets; i++) { - pollsets[i].pollset = gpr_malloc(grpc_pollset_size()); + pollsets[i].pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollsets[i].pollset, &pollsets[i].mu); } } diff --git a/test/core/iomgr/fd_posix_test.c b/test/core/iomgr/fd_posix_test.c index 4726e935d8..c1a0ef54d3 100644 --- a/test/core/iomgr/fd_posix_test.c +++ b/test/core/iomgr/fd_posix_test.c @@ -543,7 +543,7 @@ int main(int argc, char **argv) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_test_init(argc, argv); grpc_iomgr_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); test_grpc_fd(); test_grpc_fd_change(); diff --git a/test/core/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c index e7777acce1..f27e9db8c9 100644 --- a/test/core/iomgr/pollset_set_test.c +++ b/test/core/iomgr/pollset_set_test.c @@ -79,7 +79,7 @@ typedef struct test_pollset { static void init_test_pollsets(test_pollset *pollsets, const int num_pollsets) { for (int i = 0; i < num_pollsets; i++) { - pollsets[i].ps = gpr_malloc(grpc_pollset_size()); + pollsets[i].ps = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollsets[i].ps, &pollsets[i].mu); } } diff --git a/test/core/iomgr/resolve_address_posix_test.c b/test/core/iomgr/resolve_address_posix_test.c index ef4cfdf06f..fa88aca431 100644 --- a/test/core/iomgr/resolve_address_posix_test.c +++ b/test/core/iomgr/resolve_address_posix_test.c @@ -63,7 +63,7 @@ static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} void args_init(grpc_exec_ctx *exec_ctx, args_struct *args) { gpr_event_init(&args->ev); - args->pollset = gpr_malloc(grpc_pollset_size()); + args->pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(args->pollset, &args->mu); args->pollset_set = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(exec_ctx, args->pollset_set, args->pollset); diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index 3b79ef4e65..ea79adc090 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -57,7 +57,7 @@ static void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} void args_init(grpc_exec_ctx *exec_ctx, args_struct *args) { gpr_event_init(&args->ev); - args->pollset = gpr_malloc(grpc_pollset_size()); + args->pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(args->pollset, &args->mu); args->pollset_set = grpc_pollset_set_create(); grpc_pollset_set_add_pollset(exec_ctx, args->pollset_set, args->pollset); 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_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c index c767f63f0c..b324b5a65e 100644 --- a/test/core/iomgr/tcp_client_posix_test.c +++ b/test/core/iomgr/tcp_client_posix_test.c @@ -205,7 +205,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); grpc_init(); g_pollset_set = grpc_pollset_set_create(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); grpc_pollset_set_add_pollset(&exec_ctx, g_pollset_set, g_pollset); grpc_exec_ctx_finish(&exec_ctx); diff --git a/test/core/iomgr/tcp_client_uv_test.c b/test/core/iomgr/tcp_client_uv_test.c index f8938d0abb..064119f11b 100644 --- a/test/core/iomgr/tcp_client_uv_test.c +++ b/test/core/iomgr/tcp_client_uv_test.c @@ -58,7 +58,7 @@ static int g_connections_complete = 0; static grpc_endpoint *g_connecting = NULL; static gpr_timespec test_deadline(void) { - return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); + return grpc_timeout_seconds_to_deadline(10); } static void finish_connection() { @@ -73,7 +73,8 @@ static void must_succeed(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { GPR_ASSERT(g_connecting != NULL); GPR_ASSERT(error == GRPC_ERROR_NONE); - grpc_endpoint_shutdown(exec_ctx, g_connecting); + grpc_endpoint_shutdown(exec_ctx, g_connecting, + GRPC_ERROR_CREATE("must_succeed called")); grpc_endpoint_destroy(exec_ctx, g_connecting); g_connecting = NULL; finish_connection(); @@ -133,7 +134,7 @@ void test_succeeds(void) { "pollset_work", grpc_pollset_work(&exec_ctx, g_pollset, &worker, gpr_now(GPR_CLOCK_MONOTONIC), - GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)))); + grpc_timeout_seconds_to_deadline(5)))); gpr_mu_unlock(g_mu); grpc_exec_ctx_flush(&exec_ctx); gpr_mu_lock(g_mu); diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c index 99ecd581c6..5a55be888f 100644 --- a/test/core/iomgr/tcp_posix_test.c +++ b/test/core/iomgr/tcp_posix_test.c @@ -561,7 +561,7 @@ int main(int argc, char **argv) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_test_init(argc, argv); grpc_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); grpc_endpoint_tests(configs[0], g_pollset, g_mu); run_tests(); diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index 4a6570015f..6e514324a5 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -454,10 +454,11 @@ 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_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); test_no_op(); @@ -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/iomgr/tcp_server_uv_test.c b/test/core/iomgr/tcp_server_uv_test.c index 7b458c90f3..0fc74599ea 100644 --- a/test/core/iomgr/tcp_server_uv_test.c +++ b/test/core/iomgr/tcp_server_uv_test.c @@ -115,7 +115,7 @@ static void server_weak_ref_set(server_weak_ref *weak_ref, static void on_connect(grpc_exec_ctx *exec_ctx, void *arg, grpc_endpoint *tcp, grpc_pollset *pollset, grpc_tcp_server_acceptor *acceptor) { - grpc_endpoint_shutdown(exec_ctx, tcp); + grpc_endpoint_shutdown(exec_ctx, tcp, GRPC_ERROR_CREATE("Connected")); grpc_endpoint_destroy(exec_ctx, tcp); on_connect_result temp_result; @@ -203,7 +203,7 @@ static void close_cb(uv_handle_t *handle) { gpr_free(handle); } static void tcp_connect(grpc_exec_ctx *exec_ctx, const struct sockaddr *remote, socklen_t remote_len, on_connect_result *result) { - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); + gpr_timespec deadline = grpc_timeout_seconds_to_deadline(10); uv_tcp_t *client_handle = gpr_malloc(sizeof(uv_tcp_t)); uv_connect_t *req = gpr_malloc(sizeof(uv_connect_t)); int nconnects_before; diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index ba572017a2..396ec959cd 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -62,8 +62,7 @@ static int g_number_of_writes = 0; static int g_number_of_bytes_read = 0; static int g_number_of_orphan_calls = 0; -static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, - grpc_server *server) { +static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) { char read_buffer[512]; ssize_t byte_count; @@ -79,7 +78,7 @@ static void on_read(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, gpr_mu_unlock(g_mu); } -static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) { +static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) { gpr_mu_lock(g_mu); g_number_of_writes++; @@ -88,7 +87,8 @@ static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) { gpr_mu_unlock(g_mu); } -static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) { +static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, + void *user_data) { gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d", grpc_fd_wrapped_fd(emfd)); g_number_of_orphan_calls++; @@ -237,7 +237,7 @@ int main(int argc, char **argv) { grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; grpc_test_init(argc, argv); grpc_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); test_no_op(); diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c index 09f0e2d867..107abbc1b3 100644 --- a/test/core/memory_usage/client.c +++ b/test/core/memory_usage/client.c @@ -43,6 +43,7 @@ #include <grpc/support/log.h> #include <grpc/support/time.h> #include <grpc/support/useful.h> +#include "src/core/lib/support/env.h" #include "src/core/lib/support/string.h" #include "test/core/util/memory_counters.h" #include "test/core/util/test_config.h" @@ -310,6 +311,29 @@ int main(int argc, char **argv) { server_calls_end.total_size_relative - after_server_create.total_size_relative); + const char *csv_file = "memory_usage.csv"; + FILE *csv = fopen(csv_file, "w"); + if (csv) { + char *env_build = gpr_getenv("BUILD_NUMBER"); + char *env_job = gpr_getenv("JOB_NAME"); + fprintf(csv, "%f,%zi,%zi,%f,%zi,%s,%s\n", + (double)(client_calls_inflight.total_size_relative - + client_benchmark_calls_start.total_size_relative) / + benchmark_iterations, + client_channel_end.total_size_relative - + client_channel_start.total_size_relative, + after_server_create.total_size_relative - + before_server_create.total_size_relative, + (double)(server_calls_inflight.total_size_relative - + server_benchmark_calls_start.total_size_relative) / + benchmark_iterations, + server_calls_end.total_size_relative - + after_server_create.total_size_relative, + env_build == NULL ? "" : env_build, env_job == NULL ? "" : env_job); + fclose(csv); + gpr_log(GPR_INFO, "Summary written to %s", csv_file); + } + grpc_memory_counters_destroy(); return 0; } diff --git a/test/core/security/BUILD b/test/core/security/BUILD index e750c39b7c..1cb03c5cfe 100644 --- a/test/core/security/BUILD +++ b/test/core/security/BUILD @@ -34,7 +34,7 @@ load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") grpc_fuzzer( name = "ssl_server_fuzzer", srcs = ["ssl_server_fuzzer.c"], - deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util"], + deps = ["//:gpr", "//:grpc", "//test/core/util:grpc_test_util", "//test/core/end2end:ssl_test_data"], corpus = "corpus", copts = ["-std=c99"], ) diff --git a/test/core/security/oauth2_utils.c b/test/core/security/oauth2_utils.c index ff77af908a..f0550db1d0 100644 --- a/test/core/security/oauth2_utils.c +++ b/test/core/security/oauth2_utils.c @@ -87,7 +87,7 @@ char *grpc_test_fetch_oauth2_token_with_credentials( grpc_closure do_nothing_closure; grpc_auth_metadata_context null_ctx = {"", "", NULL, NULL}; - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &request.mu); request.pops = grpc_polling_entity_create_from_pollset(pollset); request.is_done = 0; diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c index ea136fbdcf..b6421f19ab 100644 --- a/test/core/security/print_google_default_creds_token.c +++ b/test/core/security/print_google_default_creds_token.c @@ -98,7 +98,7 @@ int main(int argc, char **argv) { goto end; } - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &sync.mu); sync.pops = grpc_polling_entity_create_from_pollset(pollset); sync.is_done = 0; diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c index 97e9c3d6db..d2b76bae39 100644 --- a/test/core/security/secure_endpoint_test.c +++ b/test/core/security/secure_endpoint_test.c @@ -190,7 +190,7 @@ int main(int argc, char **argv) { grpc_test_init(argc, argv); grpc_init(); - g_pollset = gpr_malloc(grpc_pollset_size()); + g_pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(g_pollset, &g_mu); grpc_endpoint_tests(configs[0], g_pollset, g_mu); test_leftover(configs[1], 1); diff --git a/test/core/security/ssl_server_fuzzer.c b/test/core/security/ssl_server_fuzzer.c index f789278add..7a3612c419 100644 --- a/test/core/security/ssl_server_fuzzer.c +++ b/test/core/security/ssl_server_fuzzer.c @@ -38,6 +38,7 @@ #include "src/core/lib/iomgr/load_file.h" #include "src/core/lib/security/credentials/credentials.h" #include "src/core/lib/security/transport/security_connector.h" +#include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/memory_counters.h" #include "test/core/util/mock_endpoint.h" @@ -46,10 +47,6 @@ bool squelch = true; // Turning this on will fail the leak check. bool leak_check = false; -#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem" -#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key" -#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem" - static void discard_write(grpc_slice slice) {} static void dont_log(gpr_log_func_args *args) {} @@ -88,12 +85,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { // Load key pair and establish server SSL credentials. grpc_ssl_pem_key_cert_pair pem_key_cert_pair; grpc_slice ca_slice, cert_slice, key_slice; - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(SSL_CA_PATH, 1, &ca_slice))); - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(SSL_CERT_PATH, 1, &cert_slice))); - GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file", - grpc_load_file(SSL_KEY_PATH, 1, &key_slice))); + ca_slice = grpc_slice_from_static_string(test_root_cert); + cert_slice = grpc_slice_from_static_string(test_server1_cert); + key_slice = grpc_slice_from_static_string(test_server1_key); const char *ca_cert = (const char *)GRPC_SLICE_START_PTR(ca_slice); pem_key_cert_pair.private_key = (const char *)GRPC_SLICE_START_PTR(key_slice); pem_key_cert_pair.cert_chain = (const char *)GRPC_SLICE_START_PTR(cert_slice); diff --git a/test/core/security/verify_jwt.c b/test/core/security/verify_jwt.c index aaf0e7f6b1..f8a7d64809 100644 --- a/test/core/security/verify_jwt.c +++ b/test/core/security/verify_jwt.c @@ -106,7 +106,7 @@ int main(int argc, char **argv) { grpc_init(); - sync.pollset = gpr_malloc(grpc_pollset_size()); + sync.pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(sync.pollset, &sync.mu); sync.is_done = 0; 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 dfe952eb37..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"], @@ -119,6 +121,13 @@ cc_test( ) cc_test( + name = "spinlock_test", + srcs = ["spinlock_test.c"], + deps = ["//:gpr", "//test/core/util:gpr_test_util"], + copts = ['-std=c99'] +) + +cc_test( name = "sync_test", srcs = ["sync_test.c"], deps = ["//:gpr", "//test/core/util:gpr_test_util"], diff --git a/test/core/support/alloc_test.c b/test/core/support/alloc_test.c index 451c580054..72e99de867 100644 --- a/test/core/support/alloc_test.c +++ b/test/core/support/alloc_test.c @@ -47,7 +47,7 @@ static void test_custom_allocs() { const gpr_allocation_functions default_fns = gpr_get_allocation_functions(); intptr_t addr_to_free = 0; char *i; - gpr_allocation_functions fns = {fake_malloc, fake_realloc, fake_free}; + gpr_allocation_functions fns = {fake_malloc, NULL, fake_realloc, fake_free}; gpr_set_allocation_functions(fns); GPR_ASSERT((void *)(size_t)0xdeadbeef == gpr_malloc(0xdeadbeef)); diff --git a/test/core/support/arena_test.c b/test/core/support/arena_test.c new file mode 100644 index 0000000000..35b2bbd1b1 --- /dev/null +++ b/test/core/support/arena_test.c @@ -0,0 +1,139 @@ +/* + * + * 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/support/arena.h" + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/useful.h> +#include <inttypes.h> +#include <string.h> + +#include "src/core/lib/support/string.h" +#include "test/core/util/test_config.h" + +static void test_noop(void) { gpr_arena_destroy(gpr_arena_create(1)); } + +static void test(const char *name, size_t init_size, const size_t *allocs, + size_t nallocs) { + gpr_strvec v; + char *s; + gpr_strvec_init(&v); + gpr_asprintf(&s, "test '%s': %" PRIdPTR " <- {", name, init_size); + gpr_strvec_add(&v, s); + for (size_t i = 0; i < nallocs; i++) { + gpr_asprintf(&s, "%" PRIdPTR ",", allocs[i]); + gpr_strvec_add(&v, s); + } + gpr_strvec_add(&v, gpr_strdup("}")); + s = gpr_strvec_flatten(&v, NULL); + gpr_strvec_destroy(&v); + gpr_log(GPR_INFO, "%s", s); + gpr_free(s); + + gpr_arena *a = gpr_arena_create(init_size); + void **ps = gpr_zalloc(sizeof(*ps) * nallocs); + for (size_t i = 0; i < nallocs; i++) { + ps[i] = gpr_arena_alloc(a, allocs[i]); + // ensure no duplicate results + for (size_t j = 0; j < i; j++) { + GPR_ASSERT(ps[i] != ps[j]); + } + // ensure writable + memset(ps[i], 1, allocs[i]); + } + gpr_arena_destroy(a); + gpr_free(ps); +} + +#define TEST(name, init_size, ...) \ + static const size_t allocs_##name[] = {__VA_ARGS__}; \ + test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name)) + +#define CONCURRENT_TEST_ITERATIONS 100000 +#define CONCURRENT_TEST_THREADS 100 + +typedef struct { + gpr_event ev_start; + gpr_arena *arena; +} concurrent_test_args; + +static void concurrent_test_body(void *arg) { + concurrent_test_args *a = arg; + gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME)); + for (size_t i = 0; i < CONCURRENT_TEST_ITERATIONS; i++) { + *(char *)gpr_arena_alloc(a->arena, 1) = (char)i; + } +} + +static void concurrent_test(void) { + gpr_log(GPR_DEBUG, "concurrent_test"); + + concurrent_test_args args; + gpr_event_init(&args.ev_start); + args.arena = gpr_arena_create(1024); + + gpr_thd_id thds[CONCURRENT_TEST_THREADS]; + + for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { + gpr_thd_options opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + gpr_thd_new(&thds[i], concurrent_test_body, &args, &opt); + } + + gpr_event_set(&args.ev_start, (void *)1); + + for (int i = 0; i < CONCURRENT_TEST_THREADS; i++) { + gpr_thd_join(thds[i]); + } + + gpr_arena_destroy(args.arena); +} + +int main(int argc, char *argv[]) { + grpc_test_init(argc, argv); + + test_noop(); + TEST(0_1, 0, 1); + TEST(1_1, 1, 1); + TEST(1_2, 1, 2); + TEST(1_3, 1, 3); + TEST(1_inc, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11); + TEST(6_123, 6, 1, 2, 3); + concurrent_test(); + + return 0; +} diff --git a/test/core/support/cpu_test.c b/test/core/support/cpu_test.c index ca0fe0ccb5..7b9bf6c5e1 100644 --- a/test/core/support/cpu_test.c +++ b/test/core/support/cpu_test.c @@ -81,9 +81,12 @@ static void worker_thread(void *arg) { uint32_t cpu; unsigned r = 12345678; unsigned i, j; - for (i = 0; i < 1000 / grpc_test_slowdown_factor(); i++) { + /* Avoid repetitive division calculations */ + int64_t max_i = 1000 / grpc_test_slowdown_factor(); + int64_t max_j = 1000000 / grpc_test_slowdown_factor(); + for (i = 0; i < max_i; i++) { /* run for a bit - just calculate something random. */ - for (j = 0; j < 1000000 / grpc_test_slowdown_factor(); j++) { + for (j = 0; j < max_j; j++) { r = (r * 17) & ((r - i) | (r * i)); } cpu = gpr_cpu_current_cpu(); diff --git a/test/core/support/spinlock_test.c b/test/core/support/spinlock_test.c new file mode 100644 index 0000000000..c70e76c7ea --- /dev/null +++ b/test/core/support/spinlock_test.c @@ -0,0 +1,161 @@ +/* + * + * 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. + * + */ + +/* Test of gpr synchronization support. */ + +#include "src/core/lib/support/spinlock.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/time.h> +#include <stdio.h> +#include <stdlib.h> +#include "test/core/util/test_config.h" + +/* ------------------------------------------------- */ +/* Tests for gpr_spinlock. */ +struct test { + int thread_count; /* number of threads */ + gpr_thd_id *threads; + + int64_t iterations; /* number of iterations per thread */ + int64_t counter; + int incr_step; /* how much to increment/decrement refcount each time */ + + gpr_spinlock mu; /* protects iterations, counter */ +}; + +/* Return pointer to a new struct test. */ +static struct test *test_new(int threads, int64_t iterations, int incr_step) { + struct test *m = gpr_malloc(sizeof(*m)); + m->thread_count = threads; + m->threads = gpr_malloc(sizeof(*m->threads) * (size_t)threads); + m->iterations = iterations; + m->counter = 0; + m->thread_count = 0; + m->incr_step = incr_step; + m->mu = GPR_SPINLOCK_INITIALIZER; + return m; +} + +/* Return pointer to a new struct test. */ +static void test_destroy(struct test *m) { + gpr_free(m->threads); + gpr_free(m); +} + +/* Create m->threads threads, each running (*body)(m) */ +static void test_create_threads(struct test *m, void (*body)(void *arg)) { + int i; + for (i = 0; i != m->thread_count; i++) { + gpr_thd_options opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + GPR_ASSERT(gpr_thd_new(&m->threads[i], body, m, &opt)); + } +} + +/* Wait until all threads report done. */ +static void test_wait(struct test *m) { + int i; + for (i = 0; i != m->thread_count; i++) { + gpr_thd_join(m->threads[i]); + } +} + +/* Test several threads running (*body)(struct test *m) for increasing settings + of m->iterations, until about timeout_s to 2*timeout_s seconds have elapsed. + If extra!=NULL, run (*extra)(m) in an additional thread. + incr_step controls by how much m->refcount should be incremented/decremented + (if at all) each time in the tests. + */ +static void test(const char *name, void (*body)(void *m), int timeout_s, + int incr_step) { + int64_t iterations = 1024; + struct test *m; + gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); + gpr_timespec time_taken; + gpr_timespec deadline = gpr_time_add( + start, gpr_time_from_micros((int64_t)timeout_s * 1000000, GPR_TIMESPAN)); + fprintf(stderr, "%s:", name); + while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0) { + iterations <<= 1; + fprintf(stderr, " %ld", (long)iterations); + m = test_new(10, iterations, incr_step); + test_create_threads(m, body); + test_wait(m); + if (m->counter != m->thread_count * m->iterations * m->incr_step) { + fprintf(stderr, "counter %ld threads %d iterations %ld\n", + (long)m->counter, m->thread_count, (long)m->iterations); + GPR_ASSERT(0); + } + test_destroy(m); + } + time_taken = gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start); + fprintf(stderr, " done %lld.%09d s\n", (long long)time_taken.tv_sec, + (int)time_taken.tv_nsec); +} + +/* Increment m->counter on each iteration; then mark thread as done. */ +static void inc(void *v /*=m*/) { + struct test *m = v; + int64_t i; + for (i = 0; i != m->iterations; i++) { + gpr_spinlock_lock(&m->mu); + m->counter++; + gpr_spinlock_unlock(&m->mu); + } +} + +/* Increment m->counter under lock acquired with trylock, m->iterations times; + then mark thread as done. */ +static void inctry(void *v /*=m*/) { + struct test *m = v; + int64_t i; + for (i = 0; i != m->iterations;) { + if (gpr_spinlock_trylock(&m->mu)) { + m->counter++; + gpr_spinlock_unlock(&m->mu); + i++; + } + } +} + +/* ------------------------------------------------- */ + +int main(int argc, char *argv[]) { + grpc_test_init(argc, argv); + test("spinlock", &inc, 1, 1); + test("spinlock try", &inctry, 1, 1); + return 0; +} 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/surface/concurrent_connectivity_test.c b/test/core/surface/concurrent_connectivity_test.c index 4f7a25ab93..ff927385d4 100644 --- a/test/core/surface/concurrent_connectivity_test.c +++ b/test/core/surface/concurrent_connectivity_test.c @@ -215,7 +215,7 @@ int main(int argc, char **argv) { /* Third round, bogus tcp server */ gpr_log(GPR_DEBUG, "Wave 3"); - args.pollset = gpr_malloc(grpc_pollset_size()); + args.pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(args.pollset, &args.mu); gpr_event_init(&args.ready); gpr_thd_new(&server, bad_server_thread, &args, &options); 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/memory_counters.c b/test/core/util/memory_counters.c index fd6770bd49..c27065f260 100644 --- a/test/core/util/memory_counters.c +++ b/test/core/util/memory_counters.c @@ -46,17 +46,23 @@ static void *guard_malloc(size_t size); static void *guard_realloc(void *vptr, size_t size); static void guard_free(void *vptr); +#ifdef GPR_LOW_LEVEL_COUNTERS +/* hide these from the microbenchmark atomic stats */ +#define NO_BARRIER_FETCH_ADD(x, sz) \ + __atomic_fetch_add((x), (sz), __ATOMIC_RELAXED) +#define NO_BARRIER_LOAD(x) __atomic_load_n((x), __ATOMIC_RELAXED) +#else +#define NO_BARRIER_FETCH_ADD(x, sz) gpr_atm_no_barrier_fetch_add(x, sz) +#define NO_BARRIER_LOAD(x) gpr_atm_no_barrier_load(x) +#endif + static void *guard_malloc(size_t size) { size_t *ptr; if (!size) return NULL; - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute, - (gpr_atm)size); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative, - (gpr_atm)size); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute, - (gpr_atm)1); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative, - (gpr_atm)1); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, (gpr_atm)1); ptr = g_old_allocs.malloc_fn(size + sizeof(size)); *ptr++ = size; return ptr; @@ -72,14 +78,10 @@ static void *guard_realloc(void *vptr, size_t size) { return NULL; } --ptr; - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_absolute, - (gpr_atm)size); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative, - -(gpr_atm)*ptr); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative, - (gpr_atm)size); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_absolute, - (gpr_atm)1); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_absolute, (gpr_atm)size); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, (gpr_atm)size); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_absolute, (gpr_atm)1); ptr = g_old_allocs.realloc_fn(ptr, size + sizeof(size)); *ptr++ = size; return ptr; @@ -89,15 +91,13 @@ static void guard_free(void *vptr) { size_t *ptr = vptr; if (!vptr) return; --ptr; - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_size_relative, - -(gpr_atm)*ptr); - gpr_atm_no_barrier_fetch_add(&g_memory_counters.total_allocs_relative, - -(gpr_atm)1); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_size_relative, -(gpr_atm)*ptr); + NO_BARRIER_FETCH_ADD(&g_memory_counters.total_allocs_relative, -(gpr_atm)1); g_old_allocs.free_fn(ptr); } -struct gpr_allocation_functions g_guard_allocs = {guard_malloc, guard_realloc, - guard_free}; +struct gpr_allocation_functions g_guard_allocs = {guard_malloc, NULL, + guard_realloc, guard_free}; void grpc_memory_counters_init() { memset(&g_memory_counters, 0, sizeof(g_memory_counters)); @@ -112,12 +112,12 @@ void grpc_memory_counters_destroy() { struct grpc_memory_counters grpc_memory_counters_snapshot() { struct grpc_memory_counters counters; counters.total_size_relative = - gpr_atm_no_barrier_load(&g_memory_counters.total_size_relative); + NO_BARRIER_LOAD(&g_memory_counters.total_size_relative); counters.total_size_absolute = - gpr_atm_no_barrier_load(&g_memory_counters.total_size_absolute); + NO_BARRIER_LOAD(&g_memory_counters.total_size_absolute); counters.total_allocs_relative = - gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_relative); + NO_BARRIER_LOAD(&g_memory_counters.total_allocs_relative); counters.total_allocs_absolute = - gpr_atm_no_barrier_load(&g_memory_counters.total_allocs_absolute); + NO_BARRIER_LOAD(&g_memory_counters.total_allocs_absolute); return counters; } 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 7b733ab9c7..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; @@ -89,13 +89,13 @@ void grpc_free_port_using_server(char *server, int port) { memset(&req, 0, sizeof(req)); memset(&rsp, 0, sizeof(rsp)); - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &pr.mu); pr.pops = grpc_polling_entity_create_from_pollset(pollset); 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; @@ -209,16 +218,16 @@ int grpc_pick_port_using_server(char *server) { memset(&pr, 0, sizeof(pr)); memset(&req, 0, sizeof(req)); - grpc_pollset *pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset *pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(pollset, &pr.mu); pr.pops = grpc_polling_entity_create_from_pollset(pollset); 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 */ diff --git a/test/core/util/test_tcp_server.c b/test/core/util/test_tcp_server.c index 2338b81ab1..496e579bc3 100644 --- a/test/core/util/test_tcp_server.c +++ b/test/core/util/test_tcp_server.c @@ -60,7 +60,7 @@ void test_tcp_server_init(test_tcp_server *server, grpc_closure_init(&server->shutdown_complete, on_server_destroyed, server, grpc_schedule_on_exec_ctx); server->shutdown = 0; - server->pollset = gpr_malloc(grpc_pollset_size()); + server->pollset = gpr_zalloc(grpc_pollset_size()); grpc_pollset_init(server->pollset, &server->mu); server->on_connect = on_connect; server->cb_data = user_data; diff --git a/test/core/util/trickle_endpoint.c b/test/core/util/trickle_endpoint.c index 7ab0488a66..0848147158 100644 --- a/test/core/util/trickle_endpoint.c +++ b/test/core/util/trickle_endpoint.c @@ -31,6 +31,8 @@ * */ +#include "src/core/lib/iomgr/sockaddr.h" + #include "test/core/util/passthru_endpoint.h" #include <inttypes.h> @@ -40,9 +42,6 @@ #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/useful.h> - -#include "src/core/lib/iomgr/sockaddr.h" - #include "src/core/lib/slice/slice_internal.h" typedef struct { |