aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/core
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2017-04-18 13:23:44 -0700
committerGravatar Craig Tiller <ctiller@google.com>2017-04-18 13:23:44 -0700
commita12c0657ef79a436db540ad0bfc5660aa7b88d08 (patch)
tree29211b259900fe730a6cdad595f16c94f09241ab /test/core
parentc3666d70902ff7b9c1735761d7156232e84ef4e4 (diff)
parent6b4435ccbcd12e29cd318389126457f7bc7bdcab (diff)
Merge github.com:grpc/grpc into hybrid
Diffstat (limited to 'test/core')
-rw-r--r--test/core/client_channel/parse_address_test.c26
-rw-r--r--test/core/client_channel/resolvers/BUILD40
-rw-r--r--test/core/client_channel/resolvers/fake_resolver_test.c187
-rw-r--r--test/core/end2end/BUILD79
-rw-r--r--test/core/end2end/fake_resolver.c211
-rw-r--r--test/core/end2end/fake_resolver.h34
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c3
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672bin0 -> 46 bytes
-rw-r--r--test/core/end2end/fuzzers/hpack.dictionary2
-rw-r--r--test/core/end2end/tests/load_reporting_hook.c22
-rw-r--r--test/core/iomgr/udp_server_test.c14
11 files changed, 453 insertions, 165 deletions
diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c
index 629cdb001f..802e41e5de 100644
--- a/test/core/client_channel/parse_address_test.c
+++ b/test/core/client_channel/parse_address_test.c
@@ -47,12 +47,12 @@
#ifdef GRPC_HAVE_UNIX_SOCKET
-static void test_parse_unix(const char *uri_text, const char *pathname) {
+static void test_grpc_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));
+ GPR_ASSERT(1 == grpc_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));
@@ -63,18 +63,18 @@ static void test_parse_unix(const char *uri_text, const char *pathname) {
#else /* GRPC_HAVE_UNIX_SOCKET */
-static void test_parse_unix(const char *uri_text, const char *pathname) {}
+static void test_grpc_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) {
+static void test_grpc_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));
+ GPR_ASSERT(1 == grpc_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,
@@ -86,14 +86,14 @@ static void test_parse_ipv4(const char *uri_text, const char *host,
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) {
+static void test_grpc_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));
+ GPR_ASSERT(1 == grpc_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,
@@ -109,8 +109,8 @@ static void test_parse_ipv6(const char *uri_text, const char *host,
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);
+ test_grpc_parse_unix("unix:/path/name", "/path/name");
+ test_grpc_parse_ipv4("ipv4:192.0.2.1:12345", "192.0.2.1", 12345);
+ test_grpc_parse_ipv6("ipv6:[2001:db8::1]:12345", "2001:db8::1", 12345, 0);
+ test_grpc_parse_ipv6("ipv6:[2001:db8::1%252]:12345", "2001:db8::1", 12345, 2);
}
diff --git a/test/core/client_channel/resolvers/BUILD b/test/core/client_channel/resolvers/BUILD
index af37072e3a..e8361cdef6 100644
--- a/test/core/client_channel/resolvers/BUILD
+++ b/test/core/client_channel/resolvers/BUILD
@@ -32,20 +32,48 @@ licenses(["notice"]) # 3-clause BSD
cc_test(
name = "dns_resolver_connectivity_test",
srcs = ["dns_resolver_connectivity_test.c"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
- copts = ['-std=c99']
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
cc_test(
name = "dns_resolver_test",
srcs = ["dns_resolver_test.c"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
- copts = ['-std=c99']
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
cc_test(
name = "sockaddr_resolver_test",
srcs = ["sockaddr_resolver_test.c"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
- copts = ['-std=c99']
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+cc_test(
+ name = "fake_resolver_test",
+ srcs = ["fake_resolver_test.c"],
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/end2end:fake_resolver",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
)
diff --git a/test/core/client_channel/resolvers/fake_resolver_test.c b/test/core/client_channel/resolvers/fake_resolver_test.c
new file mode 100644
index 0000000000..861918fbd6
--- /dev/null
+++ b/test/core/client_channel/resolvers/fake_resolver_test.c
@@ -0,0 +1,187 @@
+/*
+ *
+ * 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 <string.h>
+
+#include <grpc/support/alloc.h>
+#include <grpc/support/log.h>
+#include <grpc/support/string_util.h>
+
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
+#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/combiner.h"
+#include "src/core/lib/security/credentials/fake/fake_credentials.h"
+
+#include "test/core/end2end/fake_resolver.h"
+#include "test/core/util/test_config.h"
+
+static grpc_resolver *build_fake_resolver(
+ grpc_exec_ctx *exec_ctx, grpc_combiner *combiner,
+ grpc_fake_resolver_response_generator *response_generator) {
+ grpc_resolver_factory *factory = grpc_resolver_factory_lookup("test");
+ grpc_arg generator_arg =
+ grpc_fake_resolver_response_generator_arg(response_generator);
+ grpc_resolver_args args;
+ memset(&args, 0, sizeof(args));
+ grpc_channel_args channel_args = {1, &generator_arg};
+ args.args = &channel_args;
+ args.combiner = combiner;
+ grpc_resolver *resolver =
+ grpc_resolver_factory_create_resolver(exec_ctx, factory, &args);
+ grpc_resolver_factory_unref(factory);
+ return resolver;
+}
+
+typedef struct on_resolution_arg {
+ grpc_channel_args *resolver_result;
+ grpc_channel_args *expected_resolver_result;
+ bool was_called;
+} on_resolution_arg;
+
+void on_resolution_cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
+ on_resolution_arg *res = arg;
+ res->was_called = true;
+ // We only check the addresses channel arg because that's the only one
+ // explicitly set by the test via
+ // grpc_fake_resolver_response_generator_set_response.
+ const grpc_lb_addresses *actual_lb_addresses =
+ grpc_lb_addresses_find_channel_arg(res->resolver_result);
+ const grpc_lb_addresses *expected_lb_addresses =
+ grpc_lb_addresses_find_channel_arg(res->expected_resolver_result);
+ GPR_ASSERT(
+ grpc_lb_addresses_cmp(actual_lb_addresses, expected_lb_addresses) == 0);
+ grpc_channel_args_destroy(exec_ctx, res->resolver_result);
+ grpc_channel_args_destroy(exec_ctx, res->expected_resolver_result);
+}
+
+static void test_fake_resolver() {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_combiner *combiner = grpc_combiner_create(NULL);
+ // Create resolver.
+ grpc_fake_resolver_response_generator *response_generator =
+ grpc_fake_resolver_response_generator_create();
+ grpc_resolver *resolver =
+ build_fake_resolver(&exec_ctx, combiner, response_generator);
+ GPR_ASSERT(resolver != NULL);
+
+ // Setup expectations.
+ grpc_uri *uris[] = {grpc_uri_parse(&exec_ctx, "ipv4:10.2.1.1:1234", true),
+ grpc_uri_parse(&exec_ctx, "ipv4:127.0.0.1:4321", true)};
+ char *balancer_names[] = {"name1", "name2"};
+ const bool is_balancer[] = {true, false};
+ grpc_lb_addresses *addresses = grpc_lb_addresses_create(3, NULL);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(uris); ++i) {
+ grpc_lb_addresses_set_address_from_uri(
+ addresses, i, uris[i], is_balancer[i], balancer_names[i], NULL);
+ grpc_uri_destroy(uris[i]);
+ }
+ const grpc_arg addresses_arg =
+ grpc_lb_addresses_create_channel_arg(addresses);
+ grpc_channel_args *results =
+ grpc_channel_args_copy_and_add(NULL, &addresses_arg, 1);
+ grpc_lb_addresses_destroy(&exec_ctx, addresses);
+ on_resolution_arg on_res_arg;
+ memset(&on_res_arg, 0, sizeof(on_res_arg));
+ on_res_arg.expected_resolver_result = results;
+ grpc_closure *on_resolution = grpc_closure_create(
+ on_resolution_cb, &on_res_arg, grpc_combiner_scheduler(combiner, false));
+
+ // Set resolver results and trigger first resolution. on_resolution_cb
+ // performs the checks.
+ grpc_fake_resolver_response_generator_set_response(
+ &exec_ctx, response_generator, results);
+ grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
+ on_resolution);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(on_res_arg.was_called);
+
+ // Setup update.
+ grpc_uri *uris_update[] = {
+ grpc_uri_parse(&exec_ctx, "ipv4:192.168.1.0:31416", true)};
+ char *balancer_names_update[] = {"name3"};
+ const bool is_balancer_update[] = {false};
+ grpc_lb_addresses *addresses_update = grpc_lb_addresses_create(1, NULL);
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(uris_update); ++i) {
+ grpc_lb_addresses_set_address_from_uri(addresses_update, i, uris_update[i],
+ is_balancer_update[i],
+ balancer_names_update[i], NULL);
+ grpc_uri_destroy(uris_update[i]);
+ }
+
+ grpc_arg addresses_update_arg =
+ grpc_lb_addresses_create_channel_arg(addresses_update);
+ grpc_channel_args *results_update =
+ grpc_channel_args_copy_and_add(NULL, &addresses_update_arg, 1);
+ grpc_lb_addresses_destroy(&exec_ctx, addresses_update);
+
+ // Setup expectations for the update.
+ on_resolution_arg on_res_arg_update;
+ memset(&on_res_arg_update, 0, sizeof(on_res_arg_update));
+ on_res_arg_update.expected_resolver_result = results_update;
+ on_resolution = grpc_closure_create(on_resolution_cb, &on_res_arg_update,
+ grpc_combiner_scheduler(combiner, false));
+
+ // Set updated resolver results and trigger a second resolution.
+ grpc_fake_resolver_response_generator_set_response(
+ &exec_ctx, response_generator, results_update);
+ grpc_resolver_next_locked(&exec_ctx, resolver,
+ &on_res_arg_update.resolver_result, on_resolution);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(on_res_arg.was_called);
+
+ // Requesting a new resolution without re-senting the response shouldn't
+ // trigger the resolution callback.
+ memset(&on_res_arg, 0, sizeof(on_res_arg));
+ grpc_resolver_next_locked(&exec_ctx, resolver, &on_res_arg.resolver_result,
+ on_resolution);
+ grpc_exec_ctx_flush(&exec_ctx);
+ GPR_ASSERT(!on_res_arg.was_called);
+
+ GRPC_COMBINER_UNREF(&exec_ctx, combiner, "test_fake_resolver");
+ GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_fake_resolver");
+ grpc_exec_ctx_finish(&exec_ctx);
+ grpc_fake_resolver_response_generator_unref(response_generator);
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+ grpc_fake_resolver_init(); // Registers the "test" scheme.
+ grpc_init();
+
+ test_fake_resolver();
+
+ grpc_shutdown();
+ return 0;
+}
diff --git a/test/core/end2end/BUILD b/test/core/end2end/BUILD
index 0cef7aa01d..ffea1cc4e8 100644
--- a/test/core/end2end/BUILD
+++ b/test/core/end2end/BUILD
@@ -32,49 +32,66 @@ licenses(["notice"]) # 3-clause BSD
load(":generate_tests.bzl", "grpc_end2end_tests")
cc_library(
- name = 'cq_verifier',
- srcs = ['cq_verifier.c'],
- hdrs = ['cq_verifier.h'],
- deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util'],
- copts = ['-std=c99'],
- visibility = ["//test:__subpackages__"],
+ name = "cq_verifier",
+ srcs = ["cq_verifier.c"],
+ hdrs = ["cq_verifier.h"],
+ copts = ["-std=c99"],
+ visibility = ["//test:__subpackages__"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
)
cc_library(
- name = 'ssl_test_data',
- visibility = ["//test:__subpackages__"],
- hdrs = ['data/ssl_test_data.h'],
- copts = ['-std=c99'],
- srcs = [
- "data/client_certs.c",
- "data/server1_cert.c",
- "data/server1_key.c",
- "data/test_root_cert.c",
- ]
+ name = "ssl_test_data",
+ srcs = [
+ "data/client_certs.c",
+ "data/server1_cert.c",
+ "data/server1_key.c",
+ "data/test_root_cert.c",
+ ],
+ hdrs = ["data/ssl_test_data.h"],
+ copts = ["-std=c99"],
+ visibility = ["//test:__subpackages__"],
)
cc_library(
- name = 'fake_resolver',
- hdrs = ['fake_resolver.h'],
- srcs = ['fake_resolver.c'],
- copts = ['-std=c99'],
- deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+ name = "fake_resolver",
+ srcs = ["fake_resolver.c"],
+ hdrs = ["fake_resolver.h"],
+ copts = ["-std=c99"],
+ visibility = ["//test:__subpackages__"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
)
cc_library(
- name = 'http_proxy',
- hdrs = ['fixtures/http_proxy_fixture.h'],
- srcs = ['fixtures/http_proxy_fixture.c'],
- copts = ['-std=c99'],
- deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+ name = "http_proxy",
+ srcs = ["fixtures/http_proxy_fixture.c"],
+ hdrs = ["fixtures/http_proxy_fixture.h"],
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
)
cc_library(
- name = 'proxy',
- hdrs = ['fixtures/proxy.h'],
- srcs = ['fixtures/proxy.c'],
- copts = ['-std=c99'],
- deps = ['//:gpr', '//:grpc', '//test/core/util:grpc_test_util']
+ name = "proxy",
+ srcs = ["fixtures/proxy.c"],
+ hdrs = ["fixtures/proxy.h"],
+ copts = ["-std=c99"],
+ deps = [
+ "//:gpr",
+ "//:grpc",
+ "//test/core/util:grpc_test_util",
+ ],
)
grpc_end2end_tests()
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 1c7dd1339c..6a71c20b80 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -32,6 +32,7 @@
// This is similar to the sockaddr resolver, except that it supports a
// bunch of query args that are useful for dependency injection in tests.
+#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
@@ -46,12 +47,18 @@
#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
+#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/support/string.h"
+#include "test/core/end2end/fake_resolver.h"
+
+#define GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR \
+ "grpc.fake_resolver.response_generator"
+
//
// fake_resolver
//
@@ -62,12 +69,11 @@ typedef struct {
// passed-in parameters
grpc_channel_args* channel_args;
- grpc_lb_addresses* addresses;
- // mutex guarding the rest of the state
- gpr_mu mu;
- // have we published?
- bool published;
+ // If not NULL, the next set of resolution results to be returned to
+ // grpc_resolver_next_locked()'s closure.
+ grpc_channel_args* next_results;
+
// pending next completion, or NULL
grpc_closure* next_completion;
// target result address for next completion
@@ -76,60 +82,137 @@ typedef struct {
static void fake_resolver_destroy(grpc_exec_ctx* exec_ctx, grpc_resolver* gr) {
fake_resolver* r = (fake_resolver*)gr;
- gpr_mu_destroy(&r->mu);
+ grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_channel_args_destroy(exec_ctx, r->channel_args);
- grpc_lb_addresses_destroy(exec_ctx, r->addresses);
gpr_free(r);
}
-static void fake_resolver_shutdown(grpc_exec_ctx* exec_ctx,
- grpc_resolver* resolver) {
+static void fake_resolver_shutdown_locked(grpc_exec_ctx* exec_ctx,
+ grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
- gpr_mu_lock(&r->mu);
if (r->next_completion != NULL) {
*r->target_result = NULL;
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
}
- gpr_mu_unlock(&r->mu);
}
static void fake_resolver_maybe_finish_next_locked(grpc_exec_ctx* exec_ctx,
fake_resolver* r) {
- if (r->next_completion != NULL && !r->published) {
- r->published = true;
- grpc_arg arg = grpc_lb_addresses_create_channel_arg(r->addresses);
+ if (r->next_completion != NULL && r->next_results != NULL) {
*r->target_result =
- grpc_channel_args_copy_and_add(r->channel_args, &arg, 1);
+ grpc_channel_args_merge(r->channel_args, r->next_results);
+ grpc_channel_args_destroy(exec_ctx, r->next_results);
grpc_closure_sched(exec_ctx, r->next_completion, GRPC_ERROR_NONE);
r->next_completion = NULL;
+ r->next_results = NULL;
}
}
-static void fake_resolver_channel_saw_error(grpc_exec_ctx* exec_ctx,
- grpc_resolver* resolver) {
+static void fake_resolver_channel_saw_error_locked(grpc_exec_ctx* exec_ctx,
+ grpc_resolver* resolver) {
fake_resolver* r = (fake_resolver*)resolver;
- gpr_mu_lock(&r->mu);
- r->published = false;
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
}
-static void fake_resolver_next(grpc_exec_ctx* exec_ctx, grpc_resolver* resolver,
- grpc_channel_args** target_result,
- grpc_closure* on_complete) {
+static void fake_resolver_next_locked(grpc_exec_ctx* exec_ctx,
+ grpc_resolver* resolver,
+ grpc_channel_args** target_result,
+ grpc_closure* on_complete) {
fake_resolver* r = (fake_resolver*)resolver;
- gpr_mu_lock(&r->mu);
GPR_ASSERT(!r->next_completion);
r->next_completion = on_complete;
r->target_result = target_result;
fake_resolver_maybe_finish_next_locked(exec_ctx, r);
- gpr_mu_unlock(&r->mu);
}
static const grpc_resolver_vtable fake_resolver_vtable = {
- fake_resolver_destroy, fake_resolver_shutdown,
- fake_resolver_channel_saw_error, fake_resolver_next};
+ fake_resolver_destroy, fake_resolver_shutdown_locked,
+ fake_resolver_channel_saw_error_locked, fake_resolver_next_locked};
+
+struct grpc_fake_resolver_response_generator {
+ fake_resolver* resolver; // Set by the fake_resolver constructor to itself.
+ grpc_channel_args* next_response;
+ gpr_refcount refcount;
+};
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_create() {
+ grpc_fake_resolver_response_generator* generator =
+ gpr_zalloc(sizeof(*generator));
+ gpr_ref_init(&generator->refcount, 1);
+ return generator;
+}
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_ref(
+ grpc_fake_resolver_response_generator* generator) {
+ gpr_ref(&generator->refcount);
+ return generator;
+}
+
+void grpc_fake_resolver_response_generator_unref(
+ grpc_fake_resolver_response_generator* generator) {
+ if (gpr_unref(&generator->refcount)) {
+ gpr_free(generator);
+ }
+}
+
+static void set_response_cb(grpc_exec_ctx* exec_ctx, void* arg,
+ grpc_error* error) {
+ grpc_fake_resolver_response_generator* generator = arg;
+ fake_resolver* r = generator->resolver;
+ if (r->next_results != NULL) {
+ grpc_channel_args_destroy(exec_ctx, r->next_results);
+ }
+ r->next_results = generator->next_response;
+ fake_resolver_maybe_finish_next_locked(exec_ctx, r);
+}
+
+void grpc_fake_resolver_response_generator_set_response(
+ grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
+ grpc_channel_args* next_response) {
+ GPR_ASSERT(generator->resolver != NULL);
+ generator->next_response = grpc_channel_args_copy(next_response);
+ grpc_closure_sched(
+ exec_ctx,
+ grpc_closure_create(
+ set_response_cb, generator,
+ grpc_combiner_scheduler(generator->resolver->base.combiner, false)),
+ GRPC_ERROR_NONE);
+}
+
+static void* response_generator_arg_copy(void* p) {
+ return grpc_fake_resolver_response_generator_ref(p);
+}
+
+static void response_generator_arg_destroy(grpc_exec_ctx* exec_ctx, void* p) {
+ grpc_fake_resolver_response_generator_unref(p);
+}
+
+static int response_generator_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
+
+static const grpc_arg_pointer_vtable response_generator_arg_vtable = {
+ response_generator_arg_copy, response_generator_arg_destroy,
+ response_generator_cmp};
+
+grpc_arg grpc_fake_resolver_response_generator_arg(
+ grpc_fake_resolver_response_generator* generator) {
+ grpc_arg arg;
+ arg.type = GRPC_ARG_POINTER;
+ arg.key = GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR;
+ arg.value.pointer.p = generator;
+ arg.value.pointer.vtable = &response_generator_arg_vtable;
+ return arg;
+}
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_get_response_generator(const grpc_channel_args* args) {
+ const grpc_arg* arg =
+ grpc_channel_args_find(args, GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR);
+ if (arg == NULL || arg->type != GRPC_ARG_POINTER) return NULL;
+ return arg->value.pointer.p;
+}
//
// fake_resolver_factory
@@ -139,81 +222,15 @@ static void fake_resolver_factory_ref(grpc_resolver_factory* factory) {}
static void fake_resolver_factory_unref(grpc_resolver_factory* factory) {}
-static void do_nothing(void* ignored) {}
-
static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx,
grpc_resolver_factory* factory,
grpc_resolver_args* args) {
- if (0 != strcmp(args->uri->authority, "")) {
- gpr_log(GPR_ERROR, "authority based uri's not supported by the %s scheme",
- args->uri->scheme);
- return NULL;
- }
- // Get lb_enabled arg. Anything other than "0" is interpreted as true.
- const char* lb_enabled_qpart =
- grpc_uri_get_query_arg(args->uri, "lb_enabled");
- const bool lb_enabled =
- lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0;
-
- // Get the balancer's names.
- const char* balancer_names =
- grpc_uri_get_query_arg(args->uri, "balancer_names");
- grpc_slice_buffer balancer_names_parts;
- grpc_slice_buffer_init(&balancer_names_parts);
- if (balancer_names != NULL) {
- const grpc_slice balancer_names_slice =
- grpc_slice_from_copied_string(balancer_names);
- grpc_slice_split(balancer_names_slice, ",", &balancer_names_parts);
- grpc_slice_unref(balancer_names_slice);
- }
-
- // Construct addresses.
- grpc_slice path_slice =
- grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing);
- grpc_slice_buffer path_parts;
- grpc_slice_buffer_init(&path_parts);
- grpc_slice_split(path_slice, ",", &path_parts);
- if (balancer_names_parts.count > 0 &&
- path_parts.count != balancer_names_parts.count) {
- gpr_log(GPR_ERROR,
- "Balancer names present but mismatched with number of addresses: "
- "%lu balancer names != %lu addresses",
- (unsigned long)balancer_names_parts.count,
- (unsigned long)path_parts.count);
- return NULL;
- }
- grpc_lb_addresses* addresses =
- grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */);
- bool errors_found = false;
- for (size_t i = 0; i < addresses->num_addresses; i++) {
- grpc_uri ith_uri = *args->uri;
- char* part_str = grpc_slice_to_c_string(path_parts.slices[i]);
- ith_uri.path = part_str;
- if (!parse_ipv4(&ith_uri, &addresses->addresses[i].address)) {
- errors_found = true;
- }
- gpr_free(part_str);
- if (errors_found) break;
- addresses->addresses[i].is_balancer = lb_enabled;
- addresses->addresses[i].balancer_name =
- balancer_names_parts.count > 0
- ? grpc_dump_slice(balancer_names_parts.slices[i], GPR_DUMP_ASCII)
- : NULL;
- }
- grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts);
- grpc_slice_buffer_destroy_internal(exec_ctx, &balancer_names_parts);
- grpc_slice_unref(path_slice);
- if (errors_found) {
- grpc_lb_addresses_destroy(exec_ctx, addresses);
- return NULL;
- }
- // Instantiate resolver.
- fake_resolver* r = gpr_malloc(sizeof(fake_resolver));
- memset(r, 0, sizeof(*r));
+ fake_resolver* r = gpr_zalloc(sizeof(*r));
r->channel_args = grpc_channel_args_copy(args->args);
- r->addresses = addresses;
- gpr_mu_init(&r->mu);
grpc_resolver_init(&r->base, &fake_resolver_vtable, args->combiner);
+ grpc_fake_resolver_response_generator* response_generator =
+ grpc_fake_resolver_get_response_generator(args->args);
+ if (response_generator != NULL) response_generator->resolver = r;
return &r->base;
}
diff --git a/test/core/end2end/fake_resolver.h b/test/core/end2end/fake_resolver.h
index 7a30347f30..447289adef 100644
--- a/test/core/end2end/fake_resolver.h
+++ b/test/core/end2end/fake_resolver.h
@@ -32,8 +32,42 @@
#ifndef GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H
#define GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
+#include "src/core/lib/channel/channel_args.h"
+
#include "test/core/util/test_config.h"
void grpc_fake_resolver_init();
+// Instances of \a grpc_fake_resolver_response_generator are passed to the
+// fake resolver in a channel argument (see \a
+// grpc_fake_resolver_response_generator_arg) in order to inject and trigger
+// custom resolutions. See also \a
+// grpc_fake_resolver_response_generator_set_response.
+typedef struct grpc_fake_resolver_response_generator
+ grpc_fake_resolver_response_generator;
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_create();
+
+// Instruct the fake resolver associated with the \a response_generator instance
+// to trigger a new resolution for \a uri and \a args.
+void grpc_fake_resolver_response_generator_set_response(
+ grpc_exec_ctx* exec_ctx, grpc_fake_resolver_response_generator* generator,
+ grpc_channel_args* next_response);
+
+// Return a \a grpc_arg for a \a grpc_fake_resolver_response_generator instance.
+grpc_arg grpc_fake_resolver_response_generator_arg(
+ grpc_fake_resolver_response_generator* generator);
+// Return the \a grpc_fake_resolver_response_generator instance in \a args or
+// NULL.
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_get_response_generator(const grpc_channel_args* args);
+
+grpc_fake_resolver_response_generator*
+grpc_fake_resolver_response_generator_ref(
+ grpc_fake_resolver_response_generator* generator);
+void grpc_fake_resolver_response_generator_unref(
+ grpc_fake_resolver_response_generator* generator);
+
#endif /* GRPC_TEST_CORE_END2END_FAKE_RESOLVER_H */
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 8b8983ee17..83c82ba5c0 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -932,6 +932,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
}
uint32_t propagation_mask = read_uint32(&inp);
grpc_slice method = read_string_like_slice(&inp);
+ if (GRPC_SLICE_LENGTH(method) == 0) {
+ ok = false;
+ }
grpc_slice host = read_string_like_slice(&inp);
gpr_timespec deadline =
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672
new file mode 100644
index 0000000000..3fd5427b46
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672
Binary files differ
diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary
index 4282c61214..2bb9de34c5 100644
--- a/test/core/end2end/fuzzers/hpack.dictionary
+++ b/test/core/end2end/fuzzers/hpack.dictionary
@@ -77,6 +77,7 @@
"\x08if-range"
"\x13if-unmodified-since"
"\x0Dlast-modified"
+"\x0Blb-cost-bin"
"\x04link"
"\x08location"
"\x0Cmax-forwards"
@@ -153,6 +154,7 @@
"\x00\x13if-unmodified-since\x00"
"\x00\x0Dlast-modified\x00"
"\x00\x08lb-token\x00"
+"\x00\x0Blb-cost-bin\x00"
"\x00\x04link\x00"
"\x00\x08location\x00"
"\x00\x0Cmax-forwards\x00"
diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index 72e9db6e21..c021bc07ff 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -129,8 +129,7 @@ static void end_test(grpc_end2end_test_fixture *f) {
static void request_response_with_payload(
grpc_end2end_test_config config, grpc_end2end_test_fixture f,
const char *method_name, const char *request_msg, const char *response_msg,
- grpc_metadata *initial_lr_metadata,
- grpc_load_reporting_cost_context *cost_ctx) {
+ grpc_metadata *initial_lr_metadata, grpc_metadata *trailing_lr_metadata) {
grpc_slice request_payload_slice = grpc_slice_from_static_string(request_msg);
grpc_slice response_payload_slice =
grpc_slice_from_static_string(response_msg);
@@ -243,8 +242,9 @@ static void request_response_with_payload(
op->reserved = NULL;
op++;
op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
- GPR_ASSERT(cost_ctx != NULL);
- grpc_call_set_load_reporting_cost_context(s, cost_ctx);
+ GPR_ASSERT(trailing_lr_metadata != NULL);
+ op->data.send_status_from_server.trailing_metadata_count = 1;
+ op->data.send_status_from_server.trailing_metadata = trailing_lr_metadata;
op->data.send_status_from_server.status = GRPC_STATUS_OK;
grpc_slice status_details = grpc_slice_from_static_string("xyz");
op->data.send_status_from_server.status_details = &status_details;
@@ -298,21 +298,21 @@ static void test_load_reporting_hook(grpc_end2end_test_config config) {
const char *response_msg = "... and the response from the server";
grpc_metadata initial_lr_metadata;
+ grpc_metadata trailing_lr_metadata;
initial_lr_metadata.key = GRPC_MDSTR_LB_TOKEN;
initial_lr_metadata.value = grpc_slice_from_static_string("client-token");
memset(&initial_lr_metadata.internal_data, 0,
sizeof(initial_lr_metadata.internal_data));
- grpc_load_reporting_cost_context *cost_ctx = gpr_malloc(sizeof(*cost_ctx));
- memset(cost_ctx, 0, sizeof(*cost_ctx));
- cost_ctx->values_count = 1;
- cost_ctx->values =
- gpr_malloc(sizeof(*cost_ctx->values) * cost_ctx->values_count);
- cost_ctx->values[0] = grpc_slice_from_static_string("cost-token");
+ trailing_lr_metadata.key = GRPC_MDSTR_LB_COST_BIN;
+ trailing_lr_metadata.value = grpc_slice_from_static_string("server-token");
+ memset(&trailing_lr_metadata.internal_data, 0,
+ sizeof(trailing_lr_metadata.internal_data));
request_response_with_payload(config, f, method_name, request_msg,
- response_msg, &initial_lr_metadata, cost_ctx);
+ response_msg, &initial_lr_metadata,
+ &trailing_lr_metadata);
end_test(&f);
{
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c
index 12d8406323..1f1696a7a7 100644
--- a/test/core/iomgr/udp_server_test.c
+++ b/test/core/iomgr/udp_server_test.c
@@ -91,7 +91,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd, void *user_data) {
}
static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd,
- void *user_data) {
+ grpc_closure *closure, void *user_data) {
gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d",
grpc_fd_wrapped_fd(emfd));
g_number_of_orphan_calls++;
@@ -228,9 +228,9 @@ static void test_no_op_with_port_and_start(void) {
grpc_udp_server_destroy(&exec_ctx, s, NULL);
grpc_exec_ctx_finish(&exec_ctx);
- /* The server had a single FD, which is orphaned once in *
- * deactivated_all_ports, and once in grpc_udp_server_destroy. */
- GPR_ASSERT(g_number_of_orphan_calls == 2);
+ /* The server had a single FD, which is orphaned exactly once in *
+ * grpc_udp_server_destroy. */
+ GPR_ASSERT(g_number_of_orphan_calls == 1);
}
static void test_receive(int number_of_clients) {
@@ -297,9 +297,9 @@ static void test_receive(int number_of_clients) {
grpc_udp_server_destroy(&exec_ctx, s, NULL);
grpc_exec_ctx_finish(&exec_ctx);
- /* The server had a single FD, which is orphaned once in *
- * deactivated_all_ports, and once in grpc_udp_server_destroy. */
- GPR_ASSERT(g_number_of_orphan_calls == 2);
+ /* The server had a single FD, which is orphaned exactly once in *
+ * grpc_udp_server_destroy. */
+ GPR_ASSERT(g_number_of_orphan_calls == 1);
/* The write callback should have fired a few times. */
GPR_ASSERT(g_number_of_writes > 0);