aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/build/c-ares.c43
-rw-r--r--test/core/bad_ssl/servers/cert.c8
-rw-r--r--test/core/channel/channel_stack_test.c2
-rw-r--r--test/core/client_channel/lb_policies_test.c4
-rw-r--r--test/core/client_channel/parse_address_test.c2
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_connectivity_test.c20
-rw-r--r--test/core/client_channel/resolvers/dns_resolver_test.c2
-rw-r--r--test/core/client_channel/resolvers/sockaddr_resolver_test.c2
-rw-r--r--test/core/client_channel/uri_fuzzer_test.c2
-rw-r--r--test/core/client_channel/uri_parser_test.c2
-rw-r--r--test/core/end2end/connection_refused_test.c2
-rw-r--r--test/core/end2end/end2end_nosec_tests.c16
-rw-r--r--test/core/end2end/end2end_tests.c16
-rw-r--r--test/core/end2end/fake_resolver.c6
-rw-r--r--test/core/end2end/fixtures/h2_census.c2
-rw-r--r--test/core/end2end/fixtures/h2_compress.c2
-rw-r--r--test/core/end2end/fixtures/h2_full+pipe.c2
-rw-r--r--test/core/end2end/fixtures/h2_full+trace.c2
-rw-r--r--test/core/end2end/fixtures/h2_full.c2
-rw-r--r--test/core/end2end/fixtures/h2_http_proxy.c2
-rw-r--r--test/core/end2end/fixtures/h2_load_reporting.c4
-rw-r--r--test/core/end2end/fixtures/h2_proxy.c2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair+trace.c2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair.c2
-rw-r--r--test/core/end2end/fixtures/h2_sockpair_1byte.c2
-rw-r--r--test/core/end2end/fixtures/h2_uds.c2
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c2
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568bin0 -> 128 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840bin0 -> 1883 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480bin0 -> 911 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240bin0 -> 252 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756bin0 -> 268 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53abin0 -> 229 bytes
-rw-r--r--test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368bin0 -> 58 bytes
-rwxr-xr-xtest/core/end2end/gen_build_yaml.py3
-rwxr-xr-xtest/core/end2end/generate_tests.bzl2
-rw-r--r--test/core/end2end/goaway_server_test.c30
-rw-r--r--test/core/end2end/tests/filter_causes_close.c15
-rw-r--r--test/core/end2end/tests/keepalive_timeout.c20
-rw-r--r--test/core/end2end/tests/load_reporting_hook.c4
-rw-r--r--test/core/end2end/tests/max_connection_age.c380
-rw-r--r--test/core/end2end/tests/max_connection_idle.c117
-rw-r--r--test/core/end2end/tests/ping.c18
-rw-r--r--test/core/handshake/BUILD12
-rw-r--r--test/core/handshake/client_ssl.c10
-rw-r--r--test/core/handshake/server_ssl.c8
-rw-r--r--test/core/http/httpcli_test.c4
-rw-r--r--test/core/http/httpscli_test.c4
-rwxr-xr-xtest/core/http/test_server.py4
-rw-r--r--test/core/iomgr/ev_epoll_linux_test.c148
-rw-r--r--test/core/iomgr/resource_quota_test.c52
-rw-r--r--test/core/iomgr/timer_heap_test.c21
-rw-r--r--test/core/iomgr/timer_list_test.c16
-rw-r--r--test/core/memory_usage/client.c5
-rw-r--r--test/core/nanopb/fuzzer_response.c2
-rw-r--r--test/core/nanopb/fuzzer_serverlist.c2
-rw-r--r--test/core/security/BUILD7
-rw-r--r--test/core/security/json_token_test.c2
-rw-r--r--test/core/security/jwt_verifier_test.c2
-rw-r--r--test/core/security/secure_endpoint_test.c2
-rw-r--r--test/core/security/security_connector_test.c4
-rw-r--r--test/core/slice/BUILD7
-rw-r--r--test/core/slice/b64_test.c (renamed from test/core/security/b64_test.c)2
-rw-r--r--test/core/support/arena_test.c8
-rw-r--r--test/core/support/time_test.c18
-rw-r--r--test/core/surface/channel_create_test.c2
-rw-r--r--test/core/surface/secure_channel_create_test.c2
-rw-r--r--test/core/surface/server_chttp2_test.c2
-rw-r--r--test/core/tsi/transport_security_test.c6
-rw-r--r--test/core/util/BUILD2
-rw-r--r--test/core/util/debugger_macros.c2
-rw-r--r--test/cpp/common/BUILD24
-rw-r--r--test/cpp/common/channel_arguments_test.cc16
-rw-r--r--test/cpp/end2end/async_end2end_test.cc319
-rw-r--r--test/cpp/end2end/end2end_test.cc85
-rw-r--r--test/cpp/end2end/filter_end2end_test.cc5
-rw-r--r--test/cpp/end2end/mock_test.cc2
-rw-r--r--test/cpp/end2end/test_service_impl.cc22
-rw-r--r--test/cpp/end2end/test_service_impl.h2
-rw-r--r--test/cpp/grpclb/grpclb_api_test.cc2
-rw-r--r--test/cpp/grpclb/grpclb_test.cc2
-rw-r--r--test/cpp/microbenchmarks/BUILD93
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc28
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_hpack.cc163
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_transport.cc81
-rw-r--r--test/cpp/microbenchmarks/bm_closure.cc3
-rw-r--r--test/cpp/microbenchmarks/bm_cq.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_error.cc2
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc194
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc3
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_trickle.cc2
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc3
-rw-r--r--test/cpp/microbenchmarks/bm_metadata.cc17
-rw-r--r--test/cpp/microbenchmarks/helpers.h2
-rw-r--r--test/cpp/microbenchmarks/noop-benchmark.cc2
-rw-r--r--test/cpp/qps/BUILD194
-rw-r--r--test/cpp/qps/benchmark_config.cc (renamed from test/cpp/util/benchmark_config.cc)2
-rw-r--r--test/cpp/qps/benchmark_config.h (renamed from test/cpp/util/benchmark_config.h)0
-rw-r--r--test/cpp/qps/client_async.cc132
-rw-r--r--test/cpp/qps/client_sync.cc18
-rw-r--r--test/cpp/qps/qps_json_driver.cc2
-rw-r--r--test/cpp/qps/qps_openloop_test.cc2
-rw-r--r--test/cpp/qps/qps_test.cc2
-rw-r--r--test/cpp/qps/secure_sync_unary_ping_pong_test.cc2
-rw-r--r--test/cpp/qps/server_async.cc13
105 files changed, 2268 insertions, 285 deletions
diff --git a/test/build/c-ares.c b/test/build/c-ares.c
new file mode 100644
index 0000000000..c954e9397f
--- /dev/null
+++ b/test/build/c-ares.c
@@ -0,0 +1,43 @@
+/*
+ *
+ * Copyright 2016, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <ares.h>
+
+int main(void) {
+ ares_channel channelptr;
+
+ ares_init(&channelptr);
+ ares_destroy(channelptr);
+
+ return 0;
+}
diff --git a/test/core/bad_ssl/servers/cert.c b/test/core/bad_ssl/servers/cert.c
index 9aadf452e2..2b014b2343 100644
--- a/test/core/bad_ssl/servers/cert.c
+++ b/test/core/bad_ssl/servers/cert.c
@@ -56,11 +56,11 @@ int main(int argc, char **argv) {
grpc_init();
GPR_ASSERT(GRPC_LOG_IF_ERROR(
- "load_file", grpc_load_file("src/core/lib/tsi/test_creds/badserver.pem",
- 1, &cert_slice)));
+ "load_file",
+ grpc_load_file("src/core/tsi/test_creds/badserver.pem", 1, &cert_slice)));
GPR_ASSERT(GRPC_LOG_IF_ERROR(
- "load_file", grpc_load_file("src/core/lib/tsi/test_creds/badserver.key",
- 1, &key_slice)));
+ "load_file",
+ grpc_load_file("src/core/tsi/test_creds/badserver.key", 1, &key_slice)));
pem_key_cert_pair.private_key = (const char *)GRPC_SLICE_START_PTR(key_slice);
pem_key_cert_pair.cert_chain = (const char *)GRPC_SLICE_START_PTR(cert_slice);
diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c
index af551c4928..4be89c78b5 100644
--- a/test/core/channel/channel_stack_test.c
+++ b/test/core/channel/channel_stack_test.c
@@ -73,7 +73,7 @@ static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
}
static void call_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
- grpc_transport_stream_op *op) {
+ grpc_transport_stream_op_batch *op) {
++*(int *)(elem->call_data);
}
diff --git a/test/core/client_channel/lb_policies_test.c b/test/core/client_channel/lb_policies_test.c
index 057b90ec84..e03492f80e 100644
--- a/test/core/client_channel/lb_policies_test.c
+++ b/test/core/client_channel/lb_policies_test.c
@@ -41,8 +41,8 @@
#include <grpc/support/string_util.h>
#include <grpc/support/time.h>
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/client_channel/lb_policy_registry.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/lb_policy_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/support/string.h"
diff --git a/test/core/client_channel/parse_address_test.c b/test/core/client_channel/parse_address_test.c
index 37dd0fba52..629cdb001f 100644
--- a/test/core/client_channel/parse_address_test.c
+++ b/test/core/client_channel/parse_address_test.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/ext/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include <string.h>
diff --git a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index b85ca89337..8e15faa1dd 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -36,8 +36,8 @@
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
-#include "src/core/ext/client_channel/resolver.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/combiner.h"
#include "src/core/lib/iomgr/resolve_address.h"
@@ -48,22 +48,26 @@ static gpr_mu g_mu;
static bool g_fail_resolution = true;
static grpc_combiner *g_combiner;
-static grpc_error *my_resolve_address(const char *name, const char *addr,
- grpc_resolved_addresses **addrs) {
+static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
+ const char *default_port,
+ grpc_pollset_set *interested_parties,
+ grpc_closure *on_done,
+ grpc_resolved_addresses **addrs) {
gpr_mu_lock(&g_mu);
- GPR_ASSERT(0 == strcmp("test", name));
+ GPR_ASSERT(0 == strcmp("test", addr));
+ grpc_error *error = GRPC_ERROR_NONE;
if (g_fail_resolution) {
g_fail_resolution = false;
gpr_mu_unlock(&g_mu);
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
gpr_mu_unlock(&g_mu);
*addrs = gpr_malloc(sizeof(**addrs));
(*addrs)->naddrs = 1;
(*addrs)->addrs = gpr_malloc(sizeof(*(*addrs)->addrs));
(*addrs)->addrs[0].len = 123;
- return GRPC_ERROR_NONE;
}
+ grpc_closure_sched(exec_ctx, on_done, error);
}
static grpc_resolver *create_resolver(grpc_exec_ctx *exec_ctx,
@@ -135,7 +139,7 @@ int main(int argc, char **argv) {
grpc_init();
gpr_mu_init(&g_mu);
g_combiner = grpc_combiner_create(NULL);
- grpc_blocking_resolve_address = my_resolve_address;
+ grpc_resolve_address = my_resolve_address;
grpc_channel_args *result = (grpc_channel_args *)1;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
diff --git a/test/core/client_channel/resolvers/dns_resolver_test.c b/test/core/client_channel/resolvers/dns_resolver_test.c
index 919a85d58f..fa7857d418 100644
--- a/test/core/client_channel/resolvers/dns_resolver_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_test.c
@@ -35,7 +35,7 @@
#include <grpc/support/log.h>
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/iomgr/combiner.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/client_channel/resolvers/sockaddr_resolver_test.c b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
index bc4f02c339..847eabae3b 100644
--- a/test/core/client_channel/resolvers/sockaddr_resolver_test.c
+++ b/test/core/client_channel/resolvers/sockaddr_resolver_test.c
@@ -37,7 +37,7 @@
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/combiner.h"
diff --git a/test/core/client_channel/uri_fuzzer_test.c b/test/core/client_channel/uri_fuzzer_test.c
index baadd4fc65..51da7f9988 100644
--- a/test/core/client_channel/uri_fuzzer_test.c
+++ b/test/core/client_channel/uri_fuzzer_test.c
@@ -37,7 +37,7 @@
#include <grpc/support/alloc.h>
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
#include "src/core/lib/iomgr/exec_ctx.h"
bool squelch = true;
diff --git a/test/core/client_channel/uri_parser_test.c b/test/core/client_channel/uri_parser_test.c
index 8a127f72eb..9fd0dd07f0 100644
--- a/test/core/client_channel/uri_parser_test.c
+++ b/test/core/client_channel/uri_parser_test.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/ext/client_channel/uri_parser.h"
+#include "src/core/ext/filters/client_channel/uri_parser.h"
#include <string.h>
diff --git a/test/core/end2end/connection_refused_test.c b/test/core/end2end/connection_refused_test.c
index 16a3005539..6ded12ad48 100644
--- a/test/core/end2end/connection_refused_test.c
+++ b/test/core/end2end/connection_refused_test.c
@@ -53,7 +53,6 @@ static void *tag(intptr_t i) { return (void *)i; }
static void run_test(bool wait_for_ready, bool use_service_config) {
grpc_channel *chan;
grpc_call *call;
- gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
grpc_completion_queue *cq;
cq_verifier *cqv;
grpc_op ops[6];
@@ -98,6 +97,7 @@ static void run_test(bool wait_for_ready, bool use_service_config) {
gpr_log(GPR_INFO, "server: %s", addr);
chan = grpc_insecure_channel_create(addr, args, NULL);
grpc_slice host = grpc_slice_from_static_string("nonexistant");
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2);
call = grpc_channel_create_call(
chan, NULL, GRPC_PROPAGATE_DEFAULTS, cq,
grpc_slice_from_static_string("/service/method"), &host, deadline, NULL);
diff --git a/test/core/end2end/end2end_nosec_tests.c b/test/core/end2end/end2end_nosec_tests.c
index b351bdee27..64bdceb211 100644
--- a/test/core/end2end/end2end_nosec_tests.c
+++ b/test/core/end2end/end2end_nosec_tests.c
@@ -97,6 +97,10 @@ extern void load_reporting_hook(grpc_end2end_test_config config);
extern void load_reporting_hook_pre_init(void);
extern void max_concurrent_streams(grpc_end2end_test_config config);
extern void max_concurrent_streams_pre_init(void);
+extern void max_connection_age(grpc_end2end_test_config config);
+extern void max_connection_age_pre_init(void);
+extern void max_connection_idle(grpc_end2end_test_config config);
+extern void max_connection_idle_pre_init(void);
extern void max_message_length(grpc_end2end_test_config config);
extern void max_message_length_pre_init(void);
extern void negative_deadline(grpc_end2end_test_config config);
@@ -174,6 +178,8 @@ void grpc_end2end_tests_pre_init(void) {
large_metadata_pre_init();
load_reporting_hook_pre_init();
max_concurrent_streams_pre_init();
+ max_connection_age_pre_init();
+ max_connection_idle_pre_init();
max_message_length_pre_init();
negative_deadline_pre_init();
network_status_change_pre_init();
@@ -232,6 +238,8 @@ void grpc_end2end_tests(int argc, char **argv,
large_metadata(config);
load_reporting_hook(config);
max_concurrent_streams(config);
+ max_connection_age(config);
+ max_connection_idle(config);
max_message_length(config);
negative_deadline(config);
network_status_change(config);
@@ -363,6 +371,14 @@ void grpc_end2end_tests(int argc, char **argv,
max_concurrent_streams(config);
continue;
}
+ if (0 == strcmp("max_connection_age", argv[i])) {
+ max_connection_age(config);
+ continue;
+ }
+ if (0 == strcmp("max_connection_idle", argv[i])) {
+ max_connection_idle(config);
+ continue;
+ }
if (0 == strcmp("max_message_length", argv[i])) {
max_message_length(config);
continue;
diff --git a/test/core/end2end/end2end_tests.c b/test/core/end2end/end2end_tests.c
index 199c09ec96..37c1be4133 100644
--- a/test/core/end2end/end2end_tests.c
+++ b/test/core/end2end/end2end_tests.c
@@ -99,6 +99,10 @@ extern void load_reporting_hook(grpc_end2end_test_config config);
extern void load_reporting_hook_pre_init(void);
extern void max_concurrent_streams(grpc_end2end_test_config config);
extern void max_concurrent_streams_pre_init(void);
+extern void max_connection_age(grpc_end2end_test_config config);
+extern void max_connection_age_pre_init(void);
+extern void max_connection_idle(grpc_end2end_test_config config);
+extern void max_connection_idle_pre_init(void);
extern void max_message_length(grpc_end2end_test_config config);
extern void max_message_length_pre_init(void);
extern void negative_deadline(grpc_end2end_test_config config);
@@ -177,6 +181,8 @@ void grpc_end2end_tests_pre_init(void) {
large_metadata_pre_init();
load_reporting_hook_pre_init();
max_concurrent_streams_pre_init();
+ max_connection_age_pre_init();
+ max_connection_idle_pre_init();
max_message_length_pre_init();
negative_deadline_pre_init();
network_status_change_pre_init();
@@ -236,6 +242,8 @@ void grpc_end2end_tests(int argc, char **argv,
large_metadata(config);
load_reporting_hook(config);
max_concurrent_streams(config);
+ max_connection_age(config);
+ max_connection_idle(config);
max_message_length(config);
negative_deadline(config);
network_status_change(config);
@@ -371,6 +379,14 @@ void grpc_end2end_tests(int argc, char **argv,
max_concurrent_streams(config);
continue;
}
+ if (0 == strcmp("max_connection_age", argv[i])) {
+ max_connection_age(config);
+ continue;
+ }
+ if (0 == strcmp("max_connection_idle", argv[i])) {
+ max_connection_idle(config);
+ continue;
+ }
if (0 == strcmp("max_message_length", argv[i])) {
max_message_length(config);
continue;
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c
index 8a37531449..1c7dd1339c 100644
--- a/test/core/end2end/fake_resolver.c
+++ b/test/core/end2end/fake_resolver.c
@@ -42,9 +42,9 @@
#include <grpc/support/port_platform.h>
#include <grpc/support/string_util.h>
-#include "src/core/ext/client_channel/lb_policy_factory.h"
-#include "src/core/ext/client_channel/parse_address.h"
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/lb_policy_factory.h"
+#include "src/core/ext/filters/client_channel/parse_address.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/resolve_address.h"
#include "src/core/lib/iomgr/unix_sockets_posix.h"
diff --git a/test/core/end2end/fixtures/h2_census.c b/test/core/end2end/fixtures/h2_census.c
index 8e60123ed6..97b27b2496 100644
--- a/test/core/end2end/fixtures/h2_census.c
+++ b/test/core/end2end/fixtures/h2_census.c
@@ -41,7 +41,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_compress.c b/test/core/end2end/fixtures/h2_compress.c
index c01e45664b..8aec94d601 100644
--- a/test/core/end2end/fixtures/h2_compress.c
+++ b/test/core/end2end/fixtures/h2_compress.c
@@ -41,7 +41,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_full+pipe.c b/test/core/end2end/fixtures/h2_full+pipe.c
index c6013f3040..0191e59fc8 100644
--- a/test/core/end2end/fixtures/h2_full+pipe.c
+++ b/test/core/end2end/fixtures/h2_full+pipe.c
@@ -46,7 +46,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fixtures/h2_full+trace.c b/test/core/end2end/fixtures/h2_full+trace.c
index 01316376e0..9dbb27fc4b 100644
--- a/test/core/end2end/fixtures/h2_full+trace.c
+++ b/test/core/end2end/fixtures/h2_full+trace.c
@@ -46,7 +46,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fixtures/h2_full.c b/test/core/end2end/fixtures/h2_full.c
index 3399f1981e..49c62b3429 100644
--- a/test/core/end2end/fixtures/h2_full.c
+++ b/test/core/end2end/fixtures/h2_full.c
@@ -41,7 +41,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fixtures/h2_http_proxy.c b/test/core/end2end/fixtures/h2_http_proxy.c
index 55c65fa70e..62c435557d 100644
--- a/test/core/end2end/fixtures/h2_http_proxy.c
+++ b/test/core/end2end/fixtures/h2_http_proxy.c
@@ -42,7 +42,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fixtures/h2_load_reporting.c b/test/core/end2end/fixtures/h2_load_reporting.c
index 38321f34db..79f26ed2bc 100644
--- a/test/core/end2end/fixtures/h2_load_reporting.c
+++ b/test/core/end2end/fixtures/h2_load_reporting.c
@@ -41,8 +41,8 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_proxy.c b/test/core/end2end/fixtures/h2_proxy.c
index 9e37ed4db3..a10738fa0b 100644
--- a/test/core/end2end/fixtures/h2_proxy.c
+++ b/test/core/end2end/fixtures/h2_proxy.c
@@ -41,7 +41,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair+trace.c b/test/core/end2end/fixtures/h2_sockpair+trace.c
index edf42a4070..5ace922f05 100644
--- a/test/core/end2end/fixtures/h2_sockpair+trace.c
+++ b/test/core/end2end/fixtures/h2_sockpair+trace.c
@@ -45,7 +45,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/compress_filter.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair.c b/test/core/end2end/fixtures/h2_sockpair.c
index 94b2623b3e..3079a42dce 100644
--- a/test/core/end2end/fixtures/h2_sockpair.c
+++ b/test/core/end2end/fixtures/h2_sockpair.c
@@ -40,7 +40,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/compress_filter.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_sockpair_1byte.c b/test/core/end2end/fixtures/h2_sockpair_1byte.c
index 6f9cf8fe26..70410d75f4 100644
--- a/test/core/end2end/fixtures/h2_sockpair_1byte.c
+++ b/test/core/end2end/fixtures/h2_sockpair_1byte.c
@@ -40,7 +40,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/compress_filter.h"
#include "src/core/lib/channel/connected_channel.h"
diff --git a/test/core/end2end/fixtures/h2_uds.c b/test/core/end2end/fixtures/h2_uds.c
index bc973ea8e3..7bde69d82a 100644
--- a/test/core/end2end/fixtures/h2_uds.c
+++ b/test/core/end2end/fixtures/h2_uds.c
@@ -44,7 +44,7 @@
#include <grpc/support/sync.h>
#include <grpc/support/thd.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/channel/http_server_filter.h"
diff --git a/test/core/end2end/fuzzers/api_fuzzer.c b/test/core/end2end/fuzzers/api_fuzzer.c
index 9cc3f56437..a0acf5bf60 100644
--- a/test/core/end2end/fuzzers/api_fuzzer.c
+++ b/test/core/end2end/fuzzers/api_fuzzer.c
@@ -719,10 +719,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
grpc_test_only_set_slice_hash_seed(0);
if (squelch) gpr_set_log_function(dont_log);
input_stream inp = {data, data + size};
- grpc_resolve_address = my_resolve_address;
grpc_tcp_client_connect_impl = my_tcp_client_connect;
gpr_now_impl = now_impl;
grpc_init();
+ grpc_resolve_address = my_resolve_address;
GPR_ASSERT(g_channel == NULL);
GPR_ASSERT(g_server == NULL);
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568
new file mode 100644
index 0000000000..95a0b013c0
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5242554383597568
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840
new file mode 100644
index 0000000000..a58dc7b244
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-5965570207907840
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480
new file mode 100644
index 0000000000..139fc1cf3f
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6499902139924480
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240 b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240
new file mode 100644
index 0000000000..74f189b87f
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/clusterfuzz-testcase-6699208922890240
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756 b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756
new file mode 100644
index 0000000000..1460bc9fbf
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756
Binary files differ
diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a
new file mode 100644
index 0000000000..01428693cf
--- /dev/null
+++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53a
Binary files differ
diff --git a/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368 b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368
new file mode 100644
index 0000000000..f896b66adf
--- /dev/null
+++ b/test/core/end2end/fuzzers/server_fuzzer_corpus/clusterfuzz-testcase-5417405008314368
Binary files differ
diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py
index 0c749537e6..3c5068ff3e 100755
--- a/test/core/end2end/gen_build_yaml.py
+++ b/test/core/end2end/gen_build_yaml.py
@@ -122,6 +122,9 @@ END2END_TESTS = {
'keepalive_timeout': default_test_options._replace(proxyable=False),
'large_metadata': default_test_options,
'max_concurrent_streams': default_test_options._replace(proxyable=False),
+ 'max_connection_age': default_test_options,
+ 'max_connection_idle': connectivity_test_options._replace(
+ proxyable=False, exclude_iomgrs=['uv']),
'max_message_length': default_test_options,
'negative_deadline': default_test_options,
'network_status_change': default_test_options,
diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl
index 431c6995ba..1041219f03 100755
--- a/test/core/end2end/generate_tests.bzl
+++ b/test/core/end2end/generate_tests.bzl
@@ -109,6 +109,8 @@ END2END_TESTS = {
'keepalive_timeout': test_options(proxyable=False),
'large_metadata': test_options(),
'max_concurrent_streams': test_options(proxyable=False),
+ 'max_connection_age': test_options(),
+ 'max_connection_idle': test_options(needs_fullstack=True, proxyable=False),
'max_message_length': test_options(),
'negative_deadline': test_options(),
'network_status_change': test_options(),
diff --git a/test/core/end2end/goaway_server_test.c b/test/core/end2end/goaway_server_test.c
index 4bb258e3ed..22d93b321a 100644
--- a/test/core/end2end/goaway_server_test.c
+++ b/test/core/end2end/goaway_server_test.c
@@ -52,9 +52,11 @@ static void *tag(intptr_t i) { return (void *)i; }
static gpr_mu g_mu;
static int g_resolve_port = -1;
-static grpc_error *(*iomgr_resolve_address)(const char *name,
- const char *default_port,
- grpc_resolved_addresses **addrs);
+static void (*iomgr_resolve_address)(grpc_exec_ctx *exec_ctx, const char *addr,
+ const char *default_port,
+ grpc_pollset_set *interested_parties,
+ grpc_closure *on_done,
+ grpc_resolved_addresses **addresses);
static void set_resolve_port(int port) {
gpr_mu_lock(&g_mu);
@@ -62,16 +64,22 @@ static void set_resolve_port(int port) {
gpr_mu_unlock(&g_mu);
}
-static grpc_error *my_resolve_address(const char *name, const char *addr,
- grpc_resolved_addresses **addrs) {
- if (0 != strcmp(name, "test")) {
- return iomgr_resolve_address(name, addr, addrs);
+static void my_resolve_address(grpc_exec_ctx *exec_ctx, const char *addr,
+ const char *default_port,
+ grpc_pollset_set *interested_parties,
+ grpc_closure *on_done,
+ grpc_resolved_addresses **addrs) {
+ if (0 != strcmp(addr, "test")) {
+ iomgr_resolve_address(exec_ctx, addr, default_port, interested_parties,
+ on_done, addrs);
+ return;
}
+ grpc_error *error = GRPC_ERROR_NONE;
gpr_mu_lock(&g_mu);
if (g_resolve_port < 0) {
gpr_mu_unlock(&g_mu);
- return GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
+ error = GRPC_ERROR_CREATE_FROM_STATIC_STRING("Forced Failure");
} else {
*addrs = gpr_malloc(sizeof(**addrs));
(*addrs)->naddrs = 1;
@@ -83,8 +91,8 @@ static grpc_error *my_resolve_address(const char *name, const char *addr,
sa->sin_port = htons((uint16_t)g_resolve_port);
(*addrs)->addrs[0].len = sizeof(*sa);
gpr_mu_unlock(&g_mu);
- return GRPC_ERROR_NONE;
}
+ grpc_closure_sched(exec_ctx, on_done, error);
}
int main(int argc, char **argv) {
@@ -96,9 +104,9 @@ int main(int argc, char **argv) {
grpc_test_init(argc, argv);
gpr_mu_init(&g_mu);
- iomgr_resolve_address = grpc_blocking_resolve_address;
- grpc_blocking_resolve_address = my_resolve_address;
grpc_init();
+ iomgr_resolve_address = grpc_resolve_address;
+ grpc_resolve_address = my_resolve_address;
int was_cancelled1;
int was_cancelled2;
diff --git a/test/core/end2end/tests/filter_causes_close.c b/test/core/end2end/tests/filter_causes_close.c
index e6b02eaeee..62bf20809c 100644
--- a/test/core/end2end/tests/filter_causes_close.c
+++ b/test/core/end2end/tests/filter_causes_close.c
@@ -216,13 +216,14 @@ static void recv_im_ready(grpc_exec_ctx *exec_ctx, void *arg,
GRPC_STATUS_PERMISSION_DENIED));
}
-static void start_transport_stream_op(grpc_exec_ctx *exec_ctx,
- grpc_call_element *elem,
- grpc_transport_stream_op *op) {
+static void start_transport_stream_op_batch(
+ grpc_exec_ctx *exec_ctx, grpc_call_element *elem,
+ grpc_transport_stream_op_batch *op) {
call_data *calld = elem->call_data;
- if (op->recv_initial_metadata != NULL) {
- calld->recv_im_ready = op->recv_initial_metadata_ready;
- op->recv_initial_metadata_ready =
+ if (op->recv_initial_metadata) {
+ calld->recv_im_ready =
+ op->payload->recv_initial_metadata.recv_initial_metadata_ready;
+ op->payload->recv_initial_metadata.recv_initial_metadata_ready =
grpc_closure_create(recv_im_ready, elem, grpc_schedule_on_exec_ctx);
}
grpc_call_next_op(exec_ctx, elem, op);
@@ -248,7 +249,7 @@ static void destroy_channel_elem(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem) {}
static const grpc_channel_filter test_filter = {
- start_transport_stream_op,
+ start_transport_stream_op_batch,
grpc_channel_next_op,
sizeof(call_data),
init_call_elem,
diff --git a/test/core/end2end/tests/keepalive_timeout.c b/test/core/end2end/tests/keepalive_timeout.c
index 4296be3619..44b6e12abc 100644
--- a/test/core/end2end/tests/keepalive_timeout.c
+++ b/test/core/end2end/tests/keepalive_timeout.c
@@ -41,6 +41,7 @@
#include <grpc/support/log.h>
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
+#include "src/core/ext/transport/chttp2/transport/frame_ping.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/iomgr/exec_ctx.h"
#include "src/core/lib/support/env.h"
@@ -109,13 +110,15 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
grpc_raw_byte_buffer_create(&response_payload_slice, 1);
gpr_timespec deadline = five_seconds_time();
- grpc_arg keepalive_args[2];
- keepalive_args[0].type = GRPC_ARG_INTEGER;
- keepalive_args[0].key = GRPC_ARG_HTTP2_KEEPALIVE_TIME;
- keepalive_args[0].value.integer = 2;
- keepalive_args[1].type = GRPC_ARG_INTEGER;
- keepalive_args[1].key = GRPC_ARG_HTTP2_KEEPALIVE_TIMEOUT;
- keepalive_args[1].value.integer = 0;
+ grpc_arg keepalive_args[] = {{.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_CLIENT_KEEPALIVE_TIME_S,
+ .value.integer = 2},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_CLIENT_KEEPALIVE_TIMEOUT_S,
+ .value.integer = 0},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_HTTP2_BDP_PROBE,
+ .value.integer = 1}};
grpc_channel_args *client_args = NULL;
client_args = grpc_channel_args_copy_and_add(client_args, keepalive_args, 2);
@@ -134,6 +137,9 @@ static void test_keepalive_timeout(grpc_end2end_test_config config) {
grpc_call_error error;
grpc_slice details;
+ /* Disable ping ack to trigger the keepalive timeout */
+ grpc_set_disable_ping_ack(true);
+
c = grpc_channel_create_call(
f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
grpc_slice_from_static_string("/foo"),
diff --git a/test/core/end2end/tests/load_reporting_hook.c b/test/core/end2end/tests/load_reporting_hook.c
index d1ee26fe50..fd3d9163d0 100644
--- a/test/core/end2end/tests/load_reporting_hook.c
+++ b/test/core/end2end/tests/load_reporting_hook.c
@@ -41,8 +41,8 @@
#include <grpc/support/time.h>
#include <grpc/support/useful.h>
-#include "src/core/ext/load_reporting/load_reporting.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/load_reporting/load_reporting.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/transport/static_metadata.h"
diff --git a/test/core/end2end/tests/max_connection_age.c b/test/core/end2end/tests/max_connection_age.c
new file mode 100644
index 0000000000..59bfdbabb9
--- /dev/null
+++ b/test/core/end2end/tests/max_connection_age.c
@@ -0,0 +1,380 @@
+/*
+ *
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+#define MAX_CONNECTION_AGE_MS 500
+#define MAX_CONNECTION_AGE_GRACE_MS 1000
+#define MAX_CONNECTION_IDLE_MS 9999
+
+#define CALL_DEADLINE_S 10
+/* The amount of time we wait for the connection to time out, but after it the
+ connection should not use up its grace period. It should be a number between
+ MAX_CONNECTION_AGE_MS and MAX_CONNECTION_AGE_MS +
+ MAX_CONNECTION_AGE_GRACE_MS */
+#define CQ_MAX_CONNECTION_AGE_WAIT_TIME_S 1
+/* The amount of time we wait after the connection reaches its max age, it
+ should be shorter than CALL_DEADLINE_S - CQ_MAX_CONNECTION_AGE_WAIT_TIME_S */
+#define CQ_MAX_CONNECTION_AGE_GRACE_WAIT_TIME_S 2
+/* The grace period for the test to observe the channel shutdown process */
+#define IMMEDIATE_SHUTDOWN_GRACE_TIME_MS 3000
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static void drain_cq(grpc_completion_queue *cq) {
+ grpc_event ev;
+ do {
+ ev = grpc_completion_queue_next(cq, grpc_timeout_seconds_to_deadline(5),
+ NULL);
+ } while (ev.type != GRPC_QUEUE_SHUTDOWN);
+}
+
+static void shutdown_server(grpc_end2end_test_fixture *f) {
+ if (!f->server) return;
+ grpc_server_destroy(f->server);
+ f->server = NULL;
+}
+
+static void shutdown_client(grpc_end2end_test_fixture *f) {
+ if (!f->client) return;
+ grpc_channel_destroy(f->client);
+ f->client = NULL;
+}
+
+static void end_test(grpc_end2end_test_fixture *f) {
+ shutdown_server(f);
+ shutdown_client(f);
+
+ grpc_completion_queue_shutdown(f->cq);
+ drain_cq(f->cq);
+ grpc_completion_queue_destroy(f->cq);
+}
+
+static void test_max_age_forcibly_close(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+ cq_verifier *cqv = cq_verifier_create(f.cq);
+ grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+ .value.integer = MAX_CONNECTION_AGE_MS},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
+ .value.integer = MAX_CONNECTION_AGE_GRACE_MS},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+ .value.integer = MAX_CONNECTION_IDLE_MS}};
+ grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+ .args = server_a};
+
+ config.init_client(&f, NULL);
+ config.init_server(&f, &server_args);
+
+ grpc_call *c;
+ grpc_call *s;
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(CALL_DEADLINE_S);
+ grpc_op ops[6];
+ grpc_op *op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+
+ c = grpc_channel_create_call(
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ NULL);
+ GPR_ASSERT(c);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->data.send_initial_metadata.metadata = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ gpr_timespec expect_shutdown_time = grpc_timeout_milliseconds_to_deadline(
+ MAX_CONNECTION_AGE_MS + MAX_CONNECTION_AGE_GRACE_MS +
+ IMMEDIATE_SHUTDOWN_GRACE_TIME_MS);
+
+ /* Wait for the channel to reach its max age */
+ cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_WAIT_TIME_S);
+
+ /* After the channel reaches its max age, we still do nothing here. And wait
+ for it to use up its max age grace period. */
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ gpr_timespec channel_shutdown_time = gpr_now(GPR_CLOCK_MONOTONIC);
+ GPR_ASSERT(gpr_time_cmp(channel_shutdown_time, expect_shutdown_time) < 0);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ cq_verify(cqv);
+
+ grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+ CQ_EXPECT_COMPLETION(cqv, tag(0xdead), true);
+ cq_verify(cqv);
+
+ grpc_call_destroy(s);
+
+ /* The connection should be closed immediately after the max age grace period,
+ the in-progress RPC should fail. */
+ GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "Endpoint read failed"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_destroy(c);
+ cq_verifier_destroy(cqv);
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+static void test_max_age_gracefully_close(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+ cq_verifier *cqv = cq_verifier_create(f.cq);
+ grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+ .value.integer = MAX_CONNECTION_AGE_MS},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_AGE_GRACE_MS,
+ .value.integer = INT_MAX},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+ .value.integer = MAX_CONNECTION_IDLE_MS}};
+ grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+ .args = server_a};
+
+ config.init_client(&f, NULL);
+ config.init_server(&f, &server_args);
+
+ grpc_call *c;
+ grpc_call *s;
+ gpr_timespec deadline = grpc_timeout_seconds_to_deadline(CALL_DEADLINE_S);
+ grpc_op ops[6];
+ grpc_op *op;
+ grpc_metadata_array initial_metadata_recv;
+ grpc_metadata_array trailing_metadata_recv;
+ grpc_metadata_array request_metadata_recv;
+ grpc_call_details call_details;
+ grpc_status_code status;
+ grpc_call_error error;
+ grpc_slice details;
+ int was_cancelled = 2;
+
+ c = grpc_channel_create_call(
+ f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
+ grpc_slice_from_static_string("/foo"),
+ get_host_override_slice("foo.test.google.fr:1234", config), deadline,
+ NULL);
+ GPR_ASSERT(c);
+
+ grpc_metadata_array_init(&initial_metadata_recv);
+ grpc_metadata_array_init(&trailing_metadata_recv);
+ grpc_metadata_array_init(&request_metadata_recv);
+ grpc_call_details_init(&call_details);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->data.send_initial_metadata.metadata = NULL;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_INITIAL_METADATA;
+ op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
+ op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
+ op->data.recv_status_on_client.status = &status;
+ op->data.recv_status_on_client.status_details = &details;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ error =
+ grpc_server_request_call(f.server, &s, &call_details,
+ &request_metadata_recv, f.cq, f.cq, tag(101));
+ GPR_ASSERT(GRPC_CALL_OK == error);
+ CQ_EXPECT_COMPLETION(cqv, tag(101), true);
+ cq_verify(cqv);
+
+ /* Wait for the channel to reach its max age */
+ cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_WAIT_TIME_S);
+
+ /* The connection is shutting down gracefully. In-progress rpc should not be
+ closed, hence the completion queue should see nothing here. */
+ cq_verify_empty_timeout(cqv, CQ_MAX_CONNECTION_AGE_GRACE_WAIT_TIME_S);
+
+ memset(ops, 0, sizeof(ops));
+ op = ops;
+ op->op = GRPC_OP_SEND_INITIAL_METADATA;
+ op->data.send_initial_metadata.count = 0;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
+ op->data.send_status_from_server.trailing_metadata_count = 0;
+ op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
+ grpc_slice status_details = grpc_slice_from_static_string("xyz");
+ op->data.send_status_from_server.status_details = &status_details;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
+ op->data.recv_close_on_server.cancelled = &was_cancelled;
+ op->flags = 0;
+ op->reserved = NULL;
+ op++;
+ error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
+ GPR_ASSERT(GRPC_CALL_OK == error);
+
+ CQ_EXPECT_COMPLETION(cqv, tag(102), true);
+ CQ_EXPECT_COMPLETION(cqv, tag(1), true);
+ cq_verify(cqv);
+
+ grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+ CQ_EXPECT_COMPLETION(cqv, tag(0xdead), true);
+ cq_verify(cqv);
+
+ grpc_call_destroy(s);
+
+ /* The connection is closed gracefully with goaway, the rpc should still be
+ completed. */
+ GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED);
+ GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz"));
+ GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
+ validate_host_override_string("foo.test.google.fr:1234", call_details.host,
+ config);
+ GPR_ASSERT(was_cancelled == 1);
+
+ grpc_slice_unref(details);
+ grpc_metadata_array_destroy(&initial_metadata_recv);
+ grpc_metadata_array_destroy(&trailing_metadata_recv);
+ grpc_metadata_array_destroy(&request_metadata_recv);
+ grpc_call_details_destroy(&call_details);
+ grpc_call_destroy(c);
+ cq_verifier_destroy(cqv);
+ end_test(&f);
+ config.tear_down_data(&f);
+}
+
+void max_connection_age(grpc_end2end_test_config config) {
+ test_max_age_forcibly_close(config);
+ test_max_age_gracefully_close(config);
+}
+
+void max_connection_age_pre_init(void) {}
diff --git a/test/core/end2end/tests/max_connection_idle.c b/test/core/end2end/tests/max_connection_idle.c
new file mode 100644
index 0000000000..c0984e4d14
--- /dev/null
+++ b/test/core/end2end/tests/max_connection_idle.c
@@ -0,0 +1,117 @@
+/*
+ *
+ * Copyright 2017, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/end2end/end2end_tests.h"
+
+#include <limits.h>
+#include <string.h>
+
+#include <grpc/support/log.h>
+#include <grpc/support/sync.h>
+#include <grpc/support/time.h>
+#include <grpc/support/useful.h>
+
+#include "test/core/end2end/cq_verifier.h"
+
+#define MAX_CONNECTION_IDLE_MS 500
+#define MAX_CONNECTION_AGE_MS 9999
+
+static void *tag(intptr_t t) { return (void *)t; }
+
+static void test_max_connection_idle(grpc_end2end_test_config config) {
+ grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
+ grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
+ cq_verifier *cqv = cq_verifier_create(f.cq);
+
+ grpc_arg client_a[] = {{.type = GRPC_ARG_INTEGER,
+ .key = "grpc.testing.fixed_reconnect_backoff_ms",
+ .value.integer = 1000}};
+ grpc_arg server_a[] = {{.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_IDLE_MS,
+ .value.integer = MAX_CONNECTION_IDLE_MS},
+ {.type = GRPC_ARG_INTEGER,
+ .key = GRPC_ARG_MAX_CONNECTION_AGE_MS,
+ .value.integer = MAX_CONNECTION_AGE_MS}};
+ grpc_channel_args client_args = {.num_args = GPR_ARRAY_SIZE(client_a),
+ .args = client_a};
+ grpc_channel_args server_args = {.num_args = GPR_ARRAY_SIZE(server_a),
+ .args = server_a};
+
+ config.init_client(&f, &client_args);
+ config.init_server(&f, &server_args);
+
+ /* check that we're still in idle, and start connecting */
+ GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
+ GRPC_CHANNEL_IDLE);
+ /* we'll go through some set of transitions (some might be missed), until
+ READY is reached */
+ while (state != GRPC_CHANNEL_READY) {
+ grpc_channel_watch_connectivity_state(
+ f.client, state, grpc_timeout_seconds_to_deadline(3), f.cq, tag(99));
+ CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
+ cq_verify(cqv);
+ state = grpc_channel_check_connectivity_state(f.client, 0);
+ GPR_ASSERT(state == GRPC_CHANNEL_READY ||
+ state == GRPC_CHANNEL_CONNECTING ||
+ state == GRPC_CHANNEL_TRANSIENT_FAILURE);
+ }
+
+ /* wait for the channel to reach its maximum idle time */
+ grpc_channel_watch_connectivity_state(
+ f.client, GRPC_CHANNEL_READY,
+ grpc_timeout_milliseconds_to_deadline(MAX_CONNECTION_IDLE_MS + 3000),
+ f.cq, tag(99));
+ CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
+ cq_verify(cqv);
+ state = grpc_channel_check_connectivity_state(f.client, 0);
+ GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
+ state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);
+
+ grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
+ CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
+ cq_verify(cqv);
+
+ grpc_server_destroy(f.server);
+ grpc_channel_destroy(f.client);
+ grpc_completion_queue_shutdown(f.cq);
+ grpc_completion_queue_destroy(f.cq);
+ config.tear_down_data(&f);
+
+ cq_verifier_destroy(cqv);
+}
+
+void max_connection_idle(grpc_end2end_test_config config) {
+ test_max_connection_idle(config);
+}
+
+void max_connection_idle_pre_init(void) {}
diff --git a/test/core/end2end/tests/ping.c b/test/core/end2end/tests/ping.c
index f5bfac2255..082ac641f0 100644
--- a/test/core/end2end/tests/ping.c
+++ b/test/core/end2end/tests/ping.c
@@ -41,9 +41,12 @@
#include "test/core/end2end/cq_verifier.h"
+#define PING_NUM 5
+
static void *tag(intptr_t t) { return (void *)t; }
-static void test_ping(grpc_end2end_test_config config) {
+static void test_ping(grpc_end2end_test_config config,
+ int min_time_between_pings_ms) {
grpc_end2end_test_fixture f = config.create_fixture(NULL, NULL);
cq_verifier *cqv = cq_verifier_create(f.cq);
grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
@@ -51,7 +54,7 @@ static void test_ping(grpc_end2end_test_config config) {
grpc_arg a[] = {{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MIN_TIME_BETWEEN_PINGS_MS,
- .value.integer = 0},
+ .value.integer = min_time_between_pings_ms},
{.type = GRPC_ARG_INTEGER,
.key = GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA,
.value.integer = 20}};
@@ -70,7 +73,11 @@ static void test_ping(grpc_end2end_test_config config) {
READY is reached */
while (state != GRPC_CHANNEL_READY) {
grpc_channel_watch_connectivity_state(
- f.client, state, grpc_timeout_seconds_to_deadline(3), f.cq, tag(99));
+ f.client, state,
+ gpr_time_add(grpc_timeout_seconds_to_deadline(3),
+ gpr_time_from_millis(min_time_between_pings_ms * PING_NUM,
+ GPR_TIMESPAN)),
+ f.cq, tag(99));
CQ_EXPECT_COMPLETION(cqv, tag(99), 1);
cq_verify(cqv);
state = grpc_channel_check_connectivity_state(f.client, 0);
@@ -79,7 +86,7 @@ static void test_ping(grpc_end2end_test_config config) {
state == GRPC_CHANNEL_TRANSIENT_FAILURE);
}
- for (i = 1; i <= 5; i++) {
+ for (i = 1; i <= PING_NUM; i++) {
grpc_channel_ping(f.client, f.cq, tag(i), NULL);
CQ_EXPECT_COMPLETION(cqv, tag(i), 1);
cq_verify(cqv);
@@ -102,7 +109,8 @@ static void test_ping(grpc_end2end_test_config config) {
void ping(grpc_end2end_test_config config) {
GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
- test_ping(config);
+ test_ping(config, 0);
+ test_ping(config, 100);
}
void ping_pre_init(void) {}
diff --git a/test/core/handshake/BUILD b/test/core/handshake/BUILD
index eb8f3a9beb..996b503d35 100644
--- a/test/core/handshake/BUILD
+++ b/test/core/handshake/BUILD
@@ -34,9 +34,9 @@ cc_test(
srcs = ["client_ssl.c"],
copts = ["-std=c99"],
data = [
- "//src/core/lib/tsi/test_creds:ca.pem",
- "//src/core/lib/tsi/test_creds:server1.key",
- "//src/core/lib/tsi/test_creds:server1.pem",
+ "//src/core/tsi/test_creds:ca.pem",
+ "//src/core/tsi/test_creds:server1.key",
+ "//src/core/tsi/test_creds:server1.pem",
],
deps = [
"//:gpr",
@@ -51,9 +51,9 @@ cc_test(
srcs = ["server_ssl.c"],
copts = ["-std=c99"],
data = [
- "//src/core/lib/tsi/test_creds:ca.pem",
- "//src/core/lib/tsi/test_creds:server1.key",
- "//src/core/lib/tsi/test_creds:server1.pem",
+ "//src/core/tsi/test_creds:ca.pem",
+ "//src/core/tsi/test_creds:server1.key",
+ "//src/core/tsi/test_creds:server1.pem",
],
deps = [
"//:gpr",
diff --git a/test/core/handshake/client_ssl.c b/test/core/handshake/client_ssl.c
index 5cfe60de4b..f291d09493 100644
--- a/test/core/handshake/client_ssl.c
+++ b/test/core/handshake/client_ssl.c
@@ -54,9 +54,9 @@
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
+#define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem"
// Arguments for TLS server thread.
typedef struct {
@@ -146,7 +146,7 @@ static int alpn_select_cb(SSL *ssl, const uint8_t **out, uint8_t *out_len,
// Minimal TLS server. This is largely based on the example at
// https://wiki.openssl.org/index.php/Simple_TLS_Server and the gRPC core
-// internals in src/core/lib/tsi/ssl_transport_security.c.
+// internals in src/core/tsi/ssl_transport_security.c.
static void server_thread(void *arg) {
const server_args *args = (server_args *)arg;
@@ -172,7 +172,7 @@ static void server_thread(void *arg) {
}
// Set the cipher list to match the one expressed in
- // src/core/lib/tsi/ssl_transport_security.c.
+ // src/core/tsi/ssl_transport_security.c.
const char *cipher_list =
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
"SHA384:ECDHE-RSA-AES256-GCM-SHA384";
diff --git a/test/core/handshake/server_ssl.c b/test/core/handshake/server_ssl.c
index 0bd5a03cff..e568a37014 100644
--- a/test/core/handshake/server_ssl.c
+++ b/test/core/handshake/server_ssl.c
@@ -49,9 +49,9 @@
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-#define SSL_CERT_PATH "src/core/lib/tsi/test_creds/server1.pem"
-#define SSL_KEY_PATH "src/core/lib/tsi/test_creds/server1.key"
-#define SSL_CA_PATH "src/core/lib/tsi/test_creds/ca.pem"
+#define SSL_CERT_PATH "src/core/tsi/test_creds/server1.pem"
+#define SSL_KEY_PATH "src/core/tsi/test_creds/server1.key"
+#define SSL_CA_PATH "src/core/tsi/test_creds/ca.pem"
// Handshake completed signal to server thread.
static gpr_event client_handshake_complete;
@@ -174,7 +174,7 @@ static bool server_ssl_test(const char *alpn_list[], unsigned int alpn_list_len,
}
// Set the cipher list to match the one expressed in
- // src/core/lib/tsi/ssl_transport_security.c.
+ // src/core/tsi/ssl_transport_security.c.
const char *cipher_list =
"ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-"
"SHA384:ECDHE-RSA-AES256-GCM-SHA384";
diff --git a/test/core/http/httpcli_test.c b/test/core/http/httpcli_test.c
index f690dbaffb..d3b45c4505 100644
--- a/test/core/http/httpcli_test.c
+++ b/test/core/http/httpcli_test.c
@@ -102,7 +102,7 @@ static void test_get(int port) {
"pollset_work",
grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
&worker, gpr_now(GPR_CLOCK_MONOTONIC),
- n_seconds_time(20))));
+ n_seconds_time(1))));
gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(g_mu);
@@ -144,7 +144,7 @@ static void test_post(int port) {
"pollset_work",
grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
&worker, gpr_now(GPR_CLOCK_MONOTONIC),
- n_seconds_time(20))));
+ n_seconds_time(1))));
gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(g_mu);
diff --git a/test/core/http/httpscli_test.c b/test/core/http/httpscli_test.c
index 549411037e..acc94091f4 100644
--- a/test/core/http/httpscli_test.c
+++ b/test/core/http/httpscli_test.c
@@ -103,7 +103,7 @@ static void test_get(int port) {
"pollset_work",
grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
&worker, gpr_now(GPR_CLOCK_MONOTONIC),
- n_seconds_time(20))));
+ n_seconds_time(1))));
gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(g_mu);
@@ -146,7 +146,7 @@ static void test_post(int port) {
"pollset_work",
grpc_pollset_work(&exec_ctx, grpc_polling_entity_pollset(&g_pops),
&worker, gpr_now(GPR_CLOCK_MONOTONIC),
- n_seconds_time(20))));
+ n_seconds_time(1))));
gpr_mu_unlock(g_mu);
grpc_exec_ctx_finish(&exec_ctx);
gpr_mu_lock(g_mu);
diff --git a/test/core/http/test_server.py b/test/core/http/test_server.py
index 86c2fe96bf..dbbf5ceb3c 100755
--- a/test/core/http/test_server.py
+++ b/test/core/http/test_server.py
@@ -36,8 +36,8 @@ import os
import ssl
import sys
-_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/lib/tsi/test_creds/server1.pem'))
-_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/lib/tsi/test_creds/server1.key'))
+_PEM = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.pem'))
+_KEY = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), '../../..', 'src/core/tsi/test_creds/server1.key'))
print _PEM
open(_PEM).close()
diff --git a/test/core/iomgr/ev_epoll_linux_test.c b/test/core/iomgr/ev_epoll_linux_test.c
index d69f9a9d15..5f8124aeda 100644
--- a/test/core/iomgr/ev_epoll_linux_test.c
+++ b/test/core/iomgr/ev_epoll_linux_test.c
@@ -43,6 +43,8 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
+#include <grpc/support/thd.h>
+#include <grpc/support/useful.h>
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/iomgr/workqueue.h"
@@ -139,23 +141,25 @@ static void increment(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
* polling_island_merge()[ev_epoll_linux.c], where the parent relationship was
* inverted.
*/
+
+#define NUM_FDS 2
+#define NUM_POLLSETS 2
+#define NUM_CLOSURES 4
+
static void test_pollset_queue_merge_items() {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- const int num_fds = 2;
- const int num_pollsets = 2;
- const int num_closures = 4;
- test_fd tfds[num_fds];
- int fds[num_fds];
- test_pollset pollsets[num_pollsets];
- grpc_closure closures[num_closures];
+ test_fd tfds[NUM_FDS];
+ int fds[NUM_FDS];
+ test_pollset pollsets[NUM_POLLSETS];
+ grpc_closure closures[NUM_CLOSURES];
int i;
int result = 0;
- test_fd_init(tfds, fds, num_fds);
- test_pollset_init(pollsets, num_pollsets);
+ test_fd_init(tfds, fds, NUM_FDS);
+ test_pollset_init(pollsets, NUM_POLLSETS);
/* Two distinct polling islands, each with their own FD and pollset. */
- for (i = 0; i < num_fds; i++) {
+ for (i = 0; i < NUM_FDS; i++) {
grpc_pollset_add_fd(&exec_ctx, pollsets[i].pollset, tfds[i].fd);
grpc_exec_ctx_flush(&exec_ctx);
}
@@ -173,7 +177,7 @@ static void test_pollset_queue_merge_items() {
grpc_closure_init(
closures + 3, increment, &result,
grpc_workqueue_scheduler(grpc_fd_get_polling_island(tfds[1].fd)));
- for (i = 0; i < num_closures; ++i) {
+ for (i = 0; i < NUM_CLOSURES; ++i) {
grpc_closure_sched(&exec_ctx, closures + i, GRPC_ERROR_NONE);
}
@@ -186,7 +190,7 @@ static void test_pollset_queue_merge_items() {
* the merged polling island.
*/
grpc_pollset_worker *worker = NULL;
- for (i = 0; i < num_closures; ++i) {
+ for (i = 0; i < NUM_CLOSURES; ++i) {
const gpr_timespec deadline = gpr_time_add(
gpr_now(GPR_CLOCK_MONOTONIC), gpr_time_from_seconds(2, GPR_TIMESPAN));
gpr_mu_lock(pollsets[1].mu);
@@ -196,13 +200,17 @@ static void test_pollset_queue_merge_items() {
gpr_now(GPR_CLOCK_MONOTONIC), deadline));
gpr_mu_unlock(pollsets[1].mu);
}
- GPR_ASSERT(result == num_closures);
+ GPR_ASSERT(result == NUM_CLOSURES);
- test_fd_cleanup(&exec_ctx, tfds, num_fds);
- test_pollset_cleanup(&exec_ctx, pollsets, num_pollsets);
+ test_fd_cleanup(&exec_ctx, tfds, NUM_FDS);
+ test_pollset_cleanup(&exec_ctx, pollsets, NUM_POLLSETS);
grpc_exec_ctx_finish(&exec_ctx);
}
+#undef NUM_FDS
+#undef NUM_POLLSETS
+#undef NUM_CLOSURES
+
/*
* Cases to test:
* case 1) Polling islands of both fd and pollset are NULL
@@ -213,18 +221,20 @@ static void test_pollset_queue_merge_items() {
* case 4.2) Polling islands of fd and pollset are NOT-equal (This results
* in a merge)
* */
+
+#define NUM_FDS 8
+#define NUM_POLLSETS 4
+
static void test_add_fd_to_pollset() {
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- const int num_fds = 8;
- const int num_pollsets = 4;
- test_fd tfds[num_fds];
- int fds[num_fds];
- test_pollset pollsets[num_pollsets];
+ test_fd tfds[NUM_FDS];
+ int fds[NUM_FDS];
+ test_pollset pollsets[NUM_POLLSETS];
void *expected_pi = NULL;
int i;
- test_fd_init(tfds, fds, num_fds);
- test_pollset_init(pollsets, num_pollsets);
+ test_fd_init(tfds, fds, NUM_FDS);
+ test_pollset_init(pollsets, NUM_POLLSETS);
/*Step 1.
* Create three polling islands (This will exercise test case 1 and 2) with
@@ -285,22 +295,107 @@ static void test_add_fd_to_pollset() {
/* Compare Fd:0's polling island with that of all other Fds */
expected_pi = grpc_fd_get_polling_island(tfds[0].fd);
- for (i = 1; i < num_fds; i++) {
+ for (i = 1; i < NUM_FDS; i++) {
GPR_ASSERT(grpc_are_polling_islands_equal(
expected_pi, grpc_fd_get_polling_island(tfds[i].fd)));
}
/* Compare Fd:0's polling island with that of all other pollsets */
- for (i = 0; i < num_pollsets; i++) {
+ for (i = 0; i < NUM_POLLSETS; i++) {
GPR_ASSERT(grpc_are_polling_islands_equal(
expected_pi, grpc_pollset_get_polling_island(pollsets[i].pollset)));
}
- test_fd_cleanup(&exec_ctx, tfds, num_fds);
- test_pollset_cleanup(&exec_ctx, pollsets, num_pollsets);
+ test_fd_cleanup(&exec_ctx, tfds, NUM_FDS);
+ test_pollset_cleanup(&exec_ctx, pollsets, NUM_POLLSETS);
grpc_exec_ctx_finish(&exec_ctx);
}
+#undef NUM_FDS
+#undef NUM_POLLSETS
+
+typedef struct threading_shared {
+ gpr_mu *mu;
+ grpc_pollset *pollset;
+ grpc_wakeup_fd *wakeup_fd;
+ grpc_fd *wakeup_desc;
+ grpc_closure on_wakeup;
+ int wakeups;
+} threading_shared;
+
+static __thread int thread_wakeups = 0;
+
+static void test_threading_loop(void *arg) {
+ threading_shared *shared = arg;
+ while (thread_wakeups < 1000000) {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_pollset_worker *worker;
+ gpr_mu_lock(shared->mu);
+ GPR_ASSERT(GRPC_LOG_IF_ERROR(
+ "pollset_work",
+ grpc_pollset_work(&exec_ctx, shared->pollset, &worker,
+ gpr_now(GPR_CLOCK_MONOTONIC),
+ gpr_inf_future(GPR_CLOCK_MONOTONIC))));
+ gpr_mu_unlock(shared->mu);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
+static void test_threading_wakeup(grpc_exec_ctx *exec_ctx, void *arg,
+ grpc_error *error) {
+ threading_shared *shared = arg;
+ ++shared->wakeups;
+ ++thread_wakeups;
+ GPR_ASSERT(GRPC_LOG_IF_ERROR(
+ "consume_wakeup", grpc_wakeup_fd_consume_wakeup(shared->wakeup_fd)));
+ grpc_fd_notify_on_read(exec_ctx, shared->wakeup_desc, &shared->on_wakeup);
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_next",
+ grpc_wakeup_fd_wakeup(shared->wakeup_fd)));
+}
+
+static void test_threading(void) {
+ threading_shared shared;
+ shared.pollset = gpr_zalloc(grpc_pollset_size());
+ grpc_pollset_init(shared.pollset, &shared.mu);
+
+ gpr_thd_id thds[10];
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+ gpr_thd_options opt = gpr_thd_options_default();
+ gpr_thd_options_set_joinable(&opt);
+ gpr_thd_new(&thds[i], test_threading_loop, &shared, &opt);
+ }
+ grpc_wakeup_fd fd;
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_fd_init", grpc_wakeup_fd_init(&fd)));
+ shared.wakeup_fd = &fd;
+ shared.wakeup_desc = grpc_fd_create(fd.read_fd, "wakeup");
+ shared.wakeups = 0;
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_pollset_add_fd(&exec_ctx, shared.pollset, shared.wakeup_desc);
+ grpc_fd_notify_on_read(
+ &exec_ctx, shared.wakeup_desc,
+ grpc_closure_init(&shared.on_wakeup, test_threading_wakeup, &shared,
+ grpc_schedule_on_exec_ctx));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ GPR_ASSERT(GRPC_LOG_IF_ERROR("wakeup_first",
+ grpc_wakeup_fd_wakeup(shared.wakeup_fd)));
+ for (size_t i = 0; i < GPR_ARRAY_SIZE(thds); i++) {
+ gpr_thd_join(thds[i]);
+ }
+ fd.read_fd = 0;
+ grpc_wakeup_fd_destroy(&fd);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_fd_orphan(&exec_ctx, shared.wakeup_desc, NULL, NULL, "done");
+ grpc_pollset_shutdown(&exec_ctx, shared.pollset,
+ grpc_closure_create(destroy_pollset, shared.pollset,
+ grpc_schedule_on_exec_ctx));
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+ gpr_free(shared.pollset);
+}
+
int main(int argc, char **argv) {
const char *poll_strategy = NULL;
grpc_test_init(argc, argv);
@@ -310,6 +405,7 @@ int main(int argc, char **argv) {
if (poll_strategy != NULL && strcmp(poll_strategy, "epoll") == 0) {
test_add_fd_to_pollset();
test_pollset_queue_merge_items();
+ test_threading();
} else {
gpr_log(GPR_INFO,
"Skipping the test. The test is only relevant for 'epoll' "
diff --git a/test/core/iomgr/resource_quota_test.c b/test/core/iomgr/resource_quota_test.c
index a5b28f210d..ebce8b9da6 100644
--- a/test/core/iomgr/resource_quota_test.c
+++ b/test/core/iomgr/resource_quota_test.c
@@ -682,6 +682,56 @@ static void test_one_slice_deleted_late(void) {
}
}
+static void test_resize_to_zero(void) {
+ gpr_log(GPR_INFO, "** test_resize_to_zero **");
+ grpc_resource_quota *q = grpc_resource_quota_create("test_resize_to_zero");
+ grpc_resource_quota_resize(q, 0);
+ grpc_resource_quota_unref(q);
+}
+
+static void test_negative_rq_free_pool(void) {
+ gpr_log(GPR_INFO, "** test_negative_rq_free_pool **");
+ grpc_resource_quota *q =
+ grpc_resource_quota_create("test_negative_rq_free_pool");
+ grpc_resource_quota_resize(q, 1024);
+
+ grpc_resource_user *usr = grpc_resource_user_create(q, "usr");
+
+ grpc_resource_user_slice_allocator alloc;
+ int num_allocs = 0;
+ grpc_resource_user_slice_allocator_init(&alloc, usr, inc_int_cb, &num_allocs);
+
+ grpc_slice_buffer buffer;
+ grpc_slice_buffer_init(&buffer);
+
+ {
+ const int start_allocs = num_allocs;
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_alloc_slices(&exec_ctx, &alloc, 1024, 1, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ GPR_ASSERT(num_allocs == start_allocs + 1);
+ }
+
+ grpc_resource_quota_resize(q, 512);
+
+ double eps = 0.0001;
+ GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) < 1 + eps);
+ GPR_ASSERT(grpc_resource_quota_get_memory_pressure(q) > 1 - eps);
+
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_resource_user_unref(&exec_ctx, usr);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+
+ grpc_resource_quota_unref(q);
+ {
+ grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ grpc_slice_buffer_destroy_internal(&exec_ctx, &buffer);
+ grpc_exec_ctx_finish(&exec_ctx);
+ }
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
grpc_init();
@@ -705,6 +755,8 @@ int main(int argc, char **argv) {
test_reclaimers_can_be_posted_repeatedly();
test_one_slice();
test_one_slice_deleted_late();
+ test_resize_to_zero();
+ test_negative_rq_free_pool();
grpc_shutdown();
return 0;
}
diff --git a/test/core/iomgr/timer_heap_test.c b/test/core/iomgr/timer_heap_test.c
index 410d972313..153304fa7b 100644
--- a/test/core/iomgr/timer_heap_test.c
+++ b/test/core/iomgr/timer_heap_test.c
@@ -47,13 +47,7 @@
#include "test/core/util/test_config.h"
-static gpr_timespec random_deadline(void) {
- gpr_timespec ts;
- ts.tv_sec = rand();
- ts.tv_nsec = rand();
- ts.clock_type = GPR_CLOCK_REALTIME;
- return ts;
-}
+static gpr_atm random_deadline(void) { return rand(); }
static grpc_timer *create_test_elements(size_t num_elements) {
grpc_timer *elems = gpr_malloc(num_elements * sizeof(grpc_timer));
@@ -78,12 +72,10 @@ static void check_valid(grpc_timer_heap *pq) {
size_t left_child = 1u + 2u * i;
size_t right_child = left_child + 1u;
if (left_child < pq->timer_count) {
- GPR_ASSERT(gpr_time_cmp(pq->timers[i]->deadline,
- pq->timers[left_child]->deadline) <= 0);
+ GPR_ASSERT(pq->timers[i]->deadline <= pq->timers[left_child]->deadline);
}
if (right_child < pq->timer_count) {
- GPR_ASSERT(gpr_time_cmp(pq->timers[i]->deadline,
- pq->timers[right_child]->deadline) <= 0);
+ GPR_ASSERT(pq->timers[i]->deadline <= pq->timers[right_child]->deadline);
}
}
}
@@ -227,20 +219,19 @@ static void test2(void) {
}
if (num_inserted) {
- gpr_timespec *min_deadline = NULL;
+ gpr_atm *min_deadline = NULL;
for (size_t i = 0; i < elems_size; i++) {
if (elems[i].inserted) {
if (min_deadline == NULL) {
min_deadline = &elems[i].elem.deadline;
} else {
- if (gpr_time_cmp(elems[i].elem.deadline, *min_deadline) < 0) {
+ if (elems[i].elem.deadline < *min_deadline) {
min_deadline = &elems[i].elem.deadline;
}
}
}
}
- GPR_ASSERT(
- 0 == gpr_time_cmp(grpc_timer_heap_top(&pq)->deadline, *min_deadline));
+ GPR_ASSERT(grpc_timer_heap_top(&pq)->deadline == *min_deadline);
}
}
diff --git a/test/core/iomgr/timer_list_test.c b/test/core/iomgr/timer_list_test.c
index 85ad5277cc..46e41dd449 100644
--- a/test/core/iomgr/timer_list_test.c
+++ b/test/core/iomgr/timer_list_test.c
@@ -45,6 +45,9 @@
#define MAX_CB 30
+extern int grpc_timer_trace;
+extern int grpc_timer_check_trace;
+
static int cb_called[MAX_CB][2];
static void cb(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) {
@@ -57,7 +60,11 @@ static void add_test(void) {
grpc_timer timers[20];
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_INFO, "add_test");
+
grpc_timer_list_init(start);
+ grpc_timer_trace = 1;
+ grpc_timer_check_trace = 1;
memset(cb_called, 0, sizeof(cb_called));
/* 10 ms timers. will expire in the current epoch */
@@ -120,9 +127,7 @@ static void add_test(void) {
}
static gpr_timespec tfm(int m) {
- gpr_timespec t = gpr_time_from_millis(m, GPR_TIMESPAN);
- t.clock_type = GPR_CLOCK_REALTIME;
- return t;
+ return gpr_time_from_millis(m, GPR_CLOCK_REALTIME);
}
/* Cleaning up a list with pending timers. */
@@ -130,7 +135,11 @@ void destruction_test(void) {
grpc_timer timers[5];
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ gpr_log(GPR_INFO, "destruction_test");
+
grpc_timer_list_init(gpr_time_0(GPR_CLOCK_REALTIME));
+ grpc_timer_trace = 1;
+ grpc_timer_check_trace = 1;
memset(cb_called, 0, sizeof(cb_called));
grpc_timer_init(
@@ -170,6 +179,7 @@ void destruction_test(void) {
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
+ gpr_set_log_verbosity(GPR_LOG_SEVERITY_DEBUG);
add_test();
destruction_test();
return 0;
diff --git a/test/core/memory_usage/client.c b/test/core/memory_usage/client.c
index 107abbc1b3..51ea51bc12 100644
--- a/test/core/memory_usage/client.c
+++ b/test/core/memory_usage/client.c
@@ -237,6 +237,11 @@ int main(int argc, char **argv) {
0, grpc_slice_from_static_string("Reflector/GetAfterSvrCreation"));
// warmup period
+ for (int i = 0; i < warmup_iterations; i++) {
+ send_snapshot_request(
+ 0, grpc_slice_from_static_string("Reflector/SimpleSnapshot"));
+ }
+
for (call_idx = 0; call_idx < warmup_iterations; ++call_idx) {
init_ping_pong_request(call_idx + 1);
}
diff --git a/test/core/nanopb/fuzzer_response.c b/test/core/nanopb/fuzzer_response.c
index 202c120c67..35c0efe90d 100644
--- a/test/core/nanopb/fuzzer_response.c
+++ b/test/core/nanopb/fuzzer_response.c
@@ -36,7 +36,7 @@
#include <grpc/support/alloc.h>
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
bool squelch = true;
bool leak_check = true;
diff --git a/test/core/nanopb/fuzzer_serverlist.c b/test/core/nanopb/fuzzer_serverlist.c
index b225ae0d51..e1df401968 100644
--- a/test/core/nanopb/fuzzer_serverlist.c
+++ b/test/core/nanopb/fuzzer_serverlist.c
@@ -36,7 +36,7 @@
#include <grpc/support/alloc.h>
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
bool squelch = true;
bool leak_check = true;
diff --git a/test/core/security/BUILD b/test/core/security/BUILD
index 1cb03c5cfe..8c63f9143d 100644
--- a/test/core/security/BUILD
+++ b/test/core/security/BUILD
@@ -55,13 +55,6 @@ cc_test(
)
cc_test(
- name = "b64_test",
- srcs = ["b64_test.c"],
- deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
- copts = ['-std=c99']
-)
-
-cc_test(
name = "credentials_test",
srcs = ["credentials_test.c"],
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c
index 5cebb09bb2..97dfe87896 100644
--- a/test/core/security/json_token_test.c
+++ b/test/core/security/json_token_test.c
@@ -43,7 +43,7 @@
#include "src/core/lib/json/json.h"
#include "src/core/lib/security/credentials/oauth2/oauth2_credentials.h"
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
#include "src/core/lib/slice/slice_internal.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/security/jwt_verifier_test.c b/test/core/security/jwt_verifier_test.c
index 0a73f67528..7eec780a91 100644
--- a/test/core/security/jwt_verifier_test.c
+++ b/test/core/security/jwt_verifier_test.c
@@ -44,7 +44,7 @@
#include "src/core/lib/http/httpcli.h"
#include "src/core/lib/security/credentials/jwt/json_token.h"
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
#include "test/core/util/test_config.h"
/* This JSON key was generated with the GCE console and revoked immediately.
diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c
index b3775e91a7..8f11f98a9c 100644
--- a/test/core/security/secure_endpoint_test.c
+++ b/test/core/security/secure_endpoint_test.c
@@ -43,7 +43,7 @@
#include "src/core/lib/iomgr/iomgr.h"
#include "src/core/lib/security/transport/secure_endpoint.h"
#include "src/core/lib/slice/slice_internal.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
#include "test/core/util/test_config.h"
static gpr_mu *g_mu;
diff --git a/test/core/security/security_connector_test.c b/test/core/security/security_connector_test.c
index 4219b134f2..6c7b8e688f 100644
--- a/test/core/security/security_connector_test.c
+++ b/test/core/security/security_connector_test.c
@@ -46,8 +46,8 @@
#include "src/core/lib/support/env.h"
#include "src/core/lib/support/string.h"
#include "src/core/lib/support/tmpfile.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
+#include "src/core/tsi/transport_security.h"
#include "test/core/util/test_config.h"
static int check_transport_security_type(const grpc_auth_context *ctx) {
diff --git a/test/core/slice/BUILD b/test/core/slice/BUILD
index 67a4706348..4d64d0a818 100644
--- a/test/core/slice/BUILD
+++ b/test/core/slice/BUILD
@@ -52,3 +52,10 @@ cc_test(
deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
copts = ['-std=c99']
)
+
+cc_test(
+ name = "b64_test",
+ srcs = ["b64_test.c"],
+ deps = ["//:grpc", "//test/core/util:grpc_test_util", "//:gpr", "//test/core/util:gpr_test_util"],
+ copts = ['-std=c99']
+)
diff --git a/test/core/security/b64_test.c b/test/core/slice/b64_test.c
index 28af48075e..9e5c06551c 100644
--- a/test/core/security/b64_test.c
+++ b/test/core/slice/b64_test.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/lib/security/util/b64.h"
+#include "src/core/lib/slice/b64.h"
#include <string.h>
diff --git a/test/core/support/arena_test.c b/test/core/support/arena_test.c
index 35b2bbd1b1..9eba8a0fa6 100644
--- a/test/core/support/arena_test.c
+++ b/test/core/support/arena_test.c
@@ -83,9 +83,13 @@ static void test(const char *name, size_t init_size, const size_t *allocs,
static const size_t allocs_##name[] = {__VA_ARGS__}; \
test(#name, init_size, allocs_##name, GPR_ARRAY_SIZE(allocs_##name))
-#define CONCURRENT_TEST_ITERATIONS 100000
#define CONCURRENT_TEST_THREADS 100
+size_t concurrent_test_iterations() {
+ if (sizeof(void *) < 8) return 1000;
+ return 100000;
+}
+
typedef struct {
gpr_event ev_start;
gpr_arena *arena;
@@ -94,7 +98,7 @@ typedef struct {
static void concurrent_test_body(void *arg) {
concurrent_test_args *a = arg;
gpr_event_wait(&a->ev_start, gpr_inf_future(GPR_CLOCK_REALTIME));
- for (size_t i = 0; i < CONCURRENT_TEST_ITERATIONS; i++) {
+ for (size_t i = 0; i < concurrent_test_iterations(); i++) {
*(char *)gpr_arena_alloc(a->arena, 1) = (char)i;
}
}
diff --git a/test/core/support/time_test.c b/test/core/support/time_test.c
index e9ca08d041..4cb36a788c 100644
--- a/test/core/support/time_test.c
+++ b/test/core/support/time_test.c
@@ -255,6 +255,22 @@ static void test_similar(void) {
gpr_time_from_micros(10, GPR_TIMESPAN)));
}
+static void test_convert_extreme(void) {
+ gpr_timespec realtime = {INT64_MAX, 1, GPR_CLOCK_REALTIME};
+ gpr_timespec monotime = gpr_convert_clock_type(realtime, GPR_CLOCK_MONOTONIC);
+ GPR_ASSERT(monotime.tv_sec == realtime.tv_sec);
+ GPR_ASSERT(monotime.clock_type == GPR_CLOCK_MONOTONIC);
+}
+
+static void test_cmp_extreme(void) {
+ gpr_timespec t1 = {INT64_MAX, 1, GPR_CLOCK_REALTIME};
+ gpr_timespec t2 = {INT64_MAX, 2, GPR_CLOCK_REALTIME};
+ GPR_ASSERT(gpr_time_cmp(t1, t2) == 0);
+ t1.tv_sec = INT64_MIN;
+ t2.tv_sec = INT64_MIN;
+ GPR_ASSERT(gpr_time_cmp(t1, t2) == 0);
+}
+
int main(int argc, char *argv[]) {
grpc_test_init(argc, argv);
@@ -263,5 +279,7 @@ int main(int argc, char *argv[]) {
test_overflow();
test_sticky_infinities();
test_similar();
+ test_convert_extreme();
+ test_cmp_extreme();
return 0;
}
diff --git a/test/core/surface/channel_create_test.c b/test/core/surface/channel_create_test.c
index 654e5324d9..21bf6a0b7d 100644
--- a/test/core/surface/channel_create_test.c
+++ b/test/core/surface/channel_create_test.c
@@ -36,7 +36,7 @@
#include <grpc/grpc.h>
#include <grpc/support/log.h>
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/surface/channel.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c
index 567f8ae16e..adb956cd8b 100644
--- a/test/core/surface/secure_channel_create_test.c
+++ b/test/core/surface/secure_channel_create_test.c
@@ -36,7 +36,7 @@
#include <grpc/grpc.h>
#include <grpc/grpc_security.h>
#include <grpc/support/log.h>
-#include "src/core/ext/client_channel/resolver_registry.h"
+#include "src/core/ext/filters/client_channel/resolver_registry.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
#include "src/core/lib/security/transport/security_connector.h"
#include "src/core/lib/surface/channel.h"
diff --git a/test/core/surface/server_chttp2_test.c b/test/core/surface/server_chttp2_test.c
index 6c178abdad..8d40c64654 100644
--- a/test/core/surface/server_chttp2_test.c
+++ b/test/core/surface/server_chttp2_test.c
@@ -39,7 +39,7 @@
#include <grpc/support/time.h>
#include "src/core/lib/security/credentials/credentials.h"
#include "src/core/lib/security/credentials/fake/fake_credentials.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c
index 01e8770b24..ee4a37c314 100644
--- a/test/core/tsi/transport_security_test.c
+++ b/test/core/tsi/transport_security_test.c
@@ -31,7 +31,7 @@
*
*/
-#include "src/core/lib/tsi/transport_security.h"
+#include "src/core/tsi/transport_security.h"
#include <string.h>
@@ -43,8 +43,8 @@
#include <openssl/crypto.h>
#include "src/core/lib/support/string.h"
-#include "src/core/lib/tsi/fake_transport_security.h"
-#include "src/core/lib/tsi/ssl_transport_security.h"
+#include "src/core/tsi/fake_transport_security.h"
+#include "src/core/tsi/ssl_transport_security.h"
#include "test/core/util/test_config.h"
typedef struct {
diff --git a/test/core/util/BUILD b/test/core/util/BUILD
index e6d0d247db..03c79f1f15 100644
--- a/test/core/util/BUILD
+++ b/test/core/util/BUILD
@@ -56,9 +56,11 @@ cc_library(
"reconnect_server.c",
"slice_splitter.c",
"test_tcp_server.c",
+ "trickle_endpoint.c",
],
hdrs = [
"debugger_macros.h",
+ "trickle_endpoint.h",
"grpc_profiler.h",
"mock_endpoint.h",
"parse_hexstring.h",
diff --git a/test/core/util/debugger_macros.c b/test/core/util/debugger_macros.c
index de6a2f38a7..af61d933dd 100644
--- a/test/core/util/debugger_macros.c
+++ b/test/core/util/debugger_macros.c
@@ -39,7 +39,7 @@
#include <stdio.h>
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
#include "src/core/lib/channel/connected_channel.h"
#include "src/core/lib/surface/call.h"
diff --git a/test/cpp/common/BUILD b/test/cpp/common/BUILD
index 0e2db00f0a..48ad583981 100644
--- a/test/cpp/common/BUILD
+++ b/test/cpp/common/BUILD
@@ -34,3 +34,27 @@ cc_test(
srcs = ["alarm_cpp_test.cc"],
deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
)
+
+cc_test(
+ name = "auth_property_iterator_test",
+ srcs = ["auth_property_iterator_test.cc"],
+ deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util", "//test/cpp/util:test_util"],
+)
+
+cc_test(
+ name = "channel_arguments_test",
+ srcs = ["channel_arguments_test.cc"],
+ deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+ name = "channel_filter_test",
+ srcs = ["channel_filter_test.cc"],
+ deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util"],
+)
+
+cc_test(
+ name = "secure_auth_context_test",
+ srcs = ["secure_auth_context_test.cc"],
+ deps = ["//:grpc++", "//external:gtest", "//test/core/util:gpr_test_util", "//test/cpp/util:test_util"],
+)
diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index 9bcc9f99f6..8e7b56cbd6 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -243,6 +243,22 @@ TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
channel_args_.SetUserAgentPrefix(prefix);
EXPECT_TRUE(HasArg(arg0));
+
+ // Test if the user agent string is copied correctly
+ ChannelArguments new_channel_args(channel_args_);
+ grpc_channel_args args;
+ SetChannelArgs(new_channel_args, &args);
+ bool found = false;
+ for (size_t i = 0; i < args.num_args; i++) {
+ const grpc_arg& arg = args.args[i];
+ if (arg.type == GRPC_ARG_STRING &&
+ grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
+ EXPECT_FALSE(found);
+ EXPECT_EQ(0, strcmp(arg.value.string, arg0.value.string));
+ found = true;
+ }
+ }
+ EXPECT_TRUE(found);
}
} // namespace testing
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index 32e8a41795..0b5215ef8e 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -484,6 +484,81 @@ TEST_P(AsyncEnd2endTest, SimpleClientStreaming) {
EXPECT_TRUE(recv_status.ok());
}
+// Two pings and a final pong.
+TEST_P(AsyncEnd2endTest, SimpleClientStreamingWithCoalescingApi) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ ServerAsyncReader<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+ send_request.set_message(GetParam().message_content);
+ cli_ctx.set_initial_metadata_corked(true);
+ // tag:1 never comes up since no op is performed
+ std::unique_ptr<ClientAsyncWriter<EchoRequest>> cli_stream(
+ stub_->AsyncRequestStream(&cli_ctx, &recv_response, cq_.get(), tag(1)));
+
+ service_.RequestRequestStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+ tag(2));
+
+ cli_stream->Write(send_request, tag(3));
+
+ // 65536(64KB) is the default flow control window size. Should change this
+ // number when default flow control window size changes. For the write of
+ // send_request larger than the flow control window size, tag:3 will not come
+ // up until server read is initiated. For write of send_request smaller than
+ // the flow control window size, the request can take the free ride with
+ // initial metadata due to coalescing, thus write tag:3 will come up here.
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking)
+ .Expect(2, true)
+ .Expect(3, true)
+ .Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+ }
+
+ srv_stream.Read(&recv_request, tag(4));
+
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
+ }
+
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ cli_stream->WriteLast(send_request, WriteOptions(), tag(5));
+ srv_stream.Read(&recv_request, tag(6));
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ srv_stream.Read(&recv_request, tag(7));
+ Verifier(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get());
+
+ send_response.set_message(recv_request.message());
+ srv_stream.Finish(send_response, Status::OK, tag(8));
+ cli_stream->Finish(&recv_status, tag(9));
+ Verifier(GetParam().disable_blocking)
+ .Expect(8, true)
+ .Expect(9, true)
+ .Verify(cq_.get());
+
+ EXPECT_EQ(send_response.message(), recv_response.message());
+ EXPECT_TRUE(recv_status.ok());
+}
+
// One ping, two pongs.
TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
ResetStub();
@@ -540,6 +615,112 @@ TEST_P(AsyncEnd2endTest, SimpleServerStreaming) {
EXPECT_TRUE(recv_status.ok());
}
+// One ping, two pongs. Using WriteAndFinish API
+TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWAF) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+
+ send_request.set_message(GetParam().message_content);
+ std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
+ stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
+
+ service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
+ cq_.get(), cq_.get(), tag(2));
+
+ Verifier(GetParam().disable_blocking)
+ .Expect(1, true)
+ .Expect(2, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ send_response.set_message(recv_request.message());
+ srv_stream.Write(send_response, tag(3));
+ cli_stream->Read(&recv_response, tag(4));
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(5));
+ cli_stream->Read(&recv_response, tag(6));
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ cli_stream->Read(&recv_response, tag(7));
+ Verifier(GetParam().disable_blocking).Expect(7, false).Verify(cq_.get());
+
+ cli_stream->Finish(&recv_status, tag(8));
+ Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get());
+
+ EXPECT_TRUE(recv_status.ok());
+}
+
+// One ping, two pongs. Using WriteLast API
+TEST_P(AsyncEnd2endTest, SimpleServerStreamingWithCoalescingApiWL) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ ServerAsyncWriter<EchoResponse> srv_stream(&srv_ctx);
+
+ send_request.set_message(GetParam().message_content);
+ std::unique_ptr<ClientAsyncReader<EchoResponse>> cli_stream(
+ stub_->AsyncResponseStream(&cli_ctx, send_request, cq_.get(), tag(1)));
+
+ service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream,
+ cq_.get(), cq_.get(), tag(2));
+
+ Verifier(GetParam().disable_blocking)
+ .Expect(1, true)
+ .Expect(2, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ send_response.set_message(recv_request.message());
+ srv_stream.Write(send_response, tag(3));
+ cli_stream->Read(&recv_response, tag(4));
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ srv_stream.WriteLast(send_response, WriteOptions(), tag(5));
+ cli_stream->Read(&recv_response, tag(6));
+ srv_stream.Finish(Status::OK, tag(7));
+ Verifier(GetParam().disable_blocking)
+ .Expect(5, true)
+ .Expect(6, true)
+ .Expect(7, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ cli_stream->Read(&recv_response, tag(8));
+ Verifier(GetParam().disable_blocking).Expect(8, false).Verify(cq_.get());
+
+ cli_stream->Finish(&recv_status, tag(9));
+ Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get());
+
+ EXPECT_TRUE(recv_status.ok());
+}
+
// One ping, one pong.
TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) {
ResetStub();
@@ -599,6 +780,144 @@ TEST_P(AsyncEnd2endTest, SimpleBidiStreaming) {
EXPECT_TRUE(recv_status.ok());
}
+// One ping, one pong. Using server:WriteAndFinish api
+TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWAF) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+ send_request.set_message(GetParam().message_content);
+ cli_ctx.set_initial_metadata_corked(true);
+ std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
+ cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
+
+ service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+ tag(2));
+
+ cli_stream->WriteLast(send_request, WriteOptions(), tag(3));
+
+ // 65536(64KB) is the default flow control window size. Should change this
+ // number when default flow control window size changes. For the write of
+ // send_request larger than the flow control window size, tag:3 will not come
+ // up until server read is initiated. For write of send_request smaller than
+ // the flow control window size, the request can take the free ride with
+ // initial metadata due to coalescing, thus write tag:3 will come up here.
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking)
+ .Expect(2, true)
+ .Expect(3, true)
+ .Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+ }
+
+ srv_stream.Read(&recv_request, tag(4));
+
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
+ }
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ srv_stream.Read(&recv_request, tag(5));
+ Verifier(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get());
+
+ send_response.set_message(recv_request.message());
+ srv_stream.WriteAndFinish(send_response, WriteOptions(), Status::OK, tag(6));
+ cli_stream->Read(&recv_response, tag(7));
+ Verifier(GetParam().disable_blocking)
+ .Expect(6, true)
+ .Expect(7, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ cli_stream->Finish(&recv_status, tag(8));
+ Verifier(GetParam().disable_blocking).Expect(8, true).Verify(cq_.get());
+
+ EXPECT_TRUE(recv_status.ok());
+}
+
+// One ping, one pong. Using server:WriteLast api
+TEST_P(AsyncEnd2endTest, SimpleBidiStreamingWithCoalescingApiWL) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ ServerAsyncReaderWriter<EchoResponse, EchoRequest> srv_stream(&srv_ctx);
+
+ send_request.set_message(GetParam().message_content);
+ cli_ctx.set_initial_metadata_corked(true);
+ std::unique_ptr<ClientAsyncReaderWriter<EchoRequest, EchoResponse>>
+ cli_stream(stub_->AsyncBidiStream(&cli_ctx, cq_.get(), tag(1)));
+
+ service_.RequestBidiStream(&srv_ctx, &srv_stream, cq_.get(), cq_.get(),
+ tag(2));
+
+ cli_stream->WriteLast(send_request, WriteOptions(), tag(3));
+
+ // 65536(64KB) is the default flow control window size. Should change this
+ // number when default flow control window size changes. For the write of
+ // send_request larger than the flow control window size, tag:3 will not come
+ // up until server read is initiated. For write of send_request smaller than
+ // the flow control window size, the request can take the free ride with
+ // initial metadata due to coalescing, thus write tag:3 will come up here.
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking)
+ .Expect(2, true)
+ .Expect(3, true)
+ .Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking).Expect(2, true).Verify(cq_.get());
+ }
+
+ srv_stream.Read(&recv_request, tag(4));
+
+ if (GetParam().message_content.length() < 65536) {
+ Verifier(GetParam().disable_blocking).Expect(4, true).Verify(cq_.get());
+ } else {
+ Verifier(GetParam().disable_blocking)
+ .Expect(3, true)
+ .Expect(4, true)
+ .Verify(cq_.get());
+ }
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ srv_stream.Read(&recv_request, tag(5));
+ Verifier(GetParam().disable_blocking).Expect(5, false).Verify(cq_.get());
+
+ send_response.set_message(recv_request.message());
+ srv_stream.WriteLast(send_response, WriteOptions(), tag(6));
+ srv_stream.Finish(Status::OK, tag(7));
+ cli_stream->Read(&recv_response, tag(8));
+ Verifier(GetParam().disable_blocking)
+ .Expect(6, true)
+ .Expect(7, true)
+ .Expect(8, true)
+ .Verify(cq_.get());
+ EXPECT_EQ(send_response.message(), recv_response.message());
+
+ cli_stream->Finish(&recv_status, tag(9));
+ Verifier(GetParam().disable_blocking).Expect(9, true).Verify(cq_.get());
+
+ EXPECT_TRUE(recv_status.ok());
+}
+
// Metadata tests
TEST_P(AsyncEnd2endTest, ClientInitialMetadataRpc) {
ResetStub();
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index df78557c43..d3a83b188f 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -702,6 +702,21 @@ TEST_P(End2endTest, RequestStreamOneRequest) {
EXPECT_TRUE(s.ok());
}
+TEST_P(End2endTest, RequestStreamOneRequestWithCoalescingApi) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+
+ context.set_initial_metadata_corked(true);
+ auto stream = stub_->RequestStream(&context, &response);
+ request.set_message("hello");
+ stream->WriteLast(request, WriteOptions());
+ Status s = stream->Finish();
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+}
+
TEST_P(End2endTest, RequestStreamTwoRequests) {
ResetStub();
EchoRequest request;
@@ -718,6 +733,22 @@ TEST_P(End2endTest, RequestStreamTwoRequests) {
EXPECT_TRUE(s.ok());
}
+TEST_P(End2endTest, RequestStreamTwoRequestsWithCoalescingApi) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+
+ context.set_initial_metadata_corked(true);
+ auto stream = stub_->RequestStream(&context, &response);
+ request.set_message("hello");
+ EXPECT_TRUE(stream->Write(request));
+ stream->WriteLast(request, WriteOptions());
+ Status s = stream->Finish();
+ EXPECT_EQ(response.message(), "hellohello");
+ EXPECT_TRUE(s.ok());
+}
+
TEST_P(End2endTest, ResponseStream) {
ResetStub();
EchoRequest request;
@@ -738,6 +769,27 @@ TEST_P(End2endTest, ResponseStream) {
EXPECT_TRUE(s.ok());
}
+TEST_P(End2endTest, ResponseStreamWithCoalescingApi) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ request.set_message("hello");
+ context.AddMetadata(kServerUseCoalescingApi, "1");
+
+ auto stream = stub_->ResponseStream(&context, request);
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "0");
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "1");
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message() + "2");
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.ok());
+}
+
TEST_P(End2endTest, BidiStream) {
ResetStub();
EchoRequest request;
@@ -770,6 +822,39 @@ TEST_P(End2endTest, BidiStream) {
EXPECT_TRUE(s.ok());
}
+TEST_P(End2endTest, BidiStreamWithCoalescingApi) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ context.AddMetadata(kServerFinishAfterNReads, "3");
+ context.set_initial_metadata_corked(true);
+ grpc::string msg("hello");
+
+ auto stream = stub_->BidiStream(&context);
+
+ request.set_message(msg + "0");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "1");
+ EXPECT_TRUE(stream->Write(request));
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ request.set_message(msg + "2");
+ stream->WriteLast(request, WriteOptions());
+ EXPECT_TRUE(stream->Read(&response));
+ EXPECT_EQ(response.message(), request.message());
+
+ EXPECT_FALSE(stream->Read(&response));
+ EXPECT_FALSE(stream->Read(&response));
+
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.ok());
+}
+
// Talk to the two services with the same name but different package names.
// The two stubs are created on the same channel.
TEST_P(End2endTest, DiffPackageServices) {
diff --git a/test/cpp/end2end/filter_end2end_test.cc b/test/cpp/end2end/filter_end2end_test.cc
index bd384f68b4..2f873eeaa8 100644
--- a/test/cpp/end2end/filter_end2end_test.cc
+++ b/test/cpp/end2end/filter_end2end_test.cc
@@ -122,8 +122,9 @@ class ChannelDataImpl : public ChannelData {
class CallDataImpl : public CallData {
public:
- void StartTransportStreamOp(grpc_exec_ctx* exec_ctx, grpc_call_element* elem,
- TransportStreamOp* op) override {
+ void StartTransportStreamOpBatch(grpc_exec_ctx* exec_ctx,
+ grpc_call_element* elem,
+ TransportStreamOpBatch* op) override {
// Incrementing the counter could be done from Init(), but we want
// to test that the individual methods are actually called correctly.
if (op->recv_initial_metadata() != nullptr) IncrementCallCounter();
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index d6664da5a0..fdb2732e50 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -89,7 +89,7 @@ class MockClientReaderWriter<EchoRequest, EchoResponse> final
return true;
}
- bool Write(const EchoRequest& msg, const WriteOptions& options) override {
+ bool Write(const EchoRequest& msg, WriteOptions options) override {
gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
last_message_ = msg.message();
return true;
diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc
index 59d36e9cb5..11729c425c 100644
--- a/test/cpp/end2end/test_service_impl.cc
+++ b/test/cpp/end2end/test_service_impl.cc
@@ -246,6 +246,9 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
int server_try_cancel = GetIntValueFromMetadata(
kServerTryCancelRequest, context->client_metadata(), DO_NOT_CANCEL);
+ int server_coalescing_api = GetIntValueFromMetadata(
+ kServerUseCoalescingApi, context->client_metadata(), 0);
+
if (server_try_cancel == CANCEL_BEFORE_PROCESSING) {
ServerTryCancel(context);
return Status::CANCELLED;
@@ -260,7 +263,11 @@ Status TestServiceImpl::ResponseStream(ServerContext* context,
for (int i = 0; i < kNumResponseStreamsMsgs; i++) {
response.set_message(request->message() + grpc::to_string(i));
- writer->Write(response);
+ if (i == kNumResponseStreamsMsgs - 1 && server_coalescing_api != 0) {
+ writer->WriteLast(response, WriteOptions());
+ } else {
+ writer->Write(response);
+ }
}
if (server_try_cancel_thd != nullptr) {
@@ -305,10 +312,21 @@ Status TestServiceImpl::BidiStream(
new std::thread(&TestServiceImpl::ServerTryCancel, this, context);
}
+ // kServerFinishAfterNReads suggests after how many reads, the server should
+ // write the last message and send status (coalesced using WriteLast)
+ int server_write_last = GetIntValueFromMetadata(
+ kServerFinishAfterNReads, context->client_metadata(), 0);
+
+ int read_counts = 0;
while (stream->Read(&request)) {
+ read_counts++;
gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
response.set_message(request.message());
- stream->Write(response);
+ if (read_counts == server_write_last) {
+ stream->WriteLast(response, WriteOptions());
+ } else {
+ stream->Write(response);
+ }
}
if (server_try_cancel_thd != nullptr) {
diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h
index 88e0be7bca..b1f02f93f6 100644
--- a/test/cpp/end2end/test_service_impl.h
+++ b/test/cpp/end2end/test_service_impl.h
@@ -48,6 +48,8 @@ const int kNumResponseStreamsMsgs = 3;
const char* const kServerCancelAfterReads = "cancel_after_reads";
const char* const kServerTryCancelRequest = "server_try_cancel";
const char* const kDebugInfoTrailerKey = "debug-info-bin";
+const char* const kServerFinishAfterNReads = "server_finish_after_n_reads";
+const char* const kServerUseCoalescingApi = "server_use_coalescing_api";
typedef enum {
DO_NOT_CANCEL = 0,
diff --git a/test/cpp/grpclb/grpclb_api_test.cc b/test/cpp/grpclb/grpclb_api_test.cc
index 82ccf436f8..d9df2bb673 100644
--- a/test/cpp/grpclb/grpclb_api_test.cc
+++ b/test/cpp/grpclb/grpclb_api_test.cc
@@ -34,7 +34,7 @@
#include <grpc++/impl/codegen/config.h>
#include <gtest/gtest.h>
-#include "src/core/ext/lb_policy/grpclb/load_balancer_api.h"
+#include "src/core/ext/filters/client_channel/lb_policy/grpclb/load_balancer_api.h"
#include "src/core/lib/iomgr/sockaddr.h"
#include "src/core/lib/iomgr/sockaddr_utils.h"
#include "src/proto/grpc/lb/v1/load_balancer.pb.h" // C++ version
diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc
index 89ed9249ad..eb3e5b644d 100644
--- a/test/cpp/grpclb/grpclb_test.cc
+++ b/test/cpp/grpclb/grpclb_test.cc
@@ -51,7 +51,7 @@
#include <grpc++/impl/codegen/config.h>
extern "C" {
-#include "src/core/ext/client_channel/client_channel.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
#include "src/core/lib/channel/channel_args.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/iomgr/sockaddr.h"
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
new file mode 100644
index 0000000000..38619666dc
--- /dev/null
+++ b/test/cpp/microbenchmarks/BUILD
@@ -0,0 +1,93 @@
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+licenses(["notice"]) # 3-clause BSD
+
+cc_test(
+ name = "noop-benchmark",
+ srcs = ["noop-benchmark.cc"],
+ deps = ["//external:benchmark"],
+ linkopts = ["-pthread"],
+)
+
+cc_library(
+ name = "helpers",
+ srcs = ["helpers.cc"],
+ hdrs = ["helpers.h", "fullstack_fixtures.h", "fullstack_context_mutators.h"],
+ deps = ["//:grpc++", "//external:benchmark", "//test/core/util:grpc_test_util", "//src/proto/grpc/testing:echo_proto"],
+ linkopts = ["-pthread"],
+)
+
+cc_test(
+ name = "bm_closure",
+ srcs = ["bm_closure.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_cq",
+ srcs = ["bm_cq.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_error",
+ srcs = ["bm_error.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_fullstack_streaming_ping_pong",
+ srcs = ["bm_fullstack_streaming_ping_pong.cc"],
+ deps = [":helpers"],
+
+ )
+cc_test(
+ name = "bm_fullstack_streaming_pump",
+ srcs = ["bm_fullstack_streaming_pump.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_fullstack_trickle",
+ srcs = ["bm_fullstack_trickle.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_fullstack_unary_ping_pong",
+ srcs = ["bm_fullstack_unary_ping_pong.cc"],
+ deps = [":helpers"],
+)
+
+cc_test(
+ name = "bm_metadata",
+ srcs = ["bm_metadata.cc"],
+ deps = [":helpers"],
+)
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 1ef8caa690..cc37f0c9e9 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -34,6 +34,7 @@
/* This benchmark exists to ensure that the benchmark integration is
* working */
+#include <benchmark/benchmark.h>
#include <string.h>
#include <sstream>
@@ -44,8 +45,8 @@
#include <grpc/support/string_util.h>
extern "C" {
-#include "src/core/ext/client_channel/client_channel.h"
-#include "src/core/ext/load_reporting/load_reporting_filter.h"
+#include "src/core/ext/filters/client_channel/client_channel.h"
+#include "src/core/ext/filters/load_reporting/load_reporting_filter.h"
#include "src/core/lib/channel/channel_stack.h"
#include "src/core/lib/channel/compress_filter.h"
#include "src/core/lib/channel/connected_channel.h"
@@ -60,7 +61,6 @@ extern "C" {
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
auto &force_library_initialization = Library::get();
@@ -221,7 +221,7 @@ namespace dummy_filter {
static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
- grpc_transport_stream_op *op) {}
+ grpc_transport_stream_op_batch *op) {}
static void StartTransportOp(grpc_exec_ctx *exec_ctx,
grpc_channel_element *elem,
@@ -296,7 +296,7 @@ void SetPollsetSet(grpc_exec_ctx *exec_ctx, grpc_transport *self,
/* implementation of grpc_transport_perform_stream_op */
void PerformStreamOp(grpc_exec_ctx *exec_ctx, grpc_transport *self,
- grpc_stream *stream, grpc_transport_stream_op *op) {
+ grpc_stream *stream, grpc_transport_stream_op_batch *op) {
grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_NONE);
}
@@ -346,13 +346,15 @@ class SendEmptyMetadata {
memset(&op_, 0, sizeof(op_));
op_.on_complete = grpc_closure_init(&closure_, DoNothing, nullptr,
grpc_schedule_on_exec_ctx);
+ op_.send_initial_metadata = true;
+ op_.payload = &op_payload_;
}
class Op {
public:
Op(grpc_exec_ctx *exec_ctx, SendEmptyMetadata *p, grpc_call_stack *s) {
grpc_metadata_batch_init(&batch_);
- p->op_.send_initial_metadata = &batch_;
+ p->op_payload_.send_initial_metadata.send_initial_metadata = &batch_;
}
void Finish(grpc_exec_ctx *exec_ctx) {
grpc_metadata_batch_destroy(exec_ctx, &batch_);
@@ -366,7 +368,8 @@ class SendEmptyMetadata {
const gpr_timespec deadline_ = gpr_inf_future(GPR_CLOCK_MONOTONIC);
const gpr_timespec start_time_ = gpr_now(GPR_CLOCK_MONOTONIC);
const grpc_slice method_ = grpc_slice_from_static_string("/foo/bar");
- grpc_transport_stream_op op_;
+ grpc_transport_stream_op_batch op_;
+ grpc_transport_stream_op_batch_payload op_payload_;
grpc_closure closure_;
};
@@ -488,13 +491,16 @@ namespace isolated_call_filter {
static void StartTransportStreamOp(grpc_exec_ctx *exec_ctx,
grpc_call_element *elem,
- grpc_transport_stream_op *op) {
+ grpc_transport_stream_op_batch *op) {
if (op->recv_initial_metadata) {
- grpc_closure_sched(exec_ctx, op->recv_initial_metadata_ready,
- GRPC_ERROR_NONE);
+ grpc_closure_sched(
+ exec_ctx,
+ op->payload->recv_initial_metadata.recv_initial_metadata_ready,
+ GRPC_ERROR_NONE);
}
if (op->recv_message) {
- grpc_closure_sched(exec_ctx, op->recv_message_ready, GRPC_ERROR_NONE);
+ grpc_closure_sched(exec_ctx, op->payload->recv_message.recv_message_ready,
+ GRPC_ERROR_NONE);
}
grpc_closure_sched(exec_ctx, op->on_complete, GRPC_ERROR_NONE);
}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index 563db758f7..55d2d2f58d 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -33,6 +33,7 @@
/* Microbenchmarks around CHTTP2 HPACK operations */
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <string.h>
#include <sstream>
@@ -40,6 +41,7 @@ extern "C" {
#include "src/core/ext/transport/chttp2/transport/hpack_encoder.h"
#include "src/core/ext/transport/chttp2/transport/hpack_parser.h"
#include "src/core/lib/slice/slice_internal.h"
+#include "src/core/lib/slice/slice_string_helpers.h"
#include "src/core/lib/transport/static_metadata.h"
}
#include "test/cpp/microbenchmarks/helpers.h"
@@ -69,6 +71,7 @@ template <class Fixture>
static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
TrackCounters track_counters;
grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
+ static bool logged_representative_output = false;
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
@@ -87,8 +90,17 @@ static void BM_HpackEncoderEncodeHeader(benchmark::State &state) {
grpc_slice_buffer outbuf;
grpc_slice_buffer_init(&outbuf);
while (state.KeepRunning()) {
- grpc_chttp2_encode_header(&exec_ctx, &c, (uint32_t)state.iterations(), &b,
- state.range(0), state.range(1), &stats, &outbuf);
+ uint32_t stream_id = static_cast<uint32_t>(state.iterations());
+ grpc_chttp2_encode_header(&exec_ctx, &c, stream_id, &b, state.range(0),
+ state.range(1), &stats, &outbuf);
+ if (!logged_representative_output) {
+ logged_representative_output = true;
+ for (size_t i = 0; i < outbuf.count; i++) {
+ char *s = grpc_dump_slice(outbuf.slices[i], GPR_DUMP_HEX);
+ gpr_log(GPR_DEBUG, "%" PRIdPTR ": %s", i, s);
+ gpr_free(s);
+ }
+ }
grpc_slice_buffer_reset_and_unref_internal(&exec_ctx, &outbuf);
grpc_exec_ctx_flush(&exec_ctx);
}
@@ -131,6 +143,28 @@ class SingleInternedElem {
}
};
+template <int kLength>
+class SingleInternedBinaryElem {
+ public:
+ static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
+ grpc_slice bytes = MakeBytes();
+ std::vector<grpc_mdelem> out = {grpc_mdelem_from_slices(
+ exec_ctx, grpc_slice_intern(grpc_slice_from_static_string("abc-bin")),
+ grpc_slice_intern(bytes))};
+ grpc_slice_unref(bytes);
+ return out;
+ }
+
+ private:
+ static grpc_slice MakeBytes() {
+ std::vector<char> v;
+ for (int i = 0; i < kLength; i++) {
+ v.push_back(static_cast<char>(rand()));
+ }
+ return grpc_slice_from_copied_buffer(v.data(), v.size());
+ }
+};
+
class SingleInternedKeyElem {
public:
static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
@@ -149,6 +183,24 @@ class SingleNonInternedElem {
}
};
+template <int kLength>
+class SingleNonInternedBinaryElem {
+ public:
+ static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
+ return {grpc_mdelem_from_slices(
+ exec_ctx, grpc_slice_from_static_string("abc-bin"), MakeBytes())};
+ }
+
+ private:
+ static grpc_slice MakeBytes() {
+ std::vector<char> v;
+ for (int i = 0; i < kLength; i++) {
+ v.push_back(static_cast<char>(rand()));
+ }
+ return grpc_slice_from_copied_buffer(v.data(), v.size());
+ }
+};
+
class RepresentativeClientInitialMetadata {
public:
static std::vector<grpc_mdelem> GetElems(grpc_exec_ctx *exec_ctx) {
@@ -195,8 +247,29 @@ BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedKeyElem)
->Args({0, 16384});
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedElem)
->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<1>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<3>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<10>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<31>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleInternedBinaryElem<100>)
+ ->Args({0, 16384});
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem)
->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<1>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<3>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<10>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedBinaryElem<31>)
+ ->Args({0, 16384});
+BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader,
+ SingleNonInternedBinaryElem<100>)
+ ->Args({0, 16384});
// test with a tiny frame size, to highlight continuation costs
BENCHMARK_TEMPLATE(BM_HpackEncoderEncodeHeader, SingleNonInternedElem)
->Args({0, 1});
@@ -255,6 +328,8 @@ static void BM_HpackParserParseHeader(benchmark::State &state) {
}
grpc_exec_ctx_flush(&exec_ctx);
}
+ for (auto slice : init_slices) grpc_slice_unref(slice);
+ for (auto slice : benchmark_slices) grpc_slice_unref(slice);
grpc_chttp2_hpack_parser_destroy(&exec_ctx, &p);
grpc_exec_ctx_finish(&exec_ctx);
track_counters.Finish(state);
@@ -262,7 +337,7 @@ static void BM_HpackParserParseHeader(benchmark::State &state) {
namespace hpack_parser_fixtures {
-static grpc_slice MakeSlice(std::initializer_list<uint8_t> bytes) {
+static grpc_slice MakeSlice(std::vector<uint8_t> bytes) {
grpc_slice s = grpc_slice_malloc(bytes.size());
uint8_t *p = GRPC_SLICE_START_PTR(s);
for (auto b : bytes) {
@@ -346,6 +421,64 @@ class NonIndexedElem {
}
};
+class NonIndexedBinaryElem1 {
+ public:
+ static std::vector<grpc_slice> GetInitSlices() { return {}; }
+ static std::vector<grpc_slice> GetBenchmarkSlices() {
+ return {MakeSlice(
+ {0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n', 0x82, 0xf7, 0xb3})};
+ }
+};
+
+class NonIndexedBinaryElem3 {
+ public:
+ static std::vector<grpc_slice> GetInitSlices() { return {}; }
+ static std::vector<grpc_slice> GetBenchmarkSlices() {
+ return {MakeSlice({0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n', 0x84,
+ 0x7f, 0x4e, 0x29, 0x3f})};
+ }
+};
+
+class NonIndexedBinaryElem10 {
+ public:
+ static std::vector<grpc_slice> GetInitSlices() { return {}; }
+ static std::vector<grpc_slice> GetBenchmarkSlices() {
+ return {MakeSlice({0x00, 0x07, 'a', 'b', 'c', '-', 'b',
+ 'i', 'n', 0x8b, 0x71, 0x0c, 0xa5, 0x81,
+ 0x73, 0x7b, 0x47, 0x13, 0xe9, 0xf7, 0xe3})};
+ }
+};
+
+class NonIndexedBinaryElem31 {
+ public:
+ static std::vector<grpc_slice> GetInitSlices() { return {}; }
+ static std::vector<grpc_slice> GetBenchmarkSlices() {
+ return {MakeSlice({0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n',
+ 0xa3, 0x92, 0x43, 0x7f, 0xbe, 0x7c, 0xea, 0x6f, 0xf3,
+ 0x3d, 0xa7, 0xa7, 0x67, 0xfb, 0xe2, 0x82, 0xf7, 0xf2,
+ 0x8f, 0x1f, 0x9d, 0xdf, 0xf1, 0x7e, 0xb3, 0xef, 0xb2,
+ 0x8f, 0x53, 0x77, 0xce, 0x0c, 0x13, 0xe3, 0xfd, 0x87})};
+ }
+};
+
+class NonIndexedBinaryElem100 {
+ public:
+ static std::vector<grpc_slice> GetInitSlices() { return {}; }
+ static std::vector<grpc_slice> GetBenchmarkSlices() {
+ return {MakeSlice(
+ {0x00, 0x07, 'a', 'b', 'c', '-', 'b', 'i', 'n', 0xeb, 0x1d, 0x4d,
+ 0xe8, 0x96, 0x8c, 0x14, 0x20, 0x06, 0xc1, 0xc3, 0xdf, 0x6e, 0x1f, 0xef,
+ 0xde, 0x2f, 0xde, 0xb7, 0xf2, 0xfe, 0x6d, 0xd4, 0xe4, 0x7d, 0xf5, 0x55,
+ 0x46, 0x52, 0x3d, 0x91, 0xf2, 0xd4, 0x6f, 0xca, 0x34, 0xcd, 0xd9, 0x39,
+ 0xbd, 0x03, 0x27, 0xe3, 0x9c, 0x74, 0xcc, 0x17, 0x34, 0xed, 0xa6, 0x6a,
+ 0x77, 0x73, 0x10, 0xcd, 0x8e, 0x4e, 0x5c, 0x7c, 0x72, 0x39, 0xd8, 0xe6,
+ 0x78, 0x6b, 0xdb, 0xa5, 0xb7, 0xab, 0xe7, 0x46, 0xae, 0x21, 0xab, 0x7f,
+ 0x01, 0x89, 0x13, 0xd7, 0xca, 0x17, 0x6e, 0xcb, 0xd6, 0x79, 0x71, 0x68,
+ 0xbf, 0x8a, 0x3f, 0x32, 0xe8, 0xba, 0xf5, 0xbe, 0xb3, 0xbc, 0xde, 0x28,
+ 0xc7, 0xcf, 0x62, 0x7a, 0x58, 0x2c, 0xcf, 0x4d, 0xe3})};
+ }
+};
+
class RepresentativeClientInitialMetadata {
public:
static std::vector<grpc_slice> GetInitSlices() {
@@ -437,6 +570,11 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, IndexedSingleInternedElem);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, AddIndexedSingleInternedElem);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, KeyIndexedSingleInternedElem);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedElem);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem1);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem3);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem10);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem31);
+BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, NonIndexedBinaryElem100);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
RepresentativeClientInitialMetadata);
BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
@@ -446,4 +584,23 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader,
} // namespace hpack_parser_fixtures
+static void BM_Base16SomeStuff(benchmark::State &state) {
+ uint8_t *bytes = new uint8_t[state.range(0)];
+ for (int i = 0; i < state.range(0); i++) {
+ bytes[i] = static_cast<uint8_t>(rand());
+ }
+ uint8_t *encoded = new uint8_t[state.range(0) * 2];
+ static const uint8_t hex[] = "0123456789abcdef";
+ while (state.KeepRunning()) {
+ for (int i = 0; i < state.range(0); i++) {
+ encoded[2 * i + 0] = hex[encoded[i] >> 8];
+ encoded[2 * i + 1] = hex[encoded[i] & 0xf];
+ }
+ }
+ delete[] encoded;
+ delete[] bytes;
+ state.SetBytesProcessed(state.iterations() * state.range(0));
+}
+BENCHMARK(BM_Base16SomeStuff)->Range(1, 4096);
+
BENCHMARK_MAIN();
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
index 265a5a6b22..1611250850 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -207,7 +207,7 @@ class Stream {
static_cast<grpc_stream *>(stream_), closure);
}
- void Op(grpc_transport_stream_op *op) {
+ void Op(grpc_transport_stream_op_batch *op) {
grpc_transport_perform_stream_op(f_->exec_ctx(), f_->transport(),
static_cast<grpc_stream *>(stream_), op);
}
@@ -305,10 +305,16 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State &state) {
TrackCounters track_counters;
Fixture f(grpc::ChannelArguments(), true);
Stream s(&f);
- grpc_transport_stream_op op;
+ grpc_transport_stream_op_batch op;
+ grpc_transport_stream_op_batch_payload op_payload;
std::unique_ptr<Closure> start;
std::unique_ptr<Closure> done;
+ auto reset_op = [&]() {
+ memset(&op, 0, sizeof(op));
+ op.payload = &op_payload;
+ };
+
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
b.deadline = gpr_inf_future(GPR_CLOCK_MONOTONIC);
@@ -324,14 +330,16 @@ static void BM_StreamCreateSendInitialMetadataDestroy(benchmark::State &state) {
start = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
if (!state.KeepRunning()) return;
s.Init(state);
- memset(&op, 0, sizeof(op));
+ reset_op();
op.on_complete = done.get();
- op.send_initial_metadata = &b;
+ op.send_initial_metadata = true;
+ op.payload->send_initial_metadata.send_initial_metadata = &b;
s.Op(&op);
});
done = MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
- memset(&op, 0, sizeof(op));
- op.cancel_error = GRPC_ERROR_CANCELLED;
+ reset_op();
+ op.cancel_stream = true;
+ op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
s.Op(&op);
s.DestroyThen(start.get());
});
@@ -348,11 +356,16 @@ static void BM_TransportEmptyOp(benchmark::State &state) {
Fixture f(grpc::ChannelArguments(), true);
Stream s(&f);
s.Init(state);
- grpc_transport_stream_op op;
+ grpc_transport_stream_op_batch op;
+ grpc_transport_stream_op_batch_payload op_payload;
+ auto reset_op = [&]() {
+ memset(&op, 0, sizeof(op));
+ op.payload = &op_payload;
+ };
std::unique_ptr<Closure> c =
MakeClosure([&](grpc_exec_ctx *exec_ctx, grpc_error *error) {
if (!state.KeepRunning()) return;
- memset(&op, 0, sizeof(op));
+ reset_op();
op.on_complete = c.get();
s.Op(&op);
});
@@ -370,7 +383,12 @@ static void BM_TransportStreamSend(benchmark::State &state) {
Fixture f(grpc::ChannelArguments(), true);
Stream s(&f);
s.Init(state);
- grpc_transport_stream_op op;
+ grpc_transport_stream_op_batch op;
+ grpc_transport_stream_op_batch_payload op_payload;
+ auto reset_op = [&]() {
+ memset(&op, 0, sizeof(op));
+ op.payload = &op_payload;
+ };
grpc_slice_buffer_stream send_stream;
grpc_slice_buffer send_buffer;
grpc_slice_buffer_init(&send_buffer);
@@ -397,20 +415,23 @@ static void BM_TransportStreamSend(benchmark::State &state) {
s.chttp2_stream()->outgoing_window_delta = 1024 * 1024 * 1024;
f.chttp2_transport()->outgoing_window = 1024 * 1024 * 1024;
grpc_slice_buffer_stream_init(&send_stream, &send_buffer, 0);
- memset(&op, 0, sizeof(op));
+ reset_op();
op.on_complete = c.get();
- op.send_message = &send_stream.base;
+ op.send_message = true;
+ op.payload->send_message.send_message = &send_stream.base;
s.Op(&op);
});
- memset(&op, 0, sizeof(op));
- op.send_initial_metadata = &b;
+ reset_op();
+ op.send_initial_metadata = true;
+ op.payload->send_initial_metadata.send_initial_metadata = &b;
op.on_complete = c.get();
s.Op(&op);
f.FlushExecCtx();
- memset(&op, 0, sizeof(op));
- op.cancel_error = GRPC_ERROR_CANCELLED;
+ reset_op();
+ op.cancel_stream = true;
+ op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
s.Op(&op);
s.DestroyThen(
MakeOnceClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {}));
@@ -483,10 +504,16 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
Fixture f(grpc::ChannelArguments(), true);
Stream s(&f);
s.Init(state);
- grpc_transport_stream_op op;
+ grpc_transport_stream_op_batch_payload op_payload;
+ grpc_transport_stream_op_batch op;
grpc_byte_stream *recv_stream;
grpc_slice incoming_data = CreateIncomingDataSlice(state.range(0), 16384);
+ auto reset_op = [&]() {
+ memset(&op, 0, sizeof(op));
+ op.payload = &op_payload;
+ };
+
grpc_metadata_batch b;
grpc_metadata_batch_init(&b);
grpc_metadata_batch b_recv;
@@ -518,10 +545,11 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
s.chttp2_stream()->incoming_window_delta = 1024 * 1024 * 1024;
f.chttp2_transport()->incoming_window = 1024 * 1024 * 1024;
received = 0;
- memset(&op, 0, sizeof(op));
+ reset_op();
op.on_complete = do_nothing.get();
- op.recv_message = &recv_stream;
- op.recv_message_ready = drain_start.get();
+ op.recv_message = true;
+ op.payload->recv_message.recv_message = &recv_stream;
+ op.payload->recv_message.recv_message_ready = drain_start.get();
s.Op(&op);
f.PushInput(grpc_slice_ref(incoming_data));
});
@@ -554,9 +582,13 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
grpc_closure_run(exec_ctx, drain.get(), GRPC_ERROR_NONE);
});
- memset(&op, 0, sizeof(op));
- op.send_initial_metadata = &b;
- op.recv_initial_metadata = &b_recv;
+ reset_op();
+ op.send_initial_metadata = true;
+ op.payload->send_initial_metadata.send_initial_metadata = &b;
+ op.recv_initial_metadata = true;
+ op.payload->recv_initial_metadata.recv_initial_metadata = &b_recv;
+ op.payload->recv_initial_metadata.recv_initial_metadata_ready =
+ do_nothing.get();
op.on_complete = c.get();
s.Op(&op);
f.PushInput(SLICE_FROM_BUFFER(
@@ -573,8 +605,9 @@ static void BM_TransportStreamRecv(benchmark::State &state) {
"\x10\x14grpc-accept-encoding\x15identity,deflate,gzip"));
f.FlushExecCtx();
- memset(&op, 0, sizeof(op));
- op.cancel_error = GRPC_ERROR_CANCELLED;
+ reset_op();
+ op.cancel_stream = true;
+ op.payload->cancel_stream.cancel_error = GRPC_ERROR_CANCELLED;
s.Op(&op);
s.DestroyThen(
MakeOnceClosure([](grpc_exec_ctx *exec_ctx, grpc_error *error) {}));
diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc
index 28a385b6c1..d52fe4ee30 100644
--- a/test/cpp/microbenchmarks/bm_closure.cc
+++ b/test/cpp/microbenchmarks/bm_closure.cc
@@ -33,7 +33,9 @@
/* Test various closure related operations */
+#include <benchmark/benchmark.h>
#include <grpc/grpc.h>
+#include <sstream>
extern "C" {
#include "src/core/lib/iomgr/closure.h"
@@ -43,7 +45,6 @@ extern "C" {
}
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
auto& force_library_initialization = Library::get();
diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc
index 91e6a85101..38ac9d2705 100644
--- a/test/cpp/microbenchmarks/bm_cq.cc
+++ b/test/cpp/microbenchmarks/bm_cq.cc
@@ -34,12 +34,11 @@
/* This benchmark exists to ensure that the benchmark integration is
* working */
+#include <benchmark/benchmark.h>
#include <grpc++/completion_queue.h>
#include <grpc++/impl/grpc_library.h>
#include <grpc/grpc.h>
-
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
extern "C" {
#include "src/core/lib/surface/completion_queue.h"
@@ -59,6 +58,17 @@ static void BM_CreateDestroyCpp(benchmark::State& state) {
}
BENCHMARK(BM_CreateDestroyCpp);
+/* Create cq using a different constructor */
+static void BM_CreateDestroyCpp2(benchmark::State& state) {
+ TrackCounters track_counters;
+ while (state.KeepRunning()) {
+ grpc_completion_queue* core_cq = grpc_completion_queue_create(NULL);
+ CompletionQueue cq(core_cq);
+ }
+ track_counters.Finish(state);
+}
+BENCHMARK(BM_CreateDestroyCpp2);
+
static void BM_CreateDestroyCore(benchmark::State& state) {
TrackCounters track_counters;
while (state.KeepRunning()) {
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index 00e1a08cab..ea9777bbe6 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -33,6 +33,7 @@
/* Test various operations on grpc_error */
+#include <benchmark/benchmark.h>
#include <memory>
extern "C" {
@@ -41,7 +42,6 @@ extern "C" {
}
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
auto& force_library_initialization = Library::get();
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
index 00e37f7912..c536e15a2c 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
@@ -33,14 +33,13 @@
/* Benchmark gRPC end2end in various configurations */
+#include <benchmark/benchmark.h>
#include <sstream>
-
#include "src/core/lib/profiling/timers.h"
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
namespace grpc {
namespace testing {
@@ -240,6 +239,173 @@ static void BM_StreamingPingPongMsgs(benchmark::State& state) {
state.SetBytesProcessed(msg_size * state.iterations() * 2);
}
+// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of
+// messages in each call) in a loop on a single channel. Different from
+// BM_StreamingPingPong we are using stream coalescing api, e.g. WriteLast,
+// WriteAndFinish, set_initial_metadata_corked. These apis aim at saving
+// sendmsg syscalls for streaming by coalescing 1. initial metadata with first
+// message; 2. final streaming message with trailing metadata.
+//
+// First parmeter (i.e state.range(0)): Message size (in bytes) to use
+// Second parameter (i.e state.range(1)): Number of ping pong messages.
+// Note: One ping-pong means two messages (one from client to server and
+// the other from server to client):
+// Third parameter (i.e state.range(2)): Switch between using WriteAndFinish
+// API and WriteLast API for server.
+template <class Fixture, class ClientContextMutator, class ServerContextMutator>
+static void BM_StreamingPingPongWithCoalescingApi(benchmark::State& state) {
+ const int msg_size = state.range(0);
+ const int max_ping_pongs = state.range(1);
+ // This options is used to test out server API: WriteLast and WriteAndFinish
+ // respectively, since we can not use both of them on server side at the same
+ // time. Value 1 means we are testing out the WriteAndFinish API, and
+ // otherwise we are testing out the WriteLast API.
+ const int write_and_finish = state.range(2);
+
+ EchoTestService::AsyncService service;
+ std::unique_ptr<Fixture> fixture(new Fixture(&service));
+ {
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ EchoRequest send_request;
+ EchoRequest recv_request;
+
+ if (msg_size > 0) {
+ send_request.set_message(std::string(msg_size, 'a'));
+ send_response.set_message(std::string(msg_size, 'b'));
+ }
+
+ std::unique_ptr<EchoTestService::Stub> stub(
+ EchoTestService::NewStub(fixture->channel()));
+
+ while (state.KeepRunning()) {
+ ServerContext svr_ctx;
+ ServerContextMutator svr_ctx_mut(&svr_ctx);
+ ServerAsyncReaderWriter<EchoResponse, EchoRequest> response_rw(&svr_ctx);
+ service.RequestBidiStream(&svr_ctx, &response_rw, fixture->cq(),
+ fixture->cq(), tag(0));
+
+ ClientContext cli_ctx;
+ ClientContextMutator cli_ctx_mut(&cli_ctx);
+ cli_ctx.set_initial_metadata_corked(true);
+ // tag:1 here will never comes up, since we are not performing any op due
+ // to initial metadata coalescing.
+ auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1));
+
+ void* t;
+ bool ok;
+ int need_tags;
+
+ // Send 'max_ping_pongs' number of ping pong messages
+ int ping_pong_cnt = 0;
+ while (ping_pong_cnt < max_ping_pongs) {
+ if (ping_pong_cnt == max_ping_pongs - 1) {
+ request_rw->WriteLast(send_request, WriteOptions(), tag(2));
+ } else {
+ request_rw->Write(send_request, tag(2)); // Start client send
+ }
+
+ need_tags = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5);
+
+ if (ping_pong_cnt == 0) {
+ // wait for the server call structure (call_hook, etc.) to be
+ // initialized (async stream between client side and server side
+ // established). It is necessary when client init metadata is
+ // coalesced
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ while ((int)(intptr_t)t != 0) {
+ // In some cases tag:2 comes before tag:0 (write tag comes out
+ // first), this while loop is to make sure get tag:0.
+ int i = (int)(intptr_t)t;
+ GPR_ASSERT(need_tags & (1 << i));
+ need_tags &= ~(1 << i);
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ }
+ }
+
+ response_rw.Read(&recv_request, tag(3)); // Start server recv
+ request_rw->Read(&recv_response, tag(4)); // Start client recv
+
+ while (need_tags) {
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ GPR_ASSERT(ok);
+ int i = (int)(intptr_t)t;
+
+ // If server recv is complete, start the server send operation
+ if (i == 3) {
+ if (ping_pong_cnt == max_ping_pongs - 1) {
+ if (write_and_finish == 1) {
+ response_rw.WriteAndFinish(send_response, WriteOptions(),
+ Status::OK, tag(5));
+ } else {
+ response_rw.WriteLast(send_response, WriteOptions(), tag(5));
+ // WriteLast buffers the write, so neither server write op nor
+ // client read op will finish inside the while loop.
+ need_tags &= ~(1 << 4);
+ need_tags &= ~(1 << 5);
+ }
+ } else {
+ response_rw.Write(send_response, tag(5));
+ }
+ }
+
+ GPR_ASSERT(need_tags & (1 << i));
+ need_tags &= ~(1 << i);
+ }
+
+ ping_pong_cnt++;
+ }
+
+ if (max_ping_pongs == 0) {
+ need_tags = (1 << 6) | (1 << 7) | (1 << 8);
+ } else {
+ if (write_and_finish == 1) {
+ need_tags = (1 << 8);
+ } else {
+ // server's buffered write and the client's read of the buffered write
+ // tags should come up.
+ need_tags = (1 << 4) | (1 << 5) | (1 << 7) | (1 << 8);
+ }
+ }
+
+ // No message write or initial metadata write happened yet.
+ if (max_ping_pongs == 0) {
+ request_rw->WritesDone(tag(6));
+ // wait for server call data structure(call_hook, etc.) to be
+ // initialized, since initial metadata is corked.
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ while ((int)(intptr_t)t != 0) {
+ int i = (int)(intptr_t)t;
+ GPR_ASSERT(need_tags & (1 << i));
+ need_tags &= ~(1 << i);
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ }
+ response_rw.Finish(Status::OK, tag(7));
+ } else {
+ if (write_and_finish != 1) {
+ response_rw.Finish(Status::OK, tag(7));
+ }
+ }
+
+ Status recv_status;
+ request_rw->Finish(&recv_status, tag(8));
+
+ while (need_tags) {
+ GPR_ASSERT(fixture->cq()->Next(&t, &ok));
+ int i = (int)(intptr_t)t;
+ GPR_ASSERT(need_tags & (1 << i));
+ need_tags &= ~(1 << i);
+ }
+
+ GPR_ASSERT(recv_status.ok());
+ }
+ }
+
+ fixture->Finish(state);
+ fixture.reset();
+ state.SetBytesProcessed(msg_size * state.iterations() * max_ping_pongs * 2);
+}
+
/*******************************************************************************
* CONFIGURATIONS
*/
@@ -270,6 +436,30 @@ BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, InProcessCHTTP2, NoOpMutator,
BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, TCP, NoOpMutator, NoOpMutator)
->Range(0, 128 * 1024 * 1024);
+// Generate Args for StreamingPingPongWithCoalescingApi benchmarks. Currently
+// generates args for only "small streams" (i.e streams with 0, 1 or 2 messages)
+static void StreamingPingPongWithCoalescingApiArgs(
+ benchmark::internal::Benchmark* b) {
+ int msg_size = 0;
+
+ b->Args(
+ {0, 0, 0}); // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
+ b->Args(
+ {0, 0, 1}); // spl case: 0 ping-pong msgs (msg_size doesn't matter here)
+
+ for (msg_size = 0; msg_size <= 128 * 1024 * 1024;
+ msg_size == 0 ? msg_size++ : msg_size *= 8) {
+ b->Args({msg_size, 1, 0});
+ b->Args({msg_size, 2, 0});
+ b->Args({msg_size, 1, 1});
+ b->Args({msg_size, 2, 1});
+ }
+}
+
+BENCHMARK_TEMPLATE(BM_StreamingPingPongWithCoalescingApi, InProcessCHTTP2,
+ NoOpMutator, NoOpMutator)
+ ->Apply(StreamingPingPongWithCoalescingApiArgs);
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
index dc0e7d769a..5c1eb1165b 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
@@ -33,14 +33,13 @@
/* Benchmark gRPC end2end in various configurations */
+#include <benchmark/benchmark.h>
#include <sstream>
-
#include "src/core/lib/profiling/timers.h"
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
index 5011f06368..c563f28b55 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
@@ -33,12 +33,12 @@
/* Benchmark gRPC end2end in various configurations */
+#include <benchmark/benchmark.h>
#include "src/core/lib/profiling/timers.h"
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
extern "C" {
#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h"
#include "src/core/ext/transport/chttp2/transport/internal.h"
diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
index e51d272b10..615b05b7c7 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
@@ -33,14 +33,13 @@
/* Benchmark gRPC end2end in various configurations */
+#include <benchmark/benchmark.h>
#include <sstream>
-
#include "src/core/lib/profiling/timers.h"
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
#include "test/cpp/microbenchmarks/fullstack_fixtures.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc
index 34874b57f5..7029f369ad 100644
--- a/test/cpp/microbenchmarks/bm_metadata.cc
+++ b/test/cpp/microbenchmarks/bm_metadata.cc
@@ -33,17 +33,15 @@
/* Test out various metadata handling primitives */
+#include <benchmark/benchmark.h>
#include <grpc/grpc.h>
extern "C" {
-#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/metadata.h"
#include "src/core/lib/transport/static_metadata.h"
-#include "src/core/lib/transport/transport.h"
}
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
auto& force_library_initialization = Library::get();
@@ -65,19 +63,6 @@ static void BM_SliceFromCopied(benchmark::State& state) {
}
BENCHMARK(BM_SliceFromCopied);
-static void BM_SliceFromStreamOwnedBuffer(benchmark::State& state) {
- grpc_stream_refcount r;
- GRPC_STREAM_REF_INIT(&r, 1, NULL, NULL, "test");
- char buffer[64];
- grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT;
- while (state.KeepRunning()) {
- grpc_slice_unref_internal(&exec_ctx, grpc_slice_from_stream_owned_buffer(
- &r, buffer, sizeof(buffer)));
- }
- grpc_exec_ctx_finish(&exec_ctx);
-}
-BENCHMARK(BM_SliceFromStreamOwnedBuffer);
-
static void BM_SliceIntern(benchmark::State& state) {
TrackCounters track_counters;
gpr_slice slice = grpc_slice_from_static_string("abc");
diff --git a/test/cpp/microbenchmarks/helpers.h b/test/cpp/microbenchmarks/helpers.h
index f44b7cf83a..49ed517b1d 100644
--- a/test/cpp/microbenchmarks/helpers.h
+++ b/test/cpp/microbenchmarks/helpers.h
@@ -41,8 +41,8 @@ extern "C" {
#include "test/core/util/memory_counters.h"
}
+#include <benchmark/benchmark.h>
#include <grpc++/impl/grpc_library.h>
-#include "third_party/benchmark/include/benchmark/benchmark.h"
class Library {
public:
diff --git a/test/cpp/microbenchmarks/noop-benchmark.cc b/test/cpp/microbenchmarks/noop-benchmark.cc
index 99fa6d5f6e..7372ad04f2 100644
--- a/test/cpp/microbenchmarks/noop-benchmark.cc
+++ b/test/cpp/microbenchmarks/noop-benchmark.cc
@@ -34,7 +34,7 @@
/* This benchmark exists to ensure that the benchmark integration is
* working */
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include <benchmark/benchmark.h>
static void BM_NoOp(benchmark::State& state) {
while (state.KeepRunning()) {
diff --git a/test/cpp/qps/BUILD b/test/cpp/qps/BUILD
new file mode 100644
index 0000000000..6492b63ec3
--- /dev/null
+++ b/test/cpp/qps/BUILD
@@ -0,0 +1,194 @@
+# Copyright 2017, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+licenses(["notice"]) # 3-clause BSD
+
+cc_library(
+ name = "parse_json",
+ srcs = ["parse_json.cc"],
+ hdrs = ["parse_json.h"],
+ deps = ["//:grpc++"],
+)
+
+cc_library(
+ name = "qps_worker_impl",
+ srcs = [
+ "client_async.cc",
+ "client_sync.cc",
+ "qps_worker.cc",
+ "server_async.cc",
+ "server_sync.cc",
+ ],
+ hdrs = [
+ "client.h",
+ "qps_worker.h",
+ "server.h",
+ ],
+ deps = [
+ ":histogram",
+ ":interarrival",
+ ":usage_timer",
+ "//:grpc",
+ "//:grpc++",
+ "//external:gtest",
+ "//src/proto/grpc/testing:control_proto",
+ "//src/proto/grpc/testing:payloads_proto",
+ "//src/proto/grpc/testing:services_proto",
+ "//test/core/end2end:ssl_test_data",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
+
+cc_library(
+ name = "driver_impl",
+ srcs = [
+ "driver.cc",
+ "report.cc",
+ ],
+ hdrs = [
+ "driver.h",
+ "report.h",
+ ],
+ deps = [
+ ":histogram",
+ ":parse_json",
+ ":qps_worker_impl",
+ "//:grpc++",
+ "//src/proto/grpc/testing:control_proto",
+ "//src/proto/grpc/testing:messages_proto",
+ "//src/proto/grpc/testing:services_proto",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ ],
+)
+
+cc_library(
+ name = "benchmark_config",
+ srcs = [
+ "benchmark_config.cc",
+ ],
+ hdrs = [
+ "benchmark_config.h",
+ ],
+ deps = [
+ ":driver_impl",
+ ":histogram",
+ "//:grpc++",
+ "//external:gflags",
+ "//src/proto/grpc/testing:control_proto",
+ ],
+)
+
+cc_library(
+ name = "histogram",
+ hdrs = [
+ "histogram.h",
+ "stats.h",
+ ],
+ deps = ["//:gpr"],
+)
+
+cc_library(
+ name = "interarrival",
+ hdrs = ["interarrival.h"],
+ deps = ["//:grpc++"],
+)
+
+cc_binary(
+ name = "json_run_localhost",
+ srcs = ["json_run_localhost.cc"],
+ deps = [
+ "//:gpr",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_util",
+ ],
+)
+
+cc_test(
+ name = "qps_interarrival_test",
+ srcs = ["qps_interarrival_test.cc"],
+ deps = [
+ ":histogram",
+ ":interarrival",
+ ],
+)
+
+cc_binary(
+ name = "qps_json_driver",
+ srcs = ["qps_json_driver.cc"],
+ deps = [
+ ":benchmark_config",
+ ":driver_impl",
+ "//:grpc++",
+ "//external:gflags",
+ ],
+)
+
+cc_test(
+ name = "qps_openloop_test",
+ srcs = ["qps_openloop_test.cc"],
+ deps = [
+ ":benchmark_config",
+ ":driver_impl",
+ ":qps_worker_impl",
+ ],
+)
+
+cc_test(
+ name = "secure_sync_unary_ping_pong_test",
+ srcs = ["secure_sync_unary_ping_pong_test.cc"],
+ deps = [
+ ":benchmark_config",
+ ":driver_impl",
+ "//:grpc++",
+ ],
+)
+
+cc_library(
+ name = "usage_timer",
+ srcs = ["usage_timer.cc"],
+ hdrs = ["usage_timer.h"],
+ deps = ["//:gpr"],
+)
+
+cc_binary(
+ name = "qps_worker",
+ srcs = ["worker.cc"],
+ deps = [
+ ":qps_worker_impl",
+ "//:grpc++",
+ "//test/core/util:gpr_test_util",
+ "//test/core/util:grpc_test_util",
+ "//test/cpp/util:test_config",
+ "//test/cpp/util:test_util",
+ ],
+)
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/qps/benchmark_config.cc
index 6fc864069e..98b8d0ba37 100644
--- a/test/cpp/util/benchmark_config.cc
+++ b/test/cpp/qps/benchmark_config.cc
@@ -31,7 +31,7 @@
*
*/
-#include "test/cpp/util/benchmark_config.h"
+#include "test/cpp/qps/benchmark_config.h"
#include <gflags/gflags.h>
DEFINE_bool(enable_log_reporter, true,
diff --git a/test/cpp/util/benchmark_config.h b/test/cpp/qps/benchmark_config.h
index 6b308a15ff..6b308a15ff 100644
--- a/test/cpp/util/benchmark_config.h
+++ b/test/cpp/qps/benchmark_config.h
diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc
index 396d308e2a..29a79e7343 100644
--- a/test/cpp/qps/client_async.cc
+++ b/test/cpp/qps/client_async.cc
@@ -63,13 +63,13 @@ class ClientRpcContext {
virtual ~ClientRpcContext() {}
// next state, return false if done. Collect stats when appropriate
virtual bool RunNextState(bool, HistogramEntry* entry) = 0;
- virtual ClientRpcContext* StartNewClone() = 0;
+ virtual void StartNewClone(CompletionQueue* cq) = 0;
static void* tag(ClientRpcContext* c) { return reinterpret_cast<void*>(c); }
static ClientRpcContext* detag(void* t) {
return reinterpret_cast<ClientRpcContext*>(t);
}
- virtual void Start(CompletionQueue* cq) = 0;
+ virtual void Start(CompletionQueue* cq, const ClientConfig& config) = 0;
};
template <class RequestType, class ResponseType>
@@ -94,22 +94,17 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
next_issue_(next_issue),
start_req_(start_req) {}
~ClientRpcContextUnaryImpl() override {}
- void Start(CompletionQueue* cq) override {
- cq_ = cq;
- if (!next_issue_) { // ready to issue
- RunNextState(true, nullptr);
- } else { // wait for the issue time
- alarm_.reset(new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
- }
+ void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ StartInternal(cq);
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
switch (next_state_) {
case State::READY:
start_ = UsageTimer::Now();
response_reader_ = start_req_(stub_, &context_, req_, cq_);
+ next_state_ = State::RESP_DONE;
response_reader_->Finish(&response_, &status_,
ClientRpcContext::tag(this));
- next_state_ = State::RESP_DONE;
return true;
case State::RESP_DONE:
if (status_.ok()) {
@@ -123,9 +118,10 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
return false;
}
}
- ClientRpcContext* StartNewClone() override {
- return new ClientRpcContextUnaryImpl(stub_, req_, next_issue_, start_req_,
- callback_);
+ void StartNewClone(CompletionQueue* cq) override {
+ auto* clone = new ClientRpcContextUnaryImpl(stub_, req_, next_issue_,
+ start_req_, callback_);
+ clone->StartInternal(cq);
}
private:
@@ -147,6 +143,15 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
double start_;
std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>
response_reader_;
+
+ void StartInternal(CompletionQueue* cq) {
+ cq_ = cq;
+ if (!next_issue_) { // ready to issue
+ RunNextState(true, nullptr);
+ } else { // wait for the issue time
+ alarm_.reset(new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
+ }
+ }
};
typedef std::forward_list<ClientRpcContext*> context_list;
@@ -185,7 +190,7 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
auto* cq = cli_cqs_[t].get();
auto ctx =
setup_ctx(channels_[ch].get_stub(), next_issuers_[t], request_);
- ctx->Start(cq);
+ ctx->Start(cq, config);
}
t = (t + 1) % cli_cqs_.size();
}
@@ -248,8 +253,7 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
} else if (!ctx->RunNextState(ok, entry)) {
// The RPC and callback are done, so clone the ctx
// and kickstart the new one
- auto clone = ctx->StartNewClone();
- clone->Start(cli_cqs_[thread_idx].get());
+ ctx->StartNewClone(cli_cqs_[thread_idx].get());
// delete the old version
delete ctx;
}
@@ -330,10 +334,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
next_issue_(next_issue),
start_req_(start_req) {}
~ClientRpcContextStreamingImpl() override {}
- void Start(CompletionQueue* cq) override {
- cq_ = cq;
- stream_ = start_req_(stub_, &context_, cq, ClientRpcContext::tag(this));
- next_state_ = State::STREAM_IDLE;
+ void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ StartInternal(cq, config.messages_per_stream());
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
while (true) {
@@ -346,9 +348,9 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
}
break; // loop around, don't return
case State::WAIT:
+ next_state_ = State::READY_TO_WRITE;
alarm_.reset(
new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
- next_state_ = State::READY_TO_WRITE;
return true;
case State::READY_TO_WRITE:
if (!ok) {
@@ -369,17 +371,32 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
case State::READ_DONE:
entry->set_value((UsageTimer::Now() - start_) * 1e9);
callback_(status_, &response_);
+ if ((messages_per_stream_ != 0) &&
+ (++messages_issued_ >= messages_per_stream_)) {
+ next_state_ = State::WRITES_DONE_DONE;
+ stream_->WritesDone(ClientRpcContext::tag(this));
+ return true;
+ }
next_state_ = State::STREAM_IDLE;
break; // loop around
+ case State::WRITES_DONE_DONE:
+ next_state_ = State::FINISH_DONE;
+ stream_->Finish(&status_, ClientRpcContext::tag(this));
+ return true;
+ case State::FINISH_DONE:
+ next_state_ = State::INVALID;
+ return false;
+ break;
default:
GPR_ASSERT(false);
return false;
}
}
}
- ClientRpcContext* StartNewClone() override {
- return new ClientRpcContextStreamingImpl(stub_, req_, next_issue_,
- start_req_, callback_);
+ void StartNewClone(CompletionQueue* cq) override {
+ auto* clone = new ClientRpcContextStreamingImpl(stub_, req_, next_issue_,
+ start_req_, callback_);
+ clone->StartInternal(cq, messages_per_stream_);
}
private:
@@ -395,7 +412,9 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
WAIT,
READY_TO_WRITE,
WRITE_DONE,
- READ_DONE
+ READ_DONE,
+ WRITES_DONE_DONE,
+ FINISH_DONE
};
State next_state_;
std::function<void(grpc::Status, ResponseType*)> callback_;
@@ -408,6 +427,18 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
double start_;
std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>
stream_;
+
+ // Allow a limit on number of messages in a stream
+ int messages_per_stream_;
+ int messages_issued_;
+
+ void StartInternal(CompletionQueue* cq, int messages_per_stream) {
+ cq_ = cq;
+ next_state_ = State::STREAM_IDLE;
+ stream_ = start_req_(stub_, &context_, cq, ClientRpcContext::tag(this));
+ messages_per_stream_ = messages_per_stream;
+ messages_issued_ = 0;
+ }
};
class AsyncStreamingClient final
@@ -459,13 +490,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
next_issue_(next_issue),
start_req_(start_req) {}
~ClientRpcContextGenericStreamingImpl() override {}
- void Start(CompletionQueue* cq) override {
- cq_ = cq;
- const grpc::string kMethodName(
- "/grpc.testing.BenchmarkService/StreamingCall");
- stream_ = start_req_(stub_, &context_, kMethodName, cq,
- ClientRpcContext::tag(this));
- next_state_ = State::STREAM_IDLE;
+ void Start(CompletionQueue* cq, const ClientConfig& config) override {
+ StartInternal(cq, config.messages_per_stream());
}
bool RunNextState(bool ok, HistogramEntry* entry) override {
while (true) {
@@ -478,9 +504,9 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
}
break; // loop around, don't return
case State::WAIT:
+ next_state_ = State::READY_TO_WRITE;
alarm_.reset(
new Alarm(cq_, next_issue_(), ClientRpcContext::tag(this)));
- next_state_ = State::READY_TO_WRITE;
return true;
case State::READY_TO_WRITE:
if (!ok) {
@@ -501,17 +527,32 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
case State::READ_DONE:
entry->set_value((UsageTimer::Now() - start_) * 1e9);
callback_(status_, &response_);
+ if ((messages_per_stream_ != 0) &&
+ (++messages_issued_ >= messages_per_stream_)) {
+ next_state_ = State::WRITES_DONE_DONE;
+ stream_->WritesDone(ClientRpcContext::tag(this));
+ return true;
+ }
next_state_ = State::STREAM_IDLE;
break; // loop around
+ case State::WRITES_DONE_DONE:
+ next_state_ = State::FINISH_DONE;
+ stream_->Finish(&status_, ClientRpcContext::tag(this));
+ return true;
+ case State::FINISH_DONE:
+ next_state_ = State::INVALID;
+ return false;
+ break;
default:
GPR_ASSERT(false);
return false;
}
}
}
- ClientRpcContext* StartNewClone() override {
- return new ClientRpcContextGenericStreamingImpl(stub_, req_, next_issue_,
- start_req_, callback_);
+ void StartNewClone(CompletionQueue* cq) override {
+ auto* clone = new ClientRpcContextGenericStreamingImpl(
+ stub_, req_, next_issue_, start_req_, callback_);
+ clone->StartInternal(cq, messages_per_stream_);
}
private:
@@ -527,7 +568,9 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
WAIT,
READY_TO_WRITE,
WRITE_DONE,
- READ_DONE
+ READ_DONE,
+ WRITES_DONE_DONE,
+ FINISH_DONE
};
State next_state_;
std::function<void(grpc::Status, ByteBuffer*)> callback_;
@@ -539,6 +582,21 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
grpc::Status status_;
double start_;
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> stream_;
+
+ // Allow a limit on number of messages in a stream
+ int messages_per_stream_;
+ int messages_issued_;
+
+ void StartInternal(CompletionQueue* cq, int messages_per_stream) {
+ cq_ = cq;
+ const grpc::string kMethodName(
+ "/grpc.testing.BenchmarkService/StreamingCall");
+ next_state_ = State::STREAM_IDLE;
+ stream_ = start_req_(stub_, &context_, kMethodName, cq,
+ ClientRpcContext::tag(this));
+ messages_per_stream_ = messages_per_stream;
+ messages_issued_ = 0;
+ }
};
static std::unique_ptr<grpc::GenericStub> GenericStubCreator(
diff --git a/test/cpp/qps/client_sync.cc b/test/cpp/qps/client_sync.cc
index a944c45496..a020adde51 100644
--- a/test/cpp/qps/client_sync.cc
+++ b/test/cpp/qps/client_sync.cc
@@ -142,10 +142,13 @@ class SynchronousStreamingClient final : public SynchronousClient {
SynchronousStreamingClient(const ClientConfig& config)
: SynchronousClient(config),
context_(num_threads_),
- stream_(num_threads_) {
+ stream_(num_threads_),
+ messages_per_stream_(config.messages_per_stream()),
+ messages_issued_(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]);
+ messages_issued_[thread_idx] = 0;
}
StartThreads(num_threads_);
}
@@ -173,11 +176,17 @@ class SynchronousStreamingClient final : public SynchronousClient {
stream_[thread_idx]->Read(&responses_[thread_idx])) {
entry->set_value((UsageTimer::Now() - start) * 1e9);
// don't set the status since there isn't one yet
- return true;
+ if ((messages_per_stream_ != 0) &&
+ (++messages_issued_[thread_idx] < messages_per_stream_)) {
+ return true;
+ } else {
+ // Fall through to the below resetting code after finish
+ }
}
stream_[thread_idx]->WritesDone();
Status s = stream_[thread_idx]->Finish();
- // don't set the value since the stream is failed and shouldn't be timed
+ // don't set the value since this is either a failure (shouldn't be timed)
+ // or a stream-end (already has been timed)
entry->set_status(s.error_code());
if (!s.ok()) {
gpr_log(GPR_ERROR, "Stream %" PRIuPTR " received an error %s", thread_idx,
@@ -187,6 +196,7 @@ class SynchronousStreamingClient final : public SynchronousClient {
context_[thread_idx].~ClientContext();
new (&context_[thread_idx]) ClientContext();
stream_[thread_idx] = stub->StreamingCall(&context_[thread_idx]);
+ messages_issued_[thread_idx] = 0;
return true;
}
@@ -197,6 +207,8 @@ class SynchronousStreamingClient final : public SynchronousClient {
std::vector<
std::unique_ptr<grpc::ClientReaderWriter<SimpleRequest, SimpleResponse>>>
stream_;
+ const int messages_per_stream_;
+ std::vector<int> messages_issued_;
};
std::unique_ptr<Client> CreateSynchronousUnaryClient(
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index bd2c1f0ec6..a906137474 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -40,10 +40,10 @@
#include <gflags/gflags.h>
#include <grpc/support/log.h>
+#include "test/cpp/qps/benchmark_config.h"
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/parse_json.h"
#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
DEFINE_string(scenarios_file, "",
"JSON file containing an array of Scenario objects");
diff --git a/test/cpp/qps/qps_openloop_test.cc b/test/cpp/qps/qps_openloop_test.cc
index 70e2709ac0..28b396739f 100644
--- a/test/cpp/qps/qps_openloop_test.cc
+++ b/test/cpp/qps/qps_openloop_test.cc
@@ -36,9 +36,9 @@
#include <grpc/support/log.h>
#include "test/core/util/test_config.h"
+#include "test/cpp/qps/benchmark_config.h"
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index f94ea0cb49..7c4e2cfd3e 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -35,9 +35,9 @@
#include <grpc/support/log.h>
+#include "test/cpp/qps/benchmark_config.h"
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
index d0c47d102a..509d9f89c3 100644
--- a/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/secure_sync_unary_ping_pong_test.cc
@@ -35,9 +35,9 @@
#include <grpc/support/log.h>
+#include "test/cpp/qps/benchmark_config.h"
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
-#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index b58d91eea6..b499b82091 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -235,18 +235,17 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
return false;
}
- ResponseType response;
-
// Call the RPC processing function
- grpc::Status status = invoke_method_(&req_, &response);
+ grpc::Status status = invoke_method_(&req_, &response_);
// Have the response writer work and invoke on_finish when done
next_state_ = &ServerRpcContextUnaryImpl::finisher;
- response_writer_.Finish(response, status, AsyncQpsServerTest::tag(this));
+ response_writer_.Finish(response_, status, AsyncQpsServerTest::tag(this));
return true;
}
std::unique_ptr<ServerContextType> srv_ctx_;
RequestType req_;
+ ResponseType response_;
bool (ServerRpcContextUnaryImpl::*next_state_)(bool);
std::function<void(ServerContextType *, RequestType *,
grpc::ServerAsyncResponseWriter<ResponseType> *, void *)>
@@ -298,11 +297,10 @@ class AsyncQpsServerTest final : public grpc::testing::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);
+ grpc::Status status = invoke_method_(&req_, &response_);
// initiate the write
- stream_.Write(response, AsyncQpsServerTest::tag(this));
+ stream_.Write(response_, AsyncQpsServerTest::tag(this));
next_state_ = &ServerRpcContextStreamingImpl::write_done;
} else { // client has sent writes done
// finish the stream
@@ -326,6 +324,7 @@ class AsyncQpsServerTest final : public grpc::testing::Server {
std::unique_ptr<ServerContextType> srv_ctx_;
RequestType req_;
+ ResponseType response_;
bool (ServerRpcContextStreamingImpl::*next_state_)(bool);
std::function<void(
ServerContextType *,