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/client_channel/resolvers/dns_resolver_connectivity_test.c16
-rw-r--r--test/core/end2end/connection_refused_test.c2
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer.c2
-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/crash-59a56fa18034a104fb9f16cd58071b6ff93b8756bin0 -> 268 bytes
-rw-r--r--test/core/end2end/fuzzers/api_fuzzer_corpus/poc-c726ee220e980ed6ad17809fd9efe2844ee61555ac08e4f88afd8901cc2dd53abin0 -> 229 bytes
-rw-r--r--test/core/end2end/goaway_server_test.c30
-rw-r--r--test/core/end2end/tests/keepalive_timeout.c20
-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/memory_usage/client.c5
-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/support/time_test.c18
-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/cpp/common/BUILD24
-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/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/microbenchmarks/BUILD93
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc2
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_hpack.cc163
-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/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
53 files changed, 1454 insertions, 137 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/client_channel/resolvers/dns_resolver_connectivity_test.c b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
index b85ca89337..8449afcbbe 100644
--- a/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
+++ b/test/core/client_channel/resolvers/dns_resolver_connectivity_test.c
@@ -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/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/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-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/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/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/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/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/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/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/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/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/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/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/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/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..4af2263e82 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>
@@ -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();
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_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/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 *,