diff options
Diffstat (limited to 'test')
55 files changed, 963 insertions, 64 deletions
diff --git a/test/core/end2end/fake_resolver.c b/test/core/end2end/fake_resolver.c index 8e711c6b41..4f05f69f01 100644 --- a/test/core/end2end/fake_resolver.c +++ b/test/core/end2end/fake_resolver.c @@ -154,12 +154,34 @@ static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx, grpc_uri_get_query_arg(args->uri, "lb_enabled"); const bool lb_enabled = lb_enabled_qpart != NULL && strcmp("0", lb_enabled_qpart) != 0; + + // Get the balancer's names. + const char* balancer_names = + grpc_uri_get_query_arg(args->uri, "balancer_names"); + grpc_slice_buffer balancer_names_parts; + grpc_slice_buffer_init(&balancer_names_parts); + if (balancer_names != NULL) { + const grpc_slice balancer_names_slice = + grpc_slice_from_copied_string(balancer_names); + grpc_slice_split(balancer_names_slice, ",", &balancer_names_parts); + grpc_slice_unref(balancer_names_slice); + } + // Construct addresses. grpc_slice path_slice = grpc_slice_new(args->uri->path, strlen(args->uri->path), do_nothing); grpc_slice_buffer path_parts; grpc_slice_buffer_init(&path_parts); grpc_slice_split(path_slice, ",", &path_parts); + if (balancer_names_parts.count > 0 && + path_parts.count != balancer_names_parts.count) { + gpr_log(GPR_ERROR, + "Balancer names present but mismatched with number of addresses: " + "%lu balancer names != %lu addresses", + (unsigned long)balancer_names_parts.count, + (unsigned long)path_parts.count); + return NULL; + } grpc_lb_addresses* addresses = grpc_lb_addresses_create(path_parts.count, NULL /* user_data_vtable */); bool errors_found = false; @@ -171,10 +193,15 @@ static grpc_resolver* fake_resolver_create(grpc_exec_ctx* exec_ctx, errors_found = true; } gpr_free(part_str); - addresses->addresses[i].is_balancer = lb_enabled; if (errors_found) break; + addresses->addresses[i].is_balancer = lb_enabled; + addresses->addresses[i].balancer_name = + balancer_names_parts.count > 0 + ? grpc_dump_slice(balancer_names_parts.slices[i], GPR_DUMP_ASCII) + : NULL; } grpc_slice_buffer_destroy_internal(exec_ctx, &path_parts); + grpc_slice_buffer_destroy_internal(exec_ctx, &balancer_names_parts); grpc_slice_unref(path_slice); if (errors_found) { grpc_lb_addresses_destroy(exec_ctx, addresses); diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/039c25bc070936901fc95f63ce9cc3058158fb6d b/test/core/end2end/fuzzers/api_fuzzer_corpus/039c25bc070936901fc95f63ce9cc3058158fb6d Binary files differnew file mode 100644 index 0000000000..fd96a32975 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/039c25bc070936901fc95f63ce9cc3058158fb6d diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/0f01df12331467c4eed400465254eda05eaeb110 b/test/core/end2end/fuzzers/api_fuzzer_corpus/0f01df12331467c4eed400465254eda05eaeb110 Binary files differnew file mode 100644 index 0000000000..09bf4db585 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/0f01df12331467c4eed400465254eda05eaeb110 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/174ea33060bccea880dfdcfa12c5349e8eb4cb2a b/test/core/end2end/fuzzers/api_fuzzer_corpus/174ea33060bccea880dfdcfa12c5349e8eb4cb2a Binary files differnew file mode 100644 index 0000000000..da32e95013 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/174ea33060bccea880dfdcfa12c5349e8eb4cb2a diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/25c05b84c4b4f1a93f0f72d368c3c3644b564881 b/test/core/end2end/fuzzers/api_fuzzer_corpus/25c05b84c4b4f1a93f0f72d368c3c3644b564881 Binary files differnew file mode 100644 index 0000000000..0cde771ff9 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/25c05b84c4b4f1a93f0f72d368c3c3644b564881 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/2d743ec0a0826177cfa7ffb335c0034f482e70e5 b/test/core/end2end/fuzzers/api_fuzzer_corpus/2d743ec0a0826177cfa7ffb335c0034f482e70e5 Binary files differnew file mode 100644 index 0000000000..5449b346c0 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/2d743ec0a0826177cfa7ffb335c0034f482e70e5 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/30738789e20323323196dd3e6435fa278e73279e b/test/core/end2end/fuzzers/api_fuzzer_corpus/30738789e20323323196dd3e6435fa278e73279e Binary files differnew file mode 100644 index 0000000000..a85ff98407 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/30738789e20323323196dd3e6435fa278e73279e diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/33e01fe9738c887b159ca5add342b22c13e526cf b/test/core/end2end/fuzzers/api_fuzzer_corpus/33e01fe9738c887b159ca5add342b22c13e526cf Binary files differnew file mode 100644 index 0000000000..9b3060c517 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/33e01fe9738c887b159ca5add342b22c13e526cf diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/3a3346314bb9ddaf14877b653cfd506b6ad34fab b/test/core/end2end/fuzzers/api_fuzzer_corpus/3a3346314bb9ddaf14877b653cfd506b6ad34fab Binary files differnew file mode 100644 index 0000000000..1695b94414 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/3a3346314bb9ddaf14877b653cfd506b6ad34fab diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/42231300ca5cf30d18f55b66020926882c64248c b/test/core/end2end/fuzzers/api_fuzzer_corpus/42231300ca5cf30d18f55b66020926882c64248c Binary files differnew file mode 100644 index 0000000000..0119532390 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/42231300ca5cf30d18f55b66020926882c64248c diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/428cce92c42645f4cc4060a8cb9cef3a803c0341 b/test/core/end2end/fuzzers/api_fuzzer_corpus/428cce92c42645f4cc4060a8cb9cef3a803c0341 Binary files differnew file mode 100644 index 0000000000..39faa0d693 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/428cce92c42645f4cc4060a8cb9cef3a803c0341 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/43cdc82b082bbdc4d7d23437a7f761f1ca32ca73 b/test/core/end2end/fuzzers/api_fuzzer_corpus/43cdc82b082bbdc4d7d23437a7f761f1ca32ca73 Binary files differnew file mode 100644 index 0000000000..c8250c8ccf --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/43cdc82b082bbdc4d7d23437a7f761f1ca32ca73 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/448fc1dc939aa7f398f1577e418630abecc0a1d7 b/test/core/end2end/fuzzers/api_fuzzer_corpus/448fc1dc939aa7f398f1577e418630abecc0a1d7 Binary files differnew file mode 100644 index 0000000000..d5f631429e --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/448fc1dc939aa7f398f1577e418630abecc0a1d7 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/46171f477d11338f4cc948915350772d54319200 b/test/core/end2end/fuzzers/api_fuzzer_corpus/46171f477d11338f4cc948915350772d54319200 Binary files differnew file mode 100644 index 0000000000..df032667c6 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/46171f477d11338f4cc948915350772d54319200 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/51ea84d5a790d3d2495be453f5341c41b6153644 b/test/core/end2end/fuzzers/api_fuzzer_corpus/51ea84d5a790d3d2495be453f5341c41b6153644 Binary files differnew file mode 100644 index 0000000000..df8ee081bf --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/51ea84d5a790d3d2495be453f5341c41b6153644 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/5547a3544fc5c634024d546366704547dd72cc2b b/test/core/end2end/fuzzers/api_fuzzer_corpus/5547a3544fc5c634024d546366704547dd72cc2b Binary files differnew file mode 100644 index 0000000000..9e6f5b687d --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/5547a3544fc5c634024d546366704547dd72cc2b diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/64656ddf81738f914ead8003c19d0148c54f34d6 b/test/core/end2end/fuzzers/api_fuzzer_corpus/64656ddf81738f914ead8003c19d0148c54f34d6 Binary files differnew file mode 100644 index 0000000000..daf5bc14b1 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/64656ddf81738f914ead8003c19d0148c54f34d6 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/681b758cad3bbce4bde2d1a78a2ec4600c59b05c b/test/core/end2end/fuzzers/api_fuzzer_corpus/681b758cad3bbce4bde2d1a78a2ec4600c59b05c Binary files differnew file mode 100644 index 0000000000..d54a2af33d --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/681b758cad3bbce4bde2d1a78a2ec4600c59b05c diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/72031f24261c32d2e3bb2c7909a9315227172730 b/test/core/end2end/fuzzers/api_fuzzer_corpus/72031f24261c32d2e3bb2c7909a9315227172730 Binary files differnew file mode 100644 index 0000000000..b02f72e6be --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/72031f24261c32d2e3bb2c7909a9315227172730 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/783484ad9e15085e9039c7504aac71af1ad549a2 b/test/core/end2end/fuzzers/api_fuzzer_corpus/783484ad9e15085e9039c7504aac71af1ad549a2 Binary files differnew file mode 100644 index 0000000000..cdee9cfeb9 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/783484ad9e15085e9039c7504aac71af1ad549a2 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/78e43d163fc8226d72b979c0fe6e1593ef3cb542 b/test/core/end2end/fuzzers/api_fuzzer_corpus/78e43d163fc8226d72b979c0fe6e1593ef3cb542 Binary files differnew file mode 100644 index 0000000000..e3470adec6 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/78e43d163fc8226d72b979c0fe6e1593ef3cb542 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/7fb64b5785ebe699ca50327c88c1d8b99432fa23 b/test/core/end2end/fuzzers/api_fuzzer_corpus/7fb64b5785ebe699ca50327c88c1d8b99432fa23 Binary files differnew file mode 100644 index 0000000000..21802ec5ee --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/7fb64b5785ebe699ca50327c88c1d8b99432fa23 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/82731abc38788755495b1bac7b58bc0f12e4bdd1 b/test/core/end2end/fuzzers/api_fuzzer_corpus/82731abc38788755495b1bac7b58bc0f12e4bdd1 Binary files differnew file mode 100644 index 0000000000..20c7c70f83 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/82731abc38788755495b1bac7b58bc0f12e4bdd1 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/83776278a4997b0d178602c8419f3e6481dec01d b/test/core/end2end/fuzzers/api_fuzzer_corpus/83776278a4997b0d178602c8419f3e6481dec01d Binary files differnew file mode 100644 index 0000000000..2570ea8bc6 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/83776278a4997b0d178602c8419f3e6481dec01d diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/92c816d98f9f8669f43b46b22d5da21464d9ef41 b/test/core/end2end/fuzzers/api_fuzzer_corpus/92c816d98f9f8669f43b46b22d5da21464d9ef41 Binary files differnew file mode 100644 index 0000000000..c000647a86 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/92c816d98f9f8669f43b46b22d5da21464d9ef41 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/9ca8f5c67662fa6726db2680978e443d80785a9f b/test/core/end2end/fuzzers/api_fuzzer_corpus/9ca8f5c67662fa6726db2680978e443d80785a9f Binary files differnew file mode 100644 index 0000000000..4954b7255c --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/9ca8f5c67662fa6726db2680978e443d80785a9f diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/9cc4eeecbb2df8b130cca5e455a0f6b8a6e00660 b/test/core/end2end/fuzzers/api_fuzzer_corpus/9cc4eeecbb2df8b130cca5e455a0f6b8a6e00660 Binary files differnew file mode 100644 index 0000000000..86f991ed00 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/9cc4eeecbb2df8b130cca5e455a0f6b8a6e00660 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/a270e4304cc0dcd2c67b78c0495dedb10419f0af b/test/core/end2end/fuzzers/api_fuzzer_corpus/a270e4304cc0dcd2c67b78c0495dedb10419f0af Binary files differnew file mode 100644 index 0000000000..733f4cc62a --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/a270e4304cc0dcd2c67b78c0495dedb10419f0af diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/bc42e00a7d67fb68df3cb5893908c04884b6ad5e b/test/core/end2end/fuzzers/api_fuzzer_corpus/bc42e00a7d67fb68df3cb5893908c04884b6ad5e Binary files differnew file mode 100644 index 0000000000..af4a3481d8 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/bc42e00a7d67fb68df3cb5893908c04884b6ad5e diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/c1e5524945b3e3eabedfbb675be9e9ea99a36b94 b/test/core/end2end/fuzzers/api_fuzzer_corpus/c1e5524945b3e3eabedfbb675be9e9ea99a36b94 Binary files differnew file mode 100644 index 0000000000..12bb8f2d64 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/c1e5524945b3e3eabedfbb675be9e9ea99a36b94 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/c9f81864507c264369dd22c72aeb16f1cb1742b0 b/test/core/end2end/fuzzers/api_fuzzer_corpus/c9f81864507c264369dd22c72aeb16f1cb1742b0 Binary files differnew file mode 100644 index 0000000000..0331bad1a6 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/c9f81864507c264369dd22c72aeb16f1cb1742b0 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-177af631195e806f4056847cea4d09b5eb28cf8a b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-177af631195e806f4056847cea4d09b5eb28cf8a Binary files differnew file mode 100644 index 0000000000..344825c571 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-177af631195e806f4056847cea4d09b5eb28cf8a diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-5fc15c2ee9c70fd834588cbd256cfb52cdcbcb8d b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-5fc15c2ee9c70fd834588cbd256cfb52cdcbcb8d Binary files differnew file mode 100644 index 0000000000..ce2ffbb6d5 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-5fc15c2ee9c70fd834588cbd256cfb52cdcbcb8d diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-b5ae6881c767a7769bb957ac379f22aafe4ef05e b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-b5ae6881c767a7769bb957ac379f22aafe4ef05e Binary files differnew file mode 100644 index 0000000000..3518dffafc --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/crash-b5ae6881c767a7769bb957ac379f22aafe4ef05e diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/d0d622fa3916e800e959a3fc2c90e213d518e5f4 b/test/core/end2end/fuzzers/api_fuzzer_corpus/d0d622fa3916e800e959a3fc2c90e213d518e5f4 Binary files differnew file mode 100644 index 0000000000..0de93e6a0d --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/d0d622fa3916e800e959a3fc2c90e213d518e5f4 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/dd229da166c3bec675e882d17092238cf7d245f3 b/test/core/end2end/fuzzers/api_fuzzer_corpus/dd229da166c3bec675e882d17092238cf7d245f3 Binary files differnew file mode 100644 index 0000000000..2a994d9dda --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/dd229da166c3bec675e882d17092238cf7d245f3 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/de45c55043f63ec680e990b1edf1f0cc60ebbf4e b/test/core/end2end/fuzzers/api_fuzzer_corpus/de45c55043f63ec680e990b1edf1f0cc60ebbf4e Binary files differnew file mode 100644 index 0000000000..fab7ebbb2f --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/de45c55043f63ec680e990b1edf1f0cc60ebbf4e diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/e709e8861c09e29cdae73e337587a63fb0ccf76d b/test/core/end2end/fuzzers/api_fuzzer_corpus/e709e8861c09e29cdae73e337587a63fb0ccf76d Binary files differnew file mode 100644 index 0000000000..a481542791 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/e709e8861c09e29cdae73e337587a63fb0ccf76d diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/e839090caa1b1bfa8898eea683f5d5c9f1ed6dd1 b/test/core/end2end/fuzzers/api_fuzzer_corpus/e839090caa1b1bfa8898eea683f5d5c9f1ed6dd1 Binary files differnew file mode 100644 index 0000000000..af332baf9a --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/e839090caa1b1bfa8898eea683f5d5c9f1ed6dd1 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/e9932127668f9de0743fc639dca31acedbfc68fd b/test/core/end2end/fuzzers/api_fuzzer_corpus/e9932127668f9de0743fc639dca31acedbfc68fd Binary files differnew file mode 100644 index 0000000000..62fe8fd03e --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/e9932127668f9de0743fc639dca31acedbfc68fd diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/eacf4905e489566a3e5fcaaeac9fe91cbf916e06 b/test/core/end2end/fuzzers/api_fuzzer_corpus/eacf4905e489566a3e5fcaaeac9fe91cbf916e06 Binary files differnew file mode 100644 index 0000000000..44f3e00f98 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/eacf4905e489566a3e5fcaaeac9fe91cbf916e06 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/ec55cbebe6db506acf7af9e5d26386630319623d b/test/core/end2end/fuzzers/api_fuzzer_corpus/ec55cbebe6db506acf7af9e5d26386630319623d Binary files differnew file mode 100644 index 0000000000..14ebab0cf3 --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/ec55cbebe6db506acf7af9e5d26386630319623d diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/f09c5cabe569b5c22a16d7d584074d54d9343edc b/test/core/end2end/fuzzers/api_fuzzer_corpus/f09c5cabe569b5c22a16d7d584074d54d9343edc Binary files differnew file mode 100644 index 0000000000..58644e12ae --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/f09c5cabe569b5c22a16d7d584074d54d9343edc diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/f9048c4c18e729b6f49e929876ec30866deb16a9 b/test/core/end2end/fuzzers/api_fuzzer_corpus/f9048c4c18e729b6f49e929876ec30866deb16a9 Binary files differnew file mode 100644 index 0000000000..7c90edad4e --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/f9048c4c18e729b6f49e929876ec30866deb16a9 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/f92897ee60bd24634aa1582f162c1c8f4b249148 b/test/core/end2end/fuzzers/api_fuzzer_corpus/f92897ee60bd24634aa1582f162c1c8f4b249148 Binary files differnew file mode 100644 index 0000000000..758adafd3b --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/f92897ee60bd24634aa1582f162c1c8f4b249148 diff --git a/test/core/end2end/fuzzers/api_fuzzer_corpus/fd05ad1a9d183c2a25d820aca9940caacbaa0660 b/test/core/end2end/fuzzers/api_fuzzer_corpus/fd05ad1a9d183c2a25d820aca9940caacbaa0660 Binary files differnew file mode 100644 index 0000000000..3261a7bfda --- /dev/null +++ b/test/core/end2end/fuzzers/api_fuzzer_corpus/fd05ad1a9d183c2a25d820aca9940caacbaa0660 diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index ea6b3e9645..e3b6aee783 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -104,6 +104,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, int was_cancelled = 2; config.init_client(f, client_args); + config.init_server(f, server_args); c = grpc_channel_create_call( f->client, NULL, GRPC_PROPAGATE_DEFAULTS, f->cq, @@ -143,8 +144,6 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - config.init_server(f, server_args); - error = grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, f->cq, f->cq, tag(101)); diff --git a/test/core/iomgr/pollset_set_test.c b/test/core/iomgr/pollset_set_test.c new file mode 100644 index 0000000000..40fa858602 --- /dev/null +++ b/test/core/iomgr/pollset_set_test.c @@ -0,0 +1,467 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include "src/core/lib/iomgr/port.h" + +/* This test only relevant on linux systems where epoll is available */ +#ifdef GRPC_LINUX_EPOLL + +#include <errno.h> +#include <string.h> +#include <unistd.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/useful.h> + +#include "src/core/lib/iomgr/ev_posix.h" +#include "src/core/lib/iomgr/iomgr.h" +#include "test/core/util/test_config.h" + +/******************************************************************************* + * test_pollset_set + */ + +typedef struct test_pollset_set { grpc_pollset_set *pss; } test_pollset_set; + +void init_test_pollset_sets(test_pollset_set *pollset_sets, const int num_pss) { + for (int i = 0; i < num_pss; i++) { + pollset_sets[i].pss = grpc_pollset_set_create(); + } +} + +void cleanup_test_pollset_sets(test_pollset_set *pollset_sets, + const int num_pss) { + for (int i = 0; i < num_pss; i++) { + grpc_pollset_set_destroy(pollset_sets[i].pss); + pollset_sets[i].pss = NULL; + } +} + +/******************************************************************************* + * test_pollset + */ + +typedef struct test_pollset { + grpc_pollset *ps; + gpr_mu *mu; +} test_pollset; + +static void init_test_pollsets(test_pollset *pollsets, const int num_pollsets) { + for (int i = 0; i < num_pollsets; i++) { + pollsets[i].ps = gpr_malloc(grpc_pollset_size()); + grpc_pollset_init(pollsets[i].ps, &pollsets[i].mu); + } +} + +static void destroy_pollset(grpc_exec_ctx *exec_ctx, void *p, + grpc_error *error) { + grpc_pollset_destroy(p); +} + +static void cleanup_test_pollsets(grpc_exec_ctx *exec_ctx, + test_pollset *pollsets, + const int num_pollsets) { + grpc_closure destroyed; + for (int i = 0; i < num_pollsets; i++) { + grpc_closure_init(&destroyed, destroy_pollset, pollsets[i].ps, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(exec_ctx, pollsets[i].ps, &destroyed); + + grpc_exec_ctx_flush(exec_ctx); + gpr_free(pollsets[i].ps); + pollsets[i].ps = NULL; + } +} + +/******************************************************************************* + * test_fd + */ + +typedef struct test_fd { + grpc_fd *fd; + grpc_wakeup_fd wakeup_fd; + + bool is_on_readable_called; /* Is on_readable closure is called ? */ + grpc_closure on_readable; /* Closure to call when this fd is readable */ +} test_fd; + +void on_readable(grpc_exec_ctx *exec_ctx, void *tfd, grpc_error *error) { + ((test_fd *)tfd)->is_on_readable_called = true; +} + +static void reset_test_fd(grpc_exec_ctx *exec_ctx, test_fd *tfd) { + tfd->is_on_readable_called = false; + + grpc_closure_init(&tfd->on_readable, on_readable, tfd, + grpc_schedule_on_exec_ctx); + grpc_fd_notify_on_read(exec_ctx, tfd->fd, &tfd->on_readable); +} + +static void init_test_fds(grpc_exec_ctx *exec_ctx, test_fd *tfds, + const int num_fds) { + for (int i = 0; i < num_fds; i++) { + GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_init(&tfds[i].wakeup_fd)); + tfds[i].fd = grpc_fd_create(GRPC_WAKEUP_FD_GET_READ_FD(&tfds[i].wakeup_fd), + "test_fd"); + reset_test_fd(exec_ctx, &tfds[i]); + } +} + +static void cleanup_test_fds(grpc_exec_ctx *exec_ctx, test_fd *tfds, + const int num_fds) { + int release_fd; + + for (int i = 0; i < num_fds; i++) { + grpc_fd_shutdown(exec_ctx, tfds[i].fd, GRPC_ERROR_CREATE("fd cleanup")); + grpc_exec_ctx_flush(exec_ctx); + + /* grpc_fd_orphan frees the memory allocated for grpc_fd. Normally it also + * calls close() on the underlying fd. In our case, we are using + * grpc_wakeup_fd and we would like to destroy it ourselves (by calling + * grpc_wakeup_fd_destroy). To prevent grpc_fd from calling close() on the + * underlying fd, call it with a non-NULL 'release_fd' parameter */ + grpc_fd_orphan(exec_ctx, tfds[i].fd, NULL, &release_fd, "test_fd_cleanup"); + grpc_exec_ctx_flush(exec_ctx); + + grpc_wakeup_fd_destroy(&tfds[i].wakeup_fd); + } +} + +static void make_test_fds_readable(test_fd *tfds, const int num_fds) { + for (int i = 0; i < num_fds; i++) { + GPR_ASSERT(GRPC_ERROR_NONE == grpc_wakeup_fd_wakeup(&tfds[i].wakeup_fd)); + } +} + +static void verify_readable_and_reset(grpc_exec_ctx *exec_ctx, test_fd *tfds, + const int num_fds) { + for (int i = 0; i < num_fds; i++) { + /* Verify that the on_readable callback was called */ + GPR_ASSERT(tfds[i].is_on_readable_called); + + /* Reset the tfd[i] structure */ + GPR_ASSERT(GRPC_ERROR_NONE == + grpc_wakeup_fd_consume_wakeup(&tfds[i].wakeup_fd)); + reset_test_fd(exec_ctx, &tfds[i]); + } +} + +/******************************************************************************* + * Main tests + */ + +/* Test some typical scenarios in pollset_set */ +static void pollset_set_test_basic() { + /* We construct the following structure for this test: + * + * +---> FD0 (Added before PSS1, PS1 and PS2 are added to PSS0) + * | + * +---> FD5 (Added after PSS1, PS1 and PS2 are added to PSS0) + * | + * | + * | +---> FD1 (Added before PSS1 is added to PSS0) + * | | + * | +---> FD6 (Added after PSS1 is added to PSS0) + * | | + * +---> PSS1--+ +--> FD2 (Added before PS0 is added to PSS1) + * | | | + * | +---> PS0---+ + * | | + * PSS0---+ +--> FD7 (Added after PS0 is added to PSS1) + * | + * | + * | +---> FD3 (Added before PS1 is added to PSS0) + * | | + * +---> PS1---+ + * | | + * | +---> FD8 (Added after PS1 added to PSS0) + * | + * | + * | +---> FD4 (Added before PS2 is added to PSS0) + * | | + * +---> PS2---+ + * | + * +---> FD9 (Added after PS2 is added to PSS0) + */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_pollset_worker *worker; + gpr_timespec deadline; + + test_fd tfds[10]; + test_pollset pollsets[3]; + test_pollset_set pollset_sets[2]; + const int num_fds = GPR_ARRAY_SIZE(tfds); + const int num_ps = GPR_ARRAY_SIZE(pollsets); + const int num_pss = GPR_ARRAY_SIZE(pollset_sets); + + init_test_fds(&exec_ctx, tfds, num_fds); + init_test_pollsets(pollsets, num_ps); + init_test_pollset_sets(pollset_sets, num_pss); + + /* Construct the pollset_set/pollset/fd tree (see diagram above) */ + + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); + + grpc_pollset_add_fd(&exec_ctx, pollsets[0].ps, tfds[2].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[3].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[2].ps, tfds[4].fd); + + grpc_pollset_set_add_pollset_set(&exec_ctx, pollset_sets[0].pss, + pollset_sets[1].pss); + + grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[1].pss, pollsets[0].ps); + grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[1].ps); + grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[2].ps); + + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[5].fd); + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[6].fd); + + grpc_pollset_add_fd(&exec_ctx, pollsets[0].ps, tfds[7].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[8].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[2].ps, tfds[9].fd); + + grpc_exec_ctx_flush(&exec_ctx); + + /* Test that if any FD in the above structure is readable, it is observable by + * doing grpc_pollset_work on any pollset + * + * For every pollset, do the following: + * - (Ensure that all FDs are in reset state) + * - Make all FDs readable + * - Call grpc_pollset_work() on the pollset + * - Flush the exec_ctx + * - Verify that on_readable call back was called for all FDs (and + * reset the FDs) + * */ + for (int i = 0; i < num_ps; i++) { + make_test_fds_readable(tfds, num_fds); + + gpr_mu_lock(pollsets[i].mu); + deadline = grpc_timeout_milliseconds_to_deadline(2); + GPR_ASSERT(GRPC_ERROR_NONE == + grpc_pollset_work(&exec_ctx, pollsets[i].ps, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + gpr_mu_unlock(pollsets[i].mu); + + grpc_exec_ctx_flush(&exec_ctx); + + verify_readable_and_reset(&exec_ctx, tfds, num_fds); + grpc_exec_ctx_flush(&exec_ctx); + } + + /* Test tear down */ + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[5].fd); + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[6].fd); + grpc_exec_ctx_flush(&exec_ctx); + + grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[1].pss, pollsets[0].ps); + grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[1].ps); + grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[0].pss, pollsets[2].ps); + + grpc_pollset_set_del_pollset_set(&exec_ctx, pollset_sets[0].pss, + pollset_sets[1].pss); + grpc_exec_ctx_flush(&exec_ctx); + + cleanup_test_fds(&exec_ctx, tfds, num_fds); + cleanup_test_pollsets(&exec_ctx, pollsets, num_ps); + cleanup_test_pollset_sets(pollset_sets, num_pss); + grpc_exec_ctx_finish(&exec_ctx); +} + +/* Same FD added multiple times to the pollset_set tree */ +void pollset_set_test_dup_fds() { + /* We construct the following structure for this test: + * + * +---> FD0 + * | + * | + * PSS0---+ + * | +---> FD0 (also under PSS0) + * | | + * +---> PSS1--+ +--> FD1 (also under PSS1) + * | | + * +---> PS ---+ + * | | + * | +--> FD2 + * +---> FD1 + */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_pollset_worker *worker; + gpr_timespec deadline; + + test_fd tfds[3]; + test_pollset pollset; + test_pollset_set pollset_sets[2]; + const int num_fds = GPR_ARRAY_SIZE(tfds); + const int num_ps = 1; + const int num_pss = GPR_ARRAY_SIZE(pollset_sets); + + init_test_fds(&exec_ctx, tfds, num_fds); + init_test_pollsets(&pollset, num_ps); + init_test_pollset_sets(pollset_sets, num_pss); + + /* Construct the structure */ + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[0].fd); + grpc_pollset_set_add_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); + + grpc_pollset_add_fd(&exec_ctx, pollset.ps, tfds[1].fd); + grpc_pollset_add_fd(&exec_ctx, pollset.ps, tfds[2].fd); + + grpc_pollset_set_add_pollset(&exec_ctx, pollset_sets[1].pss, pollset.ps); + grpc_pollset_set_add_pollset_set(&exec_ctx, pollset_sets[0].pss, + pollset_sets[1].pss); + + /* Test. Make all FDs readable and make sure that can be observed by doing a + * grpc_pollset_work on the pollset 'PS' */ + make_test_fds_readable(tfds, num_fds); + + gpr_mu_lock(pollset.mu); + deadline = grpc_timeout_milliseconds_to_deadline(2); + GPR_ASSERT(GRPC_ERROR_NONE == + grpc_pollset_work(&exec_ctx, pollset.ps, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + gpr_mu_unlock(pollset.mu); + grpc_exec_ctx_flush(&exec_ctx); + + verify_readable_and_reset(&exec_ctx, tfds, num_fds); + grpc_exec_ctx_flush(&exec_ctx); + + /* Tear down */ + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[0].pss, tfds[0].fd); + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[0].fd); + grpc_pollset_set_del_fd(&exec_ctx, pollset_sets[1].pss, tfds[1].fd); + + grpc_pollset_set_del_pollset(&exec_ctx, pollset_sets[1].pss, pollset.ps); + grpc_pollset_set_del_pollset_set(&exec_ctx, pollset_sets[0].pss, + pollset_sets[1].pss); + grpc_exec_ctx_flush(&exec_ctx); + + cleanup_test_fds(&exec_ctx, tfds, num_fds); + cleanup_test_pollsets(&exec_ctx, &pollset, num_ps); + cleanup_test_pollset_sets(pollset_sets, num_pss); + grpc_exec_ctx_finish(&exec_ctx); +} + +/* Pollset_set with an empty pollset */ +void pollset_set_test_empty_pollset() { + /* We construct the following structure for this test: + * + * +---> PS0 (EMPTY) + * | + * +---> FD0 + * | + * PSS0---+ + * | +---> FD1 + * | | + * +---> PS1--+ + * | + * +---> FD2 + */ + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_pollset_worker *worker; + gpr_timespec deadline; + + test_fd tfds[3]; + test_pollset pollsets[2]; + test_pollset_set pollset_set; + const int num_fds = GPR_ARRAY_SIZE(tfds); + const int num_ps = GPR_ARRAY_SIZE(pollsets); + const int num_pss = 1; + + init_test_fds(&exec_ctx, tfds, num_fds); + init_test_pollsets(pollsets, num_ps); + init_test_pollset_sets(&pollset_set, num_pss); + + /* Construct the structure */ + grpc_pollset_set_add_fd(&exec_ctx, pollset_set.pss, tfds[0].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[1].fd); + grpc_pollset_add_fd(&exec_ctx, pollsets[1].ps, tfds[2].fd); + + grpc_pollset_set_add_pollset(&exec_ctx, pollset_set.pss, pollsets[0].ps); + grpc_pollset_set_add_pollset(&exec_ctx, pollset_set.pss, pollsets[1].ps); + + /* Test. Make all FDs readable and make sure that can be observed by doing + * grpc_pollset_work on the empty pollset 'PS0' */ + make_test_fds_readable(tfds, num_fds); + + gpr_mu_lock(pollsets[0].mu); + deadline = grpc_timeout_milliseconds_to_deadline(2); + GPR_ASSERT(GRPC_ERROR_NONE == + grpc_pollset_work(&exec_ctx, pollsets[0].ps, &worker, + gpr_now(GPR_CLOCK_MONOTONIC), deadline)); + gpr_mu_unlock(pollsets[0].mu); + grpc_exec_ctx_flush(&exec_ctx); + + verify_readable_and_reset(&exec_ctx, tfds, num_fds); + grpc_exec_ctx_flush(&exec_ctx); + + /* Tear down */ + grpc_pollset_set_del_fd(&exec_ctx, pollset_set.pss, tfds[0].fd); + grpc_pollset_set_del_pollset(&exec_ctx, pollset_set.pss, pollsets[0].ps); + grpc_pollset_set_del_pollset(&exec_ctx, pollset_set.pss, pollsets[1].ps); + grpc_exec_ctx_flush(&exec_ctx); + + cleanup_test_fds(&exec_ctx, tfds, num_fds); + cleanup_test_pollsets(&exec_ctx, pollsets, num_ps); + cleanup_test_pollset_sets(&pollset_set, num_pss); + grpc_exec_ctx_finish(&exec_ctx); +} + +int main(int argc, char **argv) { + const char *poll_strategy = grpc_get_poll_strategy_name(); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + grpc_test_init(argc, argv); + grpc_iomgr_init(); + + if (poll_strategy != NULL && strcmp(poll_strategy, "epoll") == 0) { + pollset_set_test_basic(); + pollset_set_test_dup_fds(); + pollset_set_test_empty_pollset(); + } else { + gpr_log(GPR_INFO, + "Skipping the test. The test is only relevant for 'epoll' " + "strategy. and the current strategy is: '%s'", + poll_strategy); + } + + grpc_iomgr_shutdown(&exec_ctx); + grpc_exec_ctx_finish(&exec_ctx); + return 0; +} +#else /* defined(GRPC_LINUX_EPOLL) */ +int main(int argc, char **argv) { return 0; } +#endif /* !defined(GRPC_LINUX_EPOLL) */ diff --git a/test/core/iomgr/udp_server_test.c b/test/core/iomgr/udp_server_test.c index ba7a52ea21..ba572017a2 100644 --- a/test/core/iomgr/udp_server_test.c +++ b/test/core/iomgr/udp_server_test.c @@ -88,7 +88,7 @@ static void on_write(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) { gpr_mu_unlock(g_mu); } -static void on_fd_orphaned(grpc_fd *emfd) { +static void on_fd_orphaned(grpc_exec_ctx *exec_ctx, grpc_fd *emfd) { gpr_log(GPR_INFO, "gRPC FD about to be orphaned: %d", grpc_fd_wrapped_fd(emfd)); g_number_of_orphan_calls++; diff --git a/test/core/surface/secure_channel_create_test.c b/test/core/surface/secure_channel_create_test.c index ab4067dbe1..567f8ae16e 100644 --- a/test/core/surface/secure_channel_create_test.c +++ b/test/core/surface/secure_channel_create_test.c @@ -43,45 +43,44 @@ #include "test/core/util/test_config.h" void test_unknown_scheme_target(void) { - grpc_channel *chan; - grpc_channel_credentials *creds; grpc_resolver_registry_shutdown(); grpc_resolver_registry_init(); - - creds = grpc_fake_transport_security_credentials_create(); - chan = grpc_secure_channel_create(creds, "blah://blah", NULL, NULL); - GPR_ASSERT(chan == NULL); + grpc_channel_credentials *creds = + grpc_fake_transport_security_credentials_create(); + grpc_channel *chan = + grpc_secure_channel_create(creds, "blah://blah", NULL, NULL); + grpc_channel_element *elem = + grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); + GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test"); grpc_channel_credentials_unref(&exec_ctx, creds); grpc_exec_ctx_finish(&exec_ctx); } void test_security_connector_already_in_arg(void) { - grpc_channel *chan; - grpc_channel_element *elem; - grpc_channel_args args; grpc_arg arg; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - arg.type = GRPC_ARG_POINTER; arg.value.pointer.p = NULL; - arg.key = GRPC_SECURITY_CONNECTOR_ARG; + arg.key = GRPC_ARG_SECURITY_CONNECTOR; + grpc_channel_args args; args.num_args = 1; args.args = &arg; - chan = grpc_secure_channel_create(NULL, NULL, &args, NULL); - elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); + grpc_channel *chan = grpc_secure_channel_create(NULL, NULL, &args, NULL); + grpc_channel_element *elem = + grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test"); grpc_exec_ctx_finish(&exec_ctx); } void test_null_creds(void) { - grpc_channel *chan; - grpc_channel_element *elem; - grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; - chan = grpc_secure_channel_create(NULL, NULL, NULL, NULL); - elem = grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); + grpc_channel *chan = grpc_secure_channel_create(NULL, NULL, NULL, NULL); + grpc_channel_element *elem = + grpc_channel_stack_element(grpc_channel_get_channel_stack(chan), 0); GPR_ASSERT(0 == strcmp(elem->filter->name, "lame-client")); + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; GRPC_CHANNEL_INTERNAL_UNREF(&exec_ctx, chan, "test"); grpc_exec_ctx_finish(&exec_ctx); } diff --git a/test/cpp/codegen/codegen_test_full.cc b/test/cpp/codegen/codegen_test_full.cc index d6e2416b55..bc19fc9669 100644 --- a/test/cpp/codegen/codegen_test_full.cc +++ b/test/cpp/codegen/codegen_test_full.cc @@ -1,6 +1,6 @@ /* * - * Copyright 2016, Google Inc. + * Copyright 2017, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/test/cpp/codegen/proto_utils_test.cc b/test/cpp/codegen/proto_utils_test.cc new file mode 100644 index 0000000000..1daa142b50 --- /dev/null +++ b/test/cpp/codegen/proto_utils_test.cc @@ -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. + * + */ + +#include <grpc++/impl/codegen/proto_utils.h> +#include <grpc++/impl/grpc_library.h> +#include <gtest/gtest.h> + +namespace grpc { +namespace internal { + +static GrpcLibraryInitializer g_gli_initializer; + +// Provide access to GrpcBufferWriter internals. +class GrpcBufferWriterPeer { + public: + explicit GrpcBufferWriterPeer(internal::GrpcBufferWriter* writer) + : writer_(writer) {} + bool have_backup() const { return writer_->have_backup_; } + const grpc_slice& backup_slice() const { return writer_->backup_slice_; } + const grpc_slice& slice() const { return writer_->slice_; } + + private: + GrpcBufferWriter* writer_; +}; + +class ProtoUtilsTest : public ::testing::Test {}; + +// Regression test for a memory corruption bug where a series of +// GrpcBufferWriter Next()/Backup() invocations could result in a dangling +// pointer returned by Next() due to the interaction between grpc_slice inlining +// and GRPC_SLICE_START_PTR. +TEST_F(ProtoUtilsTest, BackupNext) { + // Ensure the GrpcBufferWriter internals are initialized. + g_gli_initializer.summon(); + + grpc_byte_buffer* bp; + GrpcBufferWriter writer(&bp, 8192); + GrpcBufferWriterPeer peer(&writer); + + void* data; + int size; + // Allocate a slice. + ASSERT_TRUE(writer.Next(&data, &size)); + EXPECT_EQ(8192, size); + // Return a single byte. Before the fix that this test acts as a regression + // for, this would have resulted in an inlined backup slice. + writer.BackUp(1); + EXPECT_TRUE(!peer.have_backup()); + // On the next allocation, the slice is non-inlined. + ASSERT_TRUE(writer.Next(&data, &size)); + EXPECT_TRUE(peer.slice().refcount != NULL); + + // Cleanup. + g_core_codegen_interface->grpc_byte_buffer_destroy(bp); +} + +} // namespace internal +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/shutdown_test.cc b/test/cpp/end2end/shutdown_test.cc index 5b52b1fc1a..bd68e851d3 100644 --- a/test/cpp/end2end/shutdown_test.cc +++ b/test/cpp/end2end/shutdown_test.cc @@ -49,6 +49,7 @@ #include "src/proto/grpc/testing/echo.grpc.pb.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" +#include "test/cpp/util/test_credentials_provider.h" using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; @@ -72,7 +73,7 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { gpr_event* ev_; }; -class ShutdownTest : public ::testing::Test { +class ShutdownTest : public ::testing::TestWithParam<string> { public: ShutdownTest() : shutdown_(false), service_(&ev_) { gpr_event_init(&ev_); } @@ -85,7 +86,9 @@ class ShutdownTest : public ::testing::Test { grpc::string server_address = "localhost:" + to_string(port); ServerBuilder builder; - builder.AddListeningPort(server_address, InsecureServerCredentials()); + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(GetParam()); + builder.AddListeningPort(server_address, server_creds); builder.RegisterService(&service_); std::unique_ptr<Server> server = builder.BuildAndStart(); return server; @@ -95,7 +98,10 @@ class ShutdownTest : public ::testing::Test { void ResetStub() { string target = "dns:localhost:" + to_string(port_); - channel_ = CreateChannel(target, InsecureChannelCredentials()); + ChannelArguments args; + auto channel_creds = + GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args); + channel_ = CreateCustomChannel(target, channel_creds, args); stub_ = grpc::testing::EchoTestService::NewStub(channel_); } @@ -125,8 +131,31 @@ class ShutdownTest : public ::testing::Test { TestServiceImpl service_; }; +std::vector<string> GetAllCredentialsTypeList() { + std::vector<grpc::string> credentials_types; + if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType, + nullptr) != nullptr) { + credentials_types.push_back(kInsecureCredentialsType); + } + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + GPR_ASSERT(!credentials_types.empty()); + + std::string credentials_type_list("credentials types:"); + for (const string& type : credentials_types) { + credentials_type_list.append(" " + type); + } + gpr_log(GPR_INFO, "%s", credentials_type_list.c_str()); + return credentials_types; +} + +INSTANTIATE_TEST_CASE_P(End2EndShutdown, ShutdownTest, + ::testing::ValuesIn(GetAllCredentialsTypeList())); + // TODO(ctiller): leaked objects in this test -TEST_F(ShutdownTest, ShutdownTest) { +TEST_P(ShutdownTest, ShutdownTest) { ResetStub(); // send the request in a background thread diff --git a/test/cpp/grpclb/grpclb_test.cc b/test/cpp/grpclb/grpclb_test.cc index 4b8a434c78..89ed9249ad 100644 --- a/test/cpp/grpclb/grpclb_test.cc +++ b/test/cpp/grpclb/grpclb_test.cc @@ -52,8 +52,10 @@ #include <grpc++/impl/codegen/config.h> extern "C" { #include "src/core/ext/client_channel/client_channel.h" +#include "src/core/lib/channel/channel_args.h" #include "src/core/lib/channel/channel_stack.h" #include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" #include "src/core/lib/support/string.h" #include "src/core/lib/support/tmpfile.h" #include "src/core/lib/surface/channel.h" @@ -110,6 +112,7 @@ typedef struct server_fixture { grpc_call *server_call; grpc_completion_queue *cq; char *servers_hostport; + const char *balancer_name; int port; const char *lb_token_prefix; gpr_thd_id tid; @@ -201,10 +204,12 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, &request_metadata_recv, sf->cq, sf->cq, tag(200)); GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "LB Server[%s] up", sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) up", sf->servers_hostport, + sf->balancer_name); CQ_EXPECT_COMPLETION(cqv, tag(200), 1); cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s] after tag 200", sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 200", sf->servers_hostport, + sf->balancer_name); // make sure we've received the initial metadata from the grpclb request. GPR_ASSERT(request_metadata_recv.count > 0); @@ -221,7 +226,8 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(202), 1); cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s] after RECV_MSG", sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) after RECV_MSG", sf->servers_hostport, + sf->balancer_name); // validate initial request. grpc_byte_buffer_reader bbr; @@ -250,7 +256,8 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, op++; error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(201), NULL); GPR_ASSERT(GRPC_CALL_OK == error); - gpr_log(GPR_INFO, "LB Server[%s] after tag 201", sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 201", sf->servers_hostport, + sf->balancer_name); for (int i = 0; i < 2; i++) { if (i == 0) { @@ -276,13 +283,14 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, GPR_ASSERT(GRPC_CALL_OK == error); CQ_EXPECT_COMPLETION(cqv, tag(203), 1); cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s] after SEND_MESSAGE, iter %d", - sf->servers_hostport, i); + gpr_log(GPR_INFO, "LB Server[%s](%s) after SEND_MESSAGE, iter %d", + sf->servers_hostport, sf->balancer_name, i); grpc_byte_buffer_destroy(response_payload); grpc_slice_unref(response_payload_slice); } - gpr_log(GPR_INFO, "LB Server[%s] shutting down", sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) shutting down", sf->servers_hostport, + sf->balancer_name); op = ops; op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; @@ -299,8 +307,8 @@ static void start_lb_server(server_fixture *sf, int *ports, size_t nports, CQ_EXPECT_COMPLETION(cqv, tag(201), 1); CQ_EXPECT_COMPLETION(cqv, tag(204), 1); cq_verify(cqv); - gpr_log(GPR_INFO, "LB Server[%s] after tag 204. All done. LB server out", - sf->servers_hostport); + gpr_log(GPR_INFO, "LB Server[%s](%s) after tag 204. All done. LB server out", + sf->servers_hostport, sf->balancer_name); grpc_call_destroy(s); @@ -561,10 +569,38 @@ static void perform_request(client_fixture *cf) { gpr_free(peer); } -static void setup_client(const char *server_hostport, client_fixture *cf) { +#define BALANCERS_NAME "lb.name" +static void setup_client(const server_fixture *lb_server, + const server_fixture *backends, client_fixture *cf) { + grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; + char *lb_uri; + // The grpclb LB policy will be automatically selected by virtue of + // the fact that the returned addresses are balancer addresses. + gpr_asprintf(&lb_uri, "test:///%s?lb_enabled=1&balancer_names=%s", + lb_server->servers_hostport, lb_server->balancer_name); + + grpc_arg expected_target_arg; + expected_target_arg.type = GRPC_ARG_STRING; + expected_target_arg.key = + const_cast<char *>(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS); + + char *expected_target_names = NULL; + const char *backends_name = lb_server->servers_hostport; + gpr_asprintf(&expected_target_names, "%s;%s", backends_name, BALANCERS_NAME); + + expected_target_arg.value.string = const_cast<char *>(expected_target_names); + grpc_channel_args *args = + grpc_channel_args_copy_and_add(NULL, &expected_target_arg, 1); + gpr_free(expected_target_names); + cf->cq = grpc_completion_queue_create(NULL); - cf->server_uri = gpr_strdup(server_hostport); - cf->client = grpc_insecure_channel_create(cf->server_uri, NULL, NULL); + cf->server_uri = lb_uri; + grpc_channel_credentials *fake_creds = + grpc_fake_transport_security_credentials_create(); + cf->client = + grpc_secure_channel_create(fake_creds, cf->server_uri, args, NULL); + grpc_channel_credentials_unref(&exec_ctx, fake_creds); + grpc_channel_args_destroy(&exec_ctx, args); } static void teardown_client(client_fixture *cf) { @@ -591,10 +627,14 @@ static void setup_server(const char *host, server_fixture *sf) { gpr_join_host_port(&sf->servers_hostport, host, sf->port); } + grpc_server_credentials *server_creds = + grpc_fake_transport_security_server_credentials_create(); + sf->server = grpc_server_create(NULL, NULL); grpc_server_register_completion_queue(sf->server, sf->cq, NULL); - GPR_ASSERT((assigned_port = grpc_server_add_insecure_http2_port( - sf->server, sf->servers_hostport)) > 0); + GPR_ASSERT((assigned_port = grpc_server_add_secure_http2_port( + sf->server, sf->servers_hostport, server_creds)) > 0); + grpc_server_credentials_release(server_creds); GPR_ASSERT(sf->port == assigned_port); grpc_server_start(sf->server); } @@ -656,17 +696,10 @@ static test_fixture setup_test_fixture(int lb_server_update_delay_ms) { } tf.lb_server.lb_token_prefix = LB_TOKEN_PREFIX; + tf.lb_server.balancer_name = BALANCERS_NAME; setup_server("127.0.0.1", &tf.lb_server); gpr_thd_new(&tf.lb_server.tid, fork_lb_server, &tf.lb_server, &options); - - char *server_uri; - // The grpclb LB policy will be automatically selected by virtue of - // the fact that the returned addresses are balancer addresses. - gpr_asprintf(&server_uri, "test:///%s?lb_enabled=1", - tf.lb_server.servers_hostport); - setup_client(server_uri, &tf.client); - gpr_free(server_uri); - + setup_client(&tf.lb_server, tf.lb_backends, &tf.client); return tf; } @@ -711,8 +744,9 @@ TEST(GrpclbTest, Updates) { // batch 1. All subsequent picks will come from the second half of the // backends, those coming in the LB update. tf_result = grpc::test_update(800); - GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced == 1); - GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 0); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced + + tf_result.lb_backends[1].num_calls_serviced == + 1); GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced + tf_result.lb_backends[3].num_calls_serviced > 0); @@ -728,8 +762,9 @@ TEST(GrpclbTest, Updates) { // update. In any case, the total number of serviced calls must again be equal // to four across all the backends. tf_result = grpc::test_update(2500); - GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced >= 1); - GPR_ASSERT(tf_result.lb_backends[1].num_calls_serviced == 1); + GPR_ASSERT(tf_result.lb_backends[0].num_calls_serviced + + tf_result.lb_backends[1].num_calls_serviced >= + 2); GPR_ASSERT(tf_result.lb_backends[2].num_calls_serviced + tf_result.lb_backends[3].num_calls_serviced > 0); diff --git a/test/cpp/microbenchmarks/bm_fullstack.cc b/test/cpp/microbenchmarks/bm_fullstack.cc index c3e96c572c..9d883e68d7 100644 --- a/test/cpp/microbenchmarks/bm_fullstack.cc +++ b/test/cpp/microbenchmarks/bm_fullstack.cc @@ -54,9 +54,11 @@ extern "C" { #include "src/core/lib/surface/channel.h" #include "src/core/lib/surface/completion_queue.h" #include "src/core/lib/surface/server.h" +#include "test/core/util/memory_counters.h" #include "test/core/util/passthru_endpoint.h" #include "test/core/util/port.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 "third_party/benchmark/include/benchmark/benchmark.h" @@ -67,6 +69,7 @@ namespace testing { static class InitializeStuff { public: InitializeStuff() { + grpc_memory_counters_init(); init_lib_.init(); rq_ = grpc_resource_quota_create("bm"); } @@ -94,7 +97,42 @@ static void ApplyCommonChannelArguments(ChannelArguments* c) { c->SetInt(GRPC_ARG_MAX_SEND_MESSAGE_LENGTH, INT_MAX); } -class FullstackFixture { +#ifdef GPR_MU_COUNTERS +extern "C" gpr_atm grpc_mu_locks; +#endif + +class BaseFixture { + public: + void Finish(benchmark::State& s) { + std::ostringstream out; + this->AddToLabel(out, s); +#ifdef GPR_MU_COUNTERS + out << " locks/iter:" << ((double)(gpr_atm_no_barrier_load(&grpc_mu_locks) - + mu_locks_at_start_) / + (double)s.iterations()); +#endif + grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot(); + out << " allocs/iter:" + << ((double)(counters_at_end.total_allocs_absolute - + counters_at_start_.total_allocs_absolute) / + (double)s.iterations()); + auto label = out.str(); + if (label.length() && label[0] == ' ') { + label = label.substr(1); + } + s.SetLabel(label); + } + + virtual void AddToLabel(std::ostream& out, benchmark::State& s) = 0; + + private: +#ifdef GPR_MU_COUNTERS + const size_t mu_locks_at_start_ = gpr_atm_no_barrier_load(&grpc_mu_locks); +#endif + grpc_memory_counters counters_at_start_ = grpc_memory_counters_snapshot(); +}; + +class FullstackFixture : public BaseFixture { public: FullstackFixture(Service* service, const grpc::string& address) { ServerBuilder b; @@ -130,7 +168,7 @@ class TCP : public FullstackFixture { public: TCP(Service* service) : FullstackFixture(service, MakeAddress()) {} - void Finish(benchmark::State& state) {} + void AddToLabel(std::ostream& out, benchmark::State& state) {} private: static grpc::string MakeAddress() { @@ -145,7 +183,7 @@ class UDS : public FullstackFixture { public: UDS(Service* service) : FullstackFixture(service, MakeAddress()) {} - void Finish(benchmark::State& state) {} + void AddToLabel(std::ostream& out, benchmark::State& state) override {} private: static grpc::string MakeAddress() { @@ -157,7 +195,7 @@ class UDS : public FullstackFixture { } }; -class EndpointPairFixture { +class EndpointPairFixture : public BaseFixture { public: EndpointPairFixture(Service* service, grpc_endpoint_pair endpoints) { ServerBuilder b; @@ -233,7 +271,7 @@ class SockPair : public EndpointPairFixture { "test", initialize_stuff.rq(), 8192)) { } - void Finish(benchmark::State& state) {} + void AddToLabel(std::ostream& out, benchmark::State& state) {} }; class InProcessCHTTP2 : public EndpointPairFixture { @@ -241,11 +279,9 @@ class InProcessCHTTP2 : public EndpointPairFixture { InProcessCHTTP2(Service* service) : EndpointPairFixture(service, MakeEndpoints()) {} - void Finish(benchmark::State& state) { - std::ostringstream out; - out << "writes/iteration:" + void AddToLabel(std::ostream& out, benchmark::State& state) { + out << " writes/iter:" << ((double)stats_.num_writes / (double)state.iterations()); - state.SetLabel(out.str()); } private: @@ -402,6 +438,7 @@ static void BM_UnaryPingPong(benchmark::State& state) { std::unique_ptr<EchoTestService::Stub> stub( EchoTestService::NewStub(fixture->channel())); while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); recv_response.Clear(); ClientContext cli_ctx; ClientContextMutator cli_ctx_mut(&cli_ctx); @@ -439,6 +476,191 @@ static void BM_UnaryPingPong(benchmark::State& state) { state.range(1) * state.iterations()); } +// Repeatedly makes Streaming Bidi calls (exchanging a configurable number of +// messages in each call) in a loop on a single channel +// +// 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): +template <class Fixture, class ClientContextMutator, class ServerContextMutator> +static void BM_StreamingPingPong(benchmark::State& state) { + const int msg_size = state.range(0); + const int max_ping_pongs = state.range(1); + + 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); + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + + // Establish async stream between client side and server side + void* t; + bool ok; + int need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + + // Send 'max_ping_pongs' number of ping pong messages + int ping_pong_cnt = 0; + while (ping_pong_cnt < max_ping_pongs) { + request_rw->Write(send_request, tag(0)); // Start client send + response_rw.Read(&recv_request, tag(1)); // Start server recv + request_rw->Read(&recv_response, tag(2)); // Start client recv + + need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); + 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 == 1) { + response_rw.Write(send_response, tag(3)); + } + + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + + ping_pong_cnt++; + } + + request_rw->WritesDone(tag(0)); + response_rw.Finish(Status::OK, tag(1)); + + Status recv_status; + request_rw->Finish(&recv_status, tag(2)); + + need_tags = (1 << 0) | (1 << 1) | (1 << 2); + 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); +} + +// Repeatedly sends ping pong messages in a single streaming Bidi call in a loop +// First parmeter (i.e state.range(0)): Message size (in bytes) to use +template <class Fixture, class ClientContextMutator, class ServerContextMutator> +static void BM_StreamingPingPongMsgs(benchmark::State& state) { + const int msg_size = state.range(0); + + 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())); + + 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); + auto request_rw = stub->AsyncBidiStream(&cli_ctx, fixture->cq(), tag(1)); + + // Establish async stream between client side and server side + void* t; + bool ok; + int need_tags = (1 << 0) | (1 << 1); + while (need_tags) { + GPR_ASSERT(fixture->cq()->Next(&t, &ok)); + GPR_ASSERT(ok); + int i = (int)(intptr_t)t; + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + + while (state.KeepRunning()) { + request_rw->Write(send_request, tag(0)); // Start client send + response_rw.Read(&recv_request, tag(1)); // Start server recv + request_rw->Read(&recv_response, tag(2)); // Start client recv + + need_tags = (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3); + 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 == 1) { + response_rw.Write(send_response, tag(3)); + } + + GPR_ASSERT(need_tags & (1 << i)); + need_tags &= ~(1 << i); + } + } + + request_rw->WritesDone(tag(0)); + response_rw.Finish(Status::OK, tag(1)); + Status recv_status; + request_rw->Finish(&recv_status, tag(2)); + + need_tags = (1 << 0) | (1 << 1) | (1 << 2); + 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() * 2); +} + template <class Fixture> static void BM_PumpStreamClientToServer(benchmark::State& state) { EchoTestService::AsyncService service; @@ -470,6 +692,7 @@ static void BM_PumpStreamClientToServer(benchmark::State& state) { } response_rw.Read(&recv_request, tag(0)); while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); request_rw->Write(send_request, tag(1)); while (true) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); @@ -527,6 +750,7 @@ static void BM_PumpStreamServerToClient(benchmark::State& state) { } request_rw->Read(&recv_response, tag(0)); while (state.KeepRunning()) { + GPR_TIMER_SCOPE("BenchmarkCycle", 0); response_rw.Write(send_response, tag(1)); while (true) { GPR_ASSERT(fixture->cq()->Next(&t, &ok)); @@ -642,6 +866,32 @@ BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, SockPair) BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, InProcessCHTTP2) ->Range(0, 128 * 1024 * 1024); +// Generate Args for StreamingPingPong benchmarks. Currently generates args for +// only "small streams" (i.e streams with 0, 1 or 2 messages) +static void StreamingPingPongArgs(benchmark::internal::Benchmark* b) { + int msg_size = 0; + + b->Args({0, 0}); // 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}); + b->Args({msg_size, 2}); + } +} + +BENCHMARK_TEMPLATE(BM_StreamingPingPong, InProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Apply(StreamingPingPongArgs); +BENCHMARK_TEMPLATE(BM_StreamingPingPong, TCP, NoOpMutator, NoOpMutator) + ->Apply(StreamingPingPongArgs); + +BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, InProcessCHTTP2, NoOpMutator, + NoOpMutator) + ->Range(0, 128 * 1024 * 1024); +BENCHMARK_TEMPLATE(BM_StreamingPingPongMsgs, TCP, NoOpMutator, NoOpMutator) + ->Range(0, 128 * 1024 * 1024); + } // namespace testing } // namespace grpc |