Merge pull request #4859 from ctiller/sceq
Subchannel Sharing [The interop tests failures and Basic test failures are unrelated to this change. Merging]
diff --git a/grpc.def b/grpc.def
index d37e687..bd0bc85 100644
--- a/grpc.def
+++ b/grpc.def
@@ -99,6 +99,7 @@
grpc_auth_context_set_peer_identity_property_name
grpc_channel_credentials_release
grpc_google_default_credentials_create
+ grpc_set_ssl_roots_override_callback
grpc_ssl_credentials_create
grpc_call_credentials_release
grpc_composite_channel_credentials_create
diff --git a/include/grpc++/support/channel_arguments.h b/include/grpc++/support/channel_arguments.h
index a2960a7..4e530d4 100644
--- a/include/grpc++/support/channel_arguments.h
+++ b/include/grpc++/support/channel_arguments.h
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -51,7 +51,7 @@
/// concrete setters are provided.
class ChannelArguments {
public:
- ChannelArguments() {}
+ ChannelArguments();
~ChannelArguments() {}
ChannelArguments(const ChannelArguments& other);
@@ -62,8 +62,8 @@
void Swap(ChannelArguments& other);
- /// Populates this instance with the arguments from \a channel_args. Does not
- /// take ownership of \a channel_args.
+ /// Dump arguments in this instance to \a channel_args. Does not take
+ /// ownership of \a channel_args.
///
/// Note that the underlying arguments are shared. Changes made to either \a
/// channel_args or this instance would be reflected on both.
@@ -77,6 +77,9 @@
/// Set the compression algorithm for the channel.
void SetCompressionAlgorithm(grpc_compression_algorithm algorithm);
+ /// The given string will be sent at the front of the user agent string.
+ void SetUserAgentPrefix(const grpc::string& user_agent_prefix);
+
// Generic channel argument setters. Only for advanced use cases.
/// Set an integer argument \a value under \a key.
void SetInt(const grpc::string& key, int value);
diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h
index 3de5cae..ef7205d 100644
--- a/include/grpc/grpc_security.h
+++ b/include/grpc/grpc_security.h
@@ -167,7 +167,8 @@
before any ssl credentials are created to have the desired side effect.
If GRPC_DEFAULT_SSL_ROOTS_FILE_PATH environment is set to a valid path, the
callback will not be called. */
-void grpc_set_ssl_roots_override_callback(grpc_ssl_roots_override_callback cb);
+GRPCAPI void grpc_set_ssl_roots_override_callback(
+ grpc_ssl_roots_override_callback cb);
/* Object that holds a private key / certificate chain pair in PEM format. */
typedef struct {
diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc
index fdaa28f..76a1b31 100644
--- a/src/cpp/client/create_channel.cc
+++ b/src/cpp/client/create_channel.cc
@@ -32,7 +32,6 @@
*/
#include <memory>
-#include <sstream>
#include <grpc++/channel.h>
#include <grpc++/create_channel.h>
@@ -56,13 +55,8 @@
const ChannelArguments& args) {
internal::GrpcLibrary
init_lib; // We need to call init in case of a bad creds.
- ChannelArguments cp_args = args;
- std::ostringstream user_agent_prefix;
- user_agent_prefix << "grpc-c++/" << grpc_version_string();
- cp_args.SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING,
- user_agent_prefix.str());
return creds
- ? creds->CreateChannel(target, cp_args)
+ ? creds->CreateChannel(target, args)
: CreateChannelInternal("", grpc_lame_client_channel_create(
NULL, GRPC_STATUS_INVALID_ARGUMENT,
"Invalid credentials."));
diff --git a/src/cpp/common/channel_arguments.cc b/src/cpp/common/channel_arguments.cc
index a495118..989c105 100644
--- a/src/cpp/common/channel_arguments.cc
+++ b/src/cpp/common/channel_arguments.cc
@@ -30,14 +30,23 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
-
#include <grpc++/support/channel_arguments.h>
+#include <sstream>
+
+#include <grpc/impl/codegen/grpc_types.h>
#include <grpc/support/log.h>
#include "src/core/channel/channel_args.h"
namespace grpc {
+ChannelArguments::ChannelArguments() {
+ std::ostringstream user_agent_prefix;
+ user_agent_prefix << "grpc-c++/" << grpc_version_string();
+ // This will be ignored if used on the server side.
+ SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix.str());
+}
+
ChannelArguments::ChannelArguments(const ChannelArguments& other)
: strings_(other.strings_) {
args_.reserve(other.args_.size());
@@ -79,6 +88,31 @@
SetInt(GRPC_COMPRESSION_ALGORITHM_ARG, algorithm);
}
+// Note: a second call to this will add in front the result of the first call.
+// An example is calling this on a copy of ChannelArguments which already has a
+// prefix. The user can build up a prefix string by calling this multiple times,
+// each with more significant identifier.
+void ChannelArguments::SetUserAgentPrefix(
+ const grpc::string& user_agent_prefix) {
+ if (user_agent_prefix.empty()) {
+ return;
+ }
+ bool replaced = false;
+ for (auto it = args_.begin(); it != args_.end(); ++it) {
+ const grpc_arg& arg = *it;
+ if (arg.type == GRPC_ARG_STRING &&
+ grpc::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
+ strings_.push_back(user_agent_prefix + " " + arg.value.string);
+ it->value.string = const_cast<char*>(strings_.back().c_str());
+ replaced = true;
+ break;
+ }
+ }
+ if (!replaced) {
+ SetString(GRPC_ARG_PRIMARY_USER_AGENT_STRING, user_agent_prefix);
+ }
+}
+
void ChannelArguments::SetInt(const grpc::string& key, int value) {
grpc_arg arg;
arg.type = GRPC_ARG_INTEGER;
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.c b/src/python/grpcio/grpc/_cython/imports.generated.c
index 4aa41db..4b1860c 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.c
+++ b/src/python/grpcio/grpc/_cython/imports.generated.c
@@ -137,6 +137,7 @@
grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_peer_identity_property_name_import;
grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
+grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import;
grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
grpc_call_credentials_release_type grpc_call_credentials_release_import;
grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
@@ -401,6 +402,7 @@
grpc_auth_context_set_peer_identity_property_name_import = (grpc_auth_context_set_peer_identity_property_name_type) GetProcAddress(library, "grpc_auth_context_set_peer_identity_property_name");
grpc_channel_credentials_release_import = (grpc_channel_credentials_release_type) GetProcAddress(library, "grpc_channel_credentials_release");
grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create");
+ grpc_set_ssl_roots_override_callback_import = (grpc_set_ssl_roots_override_callback_type) GetProcAddress(library, "grpc_set_ssl_roots_override_callback");
grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create");
grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release");
grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create");
diff --git a/src/python/grpcio/grpc/_cython/imports.generated.h b/src/python/grpcio/grpc/_cython/imports.generated.h
index f5329f3..ca30742 100644
--- a/src/python/grpcio/grpc/_cython/imports.generated.h
+++ b/src/python/grpcio/grpc/_cython/imports.generated.h
@@ -361,6 +361,9 @@
typedef grpc_channel_credentials *(*grpc_google_default_credentials_create_type)(void);
extern grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
#define grpc_google_default_credentials_create grpc_google_default_credentials_create_import
+typedef void(*grpc_set_ssl_roots_override_callback_type)(grpc_ssl_roots_override_callback cb);
+extern grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import;
+#define grpc_set_ssl_roots_override_callback grpc_set_ssl_roots_override_callback_import
typedef grpc_channel_credentials *(*grpc_ssl_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, void *reserved);
extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
#define grpc_ssl_credentials_create grpc_ssl_credentials_create_import
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.c b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
index d4ddb73..1af34d9 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.c
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.c
@@ -137,6 +137,7 @@
grpc_auth_context_set_peer_identity_property_name_type grpc_auth_context_set_peer_identity_property_name_import;
grpc_channel_credentials_release_type grpc_channel_credentials_release_import;
grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
+grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import;
grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
grpc_call_credentials_release_type grpc_call_credentials_release_import;
grpc_composite_channel_credentials_create_type grpc_composite_channel_credentials_create_import;
@@ -397,6 +398,7 @@
grpc_auth_context_set_peer_identity_property_name_import = (grpc_auth_context_set_peer_identity_property_name_type) GetProcAddress(library, "grpc_auth_context_set_peer_identity_property_name");
grpc_channel_credentials_release_import = (grpc_channel_credentials_release_type) GetProcAddress(library, "grpc_channel_credentials_release");
grpc_google_default_credentials_create_import = (grpc_google_default_credentials_create_type) GetProcAddress(library, "grpc_google_default_credentials_create");
+ grpc_set_ssl_roots_override_callback_import = (grpc_set_ssl_roots_override_callback_type) GetProcAddress(library, "grpc_set_ssl_roots_override_callback");
grpc_ssl_credentials_create_import = (grpc_ssl_credentials_create_type) GetProcAddress(library, "grpc_ssl_credentials_create");
grpc_call_credentials_release_import = (grpc_call_credentials_release_type) GetProcAddress(library, "grpc_call_credentials_release");
grpc_composite_channel_credentials_create_import = (grpc_composite_channel_credentials_create_type) GetProcAddress(library, "grpc_composite_channel_credentials_create");
diff --git a/src/ruby/ext/grpc/rb_grpc_imports.generated.h b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
index 618ae5e..b61c528 100644
--- a/src/ruby/ext/grpc/rb_grpc_imports.generated.h
+++ b/src/ruby/ext/grpc/rb_grpc_imports.generated.h
@@ -361,6 +361,9 @@
typedef grpc_channel_credentials *(*grpc_google_default_credentials_create_type)(void);
extern grpc_google_default_credentials_create_type grpc_google_default_credentials_create_import;
#define grpc_google_default_credentials_create grpc_google_default_credentials_create_import
+typedef void(*grpc_set_ssl_roots_override_callback_type)(grpc_ssl_roots_override_callback cb);
+extern grpc_set_ssl_roots_override_callback_type grpc_set_ssl_roots_override_callback_import;
+#define grpc_set_ssl_roots_override_callback grpc_set_ssl_roots_override_callback_import
typedef grpc_channel_credentials *(*grpc_ssl_credentials_create_type)(const char *pem_root_certs, grpc_ssl_pem_key_cert_pair *pem_key_cert_pair, void *reserved);
extern grpc_ssl_credentials_create_type grpc_ssl_credentials_create_import;
#define grpc_ssl_credentials_create grpc_ssl_credentials_create_import
diff --git a/test/cpp/common/channel_arguments_test.cc b/test/cpp/common/channel_arguments_test.cc
index e010d37..5ee63bf 100644
--- a/test/cpp/common/channel_arguments_test.cc
+++ b/test/cpp/common/channel_arguments_test.cc
@@ -1,6 +1,6 @@
/*
*
- * Copyright 2015, Google Inc.
+ * Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -45,90 +45,131 @@
grpc_channel_args* args) {
channel_args.SetChannelArgs(args);
}
+
+ grpc::string GetDefaultUserAgentPrefix() {
+ std::ostringstream user_agent_prefix;
+ user_agent_prefix << "grpc-c++/" << grpc_version_string();
+ return user_agent_prefix.str();
+ }
+
+ void VerifyDefaultChannelArgs() {
+ grpc_channel_args args;
+ SetChannelArgs(channel_args_, &args);
+ EXPECT_EQ(static_cast<size_t>(1), args.num_args);
+ EXPECT_STREQ(GRPC_ARG_PRIMARY_USER_AGENT_STRING, args.args[0].key);
+ EXPECT_EQ(GetDefaultUserAgentPrefix(),
+ grpc::string(args.args[0].value.string));
+ }
+
+ bool HasArg(grpc_arg expected_arg) {
+ grpc_channel_args args;
+ SetChannelArgs(channel_args_, &args);
+ for (size_t i = 0; i < args.num_args; i++) {
+ const grpc_arg& arg = args.args[i];
+ if (arg.type == expected_arg.type &&
+ grpc::string(arg.key) == expected_arg.key) {
+ if (arg.type == GRPC_ARG_INTEGER) {
+ return arg.value.integer == expected_arg.value.integer;
+ } else if (arg.type == GRPC_ARG_STRING) {
+ return grpc::string(arg.value.string) == expected_arg.value.string;
+ } else if (arg.type == GRPC_ARG_POINTER) {
+ return arg.value.pointer.p == expected_arg.value.pointer.p &&
+ arg.value.pointer.copy == expected_arg.value.pointer.copy &&
+ arg.value.pointer.destroy ==
+ expected_arg.value.pointer.destroy;
+ }
+ }
+ }
+ return false;
+ }
+ ChannelArguments channel_args_;
};
TEST_F(ChannelArgumentsTest, SetInt) {
- grpc_channel_args args;
- ChannelArguments channel_args;
- // Empty arguments.
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(0), args.num_args);
+ VerifyDefaultChannelArgs();
+ grpc::string key0("key0");
+ grpc_arg arg0;
+ arg0.type = GRPC_ARG_INTEGER;
+ arg0.key = const_cast<char*>(key0.c_str());
+ arg0.value.integer = 0;
+ grpc::string key1("key1");
+ grpc_arg arg1;
+ arg1.type = GRPC_ARG_INTEGER;
+ arg1.key = const_cast<char*>(key1.c_str());
+ arg1.value.integer = 1;
- grpc::string key("key0");
- channel_args.SetInt(key, 0);
+ grpc::string arg_key0(key0);
+ channel_args_.SetInt(arg_key0, arg0.value.integer);
// Clear key early to make sure channel_args takes a copy
- key = "";
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(1), args.num_args);
- EXPECT_EQ(GRPC_ARG_INTEGER, args.args[0].type);
- EXPECT_STREQ("key0", args.args[0].key);
- EXPECT_EQ(0, args.args[0].value.integer);
+ arg_key0.clear();
+ EXPECT_TRUE(HasArg(arg0));
- key = "key1";
- channel_args.SetInt(key, 1);
- key = "";
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(2), args.num_args);
- // We do not enforce order on the arguments.
- for (size_t i = 0; i < args.num_args; i++) {
- EXPECT_EQ(GRPC_ARG_INTEGER, args.args[i].type);
- if (grpc::string(args.args[i].key) == "key0") {
- EXPECT_EQ(0, args.args[i].value.integer);
- } else if (grpc::string(args.args[i].key) == "key1") {
- EXPECT_EQ(1, args.args[i].value.integer);
- }
- }
+ grpc::string arg_key1(key1);
+ channel_args_.SetInt(arg_key1, arg1.value.integer);
+ arg_key1.clear();
+ EXPECT_TRUE(HasArg(arg0));
+ EXPECT_TRUE(HasArg(arg1));
}
TEST_F(ChannelArgumentsTest, SetString) {
- grpc_channel_args args;
- ChannelArguments channel_args;
- // Empty arguments.
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(0), args.num_args);
+ VerifyDefaultChannelArgs();
+ grpc::string key0("key0");
+ grpc::string val0("val0");
+ grpc_arg arg0;
+ arg0.type = GRPC_ARG_STRING;
+ arg0.key = const_cast<char*>(key0.c_str());
+ arg0.value.string = const_cast<char*>(val0.c_str());
+ grpc::string key1("key1");
+ grpc::string val1("val1");
+ grpc_arg arg1;
+ arg1.type = GRPC_ARG_STRING;
+ arg1.key = const_cast<char*>(key1.c_str());
+ arg1.value.string = const_cast<char*>(val1.c_str());
- grpc::string key("key0");
- grpc::string val("val0");
- channel_args.SetString(key, val);
+ grpc::string key(key0);
+ grpc::string val(val0);
+ channel_args_.SetString(key, val);
// Clear key/val early to make sure channel_args takes a copy
key = "";
val = "";
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(1), args.num_args);
- EXPECT_EQ(GRPC_ARG_STRING, args.args[0].type);
- EXPECT_STREQ("key0", args.args[0].key);
- EXPECT_STREQ("val0", args.args[0].value.string);
+ EXPECT_TRUE(HasArg(arg0));
- key = "key1";
- val = "val1";
- channel_args.SetString(key, val);
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(2), args.num_args);
- // We do not enforce order on the arguments.
- for (size_t i = 0; i < args.num_args; i++) {
- EXPECT_EQ(GRPC_ARG_STRING, args.args[i].type);
- if (grpc::string(args.args[i].key) == "key0") {
- EXPECT_STREQ("val0", args.args[i].value.string);
- } else if (grpc::string(args.args[i].key) == "key1") {
- EXPECT_STREQ("val1", args.args[i].value.string);
- }
- }
+ key = key1;
+ val = val1;
+ channel_args_.SetString(key, val);
+ // Clear key/val early to make sure channel_args takes a copy
+ key = "";
+ val = "";
+ EXPECT_TRUE(HasArg(arg0));
+ EXPECT_TRUE(HasArg(arg1));
}
TEST_F(ChannelArgumentsTest, SetPointer) {
- grpc_channel_args args;
- ChannelArguments channel_args;
- // Empty arguments.
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(0), args.num_args);
+ VerifyDefaultChannelArgs();
+ grpc::string key0("key0");
+ grpc_arg arg0;
+ arg0.type = GRPC_ARG_POINTER;
+ arg0.key = const_cast<char*>(key0.c_str());
+ arg0.value.pointer.p = &key0;
+ arg0.value.pointer.copy = nullptr;
+ arg0.value.pointer.destroy = nullptr;
- grpc::string key("key0");
- channel_args.SetPointer(key, &key);
- SetChannelArgs(channel_args, &args);
- EXPECT_EQ(static_cast<size_t>(1), args.num_args);
- EXPECT_EQ(GRPC_ARG_POINTER, args.args[0].type);
- EXPECT_STREQ("key0", args.args[0].key);
- EXPECT_EQ(&key, args.args[0].value.pointer.p);
+ grpc::string key(key0);
+ channel_args_.SetPointer(key, arg0.value.pointer.p);
+ EXPECT_TRUE(HasArg(arg0));
+}
+
+TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
+ VerifyDefaultChannelArgs();
+ grpc::string prefix("prefix");
+ grpc::string whole_prefix = prefix + " " + GetDefaultUserAgentPrefix();
+ grpc_arg arg0;
+ arg0.type = GRPC_ARG_STRING;
+ arg0.key = const_cast<char*>(GRPC_ARG_PRIMARY_USER_AGENT_STRING);
+ arg0.value.string = const_cast<char*>(whole_prefix.c_str());
+
+ channel_args_.SetUserAgentPrefix(prefix);
+ EXPECT_TRUE(HasArg(arg0));
}
} // namespace testing
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 65da71b..c852384 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -252,6 +252,9 @@
args.SetSslTargetNameOverride("foo.test.google.fr");
channel_creds = SslCredentials(ssl_opts);
}
+ if (!user_agent_prefix_.empty()) {
+ args.SetUserAgentPrefix(user_agent_prefix_);
+ }
args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args);
}
@@ -285,6 +288,7 @@
TestServiceImpl service_;
TestServiceImpl special_service_;
TestServiceImplDupPkg dup_pkg_service_;
+ grpc::string user_agent_prefix_;
};
static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs,
@@ -601,6 +605,25 @@
TestBidiStreamServerCancel(CANCEL_AFTER_PROCESSING, 5);
}
+TEST_P(End2endTest, SimpleRpcWithCustomeUserAgentPrefix) {
+ user_agent_prefix_ = "custom_prefix";
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello hello hello hello");
+ request.mutable_param()->set_echo_metadata(true);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+ const auto& trailing_metadata = context.GetServerTrailingMetadata();
+ auto iter = trailing_metadata.find("user-agent");
+ EXPECT_TRUE(iter != trailing_metadata.end());
+ grpc::string expected_prefix = user_agent_prefix_ + " grpc-c++/";
+ EXPECT_TRUE(iter->second.starts_with(expected_prefix));
+}
+
TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
ResetStub();
std::vector<std::thread*> threads;
diff --git a/test/cpp/qps/qps-sweep.sh b/test/cpp/qps/qps-sweep.sh
index 539da1d..7a35788 100755
--- a/test/cpp/qps/qps-sweep.sh
+++ b/test/cpp/qps/qps-sweep.sh
@@ -37,9 +37,26 @@
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
@@ -52,30 +69,40 @@
# 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=100 \
- --client_channels=64 --bbuf_req_size=0 --bbuf_resp_size=0 \
+ --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
+ --num_servers=1 --num_clients=0 |& 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=100 \
- --client_channels=64 --bbuf_req_size=0 --bbuf_resp_size=0 \
+ --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=100 \
- --client_channels=64 --simple_req_size=0 --simple_resp_size=0 \
+ --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 near-peak load (TBD)
+ # 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=100 \
+ --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
@@ -108,35 +135,35 @@
# 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=100 \
- --client_channels=64 --bbuf_req_size=0 --bbuf_resp_size=0 \
+ --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=100 \
- --client_channels=64 --bbuf_req_size=$big --bbuf_resp_size=$big \
+ --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=100 \
+ --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=100 \
+ --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=100 \
+ --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