diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/build/no-c++14-compat.cc | 19 | ||||
-rw-r--r-- | test/build/no-unused-but-set-variable.c | 19 | ||||
-rw-r--r-- | test/core/end2end/end2end_nosec_tests.cc | 8 | ||||
-rw-r--r-- | test/core/end2end/end2end_tests.cc | 8 | ||||
-rw-r--r-- | test/core/end2end/fixtures/h2_load_reporting.cc | 120 | ||||
-rwxr-xr-x | test/core/end2end/gen_build_yaml.py | 8 | ||||
-rwxr-xr-x | test/core/end2end/generate_tests.bzl | 9 | ||||
-rw-r--r-- | test/core/iomgr/BUILD | 21 | ||||
-rw-r--r-- | test/core/iomgr/ev_epollex_linux_test.cc | 115 | ||||
-rw-r--r-- | test/cpp/microbenchmarks/BUILD | 14 | ||||
-rw-r--r-- | test/cpp/microbenchmarks/bm_call_create.cc | 11 | ||||
-rw-r--r-- | test/cpp/microbenchmarks/bm_channel.cc | 90 | ||||
-rw-r--r-- | test/cpp/server/load_reporter/BUILD | 34 | ||||
-rw-r--r-- | test/cpp/server/load_reporter/get_cpu_stats_test.cc | 61 | ||||
-rw-r--r-- | test/cpp/server/load_reporter/load_data_store_test.cc | 4 | ||||
-rw-r--r-- | test/cpp/server/load_reporter/load_reporter_test.cc | 498 |
16 files changed, 889 insertions, 150 deletions
diff --git a/test/build/no-c++14-compat.cc b/test/build/no-c++14-compat.cc new file mode 100644 index 0000000000..0c1771c7bb --- /dev/null +++ b/test/build/no-c++14-compat.cc @@ -0,0 +1,19 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +int main(void) {} diff --git a/test/build/no-unused-but-set-variable.c b/test/build/no-unused-but-set-variable.c new file mode 100644 index 0000000000..0c1771c7bb --- /dev/null +++ b/test/build/no-unused-but-set-variable.c @@ -0,0 +1,19 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +int main(void) {} diff --git a/test/core/end2end/end2end_nosec_tests.cc b/test/core/end2end/end2end_nosec_tests.cc index 061b23b5d6..c6a4005fb3 100644 --- a/test/core/end2end/end2end_nosec_tests.cc +++ b/test/core/end2end/end2end_nosec_tests.cc @@ -88,8 +88,6 @@ extern void keepalive_timeout(grpc_end2end_test_config config); extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); -extern void load_reporting_hook(grpc_end2end_test_config config); -extern void load_reporting_hook_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); extern void max_concurrent_streams_pre_init(void); extern void max_connection_age(grpc_end2end_test_config config); @@ -220,7 +218,6 @@ void grpc_end2end_tests_pre_init(void) { invoke_large_request_pre_init(); keepalive_timeout_pre_init(); large_metadata_pre_init(); - load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); max_connection_age_pre_init(); max_connection_idle_pre_init(); @@ -307,7 +304,6 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); keepalive_timeout(config); large_metadata(config); - load_reporting_hook(config); max_concurrent_streams(config); max_connection_age(config); max_connection_idle(config); @@ -476,10 +472,6 @@ void grpc_end2end_tests(int argc, char **argv, large_metadata(config); continue; } - if (0 == strcmp("load_reporting_hook", argv[i])) { - load_reporting_hook(config); - continue; - } if (0 == strcmp("max_concurrent_streams", argv[i])) { max_concurrent_streams(config); continue; diff --git a/test/core/end2end/end2end_tests.cc b/test/core/end2end/end2end_tests.cc index 7ae475cdef..7748a39cb5 100644 --- a/test/core/end2end/end2end_tests.cc +++ b/test/core/end2end/end2end_tests.cc @@ -90,8 +90,6 @@ extern void keepalive_timeout(grpc_end2end_test_config config); extern void keepalive_timeout_pre_init(void); extern void large_metadata(grpc_end2end_test_config config); extern void large_metadata_pre_init(void); -extern void load_reporting_hook(grpc_end2end_test_config config); -extern void load_reporting_hook_pre_init(void); extern void max_concurrent_streams(grpc_end2end_test_config config); extern void max_concurrent_streams_pre_init(void); extern void max_connection_age(grpc_end2end_test_config config); @@ -223,7 +221,6 @@ void grpc_end2end_tests_pre_init(void) { invoke_large_request_pre_init(); keepalive_timeout_pre_init(); large_metadata_pre_init(); - load_reporting_hook_pre_init(); max_concurrent_streams_pre_init(); max_connection_age_pre_init(); max_connection_idle_pre_init(); @@ -311,7 +308,6 @@ void grpc_end2end_tests(int argc, char **argv, invoke_large_request(config); keepalive_timeout(config); large_metadata(config); - load_reporting_hook(config); max_concurrent_streams(config); max_connection_age(config); max_connection_idle(config); @@ -484,10 +480,6 @@ void grpc_end2end_tests(int argc, char **argv, large_metadata(config); continue; } - if (0 == strcmp("load_reporting_hook", argv[i])) { - load_reporting_hook(config); - continue; - } if (0 == strcmp("max_concurrent_streams", argv[i])) { max_concurrent_streams(config); continue; diff --git a/test/core/end2end/fixtures/h2_load_reporting.cc b/test/core/end2end/fixtures/h2_load_reporting.cc deleted file mode 100644 index 18ea10a8d2..0000000000 --- a/test/core/end2end/fixtures/h2_load_reporting.cc +++ /dev/null @@ -1,120 +0,0 @@ -/* - * - * Copyright 2016 gRPC authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include "test/core/end2end/end2end_tests.h" - -#include <string.h> - -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> - -#include "src/core/ext/filters/client_channel/client_channel.h" -#include "src/core/ext/filters/http/server/http_server_filter.h" -#include "src/core/ext/filters/load_reporting/server_load_reporting_plugin.h" -#include "src/core/ext/transport/chttp2/transport/chttp2_transport.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/channel/connected_channel.h" -#include "src/core/lib/gpr/host_port.h" -#include "src/core/lib/surface/channel.h" -#include "src/core/lib/surface/server.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" - -typedef struct load_reporting_fixture_data { - char* localaddr; -} load_reporting_fixture_data; - -static grpc_end2end_test_fixture chttp2_create_fixture_load_reporting( - grpc_channel_args* client_args, grpc_channel_args* server_args) { - grpc_end2end_test_fixture f; - int port = grpc_pick_unused_port_or_die(); - load_reporting_fixture_data* ffd = static_cast<load_reporting_fixture_data*>( - gpr_malloc(sizeof(load_reporting_fixture_data))); - memset(&f, 0, sizeof(f)); - - gpr_join_host_port(&ffd->localaddr, "localhost", port); - - f.fixture_data = ffd; - f.cq = grpc_completion_queue_create_for_next(nullptr); - f.shutdown_cq = grpc_completion_queue_create_for_pluck(nullptr); - - return f; -} - -void chttp2_init_client_load_reporting(grpc_end2end_test_fixture* f, - grpc_channel_args* client_args) { - load_reporting_fixture_data* ffd = - static_cast<load_reporting_fixture_data*>(f->fixture_data); - f->client = - grpc_insecure_channel_create(ffd->localaddr, client_args, nullptr); - GPR_ASSERT(f->client); -} - -void chttp2_init_server_load_reporting(grpc_end2end_test_fixture* f, - grpc_channel_args* server_args) { - load_reporting_fixture_data* ffd = - static_cast<load_reporting_fixture_data*>(f->fixture_data); - grpc_arg arg = grpc_load_reporting_enable_arg(); - if (f->server) { - grpc_server_destroy(f->server); - } - server_args = grpc_channel_args_copy_and_add(server_args, &arg, 1); - f->server = grpc_server_create(server_args, nullptr); - { - grpc_core::ExecCtx exec_ctx; - grpc_channel_args_destroy(server_args); - } - grpc_server_register_completion_queue(f->server, f->cq, nullptr); - GPR_ASSERT(grpc_server_add_insecure_http2_port(f->server, ffd->localaddr)); - grpc_server_start(f->server); -} - -void chttp2_tear_down_load_reporting(grpc_end2end_test_fixture* f) { - load_reporting_fixture_data* ffd = - static_cast<load_reporting_fixture_data*>(f->fixture_data); - gpr_free(ffd->localaddr); - gpr_free(ffd); -} - -/* All test configurations */ -static grpc_end2end_test_config configs[] = { - {"chttp2/fullstack+load_reporting", - FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION | - FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL | - FEATURE_MASK_SUPPORTS_AUTHORITY_HEADER, - nullptr, chttp2_create_fixture_load_reporting, - chttp2_init_client_load_reporting, chttp2_init_server_load_reporting, - chttp2_tear_down_load_reporting}, -}; - -int main(int argc, char** argv) { - size_t i; - - grpc_test_init(argc, argv); - grpc_end2end_tests_pre_init(); - grpc_init(); - - for (i = 0; i < sizeof(configs) / sizeof(*configs); i++) { - grpc_end2end_tests(argc, argv, configs[i]); - } - - grpc_shutdown(); - - return 0; -} diff --git a/test/core/end2end/gen_build_yaml.py b/test/core/end2end/gen_build_yaml.py index 04dc2a8785..d5c23262e3 100755 --- a/test/core/end2end/gen_build_yaml.py +++ b/test/core/end2end/gen_build_yaml.py @@ -47,7 +47,9 @@ inproc_fixture_options = default_unsecure_fixture_options._replace( END2END_FIXTURES = { 'h2_compress': default_unsecure_fixture_options._replace(enables_compression=True), 'h2_census': default_unsecure_fixture_options, - 'h2_load_reporting': default_unsecure_fixture_options, + # This cmake target is disabled for now because it depends on OpenCensus, + # which is Bazel-only. + # 'h2_load_reporting': default_unsecure_fixture_options, 'h2_fakesec': default_secure_fixture_options._replace(ci_mac=False), 'h2_fd': fd_unsecure_fixture_options, 'h2_full': default_unsecure_fixture_options, @@ -143,7 +145,9 @@ END2END_TESTS = { 'no_logging': default_test_options._replace(traceable=False), 'no_op': default_test_options, 'payload': default_test_options, - 'load_reporting_hook': default_test_options, + # This cmake target is disabled for now because it depends on OpenCensus, + # which is Bazel-only. + # 'load_reporting_hook': default_test_options, 'ping_pong_streaming': default_test_options._replace(cpu_cost=LOWCPU), 'ping': connectivity_test_options._replace(proxyable=False, cpu_cost=LOWCPU), diff --git a/test/core/end2end/generate_tests.bzl b/test/core/end2end/generate_tests.bzl index 67769a8cb1..39b11d08ad 100755 --- a/test/core/end2end/generate_tests.bzl +++ b/test/core/end2end/generate_tests.bzl @@ -45,7 +45,9 @@ def fixture_options(fullstack=True, includes_proxy=False, dns_resolver=True, END2END_FIXTURES = { 'h2_compress': fixture_options(), 'h2_census': fixture_options(), - 'h2_load_reporting': fixture_options(), + # TODO(juanlishen): This is disabled for now, but should be considered to re-enable once we have + # decided how the load reporting service should be enabled. + #'h2_load_reporting': fixture_options(), 'h2_fakesec': fixture_options(), 'h2_fd': fixture_options(dns_resolver=False, fullstack=False, client_channel=False, @@ -139,7 +141,10 @@ END2END_TESTS = { 'no_logging': test_options(traceable=False), 'no_op': test_options(), 'payload': test_options(), - 'load_reporting_hook': test_options(), + # TODO(juanlishen): This is disabled for now because it depends on some generated functions in + # end2end_tests.cc, which are not generated because they would depend on OpenCensus while + # OpenCensus can only be built via Bazel so far. + # 'load_reporting_hook': test_options(), 'ping_pong_streaming': test_options(), 'ping': test_options(needs_fullstack=True, proxyable=False), 'proxy_auth': test_options(needs_proxy_auth=True), diff --git a/test/core/iomgr/BUILD b/test/core/iomgr/BUILD index bbf0815e6f..cc1b6aee5e 100644 --- a/test/core/iomgr/BUILD +++ b/test/core/iomgr/BUILD @@ -18,7 +18,10 @@ licenses(["notice"]) # Apache v2 load("//test/core/util:grpc_fuzzer.bzl", "grpc_fuzzer") -grpc_package(name = "test/core/iomgr", visibility = "public") # Useful for third party devs to test their io manager implementation. +grpc_package( + name = "test/core/iomgr", + visibility = "public", +) # Useful for third party devs to test their io manager implementation. grpc_cc_library( name = "endpoint_tests", @@ -73,15 +76,27 @@ grpc_cc_test( ) grpc_cc_test( + name = "ev_epollex_linux_test", + srcs = ["ev_epollex_linux_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//:grpc", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( name = "ev_epollsig_linux_test", srcs = ["ev_epollsig_linux_test.cc"], + language = "C++", deps = [ "//:gpr", "//:grpc", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - language = "C++", ) grpc_cc_test( @@ -221,13 +236,13 @@ grpc_cc_test( name = "tcp_server_posix_test", srcs = ["tcp_server_posix_test.cc"], language = "C++", + tags = ["manual"], # TODO(adelez): Remove once this works on Foundry. deps = [ "//:gpr", "//:grpc", "//test/core/util:gpr_test_util", "//test/core/util:grpc_test_util", ], - tags = ["manual"], # TODO(adelez): Remove once this works on Foundry. ) grpc_cc_test( diff --git a/test/core/iomgr/ev_epollex_linux_test.cc b/test/core/iomgr/ev_epollex_linux_test.cc new file mode 100644 index 0000000000..08d1e68b39 --- /dev/null +++ b/test/core/iomgr/ev_epollex_linux_test.cc @@ -0,0 +1,115 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#include "src/core/lib/iomgr/port.h" + +/* This test only relevant on linux systems where epoll() is available */ +#if defined(GRPC_LINUX_EPOLL_CREATE1) && defined(GRPC_LINUX_EVENTFD) +#include "src/core/lib/iomgr/ev_epollex_linux.h" + +#include <grpc/grpc.h> +#include <string.h> +#include <sys/eventfd.h> + +#include "test/core/util/test_config.h" + +static void pollset_destroy(void* ps, grpc_error* error) { + grpc_pollset_destroy(static_cast<grpc_pollset*>(ps)); + gpr_free(ps); +} + +// This test is added to cover the case found in bug: +// https://github.com/grpc/grpc/issues/15760 +static void test_pollable_owner_fd() { + grpc_core::ExecCtx exec_ctx; + int ev_fd1; + int ev_fd2; + grpc_fd* grpc_fd1; + grpc_fd* grpc_fd2; + grpc_pollset* ps; + gpr_mu* mu; + + // == Create two grpc_fds == + // All we need is two file descriptors. Doesn't matter what type. We use + // eventfd type here for the purpose of this test + ev_fd1 = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + ev_fd2 = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + if (ev_fd1 < 0 || ev_fd2 < 0) { + gpr_log(GPR_ERROR, "Error in creating event fds for the test"); + return; + } + grpc_fd1 = grpc_fd_create(ev_fd1, "epollex-test-fd1", false); + grpc_fd2 = grpc_fd_create(ev_fd2, "epollex-test-fd2", false); + grpc_core::ExecCtx::Get()->Flush(); + + // == Create a pollset == + ps = static_cast<grpc_pollset*>(gpr_zalloc(grpc_pollset_size())); + grpc_pollset_init(ps, &mu); + grpc_core::ExecCtx::Get()->Flush(); + + // == Add fd1 to pollset == + grpc_pollset_add_fd(ps, grpc_fd1); + grpc_core::ExecCtx::Get()->Flush(); + + // == Destroy fd1 == + grpc_fd_orphan(grpc_fd1, nullptr, nullptr, "test fd1 orphan"); + grpc_core::ExecCtx::Get()->Flush(); + + // = Add fd2 to pollset == + // + // Before https://github.com/grpc/grpc/issues/15760, the following line caused + // unexpected behavior (The previous grpc_pollset_add_fd(ps, grpc_fd1) created + // an underlying structure in epollex that held a reference to grpc_fd1 which + // was being accessed here even after grpc_fd_orphan(grpc_fd1) was called + grpc_pollset_add_fd(ps, grpc_fd2); + grpc_core::ExecCtx::Get()->Flush(); + + // == Destroy fd2 == + grpc_fd_orphan(grpc_fd2, nullptr, nullptr, "test fd2 orphan"); + grpc_core::ExecCtx::Get()->Flush(); + + // == Destroy pollset + grpc_closure ps_destroy_closure; + GRPC_CLOSURE_INIT(&ps_destroy_closure, pollset_destroy, ps, + grpc_schedule_on_exec_ctx); + grpc_pollset_shutdown(ps, &ps_destroy_closure); + grpc_core::ExecCtx::Get()->Flush(); +} + +int main(int argc, char** argv) { + const char* poll_strategy = nullptr; + grpc_test_init(argc, argv); + grpc_init(); + { + grpc_core::ExecCtx exec_ctx; + poll_strategy = grpc_get_poll_strategy_name(); + if (poll_strategy != nullptr && strcmp(poll_strategy, "epollex") == 0) { + test_pollable_owner_fd(); + } else { + gpr_log(GPR_INFO, + "Skipping the test. The test is only relevant for 'epollex' " + "strategy. and the current strategy is: '%s'", + poll_strategy); + } + } + + grpc_shutdown(); + return 0; +} +#else /* defined(GRPC_LINUX_EPOLL_CREATE1) && defined(GRPC_LINUX_EVENTFD) */ +int main(int argc, char** argv) { return 0; } +#endif diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD index 7b27aed4c3..0c3b9ef816 100644 --- a/test/cpp/microbenchmarks/BUILD +++ b/test/cpp/microbenchmarks/BUILD @@ -55,6 +55,20 @@ grpc_cc_binary( ) grpc_cc_binary( + name = "bm_arena", + testonly = 1, + srcs = ["bm_arena.cc"], + deps = [":helpers"], +) + +grpc_cc_binary( + name = "bm_channel", + testonly = 1, + srcs = ["bm_channel.cc"], + deps = [":helpers"], +) + +grpc_cc_binary( name = "bm_cq", testonly = 1, srcs = ["bm_cq.cc"], diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc index dd1610dc3d..9516b2e3e2 100644 --- a/test/cpp/microbenchmarks/bm_call_create.cc +++ b/test/cpp/microbenchmarks/bm_call_create.cc @@ -604,10 +604,13 @@ BENCHMARK_TEMPLATE(BM_IsolatedFilter, HttpServerFilter, SendEmptyMetadata); typedef Fixture<&grpc_message_size_filter, CHECKS_NOT_LAST> MessageSizeFilter; BENCHMARK_TEMPLATE(BM_IsolatedFilter, MessageSizeFilter, NoOp); BENCHMARK_TEMPLATE(BM_IsolatedFilter, MessageSizeFilter, SendEmptyMetadata); -typedef Fixture<&grpc_server_load_reporting_filter, CHECKS_NOT_LAST> - LoadReportingFilter; -BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, NoOp); -BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, SendEmptyMetadata); +// This cmake target is disabled for now because it depends on OpenCensus, which +// is Bazel-only. +// typedef Fixture<&grpc_server_load_reporting_filter, CHECKS_NOT_LAST> +// LoadReportingFilter; +// BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, NoOp); +// BENCHMARK_TEMPLATE(BM_IsolatedFilter, LoadReportingFilter, +// SendEmptyMetadata); //////////////////////////////////////////////////////////////////////////////// // Benchmarks isolating grpc_call diff --git a/test/cpp/microbenchmarks/bm_channel.cc b/test/cpp/microbenchmarks/bm_channel.cc new file mode 100644 index 0000000000..15ac997540 --- /dev/null +++ b/test/cpp/microbenchmarks/bm_channel.cc @@ -0,0 +1,90 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* Benchmark channel */ + +#include <benchmark/benchmark.h> +#include <grpc/grpc.h> +#include "test/cpp/microbenchmarks/helpers.h" +#include "test/cpp/util/test_config.h" + +auto& force_library_initialization = Library::get(); + +class ChannelDestroyerFixture { + public: + ChannelDestroyerFixture() {} + virtual ~ChannelDestroyerFixture() { + if (channel_) { + grpc_channel_destroy(channel_); + } + } + virtual void Init() = 0; + + protected: + grpc_channel* channel_ = nullptr; +}; + +class InsecureChannelFixture : public ChannelDestroyerFixture { + public: + InsecureChannelFixture() {} + void Init() override { + channel_ = grpc_insecure_channel_create("localhost:1234", nullptr, nullptr); + } +}; + +class LameChannelFixture : public ChannelDestroyerFixture { + public: + LameChannelFixture() {} + void Init() override { + channel_ = grpc_lame_client_channel_create( + "localhost:1234", GRPC_STATUS_UNAUTHENTICATED, "blah"); + } +}; + +template <class Fixture> +static void BM_InsecureChannelCreateDestroy(benchmark::State& state) { + // In order to test if channel creation time is affected by the number of + // already existing channels, we create some initial channels here. + Fixture initial_channels[512]; + for (int i = 0; i < state.range(0); i++) { + initial_channels[i].Init(); + } + while (state.KeepRunning()) { + Fixture channel; + channel.Init(); + } +} +BENCHMARK_TEMPLATE(BM_InsecureChannelCreateDestroy, InsecureChannelFixture) + ->Range(0, 512); +; +BENCHMARK_TEMPLATE(BM_InsecureChannelCreateDestroy, LameChannelFixture) + ->Range(0, 512); +; + +// Some distros have RunSpecifiedBenchmarks under the benchmark namespace, +// and others do not. This allows us to support both modes. +namespace benchmark { +void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); } +} // namespace benchmark + +int main(int argc, char** argv) { + ::benchmark::Initialize(&argc, argv); + ::grpc::testing::InitTest(&argc, &argv, false); + benchmark::RunTheBenchmarksNamespaced(); + return 0; +} diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD index 5cb3a00f82..ebfcfbb348 100644 --- a/test/cpp/server/load_reporter/BUILD +++ b/test/cpp/server/load_reporter/BUILD @@ -14,7 +14,7 @@ licenses(["notice"]) # Apache v2 -load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package") +load("//bazel:grpc_build_system.bzl", "grpc_cc_binary", "grpc_cc_library", "grpc_cc_test", "grpc_package") grpc_package(name = "test/cpp/server/load_reporter") @@ -29,3 +29,35 @@ grpc_cc_test( "//test/core/util:grpc_test_util", ], ) + +grpc_cc_test( + name = "lb_load_reporter_test", + srcs = ["load_reporter_test.cc"], + external_deps = [ + "gtest", + "gmock", + "opencensus-stats-test", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:lb_load_reporter", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) + +grpc_cc_test( + name = "lb_get_cpu_stats_test", + srcs = ["get_cpu_stats_test.cc"], + external_deps = [ + "gtest", + ], + deps = [ + "//:gpr", + "//:grpc", + "//:lb_get_cpu_stats", + "//test/core/util:gpr_test_util", + "//test/core/util:grpc_test_util", + ], +) diff --git a/test/cpp/server/load_reporter/get_cpu_stats_test.cc b/test/cpp/server/load_reporter/get_cpu_stats_test.cc new file mode 100644 index 0000000000..5b1d5fa3a4 --- /dev/null +++ b/test/cpp/server/load_reporter/get_cpu_stats_test.cc @@ -0,0 +1,61 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/impl/codegen/port_platform.h> + +#include <grpc/grpc.h> +#include <gtest/gtest.h> + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include "src/cpp/server/load_reporter/get_cpu_stats.h" + +namespace grpc { +namespace testing { +namespace { + +TEST(GetCpuStatsTest, ReadOnce) { ::grpc::load_reporter::GetCpuStatsImpl(); } + +TEST(GetCpuStatsTest, BusyNoLargerThanTotal) { + auto p = ::grpc::load_reporter::GetCpuStatsImpl(); + uint64_t busy = p.first; + uint64_t total = p.second; + ASSERT_LE(busy, total); +} + +TEST(GetCpuStatsTest, Ascending) { + const size_t kRuns = 100; + auto prev = ::grpc::load_reporter::GetCpuStatsImpl(); + for (size_t i = 0; i < kRuns; ++i) { + auto cur = ::grpc::load_reporter::GetCpuStatsImpl(); + ASSERT_LE(prev.first, cur.first); + ASSERT_LE(prev.second, cur.second); + prev = cur; + } +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc index aa37b7d6ba..c92c407e4f 100644 --- a/test/cpp/server/load_reporter/load_data_store_test.cc +++ b/test/cpp/server/load_reporter/load_data_store_test.cc @@ -393,9 +393,9 @@ TEST_F(PerBalancerStoreTest, Suspend) { TEST_F(PerBalancerStoreTest, DataAggregation) { PerBalancerStore per_balancer_store(kLbId1, kLoadKey1); // Construct some Values. - LoadRecordValue v1(992, 34, 13, 234.0, 164.0, 173467.38); + LoadRecordValue v1(992, 34, 13, 234, 164, 173467); v1.InsertCallMetric(kMetric1, CallMetricValue(3, 2773.2)); - LoadRecordValue v2(4842, 213, 9, 393.0, 974.0, 1345.2398); + LoadRecordValue v2(4842, 213, 9, 393, 974, 1345); v2.InsertCallMetric(kMetric1, CallMetricValue(7, 25.234)); v2.InsertCallMetric(kMetric2, CallMetricValue(2, 387.08)); // v3 doesn't change the number of in-progress RPCs. diff --git a/test/cpp/server/load_reporter/load_reporter_test.cc b/test/cpp/server/load_reporter/load_reporter_test.cc new file mode 100644 index 0000000000..3264dba134 --- /dev/null +++ b/test/cpp/server/load_reporter/load_reporter_test.cc @@ -0,0 +1,498 @@ +/* + * + * Copyright 2018 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/impl/codegen/port_platform.h> + +#include <set> +#include <vector> + +#include <gmock/gmock.h> +#include <grpc/grpc.h> +#include <gtest/gtest.h> + +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/cpp/server/load_reporter/constants.h" +#include "src/cpp/server/load_reporter/load_reporter.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" + +#include "opencensus/stats/testing/test_utils.h" + +namespace grpc { +namespace testing { +namespace { + +using ::grpc::lb::v1::LoadBalancingFeedback; +using ::grpc::load_reporter::CensusViewProvider; +using ::grpc::load_reporter::CpuStatsProvider; +using ::grpc::load_reporter::LoadReporter; +using ::opencensus::stats::View; +using ::opencensus::stats::ViewData; +using ::opencensus::stats::ViewDataImpl; +using ::opencensus::stats::ViewDescriptor; +using ::testing::DoubleNear; +using ::testing::Return; + +constexpr uint64_t kFeedbackSampleWindowSeconds = 5; +constexpr uint64_t kFetchAndSampleIntervalSeconds = 1; +constexpr uint64_t kNumFeedbackSamplesInWindow = + kFeedbackSampleWindowSeconds / kFetchAndSampleIntervalSeconds; + +class MockCensusViewProvider : public CensusViewProvider { + public: + MOCK_METHOD0(FetchViewData, CensusViewProvider::ViewDataMap()); + + const ::opencensus::stats::ViewDescriptor& FindViewDescriptor( + const grpc::string& view_name) { + auto it = view_descriptor_map().find(view_name); + GPR_ASSERT(it != view_descriptor_map().end()); + return it->second; + } +}; + +class MockCpuStatsProvider : public CpuStatsProvider { + public: + MOCK_METHOD0(GetCpuStats, CpuStatsProvider::CpuStatsSample()); +}; + +class LoadReporterTest : public ::testing::Test { + public: + LoadReporterTest() {} + + MockCensusViewProvider* mock_census_view_provider() { + return static_cast<MockCensusViewProvider*>( + load_reporter_->census_view_provider()); + } + + void PrepareCpuExpectation(size_t call_num) { + auto mock_cpu_stats_provider = static_cast<MockCpuStatsProvider*>( + load_reporter_->cpu_stats_provider()); + ::testing::InSequence s; + for (size_t i = 0; i < call_num; ++i) { + EXPECT_CALL(*mock_cpu_stats_provider, GetCpuStats()) + .WillOnce(Return(kCpuStatsSamples[i])) + .RetiresOnSaturation(); + } + } + + CpuStatsProvider::CpuStatsSample initial_cpu_stats_{2, 20}; + const std::vector<CpuStatsProvider::CpuStatsSample> kCpuStatsSamples = { + {13, 53}, {64, 96}, {245, 345}, {314, 785}, + {874, 1230}, {1236, 2145}, {1864, 2974}}; + + std::unique_ptr<LoadReporter> load_reporter_; + + const grpc::string kHostname1 = "kHostname1"; + const grpc::string kHostname2 = "kHostname2"; + const grpc::string kHostname3 = "kHostname3"; + // Pad to the length of a valid LB ID. + const grpc::string kLbId1 = "kLbId111"; + const grpc::string kLbId2 = "kLbId222"; + const grpc::string kLbId3 = "kLbId333"; + const grpc::string kLbId4 = "kLbId444"; + const grpc::string kLoadKey1 = "kLoadKey1"; + const grpc::string kLoadKey2 = "kLoadKey2"; + const grpc::string kLoadKey3 = "kLoadKey3"; + const grpc::string kLbTag1 = "kLbTag1"; + const grpc::string kLbTag2 = "kLbTag2"; + const grpc::string kLbToken1 = "kLbId111kLbTag1"; + const grpc::string kLbToken2 = "kLbId222kLbTag2"; + const grpc::string kUser1 = "kUser1"; + const grpc::string kUser2 = "kUser2"; + const grpc::string kUser3 = "kUser3"; + const grpc::string kClientIp0 = "00"; + const grpc::string kClientIp1 = "0800000001"; + const grpc::string kClientIp2 = "3200000000000000000000000000000002"; + const grpc::string kMetric1 = "kMetric1"; + const grpc::string kMetric2 = "kMetric2"; + + private: + void SetUp() override { + auto mock_cpu = new MockCpuStatsProvider(); + auto mock_census = new MockCensusViewProvider(); + // Prepare the initial CPU stats data. Note that the expectation should be + // set up before the load reporter is initialized, because CPU stats is + // sampled at that point. + EXPECT_CALL(*mock_cpu, GetCpuStats()) + .WillOnce(Return(initial_cpu_stats_)) + .RetiresOnSaturation(); + load_reporter_ = std::unique_ptr<LoadReporter>( + new LoadReporter(kFeedbackSampleWindowSeconds, + std::unique_ptr<CensusViewProvider>(mock_census), + std::unique_ptr<CpuStatsProvider>(mock_cpu))); + } +}; + +class LbFeedbackTest : public LoadReporterTest { + public: + // Note that [start, start + count) of the fake samples (maybe plus the + // initial record) are in the window now. + void VerifyLbFeedback(const LoadBalancingFeedback& lb_feedback, size_t start, + size_t count) { + const CpuStatsProvider::CpuStatsSample* base = + start == 0 ? &initial_cpu_stats_ : &kCpuStatsSamples[start - 1]; + double expected_cpu_util = + static_cast<double>(kCpuStatsSamples[start + count - 1].first - + base->first) / + static_cast<double>(kCpuStatsSamples[start + count - 1].second - + base->second); + ASSERT_THAT(static_cast<double>(lb_feedback.server_utilization()), + DoubleNear(expected_cpu_util, 0.00001)); + double qps_sum = 0, eps_sum = 0; + for (size_t i = 0; i < count; ++i) { + qps_sum += kQpsEpsSamples[start + i].first; + eps_sum += kQpsEpsSamples[start + i].second; + } + double expected_qps = qps_sum / count; + double expected_eps = eps_sum / count; + // TODO(juanlishen): The error is big because we use sleep(). It should be + // much smaller when we use fake clock. + ASSERT_THAT(static_cast<double>(lb_feedback.calls_per_second()), + DoubleNear(expected_qps, expected_qps / 50)); + ASSERT_THAT(static_cast<double>(lb_feedback.errors_per_second()), + DoubleNear(expected_eps, expected_eps / 50)); + gpr_log(GPR_INFO, + "Verified LB feedback matches the samples of index [%lu, %lu).", + start, start + count); + } + + const std::vector<std::pair<double, double>> kQpsEpsSamples = { + {546.1, 153.1}, {62.1, 54.1}, {578.1, 154.2}, {978.1, 645.1}, + {1132.1, 846.4}, {531.5, 315.4}, {874.1, 324.9}}; +}; + +TEST_F(LbFeedbackTest, ZeroDuration) { + PrepareCpuExpectation(kCpuStatsSamples.size()); + EXPECT_CALL(*mock_census_view_provider(), FetchViewData()) + .WillRepeatedly( + Return(::grpc::load_reporter::CensusViewProvider::ViewDataMap())); + // Verify that divide-by-zero exception doesn't happen. + for (size_t i = 0; i < kCpuStatsSamples.size(); ++i) { + load_reporter_->FetchAndSample(); + } + load_reporter_->GenerateLoadBalancingFeedback(); +} + +TEST_F(LbFeedbackTest, Normal) { + // Prepare view data list using the <QPS, EPS> samples. + std::vector<CensusViewProvider::ViewDataMap> view_data_map_list; + for (const auto& p : LbFeedbackTest::kQpsEpsSamples) { + double qps = p.first; + double eps = p.second; + double ok_count = (qps - eps) * kFetchAndSampleIntervalSeconds; + double error_count = eps * kFetchAndSampleIntervalSeconds; + double ok_count_1 = ok_count / 3.0; + double ok_count_2 = ok_count - ok_count_1; + auto end_count_vd = ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndCount), + {{{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + ok_count_1}, + {{kClientIp0 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + ok_count_2}, + {{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + error_count}}); + // Values for other view data don't matter. + auto end_bytes_sent_vd = + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesSent), + {{{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 0}}); + auto end_bytes_received_vd = + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesReceived), + {{{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 0}}); + auto end_latency_vd = ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndLatencyMs), + {{{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 0}, + {{kClientIp0 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 0}}); + view_data_map_list.push_back( + {{::grpc::load_reporter::kViewEndCount, end_count_vd}, + {::grpc::load_reporter::kViewEndBytesSent, end_bytes_sent_vd}, + {::grpc::load_reporter::kViewEndBytesReceived, end_bytes_received_vd}, + {::grpc::load_reporter::kViewEndLatencyMs, end_latency_vd}}); + } + { + ::testing::InSequence s; + for (size_t i = 0; i < view_data_map_list.size(); ++i) { + EXPECT_CALL(*mock_census_view_provider(), FetchViewData()) + .WillOnce(Return(view_data_map_list[i])) + .RetiresOnSaturation(); + } + } + PrepareCpuExpectation(kNumFeedbackSamplesInWindow + 2); + // When the load reporter is created, a trivial LB feedback record is added. + // But that's not enough for generating an LB feedback. + // Fetch some view data so that non-trivial LB feedback can be generated. + for (size_t i = 0; i < kNumFeedbackSamplesInWindow / 2; ++i) { + // TODO(juanlishen): Find some fake clock to speed up testing. + sleep(1); + load_reporter_->FetchAndSample(); + } + VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 0, + kNumFeedbackSamplesInWindow / 2); + // Fetch more view data so that the feedback record window is just full (the + // initial record just falls out of the window). + for (size_t i = 0; i < (kNumFeedbackSamplesInWindow + 1) / 2; ++i) { + sleep(1); + load_reporter_->FetchAndSample(); + } + VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 0, + kNumFeedbackSamplesInWindow); + // Further fetching will cause the old records to fall out of the window. + for (size_t i = 0; i < 2; ++i) { + sleep(1); + load_reporter_->FetchAndSample(); + } + VerifyLbFeedback(load_reporter_->GenerateLoadBalancingFeedback(), 2, + kNumFeedbackSamplesInWindow); +} + +using LoadReportTest = LoadReporterTest; + +TEST_F(LoadReportTest, BasicReport) { + // Make up the first view data map. + CensusViewProvider::ViewDataMap vdm1; + vdm1.emplace( + ::grpc::load_reporter::kViewStartCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewStartCount), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1}, 1234}, + {{kClientIp2 + kLbToken1, kHostname1, kUser1}, 1225}, + {{kClientIp0 + kLbToken1, kHostname1, kUser1}, 10}, + {{kClientIp2 + kLbToken1, kHostname1, kUser2}, 464}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3}, 101}, + {{kClientIp1 + kLbToken2, kHostname2, kUser3}, 17}, + {{kClientIp2 + kLbId3 + kLbTag2, kHostname2, kUser3}, 23}})); + vdm1.emplace(::grpc::load_reporter::kViewEndCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndCount), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 641}, + {{kClientIp2 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 272}, + {{kClientIp2 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 996}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 34}, + {{kClientIp1 + kLbToken2, kHostname2, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 18}})); + vdm1.emplace(::grpc::load_reporter::kViewEndBytesSent, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesSent), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 8977}, + {{kClientIp2 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 266}, + {{kClientIp2 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 1276}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 77823}, + {{kClientIp1 + kLbToken2, kHostname2, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 48}})); + vdm1.emplace(::grpc::load_reporter::kViewEndBytesReceived, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesReceived), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 2341}, + {{kClientIp2 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 466}, + {{kClientIp2 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 518}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 81}, + {{kClientIp1 + kLbToken2, kHostname2, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 27}})); + vdm1.emplace(::grpc::load_reporter::kViewEndLatencyMs, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndLatencyMs), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 3.14}, + {{kClientIp2 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusClientError}, + 5.26}, + {{kClientIp2 + kLbToken1, kHostname1, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 45.4}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 4.4}, + {{kClientIp1 + kLbToken2, kHostname2, kUser2, + ::grpc::load_reporter::kCallStatusOk}, + 2348.0}})); + vdm1.emplace( + ::grpc::load_reporter::kViewOtherCallMetricCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewOtherCallMetricCount), + {{{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1}, + {{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2}, + 1}})); + vdm1.emplace( + ::grpc::load_reporter::kViewOtherCallMetricValue, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewOtherCallMetricValue), + {{{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1.2}, + {{kClientIp1 + kLbToken1, kHostname1, kUser2, kMetric1}, 1.2}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2}, + 3.2}})); + // Make up the second view data map. + CensusViewProvider::ViewDataMap vdm2; + vdm2.emplace( + ::grpc::load_reporter::kViewStartCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewStartCount), + {{{kClientIp2 + kLbToken1, kHostname1, kUser1}, 3}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3}, 778}})); + vdm2.emplace(::grpc::load_reporter::kViewEndCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndCount), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 24}, + {{kClientIp1 + kLbToken2, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 546}})); + vdm2.emplace(::grpc::load_reporter::kViewEndBytesSent, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesSent), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 747}, + {{kClientIp1 + kLbToken2, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 229}})); + vdm2.emplace(::grpc::load_reporter::kViewEndBytesReceived, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndBytesReceived), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 173}, + {{kClientIp1 + kLbToken2, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 438}})); + vdm2.emplace(::grpc::load_reporter::kViewEndLatencyMs, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewEndLatencyMs), + {{{kClientIp1 + kLbToken1, kHostname1, kUser1, + ::grpc::load_reporter::kCallStatusOk}, + 187}, + {{kClientIp1 + kLbToken2, kHostname2, kUser3, + ::grpc::load_reporter::kCallStatusClientError}, + 34}})); + vdm2.emplace( + ::grpc::load_reporter::kViewOtherCallMetricCount, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewOtherCallMetricCount), + {{{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric1}, 1}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2}, + 1}})); + vdm2.emplace( + ::grpc::load_reporter::kViewOtherCallMetricValue, + ::opencensus::stats::testing::TestUtils::MakeViewData( + mock_census_view_provider()->FindViewDescriptor( + ::grpc::load_reporter::kViewOtherCallMetricValue), + {{{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric1}, 9.6}, + {{kClientIp1 + kLbId2 + kLbTag1, kHostname2, kUser3, kMetric2}, + 5.7}})); + // Set up mock expectation. + EXPECT_CALL(*mock_census_view_provider(), FetchViewData()) + .WillOnce(Return(vdm1)) + .WillOnce(Return(vdm2)); + PrepareCpuExpectation(2); + // Start testing. + load_reporter_->ReportStreamCreated(kHostname1, kLbId1, kLoadKey1); + load_reporter_->ReportStreamCreated(kHostname2, kLbId2, kLoadKey2); + load_reporter_->ReportStreamCreated(kHostname2, kLbId3, kLoadKey3); + // First fetch. + load_reporter_->FetchAndSample(); + load_reporter_->GenerateLoads(kHostname1, kLbId1); + gpr_log(GPR_INFO, "First load generated."); + // Second fetch. + load_reporter_->FetchAndSample(); + load_reporter_->GenerateLoads(kHostname2, kLbId2); + gpr_log(GPR_INFO, "Second load generated."); + // TODO(juanlishen): Verify the data. +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} |