aboutsummaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/compiler/python_plugin_test.py2
-rw-r--r--test/core/bad_client/bad_client.c136
-rw-r--r--test/core/bad_client/bad_client.h52
-rwxr-xr-xtest/core/bad_client/gen_build_json.py79
-rw-r--r--test/core/bad_client/tests/connection_prefix.c79
-rw-r--r--test/core/support/cmdline_test.c23
-rw-r--r--test/cpp/end2end/server_crash_test.cc36
-rw-r--r--test/cpp/interop/interop_client.cc4
-rw-r--r--test/cpp/qps/async_streaming_ping_pong_test.cc10
-rw-r--r--test/cpp/qps/async_unary_ping_pong_test.cc11
-rw-r--r--test/cpp/qps/qps_driver.cc27
-rw-r--r--test/cpp/qps/qps_test.cc9
-rw-r--r--test/cpp/qps/report.cc50
-rw-r--r--test/cpp/qps/report.h77
-rw-r--r--test/cpp/qps/sync_streaming_ping_pong_test.cc10
-rw-r--r--test/cpp/qps/sync_unary_ping_pong_test.cc9
-rw-r--r--test/cpp/util/benchmark_config.cc69
-rw-r--r--test/cpp/util/benchmark_config.h57
18 files changed, 684 insertions, 56 deletions
diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py
index ad3bebac30..367effdb1a 100644
--- a/test/compiler/python_plugin_test.py
+++ b/test/compiler/python_plugin_test.py
@@ -520,4 +520,4 @@ class PythonPluginTest(unittest.TestCase):
if __name__ == '__main__':
os.chdir(os.path.dirname(sys.argv[0]))
- unittest.main()
+ unittest.main(verbosity=2)
diff --git a/test/core/bad_client/bad_client.c b/test/core/bad_client/bad_client.c
new file mode 100644
index 0000000000..c3725b5909
--- /dev/null
+++ b/test/core/bad_client/bad_client.c
@@ -0,0 +1,136 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+
+#include "src/core/channel/channel_stack.h"
+#include "src/core/channel/http_server_filter.h"
+#include "src/core/iomgr/endpoint_pair.h"
+#include "src/core/surface/completion_queue.h"
+#include "src/core/surface/server.h"
+#include "src/core/transport/chttp2_transport.h"
+
+#include <grpc/support/sync.h>
+#include <grpc/support/thd.h>
+
+typedef struct {
+ grpc_server *server;
+ grpc_completion_queue *cq;
+ grpc_bad_client_server_side_validator validator;
+ gpr_event done_thd;
+ gpr_event done_write;
+} thd_args;
+
+static void thd_func(void *arg) {
+ thd_args *a = arg;
+ a->validator(a->server, a->cq);
+ gpr_event_set(&a->done_thd, (void *)1);
+}
+
+static void done_write(void *arg, grpc_endpoint_cb_status status) {
+ thd_args *a = arg;
+ gpr_event_set(&a->done_write, (void *)1);
+}
+
+static grpc_transport_setup_result server_setup_transport(
+ void *ts, grpc_transport *transport, grpc_mdctx *mdctx) {
+ thd_args *a = ts;
+ static grpc_channel_filter const *extra_filters[] = {
+ &grpc_http_server_filter};
+ return grpc_server_setup_transport(a->server, transport, extra_filters,
+ GPR_ARRAY_SIZE(extra_filters), mdctx);
+}
+
+void grpc_run_bad_client_test(const char *name, const char *client_payload,
+ size_t client_payload_length,
+ grpc_bad_client_server_side_validator validator) {
+ grpc_endpoint_pair sfd;
+ thd_args a;
+ gpr_thd_id id;
+ gpr_slice slice =
+ gpr_slice_from_copied_buffer(client_payload, client_payload_length);
+
+ /* Add a debug log */
+ gpr_log(GPR_INFO, "TEST: %s", name);
+
+ /* Init grpc */
+ grpc_init();
+
+ /* Create endpoints */
+ sfd = grpc_iomgr_create_endpoint_pair(65536);
+
+ /* Create server, completion events */
+ a.server = grpc_server_create_from_filters(NULL, 0, NULL);
+ a.cq = grpc_completion_queue_create();
+ gpr_event_init(&a.done_thd);
+ gpr_event_init(&a.done_write);
+ a.validator = validator;
+ grpc_server_register_completion_queue(a.server, a.cq);
+ grpc_server_start(a.server);
+ grpc_create_chttp2_transport(server_setup_transport, &a, NULL, sfd.server,
+ NULL, 0, grpc_mdctx_create(), 0);
+
+ /* Bind everything into the same pollset */
+ grpc_endpoint_add_to_pollset(sfd.client, grpc_cq_pollset(a.cq));
+ grpc_endpoint_add_to_pollset(sfd.server, grpc_cq_pollset(a.cq));
+
+ /* Check a ground truth */
+ GPR_ASSERT(grpc_server_has_open_connections(a.server));
+
+ /* Start validator */
+ gpr_thd_new(&id, thd_func, &a, NULL);
+
+ /* Write data */
+ switch (grpc_endpoint_write(sfd.client, &slice, 1, done_write, &a)) {
+ case GRPC_ENDPOINT_WRITE_DONE:
+ done_write(&a, 1);
+ break;
+ case GRPC_ENDPOINT_WRITE_PENDING:
+ break;
+ case GRPC_ENDPOINT_WRITE_ERROR:
+ done_write(&a, 0);
+ break;
+ }
+
+ /* Await completion */
+ GPR_ASSERT(
+ gpr_event_wait(&a.done_write, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
+ GPR_ASSERT(gpr_event_wait(&a.done_thd, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)));
+
+ /* Shutdown */
+ grpc_endpoint_destroy(sfd.client);
+ grpc_server_destroy(a.server);
+ grpc_completion_queue_destroy(a.cq);
+
+ grpc_shutdown();
+}
diff --git a/test/core/bad_client/bad_client.h b/test/core/bad_client/bad_client.h
new file mode 100644
index 0000000000..4834e86cce
--- /dev/null
+++ b/test/core/bad_client/bad_client.h
@@ -0,0 +1,52 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H
+#define GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H
+
+#include <grpc/grpc.h>
+#include "test/core/util/test_config.h"
+
+typedef void (*grpc_bad_client_server_side_validator)(
+ grpc_server *server, grpc_completion_queue *cq);
+
+/* Test runner.
+
+ Create a server, and send client_payload to it as bytes from a client.
+ Execute validator in a separate thread to assert that the bytes are
+ handled as expected. */
+void grpc_run_bad_client_test(const char *name, const char *client_payload,
+ size_t client_payload_length,
+ grpc_bad_client_server_side_validator validator);
+
+#endif /* GRPC_TEST_CORE_BAD_CLIENT_BAD_CLIENT_H */
diff --git a/test/core/bad_client/gen_build_json.py b/test/core/bad_client/gen_build_json.py
new file mode 100755
index 0000000000..67969a1a12
--- /dev/null
+++ b/test/core/bad_client/gen_build_json.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# Copyright 2015, Google Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+"""Generates the appropriate build.json data for all the end2end tests."""
+
+
+import simplejson
+import collections
+
+TestOptions = collections.namedtuple('TestOptions', 'flaky')
+default_test_options = TestOptions(False)
+
+# maps test names to options
+BAD_CLIENT_TESTS = {
+ 'connection_prefix': default_test_options,
+}
+
+def main():
+ json = {
+ '#': 'generated with test/bad_client/gen_build_json.py',
+ 'libs': [
+ {
+ 'name': 'bad_client_test',
+ 'build': 'private',
+ 'language': 'c',
+ 'src': [
+ 'test/core/bad_client/bad_client.c'
+ ]
+ }],
+ 'targets': [
+ {
+ 'name': '%s_bad_client_test' % t,
+ 'build': 'test',
+ 'language': 'c',
+ 'secure': 'no',
+ 'src': ['test/core/bad_client/tests/%s.c' % t],
+ 'flaky': 'invoke_large_request' in t,
+ 'deps': [
+ 'bad_client_test',
+ 'grpc_test_util_unsecure',
+ 'grpc_unsecure',
+ 'gpr_test_util',
+ 'gpr'
+ ]
+ }
+ for t in sorted(BAD_CLIENT_TESTS.keys())]}
+ print simplejson.dumps(json, sort_keys=True, indent=2 * ' ')
+
+
+if __name__ == '__main__':
+ main()
diff --git a/test/core/bad_client/tests/connection_prefix.c b/test/core/bad_client/tests/connection_prefix.c
new file mode 100644
index 0000000000..e8bf935710
--- /dev/null
+++ b/test/core/bad_client/tests/connection_prefix.c
@@ -0,0 +1,79 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "test/core/bad_client/bad_client.h"
+#include "src/core/surface/server.h"
+
+static void verifier(grpc_server *server, grpc_completion_queue *cq) {
+ while (grpc_server_has_open_connections(server)) {
+ GPR_ASSERT(grpc_completion_queue_next(
+ cq, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(20)).type ==
+ GRPC_QUEUE_TIMEOUT);
+ }
+}
+
+int main(int argc, char **argv) {
+ grpc_test_init(argc, argv);
+
+ grpc_run_bad_client_test("conpfx_1", "X", 1, verifier);
+ grpc_run_bad_client_test("conpfx_2", "PX", 2, verifier);
+ grpc_run_bad_client_test("conpfx_3", "PRX", 3, verifier);
+ grpc_run_bad_client_test("conpfx_4", "PRIX", 4, verifier);
+ grpc_run_bad_client_test("conpfx_5", "PRI X", 5, verifier);
+ grpc_run_bad_client_test("conpfx_6", "PRI *X", 6, verifier);
+ grpc_run_bad_client_test("conpfx_7", "PRI * X", 7, verifier);
+ grpc_run_bad_client_test("conpfx_8", "PRI * HX", 8, verifier);
+ grpc_run_bad_client_test("conpfx_9", "PRI * HTX", 9, verifier);
+ grpc_run_bad_client_test("conpfx_10", "PRI * HTTX", 10, verifier);
+ grpc_run_bad_client_test("conpfx_11", "PRI * HTTPX", 11, verifier);
+ grpc_run_bad_client_test("conpfx_12", "PRI * HTTP/X", 12, verifier);
+ grpc_run_bad_client_test("conpfx_13", "PRI * HTTP/2X", 13, verifier);
+ grpc_run_bad_client_test("conpfx_14", "PRI * HTTP/2.X", 14, verifier);
+ grpc_run_bad_client_test("conpfx_15", "PRI * HTTP/2.0X", 15, verifier);
+ grpc_run_bad_client_test("conpfx_16", "PRI * HTTP/2.0\rX", 16, verifier);
+ grpc_run_bad_client_test("conpfx_17", "PRI * HTTP/2.0\r\nX", 17, verifier);
+ grpc_run_bad_client_test("conpfx_18", "PRI * HTTP/2.0\r\n\rX", 18, verifier);
+ grpc_run_bad_client_test("conpfx_19", "PRI * HTTP/2.0\r\n\r\nX", 19,
+ verifier);
+ grpc_run_bad_client_test("conpfx_20", "PRI * HTTP/2.0\r\n\r\nSX", 20,
+ verifier);
+ grpc_run_bad_client_test("conpfx_21", "PRI * HTTP/2.0\r\n\r\nSMX", 21,
+ verifier);
+ grpc_run_bad_client_test("conpfx_22", "PRI * HTTP/2.0\r\n\r\nSM\rX", 22,
+ verifier);
+ grpc_run_bad_client_test("conpfx_23", "PRI * HTTP/2.0\r\n\r\nSM\r\nX", 23,
+ verifier);
+ grpc_run_bad_client_test("conpfx_24", "PRI * HTTP/2.0\r\n\r\nSM\r\n\rX", 24,
+ verifier);
+ return 0;
+}
diff --git a/test/core/support/cmdline_test.c b/test/core/support/cmdline_test.c
index a7767ace5e..26153b192c 100644
--- a/test/core/support/cmdline_test.c
+++ b/test/core/support/cmdline_test.c
@@ -35,6 +35,7 @@
#include <string.h>
+#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/useful.h>
#include "test/core/util/test_config.h"
@@ -272,6 +273,27 @@ static void test_many(void) {
gpr_cmdline_destroy(cl);
}
+static void test_usage(void) {
+ gpr_cmdline *cl;
+ char *usage;
+
+ char *str = NULL;
+ int x = 0;
+ int flag = 2;
+
+ cl = gpr_cmdline_create(NULL);
+ gpr_cmdline_add_string(cl, "str", NULL, &str);
+ gpr_cmdline_add_int(cl, "x", NULL, &x);
+ gpr_cmdline_add_flag(cl, "flag", NULL, &flag);
+
+ usage = gpr_cmdline_usage_string(cl, "test");
+ GPR_ASSERT(0 == strcmp(usage,
+ "Usage: test [--str=string] [--x=int] [--flag|--no-flag]\n"));
+ gpr_free(usage);
+
+ gpr_cmdline_destroy(cl);
+}
+
int main(int argc, char **argv) {
grpc_test_init(argc, argv);
test_simple_int();
@@ -289,5 +311,6 @@ int main(int argc, char **argv) {
test_flag_val_true();
test_flag_val_false();
test_many();
+ test_usage();
return 0;
}
diff --git a/test/cpp/end2end/server_crash_test.cc b/test/cpp/end2end/server_crash_test.cc
index 11d73aec7d..3fdae9bc07 100644
--- a/test/cpp/end2end/server_crash_test.cc
+++ b/test/cpp/end2end/server_crash_test.cc
@@ -69,10 +69,15 @@ namespace testing {
namespace {
-class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Service {
+class ServiceImpl GRPC_FINAL
+ : public ::grpc::cpp::test::util::TestService::Service {
+ public:
+ ServiceImpl() : bidi_stream_count_(0), response_stream_count_(0) {}
+
Status BidiStream(ServerContext* context,
ServerReaderWriter<EchoResponse, EchoRequest>* stream)
GRPC_OVERRIDE {
+ bidi_stream_count_++;
EchoRequest request;
EchoResponse response;
while (stream->Read(&request)) {
@@ -87,6 +92,7 @@ class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Serv
Status ResponseStream(ServerContext* context, const EchoRequest* request,
ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
EchoResponse response;
+ response_stream_count_++;
for (int i = 0;; i++) {
std::ostringstream msg;
msg << "Hello " << i;
@@ -96,23 +102,27 @@ class ServiceImpl GRPC_FINAL : public ::grpc::cpp::test::util::TestService::Serv
}
return Status::OK;
}
+
+ int bidi_stream_count() { return bidi_stream_count_; }
+
+ int response_stream_count() { return response_stream_count_; }
+
+ private:
+ int bidi_stream_count_;
+ int response_stream_count_;
};
class CrashTest : public ::testing::Test {
protected:
CrashTest() {}
- std::unique_ptr<Server>
- CreateServerAndClient(const std::string& mode) {
+ std::unique_ptr<Server> CreateServerAndClient(const std::string& mode) {
auto port = grpc_pick_unused_port_or_die();
std::ostringstream addr_stream;
addr_stream << "localhost:" << port;
auto addr = addr_stream.str();
- client_.reset(new SubProcess({
- g_root + "/server_crash_test_client",
- "--address=" + addr,
- "--mode=" + mode
- }));
+ client_.reset(new SubProcess({g_root + "/server_crash_test_client",
+ "--address=" + addr, "--mode=" + mode}));
GPR_ASSERT(client_);
ServerBuilder builder;
@@ -121,9 +131,11 @@ class CrashTest : public ::testing::Test {
return builder.BuildAndStart();
}
- void KillClient() {
- client_.reset();
- }
+ void KillClient() { client_.reset(); }
+
+ bool HadOneBidiStream() { return service_.bidi_stream_count() == 1; }
+
+ bool HadOneResponseStream() { return service_.response_stream_count() == 1; }
private:
std::unique_ptr<SubProcess> client_;
@@ -136,6 +148,7 @@ TEST_F(CrashTest, ResponseStream) {
gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
KillClient();
server->Shutdown();
+ GPR_ASSERT(HadOneResponseStream());
}
TEST_F(CrashTest, BidiStream) {
@@ -144,6 +157,7 @@ TEST_F(CrashTest, BidiStream) {
gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_seconds(5)));
KillClient();
server->Shutdown();
+ GPR_ASSERT(HadOneBidiStream());
}
} // namespace
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index 874510e54f..e351059246 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -57,8 +57,8 @@ const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
const int kNumResponseMessages = 2000;
const int kResponseMessageSize = 1030;
const int kReceiveDelayMilliSeconds = 20;
-const int kLargeRequestSize = 314159;
-const int kLargeResponseSize = 271812;
+const int kLargeRequestSize = 271828;
+const int kLargeResponseSize = 314159;
} // namespace
InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel)
diff --git a/test/cpp/qps/async_streaming_ping_pong_test.cc b/test/cpp/qps/async_streaming_ping_pong_test.cc
index d4871c0ba1..411df4d32a 100644
--- a/test/cpp/qps/async_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/async_streaming_ping_pong_test.cc
@@ -31,12 +31,15 @@
*
*/
+#include <set>
+
#include <grpc/support/log.h>
#include <signal.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
@@ -64,16 +67,17 @@ static void RunAsyncStreamingPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
- ReportQPS(*result);
- ReportLatency(*result);
+ GetReporter()->ReportQPS(*result);
+ GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
+
signal(SIGPIPE, SIG_IGN);
grpc::testing::RunAsyncStreamingPingPong();
-
return 0;
}
diff --git a/test/cpp/qps/async_unary_ping_pong_test.cc b/test/cpp/qps/async_unary_ping_pong_test.cc
index 35f188c986..eda31b5744 100644
--- a/test/cpp/qps/async_unary_ping_pong_test.cc
+++ b/test/cpp/qps/async_unary_ping_pong_test.cc
@@ -31,12 +31,15 @@
*
*/
+#include <set>
+
#include <grpc/support/log.h>
#include <signal.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
@@ -64,16 +67,16 @@ static void RunAsyncUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
- ReportQPS(*result);
- ReportLatency(*result);
+ GetReporter()->ReportQPS(*result);
+ GetReporter()->ReportLatency(*result);
}
-
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
signal(SIGPIPE, SIG_IGN);
- grpc::testing::RunAsyncUnaryPingPong();
+ grpc::testing::RunAsyncUnaryPingPong();
return 0;
}
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
index 008830de4e..281e2e8119 100644
--- a/test/cpp/qps/qps_driver.cc
+++ b/test/cpp/qps/qps_driver.cc
@@ -31,12 +31,15 @@
*
*/
+#include <memory>
+#include <set>
+
#include <gflags/gflags.h>
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
-#include "test/cpp/util/test_config.h"
+#include "test/cpp/util/benchmark_config.h"
DEFINE_int32(num_clients, 1, "Number of client binaries");
DEFINE_int32(num_servers, 1, "Number of server binaries");
@@ -68,9 +71,10 @@ using grpc::testing::ServerType;
using grpc::testing::RpcType;
using grpc::testing::ResourceUsage;
-int main(int argc, char** argv) {
- grpc::testing::InitTest(&argc, &argv, true);
+namespace grpc {
+namespace testing {
+static void QpsDriver() {
RpcType rpc_type;
GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));
@@ -107,9 +111,20 @@ int main(int argc, char** argv) {
client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers);
- ReportQPSPerCore(*result, server_config);
- ReportLatency(*result);
- ReportTimes(*result);
+ GetReporter()->ReportQPS(*result);
+ GetReporter()->ReportQPSPerCore(*result, server_config);
+ GetReporter()->ReportLatency(*result);
+ GetReporter()->ReportTimes(*result);
+}
+
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
+
+ signal(SIGPIPE, SIG_IGN);
+ grpc::testing::QpsDriver();
return 0;
}
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index 9a81d0fc90..63a37ae07e 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -31,12 +31,15 @@
*
*/
+#include <set>
+
#include <grpc/support/log.h>
#include <signal.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
@@ -64,14 +67,16 @@ static void RunQPS() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
- ReportQPSPerCore(*result, server_config);
- ReportLatency(*result);
+ GetReporter()->ReportQPSPerCore(*result, server_config);
+ GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
+
signal(SIGPIPE, SIG_IGN);
grpc::testing::RunQPS();
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index 3115ff3bfb..e116175e3b 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -39,27 +39,55 @@
namespace grpc {
namespace testing {
-// QPS: XXX
-void ReportQPS(const ScenarioResult& result) {
+void CompositeReporter::add(std::unique_ptr<Reporter> reporter) {
+ reporters_.emplace_back(std::move(reporter));
+}
+
+void CompositeReporter::ReportQPS(const ScenarioResult& result) const {
+ for (size_t i = 0; i < reporters_.size(); ++i) {
+ reporters_[i]->ReportQPS(result);
+ }
+}
+
+void CompositeReporter::ReportQPSPerCore(const ScenarioResult& result,
+ const ServerConfig& config) const {
+ for (size_t i = 0; i < reporters_.size(); ++i) {
+ reporters_[i]->ReportQPSPerCore(result, config);
+ }
+}
+
+void CompositeReporter::ReportLatency(const ScenarioResult& result) const {
+ for (size_t i = 0; i < reporters_.size(); ++i) {
+ reporters_[i]->ReportLatency(result);
+ }
+}
+
+void CompositeReporter::ReportTimes(const ScenarioResult& result) const {
+ for (size_t i = 0; i < reporters_.size(); ++i) {
+ reporters_[i]->ReportTimes(result);
+ }
+}
+
+
+void GprLogReporter::ReportQPS(const ScenarioResult& result) const {
gpr_log(GPR_INFO, "QPS: %.1f",
result.latencies.Count() /
average(result.client_resources,
[](ResourceUsage u) { return u.wall_time; }));
}
-// QPS: XXX (YYY/server core)
-void ReportQPSPerCore(const ScenarioResult& result,
- const ServerConfig& server_config) {
- auto qps = result.latencies.Count() /
- average(result.client_resources,
- [](ResourceUsage u) { return u.wall_time; });
+void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result,
+ const ServerConfig& server_config) const {
+ auto qps =
+ result.latencies.Count() /
+ average(result.client_resources,
+ [](ResourceUsage u) { return u.wall_time; });
gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps,
qps / server_config.threads());
}
-// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
-void ReportLatency(const ScenarioResult& result) {
+void GprLogReporter::ReportLatency(const ScenarioResult& result) const {
gpr_log(GPR_INFO,
"Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
result.latencies.Percentile(50) / 1000,
@@ -69,7 +97,7 @@ void ReportLatency(const ScenarioResult& result) {
result.latencies.Percentile(99.9) / 1000);
}
-void ReportTimes(const ScenarioResult& result) {
+void GprLogReporter::ReportTimes(const ScenarioResult& result) const {
gpr_log(GPR_INFO, "Server system time: %.2f%%",
100.0 * sum(result.server_resources,
[](ResourceUsage u) { return u.system_time; }) /
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 343e426ca4..630275ecda 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -34,22 +34,77 @@
#ifndef TEST_QPS_REPORT_H
#define TEST_QPS_REPORT_H
+#include <memory>
+#include <set>
+#include <vector>
+#include <grpc++/config.h>
+
#include "test/cpp/qps/driver.h"
+#include "test/cpp/qps/qpstest.grpc.pb.h"
namespace grpc {
namespace testing {
-// QPS: XXX
-void ReportQPS(const ScenarioResult& result);
-// QPS: XXX (YYY/server core)
-void ReportQPSPerCore(const ScenarioResult& result, const ServerConfig& config);
-// Latency (50/90/95/99/99.9%-ile): AA/BB/CC/DD/EE us
-void ReportLatency(const ScenarioResult& result);
-// Server system time: XX%
-// Server user time: XX%
-// Client system time: XX%
-// Client user time: XX%
-void ReportTimes(const ScenarioResult& result);
+/** Interface for all reporters. */
+class Reporter {
+ public:
+ /** Construct a reporter with the given \a name. */
+ Reporter(const string& name) : name_(name) {}
+
+ virtual ~Reporter() {}
+
+ /** Returns this reporter's name.
+ *
+ * Names are constants, set at construction time. */
+ string name() const { return name_; }
+
+ /** Reports QPS for the given \a result. */
+ virtual void ReportQPS(const ScenarioResult& result) const = 0;
+
+ /** Reports QPS per core as (YYY/server core). */
+ virtual void ReportQPSPerCore(const ScenarioResult& result,
+ const ServerConfig& config) const = 0;
+
+ /** Reports latencies for the 50, 90, 95, 99 and 99.9 percentiles, in ms. */
+ virtual void ReportLatency(const ScenarioResult& result) const = 0;
+
+ /** Reports system and user time for client and server systems. */
+ virtual void ReportTimes(const ScenarioResult& result) const = 0;
+
+ private:
+ const string name_;
+};
+
+/** A composite for all reporters to be considered. */
+class CompositeReporter : public Reporter {
+ public:
+ CompositeReporter() : Reporter("CompositeReporter") {}
+
+ /** Adds a \a reporter to the composite. */
+ void add(std::unique_ptr<Reporter> reporter);
+
+ void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE;
+ void ReportQPSPerCore(const ScenarioResult& result,
+ const ServerConfig& config) const GRPC_OVERRIDE;
+ void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE;
+ void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
+
+ private:
+ std::vector<std::unique_ptr<Reporter> > reporters_;
+};
+
+/** Reporter to gpr_log(GPR_INFO). */
+class GprLogReporter : public Reporter {
+ public:
+ GprLogReporter(const string& name) : Reporter(name) {}
+
+ private:
+ void ReportQPS(const ScenarioResult& result) const GRPC_OVERRIDE;
+ void ReportQPSPerCore(const ScenarioResult& result,
+ const ServerConfig& config) const GRPC_OVERRIDE;
+ void ReportLatency(const ScenarioResult& result) const GRPC_OVERRIDE;
+ void ReportTimes(const ScenarioResult& result) const GRPC_OVERRIDE;
+};
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/qps/sync_streaming_ping_pong_test.cc b/test/cpp/qps/sync_streaming_ping_pong_test.cc
index 218306846b..d53905a779 100644
--- a/test/cpp/qps/sync_streaming_ping_pong_test.cc
+++ b/test/cpp/qps/sync_streaming_ping_pong_test.cc
@@ -31,12 +31,15 @@
*
*/
+#include <set>
+
#include <grpc/support/log.h>
#include <signal.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
@@ -63,14 +66,15 @@ static void RunSynchronousStreamingPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
- ReportQPS(*result);
- ReportLatency(*result);
+ GetReporter()->ReportQPS(*result);
+ GetReporter()->ReportLatency(*result);
}
-
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
+
signal(SIGPIPE, SIG_IGN);
grpc::testing::RunSynchronousStreamingPingPong();
diff --git a/test/cpp/qps/sync_unary_ping_pong_test.cc b/test/cpp/qps/sync_unary_ping_pong_test.cc
index 137ef79f2f..d276d13a43 100644
--- a/test/cpp/qps/sync_unary_ping_pong_test.cc
+++ b/test/cpp/qps/sync_unary_ping_pong_test.cc
@@ -31,12 +31,15 @@
*
*/
+#include <set>
+
#include <grpc/support/log.h>
#include <signal.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/report.h"
+#include "test/cpp/util/benchmark_config.h"
namespace grpc {
namespace testing {
@@ -63,14 +66,16 @@ static void RunSynchronousUnaryPingPong() {
const auto result =
RunScenario(client_config, 1, server_config, 1, WARMUP, BENCHMARK, -2);
- ReportQPS(*result);
- ReportLatency(*result);
+ GetReporter()->ReportQPS(*result);
+ GetReporter()->ReportLatency(*result);
}
} // namespace testing
} // namespace grpc
int main(int argc, char** argv) {
+ grpc::testing::InitBenchmark(&argc, &argv, true);
+
signal(SIGPIPE, SIG_IGN);
grpc::testing::RunSynchronousUnaryPingPong();
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc
new file mode 100644
index 0000000000..5b3c1daf5d
--- /dev/null
+++ b/test/cpp/util/benchmark_config.cc
@@ -0,0 +1,69 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <gflags/gflags.h>
+#include "test/cpp/util/benchmark_config.h"
+
+DEFINE_bool(enable_log_reporter, true,
+ "Enable reporting of benchmark results through GprLog");
+
+// In some distros, gflags is in the namespace google, and in some others,
+// in gflags. This hack is enabling us to find both.
+namespace google {}
+namespace gflags {}
+using namespace google;
+using namespace gflags;
+
+namespace grpc {
+namespace testing {
+
+void InitBenchmark(int* argc, char*** argv, bool remove_flags) {
+ ParseCommandLineFlags(argc, argv, remove_flags);
+}
+
+static std::shared_ptr<Reporter> InitBenchmarkReporters() {
+ auto* composite_reporter = new CompositeReporter;
+ if (FLAGS_enable_log_reporter) {
+ composite_reporter->add(
+ std::unique_ptr<Reporter>(new GprLogReporter("LogReporter")));
+ }
+ return std::shared_ptr<Reporter>(composite_reporter);
+}
+
+std::shared_ptr<Reporter> GetReporter() {
+ static std::shared_ptr<Reporter> reporter(InitBenchmarkReporters());
+ return reporter;
+}
+
+} // namespace testing
+} // namespace grpc
diff --git a/test/cpp/util/benchmark_config.h b/test/cpp/util/benchmark_config.h
new file mode 100644
index 0000000000..6b308a15ff
--- /dev/null
+++ b/test/cpp/util/benchmark_config.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 2015, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H
+#define GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H
+
+#include <memory>
+#include <vector>
+
+#include "test/cpp/qps/report.h"
+
+namespace grpc {
+namespace testing {
+
+void InitBenchmark(int* argc, char*** argv, bool remove_flags);
+
+/** Returns the benchmark Reporter instance.
+ *
+ * The returned instance will take care of generating reports for all the actual
+ * reporters configured via the "enable_*_reporter" command line flags (see
+ * benchmark_config.cc). */
+std::shared_ptr<Reporter> GetReporter();
+
+} // namespace testing
+} // namespace grpc
+
+#endif // GRPC_TEST_CPP_UTIL_BENCHMARK_CONFIG_H