aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp
diff options
context:
space:
mode:
authorGravatar Craig Tiller <ctiller@google.com>2016-04-21 17:07:36 -0700
committerGravatar Craig Tiller <ctiller@google.com>2016-04-21 17:07:36 -0700
commit7beea147e506b57a9656976001a1360e755a2e9b (patch)
tree57d098e53d213dfe21e1bf40b7693ff2936901d4 /test/cpp
parent788a25365d022d9797de444799c57842a6fa0603 (diff)
parent5a56891eb6b1591e97d36072ac067d762aecf07e (diff)
Merge github.com:grpc/grpc into strong-includes
Diffstat (limited to 'test/cpp')
-rw-r--r--test/cpp/qps/client.h14
-rw-r--r--test/cpp/qps/driver.cc61
-rw-r--r--test/cpp/qps/driver.h23
-rw-r--r--test/cpp/qps/interarrival.h56
-rwxr-xr-xtest/cpp/qps/qps-sweep.sh170
-rw-r--r--test/cpp/qps/qps_driver.cc213
-rw-r--r--test/cpp/qps/qps_interarrival_test.cc6
-rw-r--r--test/cpp/qps/qps_json_driver.cc33
-rw-r--r--test/cpp/qps/report.cc117
-rw-r--r--test/cpp/qps/report.h26
-rwxr-xr-xtest/cpp/qps/single_run_localhost.sh56
-rw-r--r--test/cpp/util/benchmark_config.cc9
12 files changed, 122 insertions, 662 deletions
diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h
index e958141d4e..5a9027a4a2 100644
--- a/test/cpp/qps/client.h
+++ b/test/cpp/qps/client.h
@@ -173,20 +173,6 @@ class Client {
random_dist.reset(
new ExpDist(load.poisson().offered_load() / num_threads));
break;
- case LoadParams::kUniform:
- random_dist.reset(
- new UniformDist(load.uniform().interarrival_lo() * num_threads,
- load.uniform().interarrival_hi() * num_threads));
- break;
- case LoadParams::kDeterm:
- random_dist.reset(
- new DetDist(num_threads / load.determ().offered_load()));
- break;
- case LoadParams::kPareto:
- random_dist.reset(
- new ParetoDist(load.pareto().interarrival_base() * num_threads,
- load.pareto().alpha()));
- break;
default:
GPR_ASSERT(false);
}
diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc
index c87ad6461d..2583ceb819 100644
--- a/test/cpp/qps/driver.cc
+++ b/test/cpp/qps/driver.cc
@@ -52,6 +52,7 @@
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/histogram.h"
#include "test/cpp/qps/qps_worker.h"
+#include "test/cpp/qps/stats.h"
using std::list;
using std::thread;
@@ -115,6 +116,47 @@ static deque<string> get_workers(const string& name) {
}
}
+// helpers for postprocess_scenario_result
+static double WallTime(ClientStats s) { return s.time_elapsed(); }
+static double SystemTime(ClientStats s) { return s.time_system(); }
+static double UserTime(ClientStats s) { return s.time_user(); }
+static double ServerWallTime(ServerStats s) { return s.time_elapsed(); }
+static double ServerSystemTime(ServerStats s) { return s.time_system(); }
+static double ServerUserTime(ServerStats s) { return s.time_user(); }
+static int Cores(int n) { return n; }
+
+// Postprocess ScenarioResult and populate result summary.
+static void postprocess_scenario_result(ScenarioResult* result) {
+ Histogram histogram;
+ histogram.MergeProto(result->latencies());
+
+ auto qps = histogram.Count() / average(result->client_stats(), WallTime);
+ auto qps_per_server_core = qps / sum(result->server_cores(), Cores);
+
+ result->mutable_summary()->set_qps(qps);
+ result->mutable_summary()->set_qps_per_server_core(qps_per_server_core);
+ result->mutable_summary()->set_latency_50(histogram.Percentile(50));
+ result->mutable_summary()->set_latency_90(histogram.Percentile(90));
+ result->mutable_summary()->set_latency_95(histogram.Percentile(95));
+ result->mutable_summary()->set_latency_99(histogram.Percentile(99));
+ result->mutable_summary()->set_latency_999(histogram.Percentile(99.9));
+
+ auto server_system_time = 100.0 *
+ sum(result->server_stats(), ServerSystemTime) /
+ sum(result->server_stats(), ServerWallTime);
+ auto server_user_time = 100.0 * sum(result->server_stats(), ServerUserTime) /
+ sum(result->server_stats(), ServerWallTime);
+ auto client_system_time = 100.0 * sum(result->client_stats(), SystemTime) /
+ sum(result->client_stats(), WallTime);
+ auto client_user_time = 100.0 * sum(result->client_stats(), UserTime) /
+ sum(result->client_stats(), WallTime);
+
+ result->mutable_summary()->set_server_system_time(server_system_time);
+ result->mutable_summary()->set_server_user_time(server_user_time);
+ result->mutable_summary()->set_client_system_time(client_system_time);
+ result->mutable_summary()->set_client_user_time(client_user_time);
+}
+
// Namespace for classes and functions used only in RunScenario
// Using this rather than local definitions to workaround gcc-4.4 limitations
// regarding using templates without linkage
@@ -343,8 +385,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
// Finish a run
std::unique_ptr<ScenarioResult> result(new ScenarioResult);
- result->client_config = result_client_config;
- result->server_config = result_server_config;
+ Histogram merged_latencies;
+
gpr_log(GPR_INFO, "Finishing clients");
for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
GPR_ASSERT(client->stream->Write(client_mark));
@@ -353,9 +395,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
GPR_ASSERT(client->stream->Read(&client_status));
const auto& stats = client_status.stats();
- result->latencies.MergeProto(stats.latencies());
- result->client_resources.emplace_back(
- stats.time_elapsed(), stats.time_user(), stats.time_system(), -1);
+ merged_latencies.MergeProto(stats.latencies());
+ result->add_client_stats()->CopyFrom(stats);
GPR_ASSERT(!client->stream->Read(&client_status));
}
for (auto client = &clients[0]; client != &clients[num_clients]; client++) {
@@ -363,6 +404,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
}
delete[] clients;
+ merged_latencies.FillProto(result->mutable_latencies());
+
gpr_log(GPR_INFO, "Finishing servers");
for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
GPR_ASSERT(server->stream->Write(server_mark));
@@ -370,10 +413,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
}
for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
GPR_ASSERT(server->stream->Read(&server_status));
- const auto& stats = server_status.stats();
- result->server_resources.emplace_back(
- stats.time_elapsed(), stats.time_user(), stats.time_system(),
- server_status.cores());
+ result->add_server_stats()->CopyFrom(server_status.stats());
+ result->add_server_cores(server_status.cores());
GPR_ASSERT(!server->stream->Read(&server_status));
}
for (auto server = &servers[0]; server != &servers[num_servers]; server++) {
@@ -381,6 +422,8 @@ std::unique_ptr<ScenarioResult> RunScenario(
}
delete[] servers;
+
+ postprocess_scenario_result(result.get());
return result;
}
diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h
index 21e51529d5..3a5cf138f1 100644
--- a/test/cpp/qps/driver.h
+++ b/test/cpp/qps/driver.h
@@ -41,29 +41,6 @@
namespace grpc {
namespace testing {
-class ResourceUsage {
- public:
- ResourceUsage(double w, double u, double s, int c)
- : wall_time_(w), user_time_(u), system_time_(s), cores_(c) {}
- double wall_time() const { return wall_time_; }
- double user_time() const { return user_time_; }
- double system_time() const { return system_time_; }
- int cores() const { return cores_; }
-
- private:
- double wall_time_;
- double user_time_;
- double system_time_;
- int cores_;
-};
-
-struct ScenarioResult {
- Histogram latencies;
- std::vector<ResourceUsage> client_resources;
- std::vector<ResourceUsage> server_resources;
- ClientConfig client_config;
- ServerConfig server_config;
-};
std::unique_ptr<ScenarioResult> RunScenario(
const grpc::testing::ClientConfig& client_config, size_t num_clients,
diff --git a/test/cpp/qps/interarrival.h b/test/cpp/qps/interarrival.h
index 0cc78533ce..0980d5e8ba 100644
--- a/test/cpp/qps/interarrival.h
+++ b/test/cpp/qps/interarrival.h
@@ -82,62 +82,6 @@ class ExpDist GRPC_FINAL : public RandomDistInterface {
double lambda_recip_;
};
-// UniformDist implements a random distribution that has
-// interarrival time uniformly spread between [lo,hi). The
-// mean interarrival time is (lo+hi)/2. For more information,
-// see http://en.wikipedia.org/wiki/Uniform_distribution_%28continuous%29
-
-class UniformDist GRPC_FINAL : public RandomDistInterface {
- public:
- UniformDist(double lo, double hi) : lo_(lo), range_(hi - lo) {}
- ~UniformDist() GRPC_OVERRIDE {}
- double transform(double uni) const GRPC_OVERRIDE {
- return uni * range_ + lo_;
- }
-
- private:
- double lo_;
- double range_;
-};
-
-// DetDist provides a random distribution with interarrival time
-// of val. Note that this is not additive, so using this on multiple
-// flows of control (threads within the same client or separate
-// clients) will not preserve any deterministic interarrival gap across
-// requests.
-
-class DetDist GRPC_FINAL : public RandomDistInterface {
- public:
- explicit DetDist(double val) : val_(val) {}
- ~DetDist() GRPC_OVERRIDE {}
- double transform(double uni) const GRPC_OVERRIDE { return val_; }
-
- private:
- double val_;
-};
-
-// ParetoDist provides a random distribution with interarrival time
-// spread according to a Pareto (heavy-tailed) distribution. In this
-// model, many interarrival times are close to the base, but a sufficient
-// number will be high (up to infinity) as to disturb the mean. It is a
-// good representation of the response times of data center jobs. See
-// http://en.wikipedia.org/wiki/Pareto_distribution
-
-class ParetoDist GRPC_FINAL : public RandomDistInterface {
- public:
- ParetoDist(double base, double alpha)
- : base_(base), alpha_recip_(1.0 / alpha) {}
- ~ParetoDist() GRPC_OVERRIDE {}
- double transform(double uni) const GRPC_OVERRIDE {
- // Note: Use 1.0-uni above to avoid div by zero if uni is 0
- return base_ / pow(1.0 - uni, alpha_recip_);
- }
-
- private:
- double base_;
- double alpha_recip_;
-};
-
// A class library for generating pseudo-random interarrival times
// in an efficient re-entrant way. The random table is built at construction
// time, and each call must include the thread id of the invoker
diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh
deleted file mode 100755
index 8f7fb92772..0000000000
--- a/test/cpp/qps/qps-sweep.sh
+++ /dev/null
@@ -1,170 +0,0 @@
-#!/bin/sh
-
-# 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.
-
-if [ x"$QPS_WORKERS" == x ]; then
- echo Error: Must set QPS_WORKERS variable in form \
- "host:port,host:port,..." 1>&2
- exit 1
-fi
-
-bins=`find . .. ../.. ../../.. -name bins | head -1`
-
-# Print out each command that gets executed
-set -x
-
-#
-# Specify parameters used in some of the tests
-#
-
-# big is the size in bytes of large messages (0 is the size otherwise)
-big=65536
-
-# wide is the number of client channels in multi-channel tests (1 otherwise)
-wide=64
-
-# deep is the number of RPCs outstanding on a channel in non-ping-pong tests
-# (the value used is 1 otherwise)
-deep=100
-
-# half is half the count of worker processes, used in the crossbar scenario
-# that uses equal clients and servers. The other scenarios use only 1 server
-# and either 1 client or N-1 clients as appropriate
-half=`echo $QPS_WORKERS | awk -F, '{print int(NF/2)}'`
-
-for secure in true false; do
- # Scenario 1: generic async streaming ping-pong (contentionless latency)
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=0 \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 2: generic async streaming "unconstrained" (QPS)
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=1 --num_clients=0 2>&1 | tee /tmp/qps-test.$$
-
- # Scenario 2b: QPS with a single server core
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=1 --num_clients=0 --server_core_limit=1
-
- # Scenario 2c: protobuf-based QPS
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=$wide --simple_req_size=0 --simple_resp_size=0 \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=1 --num_clients=0
-
- # Scenario 3: Latency at sub-peak load (all clients equally loaded)
- for loadfactor in 0.2 0.5 0.7; do
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=1 --num_clients=0 --poisson_load=`awk -v lf=$loadfactor \
- '$5 == "QPS:" {print int(lf * $6); exit}' /tmp/qps-test.$$`
- done
-
- rm /tmp/qps-test.$$
-
- # Scenario 4: Single-channel bidirectional throughput test (like TCP_STREAM).
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=$big \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 5: Sync unary ping-pong with protobufs
- "$bins"/opt/qps_driver --rpc_type=UNARY --client_type=SYNC_CLIENT \
- --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
- --secure_test=$secure --num_servers=1 --num_clients=1
-
- # Scenario 6: Sync streaming ping-pong with protobufs
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=SYNC_CLIENT \
- --server_type=SYNC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
- --secure_test=$secure --num_servers=1 --num_clients=1
-
- # Scenario 7: Async unary ping-pong with protobufs
- "$bins"/opt/qps_driver --rpc_type=UNARY --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 8: Async streaming ping-pong with protobufs
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=1 --simple_req_size=0 --simple_resp_size=0 \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 9: Crossbar QPS test
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=$wide --bbuf_req_size=0 --bbuf_resp_size=0 \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=$half --num_clients=0
-
- # Scenario 10: Multi-channel bidir throughput test
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=1 \
- --client_channels=$wide --bbuf_req_size=$big --bbuf_resp_size=$big \
- --async_client_threads=0 --async_server_threads=0 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 11: Single-channel request throughput test
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=1 --bbuf_req_size=$big --bbuf_resp_size=0 \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 12: Single-channel response throughput test
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_GENERIC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=1 --bbuf_req_size=0 --bbuf_resp_size=$big \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-
- # Scenario 13: Single-channel bidirectional protobuf throughput test
- "$bins"/opt/qps_driver --rpc_type=STREAMING --client_type=ASYNC_CLIENT \
- --server_type=ASYNC_SERVER --outstanding_rpcs_per_channel=$deep \
- --client_channels=1 --simple_req_size=$big --simple_resp_size=$big \
- --async_client_threads=1 --async_server_threads=1 --secure_test=$secure \
- --num_servers=1 --num_clients=1
-done
diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc
deleted file mode 100644
index e412c6919a..0000000000
--- a/test/cpp/qps/qps_driver.cc
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- *
- * 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 <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/benchmark_config.h"
-
-DEFINE_int32(num_clients, 1, "Number of client binaries");
-DEFINE_int32(num_servers, 1, "Number of server binaries");
-
-DEFINE_int32(warmup_seconds, 5, "Warmup time (in seconds)");
-DEFINE_int32(benchmark_seconds, 30, "Benchmark time (in seconds)");
-DEFINE_int32(local_workers, 0, "Number of local workers to start");
-
-// Server config
-DEFINE_int32(async_server_threads, 1, "Number of threads for async servers");
-DEFINE_string(server_type, "SYNC_SERVER", "Server type");
-DEFINE_int32(server_core_limit, -1, "Limit on server cores to use");
-
-// Client config
-DEFINE_string(rpc_type, "UNARY", "Type of RPC: UNARY or STREAMING");
-DEFINE_int32(outstanding_rpcs_per_channel, 1,
- "Number of outstanding rpcs per channel");
-DEFINE_int32(client_channels, 1, "Number of client channels");
-
-DEFINE_int32(simple_req_size, -1, "Simple proto request payload size");
-DEFINE_int32(simple_resp_size, -1, "Simple proto response payload size");
-DEFINE_int32(bbuf_req_size, -1, "Byte-buffer request payload size");
-DEFINE_int32(bbuf_resp_size, -1, "Byte-buffer response payload size");
-
-DEFINE_string(client_type, "SYNC_CLIENT", "Client type");
-DEFINE_int32(async_client_threads, 1, "Async client threads");
-
-DEFINE_double(poisson_load, -1.0, "Poisson offered load (qps)");
-DEFINE_double(uniform_lo, -1.0, "Uniform low interarrival time (us)");
-DEFINE_double(uniform_hi, -1.0, "Uniform high interarrival time (us)");
-DEFINE_double(determ_load, -1.0, "Deterministic offered load (qps)");
-DEFINE_double(pareto_base, -1.0, "Pareto base interarrival time (us)");
-DEFINE_double(pareto_alpha, -1.0, "Pareto alpha value");
-
-DEFINE_int32(client_core_limit, -1, "Limit on client cores to use");
-
-DEFINE_bool(secure_test, false, "Run a secure test");
-
-DEFINE_bool(quit, false, "Quit the workers");
-
-using grpc::testing::ClientConfig;
-using grpc::testing::ServerConfig;
-using grpc::testing::ClientType;
-using grpc::testing::ServerType;
-using grpc::testing::RpcType;
-using grpc::testing::ResourceUsage;
-using grpc::testing::SecurityParams;
-
-namespace grpc {
-namespace testing {
-
-static void QpsDriver() {
- if (FLAGS_quit) {
- RunQuit();
- return;
- }
-
- RpcType rpc_type;
- GPR_ASSERT(RpcType_Parse(FLAGS_rpc_type, &rpc_type));
-
- ClientType client_type;
- ServerType server_type;
- GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type));
- GPR_ASSERT(ServerType_Parse(FLAGS_server_type, &server_type));
-
- ClientConfig client_config;
- client_config.set_client_type(client_type);
- client_config.set_outstanding_rpcs_per_channel(
- FLAGS_outstanding_rpcs_per_channel);
- client_config.set_client_channels(FLAGS_client_channels);
-
- // Decide which type to use based on the response type
- if (FLAGS_simple_resp_size >= 0) {
- auto params =
- client_config.mutable_payload_config()->mutable_simple_params();
- params->set_resp_size(FLAGS_simple_resp_size);
- if (FLAGS_simple_req_size >= 0) {
- params->set_req_size(FLAGS_simple_req_size);
- }
- } else if (FLAGS_bbuf_resp_size >= 0) {
- auto params =
- client_config.mutable_payload_config()->mutable_bytebuf_params();
- params->set_resp_size(FLAGS_bbuf_resp_size);
- if (FLAGS_bbuf_req_size >= 0) {
- params->set_req_size(FLAGS_bbuf_req_size);
- }
- } else {
- // set a reasonable default: proto but no payload
- client_config.mutable_payload_config()->mutable_simple_params();
- }
-
- client_config.set_async_client_threads(FLAGS_async_client_threads);
- client_config.set_rpc_type(rpc_type);
-
- // set up the load parameters
- if (FLAGS_poisson_load > 0.0) {
- auto poisson = client_config.mutable_load_params()->mutable_poisson();
- poisson->set_offered_load(FLAGS_poisson_load);
- } else if (FLAGS_uniform_lo > 0.0) {
- auto uniform = client_config.mutable_load_params()->mutable_uniform();
- uniform->set_interarrival_lo(FLAGS_uniform_lo / 1e6);
- uniform->set_interarrival_hi(FLAGS_uniform_hi / 1e6);
- } else if (FLAGS_determ_load > 0.0) {
- auto determ = client_config.mutable_load_params()->mutable_determ();
- determ->set_offered_load(FLAGS_determ_load);
- } else if (FLAGS_pareto_base > 0.0) {
- auto pareto = client_config.mutable_load_params()->mutable_pareto();
- pareto->set_interarrival_base(FLAGS_pareto_base / 1e6);
- pareto->set_alpha(FLAGS_pareto_alpha);
- } else {
- client_config.mutable_load_params()->mutable_closed_loop();
- // No further load parameters to set up for closed loop
- }
-
- client_config.mutable_histogram_params()->set_resolution(
- Histogram::default_resolution());
- client_config.mutable_histogram_params()->set_max_possible(
- Histogram::default_max_possible());
-
- if (FLAGS_client_core_limit > 0) {
- client_config.set_core_limit(FLAGS_client_core_limit);
- }
-
- ServerConfig server_config;
- server_config.set_server_type(server_type);
- server_config.set_async_server_threads(FLAGS_async_server_threads);
-
- if (FLAGS_server_core_limit > 0) {
- server_config.set_core_limit(FLAGS_server_core_limit);
- }
-
- if (FLAGS_bbuf_resp_size >= 0) {
- *server_config.mutable_payload_config() = client_config.payload_config();
- }
-
- if (FLAGS_secure_test) {
- // Set up security params
- SecurityParams security;
- security.set_use_test_ca(true);
- security.set_server_host_override("foo.test.google.fr");
- client_config.mutable_security_params()->CopyFrom(security);
- server_config.mutable_security_params()->CopyFrom(security);
- }
-
- // Make sure that if we are performing a generic (bytebuf) test
- // that we are also using async streaming
- GPR_ASSERT(!client_config.payload_config().has_bytebuf_params() ||
- (client_config.client_type() == ASYNC_CLIENT &&
- client_config.rpc_type() == STREAMING &&
- server_config.server_type() == ASYNC_GENERIC_SERVER));
-
- const auto result = RunScenario(
- client_config, FLAGS_num_clients, server_config, FLAGS_num_servers,
- FLAGS_warmup_seconds, FLAGS_benchmark_seconds, FLAGS_local_workers);
-
- GetReporter()->ReportQPS(*result);
- GetReporter()->ReportQPSPerCore(*result);
- GetReporter()->ReportLatency(*result);
- GetReporter()->ReportTimes(*result);
-}
-
-} // namespace testing
-} // namespace grpc
-
-int main(int argc, char** argv) {
- grpc::testing::InitBenchmark(&argc, &argv, true);
-
- grpc::testing::QpsDriver();
-
- return 0;
-}
diff --git a/test/cpp/qps/qps_interarrival_test.cc b/test/cpp/qps/qps_interarrival_test.cc
index 48585af756..4055c8a718 100644
--- a/test/cpp/qps/qps_interarrival_test.cc
+++ b/test/cpp/qps/qps_interarrival_test.cc
@@ -63,14 +63,8 @@ static void RunTest(RandomDistInterface &&r, int threads, std::string title) {
}
using grpc::testing::ExpDist;
-using grpc::testing::DetDist;
-using grpc::testing::UniformDist;
-using grpc::testing::ParetoDist;
int main(int argc, char **argv) {
RunTest(ExpDist(10.0), 5, std::string("Exponential(10)"));
- RunTest(DetDist(5.0), 5, std::string("Det(5)"));
- RunTest(UniformDist(0.0, 10.0), 5, std::string("Uniform(0,10)"));
- RunTest(ParetoDist(1.0, 1.0), 5, std::string("Pareto(1,1)"));
return 0;
}
diff --git a/test/cpp/qps/qps_json_driver.cc b/test/cpp/qps/qps_json_driver.cc
index 8af4e291a9..e47d48a4f7 100644
--- a/test/cpp/qps/qps_json_driver.cc
+++ b/test/cpp/qps/qps_json_driver.cc
@@ -48,6 +48,7 @@ DEFINE_string(scenarios_file, "",
"JSON file containing an array of Scenario objects");
DEFINE_string(scenarios_json, "",
"JSON string containing an array of Scenario objects");
+DEFINE_bool(quit, false, "Quit the workers");
namespace grpc {
namespace testing {
@@ -55,12 +56,17 @@ namespace testing {
static void QpsDriver() {
grpc::string json;
- if (FLAGS_scenarios_file != "") {
- if (FLAGS_scenarios_json != "") {
- gpr_log(GPR_ERROR,
- "Only one of --scenarios_file or --scenarios_json must be set");
- abort();
- }
+ bool scfile = (FLAGS_scenarios_file != "");
+ bool scjson = (FLAGS_scenarios_json != "");
+ if ((!scfile && !scjson && !FLAGS_quit) ||
+ (scfile && (scjson || FLAGS_quit)) || (scjson && FLAGS_quit)) {
+ gpr_log(GPR_ERROR,
+ "Exactly one of --scenarios_file, --scenarios_json, "
+ "or --quit must be set");
+ abort();
+ }
+
+ if (scfile) {
// Read the json data from disk
FILE *json_file = fopen(FLAGS_scenarios_file.c_str(), "r");
GPR_ASSERT(json_file != NULL);
@@ -72,12 +78,11 @@ static void QpsDriver() {
fclose(json_file);
json = grpc::string(data, data + len);
delete[] data;
- } else if (FLAGS_scenarios_json != "") {
+ } else if (scjson) {
json = FLAGS_scenarios_json.c_str();
- } else {
- gpr_log(GPR_ERROR,
- "One of --scenarios_file or --scenarios_json must be set");
- abort();
+ } else if (FLAGS_quit) {
+ RunQuit();
+ return;
}
// Parse into an array of scenarios
@@ -87,12 +92,16 @@ static void QpsDriver() {
for (int i = 0; i < scenarios.scenarios_size(); i++) {
const Scenario &scenario = scenarios.scenarios(i);
std::cerr << "RUNNING SCENARIO: " << scenario.name() << "\n";
- const auto result =
+ auto result =
RunScenario(scenario.client_config(), scenario.num_clients(),
scenario.server_config(), scenario.num_servers(),
scenario.warmup_seconds(), scenario.benchmark_seconds(),
scenario.spawn_local_worker_count());
+ // Amend the result with scenario config. Eventually we should adjust
+ // RunScenario contract so we don't need to touch the result here.
+ result->mutable_scenario()->CopyFrom(scenario);
+
GetReporter()->ReportQPS(*result);
GetReporter()->ReportQPSPerCore(*result);
GetReporter()->ReportLatency(*result);
diff --git a/test/cpp/qps/report.cc b/test/cpp/qps/report.cc
index b230eb441e..3ae41399cf 100644
--- a/test/cpp/qps/report.cc
+++ b/test/cpp/qps/report.cc
@@ -33,6 +33,11 @@
#include "test/cpp/qps/report.h"
+#include <fstream>
+
+#include <google/protobuf/util/json_util.h>
+#include <google/protobuf/util/type_resolver_util.h>
+
#include <grpc/support/log.h>
#include "test/cpp/qps/driver.h"
#include "test/cpp/qps/stats.h"
@@ -40,11 +45,6 @@
namespace grpc {
namespace testing {
-static double WallTime(ResourceUsage u) { return u.wall_time(); }
-static double UserTime(ResourceUsage u) { return u.user_time(); }
-static double SystemTime(ResourceUsage u) { return u.system_time(); }
-static int Cores(ResourceUsage u) { return u.cores(); }
-
void CompositeReporter::add(std::unique_ptr<Reporter> reporter) {
reporters_.emplace_back(std::move(reporter));
}
@@ -74,102 +74,63 @@ void CompositeReporter::ReportTimes(const ScenarioResult& result) {
}
void GprLogReporter::ReportQPS(const ScenarioResult& result) {
- gpr_log(
- GPR_INFO, "QPS: %.1f",
- result.latencies.Count() / average(result.client_resources, WallTime));
+ gpr_log(GPR_INFO, "QPS: %.1f", result.summary().qps());
}
void GprLogReporter::ReportQPSPerCore(const ScenarioResult& result) {
- auto qps =
- result.latencies.Count() / average(result.client_resources, WallTime);
-
- gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", qps,
- qps / sum(result.server_resources, Cores));
+ gpr_log(GPR_INFO, "QPS: %.1f (%.1f/server core)", result.summary().qps(),
+ result.summary().qps_per_server_core());
}
void GprLogReporter::ReportLatency(const ScenarioResult& result) {
gpr_log(GPR_INFO,
"Latencies (50/90/95/99/99.9%%-ile): %.1f/%.1f/%.1f/%.1f/%.1f us",
- result.latencies.Percentile(50) / 1000,
- result.latencies.Percentile(90) / 1000,
- result.latencies.Percentile(95) / 1000,
- result.latencies.Percentile(99) / 1000,
- result.latencies.Percentile(99.9) / 1000);
+ result.summary().latency_50() / 1000,
+ result.summary().latency_90() / 1000,
+ result.summary().latency_95() / 1000,
+ result.summary().latency_99() / 1000,
+ result.summary().latency_999() / 1000);
}
void GprLogReporter::ReportTimes(const ScenarioResult& result) {
gpr_log(GPR_INFO, "Server system time: %.2f%%",
- 100.0 * sum(result.server_resources, SystemTime) /
- sum(result.server_resources, WallTime));
+ result.summary().server_system_time());
gpr_log(GPR_INFO, "Server user time: %.2f%%",
- 100.0 * sum(result.server_resources, UserTime) /
- sum(result.server_resources, WallTime));
+ result.summary().server_user_time());
gpr_log(GPR_INFO, "Client system time: %.2f%%",
- 100.0 * sum(result.client_resources, SystemTime) /
- sum(result.client_resources, WallTime));
+ result.summary().client_system_time());
gpr_log(GPR_INFO, "Client user time: %.2f%%",
- 100.0 * sum(result.client_resources, UserTime) /
- sum(result.client_resources, WallTime));
+ result.summary().client_user_time());
}
-void PerfDbReporter::ReportQPS(const ScenarioResult& result) {
- auto qps =
- result.latencies.Count() / average(result.client_resources, WallTime);
-
- perf_db_client_.setQps(qps);
- perf_db_client_.setConfigs(result.client_config, result.server_config);
+void JsonReporter::ReportQPS(const ScenarioResult& result) {
+ std::unique_ptr<google::protobuf::util::TypeResolver> type_resolver(
+ google::protobuf::util::NewTypeResolverForDescriptorPool(
+ "type.googleapis.com",
+ google::protobuf::DescriptorPool::generated_pool()));
+ grpc::string binary;
+ grpc::string json_string;
+ result.SerializeToString(&binary);
+ auto status = BinaryToJsonString(
+ type_resolver.get(), "type.googleapis.com/grpc.testing.ScenarioResult",
+ binary, &json_string);
+ GPR_ASSERT(status.ok());
+
+ std::ofstream output_file(report_file_);
+ output_file << json_string;
+ output_file.close();
}
-void PerfDbReporter::ReportQPSPerCore(const ScenarioResult& result) {
- auto qps =
- result.latencies.Count() / average(result.client_resources, WallTime);
-
- auto qps_per_core = qps / sum(result.server_resources, Cores);
-
- perf_db_client_.setQps(qps);
- perf_db_client_.setQpsPerCore(qps_per_core);
- perf_db_client_.setConfigs(result.client_config, result.server_config);
-}
-
-void PerfDbReporter::ReportLatency(const ScenarioResult& result) {
- perf_db_client_.setLatencies(result.latencies.Percentile(50) / 1000,
- result.latencies.Percentile(90) / 1000,
- result.latencies.Percentile(95) / 1000,
- result.latencies.Percentile(99) / 1000,
- result.latencies.Percentile(99.9) / 1000);
- perf_db_client_.setConfigs(result.client_config, result.server_config);
+void JsonReporter::ReportQPSPerCore(const ScenarioResult& result) {
+ // NOP - all reporting is handled by ReportQPS.
}
-void PerfDbReporter::ReportTimes(const ScenarioResult& result) {
- const double server_system_time = 100.0 *
- sum(result.server_resources, SystemTime) /
- sum(result.server_resources, WallTime);
- const double server_user_time = 100.0 *
- sum(result.server_resources, UserTime) /
- sum(result.server_resources, WallTime);
- const double client_system_time = 100.0 *
- sum(result.client_resources, SystemTime) /
- sum(result.client_resources, WallTime);
- const double client_user_time = 100.0 *
- sum(result.client_resources, UserTime) /
- sum(result.client_resources, WallTime);
-
- perf_db_client_.setTimes(server_system_time, server_user_time,
- client_system_time, client_user_time);
- perf_db_client_.setConfigs(result.client_config, result.server_config);
+void JsonReporter::ReportLatency(const ScenarioResult& result) {
+ // NOP - all reporting is handled by ReportQPS.
}
-void PerfDbReporter::SendData() {
- // send data to performance database
- bool data_state =
- perf_db_client_.sendData(hashed_id_, test_name_, sys_info_, tag_);
-
- // check state of data sending
- if (data_state) {
- gpr_log(GPR_INFO, "Data sent to performance database successfully");
- } else {
- gpr_log(GPR_INFO, "Data could not be sent to performance database");
- }
+void JsonReporter::ReportTimes(const ScenarioResult& result) {
+ // NOP - all reporting is handled by ReportQPS.
}
} // namespace testing
diff --git a/test/cpp/qps/report.h b/test/cpp/qps/report.h
index 5caf3fe69a..8f04d84124 100644
--- a/test/cpp/qps/report.h
+++ b/test/cpp/qps/report.h
@@ -104,33 +104,19 @@ class GprLogReporter : public Reporter {
void ReportTimes(const ScenarioResult& result) GRPC_OVERRIDE;
};
-/** Reporter for performance database tool */
-class PerfDbReporter : public Reporter {
+/** Dumps the report to a JSON file. */
+class JsonReporter : public Reporter {
public:
- PerfDbReporter(const string& name, const string& hashed_id,
- const string& test_name, const string& sys_info,
- const string& server_address, const string& tag)
- : Reporter(name),
- hashed_id_(hashed_id),
- test_name_(test_name),
- sys_info_(sys_info),
- tag_(tag) {
- perf_db_client_.init(grpc::CreateChannel(
- server_address, grpc::InsecureChannelCredentials()));
- }
- ~PerfDbReporter() GRPC_OVERRIDE { SendData(); };
+ JsonReporter(const string& name, const string& report_file)
+ : Reporter(name), report_file_(report_file) {}
private:
- PerfDbClient perf_db_client_;
- std::string hashed_id_;
- std::string test_name_;
- std::string sys_info_;
- std::string tag_;
void ReportQPS(const ScenarioResult& result) GRPC_OVERRIDE;
void ReportQPSPerCore(const ScenarioResult& result) GRPC_OVERRIDE;
void ReportLatency(const ScenarioResult& result) GRPC_OVERRIDE;
void ReportTimes(const ScenarioResult& result) GRPC_OVERRIDE;
- void SendData();
+
+ const string report_file_;
};
} // namespace testing
diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh
deleted file mode 100755
index f5356f1834..0000000000
--- a/test/cpp/qps/single_run_localhost.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/sh
-# 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.
-
-# performs a single qps run with one client and one server
-
-set -ex
-
-cd $(dirname $0)/../../..
-
-killall qps_worker || true
-
-config=opt
-
-NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'`
-
-make CONFIG=$config qps_worker qps_driver -j$NUMCPUS
-
-bins/$config/qps_worker -driver_port 10000 &
-PID1=$!
-bins/$config/qps_worker -driver_port 10010 &
-PID2=$!
-
-export QPS_WORKERS="localhost:10000,localhost:10010"
-
-bins/$config/qps_driver $*
-
-kill -2 $PID1 $PID2
-wait
-
diff --git a/test/cpp/util/benchmark_config.cc b/test/cpp/util/benchmark_config.cc
index 746d3d7ae6..6fc864069e 100644
--- a/test/cpp/util/benchmark_config.cc
+++ b/test/cpp/util/benchmark_config.cc
@@ -37,8 +37,8 @@
DEFINE_bool(enable_log_reporter, true,
"Enable reporting of benchmark results through GprLog");
-DEFINE_bool(report_metrics_db, false,
- "True if metrics to be reported to performance database");
+DEFINE_string(scenario_result_file, "",
+ "Write JSON benchmark report to the file specified.");
DEFINE_string(hashed_id, "", "Hash of the user id");
@@ -71,10 +71,9 @@ static std::shared_ptr<Reporter> InitBenchmarkReporters() {
composite_reporter->add(
std::unique_ptr<Reporter>(new GprLogReporter("LogReporter")));
}
- if (FLAGS_report_metrics_db) {
+ if (FLAGS_scenario_result_file != "") {
composite_reporter->add(std::unique_ptr<Reporter>(
- new PerfDbReporter("PerfDbReporter", FLAGS_hashed_id, FLAGS_test_name,
- FLAGS_sys_info, FLAGS_server_address, FLAGS_tag)));
+ new JsonReporter("JsonReporter", FLAGS_scenario_result_file)));
}
return std::shared_ptr<Reporter>(composite_reporter);