diff options
author | Mark D. Roth <roth@google.com> | 2016-09-30 07:48:00 -0700 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2016-09-30 07:48:00 -0700 |
commit | 43b817ced14083de585111c2657bbe34040bdcc7 (patch) | |
tree | 3b9e28af5b7e90e9183acae48f0750d1099fbae8 /test | |
parent | 366c6ceb8c53a4f8c4a2f9aa2c6fee8f2a070479 (diff) | |
parent | be43240564891aaa34bbd911332994fe8d197c0b (diff) |
Merge remote-tracking branch 'upstream/master' into run_interop_tests_go
Diffstat (limited to 'test')
194 files changed, 3634 insertions, 605 deletions
diff --git a/test/core/bad_client/tests/head_of_line_blocking.c b/test/core/bad_client/tests/head_of_line_blocking.c index e4051bb668..64cb79d82f 100644 --- a/test/core/bad_client/tests/head_of_line_blocking.c +++ b/test/core/bad_client/tests/head_of_line_blocking.c @@ -97,7 +97,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload != NULL); diff --git a/test/core/bad_client/tests/large_metadata.c b/test/core/bad_client/tests/large_metadata.c index ded5f17d4a..d106ce6210 100644 --- a/test/core/bad_client/tests/large_metadata.c +++ b/test/core/bad_client/tests/large_metadata.c @@ -121,7 +121,7 @@ static void server_verifier(grpc_server *server, grpc_completion_queue *cq, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); @@ -148,7 +148,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); @@ -171,7 +171,7 @@ static void server_verifier_sends_too_much_metadata(grpc_server *server, op.reserved = NULL; error = grpc_call_start_batch(s, &op, 1, tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 0); // Operation fails. + CQ_EXPECT_COMPLETION(cqv, tag(102), 0); // Operation fails. cq_verify(cqv); gpr_free((char *)meta.value); diff --git a/test/core/bad_client/tests/server_registered_method.c b/test/core/bad_client/tests/server_registered_method.c index 6216553a61..e174af5931 100644 --- a/test/core/bad_client/tests/server_registered_method.c +++ b/test/core/bad_client/tests/server_registered_method.c @@ -70,7 +70,7 @@ static void verifier_succeeds(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload != NULL); @@ -96,7 +96,7 @@ static void verifier_fails(grpc_server *server, grpc_completion_queue *cq, &deadline, &request_metadata_recv, &payload, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(payload == NULL); diff --git a/test/core/bad_client/tests/simple_request.c b/test/core/bad_client/tests/simple_request.c index 25bbe968e4..c08aa40a0a 100644 --- a/test/core/bad_client/tests/simple_request.c +++ b/test/core/bad_client/tests/simple_request.c @@ -114,7 +114,7 @@ static void verifier(grpc_server *server, grpc_completion_queue *cq, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); GPR_ASSERT(0 == strcmp(call_details.host, "localhost")); diff --git a/test/core/bad_ssl/bad_ssl_test.c b/test/core/bad_ssl/bad_ssl_test.c index bb06ab0bb9..c9cdb169b6 100644 --- a/test/core/bad_ssl/bad_ssl_test.c +++ b/test/core/bad_ssl/bad_ssl_test.c @@ -111,7 +111,7 @@ static void run_test(const char *target, size_t nops) { error = grpc_call_start_batch(c, ops, nops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status != GRPC_STATUS_OK); diff --git a/test/core/bad_ssl/gen_build_yaml.py b/test/core/bad_ssl/gen_build_yaml.py index 69f921989c..c17b17eb13 100755 --- a/test/core/bad_ssl/gen_build_yaml.py +++ b/test/core/bad_ssl/gen_build_yaml.py @@ -41,7 +41,8 @@ default_test_options = TestOptions(False, 1.0) # maps test names to options BAD_CLIENT_TESTS = { 'cert': default_test_options._replace(cpu_cost=0.1), - 'alpn': default_test_options._replace(cpu_cost=0.1), + # Disabling this test because it does not link correctly as written + # 'alpn': default_test_options._replace(cpu_cost=0.1), } def main(): diff --git a/test/core/census/data/context_empty.pb b/test/core/census/data/context_empty.pb new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/core/census/data/context_empty.pb diff --git a/test/core/census/data/context_empty.txt b/test/core/census/data/context_empty.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/core/census/data/context_empty.txt diff --git a/test/core/census/data/context_full.pb b/test/core/census/data/context_full.pb Binary files differnew file mode 100644 index 0000000000..80ebcf280b --- /dev/null +++ b/test/core/census/data/context_full.pb diff --git a/test/core/census/data/context_full.txt b/test/core/census/data/context_full.txt new file mode 100644 index 0000000000..7901a10c33 --- /dev/null +++ b/test/core/census/data/context_full.txt @@ -0,0 +1,3 @@ +trace_id { hi : 5; lo : 1 } +span_id : 7 +is_sampled : true diff --git a/test/core/census/data/context_no_sample.pb b/test/core/census/data/context_no_sample.pb Binary files differnew file mode 100644 index 0000000000..ab7ad7d109 --- /dev/null +++ b/test/core/census/data/context_no_sample.pb diff --git a/test/core/census/data/context_no_sample.txt b/test/core/census/data/context_no_sample.txt new file mode 100644 index 0000000000..150298002f --- /dev/null +++ b/test/core/census/data/context_no_sample.txt @@ -0,0 +1,2 @@ +trace_id { hi : 5; lo : 1 } +span_id : 7 diff --git a/test/core/census/data/context_span_only.pb b/test/core/census/data/context_span_only.pb Binary files differnew file mode 100644 index 0000000000..2a9527a75a --- /dev/null +++ b/test/core/census/data/context_span_only.pb diff --git a/test/core/census/data/context_span_only.txt b/test/core/census/data/context_span_only.txt new file mode 100644 index 0000000000..d90de2e614 --- /dev/null +++ b/test/core/census/data/context_span_only.txt @@ -0,0 +1,2 @@ +span_id : 7 +is_sampled : true diff --git a/test/core/census/data/context_trace_only.pb b/test/core/census/data/context_trace_only.pb Binary files differnew file mode 100644 index 0000000000..7fdf6f61a3 --- /dev/null +++ b/test/core/census/data/context_trace_only.pb diff --git a/test/core/census/data/context_trace_only.txt b/test/core/census/data/context_trace_only.txt new file mode 100644 index 0000000000..9b68a6aa92 --- /dev/null +++ b/test/core/census/data/context_trace_only.txt @@ -0,0 +1,2 @@ +trace_id { hi : 5; lo : 1 } +is_sampled : true diff --git a/test/core/census/trace_context_test.c b/test/core/census/trace_context_test.c new file mode 100644 index 0000000000..ee409e8d1a --- /dev/null +++ b/test/core/census/trace_context_test.c @@ -0,0 +1,231 @@ +/* + * + * 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. + * + */ + +#include <grpc/census.h> +#include <grpc/support/log.h> +#include <grpc/support/port_platform.h> +#include <grpc/support/useful.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include "src/core/ext/census/base_resources.h" +#include "src/core/ext/census/resource.h" +#include "test/core/util/test_config.h" + +#include "src/core/ext/census/gen/trace_context.pb.h" +#include "src/core/ext/census/trace_context.h" +#include "third_party/nanopb/pb_decode.h" +#include "third_party/nanopb/pb_encode.h" + +#define BUF_SIZE 256 + +/* Encodes a TraceContext structure (ctxt1) to a buffer, and then decodes it +to a second TraceContext (ctxt2). Validates that the resulting TraceContext +has a span_id, trace_id, and that the values are equal to those in initial +TraceContext. On success, returns true. If encode_trace_context returns 0, +decode_trace_context fails, or the resulting TraceContext is missing a trace_id +or span_id, it will return false. */ +bool validate_encode_decode_context(google_trace_TraceContext *ctxt1, + uint8_t *buffer, size_t buf_size) { + google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero; + size_t msg_length; + GPR_ASSERT(ctxt1->has_trace_id && ctxt1->has_span_id); + + msg_length = encode_trace_context(ctxt1, buffer, buf_size); + if (msg_length == 0) { + return false; + } + + if (!decode_trace_context(&ctxt2, buffer, msg_length)) { + return false; + } + + if (!ctxt2.has_trace_id || !ctxt2.has_span_id) { + return false; + } + + GPR_ASSERT( + ctxt1->trace_id.hi == ctxt2.trace_id.hi && + ctxt1->trace_id.lo == ctxt2.trace_id.lo && + ctxt1->span_id == ctxt2.span_id && + ctxt1->has_is_sampled == ctxt2.has_is_sampled && + (ctxt1->has_is_sampled ? ctxt1->is_sampled == ctxt2.is_sampled : true)); + + return true; +} + +/* Decodes a proto-encoded TraceContext from a buffer. If decode_trace_context +fails or the resulting TraceContext is missing a trace_id or span_id it will +return false, otherwise returns true. */ +bool validate_decode_context(google_trace_TraceContext *ctxt, uint8_t *buffer, + size_t msg_length) { + // Validate the decoding of a context written to buffer. + if (!decode_trace_context(ctxt, buffer, msg_length)) { + return false; + } + + if (!ctxt->has_trace_id || !ctxt->has_span_id) { + return false; + } + + return true; +} + +/* Read an encoded trace context from a file. Validates that the decoding +gives the expected result (succeed). */ +static void read_and_validate_context_from_file(google_trace_TraceContext *ctxt, + const char *file, + const bool succeed) { + uint8_t buffer[BUF_SIZE]; + FILE *input = fopen(file, "rb"); + GPR_ASSERT(input != NULL); + size_t nbytes = fread(buffer, 1, BUF_SIZE, input); + GPR_ASSERT(nbytes <= BUF_SIZE && feof(input) && !ferror(input)); + bool res = validate_decode_context(ctxt, buffer, nbytes); + GPR_ASSERT(res == succeed); + GPR_ASSERT(fclose(input) == 0); +} + +// Test full proto-buffer. +static void test_full() { + google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero; + read_and_validate_context_from_file( + &ctxt, "test/core/census/data/context_full.pb", true); +} + +// Test empty proto-buffer. +static void test_empty() { + google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero; + read_and_validate_context_from_file( + &ctxt, "test/core/census/data/context_empty.pb", false); +} + +// Test proto-buffer with only trace_id. +static void test_trace_only() { + google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero; + read_and_validate_context_from_file( + &ctxt, "test/core/census/data/context_trace_only.pb", false); +} + +// Test proto-buffer with only span_id. +static void test_span_only() { + google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero; + read_and_validate_context_from_file( + &ctxt, "test/core/census/data/context_span_only.pb", false); +} + +// Test proto-buffer without is_sampled value. +static void test_no_sample() { + google_trace_TraceContext ctxt = google_trace_TraceContext_init_zero; + read_and_validate_context_from_file( + &ctxt, "test/core/census/data/context_no_sample.pb", true); + GPR_ASSERT(ctxt.has_is_sampled == false && ctxt.is_sampled == false); +} + +static void test_encode_decode() { + uint8_t buffer[BUF_SIZE] = {0}; + + google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero; + ctxt1.has_trace_id = true; + ctxt1.trace_id.has_hi = true; + ctxt1.trace_id.has_lo = true; + ctxt1.trace_id.lo = 1; + ctxt1.trace_id.hi = 2; + ctxt1.has_span_id = true; + ctxt1.span_id = 3; + validate_encode_decode_context(&ctxt1, buffer, sizeof(buffer)); + + google_trace_TraceContext ctxt2 = google_trace_TraceContext_init_zero; + ctxt2.has_trace_id = true; + ctxt2.trace_id.has_hi = false; + ctxt2.trace_id.has_lo = false; + ctxt2.has_span_id = true; + validate_encode_decode_context(&ctxt2, buffer, sizeof(buffer)); +} + +// Test a corrupted proto-buffer. +static void test_corrupt() { + uint8_t buffer[BUF_SIZE] = {0}; + google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero; + size_t msg_length; + + ctxt1.has_trace_id = true; + ctxt1.trace_id.has_hi = true; + ctxt1.trace_id.has_lo = true; + ctxt1.trace_id.lo = 1; + ctxt1.trace_id.hi = 2; + ctxt1.has_span_id = true; + ctxt1.span_id = 3; + ctxt1.is_sampled = true; + msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer)); + + /* Corrupt some bytes. 255 (0xFF) should be illegal for the first byte of the + proto encoded object. */ + buffer[0] = 255; + + bool res = validate_decode_context(&ctxt1, buffer, msg_length); + GPR_ASSERT(res == false); +} + +static void test_buffer_size() { + // This buffer is too small, so the encode should fail. + uint8_t buffer[16] = {0}; + google_trace_TraceContext ctxt1 = google_trace_TraceContext_init_zero; + size_t msg_length; + + ctxt1.has_trace_id = true; + ctxt1.trace_id.has_hi = true; + ctxt1.trace_id.has_lo = true; + ctxt1.trace_id.lo = 1; + ctxt1.trace_id.hi = 2; + ctxt1.has_span_id = true; + ctxt1.span_id = 3; + ctxt1.is_sampled = true; + msg_length = encode_trace_context(&ctxt1, buffer, sizeof(buffer)); + + GPR_ASSERT(msg_length == 0); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_full(); + test_empty(); + test_trace_only(); + test_span_only(); + test_encode_decode(); + test_corrupt(); + test_no_sample(); + test_buffer_size(); + + return 0; +} diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 569b3f7cd2..b1c1ed9039 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -135,9 +135,9 @@ 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, call_stack); + grpc_error *error = grpc_call_stack_init( + &exec_ctx, channel_stack, 1, free_call, call_stack, NULL, NULL, + gpr_inf_future(GPR_CLOCK_MONOTONIC), call_stack); 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_config/lb_policies_test.c b/test/core/client_config/lb_policies_test.c index 3160312db6..0b9648b7e1 100644 --- a/test/core/client_config/lb_policies_test.c +++ b/test/core/client_config/lb_policies_test.c @@ -351,9 +351,9 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, ops, (size_t)(op - ops), tag(102), NULL)); - cq_expect_completion(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); if (!completed_client) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } cq_verify(cqv); @@ -376,7 +376,7 @@ static int *perform_request(servers_fixture *f, grpc_channel *client, } else { /* no response from server */ grpc_call_cancel(c, NULL); if (!completed_client) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); } } @@ -576,7 +576,7 @@ static void test_ping() { client = create_client(f); grpc_channel_ping(client, f->cq, tag(0), NULL); - cq_expect_completion(cqv, tag(0), 0); + CQ_EXPECT_COMPLETION(cqv, tag(0), 0); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(client, 1) == @@ -586,7 +586,7 @@ static void test_ping() { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f->cq, tag(99)); - cq_expect_completion(cqv, tag(99), 1); + CQ_EXPECT_COMPLETION(cqv, tag(99), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -596,7 +596,7 @@ static void test_ping() { for (i = 1; i <= 5; i++) { grpc_channel_ping(client, f->cq, tag(i), NULL); - cq_expect_completion(cqv, tag(i), 1); + CQ_EXPECT_COMPLETION(cqv, tag(i), 1); cq_verify(cqv); } gpr_free(rdata.call_details); diff --git a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c index 69c07d83f4..d3b961959d 100644 --- a/test/core/client_config/resolvers/dns_resolver_connectivity_test.c +++ b/test/core/client_config/resolvers/dns_resolver_connectivity_test.c @@ -41,29 +41,6 @@ #include "src/core/lib/iomgr/timer.h" #include "test/core/util/test_config.h" -static void client_channel_factory_ref(grpc_client_channel_factory *scv) {} -static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_client_channel_factory *scv) {} -static grpc_subchannel *client_channel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory, - grpc_subchannel_args *args) { - return NULL; -} - -static grpc_channel *client_channel_factory_create_channel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory, - const char *target, grpc_client_channel_type type, - grpc_channel_args *args) { - GPR_UNREACHABLE_CODE(return NULL); -} - -static const grpc_client_channel_factory_vtable sc_vtable = { - client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory cc_factory = {&sc_vtable}; - static gpr_mu g_mu; static bool g_fail_resolution = true; @@ -92,7 +69,6 @@ static grpc_resolver *create_resolver(const char *name) { grpc_resolver_args args; memset(&args, 0, sizeof(args)); args.uri = uri; - args.client_channel_factory = &cc_factory; grpc_resolver *resolver = grpc_resolver_factory_create_resolver(factory, &args); grpc_resolver_factory_unref(factory); @@ -127,26 +103,26 @@ int main(int argc, char **argv) { grpc_resolver *resolver = create_resolver("dns:test"); - grpc_client_config *config = (grpc_client_config *)1; + grpc_resolver_result *result = (grpc_resolver_result *)1; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; gpr_event ev1; gpr_event_init(&ev1); - grpc_resolver_next(&exec_ctx, resolver, &config, + grpc_resolver_next(&exec_ctx, resolver, &result, grpc_closure_create(on_done, &ev1)); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(wait_loop(5, &ev1)); - GPR_ASSERT(config == NULL); + GPR_ASSERT(result == NULL); gpr_event ev2; gpr_event_init(&ev2); - grpc_resolver_next(&exec_ctx, resolver, &config, + grpc_resolver_next(&exec_ctx, resolver, &result, grpc_closure_create(on_done, &ev2)); grpc_exec_ctx_flush(&exec_ctx); GPR_ASSERT(wait_loop(30, &ev2)); - GPR_ASSERT(config != NULL); + GPR_ASSERT(result != NULL); - grpc_client_config_unref(&exec_ctx, config); + grpc_resolver_result_unref(&exec_ctx, result); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test"); grpc_exec_ctx_finish(&exec_ctx); diff --git a/test/core/client_config/resolvers/dns_resolver_test.c b/test/core/client_config/resolvers/dns_resolver_test.c index 21dc99cadd..c3f4cb1244 100644 --- a/test/core/client_config/resolvers/dns_resolver_test.c +++ b/test/core/client_config/resolvers/dns_resolver_test.c @@ -38,29 +38,6 @@ #include "src/core/ext/client_config/resolver_registry.h" #include "test/core/util/test_config.h" -static void client_channel_factory_ref(grpc_client_channel_factory *scv) {} -static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_client_channel_factory *scv) {} -static grpc_subchannel *client_channel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory, - grpc_subchannel_args *args) { - GPR_UNREACHABLE_CODE(return NULL); -} - -static grpc_channel *client_channel_factory_create_channel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory, - const char *target, grpc_client_channel_type type, - grpc_channel_args *args) { - GPR_UNREACHABLE_CODE(return NULL); -} - -static const grpc_client_channel_factory_vtable sc_vtable = { - client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory cc_factory = {&sc_vtable}; - 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); @@ -71,7 +48,6 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { GPR_ASSERT(uri); memset(&args, 0, sizeof(args)); args.uri = uri; - args.client_channel_factory = &cc_factory; resolver = grpc_resolver_factory_create_resolver(factory, &args); GPR_ASSERT(resolver != NULL); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds"); diff --git a/test/core/client_config/resolvers/sockaddr_resolver_test.c b/test/core/client_config/resolvers/sockaddr_resolver_test.c index b11546b6b1..d8430d39c4 100644 --- a/test/core/client_config/resolvers/sockaddr_resolver_test.c +++ b/test/core/client_config/resolvers/sockaddr_resolver_test.c @@ -38,29 +38,6 @@ #include "src/core/ext/client_config/resolver_registry.h" #include "test/core/util/test_config.h" -static void client_channel_factory_ref(grpc_client_channel_factory *scv) {} -static void client_channel_factory_unref(grpc_exec_ctx *exec_ctx, - grpc_client_channel_factory *scv) {} -static grpc_subchannel *client_channel_factory_create_subchannel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *factory, - grpc_subchannel_args *args) { - GPR_UNREACHABLE_CODE(return NULL); -} - -static grpc_channel *client_channel_factory_create_channel( - grpc_exec_ctx *exec_ctx, grpc_client_channel_factory *cc_factory, - const char *target, grpc_client_channel_type type, - grpc_channel_args *args) { - GPR_UNREACHABLE_CODE(return NULL); -} - -static const grpc_client_channel_factory_vtable sc_vtable = { - client_channel_factory_ref, client_channel_factory_unref, - client_channel_factory_create_subchannel, - client_channel_factory_create_channel}; - -static grpc_client_channel_factory cc_factory = {&sc_vtable}; - 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); @@ -71,7 +48,6 @@ static void test_succeeds(grpc_resolver_factory *factory, const char *string) { GPR_ASSERT(uri); memset(&args, 0, sizeof(args)); args.uri = uri; - args.client_channel_factory = &cc_factory; resolver = grpc_resolver_factory_create_resolver(factory, &args); GPR_ASSERT(resolver != NULL); GRPC_RESOLVER_UNREF(&exec_ctx, resolver, "test_succeeds"); diff --git a/test/core/end2end/bad_server_response_test.c b/test/core/end2end/bad_server_response_test.c index ab80adf0e0..5ed0eb64d2 100644 --- a/test/core/end2end/bad_server_response_test.c +++ b/test/core/end2end/bad_server_response_test.c @@ -206,7 +206,7 @@ static void start_rpc(int target_port, grpc_status_code expected_status, GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); gpr_log(GPR_DEBUG, "Rpc status: %d, details: %s", status, details); diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 5331049e89..1f42d3457e 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -61,6 +61,8 @@ typedef struct metadata { list to detail other expectations */ typedef struct expectation { struct expectation *next; + const char *file; + int line; grpc_completion_type type; void *tag; int success; @@ -180,7 +182,8 @@ static void expectation_to_strvec(gpr_strvec *buf, expectation *e) { switch (e->type) { case GRPC_OP_COMPLETE: - gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d", e->success); + gpr_asprintf(&tmp, "GRPC_OP_COMPLETE result=%d %s:%d", e->success, + e->file, e->line); gpr_strvec_add(buf, tmp); break; case GRPC_QUEUE_TIMEOUT: @@ -214,25 +217,16 @@ static void fail_no_event_received(cq_verifier *v) { } void cq_verify(cq_verifier *v) { - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); - grpc_event ev; - expectation *e; - char *s; - gpr_strvec have_tags; - - gpr_strvec_init(&have_tags); - + const gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); while (v->first_expectation != NULL) { - ev = grpc_completion_queue_next(v->cq, deadline, NULL); + grpc_event ev = grpc_completion_queue_next(v->cq, deadline, NULL); if (ev.type == GRPC_QUEUE_TIMEOUT) { fail_no_event_received(v); break; } - + expectation *e; expectation *prev = NULL; for (e = v->first_expectation; e != NULL; e = e->next) { - gpr_asprintf(&s, " %p", e->tag); - gpr_strvec_add(&have_tags, s); if (e->tag == ev.tag) { verify_matches(e, &ev); if (e == v->first_expectation) v->first_expectation = e->next; @@ -243,18 +237,19 @@ void cq_verify(cq_verifier *v) { prev = e; } if (e == NULL) { - s = grpc_event_string(&ev); + char *s = grpc_event_string(&ev); gpr_log(GPR_ERROR, "cq returned unexpected event: %s", s); gpr_free(s); - s = gpr_strvec_flatten(&have_tags, NULL); - gpr_log(GPR_ERROR, "expected tags:%s", s); + gpr_strvec expectations; + gpr_strvec_init(&expectations); + expectations_to_strvec(&expectations, v); + s = gpr_strvec_flatten(&expectations, NULL); + gpr_strvec_destroy(&expectations); + gpr_log(GPR_ERROR, "expected tags:\n%s", s); gpr_free(s); - gpr_strvec_destroy(&have_tags); abort(); } } - - gpr_strvec_destroy(&have_tags); } void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { @@ -276,16 +271,19 @@ void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec) { void cq_verify_empty(cq_verifier *v) { cq_verify_empty_timeout(v, 1); } -static void add(cq_verifier *v, grpc_completion_type type, void *tag, - bool success) { +static void add(cq_verifier *v, const char *file, int line, + grpc_completion_type type, void *tag, bool success) { expectation *e = gpr_malloc(sizeof(expectation)); e->type = type; + e->file = file; + e->line = line; e->tag = tag; e->success = success; e->next = v->first_expectation; v->first_expectation = e; } -void cq_expect_completion(cq_verifier *v, void *tag, bool success) { - add(v, GRPC_OP_COMPLETE, tag, success); +void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, + bool success) { + add(v, file, line, GRPC_OP_COMPLETE, tag, success); } diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h index bf82468c9a..0a7c03c090 100644 --- a/test/core/end2end/cq_verifier.h +++ b/test/core/end2end/cq_verifier.h @@ -62,7 +62,10 @@ void cq_verify_empty_timeout(cq_verifier *v, int timeout_sec); Any functions taking ... expect a NULL terminated list of key/value pairs (each pair using two parameter slots) of metadata that MUST be present in the event. */ -void cq_expect_completion(cq_verifier *v, void *tag, bool success); +void cq_expect_completion(cq_verifier *v, const char *file, int line, void *tag, + bool success); +#define CQ_EXPECT_COMPLETION(v, tag, success) \ + cq_expect_completion(v, __FILE__, __LINE__, tag, success) int byte_buffer_eq_string(grpc_byte_buffer *byte_buffer, const char *string); int contains_metadata(grpc_metadata_array *array, const char *key, diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 348b9ed5f0..8abb81c803 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -199,7 +199,7 @@ void test_connect(const char *server_host, const char *client_host, int port, error = grpc_server_request_call(server, &s, &call_details, &request_metadata_recv, cq, cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -221,8 +221,8 @@ void test_connect(const char *server_host, const char *client_host, int port, 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); peer = grpc_call_get_peer(c); @@ -238,7 +238,7 @@ void test_connect(const char *server_host, const char *client_host, int port, grpc_call_destroy(s); } else { /* Check for a failed connection. */ - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c index 3efd18cf2e..a630262197 100644 --- a/test/core/end2end/end2end_nosec_tests.c +++ b/test/core/end2end/end2end_nosec_tests.c @@ -95,6 +95,8 @@ extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); extern void network_status_change(grpc_end2end_test_config config); extern void network_status_change_pre_init(void); +extern void no_logging(grpc_end2end_test_config config); +extern void no_logging_pre_init(void); extern void no_op(grpc_end2end_test_config config); extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); @@ -115,6 +117,8 @@ extern void shutdown_finishes_calls(grpc_end2end_test_config config); extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); extern void shutdown_finishes_tags_pre_init(void); +extern void simple_cacheable_request(grpc_end2end_test_config config); +extern void simple_cacheable_request_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); @@ -155,6 +159,7 @@ void grpc_end2end_tests_pre_init(void) { max_message_length_pre_init(); negative_deadline_pre_init(); network_status_change_pre_init(); + no_logging_pre_init(); no_op_pre_init(); payload_pre_init(); ping_pre_init(); @@ -165,6 +170,7 @@ void grpc_end2end_tests_pre_init(void) { server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); + simple_cacheable_request_pre_init(); simple_delayed_request_pre_init(); simple_metadata_pre_init(); simple_request_pre_init(); @@ -205,6 +211,7 @@ void grpc_end2end_tests(int argc, char **argv, max_message_length(config); negative_deadline(config); network_status_change(config); + no_logging(config); no_op(config); payload(config); ping(config); @@ -215,6 +222,7 @@ void grpc_end2end_tests(int argc, char **argv, server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); + simple_cacheable_request(config); simple_delayed_request(config); simple_metadata(config); simple_request(config); @@ -328,6 +336,10 @@ void grpc_end2end_tests(int argc, char **argv, network_status_change(config); continue; } + if (0 == strcmp("no_logging", argv[i])) { + no_logging(config); + continue; + } if (0 == strcmp("no_op", argv[i])) { no_op(config); continue; @@ -368,6 +380,10 @@ void grpc_end2end_tests(int argc, char **argv, shutdown_finishes_tags(config); continue; } + if (0 == strcmp("simple_cacheable_request", argv[i])) { + simple_cacheable_request(config); + continue; + } if (0 == strcmp("simple_delayed_request", argv[i])) { simple_delayed_request(config); continue; diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c index e3d791abc1..925872a71f 100644 --- a/test/core/end2end/end2end_tests.c +++ b/test/core/end2end/end2end_tests.c @@ -97,6 +97,8 @@ extern void negative_deadline(grpc_end2end_test_config config); extern void negative_deadline_pre_init(void); extern void network_status_change(grpc_end2end_test_config config); extern void network_status_change_pre_init(void); +extern void no_logging(grpc_end2end_test_config config); +extern void no_logging_pre_init(void); extern void no_op(grpc_end2end_test_config config); extern void no_op_pre_init(void); extern void payload(grpc_end2end_test_config config); @@ -117,6 +119,8 @@ extern void shutdown_finishes_calls(grpc_end2end_test_config config); extern void shutdown_finishes_calls_pre_init(void); extern void shutdown_finishes_tags(grpc_end2end_test_config config); extern void shutdown_finishes_tags_pre_init(void); +extern void simple_cacheable_request(grpc_end2end_test_config config); +extern void simple_cacheable_request_pre_init(void); extern void simple_delayed_request(grpc_end2end_test_config config); extern void simple_delayed_request_pre_init(void); extern void simple_metadata(grpc_end2end_test_config config); @@ -158,6 +162,7 @@ void grpc_end2end_tests_pre_init(void) { max_message_length_pre_init(); negative_deadline_pre_init(); network_status_change_pre_init(); + no_logging_pre_init(); no_op_pre_init(); payload_pre_init(); ping_pre_init(); @@ -168,6 +173,7 @@ void grpc_end2end_tests_pre_init(void) { server_finishes_request_pre_init(); shutdown_finishes_calls_pre_init(); shutdown_finishes_tags_pre_init(); + simple_cacheable_request_pre_init(); simple_delayed_request_pre_init(); simple_metadata_pre_init(); simple_request_pre_init(); @@ -209,6 +215,7 @@ void grpc_end2end_tests(int argc, char **argv, max_message_length(config); negative_deadline(config); network_status_change(config); + no_logging(config); no_op(config); payload(config); ping(config); @@ -219,6 +226,7 @@ void grpc_end2end_tests(int argc, char **argv, server_finishes_request(config); shutdown_finishes_calls(config); shutdown_finishes_tags(config); + simple_cacheable_request(config); simple_delayed_request(config); simple_metadata(config); simple_request(config); @@ -336,6 +344,10 @@ void grpc_end2end_tests(int argc, char **argv, network_status_change(config); continue; } + if (0 == strcmp("no_logging", argv[i])) { + no_logging(config); + continue; + } if (0 == strcmp("no_op", argv[i])) { no_op(config); continue; @@ -376,6 +388,10 @@ void grpc_end2end_tests(int argc, char **argv, shutdown_finishes_tags(config); continue; } + if (0 == strcmp("simple_cacheable_request", argv[i])) { + simple_cacheable_request(config); + continue; + } if (0 == strcmp("simple_delayed_request", argv[i])) { simple_delayed_request(config); continue; diff --git a/test/core/end2end/end2end_tests.h b/test/core/end2end/end2end_tests.h index dfa041c0c6..34af0936cd 100644 --- a/test/core/end2end/end2end_tests.h +++ b/test/core/end2end/end2end_tests.h @@ -42,6 +42,7 @@ typedef struct grpc_end2end_test_config grpc_end2end_test_config; #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 FAIL_AUTH_CHECK_SERVER_ARG_NAME "fail_auth_check" diff --git a/test/core/end2end/fixtures/h2_fd.c b/test/core/end2end/fixtures/h2_fd.c index 89fa02517d..8561feed70 100644 --- a/test/core/end2end/fixtures/h2_fd.c +++ b/test/core/end2end/fixtures/h2_fd.c @@ -95,7 +95,7 @@ static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, grpc_server_register_completion_queue(f->server, f->cq, NULL); grpc_server_start(f->server); - grpc_server_add_insecure_channel_from_fd(f->server, f->cq, sfd->fd_pair[1]); + grpc_server_add_insecure_channel_from_fd(f->server, NULL, sfd->fd_pair[1]); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/core/end2end/fixtures/h2_http_proxy.c b/test/core/end2end/fixtures/h2_http_proxy.c new file mode 100644 index 0000000000..a675a11f66 --- /dev/null +++ b/test/core/end2end/fixtures/h2_http_proxy.c @@ -0,0 +1,129 @@ +/* + * + * 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. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.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 "src/core/ext/client_config/client_channel.h" +#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" +#include "src/core/lib/channel/connected_channel.h" +#include "src/core/lib/channel/http_server_filter.h" +#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/util/port.h" +#include "test/core/util/test_config.h" + +typedef struct fullstack_fixture_data { + char *server_addr; + grpc_end2end_http_proxy *proxy; +} fullstack_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_fullstack( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + memset(&f, 0, sizeof(f)); + + fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data)); + const int server_port = grpc_pick_unused_port_or_die(); + gpr_join_host_port(&ffd->server_addr, "localhost", server_port); + ffd->proxy = grpc_end2end_http_proxy_create(); + + f.fixture_data = ffd; + f.cq = grpc_completion_queue_create(NULL); + + return f; +} + +void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args) { + fullstack_fixture_data *ffd = f->fixture_data; + char *proxy_uri; + gpr_asprintf(&proxy_uri, "http://%s", + grpc_end2end_http_proxy_get_proxy_name(ffd->proxy)); + gpr_setenv("http_proxy", proxy_uri); + gpr_free(proxy_uri); + f->client = grpc_insecure_channel_create(ffd->server_addr, client_args, NULL); + GPR_ASSERT(f->client); +} + +void chttp2_init_server_fullstack(grpc_end2end_test_fixture *f, + grpc_channel_args *server_args) { + fullstack_fixture_data *ffd = f->fixture_data; + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args, NULL); + grpc_server_register_completion_queue(f->server, f->cq, NULL); + GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->server_addr)); + grpc_server_start(f->server); +} + +void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) { + fullstack_fixture_data *ffd = f->fixture_data; + gpr_free(ffd->server_addr); + grpc_end2end_http_proxy_destroy(ffd->proxy); + gpr_free(ffd); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, + chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, + chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, +}; + +int main(int argc, char **argv) { + size_t i; + + grpc_test_init(argc, argv); + grpc_end2end_tests_pre_init(); + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(argc, argv, configs[i]); + } + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c index 8c50eeb5d5..c7b99863f0 100644 --- a/test/core/end2end/fixtures/h2_proxy.c +++ b/test/core/end2end/fixtures/h2_proxy.c @@ -113,7 +113,8 @@ void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) { /* All test configurations */ static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, + {"chttp2/fullstack+proxy", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_REQUEST_PROXYING, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; diff --git a/test/core/end2end/fixtures/h2_ssl_cert.c b/test/core/end2end/fixtures/h2_ssl_cert.c index b476bf5516..ae2604dfb5 100644 --- a/test/core/end2end/fixtures/h2_ssl_cert.c +++ b/test/core/end2end/fixtures/h2_ssl_cert.c @@ -331,7 +331,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), expected_result == SUCCESS); + CQ_EXPECT_COMPLETION(cqv, tag(1), expected_result == SUCCESS); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/fixtures/h2_ssl_proxy.c b/test/core/end2end/fixtures/h2_ssl_proxy.c index 238e6bca46..eeb54b8b88 100644 --- a/test/core/end2end/fixtures/h2_ssl_proxy.c +++ b/test/core/end2end/fixtures/h2_ssl_proxy.c @@ -184,6 +184,7 @@ static void chttp2_init_server_simple_ssl_secure_fullstack( static grpc_end2end_test_config configs[] = { {"chttp2/simple_ssl_fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_REQUEST_PROXYING | FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_secure_fullstack, diff --git a/test/core/end2end/fixtures/http_proxy.c b/test/core/end2end/fixtures/http_proxy.c new file mode 100644 index 0000000000..22533b9694 --- /dev/null +++ b/test/core/end2end/fixtures/http_proxy.c @@ -0,0 +1,481 @@ +/* + * + * 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. + * + */ + +#include "test/core/end2end/fixtures/http_proxy.h" + +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/atm.h> +#include <grpc/support/host_port.h> +#include <grpc/support/log.h> +#include <grpc/support/slice_buffer.h> +#include <grpc/support/string_util.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/useful.h> + +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/http/parser.h" +#include "src/core/lib/iomgr/closure.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/pollset_set.h" +#include "src/core/lib/iomgr/resolve_address.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "test/core/util/port.h" + +struct grpc_end2end_http_proxy { + char* proxy_name; + gpr_thd_id thd; + grpc_tcp_server* server; + grpc_channel_args* channel_args; + gpr_mu* mu; + grpc_pollset* pollset; + gpr_atm shutdown; +}; + +// +// Connection handling +// + +typedef struct proxy_connection { + grpc_endpoint* client_endpoint; + grpc_endpoint* server_endpoint; + + gpr_refcount refcount; + + grpc_pollset_set* pollset_set; + + grpc_closure on_read_request_done; + grpc_closure on_server_connect_done; + grpc_closure on_write_response_done; + grpc_closure on_client_read_done; + grpc_closure on_client_write_done; + grpc_closure on_server_read_done; + grpc_closure on_server_write_done; + + gpr_slice_buffer client_read_buffer; + gpr_slice_buffer client_deferred_write_buffer; + gpr_slice_buffer client_write_buffer; + gpr_slice_buffer server_read_buffer; + gpr_slice_buffer server_deferred_write_buffer; + gpr_slice_buffer server_write_buffer; + + grpc_http_parser http_parser; + grpc_http_request http_request; +} proxy_connection; + +// Helper function to destroy the proxy connection. +static void proxy_connection_unref(grpc_exec_ctx* exec_ctx, + proxy_connection* conn) { + if (gpr_unref(&conn->refcount)) { + grpc_endpoint_destroy(exec_ctx, conn->client_endpoint); + if (conn->server_endpoint != NULL) + grpc_endpoint_destroy(exec_ctx, conn->server_endpoint); + grpc_pollset_set_destroy(conn->pollset_set); + gpr_slice_buffer_destroy(&conn->client_read_buffer); + gpr_slice_buffer_destroy(&conn->client_deferred_write_buffer); + gpr_slice_buffer_destroy(&conn->client_write_buffer); + gpr_slice_buffer_destroy(&conn->server_read_buffer); + gpr_slice_buffer_destroy(&conn->server_deferred_write_buffer); + gpr_slice_buffer_destroy(&conn->server_write_buffer); + grpc_http_parser_destroy(&conn->http_parser); + grpc_http_request_destroy(&conn->http_request); + gpr_free(conn); + } +} + +// Helper function to shut down the proxy connection. +// Does NOT take ownership of a reference to error. +static void proxy_connection_failed(grpc_exec_ctx* exec_ctx, + proxy_connection* conn, bool is_client, + const char* prefix, grpc_error* error) { + const char* msg = grpc_error_string(error); + gpr_log(GPR_INFO, "%s: %s", prefix, msg); + grpc_error_free_string(msg); + grpc_endpoint_shutdown(exec_ctx, conn->client_endpoint); + if (conn->server_endpoint != NULL) + grpc_endpoint_shutdown(exec_ctx, conn->server_endpoint); + proxy_connection_unref(exec_ctx, conn); +} + +// Callback for writing proxy data to the client. +static void on_client_write_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy client write", error); + return; + } + // Clear write buffer (the data we just wrote). + gpr_slice_buffer_reset_and_unref(&conn->client_write_buffer); + // If more data was read from the server since we started this write, + // write that data now. + if (conn->client_deferred_write_buffer.length > 0) { + gpr_slice_buffer_move_into(&conn->client_deferred_write_buffer, + &conn->client_write_buffer); + grpc_endpoint_write(exec_ctx, conn->client_endpoint, + &conn->client_write_buffer, + &conn->on_client_write_done); + } else { + // No more writes. Unref the connection. + proxy_connection_unref(exec_ctx, conn); + } +} + +// Callback for writing proxy data to the backend server. +static void on_server_write_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, false /* is_client */, + "HTTP proxy server write", error); + return; + } + // Clear write buffer (the data we just wrote). + gpr_slice_buffer_reset_and_unref(&conn->server_write_buffer); + // If more data was read from the client since we started this write, + // write that data now. + if (conn->server_deferred_write_buffer.length > 0) { + gpr_slice_buffer_move_into(&conn->server_deferred_write_buffer, + &conn->server_write_buffer); + grpc_endpoint_write(exec_ctx, conn->server_endpoint, + &conn->server_write_buffer, + &conn->on_server_write_done); + } else { + // No more writes. Unref the connection. + proxy_connection_unref(exec_ctx, conn); + } +} + +// Callback for reading data from the client, which will be proxied to +// the backend server. +static void on_client_read_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy client read", error); + return; + } + // If there is already a pending write (i.e., server_write_buffer is + // not empty), then move the read data into server_deferred_write_buffer, + // and the next write will be requested in on_server_write_done(), when + // the current write is finished. + // + // Otherwise, move the read data into the write buffer and write it. + if (conn->server_write_buffer.length > 0) { + gpr_slice_buffer_move_into(&conn->client_read_buffer, + &conn->server_deferred_write_buffer); + } else { + gpr_slice_buffer_move_into(&conn->client_read_buffer, + &conn->server_write_buffer); + gpr_ref(&conn->refcount); + grpc_endpoint_write(exec_ctx, conn->server_endpoint, + &conn->server_write_buffer, + &conn->on_server_write_done); + } + // Read more data. + grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer, + &conn->on_client_read_done); +} + +// Callback for reading data from the backend server, which will be +// proxied to the client. +static void on_server_read_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, false /* is_client */, + "HTTP proxy server read", error); + return; + } + // If there is already a pending write (i.e., client_write_buffer is + // not empty), then move the read data into client_deferred_write_buffer, + // and the next write will be requested in on_client_write_done(), when + // the current write is finished. + // + // Otherwise, move the read data into the write buffer and write it. + if (conn->client_write_buffer.length > 0) { + gpr_slice_buffer_move_into(&conn->server_read_buffer, + &conn->client_deferred_write_buffer); + } else { + gpr_slice_buffer_move_into(&conn->server_read_buffer, + &conn->client_write_buffer); + gpr_ref(&conn->refcount); + grpc_endpoint_write(exec_ctx, conn->client_endpoint, + &conn->client_write_buffer, + &conn->on_client_write_done); + } + // Read more data. + grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer, + &conn->on_server_read_done); +} + +// Callback to write the HTTP response for the CONNECT request. +static void on_write_response_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy write response", error); + return; + } + // Clear write buffer. + gpr_slice_buffer_reset_and_unref(&conn->client_write_buffer); + // Start reading from both client and server. One of the read + // requests inherits our ref to conn, but we need to take a new ref + // for the other one. + gpr_ref(&conn->refcount); + grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer, + &conn->on_client_read_done); + grpc_endpoint_read(exec_ctx, conn->server_endpoint, &conn->server_read_buffer, + &conn->on_server_read_done); +} + +// Callback to connect to the backend server specified by the HTTP +// CONNECT request. +static void on_server_connect_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + // TODO(roth): Technically, in this case, we should handle the error + // by returning an HTTP response to the client indicating that the + // connection failed. However, for the purposes of this test code, + // it's fine to pretend this is a client-side error, which will + // cause the client connection to be dropped. + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy server connect", error); + return; + } + // We've established a connection, so send back a 200 response code to + // the client. + // The write callback inherits our reference to conn. + gpr_slice slice = + gpr_slice_from_copied_string("HTTP/1.0 200 connected\r\n\r\n"); + gpr_slice_buffer_add(&conn->client_write_buffer, slice); + grpc_endpoint_write(exec_ctx, conn->client_endpoint, + &conn->client_write_buffer, + &conn->on_write_response_done); +} + +// Callback to read the HTTP CONNECT request. +// TODO(roth): Technically, for any of the failure modes handled by this +// function, we should handle the error by returning an HTTP response to +// the client indicating that the request failed. However, for the purposes +// of this test code, it's fine to pretend this is a client-side error, +// which will cause the client connection to be dropped. +static void on_read_request_done(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + proxy_connection* conn = arg; + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy read request", error); + return; + } + // Read request and feed it to the parser. + for (size_t i = 0; i < conn->client_read_buffer.count; ++i) { + if (GPR_SLICE_LENGTH(conn->client_read_buffer.slices[i]) > 0) { + error = grpc_http_parser_parse(&conn->http_parser, + conn->client_read_buffer.slices[i], NULL); + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy request parse", error); + GRPC_ERROR_UNREF(error); + return; + } + } + } + gpr_slice_buffer_reset_and_unref(&conn->client_read_buffer); + // If we're not done reading the request, read more data. + if (conn->http_parser.state != GRPC_HTTP_BODY) { + grpc_endpoint_read(exec_ctx, conn->client_endpoint, + &conn->client_read_buffer, &conn->on_read_request_done); + return; + } + // Make sure we got a CONNECT request. + if (strcmp(conn->http_request.method, "CONNECT") != 0) { + char* msg; + gpr_asprintf(&msg, "HTTP proxy got request method %s", + conn->http_request.method); + error = GRPC_ERROR_CREATE(msg); + gpr_free(msg); + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy read request", error); + GRPC_ERROR_UNREF(error); + return; + } + // Resolve address. + grpc_resolved_addresses* resolved_addresses = NULL; + error = grpc_blocking_resolve_address(conn->http_request.path, "80", + &resolved_addresses); + if (error != GRPC_ERROR_NONE) { + proxy_connection_failed(exec_ctx, conn, true /* is_client */, + "HTTP proxy DNS lookup", error); + GRPC_ERROR_UNREF(error); + return; + } + GPR_ASSERT(resolved_addresses->naddrs >= 1); + // Connect to requested address. + // The connection callback inherits our reference to conn. + const gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(10, GPR_TIMESPAN)); + grpc_tcp_client_connect(exec_ctx, &conn->on_server_connect_done, + &conn->server_endpoint, conn->pollset_set, + (struct sockaddr*)&resolved_addresses->addrs[0].addr, + resolved_addresses->addrs[0].len, deadline); + grpc_resolved_addresses_destroy(resolved_addresses); +} + +static void on_accept(grpc_exec_ctx* exec_ctx, void* arg, + grpc_endpoint* endpoint, grpc_pollset* accepting_pollset, + grpc_tcp_server_acceptor* acceptor) { + grpc_end2end_http_proxy* proxy = arg; + // Instantiate proxy_connection. + proxy_connection* conn = gpr_malloc(sizeof(*conn)); + memset(conn, 0, sizeof(*conn)); + conn->client_endpoint = endpoint; + gpr_ref_init(&conn->refcount, 1); + conn->pollset_set = grpc_pollset_set_create(); + grpc_pollset_set_add_pollset(exec_ctx, conn->pollset_set, proxy->pollset); + grpc_closure_init(&conn->on_read_request_done, on_read_request_done, conn); + grpc_closure_init(&conn->on_server_connect_done, on_server_connect_done, + conn); + grpc_closure_init(&conn->on_write_response_done, on_write_response_done, + conn); + grpc_closure_init(&conn->on_client_read_done, on_client_read_done, conn); + grpc_closure_init(&conn->on_client_write_done, on_client_write_done, conn); + grpc_closure_init(&conn->on_server_read_done, on_server_read_done, conn); + grpc_closure_init(&conn->on_server_write_done, on_server_write_done, conn); + gpr_slice_buffer_init(&conn->client_read_buffer); + gpr_slice_buffer_init(&conn->client_deferred_write_buffer); + gpr_slice_buffer_init(&conn->client_write_buffer); + gpr_slice_buffer_init(&conn->server_read_buffer); + gpr_slice_buffer_init(&conn->server_deferred_write_buffer); + gpr_slice_buffer_init(&conn->server_write_buffer); + grpc_http_parser_init(&conn->http_parser, GRPC_HTTP_REQUEST, + &conn->http_request); + grpc_endpoint_read(exec_ctx, conn->client_endpoint, &conn->client_read_buffer, + &conn->on_read_request_done); +} + +// +// Proxy class +// + +static void thread_main(void* arg) { + grpc_end2end_http_proxy* proxy = arg; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + do { + const gpr_timespec now = gpr_now(GPR_CLOCK_MONOTONIC); + const gpr_timespec deadline = + gpr_time_add(now, gpr_time_from_seconds(1, GPR_TIMESPAN)); + grpc_pollset_worker* worker = NULL; + gpr_mu_lock(proxy->mu); + GRPC_LOG_IF_ERROR( + "grpc_pollset_work", + grpc_pollset_work(&exec_ctx, proxy->pollset, &worker, now, deadline)); + gpr_mu_unlock(proxy->mu); + grpc_exec_ctx_flush(&exec_ctx); + } while (!gpr_atm_acq_load(&proxy->shutdown)); + grpc_exec_ctx_finish(&exec_ctx); +} + +grpc_end2end_http_proxy* grpc_end2end_http_proxy_create() { + grpc_end2end_http_proxy* proxy = gpr_malloc(sizeof(*proxy)); + memset(proxy, 0, sizeof(*proxy)); + // Construct proxy address. + const int proxy_port = grpc_pick_unused_port_or_die(); + gpr_join_host_port(&proxy->proxy_name, "localhost", proxy_port); + gpr_log(GPR_INFO, "Proxy address: %s", proxy->proxy_name); + // Create TCP server. + proxy->channel_args = grpc_channel_args_copy(NULL); + grpc_error* error = + grpc_tcp_server_create(NULL, proxy->channel_args, &proxy->server); + GPR_ASSERT(error == GRPC_ERROR_NONE); + // Bind to port. + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + grpc_sockaddr_set_port((struct sockaddr*)&addr, proxy_port); + int port; + error = grpc_tcp_server_add_port(proxy->server, (struct sockaddr*)&addr, + sizeof(addr), &port); + GPR_ASSERT(error == GRPC_ERROR_NONE); + GPR_ASSERT(port == proxy_port); + // Start server. + proxy->pollset = gpr_malloc(grpc_pollset_size()); + grpc_pollset_init(proxy->pollset, &proxy->mu); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_tcp_server_start(&exec_ctx, proxy->server, &proxy->pollset, 1, on_accept, + proxy); + grpc_exec_ctx_finish(&exec_ctx); + // Start proxy thread. + gpr_thd_options opt = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&opt); + GPR_ASSERT(gpr_thd_new(&proxy->thd, thread_main, proxy, &opt)); + return proxy; +} + +static void destroy_pollset(grpc_exec_ctx* exec_ctx, void* arg, + grpc_error* error) { + grpc_pollset* pollset = arg; + grpc_pollset_destroy(pollset); + gpr_free(pollset); +} + +void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy) { + gpr_atm_rel_store(&proxy->shutdown, 1); // Signal proxy thread to shutdown. + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + gpr_thd_join(proxy->thd); + grpc_tcp_server_shutdown_listeners(&exec_ctx, proxy->server); + grpc_tcp_server_unref(&exec_ctx, proxy->server); + gpr_free(proxy->proxy_name); + grpc_channel_args_destroy(proxy->channel_args); + grpc_closure destroyed; + grpc_closure_init(&destroyed, destroy_pollset, proxy->pollset); + grpc_pollset_shutdown(&exec_ctx, proxy->pollset, &destroyed); + gpr_free(proxy); + grpc_exec_ctx_finish(&exec_ctx); +} + +const char* grpc_end2end_http_proxy_get_proxy_name( + grpc_end2end_http_proxy* proxy) { + return proxy->proxy_name; +} diff --git a/test/core/end2end/fixtures/http_proxy.h b/test/core/end2end/fixtures/http_proxy.h new file mode 100644 index 0000000000..cd47b432af --- /dev/null +++ b/test/core/end2end/fixtures/http_proxy.h @@ -0,0 +1,41 @@ +/* + * + * 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. + * + */ + +typedef struct grpc_end2end_http_proxy grpc_end2end_http_proxy; + +grpc_end2end_http_proxy* grpc_end2end_http_proxy_create(); + +void grpc_end2end_http_proxy_destroy(grpc_end2end_http_proxy* proxy); + +const char* grpc_end2end_http_proxy_get_proxy_name( + grpc_end2end_http_proxy* proxy); diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 Binary files differnew file mode 100644 index 0000000000..1aa57b990d --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/22967e8ed837f03b76a980cc1d25054fb84b40e9 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 Binary files differnew file mode 100644 index 0000000000..385a724f3d --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/3f464011f8620f227309f6b2c84df6fffb8ed962 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 Binary files differnew file mode 100644 index 0000000000..e21c7c6d39 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-15070b2a2719ed8a6cbbaac25da02b7085993648 diff --git a/test/core/end2end/fuzzers/hpack.dictionary b/test/core/end2end/fuzzers/hpack.dictionary index 3157dfca3f..a93bccfa0d 100644 --- a/test/core/end2end/fuzzers/hpack.dictionary +++ b/test/core/end2end/fuzzers/hpack.dictionary @@ -40,10 +40,11 @@ "\x03GET" "\x04grpc" "\x14grpc-accept-encoding" -"\x0Fgrpc-census-bin" "\x0Dgrpc-encoding" "\x1Egrpc-internal-encoding-request" "\x0Cgrpc-message" +"\x10grpc-payload-bin" +"\x0Egrpc-stats-bin" "\x0Bgrpc-status" "\x0Cgrpc-timeout" "\x10grpc-tracing-bin" diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index e59b7dc9fb..78b37efd37 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -60,6 +60,7 @@ END2END_FIXTURES = { 'h2_full+pipe': default_unsecure_fixture_options._replace( platforms=['linux']), 'h2_full+trace': default_unsecure_fixture_options._replace(tracing=True), + 'h2_http_proxy': default_unsecure_fixture_options._replace(ci_mac=False), 'h2_oauth2': default_secure_fixture_options._replace(ci_mac=False), 'h2_proxy': default_unsecure_fixture_options._replace(includes_proxy=True, ci_mac=False), @@ -114,6 +115,7 @@ END2END_TESTS = { 'max_message_length': default_test_options, 'negative_deadline': default_test_options, 'network_status_change': default_test_options, + 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, 'payload': default_test_options, 'load_reporting_hook': default_test_options, @@ -126,6 +128,7 @@ END2END_TESTS = { 'server_finishes_request': default_test_options, 'shutdown_finishes_calls': default_test_options, 'shutdown_finishes_tags': default_test_options, + 'simple_cacheable_request': default_test_options, 'simple_delayed_request': connectivity_test_options, 'simple_metadata': default_test_options, 'simple_request': default_test_options, @@ -223,7 +226,7 @@ def main(): 'name': '%s_nosec_test' % f, 'build': 'test', 'language': 'c', - 'secure': 'no', + 'secure': False, 'src': ['test/core/end2end/fixtures/%s.c' % f], 'run': False, 'platforms': END2END_FIXTURES[f].platforms, diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c index 67cc24c74c..a8c7b2be5a 100644 --- a/test/core/end2end/goaway_server_test.c +++ b/test/core/end2end/goaway_server_test.c @@ -175,8 +175,8 @@ int main(int argc, char **argv) { set_resolve_port(port1); /* first call should now start */ - cq_expect_completion(cqv, tag(0x101), 1); - cq_expect_completion(cqv, tag(0x301), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x301), 1); cq_verify(cqv); GPR_ASSERT(GRPC_CHANNEL_READY == @@ -200,7 +200,7 @@ int main(int argc, char **argv) { * we should see a connectivity change and then nothing */ set_resolve_port(-1); grpc_server_shutdown_and_notify(server1, cq, tag(0xdead1)); - cq_expect_completion(cqv, tag(0x9999), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x9999), 1); cq_verify(cqv); cq_verify_empty(cqv); @@ -250,8 +250,8 @@ int main(int argc, char **argv) { &request_metadata2, cq, cq, tag(0x401))); /* second call should now start */ - cq_expect_completion(cqv, tag(0x201), 1); - cq_expect_completion(cqv, tag(0x401), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x401), 1); cq_verify(cqv); /* listen for close on the server call to probe for finishing */ @@ -273,12 +273,12 @@ int main(int argc, char **argv) { grpc_call_cancel(call2, NULL); /* now everything else should finish */ - cq_expect_completion(cqv, tag(0x102), 1); - cq_expect_completion(cqv, tag(0x202), 1); - cq_expect_completion(cqv, tag(0x302), 1); - cq_expect_completion(cqv, tag(0x402), 1); - cq_expect_completion(cqv, tag(0xdead1), 1); - cq_expect_completion(cqv, tag(0xdead2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x202), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x302), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0x402), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead2), 1); cq_verify(cqv); grpc_call_destroy(call1); diff --git a/test/core/end2end/invalid_call_argument_test.c b/test/core/end2end/invalid_call_argument_test.c index 3545660701..2b9904a244 100644 --- a/test/core/end2end/invalid_call_argument_test.c +++ b/test/core/end2end/invalid_call_argument_test.c @@ -116,8 +116,8 @@ static void prepare_test(int is_client) { &g_state.call_details, &g_state.server_initial_metadata_recv, g_state.cq, g_state.cq, tag(101))); - cq_expect_completion(g_state.cqv, tag(101), 1); - cq_expect_completion(g_state.cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 1); cq_verify(g_state.cqv); } } @@ -191,7 +191,7 @@ static void test_send_initial_metadata_more_than_once() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 0); cq_verify(g_state.cqv); op = g_state.ops; @@ -312,7 +312,7 @@ static void test_receive_initial_metadata_twice_at_client() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 0); cq_verify(g_state.cqv); op = g_state.ops; op->op = GRPC_OP_RECV_INITIAL_METADATA; @@ -405,7 +405,7 @@ static void test_recv_status_on_client_twice() { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(g_state.call, g_state.ops, (size_t)(op - g_state.ops), tag(1), NULL)); - cq_expect_completion(g_state.cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(g_state.cqv, tag(1), 1); cq_verify(g_state.cqv); op = g_state.ops; diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c index 08af382197..03ff70a188 100644 --- a/test/core/end2end/no_server_test.c +++ b/test/core/end2end/no_server_test.c @@ -86,7 +86,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch( call, ops, (size_t)(op - ops), tag(1), NULL)); /* verify that all tags get completed */ - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index c9663c2155..e0c7ac7c02 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -150,7 +148,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/binary_metadata.c b/test/core/end2end/tests/binary_metadata.c index 3dd2612077..6b105def33 100644 --- a/test/core/end2end/tests/binary_metadata.c +++ b/test/core/end2end/tests/binary_metadata.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -199,7 +197,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -218,7 +216,7 @@ static void test_request_response_with_metadata_and_payload( 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -243,8 +241,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/call_creds.c b/test/core/end2end/tests/call_creds.c index 694a0aa9ef..981c0fcc8c 100644 --- a/test/core/end2end/tests/call_creds.c +++ b/test/core/end2end/tests/call_creds.c @@ -53,8 +53,6 @@ static const char overridden_iam_selector[] = "overridden_selector"; typedef enum { NONE, OVERRIDE, DESTROY } override_mode; -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -234,7 +232,7 @@ static void request_response_with_payload_and_call_creds( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); s_auth_context = grpc_call_auth_context(s); GPR_ASSERT(s_auth_context != NULL); @@ -264,7 +262,7 @@ static void request_response_with_payload_and_call_creds( 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -289,8 +287,8 @@ static void request_response_with_payload_and_call_creds( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); @@ -450,7 +448,7 @@ static void test_request_with_server_rejecting_client_creds( error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNAUTHENTICATED); diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 51c13da3b1..b4ac3b3249 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -172,7 +170,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -202,8 +200,8 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_after_client_done.c b/test/core/end2end/tests/cancel_after_client_done.c index 2b5a409dee..5adc71e255 100644 --- a/test/core/end2end/tests/cancel_after_client_done.c +++ b/test/core/end2end/tests/cancel_after_client_done.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -176,7 +174,7 @@ static void test_cancel_after_accept_and_writes_closed( error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(2)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -206,8 +204,8 @@ static void test_cancel_after_accept_and_writes_closed( GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index 85fbe9de7b..85d8799f36 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -170,7 +168,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c, NULL)); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == mode.expect_status || status == GRPC_STATUS_INTERNAL); diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index d99062c608..c57091476e 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -168,7 +166,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, error = grpc_call_start_batch(c, ops, test_ops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_CANCELLED); diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 0c893b5f9e..3b03616b3b 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -44,8 +44,6 @@ #include "test/core/end2end/cq_verifier.h" #include "test/core/end2end/tests/cancel_test_helpers.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/cancel_with_status.c b/test/core/end2end/tests/cancel_with_status.c index 673c7051ad..e65390ac4a 100644 --- a/test/core/end2end/tests/cancel_with_status.c +++ b/test/core/end2end/tests/cancel_with_status.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -152,7 +150,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) { grpc_call_cancel_with_status(c, GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/compressed_payload.c b/test/core/end2end/tests/compressed_payload.c index ec5c012238..1724da4d0c 100644 --- a/test/core/end2end/tests/compressed_payload.c +++ b/test/core/end2end/tests/compressed_payload.c @@ -50,8 +50,6 @@ #include "src/core/lib/surface/call_test_only.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -198,7 +196,7 @@ static void request_for_disabled_algorithm( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), true); + CQ_EXPECT_COMPLETION(cqv, tag(101), true); cq_verify(cqv); op = ops; @@ -215,7 +213,7 @@ static void request_for_disabled_algorithm( 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), false); + CQ_EXPECT_COMPLETION(cqv, tag(102), false); op = ops; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; @@ -226,8 +224,8 @@ static void request_for_disabled_algorithm( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), true); - cq_expect_completion(cqv, tag(1), true); + CQ_EXPECT_COMPLETION(cqv, tag(103), true); + CQ_EXPECT_COMPLETION(cqv, tag(1), true); cq_verify(cqv); /* call was cancelled (closed) ... */ @@ -361,7 +359,7 @@ static void request_with_payload_template( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(100)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(100), true); + CQ_EXPECT_COMPLETION(cqv, tag(100), true); cq_verify(cqv); GPR_ASSERT(GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer( @@ -421,7 +419,7 @@ static void request_with_payload_template( 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW); @@ -438,8 +436,8 @@ static void request_with_payload_template( op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW); @@ -484,10 +482,10 @@ static void request_with_payload_template( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(101), 1); - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/connectivity.c b/test/core/end2end/tests/connectivity.c index 5775976b1c..260297ebd4 100644 --- a/test/core/end2end/tests/connectivity.c +++ b/test/core/end2end/tests/connectivity.c @@ -102,7 +102,7 @@ static void test_connectivity(grpc_end2end_test_config config) { f.cq, tag(2)); /* and now the watch should trigger */ - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -112,7 +112,7 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_CONNECTING, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(3)); - cq_expect_completion(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || @@ -130,7 +130,7 @@ static void test_connectivity(grpc_end2end_test_config config) { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(4)); - cq_expect_completion(cqv, tag(4), 1); + CQ_EXPECT_COMPLETION(cqv, tag(4), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -148,8 +148,8 @@ static void test_connectivity(grpc_end2end_test_config config) { grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); - cq_expect_completion(cqv, tag(5), 1); - cq_expect_completion(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(5), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE || diff --git a/test/core/end2end/tests/default_host.c b/test/core/end2end/tests/default_host.c index 728ee597b5..208e31697e 100644 --- a/test/core/end2end/tests/default_host.c +++ b/test/core/end2end/tests/default_host.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -162,7 +160,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -196,8 +194,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(error == GRPC_CALL_OK); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index 536fbd0d8a..a0059b9ad5 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { @@ -139,7 +137,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, f->cq, f->cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); /* should be able to shut down the server early @@ -168,9 +166,9 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, 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_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index c05b919914..ac53e1839b 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -112,7 +110,7 @@ static void empty_batch_body(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(c, op, 0, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/tests/filter_call_init_fails.c b/test/core/end2end/tests/filter_call_init_fails.c index a09183b786..a70f50af98 100644 --- a/test/core/end2end/tests/filter_call_init_fails.c +++ b/test/core/end2end/tests/filter_call_init_fails.c @@ -174,7 +174,7 @@ static void test_request(grpc_end2end_test_config config) { &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c index c6c36d668b..cdf868377a 100644 --- a/test/core/end2end/tests/filter_causes_close.c +++ b/test/core/end2end/tests/filter_causes_close.c @@ -46,8 +46,6 @@ #include "src/core/lib/surface/channel_init.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static bool g_enable_filter = false; static void *tag(intptr_t t) { return (void *)t; } @@ -172,7 +170,7 @@ static void test_request(grpc_end2end_test_config config) { &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED); diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index f527b8617d..29347a068a 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -154,7 +152,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); /* shutdown and destroy the server */ @@ -183,9 +181,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( 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_expect_completion(cqv, tag(0xdead), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_call_destroy(s); diff --git a/test/core/end2end/tests/high_initial_seqno.c b/test/core/end2end/tests/high_initial_seqno.c index db45f5eb5a..dab527005c 100644 --- a/test/core/end2end/tests/high_initial_seqno.c +++ b/test/core/end2end/tests/high_initial_seqno.c @@ -47,8 +47,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -159,7 +157,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -184,8 +182,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/hpack_size.c b/test/core/end2end/tests/hpack_size.c index 7ff0461f5f..fb00ae4eaa 100644 --- a/test/core/end2end/tests/hpack_size.c +++ b/test/core/end2end/tests/hpack_size.c @@ -310,7 +310,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t index) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -335,8 +335,8 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t index) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/idempotent_request.c b/test/core/end2end/tests/idempotent_request.c index dfedcfebee..65f6dd08c5 100644 --- a/test/core/end2end/tests/idempotent_request.c +++ b/test/core/end2end/tests/idempotent_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -197,8 +195,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 9c9ca95129..1df237cb6c 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -39,12 +39,11 @@ #include <grpc/byte_buffer.h> #include <grpc/support/alloc.h> #include <grpc/support/log.h> +#include <grpc/support/string_util.h> #include <grpc/support/time.h> #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -101,9 +100,25 @@ static gpr_slice large_slice(void) { return slice; } -static void test_invoke_large_request(grpc_end2end_test_config config) { +static void test_invoke_large_request(grpc_end2end_test_config config, + int max_frame_size, int lookahead_bytes) { + char *name; + gpr_asprintf(&name, + "test_invoke_large_request:max_frame_size=%d:lookahead_bytes=%d", + max_frame_size, lookahead_bytes); + + grpc_arg args[2]; + args[0].type = GRPC_ARG_INTEGER; + args[0].key = GRPC_ARG_HTTP2_MAX_FRAME_SIZE; + args[0].value.integer = max_frame_size; + args[1].type = GRPC_ARG_INTEGER; + args[1].key = GRPC_ARG_HTTP2_STREAM_LOOKAHEAD_BYTES; + args[1].value.integer = lookahead_bytes; + grpc_channel_args channel_args = {GPR_ARRAY_SIZE(args), args}; + grpc_end2end_test_fixture f = - begin_test(config, "test_invoke_large_request", NULL, NULL); + begin_test(config, name, &channel_args, &channel_args); + gpr_free(name); gpr_slice request_payload_slice = large_slice(); gpr_slice response_payload_slice = large_slice(); @@ -179,7 +194,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -197,7 +212,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -222,8 +237,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); @@ -255,7 +270,26 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { } void invoke_large_request(grpc_end2end_test_config config) { - test_invoke_large_request(config); + test_invoke_large_request(config, 16384, 65536); + test_invoke_large_request(config, 32768, 65536); + + test_invoke_large_request(config, 1000000 - 1, 65536); + test_invoke_large_request(config, 1000000, 65536); + test_invoke_large_request(config, 1000000 + 1, 65536); + test_invoke_large_request(config, 1000000 + 2, 65536); + test_invoke_large_request(config, 1000000 + 3, 65536); + test_invoke_large_request(config, 1000000 + 4, 65536); + test_invoke_large_request(config, 1000000 + 5, 65536); + test_invoke_large_request(config, 1000000 + 6, 65536); + + test_invoke_large_request(config, 1000000 - 1, 2000000); + test_invoke_large_request(config, 1000000, 2000000); + test_invoke_large_request(config, 1000000 + 1, 2000000); + test_invoke_large_request(config, 1000000 + 2, 2000000); + test_invoke_large_request(config, 1000000 + 3, 2000000); + test_invoke_large_request(config, 1000000 + 4, 2000000); + test_invoke_large_request(config, 1000000 + 5, 2000000); + test_invoke_large_request(config, 1000000 + 6, 2000000); } void invoke_large_request_pre_init(void) {} diff --git a/test/core/end2end/tests/large_metadata.c b/test/core/end2end/tests/large_metadata.c index 1f27896019..eb174a2dbb 100644 --- a/test/core/end2end/tests/large_metadata.c +++ b/test/core/end2end/tests/large_metadata.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -181,7 +179,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -200,7 +198,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -222,8 +220,8 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c index 2c6519881a..59d054cf87 100644 --- a/test/core/end2end/tests/load_reporting_hook.c +++ b/test/core/end2end/tests/load_reporting_hook.c @@ -204,7 +204,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f, grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -222,7 +222,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f, 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -249,8 +249,8 @@ static void request_response_with_payload(grpc_end2end_test_fixture f, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 41de74ff87..65fa946838 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -155,7 +153,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -180,8 +178,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); @@ -382,17 +380,17 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { error = grpc_call_start_batch(s1, ops, (size_t)(op - ops), tag(102), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(live_call + 2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 2), 1); /* first request is finished, we should be able to start the second */ live_call = (live_call == 300) ? 400 : 300; - cq_expect_completion(cqv, tag(live_call + 1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 1), 1); cq_verify(cqv); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( f.server, &s2, &call_details, &request_metadata_recv, f.cq, f.cq, tag(201))); - cq_expect_completion(cqv, tag(201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(201), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -417,8 +415,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { error = grpc_call_start_batch(s2, ops, (size_t)(op - ops), tag(202), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(live_call + 2), 1); - cq_expect_completion(cqv, tag(202), 1); + CQ_EXPECT_COMPLETION(cqv, tag(live_call + 2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(202), 1); cq_verify(cqv); cq_verifier_destroy(cqv); diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 08d326ab4d..cdca3e6748 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -100,19 +98,22 @@ static void end_test(grpc_end2end_test_fixture *f) { grpc_completion_queue_destroy(f->cq); } -static void test_max_message_length(grpc_end2end_test_config config) { +static void test_max_message_length(grpc_end2end_test_config config, + bool send_limit) { + gpr_log(GPR_INFO, "testing with send_limit=%d", send_limit); + grpc_end2end_test_fixture f; - grpc_arg server_arg; - grpc_channel_args server_args; - grpc_call *c; - grpc_call *s; + grpc_arg channel_arg; + grpc_channel_args channel_args; + grpc_call *c = NULL; + grpc_call *s = NULL; cq_verifier *cqv; grpc_op ops[6]; grpc_op *op; gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); grpc_byte_buffer *request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1); - grpc_byte_buffer *recv_payload; + grpc_byte_buffer *recv_payload = NULL; grpc_metadata_array initial_metadata_recv; grpc_metadata_array trailing_metadata_recv; grpc_metadata_array request_metadata_recv; @@ -123,14 +124,17 @@ static void test_max_message_length(grpc_end2end_test_config config) { size_t details_capacity = 0; int was_cancelled = 2; - server_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH; - server_arg.type = GRPC_ARG_INTEGER; - server_arg.value.integer = 5; + channel_arg.key = send_limit ? GRPC_ARG_MAX_SEND_MESSAGE_LENGTH + : GRPC_ARG_MAX_RECEIVE_MESSAGE_LENGTH; + channel_arg.type = GRPC_ARG_INTEGER; + channel_arg.value.integer = 5; - server_args.num_args = 1; - server_args.args = &server_arg; + channel_args.num_args = 1; + channel_args.args = &channel_arg; - f = begin_test(config, "test_max_message_length", NULL, &server_args); + f = begin_test(config, "test_max_message_length", + send_limit ? &channel_args : NULL, + send_limit ? NULL : &channel_args); cqv = cq_verifier_create(f.cq); c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, @@ -175,11 +179,17 @@ static void test_max_message_length(grpc_end2end_test_config config) { error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); + if (send_limit) { + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + goto done; + } + error = grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -197,15 +207,20 @@ static void test_max_message_length(grpc_end2end_test_config config) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); - GPR_ASSERT(status != GRPC_STATUS_OK); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234")); GPR_ASSERT(was_cancelled == 1); - GPR_ASSERT(recv_payload == NULL); + +done: + GPR_ASSERT(status == GRPC_STATUS_INVALID_ARGUMENT); + GPR_ASSERT(strcmp(details, + send_limit + ? "Sent message larger than max (11 vs. 5)" + : "Received message larger than max (11 vs. 5)") == 0); gpr_free(details); grpc_metadata_array_destroy(&initial_metadata_recv); @@ -213,9 +228,10 @@ static void test_max_message_length(grpc_end2end_test_config config) { grpc_metadata_array_destroy(&request_metadata_recv); grpc_call_details_destroy(&call_details); grpc_byte_buffer_destroy(request_payload); + grpc_byte_buffer_destroy(recv_payload); grpc_call_destroy(c); - grpc_call_destroy(s); + if (s != NULL) grpc_call_destroy(s); cq_verifier_destroy(cqv); @@ -224,7 +240,8 @@ static void test_max_message_length(grpc_end2end_test_config config) { } void max_message_length(grpc_end2end_test_config config) { - test_max_message_length(config); + test_max_message_length(config, true); + test_max_message_length(config, false); } void max_message_length_pre_init(void) {} diff --git a/test/core/end2end/tests/negative_deadline.c b/test/core/end2end/tests/negative_deadline.c index dff7992f63..c999ac116a 100644 --- a/test/core/end2end/tests/negative_deadline.c +++ b/test/core/end2end/tests/negative_deadline.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -150,7 +148,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, size_t num_ops) { error = grpc_call_start_batch(c, ops, num_ops, tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); diff --git a/test/core/end2end/tests/network_status_change.c b/test/core/end2end/tests/network_status_change.c index 39ddc13754..1d4b6dbb18 100644 --- a/test/core/end2end/tests/network_status_change.c +++ b/test/core/end2end/tests/network_status_change.c @@ -46,8 +46,6 @@ /* this is a private API but exposed here for testing*/ extern void grpc_network_status_shutdown_all_endpoints(); -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -168,7 +166,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); op = ops; @@ -185,7 +183,7 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); // Simulate the network loss event @@ -207,8 +205,8 @@ static void test_invoke_network_status_change(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); // Expected behavior of a RPC when network is lost. diff --git a/test/core/end2end/tests/no_logging.c b/test/core/end2end/tests/no_logging.c new file mode 100644 index 0000000000..430bfdc797 --- /dev/null +++ b/test/core/end2end/tests/no_logging.c @@ -0,0 +1,302 @@ +/* + * + * 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. + * + */ + +#include "test/core/end2end/end2end_tests.h" + +#include <stdio.h> +#include <string.h> + +#include <grpc/byte_buffer.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> +#include <grpc/support/useful.h> +#include "src/core/lib/iomgr/error.h" +#include "src/core/lib/support/string.h" +#include "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +static void *tag(intptr_t t) { return (void *)t; } + +extern void gpr_default_log(gpr_log_func_args *args); + +static void test_no_log(gpr_log_func_args *args) { + char *message = NULL; + gpr_asprintf(&message, "Unwanted log: %s", args->message); + args->message = message; + gpr_default_log(args); + gpr_free(message); + abort(); +} + +static void test_no_error_log(gpr_log_func_args *args) { + if (args->severity == GPR_LOG_SEVERITY_ERROR) { + test_no_log(args); + } +} + +static gpr_atm g_log_func = (gpr_atm)gpr_default_log; + +static void log_dispatcher_func(gpr_log_func_args *args) { + gpr_log_func log_func = (gpr_log_func)gpr_atm_no_barrier_load(&g_log_func); + log_func(args); +} + +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), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), 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); +} + +static void simple_request_body(grpc_end2end_test_fixture f) { + grpc_call *c; + grpc_call *s; + gpr_timespec deadline = five_seconds_time(); + 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_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + char *peer; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr:1234", deadline, + NULL); + GPR_ASSERT(c); + + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + + 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->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + 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->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + cq_verify(cqv); + + peer = grpc_call_get_peer(s); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + peer = grpc_call_get_peer(c); + GPR_ASSERT(peer != NULL); + gpr_free(peer); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + 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_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); + GPR_ASSERT(0 == strcmp(details, "xyz")); + GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234")); + GPR_ASSERT(0 == call_details.flags); + GPR_ASSERT(was_cancelled == 1); + + gpr_free(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); +} + +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + f = begin_test(config, "test_invoke_simple_request_with_no_error_logging", + NULL, NULL); + simple_request_body(f); + end_test(&f); + config.tear_down_data(&f); +} + +static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { + int i; + grpc_end2end_test_fixture f = + begin_test(config, "test_invoke_10_simple_requests_with_no_error_logging", + NULL, NULL); + for (i = 0; i < 10; i++) { + simple_request_body(f); + gpr_log(GPR_INFO, "Passed simple request %d", i); + } + simple_request_body(f); + end_test(&f); + config.tear_down_data(&f); +} + +static void test_no_error_logging_in_entire_process( + grpc_end2end_test_config config) { + int i; + gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)test_no_error_log); + for (i = 0; i < 10; i++) { + test_invoke_simple_request(config); + } + test_invoke_10_simple_requests(config); + gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)gpr_default_log); +} + +static void test_no_logging_in_one_request(grpc_end2end_test_config config) { + int i; + grpc_end2end_test_fixture f = + begin_test(config, "test_no_logging_in_last_request", NULL, NULL); + for (i = 0; i < 10; i++) { + simple_request_body(f); + } + gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)test_no_log); + simple_request_body(f); + gpr_atm_no_barrier_store(&g_log_func, (gpr_atm)gpr_default_log); + end_test(&f); + config.tear_down_data(&f); +} + +void no_logging(grpc_end2end_test_config config) { + gpr_set_log_function(log_dispatcher_func); + test_no_logging_in_one_request(config); + test_no_error_logging_in_entire_process(config); + gpr_set_log_function(gpr_default_log); +} + +void no_logging_pre_init(void) {} diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 284be7af2a..8b29c219dc 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/payload.c b/test/core/end2end/tests/payload.c index 443d85eecc..c71704ff61 100644 --- a/test/core/end2end/tests/payload.c +++ b/test/core/end2end/tests/payload.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -172,7 +170,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -190,7 +188,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -215,8 +213,8 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/ping.c b/test/core/end2end/tests/ping.c index d49bec983b..5e5169dedc 100644 --- a/test/core/end2end/tests/ping.c +++ b/test/core/end2end/tests/ping.c @@ -52,7 +52,7 @@ static void test_ping(grpc_end2end_test_config config) { config.init_server(&f, NULL); grpc_channel_ping(f.client, f.cq, tag(0), NULL); - cq_expect_completion(cqv, tag(0), 0); + CQ_EXPECT_COMPLETION(cqv, tag(0), 0); /* check that we're still in idle, and start connecting */ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) == @@ -62,7 +62,7 @@ static void test_ping(grpc_end2end_test_config config) { while (state != GRPC_CHANNEL_READY) { grpc_channel_watch_connectivity_state( f.client, state, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3), f.cq, tag(99)); - cq_expect_completion(cqv, tag(99), 1); + CQ_EXPECT_COMPLETION(cqv, tag(99), 1); cq_verify(cqv); state = grpc_channel_check_connectivity_state(f.client, 0); GPR_ASSERT(state == GRPC_CHANNEL_READY || @@ -72,12 +72,12 @@ static void test_ping(grpc_end2end_test_config config) { for (i = 1; i <= 5; i++) { grpc_channel_ping(f.client, f.cq, tag(i), NULL); - cq_expect_completion(cqv, tag(i), 1); + CQ_EXPECT_COMPLETION(cqv, tag(i), 1); cq_verify(cqv); } grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead)); - cq_expect_completion(cqv, tag(0xdead), 1); + CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1); cq_verify(cqv); /* cleanup server */ diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 1d2f7943c1..7e360c415b 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -162,7 +160,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(100)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(100), 1); + CQ_EXPECT_COMPLETION(cqv, tag(100), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -208,7 +206,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -220,8 +218,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); grpc_byte_buffer_destroy(request_payload); @@ -254,10 +252,10 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(1), 1); - cq_expect_completion(cqv, tag(3), 1); - cq_expect_completion(cqv, tag(101), 1); - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); cq_verify(cqv); grpc_call_destroy(c); diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index ece6250ea1..9b2b42b558 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -156,7 +154,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, void *rc) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -181,8 +179,8 @@ static void simple_request_body(grpc_end2end_test_fixture f, void *rc) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/request_with_flags.c b/test/core/end2end/tests/request_with_flags.c index b5d398bba9..25150e6f2d 100644 --- a/test/core/end2end/tests/request_with_flags.c +++ b/test/core/end2end/tests/request_with_flags.c @@ -44,8 +44,6 @@ #include "src/core/lib/transport/byte_stream.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -165,7 +163,7 @@ static void test_invoke_request_with_flags( GPR_ASSERT(expectation == error); if (expectation == GRPC_CALL_OK) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); } diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index d94267e09c..67208c050c 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -165,7 +163,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -183,7 +181,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -203,8 +201,8 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c index a723c6fd2c..7fb9025aa3 100644 --- a/test/core/end2end/tests/server_finishes_request.c +++ b/test/core/end2end/tests/server_finishes_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -153,7 +151,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -178,8 +176,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/shutdown_finishes_calls.c b/test/core/end2end/tests/shutdown_finishes_calls.c index abb6b26a87..dff2e6f280 100644 --- a/test/core/end2end/tests/shutdown_finishes_calls.c +++ b/test/core/end2end/tests/shutdown_finishes_calls.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -147,7 +145,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -164,9 +162,9 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_server_shutdown_and_notify(f.server, f.cq, tag(1000)); grpc_server_cancel_all_calls(f.server); - cq_expect_completion(cqv, tag(1000), 1); - cq_expect_completion(cqv, tag(102), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); grpc_server_destroy(f.server); diff --git a/test/core/end2end/tests/shutdown_finishes_tags.c b/test/core/end2end/tests/shutdown_finishes_tags.c index b1f3c94562..1d110a74ea 100644 --- a/test/core/end2end/tests/shutdown_finishes_tags.c +++ b/test/core/end2end/tests/shutdown_finishes_tags.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -104,8 +102,8 @@ static void test_early_server_shutdown_finishes_tags( f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101))); grpc_server_shutdown_and_notify(f.server, f.cq, tag(1000)); - cq_expect_completion(cqv, tag(101), 0); - cq_expect_completion(cqv, tag(1000), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 0); + CQ_EXPECT_COMPLETION(cqv, tag(1000), 1); cq_verify(cqv); GPR_ASSERT(s == NULL); diff --git a/test/core/end2end/tests/simple_cacheable_request.c b/test/core/end2end/tests/simple_cacheable_request.c new file mode 100644 index 0000000000..b52eb19315 --- /dev/null +++ b/test/core/end2end/tests/simple_cacheable_request.c @@ -0,0 +1,276 @@ +/* + * + * 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 "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 "test/core/end2end/cq_verifier.h" + +enum { TIMEOUT = 200000 }; + +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), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), 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); +} + +/* Request/response with metadata and payload.*/ +static void test_cacheable_request_response_with_metadata_and_payload( + grpc_end2end_test_config config) { + grpc_call *c; + grpc_call *s; + gpr_slice request_payload_slice = gpr_slice_from_copied_string("hello world"); + gpr_slice response_payload_slice = gpr_slice_from_copied_string("hello you"); + grpc_byte_buffer *request_payload = + grpc_raw_byte_buffer_create(&request_payload_slice, 1); + grpc_byte_buffer *response_payload = + grpc_raw_byte_buffer_create(&response_payload_slice, 1); + gpr_timespec deadline = five_seconds_time(); + grpc_metadata meta_c[2] = { + {"key1", "val1", 4, 0, {{NULL, NULL, NULL, NULL}}}, + {"key2", "val2", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_metadata meta_s[2] = { + {"key3", "val3", 4, 0, {{NULL, NULL, NULL, NULL}}}, + {"key4", "val4", 4, 0, {{NULL, NULL, NULL, NULL}}}}; + grpc_end2end_test_fixture f = begin_test( + config, "test_cacheable_request_response_with_metadata_and_payload", NULL, + 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 *request_payload_recv = NULL; + grpc_byte_buffer *response_payload_recv = NULL; + grpc_call_details call_details; + grpc_status_code status; + grpc_call_error error; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + + c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq, + "/foo", "foo.test.google.fr", 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 = 2; + op->data.send_initial_metadata.metadata = meta_c; + op->flags = GRPC_INITIAL_METADATA_CACHEABLE_REQUEST; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = request_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &response_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + 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->data.recv_status_on_client.status_details_capacity = &details_capacity; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + error = + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.cq, f.cq, tag(101)); + GPR_ASSERT(GRPC_CALL_OK == error); + 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 = 2; + op->data.send_initial_metadata.metadata = meta_s; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + 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); + + memset(ops, 0, sizeof(ops)); + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_MESSAGE; + op->data.send_message = response_payload; + op->flags = 0; + op->reserved = NULL; + op++; + op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; + op->data.send_status_from_server.trailing_metadata_count = 0; + op->data.send_status_from_server.status = GRPC_STATUS_OK; + op->data.send_status_from_server.status_details = "xyz"; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + cq_verify(cqv); + + GPR_ASSERT(status == GRPC_STATUS_OK); + GPR_ASSERT(0 == strcmp(details, "xyz")); + GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); + if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { + // Our simple proxy does not support cacheable requests + } else { + GPR_ASSERT(GRPC_INITIAL_METADATA_CACHEABLE_REQUEST & call_details.flags); + } + GPR_ASSERT(was_cancelled == 0); + GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); + GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); + GPR_ASSERT(contains_metadata(&request_metadata_recv, "key1", "val1")); + GPR_ASSERT(contains_metadata(&request_metadata_recv, "key2", "val2")); + GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key3", "val3")); + GPR_ASSERT(contains_metadata(&initial_metadata_recv, "key4", "val4")); + + gpr_free(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(request_payload); + grpc_byte_buffer_destroy(response_payload); + grpc_byte_buffer_destroy(request_payload_recv); + grpc_byte_buffer_destroy(response_payload_recv); + + end_test(&f); + config.tear_down_data(&f); +} + +void simple_cacheable_request(grpc_end2end_test_config config) { + test_cacheable_request_response_with_metadata_and_payload(config); +} + +void simple_cacheable_request_pre_init(void) {} diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index e1fcc035bb..74f1232d78 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { @@ -150,7 +148,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, f->cq, f->cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -175,8 +173,8 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/simple_metadata.c b/test/core/end2end/tests/simple_metadata.c index c9b1a03da5..13c77c033e 100644 --- a/test/core/end2end/tests/simple_metadata.c +++ b/test/core/end2end/tests/simple_metadata.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -183,7 +181,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -202,7 +200,7 @@ static void test_request_response_with_metadata_and_payload( 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -227,8 +225,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index a8014e6894..ed7b850808 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -45,8 +45,6 @@ #include "src/core/lib/support/string.h" #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); peer = grpc_call_get_peer(s); @@ -197,8 +195,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { 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_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(102), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); diff --git a/test/core/end2end/tests/streaming_error_response.c b/test/core/end2end/tests/streaming_error_response.c index e15c132d63..8285468321 100644 --- a/test/core/end2end/tests/streaming_error_response.c +++ b/test/core/end2end/tests/streaming_error_response.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -163,7 +161,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { 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_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -177,7 +175,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -188,9 +186,9 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); if (!request_status_early) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } cq_verify(cqv); @@ -217,11 +215,11 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { GPR_ASSERT(GRPC_CALL_OK == error); } - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); if (request_status_early) { - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); } else { - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); } cq_verify(cqv); @@ -237,7 +235,7 @@ static void test(grpc_end2end_test_config config, bool request_status_early) { 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_EXPECT_COMPLETION(cqv, tag(3), 1); cq_verify(cqv); GPR_ASSERT(response_payload1_recv != NULL); diff --git a/test/core/end2end/tests/trailing_metadata.c b/test/core/end2end/tests/trailing_metadata.c index 41e0f00911..d7093ae723 100644 --- a/test/core/end2end/tests/trailing_metadata.c +++ b/test/core/end2end/tests/trailing_metadata.c @@ -43,8 +43,6 @@ #include <grpc/support/useful.h> #include "test/core/end2end/cq_verifier.h" -enum { TIMEOUT = 200000 }; - static void *tag(intptr_t t) { return (void *)t; } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, @@ -186,7 +184,7 @@ static void test_request_response_with_metadata_and_payload( grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, f.cq, f.cq, tag(101)); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -205,7 +203,7 @@ static void test_request_response_with_metadata_and_payload( 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_EXPECT_COMPLETION(cqv, tag(102), 1); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -231,8 +229,8 @@ static void test_request_response_with_metadata_and_payload( error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(103), 1); - cq_expect_completion(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(103), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); cq_verify(cqv); GPR_ASSERT(status == GRPC_STATUS_OK); diff --git a/test/core/http/parser_test.c b/test/core/http/parser_test.c index d645d2879c..2fc354d9ee 100644 --- a/test/core/http/parser_test.c +++ b/test/core/http/parser_test.c @@ -62,7 +62,8 @@ static void test_request_succeeds(grpc_slice_split_mode split_mode, grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request); for (i = 0; i < num_slices; i++) { - GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i]) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], NULL) == + GRPC_ERROR_NONE); gpr_slice_unref(slices[i]); } GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE); @@ -118,7 +119,8 @@ static void test_succeeds(grpc_slice_split_mode split_mode, char *response_text, grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); for (i = 0; i < num_slices; i++) { - GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i]) == GRPC_ERROR_NONE); + GPR_ASSERT(grpc_http_parser_parse(&parser, slices[i], NULL) == + GRPC_ERROR_NONE); gpr_slice_unref(slices[i]); } GPR_ASSERT(grpc_http_parser_eof(&parser) == GRPC_ERROR_NONE); @@ -171,7 +173,7 @@ static void test_fails(grpc_slice_split_mode split_mode, char *response_text) { for (i = 0; i < num_slices; i++) { if (GRPC_ERROR_NONE == error) { - error = grpc_http_parser_parse(&parser, slices[i]); + error = grpc_http_parser_parse(&parser, slices[i], NULL); } gpr_slice_unref(slices[i]); } @@ -204,7 +206,7 @@ static void test_request_fails(grpc_slice_split_mode split_mode, for (i = 0; i < num_slices; i++) { if (error == GRPC_ERROR_NONE) { - error = grpc_http_parser_parse(&parser, slices[i]); + error = grpc_http_parser_parse(&parser, slices[i], NULL); } gpr_slice_unref(slices[i]); } diff --git a/test/core/http/request_fuzzer.c b/test/core/http/request_fuzzer.c index 5941401867..bb6cb92c0c 100644 --- a/test/core/http/request_fuzzer.c +++ b/test/core/http/request_fuzzer.c @@ -48,7 +48,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memset(&request, 0, sizeof(request)); grpc_http_parser_init(&parser, GRPC_HTTP_REQUEST, &request); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); - GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice)); + GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice, NULL)); GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser)); gpr_slice_unref(slice); grpc_http_parser_destroy(&parser); diff --git a/test/core/http/response_fuzzer.c b/test/core/http/response_fuzzer.c index acde7c80a4..4393840484 100644 --- a/test/core/http/response_fuzzer.c +++ b/test/core/http/response_fuzzer.c @@ -47,7 +47,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { memset(&response, 0, sizeof(response)); grpc_http_parser_init(&parser, GRPC_HTTP_RESPONSE, &response); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); - GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice)); + GRPC_ERROR_UNREF(grpc_http_parser_parse(&parser, slice, NULL)); GRPC_ERROR_UNREF(grpc_http_parser_eof(&parser)); gpr_slice_unref(slice); grpc_http_parser_destroy(&parser); diff --git a/test/core/iomgr/combiner_test.c b/test/core/iomgr/combiner_test.c new file mode 100644 index 0000000000..197998c1e5 --- /dev/null +++ b/test/core/iomgr/combiner_test.c @@ -0,0 +1,164 @@ +/* + * + * 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/combiner.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 "test/core/util/test_config.h" + +static void test_no_op(void) { + gpr_log(GPR_DEBUG, "test_no_op"); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_combiner_destroy(&exec_ctx, grpc_combiner_create(NULL)); + grpc_exec_ctx_finish(&exec_ctx); +} + +static void set_bool_to_true(grpc_exec_ctx *exec_ctx, void *value, + grpc_error *error) { + *(bool *)value = true; +} + +static void test_execute_one(void) { + gpr_log(GPR_DEBUG, "test_execute_one"); + + grpc_combiner *lock = grpc_combiner_create(NULL); + bool done = false; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_combiner_execute(&exec_ctx, lock, + grpc_closure_create(set_bool_to_true, &done), + GRPC_ERROR_NONE); + grpc_exec_ctx_flush(&exec_ctx); + GPR_ASSERT(done); + grpc_combiner_destroy(&exec_ctx, lock); + grpc_exec_ctx_finish(&exec_ctx); +} + +typedef struct { + size_t ctr; + grpc_combiner *lock; +} thd_args; + +typedef struct { + size_t *ctr; + size_t value; +} ex_args; + +static void check_one(grpc_exec_ctx *exec_ctx, void *a, grpc_error *error) { + ex_args *args = a; + GPR_ASSERT(*args->ctr == args->value - 1); + *args->ctr = args->value; + gpr_free(a); +} + +static void execute_many_loop(void *a) { + thd_args *args = a; + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + size_t n = 1; + for (size_t i = 0; i < 10; i++) { + for (size_t j = 0; j < 10000; j++) { + ex_args *c = gpr_malloc(sizeof(*c)); + c->ctr = &args->ctr; + c->value = n++; + grpc_combiner_execute(&exec_ctx, args->lock, + grpc_closure_create(check_one, c), GRPC_ERROR_NONE); + grpc_exec_ctx_flush(&exec_ctx); + } + // sleep for a little bit, to test a combiner draining and another thread + // picking it up + gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100)); + } + grpc_exec_ctx_finish(&exec_ctx); +} + +static void test_execute_many(void) { + gpr_log(GPR_DEBUG, "test_execute_many"); + + grpc_combiner *lock = grpc_combiner_create(NULL); + gpr_thd_id thds[100]; + thd_args ta[GPR_ARRAY_SIZE(thds)]; + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + ta[i].ctr = 0; + ta[i].lock = lock; + GPR_ASSERT(gpr_thd_new(&thds[i], execute_many_loop, &ta[i], &options)); + } + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_join(thds[i]); + } + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_combiner_destroy(&exec_ctx, lock); + grpc_exec_ctx_finish(&exec_ctx); +} + +static bool got_in_finally = false; + +static void in_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + got_in_finally = true; +} + +static void add_finally(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { + grpc_combiner_execute_finally(exec_ctx, arg, + grpc_closure_create(in_finally, NULL), + GRPC_ERROR_NONE, false); +} + +static void test_execute_finally(void) { + gpr_log(GPR_DEBUG, "test_execute_finally"); + + grpc_combiner *lock = grpc_combiner_create(NULL); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_combiner_execute(&exec_ctx, lock, grpc_closure_create(add_finally, lock), + GRPC_ERROR_NONE); + grpc_exec_ctx_flush(&exec_ctx); + GPR_ASSERT(got_in_finally); + grpc_combiner_destroy(&exec_ctx, lock); + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + grpc_init(); + test_no_op(); + test_execute_one(); + test_execute_finally(); + test_execute_many(); + grpc_shutdown(); + + return 0; +} diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c index 75a99faf3f..a82f20df83 100644 --- a/test/core/nanopb/fuzzer_response.c +++ b/test/core/nanopb/fuzzer_response.c @@ -41,7 +41,10 @@ bool squelch = true; bool leak_check = true; +static void dont_log(gpr_log_func_args *args) {} + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (squelch) gpr_set_log_function(dont_log); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); grpc_grpclb_initial_response *response; if ((response = grpc_grpclb_initial_response_parse(slice))) { diff --git a/test/core/nanopb/fuzzer_serverlist.c b/test/core/nanopb/fuzzer_serverlist.c index df2044d907..9700bf1cda 100644 --- a/test/core/nanopb/fuzzer_serverlist.c +++ b/test/core/nanopb/fuzzer_serverlist.c @@ -41,7 +41,10 @@ bool squelch = true; bool leak_check = true; +static void dont_log(gpr_log_func_args *args) {} + int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + if (squelch) gpr_set_log_function(dont_log); gpr_slice slice = gpr_slice_from_copied_buffer((const char *)data, size); grpc_grpclb_serverlist *serverlist; if ((serverlist = grpc_grpclb_response_parse_serverlist(slice))) { diff --git a/test/core/support/mpscq_test.c b/test/core/support/mpscq_test.c new file mode 100644 index 0000000000..491eb9148b --- /dev/null +++ b/test/core/support/mpscq_test.c @@ -0,0 +1,206 @@ +/* + * + * 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. + * + */ + +#include "src/core/lib/support/mpscq.h" + +#include <stdlib.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <grpc/support/useful.h> +#include "test/core/util/test_config.h" + +typedef struct test_node { + gpr_mpscq_node node; + size_t i; + size_t *ctr; +} test_node; + +static test_node *new_node(size_t i, size_t *ctr) { + test_node *n = gpr_malloc(sizeof(test_node)); + n->i = i; + n->ctr = ctr; + return n; +} + +static void test_serial(void) { + gpr_log(GPR_DEBUG, "test_serial"); + gpr_mpscq q; + gpr_mpscq_init(&q); + for (size_t i = 0; i < 10000000; i++) { + gpr_mpscq_push(&q, &new_node(i, NULL)->node); + } + for (size_t i = 0; i < 10000000; i++) { + test_node *n = (test_node *)gpr_mpscq_pop(&q); + GPR_ASSERT(n); + GPR_ASSERT(n->i == i); + gpr_free(n); + } +} + +typedef struct { + size_t ctr; + gpr_mpscq *q; + gpr_event *start; +} thd_args; + +#define THREAD_ITERATIONS 100000 + +static void test_thread(void *args) { + thd_args *a = args; + gpr_event_wait(a->start, gpr_inf_future(GPR_CLOCK_REALTIME)); + for (size_t i = 1; i <= THREAD_ITERATIONS; i++) { + gpr_mpscq_push(a->q, &new_node(i, &a->ctr)->node); + } +} + +static void test_mt(void) { + gpr_log(GPR_DEBUG, "test_mt"); + gpr_event start; + gpr_event_init(&start); + gpr_thd_id thds[100]; + thd_args ta[GPR_ARRAY_SIZE(thds)]; + gpr_mpscq q; + gpr_mpscq_init(&q); + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + ta[i].ctr = 0; + ta[i].q = &q; + ta[i].start = &start; + GPR_ASSERT(gpr_thd_new(&thds[i], test_thread, &ta[i], &options)); + } + size_t num_done = 0; + size_t spins = 0; + gpr_event_set(&start, (void *)1); + while (num_done != GPR_ARRAY_SIZE(thds)) { + gpr_mpscq_node *n; + while ((n = gpr_mpscq_pop(&q)) == NULL) { + spins++; + } + test_node *tn = (test_node *)n; + GPR_ASSERT(*tn->ctr == tn->i - 1); + *tn->ctr = tn->i; + if (tn->i == THREAD_ITERATIONS) num_done++; + gpr_free(tn); + } + gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, spins); + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_join(thds[i]); + } + gpr_mpscq_destroy(&q); +} + +typedef struct { + thd_args *ta; + size_t num_thds; + gpr_mu mu; + size_t num_done; + size_t spins; + gpr_mpscq *q; + gpr_event *start; +} pull_args; + +static void pull_thread(void *arg) { + pull_args *pa = arg; + gpr_event_wait(pa->start, gpr_inf_future(GPR_CLOCK_REALTIME)); + + for (;;) { + gpr_mu_lock(&pa->mu); + if (pa->num_done == pa->num_thds) { + gpr_mu_unlock(&pa->mu); + return; + } + gpr_mpscq_node *n; + while ((n = gpr_mpscq_pop(pa->q)) == NULL) { + pa->spins++; + } + test_node *tn = (test_node *)n; + GPR_ASSERT(*tn->ctr == tn->i - 1); + *tn->ctr = tn->i; + if (tn->i == THREAD_ITERATIONS) pa->num_done++; + gpr_free(tn); + gpr_mu_unlock(&pa->mu); + } +} + +static void test_mt_multipop(void) { + gpr_log(GPR_DEBUG, "test_mt_multipop"); + gpr_event start; + gpr_event_init(&start); + gpr_thd_id thds[100]; + gpr_thd_id pull_thds[100]; + thd_args ta[GPR_ARRAY_SIZE(thds)]; + gpr_mpscq q; + gpr_mpscq_init(&q); + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + ta[i].ctr = 0; + ta[i].q = &q; + ta[i].start = &start; + GPR_ASSERT(gpr_thd_new(&thds[i], test_thread, &ta[i], &options)); + } + pull_args pa; + pa.ta = ta; + pa.num_thds = GPR_ARRAY_SIZE(thds); + pa.spins = 0; + pa.num_done = 0; + pa.q = &q; + pa.start = &start; + gpr_mu_init(&pa.mu); + for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) { + gpr_thd_options options = gpr_thd_options_default(); + gpr_thd_options_set_joinable(&options); + GPR_ASSERT(gpr_thd_new(&pull_thds[i], pull_thread, &pa, &options)); + } + gpr_event_set(&start, (void *)1); + for (size_t i = 0; i < GPR_ARRAY_SIZE(pull_thds); i++) { + gpr_thd_join(pull_thds[i]); + } + gpr_log(GPR_DEBUG, "spins: %" PRIdPTR, pa.spins); + for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) { + gpr_thd_join(thds[i]); + } + gpr_mpscq_destroy(&q); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_serial(); + test_mt(); + test_mt_multipop(); + return 0; +} diff --git a/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 new file mode 100644 index 0000000000..a0c7605580 --- /dev/null +++ b/test/core/support/percent_decode_corpus/04cb8ccc553f9b2f5e52c421aff6d1c954d3dae6 @@ -0,0 +1 @@ +:Ê%cE'yzŠ
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 new file mode 100644 index 0000000000..8b36124b3f --- /dev/null +++ b/test/core/support/percent_decode_corpus/0dd8f3a63745b3a2d39791559b5c1b311447b537 @@ -0,0 +1 @@ +x;x_%C88
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 new file mode 100644 index 0000000000..ea02afac49 --- /dev/null +++ b/test/core/support/percent_decode_corpus/17eeaca784409adbe43365c32ac87915d736bba3 @@ -0,0 +1,2 @@ +xxyyz%øyzŠ[zxy'z + diff --git a/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 new file mode 100644 index 0000000000..9e9b466b2f --- /dev/null +++ b/test/core/support/percent_decode_corpus/2040c1ff65f52a7ae668c2c8f324de5dacc9d695 @@ -0,0 +1 @@ +xx;x_%;:Ê%C)x_%C88c8E'yzŠ8
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb new file mode 100644 index 0000000000..88c739ecaa --- /dev/null +++ b/test/core/support/percent_decode_corpus/26b0d1da23027ae54db96e125e4a9e98842d77fb @@ -0,0 +1 @@ +))'x;x_%C88xy(Pyz)
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 new file mode 100644 index 0000000000..5e6f546ff5 --- /dev/null +++ b/test/core/support/percent_decode_corpus/2a089c0db45acdb4c6ed8e7ff81ca7235792c0b9 @@ -0,0 +1 @@ +_x;x)x;x_x;x_%88%8888:
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a new file mode 100644 index 0000000000..71d688b694 --- /dev/null +++ b/test/core/support/percent_decode_corpus/35b7b3bc3a740d5c3abca0d75b53f0e1e1ee998a @@ -0,0 +1 @@ +x8
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 new file mode 100644 index 0000000000..5a89a07ba7 --- /dev/null +++ b/test/core/support/percent_decode_corpus/36367ba1adba47a1cbc3a88707fde8cc7abdc248 @@ -0,0 +1 @@ +x);x(_%88x;x_%88
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 new file mode 100644 index 0000000000..cfa2be994f --- /dev/null +++ b/test/core/support/percent_decode_corpus/39c2ba51548a0beaf0d6d1164531f1447dc311b5 @@ -0,0 +1 @@ +)x;x_x;x_%88%88:
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 new file mode 100644 index 0000000000..c1ddf65acd --- /dev/null +++ b/test/core/support/percent_decode_corpus/56d08fea787c041395c6697ce26cfbc0decbe688 @@ -0,0 +1 @@ +%cyzŠ
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 new file mode 100644 index 0000000000..dc427d1e12 --- /dev/null +++ b/test/core/support/percent_decode_corpus/678d981fdabb9f0d6640235cf1719dd1e1e66ae9 @@ -0,0 +1 @@ +%øyzŠ
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d new file mode 100644 index 0000000000..154449d0ef --- /dev/null +++ b/test/core/support/percent_decode_corpus/68751961609ec010565de0aa87521dcbf0722c5d @@ -0,0 +1 @@ +Ê:%Ec
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 new file mode 100644 index 0000000000..841ced83c3 --- /dev/null +++ b/test/core/support/percent_decode_corpus/7875c06c6f03c9aa2f8e9c59f8d8957c8a32e759 @@ -0,0 +1,2 @@ +xxyyz!úyzŠ[zxy'zyz +Š diff --git a/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f new file mode 100644 index 0000000000..6790bc2798 --- /dev/null +++ b/test/core/support/percent_decode_corpus/7b302090e090a5829b6d1dd7be30bd4e36a7e60f @@ -0,0 +1 @@ +x;:Ê%)x_%C8cE'yzŠ8
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 new file mode 100644 index 0000000000..1625d0a1ae --- /dev/null +++ b/test/core/support/percent_decode_corpus/875e1022169c9e4c541a9ad894e69e989df22ba1 @@ -0,0 +1 @@ +x;x_%88
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 new file mode 100644 index 0000000000..125c330b3e --- /dev/null +++ b/test/core/support/percent_decode_corpus/8c1051ce066f5a26de9a9d133180621d0da957b4 @@ -0,0 +1 @@ +)))'x;x_%C88)'x;x_%C89xyyzxyyz)
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 new file mode 100644 index 0000000000..6e6f08cb07 --- /dev/null +++ b/test/core/support/percent_decode_corpus/8e084e628ab83a18ac7ca7cb3506525263655c63 @@ -0,0 +1 @@ +))'x;x_%C88xyyz)
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 new file mode 100644 index 0000000000..ab4a1c7657 --- /dev/null +++ b/test/core/support/percent_decode_corpus/9d316c4675f40ddccaf8f1cc7aea94170b1e4223 @@ -0,0 +1 @@ +x%8
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae new file mode 100644 index 0000000000..4ac1945a84 --- /dev/null +++ b/test/core/support/percent_decode_corpus/ad1c7c11d18a7d116e2c2ef4d4c5afb1270836ae @@ -0,0 +1 @@ +x);x(_%88x;x_xxyyz
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 new file mode 100644 index 0000000000..5c673ae28a --- /dev/null +++ b/test/core/support/percent_decode_corpus/b471f94aa4facf502e622e4a248f1ba4063ae681 @@ -0,0 +1 @@ +Ê%ccyzyzŠ
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b new file mode 100644 index 0000000000..e478275ed4 --- /dev/null +++ b/test/core/support/percent_decode_corpus/bf52ece030f16136d46e0dc97f58d60a0d8a1f0b @@ -0,0 +1,2 @@ +)'xyyz!úyzŠ[zxÊ%ccyzyzy'z*zŠ +Š diff --git a/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 new file mode 100644 index 0000000000..c73cbfe8af --- /dev/null +++ b/test/core/support/percent_decode_corpus/d5b2a7177339ba2b7ce2f60e5f4459bef1e72758 @@ -0,0 +1,2 @@ +)'xyyz)úyzŠ[zxÊ%cCyzyzy'z*zŠ +Š diff --git a/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 new file mode 100644 index 0000000000..f9f7246e9c --- /dev/null +++ b/test/core/support/percent_decode_corpus/de867b64c54a7ed773dc611fc5cd2f17c5433113 @@ -0,0 +1,2 @@ +xxyyz%%øyzŠ[zxy'zyz +Š diff --git a/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a new file mode 100644 index 0000000000..83ac46d833 --- /dev/null +++ b/test/core/support/percent_decode_corpus/e3948dbe004950591630dd5c52f4e0fcbd5e388a @@ -0,0 +1 @@ +Ê:%Dx;:Ê%)x_%C8cc
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a new file mode 100644 index 0000000000..e8a0f87653 --- /dev/null +++ b/test/core/support/percent_decode_corpus/e7064f0b80f61dbc65915311032d27baa569ae2a @@ -0,0 +1 @@ +)
\ No newline at end of file diff --git a/test/core/support/percent_decode_corpus/xyz b/test/core/support/percent_decode_corpus/xyz new file mode 100644 index 0000000000..cd470e6190 --- /dev/null +++ b/test/core/support/percent_decode_corpus/xyz @@ -0,0 +1 @@ +xyz diff --git a/test/core/support/percent_decode_fuzzer.c b/test/core/support/percent_decode_fuzzer.c new file mode 100644 index 0000000000..3e02980e05 --- /dev/null +++ b/test/core/support/percent_decode_fuzzer.c @@ -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. + * + */ + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/support/percent_encoding.h" +#include "test/core/util/memory_counters.h" + +bool squelch = true; +bool leak_check = true; + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct grpc_memory_counters counters; + grpc_memory_counters_init(); + gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); + gpr_slice output; + if (gpr_strict_percent_decode_slice( + input, gpr_url_percent_encoding_unreserved_bytes, &output)) { + gpr_slice_unref(output); + } + if (gpr_strict_percent_decode_slice( + input, gpr_compatible_percent_encoding_unreserved_bytes, &output)) { + gpr_slice_unref(output); + } + gpr_slice_unref(gpr_permissive_percent_decode_slice(input)); + gpr_slice_unref(input); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); + return 0; +} diff --git a/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f new file mode 100644 index 0000000000..d09c4a039c --- /dev/null +++ b/test/core/support/percent_encode_corpus/0d3ee7fa54e6c66103965fd4409b044ba7db6c3f @@ -0,0 +1,3 @@ +_x;7y +xyz')S)xy-zý +Æ*
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 new file mode 100644 index 0000000000..4d0c38d0e2 --- /dev/null +++ b/test/core/support/percent_encode_corpus/2e7ccf75e27b9501e3b28cf1c50ed0c45ab7c226 @@ -0,0 +1 @@ +xyx
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf new file mode 100644 index 0000000000..fc6e93342a --- /dev/null +++ b/test/core/support/percent_encode_corpus/55bb859f3942c462b03b7cbcf22ab4a0ac9705cf @@ -0,0 +1 @@ +.yx.yxxxyzxyyzxy
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 new file mode 100644 index 0000000000..6823c73f76 --- /dev/null +++ b/test/core/support/percent_encode_corpus/56070cecd54c845b6d4334953b17b712eb000d93 @@ -0,0 +1 @@ +xyrxyxyzxxyzxyzxyxyy
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 new file mode 100644 index 0000000000..a65cbb4d5b --- /dev/null +++ b/test/core/support/percent_encode_corpus/61f50e891bf7ff5eb7a7af206f1e25d77f8756e7 @@ -0,0 +1,3 @@ +xy +xyz +)S-Æþ
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a new file mode 100644 index 0000000000..8d031d7e2d --- /dev/null +++ b/test/core/support/percent_encode_corpus/6e0c60cefc704c7940e475a87dd9ae423061cb5a @@ -0,0 +1,3 @@ +xy +xyz +)S)Æ*
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e new file mode 100644 index 0000000000..4d82ca3953 --- /dev/null +++ b/test/core/support/percent_encode_corpus/7271ebcc6d22a0f186f7bc3c1973a7ed1bec8d8e @@ -0,0 +1,4 @@ +x;7y +xyz +)S)xyz +Æ*
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 new file mode 100644 index 0000000000..bb7f4ae07e --- /dev/null +++ b/test/core/support/percent_encode_corpus/74c83ece3e2920a67593a9be9c82468f16cbb969 @@ -0,0 +1 @@ +xyzxy
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 new file mode 100644 index 0000000000..50879d0f37 --- /dev/null +++ b/test/core/support/percent_encode_corpus/98e004fd2a9f141a7a019720820080e12d637c06 @@ -0,0 +1,3 @@ +xy +xz +)Sxy-Æzx_yþ
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b new file mode 100644 index 0000000000..dc1ab9bfc2 --- /dev/null +++ b/test/core/support/percent_encode_corpus/ba2c1e98227aa21ea3bb2ca4d0e504119717da8b @@ -0,0 +1,3 @@ +_x;7y +xyz')S)xyz +Æ*
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 new file mode 100644 index 0000000000..3476e0b70b --- /dev/null +++ b/test/core/support/percent_encode_corpus/c16b9fd45370d4afb5d3ebd307a6e263c25ffd45 @@ -0,0 +1,2 @@ +xyz +)S
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 new file mode 100644 index 0000000000..822d50abf8 --- /dev/null +++ b/test/core/support/percent_encode_corpus/d58c3cd4eab9b6d2343abfa1c25c90a383fe0ec3 @@ -0,0 +1 @@ +.yx
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 new file mode 100644 index 0000000000..101639c93d --- /dev/null +++ b/test/core/support/percent_encode_corpus/e2619218ede30d2b7b8ecd601a9f0ae754b728b4 @@ -0,0 +1,4 @@ +x;y +xyz +)S)xyz +Æ*
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 new file mode 100644 index 0000000000..6e07ab342f --- /dev/null +++ b/test/core/support/percent_encode_corpus/f93b3653e453f0e3eea3198001be6ce46e64bd21 @@ -0,0 +1,5 @@ +x;y +xøyz +)S)xyz +Æ.y~ +)S
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 new file mode 100644 index 0000000000..13d7fab596 --- /dev/null +++ b/test/core/support/percent_encode_corpus/fd41d029c7682ad3d1c40a9fd017a4c85b673a54 @@ -0,0 +1,3 @@ +xy +xyz +)S)S
\ No newline at end of file diff --git a/test/core/support/percent_encode_corpus/xyz b/test/core/support/percent_encode_corpus/xyz new file mode 100644 index 0000000000..cd470e6190 --- /dev/null +++ b/test/core/support/percent_encode_corpus/xyz @@ -0,0 +1 @@ +xyz diff --git a/test/core/support/percent_encode_fuzzer.c b/test/core/support/percent_encode_fuzzer.c new file mode 100644 index 0000000000..c9548232b5 --- /dev/null +++ b/test/core/support/percent_encode_fuzzer.c @@ -0,0 +1,73 @@ +/* + * + * 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. + * + */ + +#include <stdbool.h> +#include <stdint.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/support/percent_encoding.h" +#include "test/core/util/memory_counters.h" + +bool squelch = true; +bool leak_check = true; + +static void test(const uint8_t *data, size_t size, const uint8_t *dict) { + struct grpc_memory_counters counters; + grpc_memory_counters_init(); + gpr_slice input = gpr_slice_from_copied_buffer((const char *)data, size); + gpr_slice output = gpr_percent_encode_slice(input, dict); + gpr_slice decoded_output; + // encoder must always produce decodable output + GPR_ASSERT(gpr_strict_percent_decode_slice(output, dict, &decoded_output)); + gpr_slice permissive_decoded_output = + gpr_permissive_percent_decode_slice(output); + // and decoded output must always match the input + GPR_ASSERT(gpr_slice_cmp(input, decoded_output) == 0); + GPR_ASSERT(gpr_slice_cmp(input, permissive_decoded_output) == 0); + gpr_slice_unref(input); + gpr_slice_unref(output); + gpr_slice_unref(decoded_output); + gpr_slice_unref(permissive_decoded_output); + counters = grpc_memory_counters_snapshot(); + grpc_memory_counters_destroy(); + GPR_ASSERT(counters.total_size_relative == 0); +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + test(data, size, gpr_url_percent_encoding_unreserved_bytes); + test(data, size, gpr_compatible_percent_encoding_unreserved_bytes); + return 0; +} diff --git a/test/core/support/percent_encoding_test.c b/test/core/support/percent_encoding_test.c new file mode 100644 index 0000000000..ab5f3f2d14 --- /dev/null +++ b/test/core/support/percent_encoding_test.c @@ -0,0 +1,157 @@ +/* + * + * 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. + * + */ + +#include "src/core/lib/support/percent_encoding.h" + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> + +#include "src/core/lib/support/string.h" +#include "test/core/util/test_config.h" + +#define TEST_VECTOR(raw, encoded, dict) \ + test_vector(raw, sizeof(raw) - 1, encoded, sizeof(encoded) - 1, dict) + +#define TEST_NONCONFORMANT_VECTOR(encoded, permissive_unencoded, dict) \ + test_nonconformant_vector(encoded, sizeof(encoded) - 1, \ + permissive_unencoded, \ + sizeof(permissive_unencoded) - 1, dict) + +static void test_vector(const char *raw, size_t raw_length, const char *encoded, + size_t encoded_length, const uint8_t *dict) { + char *raw_msg = gpr_dump(raw, raw_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded_msg = + gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", raw_msg, encoded_msg); + gpr_free(raw_msg); + gpr_free(encoded_msg); + + gpr_slice raw_slice = gpr_slice_from_copied_buffer(raw, raw_length); + gpr_slice encoded_slice = + gpr_slice_from_copied_buffer(encoded, encoded_length); + gpr_slice raw2encoded_slice = gpr_percent_encode_slice(raw_slice, dict); + gpr_slice encoded2raw_slice; + GPR_ASSERT( + gpr_strict_percent_decode_slice(encoded_slice, dict, &encoded2raw_slice)); + gpr_slice encoded2raw_permissive_slice = + gpr_permissive_percent_decode_slice(encoded_slice); + + char *raw2encoded_msg = + gpr_dump_slice(raw2encoded_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded2raw_msg = + gpr_dump_slice(encoded2raw_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded2raw_permissive_msg = gpr_dump_slice( + encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, + "Result:\nraw2encoded = %s\nencoded2raw = %s\nencoded2raw_permissive " + "= %s", + raw2encoded_msg, encoded2raw_msg, encoded2raw_permissive_msg); + gpr_free(raw2encoded_msg); + gpr_free(encoded2raw_msg); + gpr_free(encoded2raw_permissive_msg); + + GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_slice)); + GPR_ASSERT(0 == gpr_slice_cmp(raw_slice, encoded2raw_permissive_slice)); + GPR_ASSERT(0 == gpr_slice_cmp(encoded_slice, raw2encoded_slice)); + + gpr_slice_unref(encoded2raw_slice); + gpr_slice_unref(encoded2raw_permissive_slice); + gpr_slice_unref(raw2encoded_slice); + gpr_slice_unref(raw_slice); + gpr_slice_unref(encoded_slice); +} + +static void test_nonconformant_vector(const char *encoded, + size_t encoded_length, + const char *permissive_unencoded, + size_t permissive_unencoded_length, + const uint8_t *dict) { + char *permissive_unencoded_msg = + gpr_dump(permissive_unencoded, permissive_unencoded_length, + GPR_DUMP_HEX | GPR_DUMP_ASCII); + char *encoded_msg = + gpr_dump(encoded, encoded_length, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Trial:\nraw = %s\nencoded = %s", permissive_unencoded_msg, + encoded_msg); + gpr_free(permissive_unencoded_msg); + gpr_free(encoded_msg); + + gpr_slice permissive_unencoded_slice = gpr_slice_from_copied_buffer( + permissive_unencoded, permissive_unencoded_length); + gpr_slice encoded_slice = + gpr_slice_from_copied_buffer(encoded, encoded_length); + gpr_slice encoded2raw_slice; + GPR_ASSERT(!gpr_strict_percent_decode_slice(encoded_slice, dict, + &encoded2raw_slice)); + gpr_slice encoded2raw_permissive_slice = + gpr_permissive_percent_decode_slice(encoded_slice); + + char *encoded2raw_permissive_msg = gpr_dump_slice( + encoded2raw_permissive_slice, GPR_DUMP_HEX | GPR_DUMP_ASCII); + gpr_log(GPR_DEBUG, "Result:\nencoded2raw_permissive = %s", + encoded2raw_permissive_msg); + gpr_free(encoded2raw_permissive_msg); + + GPR_ASSERT(0 == gpr_slice_cmp(permissive_unencoded_slice, + encoded2raw_permissive_slice)); + + gpr_slice_unref(permissive_unencoded_slice); + gpr_slice_unref(encoded2raw_permissive_slice); + gpr_slice_unref(encoded_slice); +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + TEST_VECTOR( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.~", + gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x00", "%00", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x01", "%01", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("a b", "a%20b", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR(" b", "%20b", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("a b", "a b", gpr_compatible_percent_encoding_unreserved_bytes); + TEST_VECTOR(" b", " b", gpr_compatible_percent_encoding_unreserved_bytes); + TEST_VECTOR("\x0f", "%0F", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\xff", "%FF", gpr_url_percent_encoding_unreserved_bytes); + TEST_VECTOR("\xee", "%EE", gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%", "%", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%A", "%A", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("%AG", "%AG", + gpr_url_percent_encoding_unreserved_bytes); + TEST_NONCONFORMANT_VECTOR("\0", "\0", + gpr_url_percent_encoding_unreserved_bytes); + return 0; +} diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c index 450cc37233..580eb303f6 100644 --- a/test/core/surface/channel_create_test.c +++ b/test/core/surface/channel_create_test.c @@ -40,7 +40,7 @@ void test_unknown_scheme_target(void) { grpc_channel *chan; /* avoid default prefix */ grpc_resolver_registry_shutdown(); - grpc_resolver_registry_init(""); + grpc_resolver_registry_init(); chan = grpc_insecure_channel_create("blah://blah", NULL, NULL); GPR_ASSERT(chan != NULL); diff --git a/test/core/surface/invalid_channel_args_test.c b/test/core/surface/invalid_channel_args_test.c index 1b1b8b8f92..0640879866 100644 --- a/test/core/surface/invalid_channel_args_test.c +++ b/test/core/surface/invalid_channel_args_test.c @@ -84,38 +84,6 @@ static void one_test(grpc_channel_args *args, char *expected_error_message) { static void test_no_error_message(void) { one_test(NULL, NULL); } -static void test_max_message_length_type(void) { - grpc_arg client_arg; - grpc_channel_args client_args; - char *expected_error_message; - - client_arg.type = GRPC_ARG_STRING; - client_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH; - client_arg.value.string = NULL; - - client_args.num_args = 1; - client_args.args = &client_arg; - expected_error_message = compose_error_string( - GRPC_ARG_MAX_MESSAGE_LENGTH, " ignored: it must be an integer"); - one_test(&client_args, expected_error_message); -} - -static void test_max_message_length_negative(void) { - grpc_arg client_arg; - grpc_channel_args client_args; - char *expected_error_message; - - client_arg.type = GRPC_ARG_INTEGER; - client_arg.key = GRPC_ARG_MAX_MESSAGE_LENGTH; - client_arg.value.integer = -1; - - client_args.num_args = 1; - client_args.args = &client_arg; - expected_error_message = compose_error_string(GRPC_ARG_MAX_MESSAGE_LENGTH, - " ignored: it must be >= 0"); - one_test(&client_args, expected_error_message); -} - static void test_default_authority_type(void) { grpc_arg client_arg; grpc_channel_args client_args; @@ -174,8 +142,6 @@ int main(int argc, char **argv) { gpr_set_log_function(log_error_sink); test_no_error_message(); - test_max_message_length_type(); - test_max_message_length_negative(); test_default_authority_type(); test_ssl_name_override_type(); test_ssl_name_override_failed(); diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c index f36f980575..6afcefca92 100644 --- a/test/core/surface/lame_client_test.c +++ b/test/core/surface/lame_client_test.c @@ -49,32 +49,31 @@ static void *tag(intptr_t x) { return (void *)x; } void verify_connectivity(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { - grpc_transport_op *op = arg; - GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN == *op->connectivity_state); + grpc_connectivity_state *state = arg; + GPR_ASSERT(GRPC_CHANNEL_SHUTDOWN == *state); GPR_ASSERT(error == GRPC_ERROR_NONE); } void do_nothing(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {} void test_transport_op(grpc_channel *channel) { - grpc_transport_op op; + grpc_transport_op *op; grpc_channel_element *elem; grpc_connectivity_state state = GRPC_CHANNEL_IDLE; grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - memset(&op, 0, sizeof(op)); - grpc_closure_init(&transport_op_cb, verify_connectivity, &op); + grpc_closure_init(&transport_op_cb, verify_connectivity, &state); - op.on_connectivity_state_change = &transport_op_cb; - op.connectivity_state = &state; + op = grpc_make_transport_op(NULL); + op->on_connectivity_state_change = &transport_op_cb; + op->connectivity_state = &state; elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(channel), 0); - elem->filter->start_transport_op(&exec_ctx, elem, &op); + elem->filter->start_transport_op(&exec_ctx, elem, op); grpc_exec_ctx_finish(&exec_ctx); - memset(&op, 0, sizeof(op)); grpc_closure_init(&transport_op_cb, do_nothing, NULL); - op.on_consumed = &transport_op_cb; - elem->filter->start_transport_op(&exec_ctx, elem, &op); + op = grpc_make_transport_op(&transport_op_cb); + elem->filter->start_transport_op(&exec_ctx, elem, op); grpc_exec_ctx_finish(&exec_ctx); } @@ -132,7 +131,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ - cq_expect_completion(cqv, tag(1), 0); + CQ_EXPECT_COMPLETION(cqv, tag(1), 0); cq_verify(cqv); memset(ops, 0, sizeof(ops)); @@ -149,7 +148,7 @@ int main(int argc, char **argv) { GPR_ASSERT(GRPC_CALL_OK == error); /* the call should immediately fail */ - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); peer = grpc_call_get_peer(call); diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index 3eeb55d033..53bdf612fc 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -38,22 +38,18 @@ #include <grpc/grpc.h> #include <grpc/grpc_security.h> #include <grpc/grpc_security_constants.h> -#include <grpc/impl/codegen/alloc.h> #include <grpc/impl/codegen/atm.h> -#include <grpc/impl/codegen/byte_buffer.h> #include <grpc/impl/codegen/byte_buffer_reader.h> #include <grpc/impl/codegen/compression_types.h> #include <grpc/impl/codegen/connectivity_state.h> +#include <grpc/impl/codegen/gpr_types.h> #include <grpc/impl/codegen/grpc_types.h> -#include <grpc/impl/codegen/log.h> #include <grpc/impl/codegen/port_platform.h> #include <grpc/impl/codegen/propagation_bits.h> #include <grpc/impl/codegen/slice.h> -#include <grpc/impl/codegen/slice_buffer.h> #include <grpc/impl/codegen/status.h> #include <grpc/impl/codegen/sync.h> #include <grpc/impl/codegen/sync_generic.h> -#include <grpc/impl/codegen/time.h> #include <grpc/status.h> #include <grpc/support/alloc.h> #include <grpc/support/atm.h> diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c index b952503167..f8a9a64211 100644 --- a/test/core/surface/secure_channel_create_test.c +++ b/test/core/surface/secure_channel_create_test.c @@ -46,7 +46,7 @@ void test_unknown_scheme_target(void) { grpc_channel *chan; grpc_channel_credentials *creds; grpc_resolver_registry_shutdown(); - grpc_resolver_registry_init(""); + grpc_resolver_registry_init(); creds = grpc_fake_transport_security_credentials_create(); chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL); diff --git a/test/core/transport/chttp2/hpack_encoder_test.c b/test/core/transport/chttp2/hpack_encoder_test.c index 186bb6406f..1c1c74879b 100644 --- a/test/core/transport/chttp2/hpack_encoder_test.c +++ b/test/core/transport/chttp2/hpack_encoder_test.c @@ -97,7 +97,7 @@ static void verify(size_t window_available, int eof, size_t expect_window_used, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, &stats, + grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, eof, 16384, &stats, &output); merged = grpc_slice_merge(output.slices, output.count); gpr_slice_buffer_destroy(&output); @@ -202,7 +202,8 @@ static void verify_table_size_change_match_elem_size(const char *key, grpc_transport_one_way_stats stats; memset(&stats, 0, sizeof(stats)); - grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, &stats, &output); + grpc_chttp2_encode_header(&g_compressor, 0xdeadbeef, &b, 0, 16384, &stats, + &output); gpr_slice_buffer_destroy(&output); grpc_metadata_batch_destroy(&b); diff --git a/test/core/util/test_config.c b/test/core/util/test_config.c index 270d16600d..479aeda898 100644 --- a/test/core/util/test_config.c +++ b/test/core/util/test_config.c @@ -34,7 +34,6 @@ #include "test/core/util/test_config.h" #include <grpc/support/log.h> -#include <grpc/support/port_platform.h> #include <signal.h> #include <stdbool.h> #include <stdio.h> diff --git a/test/cpp/codegen/codegen_test_full.cc b/test/cpp/codegen/codegen_test_full.cc index 4500540baf..d6e2416b55 100644 --- a/test/cpp/codegen/codegen_test_full.cc +++ b/test/cpp/codegen/codegen_test_full.cc @@ -32,6 +32,7 @@ */ #include <grpc++/completion_queue.h> +#include <grpc/support/time.h> #include <gtest/gtest.h> namespace grpc { diff --git a/test/cpp/codegen/compiler_test_golden b/test/cpp/codegen/compiler_test_golden index ef3d1aaa51..7b0fd6ce80 100644 --- a/test/cpp/codegen/compiler_test_golden +++ b/test/cpp/codegen/compiler_test_golden @@ -43,6 +43,7 @@ #include <grpc++/impl/codegen/async_stream.h> #include <grpc++/impl/codegen/async_unary_call.h> +#include <grpc++/impl/codegen/method_handler_impl.h> #include <grpc++/impl/codegen/proto_utils.h> #include <grpc++/impl/codegen/rpc_method.h> #include <grpc++/impl/codegen/service_type.h> @@ -206,6 +207,27 @@ class ServiceA GRPC_FINAL { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; + template <class BaseClass> + class WithStreamedUnaryMethod_MethodA1 : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_MethodA1() { + ::grpc::Service::MarkMethodStreamedUnary(0, + new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodA1<BaseClass>::StreamedMethodA1, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_MethodA1() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status MethodA1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedMethodA1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_MethodA1<Service > StreamedUnaryService; }; // ServiceB leading comment 1 @@ -284,6 +306,27 @@ class ServiceB GRPC_FINAL { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } }; + template <class BaseClass> + class WithStreamedUnaryMethod_MethodB1 : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service *service) {} + public: + WithStreamedUnaryMethod_MethodB1() { + ::grpc::Service::MarkMethodStreamedUnary(0, + new ::grpc::StreamedUnaryHandler< ::grpc::testing::Request, ::grpc::testing::Response>(std::bind(&WithStreamedUnaryMethod_MethodB1<BaseClass>::StreamedMethodB1, this, std::placeholders::_1, std::placeholders::_2))); + } + ~WithStreamedUnaryMethod_MethodB1() GRPC_OVERRIDE { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status MethodB1(::grpc::ServerContext* context, const ::grpc::testing::Request* request, ::grpc::testing::Response* response) GRPC_FINAL GRPC_OVERRIDE { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedMethodB1(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::grpc::testing::Request,::grpc::testing::Response>* server_unary_streamer) = 0; + }; + typedef WithStreamedUnaryMethod_MethodB1<Service > StreamedUnaryService; }; // ServiceB trailing comment 1 diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index ac79fe8274..a9b7c8f8d3 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -897,8 +897,8 @@ TEST_P(AsyncEnd2endTest, UnimplementedRpc) { GetChannelCredentials(GetParam().credentials_type, &args); std::shared_ptr<Channel> channel = CreateCustomChannel(server_address_.str(), channel_creds, args); - std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub; - stub = grpc::testing::UnimplementedService::NewStub(channel); + std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub; + stub = grpc::testing::UnimplementedEchoService::NewStub(channel); EchoRequest send_request; EchoResponse recv_response; Status recv_status; diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc index 30b04fb9b9..c452ad2beb 100644 --- a/test/cpp/end2end/client_crash_test.cc +++ b/test/cpp/end2end/client_crash_test.cc @@ -38,6 +38,7 @@ #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> #include <grpc/support/time.h> #include <gtest/gtest.h> diff --git a/test/cpp/end2end/client_crash_test_server.cc b/test/cpp/end2end/client_crash_test_server.cc index 9568ca26be..6e1457407c 100644 --- a/test/cpp/end2end/client_crash_test_server.cc +++ b/test/cpp/end2end/client_crash_test_server.cc @@ -39,6 +39,8 @@ #include <grpc++/server.h> #include <grpc++/server_builder.h> #include <grpc++/server_context.h> +#include <grpc/support/log.h> + #include "src/proto/grpc/testing/echo.grpc.pb.h" DEFINE_string(address, "", "Address to bind to"); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 46a58d3ac3..b1d3ce92f6 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -44,6 +44,7 @@ #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> #include <grpc/support/time.h> #include <gtest/gtest.h> @@ -79,11 +80,14 @@ const char kTestCredsPluginErrorMsg[] = "Could not find plugin metadata."; class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { public: - static const char kMetadataKey[]; + static const char kGoodMetadataKey[]; + static const char kBadMetadataKey[]; - TestMetadataCredentialsPlugin(grpc::string_ref metadata_value, + TestMetadataCredentialsPlugin(grpc::string_ref metadata_key, + grpc::string_ref metadata_value, bool is_blocking, bool is_successful) - : metadata_value_(metadata_value.data(), metadata_value.length()), + : metadata_key_(metadata_key.data(), metadata_key.length()), + metadata_value_(metadata_value.data(), metadata_value.length()), is_blocking_(is_blocking), is_successful_(is_successful) {} @@ -98,7 +102,7 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated()); EXPECT_TRUE(metadata != nullptr); if (is_successful_) { - metadata->insert(std::make_pair(kMetadataKey, metadata_value_)); + metadata->insert(std::make_pair(metadata_key_, metadata_value_)); return Status::OK; } else { return Status(StatusCode::NOT_FOUND, kTestCredsPluginErrorMsg); @@ -106,12 +110,16 @@ class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin { } private: + grpc::string metadata_key_; grpc::string metadata_value_; bool is_blocking_; bool is_successful_; }; -const char TestMetadataCredentialsPlugin::kMetadataKey[] = "TestPluginMetadata"; +const char TestMetadataCredentialsPlugin::kBadMetadataKey[] = + "TestPluginMetadata"; +const char TestMetadataCredentialsPlugin::kGoodMetadataKey[] = + "test-plugin-metadata"; class TestAuthMetadataProcessor : public AuthMetadataProcessor { public: @@ -122,13 +130,17 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { std::shared_ptr<CallCredentials> GetCompatibleClientCreds() { return MetadataCredentialsFromPlugin( std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin(kGoodGuy, is_blocking_, true))); + new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy, + is_blocking_, true))); } std::shared_ptr<CallCredentials> GetIncompatibleClientCreds() { return MetadataCredentialsFromPlugin( std::unique_ptr<MetadataCredentialsPlugin>( - new TestMetadataCredentialsPlugin("Mr Hyde", is_blocking_, true))); + new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde", + is_blocking_, true))); } // Interface implementation @@ -141,7 +153,7 @@ class TestAuthMetadataProcessor : public AuthMetadataProcessor { EXPECT_TRUE(context != nullptr); EXPECT_TRUE(response_metadata != nullptr); auto auth_md = - auth_metadata.find(TestMetadataCredentialsPlugin::kMetadataKey); + auth_metadata.find(TestMetadataCredentialsPlugin::kGoodMetadataKey); EXPECT_NE(auth_md, auth_metadata.end()); string_ref auth_md_value = auth_md->second; if (auth_md_value == kGoodGuy) { @@ -967,8 +979,8 @@ TEST_P(End2endTest, ChannelStateTimeout) { // Talking to a non-existing service. TEST_P(End2endTest, NonExistingService) { ResetChannel(); - std::unique_ptr<grpc::testing::UnimplementedService::Stub> stub; - stub = grpc::testing::UnimplementedService::NewStub(channel_); + std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub; + stub = grpc::testing::UnimplementedEchoService::NewStub(channel_); EchoRequest request; EchoResponse response; @@ -1321,6 +1333,40 @@ TEST_P(SecureEnd2endTest, OverridePerCallCredentials) { EXPECT_TRUE(s.ok()); } +TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials( + MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( + new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kBadMetadataKey, + "Does not matter, will fail the key is invalid.", false, true)))); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); +} + +TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + context.set_credentials( + MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( + new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kGoodMetadataKey, + "With illegal \n value.", false, true)))); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED); +} + TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { ResetStub(); EchoRequest request; @@ -1329,6 +1375,7 @@ TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) { context.set_credentials( MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", false, false)))); request.set_message("Hello"); @@ -1387,6 +1434,7 @@ TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) { context.set_credentials( MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>( new TestMetadataCredentialsPlugin( + TestMetadataCredentialsPlugin::kGoodMetadataKey, "Does not matter, will fail anyway (see 3rd param)", true, false)))); request.set_message("Hello"); diff --git a/test/cpp/end2end/hybrid_end2end_test.cc b/test/cpp/end2end/hybrid_end2end_test.cc index 7e0c0e8a7c..82361d0e90 100644 --- a/test/cpp/end2end/hybrid_end2end_test.cc +++ b/test/cpp/end2end/hybrid_end2end_test.cc @@ -199,7 +199,8 @@ class HybridEnd2endTest : public ::testing::Test { HybridEnd2endTest() {} void SetUpServer(::grpc::Service* service1, ::grpc::Service* service2, - AsyncGenericService* generic_service) { + AsyncGenericService* generic_service, + int max_message_size = 0) { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; @@ -217,6 +218,11 @@ class HybridEnd2endTest : public ::testing::Test { if (generic_service) { builder.RegisterAsyncGenericService(generic_service); } + + if (max_message_size != 0) { + builder.SetMaxMessageSize(max_message_size); + } + // Create a separate cq for each potential handler. for (int i = 0; i < 5; i++) { cqs_.push_back(builder.AddCompletionQueue(false)); @@ -346,7 +352,7 @@ class HybridEnd2endTest : public ::testing::Test { EXPECT_TRUE(s.ok()); } - grpc::testing::UnimplementedService::Service unimplemented_service_; + grpc::testing::UnimplementedEchoService::Service unimplemented_service_; std::vector<std::unique_ptr<ServerCompletionQueue>> cqs_; std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; std::unique_ptr<Server> server_; @@ -415,6 +421,83 @@ TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_SyncDupService) { request_stream_handler_thread.join(); } +// Add a second service with one sync streamed unary method. +class StreamedUnaryDupPkg + : public duplicate::EchoTestService::WithStreamedUnaryMethod_Echo< + TestServiceImplDupPkg> { + public: + Status StreamedEcho(ServerContext* context, + ServerUnaryStreamer<EchoRequest, EchoResponse>* stream) + GRPC_OVERRIDE { + EchoRequest req; + EchoResponse resp; + uint32_t next_msg_sz; + stream->NextMessageSize(&next_msg_sz); + gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); + GPR_ASSERT(stream->Read(&req)); + resp.set_message(req.message() + "_dup"); + GPR_ASSERT(stream->Write(resp)); + return Status::OK; + } +}; + +TEST_F(HybridEnd2endTest, + AsyncRequestStreamResponseStream_SyncStreamedUnaryDupService) { + typedef EchoTestService::WithAsyncMethod_RequestStream< + EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> + SType; + SType service; + StreamedUnaryDupPkg dup_service; + SetUpServer(&service, &dup_service, nullptr, 8192); + ResetStub(); + std::thread response_stream_handler_thread(HandleServerStreaming<SType>, + &service, cqs_[0].get()); + std::thread request_stream_handler_thread(HandleClientStreaming<SType>, + &service, cqs_[1].get()); + TestAllMethods(); + SendEchoToDupService(); + response_stream_handler_thread.join(); + request_stream_handler_thread.join(); +} + +// Add a second service that is fully Streamed Unary +class FullyStreamedUnaryDupPkg + : public duplicate::EchoTestService::StreamedUnaryService { + public: + Status StreamedEcho(ServerContext* context, + ServerUnaryStreamer<EchoRequest, EchoResponse>* stream) + GRPC_OVERRIDE { + EchoRequest req; + EchoResponse resp; + uint32_t next_msg_sz; + stream->NextMessageSize(&next_msg_sz); + gpr_log(GPR_INFO, "Streamed Unary Next Message Size is %u", next_msg_sz); + GPR_ASSERT(stream->Read(&req)); + resp.set_message(req.message() + "_dup"); + GPR_ASSERT(stream->Write(resp)); + return Status::OK; + } +}; + +TEST_F(HybridEnd2endTest, + AsyncRequestStreamResponseStream_SyncFullyStreamedUnaryDupService) { + typedef EchoTestService::WithAsyncMethod_RequestStream< + EchoTestService::WithAsyncMethod_ResponseStream<TestServiceImpl>> + SType; + SType service; + FullyStreamedUnaryDupPkg dup_service; + SetUpServer(&service, &dup_service, nullptr, 8192); + ResetStub(); + std::thread response_stream_handler_thread(HandleServerStreaming<SType>, + &service, cqs_[0].get()); + std::thread request_stream_handler_thread(HandleClientStreaming<SType>, + &service, cqs_[1].get()); + TestAllMethods(); + SendEchoToDupService(); + response_stream_handler_thread.join(); + request_stream_handler_thread.join(); +} + // Add a second service with one async method. TEST_F(HybridEnd2endTest, AsyncRequestStreamResponseStream_AsyncDupService) { typedef EchoTestService::WithAsyncMethod_RequestStream< diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc index 0ace5d9418..0da5861b67 100644 --- a/test/cpp/end2end/mock_test.cc +++ b/test/cpp/end2end/mock_test.cc @@ -31,6 +31,7 @@ * */ +#include <climits> #include <thread> #include <grpc++/channel.h> @@ -40,6 +41,7 @@ #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> #include <grpc/support/time.h> #include <gtest/gtest.h> @@ -63,6 +65,10 @@ class MockClientReaderWriter GRPC_FINAL : public ClientReaderWriterInterface<W, R> { public: void WaitForInitialMetadata() GRPC_OVERRIDE {} + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = UINT_MAX; + return true; + } bool Read(R* msg) GRPC_OVERRIDE { return true; } bool Write(const W& msg) GRPC_OVERRIDE { return true; } bool WritesDone() GRPC_OVERRIDE { return true; } @@ -74,6 +80,10 @@ class MockClientReaderWriter<EchoRequest, EchoResponse> GRPC_FINAL public: MockClientReaderWriter() : writes_done_(false) {} void WaitForInitialMetadata() GRPC_OVERRIDE {} + bool NextMessageSize(uint32_t* sz) GRPC_OVERRIDE { + *sz = UINT_MAX; + return true; + } bool Read(EchoResponse* msg) GRPC_OVERRIDE { if (writes_done_) return false; msg->set_message(last_message_); diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc index e447360276..16a5fa2322 100644 --- a/test/cpp/end2end/server_crash_test.cc +++ b/test/cpp/end2end/server_crash_test.cc @@ -38,6 +38,7 @@ #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> #include <grpc/support/time.h> #include <gtest/gtest.h> diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc index ece948d5a7..10a251c952 100644 --- a/test/cpp/end2end/server_crash_test_client.cc +++ b/test/cpp/end2end/server_crash_test_client.cc @@ -40,6 +40,8 @@ #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> +#include <grpc/support/log.h> + #include "src/proto/grpc/testing/echo.grpc.pb.h" DEFINE_string(address, "", "Address to connect to"); diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index 3f98de6db7..4cba3b1c81 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -33,6 +33,8 @@ #include <thread> +#include <gtest/gtest.h> + #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> @@ -40,8 +42,8 @@ #include <grpc++/server_builder.h> #include <grpc++/server_context.h> #include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpc/support/sync.h> -#include <gtest/gtest.h> #include "src/core/lib/support/env.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" diff --git a/test/cpp/end2end/streaming_throughput_test.cc b/test/cpp/end2end/streaming_throughput_test.cc index 9e82c30701..fbef761ca9 100644 --- a/test/cpp/end2end/streaming_throughput_test.cc +++ b/test/cpp/end2end/streaming_throughput_test.cc @@ -35,6 +35,8 @@ #include <mutex> #include <thread> +#include <gtest/gtest.h> + #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> @@ -45,9 +47,9 @@ #include <grpc++/server_context.h> #include <grpc/grpc.h> #include <grpc/support/atm.h> +#include <grpc/support/log.h> #include <grpc/support/thd.h> #include <grpc/support/time.h> -#include <gtest/gtest.h> #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 52abd80d69..2de344efd5 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -38,7 +38,8 @@ #include <grpc++/security/credentials.h> #include <grpc++/server_context.h> -#include <grpc/grpc.h> +#include <grpc/support/log.h> + #include <gtest/gtest.h> #include "src/proto/grpc/testing/echo.grpc.pb.h" diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc index 33de1ee93c..e67189c69e 100644 --- a/test/cpp/grpclb/grpclb_api_test.cc +++ b/test/cpp/grpclb/grpclb_api_test.cc @@ -31,10 +31,12 @@ * */ +#include <grpc++/impl/codegen/config.h> #include <gtest/gtest.h> -#include <string> #include "src/core/ext/lb_policy/grpclb/load_balancer_api.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/iomgr/sockaddr_utils.h" #include "src/proto/grpc/lb/v1/load_balancer.pb.h" // C++ version namespace grpc { @@ -45,8 +47,28 @@ using grpc::lb::v1::LoadBalanceResponse; class GrpclbTest : public ::testing::Test {}; +grpc::string Ip4ToPackedString(const char* ip_str) { + struct in_addr ip4; + GPR_ASSERT(inet_pton(AF_INET, ip_str, &ip4) == 1); + return grpc::string(reinterpret_cast<const char*>(&ip4), sizeof(ip4)); +} + +grpc::string PackedStringToIp(const grpc_grpclb_ip_address& pb_ip) { + char ip_str[46] = {0}; + int af = -1; + if (pb_ip.size == 4) { + af = AF_INET; + } else if (pb_ip.size == 16) { + af = AF_INET6; + } else { + abort(); + } + GPR_ASSERT(inet_ntop(af, pb_ip.bytes, ip_str, 46) != NULL); + return ip_str; +} + TEST_F(GrpclbTest, CreateRequest) { - const std::string service_name = "AServiceName"; + const grpc::string service_name = "AServiceName"; LoadBalanceRequest request; grpc_grpclb_request* c_req = grpc_grpclb_request_create(service_name.c_str()); gpr_slice slice = grpc_grpclb_request_encode(c_req); @@ -65,7 +87,7 @@ TEST_F(GrpclbTest, ParseInitialResponse) { initial_response->mutable_client_stats_report_interval(); client_stats_report_interval->set_seconds(123); client_stats_report_interval->set_nanos(456); - const std::string encoded_response = response.SerializeAsString(); + const grpc::string encoded_response = response.SerializeAsString(); gpr_slice encoded_slice = gpr_slice_from_copied_string(encoded_response.c_str()); @@ -82,29 +104,31 @@ TEST_F(GrpclbTest, ParseResponseServerList) { LoadBalanceResponse response; auto* serverlist = response.mutable_server_list(); auto* server = serverlist->add_servers(); - server->set_ip_address("127.0.0.1"); + server->set_ip_address(Ip4ToPackedString("127.0.0.1")); server->set_port(12345); server->set_drop_request(true); server = response.mutable_server_list()->add_servers(); - server->set_ip_address("10.0.0.1"); + server->set_ip_address(Ip4ToPackedString("10.0.0.1")); server->set_port(54321); server->set_drop_request(false); auto* expiration_interval = serverlist->mutable_expiration_interval(); expiration_interval->set_seconds(888); expiration_interval->set_nanos(999); - const std::string encoded_response = response.SerializeAsString(); - gpr_slice encoded_slice = - gpr_slice_from_copied_string(encoded_response.c_str()); + const grpc::string encoded_response = response.SerializeAsString(); + const gpr_slice encoded_slice = gpr_slice_from_copied_buffer( + encoded_response.data(), encoded_response.size()); grpc_grpclb_serverlist* c_serverlist = grpc_grpclb_response_parse_serverlist(encoded_slice); ASSERT_EQ(c_serverlist->num_servers, 2ul); EXPECT_TRUE(c_serverlist->servers[0]->has_ip_address); - EXPECT_TRUE(strcmp(c_serverlist->servers[0]->ip_address, "127.0.0.1") == 0); + EXPECT_EQ(PackedStringToIp(c_serverlist->servers[0]->ip_address), + "127.0.0.1"); EXPECT_EQ(c_serverlist->servers[0]->port, 12345); EXPECT_TRUE(c_serverlist->servers[0]->drop_request); EXPECT_TRUE(c_serverlist->servers[1]->has_ip_address); - EXPECT_TRUE(strcmp(c_serverlist->servers[1]->ip_address, "10.0.0.1") == 0); + + EXPECT_EQ(PackedStringToIp(c_serverlist->servers[1]->ip_address), "10.0.0.1"); EXPECT_EQ(c_serverlist->servers[1]->port, 54321); EXPECT_FALSE(c_serverlist->servers[1]->drop_request); diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc index b2fdce2963..95abe38031 100644 --- a/test/cpp/grpclb/grpclb_test.cc +++ b/test/cpp/grpclb/grpclb_test.cc @@ -37,8 +37,10 @@ #include <cstring> #include <string> -extern "C" { +#include <gtest/gtest.h> + #include <grpc/grpc.h> +#include <grpc/impl/codegen/byte_buffer_reader.h> #include <grpc/support/alloc.h> #include <grpc/support/host_port.h> #include <grpc/support/log.h> @@ -47,8 +49,11 @@ extern "C" { #include <grpc/support/thd.h> #include <grpc/support/time.h> +#include <grpc++/impl/codegen/config.h> +extern "C" { #include "src/core/ext/client_config/client_channel.h" #include "src/core/lib/channel/channel_stack.h" +#include "src/core/lib/iomgr/sockaddr.h" #include "src/core/lib/support/string.h" #include "src/core/lib/support/tmpfile.h" #include "src/core/lib/surface/channel.h" @@ -61,16 +66,19 @@ extern "C" { #include "src/proto/grpc/lb/v1/load_balancer.pb.h" #define NUM_BACKENDS 4 +#define PAYLOAD "hello you" // TODO(dgq): Other scenarios in need of testing: // - Send an empty serverlist update and verify that the client request blocks // until a new serverlist with actual contents is available. // - Send identical serverlist update +// - Send a serverlist with faulty ip:port addresses (port > 2^16, etc). // - Test reception of invalid serverlist // - Test pinging // - Test against a non-LB server. That server should return UNIMPLEMENTED and // the call should fail. // - Random LB server closing the stream unexpectedly. +// - Test using DNS-resolvable names (localhost?) namespace grpc { namespace { @@ -105,8 +113,8 @@ static gpr_slice build_response_payload_slice( int64_t expiration_interval_secs, int32_t expiration_interval_nanos) { // server_list { // servers { - // ip_address: "127.0.0.1" - // port: ... + // ip_address: <in_addr/6 bytes of an IP> + // port: <16 bit uint> // load_balance_token: "token..." // } // ... @@ -125,21 +133,21 @@ static gpr_slice build_response_payload_slice( } for (size_t i = 0; i < nports; i++) { auto *server = serverlist->add_servers(); - server->set_ip_address(host); + // TODO(dgq): test ipv6 + struct in_addr ip4; + GPR_ASSERT(inet_pton(AF_INET, host, &ip4) == 1); + server->set_ip_address( + grpc::string(reinterpret_cast<const char *>(&ip4), sizeof(ip4))); server->set_port(ports[i]); // The following long long int cast is meant to work around the // disfunctional implementation of std::to_string in gcc 4.4, which doesn't // have a version for int but does have one for long long int. - server->set_load_balance_token("token" + - std::to_string((long long int)ports[i])); + string token_data = "token" + std::to_string((long long int)ports[i]); + token_data.resize(64, '-'); + server->set_load_balance_token(token_data); } - - gpr_log(GPR_INFO, "generating response: %s", - response.ShortDebugString().c_str()); - - const gpr_slice response_slice = - gpr_slice_from_copied_string(response.SerializeAsString().c_str()); - return response_slice; + const grpc::string &enc_resp = response.SerializeAsString(); + return gpr_slice_from_copied_buffer(enc_resp.data(), enc_resp.size()); } static void drain_cq(grpc_completion_queue *cq) { @@ -177,10 +185,41 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, tag(200)); GPR_ASSERT(GRPC_CALL_OK == error); gpr_log(GPR_INFO, "LB Server[%s] up", sf->servers_hostport); - cq_expect_completion(cqv, tag(200), 1); + CQ_EXPECT_COMPLETION(cqv, tag(200), 1); cq_verify(cqv); gpr_log(GPR_INFO, "LB Server[%s] after tag 200", sf->servers_hostport); + // make sure we've received the initial metadata from the grpclb request. + GPR_ASSERT(request_metadata_recv.count > 0); + GPR_ASSERT(request_metadata_recv.metadata != NULL); + + // receive request for backends + op = ops; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op->flags = 0; + op->reserved = NULL; + op++; + error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), NULL); + GPR_ASSERT(GRPC_CALL_OK == error); + CQ_EXPECT_COMPLETION(cqv, tag(202), 1); + cq_verify(cqv); + gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport); + + // validate initial request. + grpc_byte_buffer_reader bbr; + grpc_byte_buffer_reader_init(&bbr, request_payload_recv); + gpr_slice request_payload_slice = grpc_byte_buffer_reader_readall(&bbr); + grpc::lb::v1::LoadBalanceRequest request; + request.ParseFromArray(GPR_SLICE_START_PTR(request_payload_slice), + GPR_SLICE_LENGTH(request_payload_slice)); + GPR_ASSERT(request.has_initial_request()); + GPR_ASSERT(request.initial_request().name() == "load.balanced.service.name"); + gpr_slice_unref(request_payload_slice); + grpc_byte_buffer_reader_destroy(&bbr); + grpc_byte_buffer_destroy(request_payload_recv); + + gpr_slice response_payload_slice; op = ops; op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; @@ -196,21 +235,6 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, GPR_ASSERT(GRPC_CALL_OK == error); gpr_log(GPR_INFO, "LB Server[%s] after tag 201", sf->servers_hostport); - // receive request for backends - op = ops; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op->flags = 0; - op->reserved = NULL; - op++; - error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(202), NULL); - GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(202), 1); - cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport); - // TODO(dgq): validate request. - grpc_byte_buffer_destroy(request_payload_recv); - gpr_slice response_payload_slice; for (int i = 0; i < 2; i++) { if (i == 0) { // First half of the ports. @@ -233,7 +257,7 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(203), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(203), 1); + CQ_EXPECT_COMPLETION(cqv, tag(203), 1); cq_verify(cqv); gpr_log(GPR_INFO, "LB Server[%s] after SEND_MESSAGE, iter %d", sf->servers_hostport, i); @@ -254,8 +278,8 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(204), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(201), 1); - cq_expect_completion(cqv, tag(204), 1); + CQ_EXPECT_COMPLETION(cqv, tag(201), 1); + CQ_EXPECT_COMPLETION(cqv, tag(204), 1); cq_verify(cqv); gpr_log(GPR_INFO, "LB Server[%s] after tag 204. All done. LB server out", sf->servers_hostport); @@ -303,6 +327,16 @@ static void start_backend_server(server_fixture *sf) { return; } GPR_ASSERT(ev.type == GRPC_OP_COMPLETE); + + // The following long long int cast is meant to work around the + // disfunctional implementation of std::to_string in gcc 4.4, which doesn't + // have a version for int but does have one for long long int. + string expected_token = "token" + std::to_string((long long int)sf->port); + expected_token.resize(64, '-'); + GPR_ASSERT(contains_metadata(&request_metadata_recv, + "load-reporting-initial", + expected_token.c_str())); + gpr_log(GPR_INFO, "Server[%s] after tag 100", sf->servers_hostport); op = ops; @@ -321,8 +355,7 @@ static void start_backend_server(server_fixture *sf) { gpr_log(GPR_INFO, "Server[%s] after tag 101", sf->servers_hostport); bool exit = false; - gpr_slice response_payload_slice = - gpr_slice_from_copied_string("hello you"); + gpr_slice response_payload_slice = gpr_slice_from_copied_string(PAYLOAD); while (!exit) { op = ops; op->op = GRPC_OP_RECV_MESSAGE; @@ -394,8 +427,8 @@ static void start_backend_server(server_fixture *sf) { error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - cq_expect_completion(cqv, tag(101), 1); - cq_expect_completion(cqv, tag(104), 1); + CQ_EXPECT_COMPLETION(cqv, tag(101), 1); + CQ_EXPECT_COMPLETION(cqv, tag(104), 1); cq_verify(cqv); gpr_log(GPR_INFO, "Server[%s] DONE. After servicing %d calls", sf->servers_hostport, sf->num_calls_serviced); @@ -474,10 +507,9 @@ static void perform_request(client_fixture *cf) { error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - peer = grpc_call_get_peer(c); - cq_expect_completion(cqv, tag(2), 1); + CQ_EXPECT_COMPLETION(cqv, tag(2), 1); cq_verify(cqv); - gpr_free(peer); + GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, PAYLOAD)); grpc_byte_buffer_destroy(request_payload); grpc_byte_buffer_destroy(response_payload_recv); @@ -493,8 +525,8 @@ static void perform_request(client_fixture *cf) { 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(1), 1); - cq_expect_completion(cqv, tag(3), 1); + CQ_EXPECT_COMPLETION(cqv, tag(1), 1); + CQ_EXPECT_COMPLETION(cqv, tag(3), 1); cq_verify(cqv); peer = grpc_call_get_peer(c); gpr_log(GPR_INFO, "Client DONE WITH SERVER %s ", peer); @@ -583,27 +615,30 @@ static void fork_lb_server(void *arg) { tf->lb_server_update_delay_ms); } -static void setup_test_fixture(test_fixture *tf, - int lb_server_update_delay_ms) { - tf->lb_server_update_delay_ms = lb_server_update_delay_ms; +static test_fixture setup_test_fixture(int lb_server_update_delay_ms) { + test_fixture tf; + memset(&tf, 0, sizeof(tf)); + tf.lb_server_update_delay_ms = lb_server_update_delay_ms; gpr_thd_options options = gpr_thd_options_default(); gpr_thd_options_set_joinable(&options); for (int i = 0; i < NUM_BACKENDS; ++i) { - setup_server("127.0.0.1", &tf->lb_backends[i]); - gpr_thd_new(&tf->lb_backends[i].tid, fork_backend_server, - &tf->lb_backends[i], &options); + setup_server("127.0.0.1", &tf.lb_backends[i]); + gpr_thd_new(&tf.lb_backends[i].tid, fork_backend_server, &tf.lb_backends[i], + &options); } - setup_server("127.0.0.1", &tf->lb_server); - gpr_thd_new(&tf->lb_server.tid, fork_lb_server, &tf->lb_server, &options); + setup_server("127.0.0.1", &tf.lb_server); + gpr_thd_new(&tf.lb_server.tid, fork_lb_server, &tf.lb_server, &options); char *server_uri; gpr_asprintf(&server_uri, "ipv4:%s?lb_policy=grpclb&lb_enabled=1", - tf->lb_server.servers_hostport); - setup_client(server_uri, &tf->client); + tf.lb_server.servers_hostport); + setup_client(server_uri, &tf.client); gpr_free(server_uri); + + return tf; } static void teardown_test_fixture(test_fixture *tf) { @@ -614,19 +649,13 @@ static void teardown_test_fixture(test_fixture *tf) { teardown_server(&tf->lb_server); } -// The LB server will send two updates: batch 1 and batch 2. Each batch -// contains -// two addresses, both of a valid and running backend server. Batch 1 is -// readily -// available and provided as soon as the client establishes the streaming -// call. -// Batch 2 is sent after a delay of \a lb_server_update_delay_ms -// milliseconds. +// The LB server will send two updates: batch 1 and batch 2. Each batch contains +// two addresses, both of a valid and running backend server. Batch 1 is readily +// available and provided as soon as the client establishes the streaming call. +// Batch 2 is sent after a delay of \a lb_server_update_delay_ms milliseconds. static test_fixture test_update(int lb_server_update_delay_ms) { gpr_log(GPR_INFO, "start %s(%d)", __func__, lb_server_update_delay_ms); - test_fixture tf; - memset(&tf, 0, sizeof(tf)); - setup_test_fixture(&tf, lb_server_update_delay_ms); + test_fixture tf = setup_test_fixture(lb_server_update_delay_ms); perform_request( &tf.client); // "consumes" 1st backend server of 1st serverlist perform_request( @@ -642,13 +671,7 @@ static test_fixture test_update(int lb_server_update_delay_ms) { return tf; } -} // namespace -} // namespace grpc - -int main(int argc, char **argv) { - grpc_test_init(argc, argv); - grpc_init(); - +TEST(GrpclbTest, Updates) { grpc::test_fixture tf_result; // Clients take a bit over one second to complete a call (the last part of the // call sleeps for 1 second while verifying the client's completion queue is @@ -683,7 +706,18 @@ int main(int argc, char **argv) { GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced > 0); GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced > 0); GPR_ASSERT(tf_result.lb_backends[3].num_calls_serviced == 0); +} +TEST(GrpclbTest, InvalidAddressInServerlist) {} + +} // namespace +} // namespace grpc + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc_test_init(argc, argv); + grpc_init(); + const auto result = RUN_ALL_TESTS(); grpc_shutdown(); - return 0; + return result; } diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index e8ae6ee572..032b378b1a 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -39,6 +39,7 @@ #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc/grpc.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index f6395054b1..424c9d17e9 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -40,6 +40,7 @@ #include <grpc++/client_context.h> #include <grpc++/security/credentials.h> #include <grpc/grpc.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/string_util.h> #include <grpc/support/useful.h> diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc index 7e40bcf40a..b1c43cd017 100644 --- a/test/cpp/interop/interop_server.cc +++ b/test/cpp/interop/interop_server.cc @@ -56,6 +56,7 @@ DEFINE_bool(use_tls, false, "Whether to use tls."); DEFINE_int32(port, 0, "Server port."); +DEFINE_int32(max_send_message_size, -1, "The maximum send message size."); using grpc::Server; using grpc::ServerBuilder; @@ -326,6 +327,9 @@ void grpc::testing::interop::RunServer( ServerBuilder builder; builder.RegisterService(&service); builder.AddListeningPort(server_address.str(), creds); + if (FLAGS_max_send_message_size >= 0) { + builder.SetMaxSendMessageSize(FLAGS_max_send_message_size); + } std::unique_ptr<Server> server(builder.BuildAndStart()); gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str()); while (!g_got_sigint) { diff --git a/test/cpp/interop/metrics_client.cc b/test/cpp/interop/metrics_client.cc index 179de30805..9d5212e9d5 100644 --- a/test/cpp/interop/metrics_client.cc +++ b/test/cpp/interop/metrics_client.cc @@ -36,6 +36,7 @@ #include <gflags/gflags.h> #include <grpc++/grpc++.h> +#include <grpc/support/log.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/test/cpp/interop/stress_interop_client.cc b/test/cpp/interop/stress_interop_client.cc index 1d5fc80cf2..0ea71e4cf4 100644 --- a/test/cpp/interop/stress_interop_client.cc +++ b/test/cpp/interop/stress_interop_client.cc @@ -38,6 +38,7 @@ #include <vector> #include <grpc++/create_channel.h> +#include <grpc/support/log.h> #include "test/cpp/interop/interop_client.h" #include "test/cpp/util/metrics_server.h" diff --git a/test/cpp/interop/stress_test.cc b/test/cpp/interop/stress_test.cc index 7787931900..5647cb5531 100644 --- a/test/cpp/interop/stress_test.cc +++ b/test/cpp/interop/stress_test.cc @@ -41,6 +41,7 @@ #include <grpc++/create_channel.h> #include <grpc++/grpc++.h> #include <grpc++/impl/thd.h> +#include <grpc/support/log.h> #include <grpc/support/time.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index fada4ba767..5fb87b2782 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -129,13 +129,20 @@ class HistogramEntry GRPC_FINAL { class Client { public: - Client() : timer_(new UsageTimer), interarrival_timer_() {} + Client() + : timer_(new UsageTimer), + interarrival_timer_(), + started_requests_(false) { + gpr_event_init(&start_requests_); + } virtual ~Client() {} ClientStats Mark(bool reset) { Histogram latencies; UsageTimer::Result timer_result; + MaybeStartRequests(); + // avoid std::vector for old compilers that expect a copy constructor if (reset) { Histogram* to_merge = new Histogram[threads_.size()]; @@ -189,7 +196,10 @@ class Client { } } - void EndThreads() { threads_.clear(); } + void EndThreads() { + MaybeStartRequests(); + threads_.clear(); + } virtual void DestroyMultithreading() = 0; virtual bool ThreadFunc(HistogramEntry* histogram, size_t thread_idx) = 0; @@ -265,6 +275,13 @@ class Client { Thread& operator=(const Thread&); void ThreadFunc() { + while (!gpr_event_wait( + &client_->start_requests_, + gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_seconds(1, GPR_TIMESPAN)))) { + gpr_log(GPR_INFO, "Waiting for benchmark to start"); + } + for (;;) { // run the loop body HistogramEntry entry; @@ -302,6 +319,16 @@ class Client { size_t threads_remaining_; std::condition_variable threads_complete_; + gpr_event start_requests_; + bool started_requests_; + + void MaybeStartRequests() { + if (!started_requests_) { + started_requests_ = true; + gpr_event_set(&start_requests_, (void*)1); + } + } + void CompleteThread() { std::lock_guard<std::mutex> g(thread_completion_mu_); threads_remaining_--; @@ -359,7 +386,7 @@ class ClientImpl : public Client { gpr_log(GPR_INFO, "Connecting to %s", target.c_str()); GPR_ASSERT(channel_->WaitForConnected( gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_seconds(30, GPR_TIMESPAN)))); + gpr_time_from_seconds(300, GPR_TIMESPAN)))); stub_ = create_stub(channel_); } Channel* get_channel() { return channel_.get(); } diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 93f9271553..b4c18bcb46 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -186,6 +186,9 @@ std::unique_ptr<ScenarioResult> RunScenario( const ClientConfig& initial_client_config, size_t num_clients, const ServerConfig& initial_server_config, size_t num_servers, int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count) { + // Log everything from the driver + gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG); + // ClientContext allocations (all are destroyed at scope exit) list<ClientContext> contexts; @@ -363,12 +366,37 @@ std::unique_ptr<ScenarioResult> RunScenario( if (!clients[i].stream->Write(args)) { gpr_log(GPR_ERROR, "Could not write args to client %zu", i); } + } + + for (size_t i = 0; i < num_clients; i++) { ClientStatus init_status; if (!clients[i].stream->Read(&init_status)) { gpr_log(GPR_ERROR, "Client %zu did not yield initial status", i); } } + // Send an initial mark: clients can use this to know that everything is ready + // to start + gpr_log(GPR_INFO, "Initiating"); + ServerArgs server_mark; + server_mark.mutable_mark()->set_reset(true); + ClientArgs client_mark; + client_mark.mutable_mark()->set_reset(true); + ServerStatus server_status; + ClientStatus client_status; + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + if (!client->stream->Write(client_mark)) { + gpr_log(GPR_ERROR, "Couldn't write mark to client %zu", i); + } + } + for (size_t i = 0; i < num_clients; i++) { + auto client = &clients[i]; + if (!client->stream->Read(&client_status)) { + gpr_log(GPR_ERROR, "Couldn't get status from client %zu", i); + } + } + // Let everything warmup gpr_log(GPR_INFO, "Warming up"); gpr_timespec start = gpr_now(GPR_CLOCK_REALTIME); @@ -377,10 +405,6 @@ std::unique_ptr<ScenarioResult> RunScenario( // Start a run gpr_log(GPR_INFO, "Starting"); - ServerArgs server_mark; - server_mark.mutable_mark()->set_reset(true); - ClientArgs client_mark; - client_mark.mutable_mark()->set_reset(true); for (size_t i = 0; i < num_servers; i++) { auto server = &servers[i]; if (!server->stream->Write(server_mark)) { @@ -393,8 +417,6 @@ std::unique_ptr<ScenarioResult> RunScenario( gpr_log(GPR_ERROR, "Couldn't write mark to client %zu", i); } } - ServerStatus server_status; - ClientStatus client_status; for (size_t i = 0; i < num_servers; i++) { auto server = &servers[i]; if (!server->stream->Read(&server_status)) { diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py index 4ff4e44b8b..369da2c8ca 100755 --- a/test/cpp/qps/gen_build_yaml.py +++ b/test/cpp/qps/gen_build_yaml.py @@ -74,8 +74,8 @@ print yaml.dump({ 'name': 'json_run_localhost', 'shortname': 'json_run_localhost:%s' % scenario_json['name'], 'args': ['--scenarios_json', _scenario_json_string(scenario_json)], - 'ci_platforms': ['linux', 'mac', 'posix', 'windows'], - 'platforms': ['linux', 'mac', 'posix', 'windows'], + 'ci_platforms': ['linux'], + 'platforms': ['linux'], 'flaky': False, 'language': 'c++', 'boringssl': True, @@ -85,5 +85,6 @@ print yaml.dump({ 'timeout_seconds': 3*60 } for scenario_json in scenario_config.CXXLanguage().scenarios() + if 'scalable' in scenario_json.get('CATEGORIES', []) ] }) diff --git a/test/cpp/util/byte_buffer_proto_helper.cc b/test/cpp/util/byte_buffer_proto_helper.cc index 2512c9bdf8..d625d6f3f4 100644 --- a/test/cpp/util/byte_buffer_proto_helper.cc +++ b/test/cpp/util/byte_buffer_proto_helper.cc @@ -38,7 +38,7 @@ namespace testing { bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { std::vector<Slice> slices; - buffer->Dump(&slices); + (void)buffer->Dump(&slices); grpc::string buf; buf.reserve(buffer->Length()); for (auto s = slices.begin(); s != slices.end(); s++) { diff --git a/test/cpp/util/byte_buffer_test.cc b/test/cpp/util/byte_buffer_test.cc index 1167c790d4..2089a62011 100644 --- a/test/cpp/util/byte_buffer_test.cc +++ b/test/cpp/util/byte_buffer_test.cc @@ -100,7 +100,7 @@ TEST_F(ByteBufferTest, Dump) { slices.push_back(Slice(world, Slice::STEAL_REF)); ByteBuffer buffer(&slices[0], 2); slices.clear(); - buffer.Dump(&slices); + (void)buffer.Dump(&slices); EXPECT_TRUE(SliceEqual(slices[0], hello)); EXPECT_TRUE(SliceEqual(slices[1], world)); } diff --git a/test/cpp/util/cli_call.cc b/test/cpp/util/cli_call.cc index 98b9d930d6..1edffbe08e 100644 --- a/test/cpp/util/cli_call.cc +++ b/test/cpp/util/cli_call.cc @@ -94,7 +94,7 @@ Status CliCall::Call(std::shared_ptr<grpc::Channel> channel, if (status.ok()) { std::vector<grpc::Slice> slices; - recv_buffer.Dump(&slices); + (void)recv_buffer.Dump(&slices); response->clear(); for (size_t i = 0; i < slices.size(); i++) { diff --git a/test/cpp/util/grpc_tool.cc b/test/cpp/util/grpc_tool.cc index f06053ca23..8fb325cf76 100644 --- a/test/cpp/util/grpc_tool.cc +++ b/test/cpp/util/grpc_tool.cc @@ -51,19 +51,22 @@ #include "test/cpp/util/cli_call.h" #include "test/cpp/util/proto_file_parser.h" #include "test/cpp/util/proto_reflection_descriptor_database.h" +#include "test/cpp/util/service_describer.h" #include "test/cpp/util/test_config.h" +namespace grpc { +namespace testing { + +DEFINE_bool(l, false, "Use a long listing format"); DEFINE_bool(remotedb, true, "Use server types to parse and format messages"); DEFINE_string(metadata, "", "Metadata to send to server, in the form of key1:val1:key2:val2"); DEFINE_string(proto_path, ".", "Path to look for the proto file."); -DEFINE_string(proto_file, "", "Name of the proto file."); +DEFINE_string(protofiles, "", "Name of the proto file."); DEFINE_bool(binary_input, false, "Input in binary format"); DEFINE_bool(binary_output, false, "Output in binary format"); DEFINE_string(infile, "", "Input file (default is stdin)"); -namespace grpc { -namespace testing { namespace { class GrpcTool { @@ -71,15 +74,17 @@ class GrpcTool { explicit GrpcTool(); virtual ~GrpcTool() {} - bool Help(int argc, const char** argv, CliCredentials cred, + bool Help(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); - bool CallMethod(int argc, const char** argv, CliCredentials cred, + bool CallMethod(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); + bool ListServices(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool PrintType(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); // TODO(zyc): implement the following methods // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback // callback); - // bool PrintType(int argc, const char** argv, GrpcToolOutputCallback - // callback); // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback // callback); // bool ParseMessage(int argc, const char** argv, GrpcToolOutputCallback @@ -101,7 +106,7 @@ class GrpcTool { }; template <typename T> -std::function<bool(GrpcTool*, int, const char**, const CliCredentials, +std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, GrpcToolOutputCallback)> BindWith5Args(T&& func) { return std::bind(std::forward<T>(func), std::placeholders::_1, @@ -156,7 +161,7 @@ void PrintMetadata(const T& m, const grpc::string& message) { struct Command { const char* command; - std::function<bool(GrpcTool*, int, const char**, const CliCredentials, + std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, GrpcToolOutputCallback)> function; int min_args; @@ -165,10 +170,10 @@ struct Command { const Command ops[] = { {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX}, - // {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, - // {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3}, - // {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, + {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, // {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, // {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, // {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, @@ -178,9 +183,9 @@ void Usage(const grpc::string& msg) { fprintf( stderr, "%s\n" - // " grpc_cli ls ... ; List services\n" + " grpc_cli ls ... ; List services\n" " grpc_cli call ... ; Call method\n" - // " grpc_cli type ... ; Print type\n" + " grpc_cli type ... ; Print type\n" // " grpc_cli parse ... ; Parse message\n" // " grpc_cli totext ... ; Convert binary message to text\n" // " grpc_cli tobinary ... ; Convert text message to binary\n" @@ -201,7 +206,7 @@ const Command* FindCommand(const grpc::string& name) { } } // namespace -int GrpcToolMainLib(int argc, const char** argv, const CliCredentials cred, +int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback) { if (argc < 2) { Usage("No command specified"); @@ -238,7 +243,7 @@ void GrpcTool::CommandUsage(const grpc::string& usage) const { } } -bool GrpcTool::Help(int argc, const char** argv, const CliCredentials cred, +bool GrpcTool::Help(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback) { CommandUsage( "Print help\n" @@ -257,8 +262,136 @@ bool GrpcTool::Help(int argc, const char** argv, const CliCredentials cred, return true; } +bool GrpcTool::ListServices(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "List services\n" + " grpc_cli ls <address> [<service>[/<method>]]\n" + " <address> ; host:port\n" + " <service> ; Exported service name\n" + " <method> ; Method name\n" + " --l ; Use a long listing format\n" + " --outfile ; Output filename (defaults to stdout)\n" + + cred.GetCredentialUsage()); + + grpc::string server_address(argv[0]); + std::shared_ptr<grpc::Channel> channel = + grpc::CreateChannel(server_address, cred.GetCredentials()); + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + + std::vector<grpc::string> service_list; + if (!desc_db.GetServices(&service_list)) { + return false; + } + + // If no service is specified, dump the list of services. + grpc::string output; + if (argc < 2) { + // List all services, if --l is passed, then include full description, + // otherwise include a summarized list only. + if (FLAGS_l) { + output = DescribeServiceList(service_list, desc_pool); + } else { + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + output.append(service); + output.append("\n"); + } + } + } else { + grpc::string service_name; + grpc::string method_name; + std::stringstream ss(argv[1]); + + // Remove leading slashes. + while (ss.peek() == '/') { + ss.get(); + } + + // Parse service and method names. Support the following patterns: + // Service + // Service Method + // Service.Method + // Service/Method + if (argc == 3) { + std::getline(ss, service_name, '/'); + method_name = argv[2]; + } else { + if (std::getline(ss, service_name, '/')) { + std::getline(ss, method_name); + } + } + + const grpc::protobuf::ServiceDescriptor* service = + desc_pool.FindServiceByName(service_name); + if (service != nullptr) { + if (method_name.empty()) { + output = FLAGS_l ? DescribeService(service) : SummarizeService(service); + } else { + method_name.insert(0, 1, '.'); + method_name.insert(0, service_name); + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(method_name); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Method %s not found in service %s.\n", + method_name.c_str(), service_name.c_str()); + return false; + } + } + } else { + if (!method_name.empty()) { + fprintf(stderr, "Service %s not found.\n", service_name.c_str()); + return false; + } else { + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(service_name); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Service or method %s not found.\n", + service_name.c_str()); + return false; + } + } + } + } + return callback(output); +} + +bool GrpcTool::PrintType(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Print type\n" + " grpc_cli type <address> <type>\n" + " <address> ; host:port\n" + " <type> ; Protocol buffer type name\n" + + cred.GetCredentialUsage()); + + grpc::string server_address(argv[0]); + std::shared_ptr<grpc::Channel> channel = + grpc::CreateChannel(server_address, cred.GetCredentials()); + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + + grpc::string output; + const grpc::protobuf::Descriptor* descriptor = + desc_pool.FindMessageTypeByName(argv[1]); + if (descriptor != nullptr) { + output = descriptor->DebugString(); + } else { + fprintf(stderr, "Type %s not found.\n", argv[1]); + return false; + } + return callback(output); +} + bool GrpcTool::CallMethod(int argc, const char** argv, - const CliCredentials cred, + const CliCredentials& cred, GrpcToolOutputCallback callback) { CommandUsage( "Call method\n" @@ -267,10 +400,10 @@ bool GrpcTool::CallMethod(int argc, const char** argv, " <service> ; Exported service name\n" " <method> ; Method name\n" " <request> ; Text protobuffer (overrides infile)\n" - " --proto_file ; Comma separated proto files used as a" + " --protofiles ; Comma separated proto files used as a" " fallback when parsing request/response\n" " --proto_path ; The search path of proto files, valid" - " only when --proto_file is given\n" + " only when --protofiles is given\n" " --metadata ; The metadata to be sent to the server\n" " --infile ; Input filename (defaults to stdin)\n" " --outfile ; Output filename (defaults to stdout)\n" @@ -310,7 +443,7 @@ bool GrpcTool::CallMethod(int argc, const char** argv, if (!FLAGS_binary_input || !FLAGS_binary_output) { parser.reset( new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr, - FLAGS_proto_path, FLAGS_proto_file)); + FLAGS_proto_path, FLAGS_protofiles)); if (parser->HasError()) { return false; } diff --git a/test/cpp/util/grpc_tool.h b/test/cpp/util/grpc_tool.h index 3da86937c2..df3680258b 100644 --- a/test/cpp/util/grpc_tool.h +++ b/test/cpp/util/grpc_tool.h @@ -45,7 +45,7 @@ namespace testing { typedef std::function<bool(const grpc::string &)> GrpcToolOutputCallback; -int GrpcToolMainLib(int argc, const char **argv, CliCredentials cred, +int GrpcToolMainLib(int argc, const char **argv, const CliCredentials &cred, GrpcToolOutputCallback callback); } // namespace testing diff --git a/test/cpp/util/grpc_tool_test.cc b/test/cpp/util/grpc_tool_test.cc index b96afaf50c..bad1579f11 100644 --- a/test/cpp/util/grpc_tool_test.cc +++ b/test/cpp/util/grpc_tool_test.cc @@ -35,6 +35,7 @@ #include <sstream> +#include <gflags/gflags.h> #include <grpc++/channel.h> #include <grpc++/client_context.h> #include <grpc++/create_channel.h> @@ -55,8 +56,41 @@ using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; +#define USAGE_REGEX "( grpc_cli .+\n){2,10}" + +#define ECHO_TEST_SERVICE_SUMMARY \ + "Echo\n" \ + "RequestStream\n" \ + "ResponseStream\n" \ + "BidiStream\n" \ + "Unimplemented\n" + +#define ECHO_TEST_SERVICE_DESCRIPTION \ + "filename: src/proto/grpc/testing/echo.proto\n" \ + "package: grpc.testing;\n" \ + "service EchoTestService {\n" \ + " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ + "{}\n" \ + " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \ + "(grpc.testing.EchoResponse) {}\n" \ + " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \ + "grpc.testing.EchoResponse) {}\n" \ + " rpc BidiStream(stream grpc.testing.EchoRequest) returns (stream " \ + "grpc.testing.EchoResponse) {}\n" \ + " rpc Unimplemented(grpc.testing.EchoRequest) returns " \ + "(grpc.testing.EchoResponse) {}\n" \ + "}\n" \ + "\n" + +#define ECHO_METHOD_DESCRIPTION \ + " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ + "{}\n" + namespace grpc { namespace testing { + +DECLARE_bool(l); + namespace { class TestCliCredentials GRPC_FINAL : public grpc::testing::CliCredentials { @@ -68,6 +102,17 @@ class TestCliCredentials GRPC_FINAL : public grpc::testing::CliCredentials { const grpc::string GetCredentialUsage() const GRPC_OVERRIDE { return ""; } }; +bool PrintStream(std::stringstream* ss, const grpc::string& output) { + (*ss) << output; + return true; +} + +template <typename T> +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); +} + } // namespame class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { @@ -109,24 +154,19 @@ class GrpcToolTest : public ::testing::Test { void ShutdownServer() { server_->Shutdown(); } + void ExitWhenError(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + int result = GrpcToolMainLib(argc, argv, cred, callback); + if (result) { + exit(result); + } + } + std::unique_ptr<Server> server_; TestServiceImpl service_; reflection::ProtoServerReflectionPlugin plugin_; }; -static bool PrintStream(std::stringstream* ss, const grpc::string& output) { - (*ss) << output << std::endl; - return true; -} - -template <typename T> -static size_t ArraySize(T& a) { - return ((sizeof(a) / sizeof(*(a))) / - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); -} - -#define USAGE_REGEX "( grpc_cli .+\n){2,10}" - TEST_F(GrpcToolTest, NoCommand) { // Test input "grpc_cli" std::stringstream output_stream; @@ -168,8 +208,122 @@ TEST_F(GrpcToolTest, HelpCommand) { EXPECT_TRUE(0 == output_stream.tellp()); } +TEST_F(GrpcToolTest, ListCommand) { + // Test input "grpc_cli list localhost:<port>" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; + + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + "grpc.testing.EchoTestService\n" + "grpc.reflection.v1alpha.ServerReflection\n")); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneService) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_SUMMARY + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY)); + + // with -l flag + output_stream.str(grpc::string()); + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_DESCRIPTION + EXPECT_TRUE( + 0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeCommand) { + // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.EchoRequest"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + const grpc::protobuf::Descriptor* desc = + grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( + "grpc.testing.EchoRequest"); + // Expected output: the DebugString of grpc.testing.EchoRequest + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), desc->DebugString().c_str())); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneMethod) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService.Echo"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "Echo" + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n")); + + // with -l flag + output_stream.str(grpc::string()); + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_METHOD_DESCRIPTION + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeNotFound) { + // Test input "grpc_cli type localhost:<port> grpc.testing.DummyRequest" + std::stringstream output_stream; + + const grpc::string server_address = SetUpServer(); + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.DummyRequest"}; + + EXPECT_DEATH(ExitWhenError(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ".*Type grpc.testing.DummyRequest not found.*"); + + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommand) { - // Test input "grpc_cli call Echo" + // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" std::stringstream output_stream; const grpc::string server_address = SetUpServer(); @@ -186,7 +340,7 @@ TEST_F(GrpcToolTest, CallCommand) { } TEST_F(GrpcToolTest, TooFewArguments) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" + // Test input "grpc_cli call Echo" std::stringstream output_stream; const char* argv[] = {"grpc_cli", "call", "Echo"}; diff --git a/test/cpp/util/metrics_server.cc b/test/cpp/util/metrics_server.cc index 1c7cd6382a..9296d6515e 100644 --- a/test/cpp/util/metrics_server.cc +++ b/test/cpp/util/metrics_server.cc @@ -35,6 +35,7 @@ #include <grpc++/server.h> #include <grpc++/server_builder.h> +#include <grpc/support/log.h> #include "src/proto/grpc/testing/metrics.grpc.pb.h" #include "src/proto/grpc/testing/metrics.pb.h" diff --git a/test/cpp/util/proto_reflection_descriptor_database.h b/test/cpp/util/proto_reflection_descriptor_database.h index eb7cf4907d..0e69696d5f 100644 --- a/test/cpp/util/proto_reflection_descriptor_database.h +++ b/test/cpp/util/proto_reflection_descriptor_database.h @@ -45,6 +45,8 @@ #include <grpc++/ext/reflection.grpc.pb.h> #endif // GRPC_NO_GENERATED_CODE #include <grpc++/grpc++.h> +#include <grpc++/impl/codegen/config_protobuf.h> + namespace grpc { // ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and diff --git a/test/cpp/util/service_describer.cc b/test/cpp/util/service_describer.cc new file mode 100644 index 0000000000..4fe4a74805 --- /dev/null +++ b/test/cpp/util/service_describer.cc @@ -0,0 +1,108 @@ +/* + * + * 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. + * + */ + +#include "test/cpp/util/service_describer.h" + +#include <iostream> +#include <sstream> +#include <string> +#include <vector> + +namespace grpc { +namespace testing { + +grpc::string DescribeServiceList(std::vector<grpc::string> service_list, + grpc::protobuf::DescriptorPool& desc_pool) { + std::stringstream result; + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + const grpc::protobuf::ServiceDescriptor* service_desc = + desc_pool.FindServiceByName(service); + if (service_desc != nullptr) { + result << DescribeService(service_desc); + } + } + return result.str(); +} + +grpc::string DescribeService(const grpc::protobuf::ServiceDescriptor* service) { + grpc::string result; + if (service->options().deprecated()) { + result.append("DEPRECATED\n"); + } + result.append("filename: " + service->file()->name() + "\n"); + + grpc::string package = service->full_name(); + size_t pos = package.rfind("." + service->name()); + if (pos != grpc::string::npos) { + package.erase(pos); + result.append("package: " + package + ";\n"); + } + result.append("service " + service->name() + " {\n"); + for (int i = 0; i < service->method_count(); ++i) { + result.append(DescribeMethod(service->method(i))); + } + result.append("}\n\n"); + return result; +} + +grpc::string DescribeMethod(const grpc::protobuf::MethodDescriptor* method) { + std::stringstream result; + result << " rpc " << method->name() + << (method->client_streaming() ? "(stream " : "(") + << method->input_type()->full_name() << ") returns " + << (method->server_streaming() ? "(stream " : "(") + << method->output_type()->full_name() << ") {}\n"; + if (method->options().deprecated()) { + result << " DEPRECATED"; + } + return result.str(); +} + +grpc::string SummarizeService( + const grpc::protobuf::ServiceDescriptor* service) { + grpc::string result; + for (int i = 0; i < service->method_count(); ++i) { + result.append(SummarizeMethod(service->method(i))); + } + return result; +} + +grpc::string SummarizeMethod(const grpc::protobuf::MethodDescriptor* method) { + grpc::string result = method->name(); + result.append("\n"); + return result; +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/service_describer.h b/test/cpp/util/service_describer.h new file mode 100644 index 0000000000..02c58e84c4 --- /dev/null +++ b/test/cpp/util/service_describer.h @@ -0,0 +1,57 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H +#define GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H + +#include <grpc++/support/config.h> +#include "test/cpp/util/config_grpc_cli.h" + +namespace grpc { +namespace testing { + +grpc::string DescribeServiceList(std::vector<grpc::string> service_list, + grpc::protobuf::DescriptorPool& desc_pool); + +grpc::string DescribeService(const grpc::protobuf::ServiceDescriptor* service); + +grpc::string DescribeMethod(const grpc::protobuf::MethodDescriptor* method); + +grpc::string SummarizeService(const grpc::protobuf::ServiceDescriptor* service); + +grpc::string SummarizeMethod(const grpc::protobuf::MethodDescriptor* method); + +} // namespase testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H diff --git a/test/cpp/util/test_config.cc b/test/cpp/util/test_config_cc.cc index 8711746129..8711746129 100644 --- a/test/cpp/util/test_config.cc +++ b/test/cpp/util/test_config_cc.cc diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc index 6e68f59e6a..ca15f29795 100644 --- a/test/cpp/util/test_credentials_provider.cc +++ b/test/cpp/util/test_credentials_provider.cc @@ -37,6 +37,7 @@ #include <unordered_map> #include <grpc++/impl/sync.h> +#include <grpc/support/log.h> #include <grpc/support/sync.h> #include "test/core/end2end/data/ssl_test_data.h" diff --git a/test/distrib/csharp/DistribTest/.gitignore b/test/distrib/csharp/DistribTest/.gitignore index 1746e3269e..07f3d570e5 100644 --- a/test/distrib/csharp/DistribTest/.gitignore +++ b/test/distrib/csharp/DistribTest/.gitignore @@ -1,2 +1,3 @@ bin obj +*.lock.json diff --git a/test/distrib/csharp/DistribTest/DistribTest.csproj b/test/distrib/csharp/DistribTest/DistribTest.csproj index 6ca03b2c80..0bff9ff3e0 100644 --- a/test/distrib/csharp/DistribTest/DistribTest.csproj +++ b/test/distrib/csharp/DistribTest/DistribTest.csproj @@ -65,7 +65,7 @@ <Reference Include="System" /> <Reference Include="System.Core" /> <Reference Include="System.Interactive.Async"> - <HintPath>..\packages\Ix-Async.1.2.3\lib\net45\System.Interactive.Async.dll</HintPath> + <HintPath>..\packages\System.Interactive.Async.3.0.0\lib\net45\System.Interactive.Async.dll</HintPath> </Reference> <Reference Include="System.Net" /> <Reference Include="System.Net.Http" /> diff --git a/test/distrib/csharp/DistribTest/DistribTest.project.json b/test/distrib/csharp/DistribTest/DistribTest.project.json new file mode 100644 index 0000000000..422545ea8f --- /dev/null +++ b/test/distrib/csharp/DistribTest/DistribTest.project.json @@ -0,0 +1,11 @@ +// This file exists only to prevent VS2015 from mistakenly picking up +// project.json file when building .csproj project. +// See https://github.com/Microsoft/msbuild/issues/394 +{ + "frameworks": { + "net45": { } + }, + "runtimes": { + "win": { } + } +} diff --git a/test/distrib/csharp/DistribTest/Properties/AssemblyInfo.cs b/test/distrib/csharp/DistribTest/Properties/AssemblyInfo.cs index bc25b263ca..eacc41ee3c 100644 --- a/test/distrib/csharp/DistribTest/Properties/AssemblyInfo.cs +++ b/test/distrib/csharp/DistribTest/Properties/AssemblyInfo.cs @@ -1,4 +1,37 @@ -using System.Reflection; +#region Copyright notice and license + +// 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. + +#endregion + +using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; diff --git a/test/distrib/csharp/DistribTest/packages.config b/test/distrib/csharp/DistribTest/packages.config index e5d2d9d383..84be8f76b5 100644 --- a/test/distrib/csharp/DistribTest/packages.config +++ b/test/distrib/csharp/DistribTest/packages.config @@ -6,6 +6,6 @@ <package id="Grpc" version="__GRPC_NUGET_VERSION__" targetFramework="net45" /> <package id="Grpc.Auth" version="__GRPC_NUGET_VERSION__" targetFramework="net45" /> <package id="Grpc.Core" version="__GRPC_NUGET_VERSION__" targetFramework="net45" /> - <package id="Ix-Async" version="1.2.3" targetFramework="net45" /> + <package id="System.Interactive.Async" version="3.0.0" targetFramework="net45" /> <package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" /> -</packages> +</packages>
\ No newline at end of file diff --git a/test/distrib/csharp/DistribTest/project.json b/test/distrib/csharp/DistribTest/project.json new file mode 100644 index 0000000000..09266e5d4d --- /dev/null +++ b/test/distrib/csharp/DistribTest/project.json @@ -0,0 +1,22 @@ +{ + "buildOptions": { + "emitEntryPoint": true + }, + "dependencies": { + "Grpc.Auth": "__GRPC_NUGET_VERSION__", + "Grpc.Core": "__GRPC_NUGET_VERSION__", + // Necessary for native deps to get copied correctly. + "Microsoft.NETCore.Platforms": "1.0.1" + }, + "frameworks": { + "net45": { }, + "netcoreapp1.0": { + "dependencies": { + "Microsoft.NETCore.App": { + "type": "platform", + "version": "1.0.0" + } + } + } + } +} diff --git a/test/distrib/csharp/run_distrib_test.bat b/test/distrib/csharp/run_distrib_test.bat index 67bfc58ac8..6cf381142f 100644 --- a/test/distrib/csharp/run_distrib_test.bat +++ b/test/distrib/csharp/run_distrib_test.bat @@ -31,12 +31,22 @@ cd /d %~dp0 @rem extract input artifacts -powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets.zip', 'TestNugetFeed');" +powershell -Command "Add-Type -Assembly 'System.IO.Compression.FileSystem'; [System.IO.Compression.ZipFile]::ExtractToDirectory('../../../input_artifacts/csharp_nugets_dotnetcli.zip', 'TestNugetFeed');" update_version.sh auto set NUGET=C:\nuget\nuget.exe -%NUGET% restore || goto :error + +@rem TODO(jtattermusch): Get rid of this hack. See #8034 +@rem We can't do just "nuget restore" because restoring a .sln solution doesn't work +@rem with nuget 3.X. On the other hand, we need nuget 2.12+ to be able to restore +@rem some of the packages (e.g. System.Interactive.Async), but nuget 2.12 +@rem hasn't been officially released. +@rem Please note that "Restore nuget packages" in VS2013 and VS2015 GUI works as usual. + +cd DistribTest || goto :error +%NUGET% restore -PackagesDirectory ../packages || goto :error +cd .. @call build_vs2015.bat DistribTest.sln %MSBUILD_EXTRA_ARGS% || goto :error diff --git a/test/distrib/csharp/run_distrib_test.sh b/test/distrib/csharp/run_distrib_test.sh index 64e98d8009..0a77c1af44 100755 --- a/test/distrib/csharp/run_distrib_test.sh +++ b/test/distrib/csharp/run_distrib_test.sh @@ -32,7 +32,7 @@ set -ex cd $(dirname $0) -unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets.zip" -d TestNugetFeed +unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed ./update_version.sh auto diff --git a/test/distrib/csharp/run_distrib_test_dotnetcli.sh b/test/distrib/csharp/run_distrib_test_dotnetcli.sh new file mode 100755 index 0000000000..493c5049fb --- /dev/null +++ b/test/distrib/csharp/run_distrib_test_dotnetcli.sh @@ -0,0 +1,58 @@ +#!/bin/bash +# 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. + +set -ex + +cd $(dirname $0) + +unzip -o "$EXTERNAL_GIT_ROOT/input_artifacts/csharp_nugets_dotnetcli.zip" -d TestNugetFeed + +./update_version.sh auto + +cd DistribTest + +# TODO(jtattermusch): make sure we don't pollute the global nuget cache with +# the nugets being tested. +dotnet restore + +dotnet build +dotnet publish + +# .NET 4.5 target after dotnet build +mono bin/Debug/net45/*-x64/DistribTest.exe + +# .NET 4.5 target after dotnet publish +mono bin/Debug/net45/*-x64/publish/DistribTest.exe + +# .NET Core target after dotnet build +dotnet exec bin/Debug/netcoreapp1.0/DistribTest.dll + +# .NET Core target after dotnet publish +dotnet exec bin/Debug/netcoreapp1.0/publish/DistribTest.dll diff --git a/test/distrib/csharp/update_version.sh b/test/distrib/csharp/update_version.sh index 189d0ad357..2961d0c5ef 100755 --- a/test/distrib/csharp/update_version.sh +++ b/test/distrib/csharp/update_version.sh @@ -35,10 +35,10 @@ cd $(dirname $0) CSHARP_VERSION="$1" if [ "$CSHARP_VERSION" == "auto" ] then - # autodetect C# version - CSHARP_VERSION=$(ls TestNugetFeed | grep '^Grpc\.[0-9].*\.nupkg$' | sed s/^Grpc\.// | sed s/\.nupkg$//) + # autodetect C# version from the name of Grpc.Core.0.0.0-x.nupkg file + CSHARP_VERSION=$(ls TestNugetFeed | grep -m 1 '^Grpc\.Core\.[0-9].*\.nupkg$' | sed s/^Grpc\.Core\.// | sed s/\.nupkg$// | sed s/\.symbols$//) echo "Autodetected nuget ${CSHARP_VERSION}" fi # Replaces version placeholder with value provided as first argument. -sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj +sed -ibak "s/__GRPC_NUGET_VERSION__/${CSHARP_VERSION}/g" DistribTest/packages.config DistribTest/DistribTest.csproj DistribTest/project.json diff --git a/test/distrib/php/run_distrib_test.sh b/test/distrib/php/run_distrib_test.sh index 5c86283282..9ce3e05cd4 100755 --- a/test/distrib/php/run_distrib_test.sh +++ b/test/distrib/php/run_distrib_test.sh @@ -32,8 +32,9 @@ set -ex cd $(dirname $0) -cp -r $EXTERNAL_GIT_ROOT/input_artifacts/grpc-php.tgz . +cp -r $EXTERNAL_GIT_ROOT/input_artifacts/grpc-*.tgz . -pecl install grpc-php.tgz +find . -regextype sed -regex ".*/grpc-[0-9].*.tgz" | cut -b3- | \ + xargs pecl install php -d extension=grpc.so -d max_execution_time=300 distribtest.php |