diff options
author | Alistair Veitch <aveitch@google.com> | 2015-06-01 13:34:15 -0700 |
---|---|---|
committer | Alistair Veitch <aveitch@google.com> | 2015-06-01 13:34:15 -0700 |
commit | f3da552d5b62acabd6a3cdb37b1794fa9a50a9a5 (patch) | |
tree | 56d8b80561dab416b81e5309c60088aaa8bc570e /test | |
parent | 269676209ead4602e0cb0bd02ebf378dcd5df7b3 (diff) | |
parent | 7f61193cdeacfb21f4e99ac6b8e2c0da33a643e8 (diff) |
merge with master
Diffstat (limited to 'test')
93 files changed, 2779 insertions, 480 deletions
diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py index ad3bebac30..367effdb1a 100644 --- a/test/compiler/python_plugin_test.py +++ b/test/compiler/python_plugin_test.py @@ -520,4 +520,4 @@ class PythonPluginTest(unittest.TestCase): if __name__ == '__main__': os.chdir(os.path.dirname(sys.argv[0])) - unittest.main() + unittest.main(verbosity=2) diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c new file mode 100644 index 0000000000..9d1c4ce2d7 --- /dev/null +++ b/test/core/bad_client/bad_client.c @@ -0,0 +1,137 @@ +/* + * + * 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/bad_client/bad_client.h" + +#include "src/core/channel/channel_stack.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/endpoint_pair.h" +#include "src/core/surface/completion_queue.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" + +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> + +typedef struct { + grpc_server *server; + grpc_completion_queue *cq; + grpc_bad_client_server_side_validator validator; + gpr_event done_thd; + gpr_event done_write; +} thd_args; + +static void thd_func(void *arg) { + thd_args *a = arg; + a->validator(a->server, a->cq); + gpr_event_set(&a->done_thd, (void *)1); +} + +static void done_write(void *arg, grpc_endpoint_cb_status status) { + thd_args *a = arg; + gpr_event_set(&a->done_write, (void *)1); +} + +static grpc_transport_setup_result server_setup_transport( + void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { + thd_args *a = ts; + static grpc_channel_filter const *extra_filters[] = { + &grpc_http_server_filter}; + return grpc_server_setup_transport(a->server, transport, extra_filters, + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(a->server)); +} + +void grpc_run_bad_client_test(const char *name, const char *client_payload, + size_t client_payload_length, + grpc_bad_client_server_side_validator validator) { + grpc_endpoint_pair sfd; + thd_args a; + gpr_thd_id id; + gpr_slice slice = + gpr_slice_from_copied_buffer(client_payload, client_payload_length); + + /* Add a debug log */ + gpr_log(GPR_INFO, "TEST: %s", name); + + /* Init grpc */ + grpc_init(); + + /* Create endpoints */ + sfd = grpc_iomgr_create_endpoint_pair(65536); + + /* Create server, completion events */ + a.server = grpc_server_create_from_filters(NULL, 0, NULL); + a.cq = grpc_completion_queue_create(); + gpr_event_init(&a.done_thd); + gpr_event_init(&a.done_write); + a.validator = validator; + grpc_server_register_completion_queue(a.server, a.cq); + grpc_server_start(a.server); + grpc_create_chttp2_transport(server_setup_transport, &a, NULL, sfd.server, + NULL, 0, grpc_mdctx_create(), 0); + + /* Bind everything into the same pollset */ + grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq)); + grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq)); + + /* Check a ground truth */ + GPR_ASSERT(grpc_server_has_open_connections(a.server)); + + /* Start validator */ + gpr_thd_new(&id, thd_func, &a, NULL); + + /* Write data */ + switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) { + case GRPC_ENDPOINT_WRITE_DONE: + done_write(&a, 1); + break; + case GRPC_ENDPOINT_WRITE_PENDING: + break; + case GRPC_ENDPOINT_WRITE_ERROR: + done_write(&a, 0); + break; + } + + /* Await completion */ + GPR_ASSERT( + gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); + GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5))); + + /* Shutdown */ + grpc_endpoint_destroy(sfd.client); + grpc_server_destroy(a.server); + grpc_completion_queue_destroy(a.cq); + + grpc_shutdown(); +} diff --git a/test/core/bad_client/bad_client.h b/test/core/bad_client/bad_client.h new file mode 100644 index 0000000000..4834e86cce --- /dev/null +++ b/test/core/bad_client/bad_client.h @@ -0,0 +1,52 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H +#define GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H + +#include <grpc/grpc.h> +#include "test/core/util/test_config.h" + +typedef void (*grpc_bad_client_server_side_validator)( + grpc_server *server, grpc_completion_queue *cq); + +/* Test runner. + + Create a server, and send client_payload to it as bytes from a client. + Execute validator in a separate thread to assert that the bytes are + handled as expected. */ +void grpc_run_bad_client_test(const char *name, const char *client_payload, + size_t client_payload_length, + grpc_bad_client_server_side_validator validator); + +#endif /* GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H */ diff --git a/test/core/bad_client/gen_build_json.py b/test/core/bad_client/gen_build_json.py new file mode 100755 index 0000000000..67969a1a12 --- /dev/null +++ b/test/core/bad_client/gen_build_json.py @@ -0,0 +1,79 @@ +#!/usr/bin/env python +# 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. + + +"""Generates the appropriate build.json data for all the end2end tests.""" + + +import simplejson +import collections + +TestOptions = collections.namedtuple('TestOptions', 'flaky') +default_test_options = TestOptions(False) + +# maps test names to options +BAD_CLIENT_TESTS = { + 'connection_prefix': default_test_options, +} + +def main(): + json = { + '#': 'generated with test/bad_client/gen_build_json.py', + 'libs': [ + { + 'name': 'bad_client_test', + 'build': 'private', + 'language': 'c', + 'src': [ + 'test/core/bad_client/bad_client.c' + ] + }], + 'targets': [ + { + 'name': '%s_bad_client_test' % t, + 'build': 'test', + 'language': 'c', + 'secure': 'no', + 'src': ['test/core/bad_client/tests/%s.c' % t], + 'flaky': 'invoke_large_request' in t, + 'deps': [ + 'bad_client_test', + 'grpc_test_util_unsecure', + 'grpc_unsecure', + 'gpr_test_util', + 'gpr' + ] + } + for t in sorted(BAD_CLIENT_TESTS.keys())]} + print simplejson.dumps(json, sort_keys=True, indent=2 * ' ') + + +if __name__ == '__main__': + main() diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c new file mode 100644 index 0000000000..e8bf935710 --- /dev/null +++ b/test/core/bad_client/tests/connection_prefix.c @@ -0,0 +1,79 @@ +/* + * + * 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/bad_client/bad_client.h" +#include "src/core/surface/server.h" + +static void verifier(grpc_server *server, grpc_completion_queue *cq) { + while (grpc_server_has_open_connections(server)) { + GPR_ASSERT(grpc_completion_queue_next( + cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20)).type == + GRPC_QUEUE_TIMEOUT); + } +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + + grpc_run_bad_client_test("conpfx_1", "X", 1, verifier); + grpc_run_bad_client_test("conpfx_2", "PX", 2, verifier); + grpc_run_bad_client_test("conpfx_3", "PRX", 3, verifier); + grpc_run_bad_client_test("conpfx_4", "PRIX", 4, verifier); + grpc_run_bad_client_test("conpfx_5", "PRI X", 5, verifier); + grpc_run_bad_client_test("conpfx_6", "PRI *X", 6, verifier); + grpc_run_bad_client_test("conpfx_7", "PRI * X", 7, verifier); + grpc_run_bad_client_test("conpfx_8", "PRI * HX", 8, verifier); + grpc_run_bad_client_test("conpfx_9", "PRI * HTX", 9, verifier); + grpc_run_bad_client_test("conpfx_10", "PRI * HTTX", 10, verifier); + grpc_run_bad_client_test("conpfx_11", "PRI * HTTPX", 11, verifier); + grpc_run_bad_client_test("conpfx_12", "PRI * HTTP/X", 12, verifier); + grpc_run_bad_client_test("conpfx_13", "PRI * HTTP/2X", 13, verifier); + grpc_run_bad_client_test("conpfx_14", "PRI * HTTP/2.X", 14, verifier); + grpc_run_bad_client_test("conpfx_15", "PRI * HTTP/2.0X", 15, verifier); + grpc_run_bad_client_test("conpfx_16", "PRI * HTTP/2.0\rX", 16, verifier); + grpc_run_bad_client_test("conpfx_17", "PRI * HTTP/2.0\r\nX", 17, verifier); + grpc_run_bad_client_test("conpfx_18", "PRI * HTTP/2.0\r\n\rX", 18, verifier); + grpc_run_bad_client_test("conpfx_19", "PRI * HTTP/2.0\r\n\r\nX", 19, + verifier); + grpc_run_bad_client_test("conpfx_20", "PRI * HTTP/2.0\r\n\r\nSX", 20, + verifier); + grpc_run_bad_client_test("conpfx_21", "PRI * HTTP/2.0\r\n\r\nSMX", 21, + verifier); + grpc_run_bad_client_test("conpfx_22", "PRI * HTTP/2.0\r\n\r\nSM\rX", 22, + verifier); + grpc_run_bad_client_test("conpfx_23", "PRI * HTTP/2.0\r\n\r\nSM\r\nX", 23, + verifier); + grpc_run_bad_client_test("conpfx_24", "PRI * HTTP/2.0\r\n\r\nSM\r\n\rX", 24, + verifier); + return 0; +} diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 957dee1aa7..fe92f2f023 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -39,8 +39,6 @@ #include <grpc/support/log.h> #include "test/core/util/test_config.h" -#define LOG_TEST_NAME() gpr_log(GPR_INFO, "%s", __FUNCTION__) - static void channel_init_func(grpc_channel_element *elem, const grpc_channel_args *args, grpc_mdctx *metadata_context, int is_first, @@ -91,8 +89,6 @@ static void test_create_channel_stack(void) { int *channel_data; int *call_data; - LOG_TEST_NAME(); - metadata_context = grpc_mdctx_create(); arg.type = GRPC_ARG_INTEGER; diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 66480254d2..7822d001d1 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -127,11 +127,15 @@ static gpr_slice merge_slices(gpr_slice *slices, size_t nslices) { } static int byte_buffer_eq_slice(grpc_byte_buffer *bb, gpr_slice b) { - gpr_slice a = - merge_slices(bb->data.slice_buffer.slices, bb->data.slice_buffer.count); - int ok = GPR_SLICE_LENGTH(a) == GPR_SLICE_LENGTH(b) && - 0 == memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b), - GPR_SLICE_LENGTH(a)); + gpr_slice a; + int ok; + + if (!bb) return 0; + + a = merge_slices(bb->data.slice_buffer.slices, bb->data.slice_buffer.count); + ok = GPR_SLICE_LENGTH(a) == GPR_SLICE_LENGTH(b) && + 0 == memcmp(GPR_SLICE_START_PTR(a), GPR_SLICE_START_PTR(b), + GPR_SLICE_LENGTH(a)); gpr_slice_unref(a); gpr_slice_unref(b); return ok; diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index be3c7ca17f..06614a93e7 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -211,6 +211,9 @@ void test_connect(const char *server_host, const char *client_host, int port, grpc_completion_queue_shutdown(server_cq); drain_cq(server_cq); grpc_completion_queue_destroy(server_cq); + + grpc_call_details_destroy(&call_details); + gpr_free(details); } int main(int argc, char **argv) { diff --git a/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c new file mode 100644 index 0000000000..f92b40efeb --- /dev/null +++ b/test/core/end2end/fixtures/chttp2_fullstack_with_poll.c @@ -0,0 +1,118 @@ +/* + * + * 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 <string.h> + +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/client.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.h" +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.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/port.h" +#include "test/core/util/test_config.h" + +typedef struct fullstack_fixture_data { + char *localaddr; +} 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; + int port = grpc_pick_unused_port_or_die(); + fullstack_fixture_data *ffd = gpr_malloc(sizeof(fullstack_fixture_data)); + memset(&f, 0, sizeof(f)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + f.fixture_data = ffd; + f.client_cq = grpc_completion_queue_create(); + f.server_cq = grpc_completion_queue_create(); + + return f; +} + +void chttp2_init_client_fullstack(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args) { + fullstack_fixture_data *ffd = f->fixture_data; + f->client = grpc_channel_create(ffd->localaddr, client_args); +} + +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); + grpc_server_register_completion_queue(f->server, f->server_cq); + GPR_ASSERT(grpc_server_add_http2_port(f->server, ffd->localaddr)); + 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->localaddr); + 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_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(configs[i]); + } + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c new file mode 100644 index 0000000000..a5865d37c8 --- /dev/null +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack_with_poll.c @@ -0,0 +1,168 @@ +/* + * + * 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 "src/core/channel/channel_args.h" +#include "src/core/security/credentials.h" +#include "src/core/support/env.h" +#include "src/core/support/file.h" +#include "src/core/support/string.h" +#include <grpc/support/alloc.h> +#include <grpc/support/host_port.h> +#include <grpc/support/log.h> +#include "test/core/util/test_config.h" +#include "test/core/util/port.h" +#include "test/core/end2end/data/ssl_test_data.h" + +typedef struct fullstack_secure_fixture_data { + char *localaddr; +} fullstack_secure_fixture_data; + +static grpc_end2end_test_fixture chttp2_create_fixture_secure_fullstack( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_end2end_test_fixture f; + int port = grpc_pick_unused_port_or_die(); + fullstack_secure_fixture_data *ffd = + gpr_malloc(sizeof(fullstack_secure_fixture_data)); + memset(&f, 0, sizeof(f)); + + gpr_join_host_port(&ffd->localaddr, "localhost", port); + + f.fixture_data = ffd; + f.client_cq = grpc_completion_queue_create(); + f.server_cq = grpc_completion_queue_create(); + + return f; +} + +static void chttp2_init_client_secure_fullstack(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args, + grpc_credentials *creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + f->client = grpc_secure_channel_create(creds, ffd->localaddr, client_args); + GPR_ASSERT(f->client != NULL); + grpc_credentials_release(creds); +} + +static void chttp2_init_server_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args, + grpc_server_credentials *server_creds) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + if (f->server) { + grpc_server_destroy(f->server); + } + f->server = grpc_server_create(server_args); + grpc_server_register_completion_queue(f->server, f->server_cq); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, + server_creds)); + grpc_server_credentials_release(server_creds); + grpc_server_start(f->server); +} + +void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { + fullstack_secure_fixture_data *ffd = f->fixture_data; + gpr_free(ffd->localaddr); + gpr_free(ffd); +} + +static void chttp2_init_client_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { + grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL); + grpc_arg ssl_name_override = {GRPC_ARG_STRING, + GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, + {"foo.test.google.fr"}}; + grpc_channel_args *new_client_args = + grpc_channel_args_copy_and_add(client_args, &ssl_name_override); + chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); + grpc_channel_args_destroy(new_client_args); +} + +static void chttp2_init_server_simple_ssl_secure_fullstack( + grpc_end2end_test_fixture *f, grpc_channel_args *server_args) { + grpc_ssl_pem_key_cert_pair pem_cert_key_pair = {test_server1_key, + test_server1_cert}; + grpc_server_credentials *ssl_creds = + grpc_ssl_server_credentials_create(NULL, &pem_cert_key_pair, 1); + chttp2_init_server_secure_fullstack(f, server_args, ssl_creds); +} + +/* All test configurations */ + +static grpc_end2end_test_config configs[] = { + {"chttp2/simple_ssl_fullstack", + FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | + FEATURE_MASK_SUPPORTS_HOSTNAME_VERIFICATION | + FEATURE_MASK_SUPPORTS_PER_CALL_CREDENTIALS, + chttp2_create_fixture_secure_fullstack, + chttp2_init_client_simple_ssl_secure_fullstack, + chttp2_init_server_simple_ssl_secure_fullstack, + chttp2_tear_down_secure_fullstack}, +}; + +int main(int argc, char **argv) { + size_t i; + FILE *roots_file; + size_t roots_size = strlen(test_root_cert); + char *roots_filename; + + grpc_platform_become_multipoller = grpc_poll_become_multipoller; + + grpc_test_init(argc, argv); + + /* Set the SSL roots env var. */ + roots_file = gpr_tmpfile("chttp2_simple_ssl_with_poll_fullstack_test", + &roots_filename); + GPR_ASSERT(roots_filename != NULL); + GPR_ASSERT(roots_file != NULL); + GPR_ASSERT(fwrite(test_root_cert, 1, roots_size, roots_file) == roots_size); + fclose(roots_file); + gpr_setenv(GRPC_DEFAULT_SSL_ROOTS_FILE_PATH_ENV_VAR, roots_filename); + + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(configs[i]); + } + + grpc_shutdown(); + + /* Cleanup. */ + remove(roots_filename); + gpr_free(roots_filename); + + return 0; +} diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c index 43ebf7eed5..e0221d0452 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair.c @@ -62,7 +62,8 @@ static grpc_transport_setup_result server_setup_transport( static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; return grpc_server_setup_transport(f->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); } typedef struct { diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c index 385d5a4e81..37b5529d7f 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c @@ -62,7 +62,8 @@ static grpc_transport_setup_result server_setup_transport( static grpc_channel_filter const *extra_filters[] = { &grpc_http_server_filter}; return grpc_server_setup_transport(f->server, transport, extra_filters, - GPR_ARRAY_SIZE(extra_filters), mdctx); + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); } typedef struct { diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c new file mode 100644 index 0000000000..b15a18f1a7 --- /dev/null +++ b/test/core/end2end/fixtures/chttp2_socket_pair_with_grpc_trace.c @@ -0,0 +1,157 @@ +/* + * + * 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 <string.h> + +#include "src/core/channel/client_channel.h" +#include "src/core/channel/connected_channel.h" +#include "src/core/channel/http_client_filter.h" +#include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/endpoint_pair.h" +#include "src/core/iomgr/iomgr.h" +#include "src/core/support/env.h" +#include "src/core/surface/channel.h" +#include "src/core/surface/client.h" +#include "src/core/surface/server.h" +#include "src/core/transport/chttp2_transport.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/port.h" +#include "test/core/util/test_config.h" + +/* chttp2 transport that is immediately available (used for testing + connected_channel without a client_channel */ + +static grpc_transport_setup_result server_setup_transport( + void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { + grpc_end2end_test_fixture *f = ts; + static grpc_channel_filter const *extra_filters[] = { + &grpc_http_server_filter}; + return grpc_server_setup_transport(f->server, transport, extra_filters, + GPR_ARRAY_SIZE(extra_filters), mdctx, + grpc_server_get_channel_args(f->server)); +} + +typedef struct { + grpc_end2end_test_fixture *f; + grpc_channel_args *client_args; +} sp_client_setup; + +static grpc_transport_setup_result client_setup_transport( + void *ts, grpc_transport *transport, grpc_mdctx *mdctx) { + sp_client_setup *cs = ts; + + const grpc_channel_filter *filters[] = {&grpc_client_surface_filter, + &grpc_http_client_filter, + &grpc_connected_channel_filter}; + size_t nfilters = sizeof(filters) / sizeof(*filters); + grpc_channel *channel = grpc_channel_create_from_filters( + filters, nfilters, cs->client_args, mdctx, 1); + + cs->f->client = channel; + + return grpc_connected_channel_bind_transport( + grpc_channel_get_channel_stack(channel), transport); +} + +static grpc_end2end_test_fixture chttp2_create_fixture_socketpair( + grpc_channel_args *client_args, grpc_channel_args *server_args) { + grpc_endpoint_pair *sfd = gpr_malloc(sizeof(grpc_endpoint_pair)); + + grpc_end2end_test_fixture f; + memset(&f, 0, sizeof(f)); + f.fixture_data = sfd; + f.client_cq = grpc_completion_queue_create(); + f.server_cq = grpc_completion_queue_create(); + + *sfd = grpc_iomgr_create_endpoint_pair(65536); + + return f; +} + +static void chttp2_init_client_socketpair(grpc_end2end_test_fixture *f, + grpc_channel_args *client_args) { + grpc_endpoint_pair *sfd = f->fixture_data; + sp_client_setup cs; + cs.client_args = client_args; + cs.f = f; + grpc_create_chttp2_transport(client_setup_transport, &cs, client_args, + sfd->client, NULL, 0, grpc_mdctx_create(), 1); + GPR_ASSERT(f->client); +} + +static void chttp2_init_server_socketpair(grpc_end2end_test_fixture *f, + grpc_channel_args *server_args) { + grpc_endpoint_pair *sfd = f->fixture_data; + GPR_ASSERT(!f->server); + f->server = grpc_server_create_from_filters(NULL, 0, server_args); + grpc_server_register_completion_queue(f->server, f->server_cq); + grpc_server_start(f->server); + grpc_create_chttp2_transport(server_setup_transport, f, server_args, + sfd->server, NULL, 0, grpc_mdctx_create(), 0); +} + +static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture *f) { + gpr_free(f->fixture_data); +} + +/* All test configurations */ +static grpc_end2end_test_config configs[] = { + {"chttp2/socketpair", 0, chttp2_create_fixture_socketpair, + chttp2_init_client_socketpair, chttp2_init_server_socketpair, + chttp2_tear_down_socketpair}, +}; + +int main(int argc, char **argv) { + size_t i; + + /* force tracing on, with a value to force many + code paths in trace.c to be taken */ + gpr_setenv("GRPC_TRACE", "doesnt-exist,http,all"); + + grpc_test_init(argc, argv); + grpc_init(); + + for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { + grpc_end2end_tests(configs[i]); + } + + grpc_shutdown(); + + return 0; +} diff --git a/test/core/end2end/gen_build_json.py b/test/core/end2end/gen_build_json.py index bce2d7a796..fb13c7840c 100755 --- a/test/core/end2end/gen_build_json.py +++ b/test/core/end2end/gen_build_json.py @@ -44,11 +44,14 @@ default_secure_fixture_options = FixtureOptions(True, ['windows', 'posix']) END2END_FIXTURES = { 'chttp2_fake_security': default_secure_fixture_options, 'chttp2_fullstack': default_unsecure_fixture_options, + 'chttp2_fullstack_with_poll': FixtureOptions(False, ['posix']), 'chttp2_fullstack_uds_posix': FixtureOptions(False, ['posix']), 'chttp2_simple_ssl_fullstack': default_secure_fixture_options, + 'chttp2_simple_ssl_fullstack_with_poll': FixtureOptions(True, ['posix']), 'chttp2_simple_ssl_with_oauth2_fullstack': default_secure_fixture_options, 'chttp2_socket_pair': default_unsecure_fixture_options, 'chttp2_socket_pair_one_byte_at_a_time': default_unsecure_fixture_options, + 'chttp2_socket_pair_with_grpc_trace': default_unsecure_fixture_options, } TestOptions = collections.namedtuple('TestOptions', 'flaky secure') @@ -81,6 +84,7 @@ END2END_TESTS = { 'request_response_with_payload_and_call_creds': TestOptions(flaky=False, secure=True), 'request_with_large_metadata': default_test_options, 'request_with_payload': default_test_options, + 'server_finishes_request': default_test_options, 'simple_delayed_request': default_test_options, 'simple_request': default_test_options, 'simple_request_with_high_initial_sequence_number': default_test_options, diff --git a/test/core/end2end/tests/bad_hostname.c b/test/core/end2end/tests/bad_hostname.c index e145d2e95b..0220f34534 100644 --- a/test/core/end2end/tests/bad_hostname.c +++ b/test/core/end2end/tests/bad_hostname.c @@ -158,7 +158,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { static void test_invoke_simple_request(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - f = begin_test(config, __FUNCTION__, NULL, NULL); + f = begin_test(config, "test_invoke_simple_request", NULL, NULL); simple_request_body(f); end_test(&f); config.tear_down_data(&f); diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 275333897f..daf386c326 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -105,7 +105,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, grpc_op *op; grpc_call *c; grpc_call *s; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "cancel_after_accept", NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c index eaf8b60e98..0bd98997e9 100644 --- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c +++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c @@ -105,7 +105,7 @@ static void test_cancel_after_accept_and_writes_closed( grpc_op *op; grpc_call *c; grpc_call *s; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_cancel_after_accept_and_writes_closed", NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index 618d9e97e3..c5e0ca5517 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -106,7 +106,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, grpc_op *op; grpc_call *c; grpc_end2end_test_fixture f = - begin_test(config, __FUNCTION__, mode, NULL, NULL); + begin_test(config, "test_cancel_after_invoke", mode, NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); grpc_metadata_array initial_metadata_recv; diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index 9c9d6aadcc..0482d370dc 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -103,7 +103,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, grpc_op ops[6]; grpc_op *op; grpc_call *c; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "cancel_before_invoke", NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); grpc_metadata_array initial_metadata_recv; diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 1bc393aba7..f0984cb5dc 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -100,7 +100,7 @@ static void end_test(grpc_end2end_test_fixture *f) { static void test_cancel_in_a_vacuum(grpc_end2end_test_config config, cancellation_mode mode) { grpc_call *c; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_cancel_in_a_vacuum", NULL, NULL); gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c index 2017ab6536..b808684cd1 100644 --- a/test/core/end2end/tests/census_simple_request.c +++ b/test/core/end2end/tests/census_simple_request.c @@ -204,7 +204,7 @@ static void test_invoke_request_with_census( server_args.num_args = 1; server_args.args = &server_arg; - gpr_asprintf(&fullname, "%s/%s", __FUNCTION__, name); + gpr_asprintf(&fullname, "%s/%s", "test_invoke_request_with_census", name); f = begin_test(config, fullname, &client_args, &server_args); body(f); end_test(&f); diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index 89fff81dba..60e7d227b9 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -180,7 +180,7 @@ static void disappearing_server_test(grpc_end2end_test_config config) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); + gpr_log(GPR_INFO, "%s/%s", "disappearing_server_test", config.name); config.init_client(&f, NULL); config.init_server(&f, NULL); diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c index 42280a6046..a44823033d 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c @@ -102,7 +102,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_call *c; grpc_call *s; gpr_timespec deadline = five_seconds_time(); - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_early_server_shutdown_finishes_inflight_calls", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c index 857fbb3c88..a8eb2144bb 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c @@ -99,7 +99,7 @@ static void end_test(grpc_end2end_test_fixture *f) { static void test_early_server_shutdown_finishes_tags( grpc_end2end_test_config config) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_early_server_shutdown_finishes_tags", NULL, NULL); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_call *s = (void *)1; grpc_call_details call_details; diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index a57f921efb..d1e5527e9e 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -121,7 +121,7 @@ static void empty_batch_body(grpc_end2end_test_fixture f) { static void test_invoke_empty_body(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - f = begin_test(config, __FUNCTION__, NULL, NULL); + f = begin_test(config, "test_invoke_empty_body", NULL, NULL); empty_batch_body(f); end_test(&f); config.tear_down_data(&f); diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index 9c44f6e127..d7b9fde3a6 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -101,7 +101,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( grpc_call *c; grpc_call *s; gpr_timespec deadline = five_seconds_time(); - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_early_server_shutdown_finishes_inflight_calls", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index f369e7805e..5552016efa 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -102,7 +102,7 @@ static gpr_slice large_slice(void) { } static void test_invoke_large_request(grpc_end2end_test_config config) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_large_request", NULL, NULL); gpr_slice request_payload_slice = large_slice(); gpr_slice response_payload_slice = large_slice(); @@ -171,23 +171,30 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; + op = ops; 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++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 59227d98ab..ef0af34c0d 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -222,7 +222,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { server_args.num_args = 1; server_args.args = &server_arg; - f = begin_test(config, __FUNCTION__, NULL, &server_args); + f = begin_test(config, "test_max_concurrent_streams", NULL, &server_args); v_client = cq_verifier_create(f.client_cq); v_server = cq_verifier_create(f.server_cq); diff --git a/test/core/end2end/tests/max_message_length.c b/test/core/end2end/tests/max_message_length.c index 99aeb9d049..532986e7d0 100644 --- a/test/core/end2end/tests/max_message_length.c +++ b/test/core/end2end/tests/max_message_length.c @@ -126,7 +126,7 @@ static void test_max_message_length(grpc_end2end_test_config config) { server_args.num_args = 1; server_args.args = &server_arg; - f = begin_test(config, __FUNCTION__, NULL, &server_args); + f = begin_test(config, "test_max_message_length", NULL, &server_args); v_client = cq_verifier_create(f.client_cq); v_server = cq_verifier_create(f.server_cq); @@ -178,8 +178,7 @@ static void test_max_message_length(grpc_end2end_test_config config) { cq_expect_completion(v_client, tag(1), 1); cq_verify(v_client); - GPR_ASSERT(status == GRPC_STATUS_CANCELLED); - GPR_ASSERT(0 == strcmp(details, "Cancelled")); + 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); @@ -189,6 +188,7 @@ static void test_max_message_length(grpc_end2end_test_config config) { grpc_metadata_array_destroy(&trailing_metadata_recv); grpc_metadata_array_destroy(&request_metadata_recv); grpc_call_details_destroy(&call_details); + grpc_byte_buffer_destroy(request_payload); grpc_call_destroy(c); grpc_call_destroy(s); diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 000d2ffa2a..5b18efcbfd 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -96,7 +96,7 @@ static void end_test(grpc_end2end_test_fixture *f) { } static void test_no_op(grpc_end2end_test_config config) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "no-op", NULL, NULL); end_test(&f); config.tear_down_data(&f); } diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 2bd17924f3..cfd4e45703 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -100,7 +100,7 @@ static void end_test(grpc_end2end_test_fixture *f) { /* Client pings and server pongs. Repeat messages rounds before finishing. */ static void test_pingpong_streaming(grpc_end2end_test_config config, int messages) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_pingpong_streaming", NULL, NULL); grpc_call *c; grpc_call *s; gpr_timespec deadline = five_seconds_time(); diff --git a/test/core/end2end/tests/registered_call.c b/test/core/end2end/tests/registered_call.c index 54663c3690..2cf2ccec1a 100644 --- a/test/core/end2end/tests/registered_call.c +++ b/test/core/end2end/tests/registered_call.c @@ -188,7 +188,7 @@ static void simple_request_body(grpc_end2end_test_fixture f, void *rc) { } static void test_invoke_simple_request(grpc_end2end_test_config config) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_simple_request", NULL, NULL); void *rc = grpc_channel_register_call(f.client, "/foo", "foo.test.google.fr:1234"); @@ -199,7 +199,7 @@ static void test_invoke_simple_request(grpc_end2end_test_config config) { static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { int i; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_10_simple_requests", NULL, NULL); void *rc = grpc_channel_register_call(f.client, "/foo", "foo.test.google.fr:1234"); diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c index 709dc47b72..69eb68a2a1 100644 --- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c @@ -127,7 +127,7 @@ static void test_request_response_with_metadata_and_payload( "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", 16, {{NULL, NULL, NULL}}}}; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; @@ -188,6 +188,18 @@ static void test_request_response_with_metadata_and_payload( op->data.send_initial_metadata.count = 2; op->data.send_initial_metadata.metadata = meta_s; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; @@ -196,15 +208,9 @@ static void test_request_response_with_metadata_and_payload( op->data.send_status_from_server.status = GRPC_STATUS_OK; op->data.send_status_from_server.status_details = "xyz"; op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c index bc32a503dd..fe15fa257d 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c @@ -113,7 +113,7 @@ static void test_request_response_with_metadata_and_payload( {"key2", "val2", 4, {{NULL, NULL, NULL}}}}; grpc_metadata meta_s[2] = {{"key3", "val3", 4, {{NULL, NULL, NULL}}}, {"key4", "val4", 4, {{NULL, NULL, NULL}}}}; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; @@ -174,6 +174,18 @@ static void test_request_response_with_metadata_and_payload( op->data.send_initial_metadata.count = 2; op->data.send_initial_metadata.metadata = meta_s; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; @@ -182,15 +194,9 @@ static void test_request_response_with_metadata_and_payload( op->data.send_status_from_server.status = GRPC_STATUS_OK; op->data.send_status_from_server.status_details = "xyz"; op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c index be0cca696b..f0122ea95d 100644 --- a/test/core/end2end/tests/request_response_with_payload.c +++ b/test/core/end2end/tests/request_response_with_payload.c @@ -165,6 +165,18 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; @@ -173,15 +185,9 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { op->data.send_status_from_server.status = GRPC_STATUS_OK; op->data.send_status_from_server.status_details = "xyz"; op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); @@ -217,7 +223,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { payload and status. */ static void test_invoke_request_response_with_payload( grpc_end2end_test_config config) { - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_request_response_with_payload", NULL, NULL); request_response_with_payload(f); end_test(&f); config.tear_down_data(&f); @@ -226,7 +232,7 @@ static void test_invoke_request_response_with_payload( static void test_invoke_10_request_response_with_payload( grpc_end2end_test_config config) { int i; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_10_request_response_with_payload", NULL, NULL); for (i = 0; i < 10; i++) { request_response_with_payload(f); } diff --git a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c index 01554bed8c..08443f19a5 100644 --- a/test/core/end2end/tests/request_response_with_payload_and_call_creds.c +++ b/test/core/end2end/tests/request_response_with_payload_and_call_creds.c @@ -111,10 +111,27 @@ static void end_test(grpc_end2end_test_fixture *f) { grpc_completion_queue_destroy(f->client_cq); } +static void print_auth_context(int is_client, const grpc_auth_context *ctx) { + const grpc_auth_property *p; + grpc_auth_property_iterator it; + gpr_log(GPR_INFO, "%s peer:", is_client ? "client" : "server"); + gpr_log(GPR_INFO, "\tauthenticated: %s", + grpc_auth_context_peer_is_authenticated(ctx) ? "YES" : "NO"); + it = grpc_auth_context_peer_identity(ctx); + while ((p = grpc_auth_property_iterator_next(&it)) != NULL) { + gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + } + gpr_log(GPR_INFO, "\tall properties:"); + it = grpc_auth_context_property_iterator(ctx); + while ((p = grpc_auth_property_iterator_next(&it)) != NULL) { + gpr_log(GPR_INFO, "\t\t%s: %s", p->name, p->value); + } +} + static void test_call_creds_failure(grpc_end2end_test_config config) { grpc_call *c; grpc_credentials *creds = NULL; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_call_creds_failure", NULL, NULL); gpr_timespec deadline = five_seconds_time(); c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "foo.test.google.fr", deadline); @@ -125,6 +142,8 @@ static void test_call_creds_failure(grpc_end2end_test_config config) { GPR_ASSERT(grpc_call_set_credentials(c, creds) != GRPC_CALL_OK); grpc_credentials_release(creds); + grpc_call_destroy(c); + end_test(&f); config.tear_down_data(&f); } @@ -158,6 +177,7 @@ static void request_response_with_payload_and_call_creds( size_t details_capacity = 0; int was_cancelled = 2; grpc_credentials *creds = NULL; + const grpc_auth_context *s_auth_context = NULL; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", "foo.test.google.fr", deadline); @@ -212,10 +232,13 @@ static void request_response_with_payload_and_call_creds( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, f.server_cq, + f.server_cq, f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), 1); cq_verify(v_server); + s_auth_context = grpc_call_auth_context(s); + GPR_ASSERT(s_auth_context != NULL); + print_auth_context(0, s_auth_context); /* Cannot set creds on the server call object. */ GPR_ASSERT(grpc_call_set_credentials(s, NULL) != GRPC_CALL_OK); @@ -224,6 +247,18 @@ static void request_response_with_payload_and_call_creds( op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; @@ -232,15 +267,9 @@ static void request_response_with_payload_and_call_creds( op->data.send_status_from_server.status = GRPC_STATUS_OK; op->data.send_status_from_server.status_details = "xyz"; op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); @@ -310,17 +339,17 @@ static void request_response_with_payload_and_call_creds( void test_request_response_with_payload_and_call_creds( grpc_end2end_test_config config) { - request_response_with_payload_and_call_creds(__FUNCTION__, config, NONE); + request_response_with_payload_and_call_creds("test_request_response_with_payload_and_call_creds", config, NONE); } void test_request_response_with_payload_and_overridden_call_creds( grpc_end2end_test_config config) { - request_response_with_payload_and_call_creds(__FUNCTION__, config, OVERRIDE); + request_response_with_payload_and_call_creds("test_request_response_with_payload_and_overridden_call_creds", config, OVERRIDE); } void test_request_response_with_payload_and_deleted_call_creds( grpc_end2end_test_config config) { - request_response_with_payload_and_call_creds(__FUNCTION__, config, DESTROY); + request_response_with_payload_and_call_creds("test_request_response_with_payload_and_deleted_call_creds", config, DESTROY); } void grpc_end2end_tests(grpc_end2end_test_config config) { diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c index 12f289cfdd..2f221f43d5 100644 --- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c @@ -112,7 +112,7 @@ static void test_request_response_with_metadata_and_payload( grpc_metadata meta_c[2] = {{"key1", "val1", 4, {{NULL, NULL, NULL}}}, {"key2", "val2", 4, {{NULL, NULL, NULL}}}}; grpc_metadata meta_s[2] = {{"key3", "val3", 4, {{NULL, NULL, NULL}}}, {"key4", "val4", 4, {{NULL, NULL, NULL}}}}; grpc_metadata meta_t[2] = {{"key5", "val5", 4, {{NULL, NULL, NULL}}}, {"key6", "val6", 4, {{NULL, NULL, NULL}}}}; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_request_response_with_metadata_and_payload", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; @@ -174,6 +174,18 @@ static void test_request_response_with_metadata_and_payload( op->data.send_initial_metadata.count = 2; op->data.send_initial_metadata.metadata = meta_s; op++; + op->op = GRPC_OP_RECV_MESSAGE; + op->data.recv_message = &request_payload_recv; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; op->op = GRPC_OP_SEND_MESSAGE; op->data.send_message = response_payload; op++; @@ -183,15 +195,9 @@ static void test_request_response_with_metadata_and_payload( op->data.send_status_from_server.status = GRPC_STATUS_OK; op->data.send_status_from_server.status_details = "xyz"; op++; - op->op = GRPC_OP_RECV_MESSAGE; - op->data.recv_message = &request_payload_recv; - op++; - op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; - op->data.recv_close_on_server.cancelled = &was_cancelled; - op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c index 08a16213a1..b89ccb76f0 100644 --- a/test/core/end2end/tests/request_with_large_metadata.c +++ b/test/core/end2end/tests/request_with_large_metadata.c @@ -106,7 +106,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { grpc_byte_buffer_create(&request_payload_slice, 1); gpr_timespec deadline = five_seconds_time(); grpc_metadata meta; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_request_with_large_metadata", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; @@ -169,20 +169,26 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; 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++; op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &request_payload_recv; op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->data.recv_close_on_server.cancelled = &was_cancelled; op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + 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++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index bba50b3113..9f6f2a9b22 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -105,7 +105,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { grpc_byte_buffer *request_payload = grpc_byte_buffer_create(&request_payload_slice, 1); gpr_timespec deadline = five_seconds_time(); - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_request_with_payload", NULL, NULL); cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); grpc_op ops[6]; @@ -160,20 +160,26 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { op->op = GRPC_OP_SEND_INITIAL_METADATA; op->data.send_initial_metadata.count = 0; 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++; op->op = GRPC_OP_RECV_MESSAGE; op->data.recv_message = &request_payload_recv; op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + op = ops; op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; op->data.recv_close_on_server.cancelled = &was_cancelled; op++; - GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + 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++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(103))); - cq_expect_completion(v_server, tag(102), 1); + cq_expect_completion(v_server, tag(103), 1); cq_verify(v_server); cq_expect_completion(v_client, tag(1), 1); diff --git a/test/core/end2end/tests/server_finishes_request.c b/test/core/end2end/tests/server_finishes_request.c new file mode 100644 index 0000000000..a0c1865290 --- /dev/null +++ b/test/core/end2end/tests/server_finishes_request.c @@ -0,0 +1,200 @@ +/* + * + * 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 "src/core/support/string.h" +#include <grpc/byte_buffer.h> +#include <grpc/grpc.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(gpr_intptr 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_client(&f, client_args); + config.init_server(&f, server_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()); + } while (ev.type != GRPC_QUEUE_SHUTDOWN); +} + +static void shutdown_server(grpc_end2end_test_fixture *f) { + if (!f->server) return; + grpc_server_shutdown(f->server); + 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->server_cq); + drain_cq(f->server_cq); + grpc_completion_queue_destroy(f->server_cq); + grpc_completion_queue_shutdown(f->client_cq); + drain_cq(f->client_cq); + grpc_completion_queue_destroy(f->client_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 *v_client = cq_verifier_create(f.client_cq); + cq_verifier *v_server = cq_verifier_create(f.server_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; + char *details = NULL; + size_t details_capacity = 0; + int was_cancelled = 2; + + c = grpc_channel_create_call(f.client, f.client_cq, "/foo", + "foo.test.google.fr:1234", deadline); + 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); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + op++; + op->op = GRPC_OP_RECV_INITIAL_METADATA; + op->data.recv_initial_metadata = &initial_metadata_recv; + 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++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1))); + + GPR_ASSERT(GRPC_CALL_OK == + grpc_server_request_call(f.server, &s, &call_details, + &request_metadata_recv, f.server_cq, + f.server_cq, tag(101))); + cq_expect_completion(v_server, tag(101), 1); + cq_verify(v_server); + + op = ops; + op->op = GRPC_OP_SEND_INITIAL_METADATA; + op->data.send_initial_metadata.count = 0; + 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++; + op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; + op->data.recv_close_on_server.cancelled = &was_cancelled; + op++; + GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(s, ops, op - ops, tag(102))); + + cq_expect_completion(v_server, tag(102), 1); + cq_verify(v_server); + + cq_expect_completion(v_client, tag(1), 1); + cq_verify(v_client); + + 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(was_cancelled == 0); + + 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(v_client); + cq_verifier_destroy(v_server); +} + +static void test_invoke_simple_request(grpc_end2end_test_config config) { + grpc_end2end_test_fixture f; + + f = begin_test(config, "test_invoke_simple_request", NULL, NULL); + simple_request_body(f); + end_test(&f); + config.tear_down_data(&f); +} + +void grpc_end2end_tests(grpc_end2end_test_config config) { + test_invoke_simple_request(config); +} diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index d8463d4c6c..59cc9b5488 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -185,7 +185,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, static void test_simple_delayed_request_short(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); + gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_short", config.name); f = config.create_fixture(NULL, NULL); simple_delayed_request_body(config, &f, NULL, NULL, 100000); end_test(&f); @@ -195,7 +195,7 @@ static void test_simple_delayed_request_short(grpc_end2end_test_config config) { static void test_simple_delayed_request_long(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - gpr_log(GPR_INFO, "%s/%s", __FUNCTION__, config.name); + gpr_log(GPR_INFO, "%s/%s", "test_simple_delayed_request_long", config.name); f = config.create_fixture(NULL, NULL); /* This timeout should be longer than a single retry */ simple_delayed_request_body(config, &f, NULL, NULL, 1500000); diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index 98e677900e..80c092cd35 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -191,7 +191,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { static void test_invoke_simple_request(grpc_end2end_test_config config) { grpc_end2end_test_fixture f; - f = begin_test(config, __FUNCTION__, NULL, NULL); + f = begin_test(config, "test_invoke_simple_request", NULL, NULL); simple_request_body(f); end_test(&f); config.tear_down_data(&f); @@ -199,7 +199,7 @@ static void test_invoke_simple_request(grpc_end2end_test_config config) { static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { int i; - grpc_end2end_test_fixture f = begin_test(config, __FUNCTION__, NULL, NULL); + grpc_end2end_test_fixture f = begin_test(config, "test_invoke_10_simple_requests", NULL, NULL); for (i = 0; i < 10; i++) { simple_request_body(f); gpr_log(GPR_INFO, "Passed simple request %d", i); diff --git a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c index 3c1a19a5dd..67e0730f5e 100644 --- a/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c +++ b/test/core/end2end/tests/simple_request_with_high_initial_sequence_number.c @@ -201,7 +201,7 @@ static void test_invoke_10_simple_requests(grpc_end2end_test_config config, int client_args.num_args = 1; client_args.args = &client_arg; - f = begin_test(config, __FUNCTION__, &client_args, NULL); + f = begin_test(config, "test_invoke_10_simple_requests", &client_args, NULL); for (i = 0; i < 10; i++) { simple_request_body(f); gpr_log(GPR_INFO, "Passed simple request %d", i); diff --git a/test/core/fling/fling_test.c b/test/core/fling/fling_test.c index 7c1643df6a..6b07f83d5b 100644 --- a/test/core/fling/fling_test.c +++ b/test/core/fling/fling_test.c @@ -60,7 +60,7 @@ int main(int argc, char **argv) { args[1] = "--bind"; gpr_join_host_port(&args[2], "::", port); args[3] = "--no-secure"; - svr = gpr_subprocess_create(4, args); + svr = gpr_subprocess_create(4, (const char**)args); gpr_free(args[0]); gpr_free(args[2]); @@ -71,7 +71,7 @@ int main(int argc, char **argv) { args[3] = "--scenario=ping-pong-request"; args[4] = "--no-secure"; args[5] = 0; - cli = gpr_subprocess_create(6, args); + cli = gpr_subprocess_create(6, (const char**)args); gpr_free(args[0]); gpr_free(args[2]); diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c index 17a2996baa..fb2dbc00ce 100644 --- a/test/core/httpcli/httpcli_test.c +++ b/test/core/httpcli/httpcli_test.c @@ -56,7 +56,7 @@ static void on_finish(void *arg, const grpc_httpcli_response *response) { static void test_get(int use_ssl) { grpc_httpcli_request req; - gpr_log(GPR_INFO, "running %s with use_ssl=%d.", __FUNCTION__, use_ssl); + gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_get", use_ssl); gpr_event_init(&g_done); memset(&req, 0, sizeof(req)); @@ -72,7 +72,7 @@ static void test_get(int use_ssl) { static void test_post(int use_ssl) { grpc_httpcli_request req; - gpr_log(GPR_INFO, "running %s with use_ssl=%d.", __FUNCTION__, (int)use_ssl); + gpr_log(GPR_INFO, "running %s with use_ssl=%d.", "test_post", (int)use_ssl); gpr_event_init(&g_done); memset(&req, 0, sizeof(req)); diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c index e63048e26c..f9c5282f19 100644 --- a/test/core/iomgr/endpoint_tests.c +++ b/test/core/iomgr/endpoint_tests.c @@ -160,7 +160,7 @@ static void read_and_write_test_write_handler(void *data, GPR_ASSERT(error != GRPC_ENDPOINT_CB_ERROR); - gpr_log(GPR_DEBUG, "%s: error=%d", __FUNCTION__, error); + gpr_log(GPR_DEBUG, "%s: error=%d", "read_and_write_test_write_handler", error); if (error == GRPC_ENDPOINT_CB_SHUTDOWN) { gpr_log(GPR_INFO, "Write handler shutdown"); @@ -213,7 +213,7 @@ static void read_and_write_test(grpc_endpoint_test_config config, size_t slice_size, int shutdown) { struct read_and_write_test_state state; gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); - grpc_endpoint_test_fixture f = begin_test(config, __FUNCTION__, slice_size); + grpc_endpoint_test_fixture f = begin_test(config, "read_and_write_test", slice_size); if (shutdown) { gpr_log(GPR_INFO, "Start read and write shutdown test"); @@ -323,7 +323,7 @@ static void shutdown_during_write_test(grpc_endpoint_test_config config, shutdown_during_write_test_state read_st; shutdown_during_write_test_state write_st; gpr_slice *slices; - grpc_endpoint_test_fixture f = begin_test(config, __FUNCTION__, slice_size); + grpc_endpoint_test_fixture f = begin_test(config, "shutdown_during_write_test", slice_size); gpr_log(GPR_INFO, "testing shutdown during a write"); diff --git a/test/core/iomgr/sockaddr_utils_test.c b/test/core/iomgr/sockaddr_utils_test.c index 9212f01c3f..dfab340959 100644 --- a/test/core/iomgr/sockaddr_utils_test.c +++ b/test/core/iomgr/sockaddr_utils_test.c @@ -75,7 +75,7 @@ static void test_sockaddr_is_v4mapped(void) { struct sockaddr_in output4; struct sockaddr_in expect4; - gpr_log(GPR_INFO, "%s", __FUNCTION__); + gpr_log(GPR_INFO, "%s", "test_sockaddr_is_v4mapped"); /* v4mapped input should succeed. */ input6 = make_addr6(kMapped, sizeof(kMapped)); @@ -106,7 +106,7 @@ static void test_sockaddr_to_v4mapped(void) { struct sockaddr_in6 output6; struct sockaddr_in6 expect6; - gpr_log(GPR_INFO, "%s", __FUNCTION__); + gpr_log(GPR_INFO, "%s", "test_sockaddr_to_v4mapped"); /* IPv4 input should succeed. */ input4 = make_addr4(kIPv4, sizeof(kIPv4)); @@ -135,7 +135,7 @@ static void test_sockaddr_is_wildcard(void) { struct sockaddr dummy; int port; - gpr_log(GPR_INFO, "%s", __FUNCTION__); + gpr_log(GPR_INFO, "%s", "test_sockaddr_is_wildcard"); /* Generate wildcards. */ grpc_sockaddr_make_wildcards(555, &wild4, &wild6); @@ -192,7 +192,7 @@ static void test_sockaddr_to_string(void) { struct sockaddr_in6 input6; struct sockaddr dummy; - gpr_log(GPR_INFO, "%s", __FUNCTION__); + gpr_log(GPR_INFO, "%s", "test_sockaddr_to_string"); errno = 0x7EADBEEF; diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index 1c02c4b2f8..328b19f68a 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -43,7 +43,7 @@ #include <string.h> #include <unistd.h> -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", #x) static gpr_mu mu; static gpr_cv cv; @@ -66,7 +66,7 @@ static void test_no_op(void) { static void test_no_op_with_start(void) { grpc_tcp_server *s = grpc_tcp_server_create(); - LOG_TEST(); + LOG_TEST("test_no_op_with_start"); grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); grpc_tcp_server_destroy(s, NULL, NULL); } @@ -74,7 +74,7 @@ static void test_no_op_with_start(void) { static void test_no_op_with_port(void) { struct sockaddr_in addr; grpc_tcp_server *s = grpc_tcp_server_create(); - LOG_TEST(); + LOG_TEST("test_no_op_with_port"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -87,7 +87,7 @@ static void test_no_op_with_port(void) { static void test_no_op_with_port_and_start(void) { struct sockaddr_in addr; grpc_tcp_server *s = grpc_tcp_server_create(); - LOG_TEST(); + LOG_TEST("test_no_op_with_port_and_start"); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; @@ -107,7 +107,7 @@ static void test_connect(int n) { int nconnects_before; gpr_timespec deadline; int i; - LOG_TEST(); + LOG_TEST("test_connect"); gpr_log(GPR_INFO, "clients=%d", n); gpr_mu_lock(&mu); diff --git a/test/core/security/auth_context_test.c b/test/core/security/auth_context_test.c new file mode 100644 index 0000000000..2fb0c01f6f --- /dev/null +++ b/test/core/security/auth_context_test.c @@ -0,0 +1,143 @@ +/* + * + * 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<string.h> + +#include "src/core/security/security_context.h" +#include "src/core/support/string.h" +#include "test/core/util/test_config.h" + +#include <grpc/support/log.h> + +static void test_empty_context(void) { + grpc_auth_context *ctx = grpc_auth_context_create(NULL, 0); + grpc_auth_property_iterator it; + + gpr_log(GPR_INFO, "test_empty_context"); + GPR_ASSERT(ctx != NULL); + GPR_ASSERT(grpc_auth_context_peer_identity_property_name(ctx) == NULL); + it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + it = grpc_auth_context_property_iterator(ctx); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + grpc_auth_context_unref(ctx); +} + +static void test_simple_context(void) { + grpc_auth_context *ctx = grpc_auth_context_create(NULL, 3); + grpc_auth_property_iterator it; + size_t i; + + gpr_log(GPR_INFO, "test_simple_context"); + GPR_ASSERT(ctx != NULL); + GPR_ASSERT(ctx->property_count == 3); + ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi"); + ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo"); + ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar"); + ctx->peer_identity_property_name = ctx->properties[0].name; + + GPR_ASSERT( + strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); + it = grpc_auth_context_property_iterator(ctx); + for (i = 0; i < ctx->property_count; i++) { + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); + GPR_ASSERT(p == &ctx->properties[i]); + } + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + grpc_auth_context_unref(ctx); +} + +static void test_chained_context(void) { + grpc_auth_context *chained = grpc_auth_context_create(NULL, 2); + grpc_auth_context *ctx = grpc_auth_context_create(chained, 3); + grpc_auth_property_iterator it; + size_t i; + + gpr_log(GPR_INFO, "test_chained_context"); + grpc_auth_context_unref(chained); + chained->properties[0] = + grpc_auth_property_init_from_cstring("name", "padapo"); + chained->properties[1] = grpc_auth_property_init_from_cstring("foo", "baz"); + ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi"); + ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo"); + ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar"); + ctx->peer_identity_property_name = ctx->properties[0].name; + + GPR_ASSERT( + strcmp(grpc_auth_context_peer_identity_property_name(ctx), "name") == 0); + it = grpc_auth_context_property_iterator(ctx); + for (i = 0; i < ctx->property_count; i++) { + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); + GPR_ASSERT(p == &ctx->properties[i]); + } + for (i = 0; i < chained->property_count; i++) { + const grpc_auth_property *p = grpc_auth_property_iterator_next(&it); + GPR_ASSERT(p == &chained->properties[i]); + } + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + it = grpc_auth_context_find_properties_by_name(ctx, "foo"); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[2]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[1]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + it = grpc_auth_context_peer_identity(ctx); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[0]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &ctx->properties[1]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == &chained->properties[0]); + GPR_ASSERT(grpc_auth_property_iterator_next(&it) == NULL); + + grpc_auth_context_unref(ctx); +} + + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_empty_context(); + test_simple_context(); + test_chained_context(); + return 0; +} + diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 1b657e3d89..9a77f88e73 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -135,51 +135,113 @@ static grpc_httpcli_response http_response(int status, const char *body) { return response; } +static void test_empty_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); + GPR_ASSERT(store->num_entries == 0); + GPR_ASSERT(store->allocated == 0); + grpc_credentials_md_store_unref(store); +} + +static void test_ref_unref_empty_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); + grpc_credentials_md_store_ref(store); + grpc_credentials_md_store_ref(store); + GPR_ASSERT(store->num_entries == 0); + GPR_ASSERT(store->allocated == 0); + grpc_credentials_md_store_unref(store); + grpc_credentials_md_store_unref(store); + grpc_credentials_md_store_unref(store); +} + +static void test_add_to_empty_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); + const char *key_str = "hello"; + const char *value_str = "there blah blah blah blah blah blah blah"; + gpr_slice key = gpr_slice_from_copied_string(key_str); + gpr_slice value = gpr_slice_from_copied_string(value_str); + grpc_credentials_md_store_add(store, key, value); + GPR_ASSERT(store->num_entries == 1); + GPR_ASSERT(gpr_slice_cmp(key, store->entries[0].key) == 0); + GPR_ASSERT(gpr_slice_cmp(value, store->entries[0].value) == 0); + gpr_slice_unref(key); + gpr_slice_unref(value); + grpc_credentials_md_store_unref(store); +} + +static void test_add_cstrings_to_empty_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(0); + const char *key_str = "hello"; + const char *value_str = "there blah blah blah blah blah blah blah"; + grpc_credentials_md_store_add_cstrings(store, key_str, value_str); + GPR_ASSERT(store->num_entries == 1); + GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].key, key_str) == 0); + GPR_ASSERT(gpr_slice_str_cmp(store->entries[0].value, value_str) == 0); + grpc_credentials_md_store_unref(store); +} + +static void test_empty_preallocated_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(4); + GPR_ASSERT(store->num_entries == 0); + GPR_ASSERT(store->allocated == 4); + GPR_ASSERT(store->entries != NULL); + grpc_credentials_md_store_unref(store); +} + +static void test_add_abunch_to_md_store(void) { + grpc_credentials_md_store *store = grpc_credentials_md_store_create(4); + size_t num_entries = 1000; + const char *key_str = "hello"; + const char *value_str = "there blah blah blah blah blah blah blah"; + size_t i; + for (i = 0; i < num_entries; i++) { + grpc_credentials_md_store_add_cstrings(store, key_str, value_str); + } + for (i = 0; i < num_entries; i++) { + GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].key, key_str) == 0); + GPR_ASSERT(gpr_slice_str_cmp(store->entries[i].value, value_str) == 0); + } + grpc_credentials_md_store_unref(store); +} + static void test_oauth2_token_fetcher_creds_parsing_ok(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, valid_oauth2_json_response); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_OK); GPR_ASSERT(token_lifetime.tv_sec == 3599); GPR_ASSERT(token_lifetime.tv_nsec == 0); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->key), - "Authorization") == 0); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(token_elem->value), - "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0); - grpc_mdelem_unref(token_elem); - grpc_mdctx_unref(ctx); + GPR_ASSERT(token_md->num_entries == 1); + GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].key, "Authorization") == 0); + GPR_ASSERT(gpr_slice_str_cmp(token_md->entries[0].value, + "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == + 0); + grpc_credentials_md_store_unref(token_md); } static void test_oauth2_token_fetcher_creds_parsing_bad_http_status(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(401, valid_oauth2_json_response); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } static void test_oauth2_token_fetcher_creds_parsing_empty_http_body(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, ""); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, @@ -187,28 +249,24 @@ static void test_oauth2_token_fetcher_creds_parsing_invalid_json(void) { " \"expires_in\":3599, " " \"token_type\":\"Bearer\""); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } static void test_oauth2_token_fetcher_creds_parsing_missing_token(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, "{" " \"expires_in\":3599, " " \"token_type\":\"Bearer\"}"); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, @@ -216,35 +274,32 @@ static void test_oauth2_token_fetcher_creds_parsing_missing_token_type(void) { " \"expires_in\":3599, " "}"); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } static void test_oauth2_token_fetcher_creds_parsing_missing_token_lifetime( void) { - grpc_mdctx *ctx = grpc_mdctx_create(); - grpc_mdelem *token_elem = NULL; + grpc_credentials_md_store *token_md = NULL; gpr_timespec token_lifetime; grpc_httpcli_response response = http_response(200, "{\"access_token\":\"ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_\"," " \"token_type\":\"Bearer\"}"); GPR_ASSERT(grpc_oauth2_token_fetcher_credentials_parse_server_response( - &response, ctx, &token_elem, &token_lifetime) == + &response, &token_md, &token_lifetime) == GRPC_CREDENTIALS_ERROR); - grpc_mdctx_unref(ctx); } -static void check_metadata(expected_md *expected, grpc_mdelem **md_elems, +static void check_metadata(expected_md *expected, grpc_credentials_md *md_elems, size_t num_md) { size_t i; for (i = 0; i < num_md; i++) { size_t j; for (j = 0; j < num_md; j++) { - if (0 == gpr_slice_str_cmp(md_elems[j]->key->slice, expected[i].key)) { - GPR_ASSERT(0 == gpr_slice_str_cmp(md_elems[j]->value->slice, - expected[i].value)); + if (0 == gpr_slice_str_cmp(md_elems[j].key, expected[i].key)) { + GPR_ASSERT(gpr_slice_str_cmp(md_elems[j].value, expected[i].value) == + 0); break; } } @@ -255,7 +310,7 @@ static void check_metadata(expected_md *expected, grpc_mdelem **md_elems, } } -static void check_iam_metadata(void *user_data, grpc_mdelem **md_elems, +static void check_iam_metadata(void *user_data, grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { grpc_credentials *c = (grpc_credentials *)user_data; expected_md emd[] = { @@ -277,7 +332,7 @@ static void test_iam_creds(void) { } static void check_ssl_oauth2_composite_metadata( - void *user_data, grpc_mdelem **md_elems, size_t num_md, + void *user_data, grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { grpc_credentials *c = (grpc_credentials *)user_data; expected_md emd[] = { @@ -327,7 +382,7 @@ void test_ssl_fake_transport_security_composite_creds_failure(void) { } static void check_ssl_oauth2_iam_composite_metadata( - void *user_data, grpc_mdelem **md_elems, size_t num_md, + void *user_data, grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { grpc_credentials *c = (grpc_credentials *)user_data; expected_md emd[] = { @@ -374,20 +429,20 @@ static void test_ssl_oauth2_iam_composite_creds(void) { } static void on_oauth2_creds_get_metadata_success( - void *user_data, grpc_mdelem **md_elems, size_t num_md, + void *user_data, grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { GPR_ASSERT(status == GRPC_CREDENTIALS_OK); GPR_ASSERT(num_md == 1); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), - "Authorization") == 0); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), - "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == 0); + GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0); + GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value, + "Bearer ya29.AHES6ZRN3-HlhAPya30GnW_bHSb_") == + 0); GPR_ASSERT(user_data != NULL); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0); } static void on_oauth2_creds_get_metadata_failure( - void *user_data, grpc_mdelem **md_elems, size_t num_md, + void *user_data, grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR); GPR_ASSERT(num_md == 0); @@ -719,24 +774,22 @@ static void test_service_account_creds_signing_failure(void) { } static void on_jwt_creds_get_metadata_success(void *user_data, - grpc_mdelem **md_elems, + grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { char *expected_md_value; gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt); GPR_ASSERT(status == GRPC_CREDENTIALS_OK); GPR_ASSERT(num_md == 1); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->key), - "Authorization") == 0); - GPR_ASSERT(strcmp(grpc_mdstr_as_c_string(md_elems[0]->value), - expected_md_value) == 0); + GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].key, "Authorization") == 0); + GPR_ASSERT(gpr_slice_str_cmp(md_elems[0].value, expected_md_value) == 0); GPR_ASSERT(user_data != NULL); GPR_ASSERT(strcmp((const char *)user_data, test_user_data) == 0); gpr_free(expected_md_value); } static void on_jwt_creds_get_metadata_failure(void *user_data, - grpc_mdelem **md_elems, + grpc_credentials_md *md_elems, size_t num_md, grpc_credentials_status status) { GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR); @@ -796,6 +849,12 @@ static void test_jwt_creds_signing_failure(void) { int main(int argc, char **argv) { grpc_test_init(argc, argv); + test_empty_md_store(); + test_ref_unref_empty_md_store(); + test_add_to_empty_md_store(); + test_add_cstrings_to_empty_md_store(); + test_empty_preallocated_md_store(); + test_add_abunch_to_md_store(); test_oauth2_token_fetcher_creds_parsing_ok(); test_oauth2_token_fetcher_creds_parsing_bad_http_status(); test_oauth2_token_fetcher_creds_parsing_empty_http_body(); diff --git a/test/core/support/cmdline_test.c b/test/core/support/cmdline_test.c index 52c311f75c..26153b192c 100644 --- a/test/core/support/cmdline_test.c +++ b/test/core/support/cmdline_test.c @@ -35,16 +35,17 @@ #include <string.h> +#include <grpc/support/alloc.h> #include <grpc/support/log.h> #include <grpc/support/useful.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FILE__) static void test_simple_int(void) { int x = 1; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "-foo", "3"}; + char *args[] = {(char *)__FILE__, "-foo", "3"}; LOG_TEST(); @@ -59,7 +60,7 @@ static void test_simple_int(void) { static void test_eq_int(void) { int x = 1; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "-foo=3"}; + char *args[] = {(char *)__FILE__, "-foo=3"}; LOG_TEST(); @@ -74,7 +75,7 @@ static void test_eq_int(void) { static void test_2dash_int(void) { int x = 1; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo", "3"}; + char *args[] = {(char *)__FILE__, "--foo", "3"}; LOG_TEST(); @@ -89,7 +90,7 @@ static void test_2dash_int(void) { static void test_2dash_eq_int(void) { int x = 1; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=3"}; + char *args[] = {(char *)__FILE__, "--foo=3"}; LOG_TEST(); @@ -104,7 +105,7 @@ static void test_2dash_eq_int(void) { static void test_simple_string(void) { char *x = NULL; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "-foo", "3"}; + char *args[] = {(char *)__FILE__, "-foo", "3"}; LOG_TEST(); @@ -119,7 +120,7 @@ static void test_simple_string(void) { static void test_eq_string(void) { char *x = NULL; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "-foo=3"}; + char *args[] = {(char *)__FILE__, "-foo=3"}; LOG_TEST(); @@ -134,7 +135,7 @@ static void test_eq_string(void) { static void test_2dash_string(void) { char *x = NULL; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo", "3"}; + char *args[] = {(char *)__FILE__, "--foo", "3"}; LOG_TEST(); @@ -149,7 +150,7 @@ static void test_2dash_string(void) { static void test_2dash_eq_string(void) { char *x = NULL; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=3"}; + char *args[] = {(char *)__FILE__, "--foo=3"}; LOG_TEST(); @@ -164,7 +165,7 @@ static void test_2dash_eq_string(void) { static void test_flag_on(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo"}; + char *args[] = {(char *)__FILE__, "--foo"}; LOG_TEST(); @@ -179,7 +180,7 @@ static void test_flag_on(void) { static void test_flag_no(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--no-foo"}; + char *args[] = {(char *)__FILE__, "--no-foo"}; LOG_TEST(); @@ -194,7 +195,7 @@ static void test_flag_no(void) { static void test_flag_val_1(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=1"}; + char *args[] = {(char *)__FILE__, "--foo=1"}; LOG_TEST(); @@ -209,7 +210,7 @@ static void test_flag_val_1(void) { static void test_flag_val_0(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=0"}; + char *args[] = {(char *)__FILE__, "--foo=0"}; LOG_TEST(); @@ -224,7 +225,7 @@ static void test_flag_val_0(void) { static void test_flag_val_true(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=true"}; + char *args[] = {(char *)__FILE__, "--foo=true"}; LOG_TEST(); @@ -239,7 +240,7 @@ static void test_flag_val_true(void) { static void test_flag_val_false(void) { int x = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--foo=false"}; + char *args[] = {(char *)__FILE__, "--foo=false"}; LOG_TEST(); @@ -257,7 +258,7 @@ static void test_many(void) { int flag = 2; gpr_cmdline *cl; - char *args[] = {(char *)__FUNCTION__, "--str", "hello", "-x=4", "-no-flag"}; + char *args[] = {(char *)__FILE__, "--str", "hello", "-x=4", "-no-flag"}; LOG_TEST(); @@ -272,6 +273,27 @@ static void test_many(void) { gpr_cmdline_destroy(cl); } +static void test_usage(void) { + gpr_cmdline *cl; + char *usage; + + char *str = NULL; + int x = 0; + int flag = 2; + + cl = gpr_cmdline_create(NULL); + gpr_cmdline_add_string(cl, "str", NULL, &str); + gpr_cmdline_add_int(cl, "x", NULL, &x); + gpr_cmdline_add_flag(cl, "flag", NULL, &flag); + + usage = gpr_cmdline_usage_string(cl, "test"); + GPR_ASSERT(0 == strcmp(usage, + "Usage: test [--str=string] [--x=int] [--flag|--no-flag]\n")); + gpr_free(usage); + + gpr_cmdline_destroy(cl); +} + int main(int argc, char **argv) { grpc_test_init(argc, argv); test_simple_int(); @@ -289,5 +311,6 @@ int main(int argc, char **argv) { test_flag_val_true(); test_flag_val_false(); test_many(); + test_usage(); return 0; } diff --git a/test/core/support/env_test.c b/test/core/support/env_test.c index aedf9313f3..69aebcc918 100644 --- a/test/core/support/env_test.c +++ b/test/core/support/env_test.c @@ -41,14 +41,14 @@ #include "src/core/support/string.h" #include "test/core/util/test_config.h" -#define LOG_TEST_NAME() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) static void test_setenv_getenv(void) { const char *name = "FOO"; const char *value = "BAR"; char *retrieved_value; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_setenv_getenv"); gpr_setenv(name, value); retrieved_value = gpr_getenv(name); diff --git a/test/core/support/file_test.c b/test/core/support/file_test.c index 56e7a4948e..330b2173ef 100644 --- a/test/core/support/file_test.c +++ b/test/core/support/file_test.c @@ -42,7 +42,7 @@ #include "src/core/support/string.h" #include "test/core/util/test_config.h" -#define LOG_TEST_NAME() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) static const char prefix[] = "file_test"; @@ -53,7 +53,7 @@ static void test_load_empty_file(void) { int success; char *tmp_name; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_load_empty_file"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); @@ -81,7 +81,7 @@ static void test_load_failure(void) { int success; char *tmp_name; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_load_failure"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); @@ -104,7 +104,7 @@ static void test_load_small_file(void) { char *tmp_name; const char *blah = "blah"; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_load_small_file"); tmp = gpr_tmpfile(prefix, &tmp_name); GPR_ASSERT(tmp_name != NULL); @@ -138,7 +138,7 @@ static void test_load_big_file(void) { unsigned char *current; size_t i; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_load_big_file"); for (i = 0; i < sizeof(buffer); i++) { buffer[i] = 42; diff --git a/test/core/support/histogram_test.c b/test/core/support/histogram_test.c index 3994430874..be935ede09 100644 --- a/test/core/support/histogram_test.c +++ b/test/core/support/histogram_test.c @@ -34,7 +34,7 @@ #include <grpc/support/histogram.h> #include <grpc/support/log.h> -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__); +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x); static void test_no_op(void) { gpr_histogram_destroy(gpr_histogram_create(0.01, 60e9)); @@ -52,7 +52,7 @@ static void expect_percentile(gpr_histogram *h, double percentile, static void test_simple(void) { gpr_histogram *h; - LOG_TEST(); + LOG_TEST("test_simple"); h = gpr_histogram_create(0.01, 60e9); gpr_histogram_add(h, 10000); @@ -72,7 +72,7 @@ static void test_percentile(void) { double i; double cur; - LOG_TEST(); + LOG_TEST("test_percentile"); h = gpr_histogram_create(0.05, 1e9); gpr_histogram_add(h, 2.5); @@ -117,7 +117,7 @@ static void test_merge(void) { double i; double cur; - LOG_TEST(); + LOG_TEST("test_merge"); h1 = gpr_histogram_create(0.05, 1e9); gpr_histogram_add(h1, 2.5); diff --git a/test/core/support/slice_test.c b/test/core/support/slice_test.c index 4ab3d6f45b..63dedea50f 100644 --- a/test/core/support/slice_test.c +++ b/test/core/support/slice_test.c @@ -38,7 +38,7 @@ #include <grpc/support/log.h> #include "test/core/util/test_config.h" -#define LOG_TEST_NAME() gpr_log(GPR_INFO, "%s", __FUNCTION__); +#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x); static void test_slice_malloc_returns_something_sensible(void) { /* Calls gpr_slice_create for various lengths and verifies the internals for @@ -47,7 +47,7 @@ static void test_slice_malloc_returns_something_sensible(void) { size_t i; gpr_slice slice; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_slice_malloc_returns_something_sensible"); for (length = 0; length <= 1024; length++) { slice = gpr_slice_malloc(length); @@ -108,7 +108,7 @@ static void test_slice_sub_works(unsigned length) { gpr_slice sub; unsigned i, j, k; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_slice_sub_works"); gpr_log(GPR_INFO, "length=%d", length); /* Create a slice in which each byte is equal to the distance from it to the @@ -147,7 +147,7 @@ static void test_slice_split_head_works(int length) { gpr_slice head, tail; int i; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_slice_split_head_works"); gpr_log(GPR_INFO, "length=%d", length); /* Create a slice in which each byte is equal to the distance from it to the @@ -175,7 +175,7 @@ static void test_slice_split_tail_works(int length) { gpr_slice head, tail; int i; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_slice_split_tail_works"); gpr_log(GPR_INFO, "length=%d", length); /* Create a slice in which each byte is equal to the distance from it to the @@ -202,7 +202,7 @@ static void test_slice_from_copied_string_works(void) { static const char *text = "HELLO WORLD!"; gpr_slice slice; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_slice_from_copied_string_works"); slice = gpr_slice_from_copied_string(text); GPR_ASSERT(strlen(text) == GPR_SLICE_LENGTH(slice)); diff --git a/test/core/support/string_test.c b/test/core/support/string_test.c index a78e4782a2..a1692ab39f 100644 --- a/test/core/support/string_test.c +++ b/test/core/support/string_test.c @@ -42,13 +42,13 @@ #include <grpc/support/useful.h> #include "test/core/util/test_config.h" -#define LOG_TEST_NAME() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST_NAME(x) gpr_log(GPR_INFO, "%s", x) static void test_strdup(void) { static const char *src1 = "hello world"; char *dst1; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_strdup"); dst1 = gpr_strdup(src1); GPR_ASSERT(0 == strcmp(src1, dst1)); @@ -65,7 +65,7 @@ static void expect_hexdump(const char *buf, size_t len, gpr_uint32 flags, } static void test_hexdump(void) { - LOG_TEST_NAME(); + LOG_TEST_NAME("test_hexdump"); expect_hexdump("\x01", 1, 0, "01"); expect_hexdump("\x01", 1, GPR_HEXDUMP_PLAINTEXT, "01 '.'"); expect_hexdump("\x01\x02", 2, 0, "01 02"); @@ -86,7 +86,7 @@ static void test_pu32_succeed(const char *s, gpr_uint32 want) { } static void test_parse_uint32(void) { - LOG_TEST_NAME(); + LOG_TEST_NAME("test_parse_uint32"); test_pu32_fail("-1"); test_pu32_fail("a"); @@ -123,7 +123,7 @@ static void test_asprintf(void) { char *buf; int i, j; - LOG_TEST_NAME(); + LOG_TEST_NAME("test_asprintf"); /* Print an empty string. */ GPR_ASSERT(gpr_asprintf(&buf, "") == 0); diff --git a/test/core/surface/byte_buffer_reader_test.c b/test/core/surface/byte_buffer_reader_test.c index b121abf757..9265ef16b0 100644 --- a/test/core/surface/byte_buffer_reader_test.c +++ b/test/core/surface/byte_buffer_reader_test.c @@ -44,13 +44,13 @@ #include <string.h> -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void test_create(void) { grpc_byte_buffer *buffer; grpc_byte_buffer_reader *reader; gpr_slice empty = gpr_empty_slice(); - LOG_TEST(); + LOG_TEST("test_create"); buffer = grpc_byte_buffer_create(&empty, 1); reader = grpc_byte_buffer_reader_create(buffer); grpc_byte_buffer_reader_destroy(reader); @@ -64,7 +64,7 @@ static void test_read_one_slice(void) { gpr_slice first_slice, second_slice; int first_code, second_code; - LOG_TEST(); + LOG_TEST("test_read_one_slice"); slice = gpr_slice_from_copied_string("test"); buffer = grpc_byte_buffer_create(&slice, 1); gpr_slice_unref(slice); @@ -86,7 +86,7 @@ static void test_read_one_slice_malloc(void) { gpr_slice first_slice, second_slice; int first_code, second_code; - LOG_TEST(); + LOG_TEST("test_read_one_slice_malloc"); slice = gpr_slice_malloc(4); memcpy(GPR_SLICE_START_PTR(slice), "test", 4); buffer = grpc_byte_buffer_create(&slice, 1); diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c index 3e84eaf54c..e26f379bfc 100644 --- a/test/core/surface/completion_queue_test.c +++ b/test/core/surface/completion_queue_test.c @@ -41,7 +41,7 @@ #include <grpc/support/useful.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void *create_test_tag(void) { static gpr_intptr i = 0; @@ -59,14 +59,14 @@ static void shutdown_and_destroy(grpc_completion_queue *cc) { /* ensure we can create and destroy a completion channel */ static void test_no_op(void) { - LOG_TEST(); + LOG_TEST("test_no_op"); shutdown_and_destroy(grpc_completion_queue_create()); } static void test_wait_empty(void) { grpc_completion_queue *cc; - LOG_TEST(); + LOG_TEST("test_wait_empty"); cc = grpc_completion_queue_create(); GPR_ASSERT(grpc_completion_queue_next(cc, gpr_now()).type == @@ -79,7 +79,7 @@ static void test_cq_end_op(void) { grpc_completion_queue *cc; void *tag = create_test_tag(); - LOG_TEST(); + LOG_TEST("test_cq_end_op"); cc = grpc_completion_queue_create(); @@ -100,7 +100,7 @@ static void test_pluck(void) { void *tags[128]; unsigned i, j; - LOG_TEST(); + LOG_TEST("test_pluck"); for (i = 0; i < GPR_ARRAY_SIZE(tags); i++) { tags[i] = create_test_tag(); @@ -222,7 +222,7 @@ static void test_threading(int producers, int consumers) { int total_consumed = 0; static int optid = 101; - gpr_log(GPR_INFO, "%s: %d producers, %d consumers", __FUNCTION__, producers, + gpr_log(GPR_INFO, "%s: %d producers, %d consumers", "test_threading", producers, consumers); grpc_completion_queue_dont_poll_test_only(cc); diff --git a/test/core/transport/chttp2/hpack_table_test.c b/test/core/transport/chttp2/hpack_table_test.c index d1e5f0829a..6bc697878a 100644 --- a/test/core/transport/chttp2/hpack_table_test.c +++ b/test/core/transport/chttp2/hpack_table_test.c @@ -41,7 +41,7 @@ #include <grpc/support/log.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void assert_str(const grpc_chttp2_hptbl *tbl, grpc_mdstr *mdstr, const char *str) { @@ -62,7 +62,7 @@ static void test_static_lookup(void) { mdctx = grpc_mdctx_create(); grpc_chttp2_hptbl_init(&tbl, mdctx); - LOG_TEST(); + LOG_TEST("test_static_lookup"); assert_index(&tbl, 1, ":authority", ""); assert_index(&tbl, 2, ":method", "GET"); assert_index(&tbl, 3, ":method", "POST"); @@ -136,7 +136,7 @@ static void test_many_additions(void) { char *value; grpc_mdctx *mdctx; - LOG_TEST(); + LOG_TEST("test_many_additions"); mdctx = grpc_mdctx_create(); grpc_chttp2_hptbl_init(&tbl, mdctx); @@ -177,7 +177,7 @@ static void test_find(void) { grpc_mdctx *mdctx; grpc_chttp2_hptbl_find_result r; - LOG_TEST(); + LOG_TEST("test_find"); mdctx = grpc_mdctx_create(); grpc_chttp2_hptbl_init(&tbl, mdctx); diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c index d678e0af73..3c6976ee9d 100644 --- a/test/core/transport/chttp2/stream_map_test.c +++ b/test/core/transport/chttp2/stream_map_test.c @@ -35,13 +35,13 @@ #include <grpc/support/log.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) /* test creation & destruction */ static void test_no_op(void) { grpc_chttp2_stream_map map; - LOG_TEST(); + LOG_TEST("test_no_op"); grpc_chttp2_stream_map_init(&map, 8); grpc_chttp2_stream_map_destroy(&map); @@ -51,7 +51,7 @@ static void test_no_op(void) { static void test_empty_find(void) { grpc_chttp2_stream_map map; - LOG_TEST(); + LOG_TEST("test_empty_find"); grpc_chttp2_stream_map_init(&map, 8); GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 39128)); @@ -62,7 +62,7 @@ static void test_empty_find(void) { static void test_double_deletion(void) { grpc_chttp2_stream_map map; - LOG_TEST(); + LOG_TEST("test_double_deletion"); grpc_chttp2_stream_map_init(&map, 8); GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map)); @@ -87,7 +87,7 @@ static void test_basic_add_find(size_t n) { size_t i; size_t got; - LOG_TEST(); + LOG_TEST("test_basic_add_find"); gpr_log(GPR_INFO, "n = %d", n); grpc_chttp2_stream_map_init(&map, 8); @@ -143,7 +143,7 @@ static void test_delete_evens_sweep(size_t n) { grpc_chttp2_stream_map map; size_t i; - LOG_TEST(); + LOG_TEST("test_delete_evens_sweep"); gpr_log(GPR_INFO, "n = %d", n); grpc_chttp2_stream_map_init(&map, 8); @@ -165,7 +165,7 @@ static void test_delete_evens_incremental(size_t n) { grpc_chttp2_stream_map map; size_t i; - LOG_TEST(); + LOG_TEST("test_delete_evens_incremental"); gpr_log(GPR_INFO, "n = %d", n); grpc_chttp2_stream_map_init(&map, 8); @@ -186,7 +186,7 @@ static void test_periodic_compaction(size_t n) { size_t i; size_t del; - LOG_TEST(); + LOG_TEST("test_periodic_compaction"); gpr_log(GPR_INFO, "n = %d", n); grpc_chttp2_stream_map_init(&map, 16); diff --git a/test/core/transport/chttp2/timeout_encoding_test.c b/test/core/transport/chttp2/timeout_encoding_test.c index fdb27a22ce..daaae1d39d 100644 --- a/test/core/transport/chttp2/timeout_encoding_test.c +++ b/test/core/transport/chttp2/timeout_encoding_test.c @@ -42,7 +42,7 @@ #include <grpc/support/useful.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) static void assert_encodes_as(gpr_timespec ts, const char *s) { char buffer[GRPC_CHTTP2_TIMEOUT_ENCODE_MIN_BUFSIZE]; @@ -52,7 +52,7 @@ static void assert_encodes_as(gpr_timespec ts, const char *s) { } void test_encoding(void) { - LOG_TEST(); + LOG_TEST("test_encoding"); assert_encodes_as(gpr_time_from_micros(-1), "1n"); assert_encodes_as(gpr_time_from_seconds(-10), "1n"); assert_encodes_as(gpr_time_from_nanos(10), "10n"); @@ -116,7 +116,7 @@ void decode_suite(char ext, gpr_timespec (*answer)(long x)) { } void test_decoding(void) { - LOG_TEST(); + LOG_TEST("test_decoding"); decode_suite('n', gpr_time_from_nanos); decode_suite('u', gpr_time_from_micros); decode_suite('m', gpr_time_from_millis); @@ -128,7 +128,7 @@ void test_decoding(void) { void test_decoding_fails(void) { gpr_timespec x; - LOG_TEST(); + LOG_TEST("test_decoding_fails"); GPR_ASSERT(0 == grpc_chttp2_decode_timeout("", &x)); GPR_ASSERT(0 == grpc_chttp2_decode_timeout(" ", &x)); GPR_ASSERT(0 == grpc_chttp2_decode_timeout("x", &x)); diff --git a/test/core/transport/metadata_test.c b/test/core/transport/metadata_test.c index 66b5407d3c..9b242c5493 100644 --- a/test/core/transport/metadata_test.c +++ b/test/core/transport/metadata_test.c @@ -41,7 +41,7 @@ #include <grpc/support/log.h> #include "test/core/util/test_config.h" -#define LOG_TEST() gpr_log(GPR_INFO, "%s", __FUNCTION__) +#define LOG_TEST(x) gpr_log(GPR_INFO, "%s", x) /* a large number */ #define MANY 10000 @@ -49,7 +49,7 @@ static void test_no_op(void) { grpc_mdctx *ctx; - LOG_TEST(); + LOG_TEST("test_no_op"); ctx = grpc_mdctx_create(); grpc_mdctx_unref(ctx); @@ -59,7 +59,7 @@ static void test_create_string(void) { grpc_mdctx *ctx; grpc_mdstr *s1, *s2, *s3; - LOG_TEST(); + LOG_TEST("test_create_string"); ctx = grpc_mdctx_create(); s1 = grpc_mdstr_from_string(ctx, "hello"); @@ -79,7 +79,7 @@ static void test_create_metadata(void) { grpc_mdctx *ctx; grpc_mdelem *m1, *m2, *m3; - LOG_TEST(); + LOG_TEST("test_create_metadata"); ctx = grpc_mdctx_create(); m1 = grpc_mdelem_from_strings(ctx, "a", "b"); @@ -104,7 +104,7 @@ static void test_create_many_ephemeral_metadata(void) { long i; size_t mdtab_capacity_before; - LOG_TEST(); + LOG_TEST("test_create_many_ephemeral_metadata"); ctx = grpc_mdctx_create(); mdtab_capacity_before = grpc_mdctx_get_mdtab_capacity_test_only(ctx); @@ -126,7 +126,7 @@ static void test_create_many_persistant_metadata(void) { grpc_mdelem **created = gpr_malloc(sizeof(grpc_mdelem *) * MANY); grpc_mdelem *md; - LOG_TEST(); + LOG_TEST("test_create_many_persistant_metadata"); ctx = grpc_mdctx_create(); /* add phase */ @@ -153,7 +153,7 @@ static void test_create_many_persistant_metadata(void) { static void test_spin_creating_the_same_thing(void) { grpc_mdctx *ctx; - LOG_TEST(); + LOG_TEST("test_spin_creating_the_same_thing"); ctx = grpc_mdctx_create(); GPR_ASSERT(grpc_mdctx_get_mdtab_count_test_only(ctx) == 0); @@ -183,7 +183,7 @@ static void test_things_stick_around(void) { int *shuf = gpr_malloc(sizeof(int) * nstrs); grpc_mdstr *test; - LOG_TEST(); + LOG_TEST("test_things_stick_around"); ctx = grpc_mdctx_create(); @@ -229,7 +229,7 @@ static void test_slices_work(void) { grpc_mdstr *str; gpr_slice slice; - LOG_TEST(); + LOG_TEST("test_slices_work"); ctx = grpc_mdctx_create(); @@ -254,7 +254,7 @@ static void test_base64_and_huffman_works(void) { gpr_slice slice1; gpr_slice slice2; - LOG_TEST(); + LOG_TEST("test_base64_and_huffman_works"); ctx = grpc_mdctx_create(); str = grpc_mdstr_from_string(ctx, "abcdefg"); diff --git a/test/cpp/end2end/client_crash_test.cc b/test/cpp/end2end/client_crash_test.cc new file mode 100644 index 0000000000..e86681f75a --- /dev/null +++ b/test/cpp/end2end/client_crash_test.cc @@ -0,0 +1,165 @@ +/* + * + * 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 <thread> + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" +#include "src/cpp/server/thread_pool.h" +#include <grpc++/channel_arguments.h> +#include <grpc++/channel_interface.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/credentials.h> +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc++/server_credentials.h> +#include <grpc++/status.h> +#include <grpc++/stream.h> +#include <grpc++/time.h> +#include <gtest/gtest.h> + +#include <grpc/grpc.h> +#include <grpc/support/thd.h> +#include <grpc/support/time.h> + +#include "test/cpp/util/subprocess.h" + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; +using std::chrono::system_clock; + +static std::string g_root; + +namespace grpc { +namespace testing { + +namespace { + +class CrashTest : public ::testing::Test { + protected: + CrashTest() {} + + std::unique_ptr<grpc::cpp::test::util::TestService::Stub> + CreateServerAndStub() { + auto port = grpc_pick_unused_port_or_die(); + std::ostringstream addr_stream; + addr_stream << "localhost:" << port; + auto addr = addr_stream.str(); + server_.reset(new SubProcess({ + g_root + "/client_crash_test_server", + "--address=" + addr, + })); + GPR_ASSERT(server_); + return grpc::cpp::test::util::TestService::NewStub( + CreateChannel(addr, InsecureCredentials(), ChannelArguments())); + } + + void KillServer() { + server_.reset(); + // give some time for the TCP connection to drop + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1))); + } + + private: + std::unique_ptr<SubProcess> server_; +}; + +TEST_F(CrashTest, KillAfterWrite) { + auto stub = CreateServerAndStub(); + + EchoRequest request; + EchoResponse response; + ClientContext context; + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + EXPECT_EQ(response.message(), request.message()); + + request.set_message("I'm going to kill you"); + EXPECT_TRUE(stream->Write(request)); + + KillServer(); + + EXPECT_FALSE(stream->Read(&response)); + + EXPECT_FALSE(stream->Finish().IsOk()); +} + +TEST_F(CrashTest, KillBeforeWrite) { + auto stub = CreateServerAndStub(); + + EchoRequest request; + EchoResponse response; + ClientContext context; + + auto stream = stub->BidiStream(&context); + + request.set_message("Hello"); + EXPECT_TRUE(stream->Write(request)); + EXPECT_TRUE(stream->Read(&response)); + EXPECT_EQ(response.message(), request.message()); + + KillServer(); + + request.set_message("You should be dead"); + EXPECT_FALSE(stream->Write(request)); + EXPECT_FALSE(stream->Read(&response)); + + EXPECT_FALSE(stream->Finish().IsOk()); +} + +} // namespace + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + std::string me = argv[0]; + auto lslash = me.rfind('/'); + if (lslash != std::string::npos) { + g_root = me.substr(0, lslash); + } else { + g_root = "."; + } + + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/client_crash_test_server.cc b/test/cpp/end2end/client_crash_test_server.cc new file mode 100644 index 0000000000..20808a0240 --- /dev/null +++ b/test/cpp/end2end/client_crash_test_server.cc @@ -0,0 +1,94 @@ +/* + * + * 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 <iostream> +#include <memory> +#include <string> +#include <gflags/gflags.h> + +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc++/server_credentials.h> +#include <grpc++/status.h> +#include "test/cpp/util/echo.grpc.pb.h" + +DEFINE_string(address, "", "Address to bind to"); + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + +namespace grpc { +namespace testing { + +class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Service { + Status BidiStream(ServerContext* context, + ServerReaderWriter<EchoResponse, EchoRequest>* stream) + GRPC_OVERRIDE { + EchoRequest request; + EchoResponse response; + while (stream->Read(&request)) { + gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); + response.set_message(request.message()); + stream->Write(response); + } + return Status::OK; + } +}; + +void RunServer() { + ServiceImpl service; + + ServerBuilder builder; + builder.AddListeningPort(FLAGS_address, grpc::InsecureServerCredentials()); + builder.RegisterService(&service); + std::unique_ptr<Server> server(builder.BuildAndStart()); + std::cout << "Server listening on " << FLAGS_address << std::endl; + server->Wait(); +} +} +} + +int main(int argc, char** argv) { + ParseCommandLineFlags(&argc, &argv, true); + grpc::testing::RunServer(); + + return 0; +} diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 76271c3e1d..7a15591b44 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -96,14 +96,16 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { signal_client_ = true; } while (!context->IsCancelled()) { - std::this_thread::sleep_for(std::chrono::microseconds( - request->param().client_cancel_after_us())); + gpr_sleep_until(gpr_time_add( + gpr_now(), + gpr_time_from_micros(request->param().client_cancel_after_us()))); } return Status::Cancelled; } else if (request->has_param() && request->param().server_cancel_after_us()) { - std::this_thread::sleep_for( - std::chrono::microseconds(request->param().server_cancel_after_us())); + gpr_sleep_until(gpr_time_add( + gpr_now(), + gpr_time_from_micros(request->param().server_cancel_after_us()))); return Status::Cancelled; } else { EXPECT_FALSE(context->IsCancelled()); @@ -469,7 +471,7 @@ TEST_F(End2endTest, BadCredentials) { } void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { - std::this_thread::sleep_for(std::chrono::microseconds(delay_us)); + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(delay_us))); while (!service->signal_client()) { } context->TryCancel(); diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc new file mode 100644 index 0000000000..3fdae9bc07 --- /dev/null +++ b/test/cpp/end2end/server_crash_test.cc @@ -0,0 +1,180 @@ +/* + * + * 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 <thread> + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/echo_duplicate.grpc.pb.h" +#include "test/cpp/util/echo.grpc.pb.h" +#include "src/cpp/server/thread_pool.h" +#include <grpc++/channel_arguments.h> +#include <grpc++/channel_interface.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/credentials.h> +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc++/server_credentials.h> +#include <grpc++/status.h> +#include <grpc++/stream.h> +#include <grpc++/time.h> +#include <gtest/gtest.h> + +#include <grpc/grpc.h> +#include <grpc/support/thd.h> +#include <grpc/support/time.h> + +#include "test/cpp/util/subprocess.h" + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; +using std::chrono::system_clock; + +static std::string g_root; + +namespace grpc { +namespace testing { + +namespace { + +class ServiceImpl GRPC_FINAL + : public ::grpc::cpp::test::util::TestService::Service { + public: + ServiceImpl() : bidi_stream_count_(0), response_stream_count_(0) {} + + Status BidiStream(ServerContext* context, + ServerReaderWriter<EchoResponse, EchoRequest>* stream) + GRPC_OVERRIDE { + bidi_stream_count_++; + EchoRequest request; + EchoResponse response; + while (stream->Read(&request)) { + gpr_log(GPR_INFO, "recv msg %s", request.message().c_str()); + response.set_message(request.message()); + stream->Write(response); + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1))); + } + return Status::OK; + } + + Status ResponseStream(ServerContext* context, const EchoRequest* request, + ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE { + EchoResponse response; + response_stream_count_++; + for (int i = 0;; i++) { + std::ostringstream msg; + msg << "Hello " << i; + response.set_message(msg.str()); + if (!writer->Write(response)) break; + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(1))); + } + return Status::OK; + } + + int bidi_stream_count() { return bidi_stream_count_; } + + int response_stream_count() { return response_stream_count_; } + + private: + int bidi_stream_count_; + int response_stream_count_; +}; + +class CrashTest : public ::testing::Test { + protected: + CrashTest() {} + + std::unique_ptr<Server> CreateServerAndClient(const std::string& mode) { + auto port = grpc_pick_unused_port_or_die(); + std::ostringstream addr_stream; + addr_stream << "localhost:" << port; + auto addr = addr_stream.str(); + client_.reset(new SubProcess({g_root + "/server_crash_test_client", + "--address=" + addr, "--mode=" + mode})); + GPR_ASSERT(client_); + + ServerBuilder builder; + builder.AddListeningPort(addr, grpc::InsecureServerCredentials()); + builder.RegisterService(&service_); + return builder.BuildAndStart(); + } + + void KillClient() { client_.reset(); } + + bool HadOneBidiStream() { return service_.bidi_stream_count() == 1; } + + bool HadOneResponseStream() { return service_.response_stream_count() == 1; } + + private: + std::unique_ptr<SubProcess> client_; + ServiceImpl service_; +}; + +TEST_F(CrashTest, ResponseStream) { + auto server = CreateServerAndClient("response"); + + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5))); + KillClient(); + server->Shutdown(); + GPR_ASSERT(HadOneResponseStream()); +} + +TEST_F(CrashTest, BidiStream) { + auto server = CreateServerAndClient("bidi"); + + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5))); + KillClient(); + server->Shutdown(); + GPR_ASSERT(HadOneBidiStream()); +} + +} // namespace + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + std::string me = argv[0]; + auto lslash = me.rfind('/'); + if (lslash != std::string::npos) { + g_root = me.substr(0, lslash); + } else { + g_root = "."; + } + + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/server_crash_test_client.cc b/test/cpp/end2end/server_crash_test_client.cc new file mode 100644 index 0000000000..497ccb4cb2 --- /dev/null +++ b/test/cpp/end2end/server_crash_test_client.cc @@ -0,0 +1,93 @@ +/* + * + * 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 <iostream> +#include <memory> +#include <sstream> +#include <string> +#include <gflags/gflags.h> + +#include <grpc++/channel_arguments.h> +#include <grpc++/channel_interface.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/credentials.h> +#include <grpc++/status.h> +#include "test/cpp/util/echo.grpc.pb.h" + +DEFINE_string(address, "", "Address to connect to"); +DEFINE_string(mode, "", "Test mode to use"); + +using grpc::cpp::test::util::EchoRequest; +using grpc::cpp::test::util::EchoResponse; + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + +int main(int argc, char** argv) { + ParseCommandLineFlags(&argc, &argv, true); + auto stub = grpc::cpp::test::util::TestService::NewStub( + grpc::CreateChannel(FLAGS_address, grpc::InsecureCredentials(), grpc::ChannelArguments())); + + EchoRequest request; + EchoResponse response; + grpc::ClientContext context; + + if (FLAGS_mode == "bidi") { + auto stream = stub->BidiStream(&context); + for (int i = 0;; i++) { + std::ostringstream msg; + msg << "Hello " << i; + request.set_message(msg.str()); + GPR_ASSERT(stream->Write(request)); + GPR_ASSERT(stream->Read(&response)); + GPR_ASSERT(response.message() == request.message()); + } + } else if (FLAGS_mode == "response") { + EchoRequest request; + request.set_message("Hello"); + auto stream = stub->ResponseStream(&context, request); + for (;;) { + GPR_ASSERT(stream->Read(&response)); + } + } else { + gpr_log(GPR_ERROR, "invalid test mode '%s'", FLAGS_mode.c_str()); + return 1; + } + + return 0; +} diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc index 12656128c0..310227a29c 100644 --- a/test/cpp/end2end/thread_stress_test.cc +++ b/test/cpp/end2end/thread_stress_test.cc @@ -94,14 +94,16 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { signal_client_ = true; } while (!context->IsCancelled()) { - std::this_thread::sleep_for(std::chrono::microseconds( - request->param().client_cancel_after_us())); + gpr_sleep_until(gpr_time_add( + gpr_now(), + gpr_time_from_micros(request->param().client_cancel_after_us()))); } return Status::Cancelled; } else if (request->has_param() && request->param().server_cancel_after_us()) { - std::this_thread::sleep_for( - std::chrono::microseconds(request->param().server_cancel_after_us())); + gpr_sleep_until(gpr_time_add( + gpr_now(), + gpr_time_from_micros(request->param().server_cancel_after_us()))); return Status::Cancelled; } else { EXPECT_FALSE(context->IsCancelled()); diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc index 874510e54f..e351059246 100644 --- a/test/cpp/interop/interop_client.cc +++ b/test/cpp/interop/interop_client.cc @@ -57,8 +57,8 @@ const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979}; const int kNumResponseMessages = 2000; const int kResponseMessageSize = 1030; const int kReceiveDelayMilliSeconds = 20; -const int kLargeRequestSize = 314159; -const int kLargeResponseSize = 271812; +const int kLargeRequestSize = 271828; +const int kLargeResponseSize = 314159; } // namespace InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel) diff --git a/test/cpp/qps/async_streaming_ping_pong_test.cc b/test/cpp/qps/async_streaming_ping_pong_test.cc index a1822b7e15..411df4d32a 100644 --- a/test/cpp/qps/async_streaming_ping_pong_test.cc +++ b/test/cpp/qps/async_streaming_ping_pong_test.cc @@ -31,12 +31,15 @@ * */ +#include <set> + #include <grpc/support/log.h> #include <signal.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" +#include "test/cpp/util/benchmark_config.h" namespace grpc { namespace testing { @@ -64,16 +67,17 @@ static void RunAsyncStreamingPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); - ReportQPS(result); - ReportLatency(result); + GetReporter()->ReportQPS(*result); + GetReporter()->ReportLatency(*result); } } // namespace testing } // namespace grpc int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); + signal(SIGPIPE, SIG_IGN); grpc::testing::RunAsyncStreamingPingPong(); - return 0; } diff --git a/test/cpp/qps/async_unary_ping_pong_test.cc b/test/cpp/qps/async_unary_ping_pong_test.cc index 8b037a8656..eda31b5744 100644 --- a/test/cpp/qps/async_unary_ping_pong_test.cc +++ b/test/cpp/qps/async_unary_ping_pong_test.cc @@ -31,12 +31,15 @@ * */ +#include <set> + #include <grpc/support/log.h> #include <signal.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" +#include "test/cpp/util/benchmark_config.h" namespace grpc { namespace testing { @@ -64,16 +67,16 @@ static void RunAsyncUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); - ReportQPS(result); - ReportLatency(result); + GetReporter()->ReportQPS(*result); + GetReporter()->ReportLatency(*result); } - } // namespace testing } // namespace grpc int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); signal(SIGPIPE, SIG_IGN); - grpc::testing::RunAsyncUnaryPingPong(); + grpc::testing::RunAsyncUnaryPingPong(); return 0; } diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index 2dc5b3860f..dc3a9f2ac5 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -113,24 +113,26 @@ class Client { : done_(false), new_(nullptr), impl_([this, idx, client]() { - for (;;) { - // run the loop body - bool thread_still_ok = client->ThreadFunc(&histogram_, idx); - // lock, see if we're done - std::lock_guard<std::mutex> g(mu_); - if (!thread_still_ok) { - gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); - done_ = true; - } - if (done_) {return;} - // check if we're marking, swap out the histogram if so - if (new_) { - new_->Swap(&histogram_); - new_ = nullptr; - cv_.notify_one(); - } + for (;;) { + // run the loop body + bool thread_still_ok = client->ThreadFunc(&histogram_, idx); + // lock, see if we're done + std::lock_guard<std::mutex> g(mu_); + if (!thread_still_ok) { + gpr_log(GPR_ERROR, "Finishing client thread due to RPC error"); + done_ = true; } - }) {} + if (done_) { + return; + } + // check if we're marking, swap out the histogram if so + if (new_) { + new_->Swap(&histogram_); + new_ = nullptr; + cv_.notify_one(); + } + } + }) {} ~Thread() { { @@ -168,10 +170,9 @@ class Client { std::unique_ptr<Timer> timer_; }; -std::unique_ptr<Client> - CreateSynchronousUnaryClient(const ClientConfig& args); -std::unique_ptr<Client> - CreateSynchronousStreamingClient(const ClientConfig& args); +std::unique_ptr<Client> CreateSynchronousUnaryClient(const ClientConfig& args); +std::unique_ptr<Client> CreateSynchronousStreamingClient( + const ClientConfig& args); std::unique_ptr<Client> CreateAsyncUnaryClient(const ClientConfig& args); std::unique_ptr<Client> CreateAsyncStreamingClient(const ClientConfig& args); diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index e3ab57728d..00bbd8a8a0 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -128,16 +128,16 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { class AsyncClient : public Client { public: explicit AsyncClient(const ClientConfig& config, - std::function<void(CompletionQueue*, TestService::Stub*, - const SimpleRequest&)> setup_ctx) : - Client(config) { + std::function<void(CompletionQueue*, TestService::Stub*, + const SimpleRequest&)> setup_ctx) + : Client(config) { for (int i = 0; i < config.async_client_threads(); i++) { cli_cqs_.emplace_back(new CompletionQueue); } int t = 0; for (int i = 0; i < config.outstanding_rpcs_per_channel(); i++) { for (auto channel = channels_.begin(); channel != channels_.end(); - channel++) { + channel++) { auto* cq = cli_cqs_[t].get(); t = (t + 1) % cli_cqs_.size(); setup_ctx(cq, channel->get_stub(), request_); @@ -155,16 +155,19 @@ class AsyncClient : public Client { } } - bool ThreadFunc(Histogram* histogram, size_t thread_idx) - GRPC_OVERRIDE GRPC_FINAL { + bool ThreadFunc(Histogram* histogram, + size_t thread_idx) GRPC_OVERRIDE GRPC_FINAL { void* got_tag; bool ok; - switch (cli_cqs_[thread_idx]->AsyncNext(&got_tag, &ok, - std::chrono::system_clock::now() + - std::chrono::seconds(1))) { - case CompletionQueue::SHUTDOWN: return false; - case CompletionQueue::TIMEOUT: return true; - case CompletionQueue::GOT_EVENT: break; + switch (cli_cqs_[thread_idx]->AsyncNext( + &got_tag, &ok, + std::chrono::system_clock::now() + std::chrono::seconds(1))) { + case CompletionQueue::SHUTDOWN: + return false; + case CompletionQueue::TIMEOUT: + return true; + case CompletionQueue::GOT_EVENT: + break; } ClientRpcContext* ctx = ClientRpcContext::detag(got_tag); @@ -177,18 +180,20 @@ class AsyncClient : public Client { return true; } + private: std::vector<std::unique_ptr<CompletionQueue>> cli_cqs_; }; class AsyncUnaryClient GRPC_FINAL : public AsyncClient { public: - explicit AsyncUnaryClient(const ClientConfig& config) : - AsyncClient(config, SetupCtx) { + explicit AsyncUnaryClient(const ClientConfig& config) + : AsyncClient(config, SetupCtx) { StartThreads(config.async_client_threads()); } ~AsyncUnaryClient() GRPC_OVERRIDE { EndThreads(); } -private: + + private: static void SetupCtx(CompletionQueue* cq, TestService::Stub* stub, const SimpleRequest& req) { auto check_done = [](grpc::Status s, SimpleResponse* response) {}; @@ -205,12 +210,11 @@ template <class RequestType, class ResponseType> class ClientRpcContextStreamingImpl : public ClientRpcContext { public: ClientRpcContextStreamingImpl( - TestService::Stub *stub, const RequestType &req, - std::function< - std::unique_ptr<grpc::ClientAsyncReaderWriter< - RequestType,ResponseType>>( - TestService::Stub *, grpc::ClientContext *, void *)> start_req, - std::function<void(grpc::Status, ResponseType *)> on_done) + TestService::Stub* stub, const RequestType& req, + std::function<std::unique_ptr< + grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>( + TestService::Stub*, grpc::ClientContext*, void*)> start_req, + std::function<void(grpc::Status, ResponseType*)> on_done) : context_(), stub_(stub), req_(req), @@ -221,7 +225,7 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { start_(Timer::Now()), stream_(start_req_(stub_, &context_, ClientRpcContext::tag(this))) {} ~ClientRpcContextStreamingImpl() GRPC_OVERRIDE {} - bool RunNextState(bool ok, Histogram *hist) GRPC_OVERRIDE { + bool RunNextState(bool ok, Histogram* hist) GRPC_OVERRIDE { return (this->*next_state_)(ok, hist); } void StartNewClone() GRPC_OVERRIDE { @@ -229,59 +233,58 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { } private: - bool ReqSent(bool ok, Histogram *) { - return StartWrite(ok); - } + bool ReqSent(bool ok, Histogram*) { return StartWrite(ok); } bool StartWrite(bool ok) { if (!ok) { - return(false); + return (false); } start_ = Timer::Now(); next_state_ = &ClientRpcContextStreamingImpl::WriteDone; stream_->Write(req_, ClientRpcContext::tag(this)); return true; } - bool WriteDone(bool ok, Histogram *) { + bool WriteDone(bool ok, Histogram*) { if (!ok) { - return(false); + return (false); } next_state_ = &ClientRpcContextStreamingImpl::ReadDone; stream_->Read(&response_, ClientRpcContext::tag(this)); return true; } - bool ReadDone(bool ok, Histogram *hist) { + bool ReadDone(bool ok, Histogram* hist) { hist->Add((Timer::Now() - start_) * 1e9); return StartWrite(ok); } grpc::ClientContext context_; - TestService::Stub *stub_; + TestService::Stub* stub_; RequestType req_; ResponseType response_; - bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram *); - std::function<void(grpc::Status, ResponseType *)> callback_; - std::function<std::unique_ptr<grpc::ClientAsyncReaderWriter< - RequestType,ResponseType>>( - TestService::Stub *, grpc::ClientContext *, void *)> start_req_; + bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram*); + std::function<void(grpc::Status, ResponseType*)> callback_; + std::function< + std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>( + TestService::Stub*, grpc::ClientContext*, void*)> start_req_; grpc::Status status_; double start_; - std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType,ResponseType>> - stream_; + std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>> + stream_; }; class AsyncStreamingClient GRPC_FINAL : public AsyncClient { public: - explicit AsyncStreamingClient(const ClientConfig &config) : - AsyncClient(config, SetupCtx) { + explicit AsyncStreamingClient(const ClientConfig& config) + : AsyncClient(config, SetupCtx) { StartThreads(config.async_client_threads()); } ~AsyncStreamingClient() GRPC_OVERRIDE { EndThreads(); } -private: + + private: static void SetupCtx(CompletionQueue* cq, TestService::Stub* stub, - const SimpleRequest& req) { + const SimpleRequest& req) { auto check_done = [](grpc::Status s, SimpleResponse* response) {}; - auto start_req = [cq](TestService::Stub *stub, grpc::ClientContext *ctx, - void *tag) { + auto start_req = [cq](TestService::Stub* stub, grpc::ClientContext* ctx, + void* tag) { auto stream = stub->AsyncStreamingCall(ctx, cq, tag); return stream; }; diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc index 264293561d..c28dc91321 100644 --- a/test/cpp/qps/client_sync.cc +++ b/test/cpp/qps/client_sync.cc @@ -99,7 +99,9 @@ class SynchronousUnaryClient GRPC_FINAL : public SynchronousClient { class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { public: SynchronousStreamingClient(const ClientConfig& config) - : SynchronousClient(config), context_(num_threads_), stream_(num_threads_) { + : SynchronousClient(config), + context_(num_threads_), + stream_(num_threads_) { for (size_t thread_idx = 0; thread_idx < num_threads_; thread_idx++) { auto* stub = channels_[thread_idx % channels_.size()].get_stub(); stream_[thread_idx] = stub->StreamingCall(&context_[thread_idx]); @@ -110,8 +112,8 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { EndThreads(); for (auto stream = stream_.begin(); stream != stream_.end(); stream++) { if (*stream) { - (*stream)->WritesDone(); - EXPECT_TRUE((*stream)->Finish().IsOk()); + (*stream)->WritesDone(); + EXPECT_TRUE((*stream)->Finish().IsOk()); } } } @@ -119,7 +121,7 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { bool ThreadFunc(Histogram* histogram, size_t thread_idx) GRPC_OVERRIDE { double start = Timer::Now(); if (stream_[thread_idx]->Write(request_) && - stream_[thread_idx]->Read(&responses_[thread_idx])) { + stream_[thread_idx]->Read(&responses_[thread_idx])) { histogram->Add((Timer::Now() - start) * 1e9); return true; } @@ -128,8 +130,8 @@ class SynchronousStreamingClient GRPC_FINAL : public SynchronousClient { private: std::vector<grpc::ClientContext> context_; - std::vector<std::unique_ptr<grpc::ClientReaderWriter< - SimpleRequest, SimpleResponse>>> stream_; + std::vector<std::unique_ptr< + grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>>> stream_; }; std::unique_ptr<Client> CreateSynchronousUnaryClient( diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 9f7d3b56a4..bf12730f97 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -44,9 +44,11 @@ #include <thread> #include <deque> #include <vector> +#include <unistd.h> #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/qps_worker.h" #include "test/core/util/port.h" +#include "test/core/util/test_config.h" using std::list; using std::thread; @@ -75,13 +77,10 @@ static deque<string> get_hosts(const string& name) { } } -ScenarioResult RunScenario(const ClientConfig& initial_client_config, - size_t num_clients, - const ServerConfig& server_config, - size_t num_servers, - int warmup_seconds, - int benchmark_seconds, - int spawn_local_worker_count) { +std::unique_ptr<ScenarioResult> RunScenario( + const ClientConfig& initial_client_config, size_t num_clients, + const ServerConfig& server_config, size_t num_servers, int warmup_seconds, + int benchmark_seconds, int spawn_local_worker_count) { // ClientContext allocator (all are destroyed at scope exit) list<ClientContext> contexts; auto alloc_context = [&contexts]() { @@ -89,6 +88,11 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, return &contexts.back(); }; + // To be added to the result, containing the final configuration used for + // client and config (incluiding host, etc.) + ClientConfig result_client_config; + ServerConfig result_server_config; + // Get client, server lists auto workers = get_hosts("QPS_WORKERS"); ClientConfig client_config = initial_client_config; @@ -96,6 +100,16 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, // Spawn some local workers if desired vector<unique_ptr<QpsWorker>> local_workers; for (int i = 0; i < abs(spawn_local_worker_count); i++) { + // act as if we're a new test -- gets a good rng seed + static bool called_init = false; + if (!called_init) { + char args_buf[100]; + strcpy(args_buf, "some-benchmark"); + char* args[] = {args_buf}; + grpc_test_init(1, args); + called_init = true; + } + int driver_port = grpc_pick_unused_port_or_die(); int benchmark_port = grpc_pick_unused_port_or_die(); local_workers.emplace_back(new QpsWorker(driver_port, benchmark_port)); @@ -127,6 +141,8 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, sd.stub = std::move(Worker::NewStub( CreateChannel(workers[i], InsecureCredentials(), ChannelArguments()))); ServerArgs args; + result_server_config = server_config; + result_server_config.set_host(workers[i]); *args.mutable_setup() = server_config; sd.stream = std::move(sd.stub->RunServer(alloc_context())); GPR_ASSERT(sd.stream->Write(args)); @@ -156,6 +172,8 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, cd.stub = std::move(Worker::NewStub(CreateChannel( workers[i + num_servers], InsecureCredentials(), ChannelArguments()))); ClientArgs args; + result_client_config = client_config; + result_client_config.set_host(workers[i + num_servers]); *args.mutable_setup() = client_config; cd.stream = std::move(cd.stub->RunTest(alloc_context())); GPR_ASSERT(cd.stream->Write(args)); @@ -193,10 +211,13 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, // Wait some time gpr_log(GPR_INFO, "Running"); - gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds))); + gpr_sleep_until( + gpr_time_add(start, gpr_time_from_seconds(benchmark_seconds))); // Finish a run - ScenarioResult result; + std::unique_ptr<ScenarioResult> result(new ScenarioResult); + result->client_config = result_client_config; + result->server_config = result_server_config; gpr_log(GPR_INFO, "Finishing"); for (auto server = servers.begin(); server != servers.end(); server++) { GPR_ASSERT(server->stream->Write(server_mark)); @@ -207,14 +228,14 @@ ScenarioResult RunScenario(const ClientConfig& initial_client_config, for (auto server = servers.begin(); server != servers.end(); server++) { GPR_ASSERT(server->stream->Read(&server_status)); const auto& stats = server_status.stats(); - result.server_resources.push_back(ResourceUsage{ + result->server_resources.push_back(ResourceUsage{ stats.time_elapsed(), stats.time_user(), stats.time_system()}); } for (auto client = clients.begin(); client != clients.end(); client++) { GPR_ASSERT(client->stream->Read(&client_status)); const auto& stats = client_status.stats(); - result.latencies.MergeProto(stats.latencies()); - result.client_resources.push_back(ResourceUsage{ + result->latencies.MergeProto(stats.latencies()); + result->client_resources.push_back(ResourceUsage{ stats.time_elapsed(), stats.time_user(), stats.time_system()}); } diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index eb7119a89d..5e9d4b3cb9 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -34,6 +34,8 @@ #ifndef TEST_QPS_DRIVER_H #define TEST_QPS_DRIVER_H +#include <memory> + #include "test/cpp/qps/histogram.h" #include "test/cpp/qps/qpstest.grpc.pb.h" @@ -49,15 +51,14 @@ struct ScenarioResult { Histogram latencies; std::vector<ResourceUsage> client_resources; std::vector<ResourceUsage> server_resources; + ClientConfig client_config; + ServerConfig server_config; }; -ScenarioResult RunScenario(const grpc::testing::ClientConfig& client_config, - size_t num_clients, - const grpc::testing::ServerConfig& server_config, - size_t num_servers, - int warmup_seconds, - int benchmark_seconds, - int spawn_local_worker_count); +std::unique_ptr<ScenarioResult> RunScenario( + const grpc::testing::ClientConfig& client_config, size_t num_clients, + const grpc::testing::ServerConfig& server_config, size_t num_servers, + int warmup_seconds, int benchmark_seconds, int spawn_local_worker_count); } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh index 7bc6eade2c..cb93201933 100755 --- a/test/cpp/qps/qps-sweep.sh +++ b/test/cpp/qps/qps-sweep.sh @@ -1,5 +1,34 @@ #!/bin/sh +# 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. + if [ x"$QPS_WORKERS" == x ]; then echo Error: Must set QPS_WORKERS variable in form \ "host:port,host:port,..." 1>&2 diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc index fc8e04201c..281e2e8119 100644 --- a/test/cpp/qps/qps_driver.cc +++ b/test/cpp/qps/qps_driver.cc @@ -31,12 +31,15 @@ * */ +#include <memory> +#include <set> + #include <gflags/gflags.h> #include <grpc/support/log.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" -#include "test/cpp/util/test_config.h" +#include "test/cpp/util/benchmark_config.h" DEFINE_int32(num_clients, 1, "Number of client binaries"); DEFINE_int32(num_servers, 1, "Number of server binaries"); @@ -68,9 +71,10 @@ using grpc::testing::ServerType; using grpc::testing::RpcType; using grpc::testing::ResourceUsage; -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); +namespace grpc { +namespace testing { +static void QpsDriver() { RpcType rpc_type; GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type)); @@ -100,17 +104,27 @@ int main(int argc, char** argv) { // client will deadlock on a timer. GPR_ASSERT(!(server_type == grpc::testing::SYNCHRONOUS_SERVER && rpc_type == grpc::testing::STREAMING && - FLAGS_server_threads < FLAGS_client_channels * - FLAGS_outstanding_rpcs_per_channel)); + FLAGS_server_threads < + FLAGS_client_channels * FLAGS_outstanding_rpcs_per_channel)); - auto result = RunScenario(client_config, FLAGS_num_clients, - server_config, FLAGS_num_servers, - FLAGS_warmup_seconds, FLAGS_benchmark_seconds, - FLAGS_local_workers); + const auto result = RunScenario( + client_config, FLAGS_num_clients, server_config, FLAGS_num_servers, + FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers); + + GetReporter()->ReportQPS(*result); + GetReporter()->ReportQPSPerCore(*result, server_config); + GetReporter()->ReportLatency(*result); + GetReporter()->ReportTimes(*result); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); - ReportQPSPerCore(result, server_config); - ReportLatency(result); - ReportTimes(result); + signal(SIGPIPE, SIG_IGN); + grpc::testing::QpsDriver(); return 0; } diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc index f567e4cf06..63a37ae07e 100644 --- a/test/cpp/qps/qps_test.cc +++ b/test/cpp/qps/qps_test.cc @@ -31,12 +31,15 @@ * */ +#include <set> + #include <grpc/support/log.h> #include <signal.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" +#include "test/cpp/util/benchmark_config.h" namespace grpc { namespace testing { @@ -64,14 +67,16 @@ static void RunQPS() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); - ReportQPSPerCore(result, server_config); - ReportLatency(result); + GetReporter()->ReportQPSPerCore(*result, server_config); + GetReporter()->ReportLatency(*result); } } // namespace testing } // namespace grpc int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); + signal(SIGPIPE, SIG_IGN); grpc::testing::RunQPS(); diff --git a/test/cpp/qps/qps_worker.cc b/test/cpp/qps/qps_worker.cc index 46d70dce52..fb49271991 100644 --- a/test/cpp/qps/qps_worker.cc +++ b/test/cpp/qps/qps_worker.cc @@ -64,17 +64,19 @@ namespace testing { std::unique_ptr<Client> CreateClient(const ClientConfig& config) { switch (config.client_type()) { case ClientType::SYNCHRONOUS_CLIENT: - return (config.rpc_type() == RpcType::UNARY) ? - CreateSynchronousUnaryClient(config) : - CreateSynchronousStreamingClient(config); + return (config.rpc_type() == RpcType::UNARY) + ? CreateSynchronousUnaryClient(config) + : CreateSynchronousStreamingClient(config); case ClientType::ASYNC_CLIENT: - return (config.rpc_type() == RpcType::UNARY) ? - CreateAsyncUnaryClient(config) : CreateAsyncStreamingClient(config); + return (config.rpc_type() == RpcType::UNARY) + ? CreateAsyncUnaryClient(config) + : CreateAsyncStreamingClient(config); } abort(); } -std::unique_ptr<Server> CreateServer(const ServerConfig& config, int server_port) { +std::unique_ptr<Server> CreateServer(const ServerConfig& config, + int server_port) { switch (config.server_type()) { case ServerType::SYNCHRONOUS_SERVER: return CreateSynchronousServer(config, server_port); @@ -86,7 +88,8 @@ std::unique_ptr<Server> CreateServer(const ServerConfig& config, int server_port class WorkerImpl GRPC_FINAL : public Worker::Service { public: - explicit WorkerImpl(int server_port) : server_port_(server_port), acquired_(false) {} + explicit WorkerImpl(int server_port) + : server_port_(server_port), acquired_(false) {} Status RunTest(ServerContext* ctx, ServerReaderWriter<ClientStatus, ClientArgs>* stream) @@ -97,7 +100,7 @@ class WorkerImpl GRPC_FINAL : public Worker::Service { } grpc_profiler_start("qps_client.prof"); - Status ret = RunTestBody(ctx,stream); + Status ret = RunTestBody(ctx, stream); grpc_profiler_stop(); return ret; } @@ -111,7 +114,7 @@ class WorkerImpl GRPC_FINAL : public Worker::Service { } grpc_profiler_start("qps_server.prof"); - Status ret = RunServerBody(ctx,stream); + Status ret = RunServerBody(ctx, stream); grpc_profiler_stop(); return ret; } @@ -226,8 +229,7 @@ QpsWorker::QpsWorker(int driver_port, int server_port) { server_ = std::move(builder.BuildAndStart()); } -QpsWorker::~QpsWorker() { -} +QpsWorker::~QpsWorker() {} } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index 1553ef5f07..122a7df1ac 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -102,6 +102,7 @@ message ClientConfig { // only for async client: optional int32 async_client_threads = 7; optional RpcType rpc_type = 8 [default=UNARY]; + optional string host = 9; } // Request current stats @@ -129,6 +130,7 @@ message ServerConfig { required ServerType server_type = 1; optional int32 threads = 2 [default=1]; optional bool enable_ssl = 3 [default=false]; + optional string host = 4; } message ServerArgs { diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc index 29d88da344..e116175e3b 100644 --- a/test/cpp/qps/report.cc +++ b/test/cpp/qps/report.cc @@ -39,27 +39,57 @@ namespace grpc { namespace testing { -// QPS: XXX -void ReportQPS(const ScenarioResult& result) { +void CompositeReporter::add(std::unique_ptr<Reporter> reporter) { + reporters_.emplace_back(std::move(reporter)); +} + +void CompositeReporter::ReportQPS(const ScenarioResult& result) const { + for (size_t i = 0; i < reporters_.size(); ++i) { + reporters_[i]->ReportQPS(result); + } +} + +void CompositeReporter::ReportQPSPerCore(const ScenarioResult& result, + const ServerConfig& config) const { + for (size_t i = 0; i < reporters_.size(); ++i) { + reporters_[i]->ReportQPSPerCore(result, config); + } +} + +void CompositeReporter::ReportLatency(const ScenarioResult& result) const { + for (size_t i = 0; i < reporters_.size(); ++i) { + reporters_[i]->ReportLatency(result); + } +} + +void CompositeReporter::ReportTimes(const ScenarioResult& result) const { + for (size_t i = 0; i < reporters_.size(); ++i) { + reporters_[i]->ReportTimes(result); + } +} + + +void GprLogReporter::ReportQPS(const ScenarioResult& result) const { gpr_log(GPR_INFO, "QPS: %.1f", result.latencies.Count() / average(result.client_resources, [](ResourceUsage u) { return u.wall_time; })); } -// QPS: XXX (YYY/server core) -void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& server_config) { - auto qps = +void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result, + const ServerConfig& server_config) const { + auto qps = result.latencies.Count() / average(result.client_resources, [](ResourceUsage u) { return u.wall_time; }); - gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, qps/server_config.threads()); + gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps, + qps / server_config.threads()); } -// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us -void ReportLatency(const ScenarioResult& result) { - gpr_log(GPR_INFO, "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", +void GprLogReporter::ReportLatency(const ScenarioResult& result) const { + gpr_log(GPR_INFO, + "Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us", result.latencies.Percentile(50) / 1000, result.latencies.Percentile(90) / 1000, result.latencies.Percentile(95) / 1000, @@ -67,7 +97,7 @@ void ReportLatency(const ScenarioResult& result) { result.latencies.Percentile(99.9) / 1000); } -void ReportTimes(const ScenarioResult& result) { +void GprLogReporter::ReportTimes(const ScenarioResult& result) const { gpr_log(GPR_INFO, "Server system time: %.2f%%", 100.0 * sum(result.server_resources, [](ResourceUsage u) { return u.system_time; }) / diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h index 343e426ca4..630275ecda 100644 --- a/test/cpp/qps/report.h +++ b/test/cpp/qps/report.h @@ -34,22 +34,77 @@ #ifndef TEST_QPS_REPORT_H #define TEST_QPS_REPORT_H +#include <memory> +#include <set> +#include <vector> +#include <grpc++/config.h> + #include "test/cpp/qps/driver.h" +#include "test/cpp/qps/qpstest.grpc.pb.h" namespace grpc { namespace testing { -// QPS: XXX -void ReportQPS(const ScenarioResult& result); -// QPS: XXX (YYY/server core) -void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config); -// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us -void ReportLatency(const ScenarioResult& result); -// Server system time: XX% -// Server user time: XX% -// Client system time: XX% -// Client user time: XX% -void ReportTimes(const ScenarioResult& result); +/** Interface for all reporters. */ +class Reporter { + public: + /** Construct a reporter with the given \a name. */ + Reporter(const string& name) : name_(name) {} + + virtual ~Reporter() {} + + /** Returns this reporter's name. + * + * Names are constants, set at construction time. */ + string name() const { return name_; } + + /** Reports QPS for the given \a result. */ + virtual void ReportQPS(const ScenarioResult& result) const = 0; + + /** Reports QPS per core as (YYY/server core). */ + virtual void ReportQPSPerCore(const ScenarioResult& result, + const ServerConfig& config) const = 0; + + /** Reports latencies for the 50, 90, 95, 99 and 99.9 percentiles, in ms. */ + virtual void ReportLatency(const ScenarioResult& result) const = 0; + + /** Reports system and user time for client and server systems. */ + virtual void ReportTimes(const ScenarioResult& result) const = 0; + + private: + const string name_; +}; + +/** A composite for all reporters to be considered. */ +class CompositeReporter : public Reporter { + public: + CompositeReporter() : Reporter("CompositeReporter") {} + + /** Adds a \a reporter to the composite. */ + void add(std::unique_ptr<Reporter> reporter); + + void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE; + void ReportQPSPerCore(const ScenarioResult& result, + const ServerConfig& config) const GRPC_OVERRIDE; + void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE; + void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE; + + private: + std::vector<std::unique_ptr<Reporter> > reporters_; +}; + +/** Reporter to gpr_log(GPR_INFO). */ +class GprLogReporter : public Reporter { + public: + GprLogReporter(const string& name) : Reporter(name) {} + + private: + void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE; + void ReportQPSPerCore(const ScenarioResult& result, + const ServerConfig& config) const GRPC_OVERRIDE; + void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE; + void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE; +}; } // namespace testing } // namespace grpc diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index 6cb3192908..b9998405f6 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -64,7 +64,7 @@ namespace testing { class AsyncQpsServerTest : public Server { public: AsyncQpsServerTest(const ServerConfig &config, int port) : shutdown_(false) { - char* server_address = NULL; + char *server_address = NULL; gpr_join_host_port(&server_address, "::", port); ServerBuilder builder; @@ -95,16 +95,19 @@ class AsyncQpsServerTest : public Server { threads_.push_back(std::thread([=]() { // Wait until work is available or we are shutting down bool ok; - void* got_tag; + void *got_tag; while (srv_cq_->Next(&got_tag, &ok)) { - ServerRpcContext* ctx = detag(got_tag); + ServerRpcContext *ctx = detag(got_tag); // The tag is a pointer to an RPC context to invoke - if (ctx->RunNextState(ok) == false) { + bool still_going = ctx->RunNextState(ok); + std::lock_guard<std::mutex> g(shutdown_mutex_); + if (!shutdown_) { // this RPC context is done, so refresh it - std::lock_guard<std::mutex> g(shutdown_mutex_); - if (!shutdown_) { + if (!still_going) { ctx->Reset(); } + } else { + return; } } return; @@ -116,11 +119,15 @@ class AsyncQpsServerTest : public Server { { std::lock_guard<std::mutex> g(shutdown_mutex_); shutdown_ = true; - srv_cq_->Shutdown(); } for (auto thr = threads_.begin(); thr != threads_.end(); thr++) { thr->join(); } + srv_cq_->Shutdown(); + bool ok; + void *got_tag; + while (srv_cq_->Next(&got_tag, &ok)) + ; while (!contexts_.empty()) { delete contexts_.front(); contexts_.pop_front(); @@ -133,23 +140,23 @@ class AsyncQpsServerTest : public Server { ServerRpcContext() {} virtual ~ServerRpcContext(){}; virtual bool RunNextState(bool) = 0; // next state, return false if done - virtual void Reset() = 0; // start this back at a clean state + virtual void Reset() = 0; // start this back at a clean state }; - static void* tag(ServerRpcContext* func) { - return reinterpret_cast<void*>(func); + static void *tag(ServerRpcContext *func) { + return reinterpret_cast<void *>(func); } - static ServerRpcContext* detag(void* tag) { - return reinterpret_cast<ServerRpcContext*>(tag); + static ServerRpcContext *detag(void *tag) { + return reinterpret_cast<ServerRpcContext *>(tag); } template <class RequestType, class ResponseType> class ServerRpcContextUnaryImpl GRPC_FINAL : public ServerRpcContext { public: ServerRpcContextUnaryImpl( - std::function<void(ServerContext*, RequestType*, - grpc::ServerAsyncResponseWriter<ResponseType>*, - void*)> request_method, - std::function<grpc::Status(const RequestType*, ResponseType*)> + std::function<void(ServerContext *, RequestType *, + grpc::ServerAsyncResponseWriter<ResponseType> *, + void *)> request_method, + std::function<grpc::Status(const RequestType *, ResponseType *)> invoke_method) : next_state_(&ServerRpcContextUnaryImpl::invoker), request_method_(request_method), @@ -159,7 +166,9 @@ class AsyncQpsServerTest : public Server { AsyncQpsServerTest::tag(this)); } ~ServerRpcContextUnaryImpl() GRPC_OVERRIDE {} - bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);} + bool RunNextState(bool ok) GRPC_OVERRIDE { + return (this->*next_state_)(ok); + } void Reset() GRPC_OVERRIDE { srv_ctx_ = ServerContext(); req_ = RequestType(); @@ -192,10 +201,10 @@ class AsyncQpsServerTest : public Server { ServerContext srv_ctx_; RequestType req_; bool (ServerRpcContextUnaryImpl::*next_state_)(bool); - std::function<void(ServerContext*, RequestType*, - grpc::ServerAsyncResponseWriter<ResponseType>*, void*)> + std::function<void(ServerContext *, RequestType *, + grpc::ServerAsyncResponseWriter<ResponseType> *, void *)> request_method_; - std::function<grpc::Status(const RequestType*, ResponseType*)> + std::function<grpc::Status(const RequestType *, ResponseType *)> invoke_method_; grpc::ServerAsyncResponseWriter<ResponseType> response_writer_; }; @@ -204,9 +213,9 @@ class AsyncQpsServerTest : public Server { class ServerRpcContextStreamingImpl GRPC_FINAL : public ServerRpcContext { public: ServerRpcContextStreamingImpl( - std::function<void(ServerContext *, - grpc::ServerAsyncReaderWriter<ResponseType, - RequestType> *, void *)> request_method, + std::function<void(ServerContext *, grpc::ServerAsyncReaderWriter< + ResponseType, RequestType> *, + void *)> request_method, std::function<grpc::Status(const RequestType *, ResponseType *)> invoke_method) : next_state_(&ServerRpcContextStreamingImpl::request_done), @@ -215,14 +224,15 @@ class AsyncQpsServerTest : public Server { stream_(&srv_ctx_) { request_method_(&srv_ctx_, &stream_, AsyncQpsServerTest::tag(this)); } - ~ServerRpcContextStreamingImpl() GRPC_OVERRIDE { + ~ServerRpcContextStreamingImpl() GRPC_OVERRIDE {} + bool RunNextState(bool ok) GRPC_OVERRIDE { + return (this->*next_state_)(ok); } - bool RunNextState(bool ok) GRPC_OVERRIDE {return (this->*next_state_)(ok);} void Reset() GRPC_OVERRIDE { srv_ctx_ = ServerContext(); req_ = RequestType(); - stream_ = grpc::ServerAsyncReaderWriter<ResponseType, - RequestType>(&srv_ctx_); + stream_ = + grpc::ServerAsyncReaderWriter<ResponseType, RequestType>(&srv_ctx_); // Then request the method next_state_ = &ServerRpcContextStreamingImpl::request_done; @@ -241,47 +251,47 @@ class AsyncQpsServerTest : public Server { bool read_done(bool ok) { if (ok) { - // invoke the method - ResponseType response; - // Call the RPC processing function - grpc::Status status = invoke_method_(&req_, &response); - // initiate the write - stream_.Write(response, AsyncQpsServerTest::tag(this)); - next_state_ = &ServerRpcContextStreamingImpl::write_done; - } else { // client has sent writes done - // finish the stream - stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); - next_state_ = &ServerRpcContextStreamingImpl::finish_done; + // invoke the method + ResponseType response; + // Call the RPC processing function + grpc::Status status = invoke_method_(&req_, &response); + // initiate the write + stream_.Write(response, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::write_done; + } else { // client has sent writes done + // finish the stream + stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::finish_done; } return true; } bool write_done(bool ok) { // now go back and get another streaming read! if (ok) { - stream_.Read(&req_, AsyncQpsServerTest::tag(this)); - next_state_ = &ServerRpcContextStreamingImpl::read_done; - } - else { - stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); - next_state_ = &ServerRpcContextStreamingImpl::finish_done; + stream_.Read(&req_, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::read_done; + } else { + stream_.Finish(Status::OK, AsyncQpsServerTest::tag(this)); + next_state_ = &ServerRpcContextStreamingImpl::finish_done; } return true; } - bool finish_done(bool ok) {return false; /* reset the context */ } + bool finish_done(bool ok) { return false; /* reset the context */ } ServerContext srv_ctx_; RequestType req_; bool (ServerRpcContextStreamingImpl::*next_state_)(bool); - std::function<void(ServerContext *, - grpc::ServerAsyncReaderWriter<ResponseType, - RequestType> *, void *)> request_method_; + std::function<void( + ServerContext *, + grpc::ServerAsyncReaderWriter<ResponseType, RequestType> *, void *)> + request_method_; std::function<grpc::Status(const RequestType *, ResponseType *)> invoke_method_; - grpc::ServerAsyncReaderWriter<ResponseType,RequestType> stream_; + grpc::ServerAsyncReaderWriter<ResponseType, RequestType> stream_; }; - static Status ProcessRPC(const SimpleRequest* request, - SimpleResponse* response) { + static Status ProcessRPC(const SimpleRequest *request, + SimpleResponse *response) { if (request->response_size() > 0) { if (!SetPayload(request->response_type(), request->response_size(), response->mutable_payload())) { @@ -294,19 +304,20 @@ class AsyncQpsServerTest : public Server { std::unique_ptr<grpc::Server> server_; std::unique_ptr<grpc::ServerCompletionQueue> srv_cq_; TestService::AsyncService async_service_; - std::function<void(ServerContext*, SimpleRequest*, - grpc::ServerAsyncResponseWriter<SimpleResponse>*, void*)> + std::function<void(ServerContext *, SimpleRequest *, + grpc::ServerAsyncResponseWriter<SimpleResponse> *, void *)> request_unary_; - std::function<void(ServerContext*, grpc::ServerAsyncReaderWriter< - SimpleResponse,SimpleRequest>*, void*)> + std::function<void( + ServerContext *, + grpc::ServerAsyncReaderWriter<SimpleResponse, SimpleRequest> *, void *)> request_streaming_; - std::forward_list<ServerRpcContext*> contexts_; + std::forward_list<ServerRpcContext *> contexts_; std::mutex shutdown_mutex_; bool shutdown_; }; -std::unique_ptr<Server> CreateAsyncServer(const ServerConfig& config, +std::unique_ptr<Server> CreateAsyncServer(const ServerConfig &config, int port) { return std::unique_ptr<Server>(new AsyncQpsServerTest(config, port)); } diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 2770233a7c..bc00de9ced 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -70,18 +70,18 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service { } return Status::OK; } - Status StreamingCall(ServerContext *context, - ServerReaderWriter<SimpleResponse, SimpleRequest>* - stream) GRPC_OVERRIDE { + Status StreamingCall( + ServerContext* context, + ServerReaderWriter<SimpleResponse, SimpleRequest>* stream) GRPC_OVERRIDE { SimpleRequest request; while (stream->Read(&request)) { SimpleResponse response; if (request.response_size() > 0) { - if (!Server::SetPayload(request.response_type(), - request.response_size(), - response.mutable_payload())) { - return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); - } + if (!Server::SetPayload(request.response_type(), + request.response_size(), + response.mutable_payload())) { + return Status(grpc::StatusCode::INTERNAL, "Error creating payload."); + } } stream->Write(response); } diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index 2f60b4e49d..9d76f08f80 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -1,4 +1,32 @@ #!/bin/sh +# 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. # performs a single qps run with one client and one server diff --git a/test/cpp/qps/sync_streaming_ping_pong_test.cc b/test/cpp/qps/sync_streaming_ping_pong_test.cc index 48c7ff63e0..d53905a779 100644 --- a/test/cpp/qps/sync_streaming_ping_pong_test.cc +++ b/test/cpp/qps/sync_streaming_ping_pong_test.cc @@ -31,12 +31,15 @@ * */ +#include <set> + #include <grpc/support/log.h> #include <signal.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" +#include "test/cpp/util/benchmark_config.h" namespace grpc { namespace testing { @@ -63,14 +66,15 @@ static void RunSynchronousStreamingPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); - ReportQPS(result); - ReportLatency(result); + GetReporter()->ReportQPS(*result); + GetReporter()->ReportLatency(*result); } - } // namespace testing } // namespace grpc int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); + signal(SIGPIPE, SIG_IGN); grpc::testing::RunSynchronousStreamingPingPong(); diff --git a/test/cpp/qps/sync_unary_ping_pong_test.cc b/test/cpp/qps/sync_unary_ping_pong_test.cc index 4c4de6377b..d276d13a43 100644 --- a/test/cpp/qps/sync_unary_ping_pong_test.cc +++ b/test/cpp/qps/sync_unary_ping_pong_test.cc @@ -31,12 +31,15 @@ * */ +#include <set> + #include <grpc/support/log.h> #include <signal.h> #include "test/cpp/qps/driver.h" #include "test/cpp/qps/report.h" +#include "test/cpp/util/benchmark_config.h" namespace grpc { namespace testing { @@ -63,14 +66,16 @@ static void RunSynchronousUnaryPingPong() { const auto result = RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2); - ReportQPS(result); - ReportLatency(result); + GetReporter()->ReportQPS(*result); + GetReporter()->ReportLatency(*result); } } // namespace testing } // namespace grpc int main(int argc, char** argv) { + grpc::testing::InitBenchmark(&argc, &argv, true); + signal(SIGPIPE, SIG_IGN); grpc::testing::RunSynchronousUnaryPingPong(); diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc index 281c617382..dfc102fc17 100644 --- a/test/cpp/qps/worker.cc +++ b/test/cpp/qps/worker.cc @@ -37,6 +37,7 @@ #include <thread> #include <grpc/grpc.h> +#include <grpc/support/time.h> #include <gflags/gflags.h> #include "qps_worker.h" @@ -47,7 +48,7 @@ DEFINE_int32(server_port, 0, "Spawned server port."); static bool got_sigint = false; -static void sigint_handler(int x) {got_sigint = true;} +static void sigint_handler(int x) { got_sigint = true; } namespace grpc { namespace testing { @@ -56,7 +57,7 @@ static void RunServer() { QpsWorker worker(FLAGS_driver_port, FLAGS_server_port); while (!got_sigint) { - std::this_thread::sleep_for(std::chrono::seconds(5)); + gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5))); } } @@ -69,6 +70,6 @@ int main(int argc, char** argv) { signal(SIGINT, sigint_handler); grpc::testing::RunServer(); - + return 0; } diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc new file mode 100644 index 0000000000..5b3c1daf5d --- /dev/null +++ b/test/cpp/util/benchmark_config.cc @@ -0,0 +1,69 @@ +/* + * + * 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 <gflags/gflags.h> +#include "test/cpp/util/benchmark_config.h" + +DEFINE_bool(enable_log_reporter, true, + "Enable reporting of benchmark results through GprLog"); + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + +namespace grpc { +namespace testing { + +void InitBenchmark(int* argc, char*** argv, bool remove_flags) { + ParseCommandLineFlags(argc, argv, remove_flags); +} + +static std::shared_ptr<Reporter> InitBenchmarkReporters() { + auto* composite_reporter = new CompositeReporter; + if (FLAGS_enable_log_reporter) { + composite_reporter->add( + std::unique_ptr<Reporter>(new GprLogReporter("LogReporter"))); + } + return std::shared_ptr<Reporter>(composite_reporter); +} + +std::shared_ptr<Reporter> GetReporter() { + static std::shared_ptr<Reporter> reporter(InitBenchmarkReporters()); + return reporter; +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/benchmark_config.h b/test/cpp/util/benchmark_config.h new file mode 100644 index 0000000000..6b308a15ff --- /dev/null +++ b/test/cpp/util/benchmark_config.h @@ -0,0 +1,57 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H +#define GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H + +#include <memory> +#include <vector> + +#include "test/cpp/qps/report.h" + +namespace grpc { +namespace testing { + +void InitBenchmark(int* argc, char*** argv, bool remove_flags); + +/** Returns the benchmark Reporter instance. + * + * The returned instance will take care of generating reports for all the actual + * reporters configured via the "enable_*_reporter" command line flags (see + * benchmark_config.cc). */ +std::shared_ptr<Reporter> GetReporter(); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H diff --git a/test/cpp/util/subprocess.cc b/test/cpp/util/subprocess.cc new file mode 100644 index 0000000000..d758f629ac --- /dev/null +++ b/test/cpp/util/subprocess.cc @@ -0,0 +1,59 @@ +/* + * + * 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/cpp/util/subprocess.h" + +#include <vector> + +#include <grpc/support/subprocess.h> + +namespace grpc { + +static gpr_subprocess *MakeProcess(std::initializer_list<std::string> args) { + std::vector<const char *> vargs; + for (auto it = args.begin(); it != args.end(); ++it) { + vargs.push_back(it->c_str()); + } + return gpr_subprocess_create(vargs.size(), &vargs[0]); +} + +SubProcess::SubProcess(std::initializer_list<std::string> args) + : subprocess_(MakeProcess(args)) {} + +SubProcess::~SubProcess() { gpr_subprocess_destroy(subprocess_); } + +int SubProcess::Join() { return gpr_subprocess_join(subprocess_); } + +void SubProcess::Interrupt() { gpr_subprocess_interrupt(subprocess_); } + +} // namespace grpc
\ No newline at end of file diff --git a/test/cpp/util/subprocess.h b/test/cpp/util/subprocess.h new file mode 100644 index 0000000000..8fafe3d177 --- /dev/null +++ b/test/cpp/util/subprocess.h @@ -0,0 +1,61 @@ +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_SUBPROCESS_H +#define GRPC_TEST_CPP_UTIL_SUBPROCESS_H + +#include <initializer_list> +#include <string> + +struct gpr_subprocess; + +namespace grpc { + +class SubProcess { + public: + SubProcess(std::initializer_list<std::string> args); + ~SubProcess(); + + int Join(); + void Interrupt(); + + private: + SubProcess(const SubProcess& other); + SubProcess& operator=(const SubProcess& other); + + gpr_subprocess* const subprocess_; +}; + +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_SUBPROCESS_H |