diff options
author | 2017-04-18 13:39:18 -0700 | |
---|---|---|
committer | 2017-04-18 13:39:18 -0700 | |
commit | cac4e178fda78564934c21ec2e77b5763dc3111a (patch) | |
tree | 175197d7ffac02cdc936e3844ace737103b6e928 /test/core/end2end | |
parent | 8b24229b7ca6b30b6c3eae64e20551386abc6ecb (diff) | |
parent | c2d9f1e297b7a504412be85ec9840e59bfdb794e (diff) |
Merge github.com:grpc/grpc into cpparena
Diffstat (limited to 'test/core/end2end')
-rw-r--r-- | test/core/end2end/BUILD | 79 | ||||
-rw-r--r-- | test/core/end2end/fake_resolver.c | 211 | ||||
-rw-r--r-- | test/core/end2end/fake_resolver.h | 34 | ||||
-rw-r--r-- | test/core/end2end/fuzzers/api_fuzzer.c | 3 | ||||
-rw-r--r-- | test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672 | bin | 0 -> 46 bytes | |||
-rw-r--r-- | test/core/end2end/fuzzers/hpack.dictionary | 2 | ||||
-rw-r--r-- | test/core/end2end/tests/load_reporting_hook.c | 22 |
7 files changed, 212 insertions, 139 deletions
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 7671609d3c..88a0e301da 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 Binary files differnew file mode 100644 index 0000000000..3fd5427b46 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5867145026076672 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 15a69aa4d6..5f671405c2 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; |