aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp
diff options
context:
space:
mode:
authorGravatar David Garcia Quintas <dgq@google.com>2015-08-09 08:52:47 -0700
committerGravatar David Garcia Quintas <dgq@google.com>2015-08-09 09:10:56 -0700
commit10494fcb61d638682fb8e5d28356a1f5125e8d0a (patch)
treeb2ca81762344cd45d5333b732ff8b197e476f958 /test/cpp
parentbaa2aa644226b00ad9cb493660356f4473acd212 (diff)
parent7a75936001478a0f7ea7eaf204c1b19bd55190f9 (diff)
Merge branch 'master' into compression-accept-encoding
Diffstat (limited to 'test/cpp')
-rw-r--r--test/cpp/client/credentials_test.cc2
-rw-r--r--test/cpp/common/auth_property_iterator_test.cc17
-rw-r--r--test/cpp/common/secure_auth_context_test.cc24
-rw-r--r--test/cpp/end2end/async_end2end_test.cc74
-rw-r--r--test/cpp/end2end/end2end_test.cc270
-rw-r--r--test/cpp/end2end/generic_end2end_test.cc9
-rw-r--r--test/cpp/end2end/mock_test.cc4
-rw-r--r--test/cpp/end2end/thread_stress_test.cc4
-rw-r--r--test/cpp/interop/client.cc6
-rw-r--r--test/cpp/interop/client_helper.cc3
-rw-r--r--test/cpp/interop/interop_client.cc19
-rw-r--r--test/cpp/interop/interop_client.h1
-rw-r--r--test/cpp/interop/reconnect_interop_client.cc103
-rw-r--r--test/cpp/interop/reconnect_interop_server.cc190
-rw-r--r--test/cpp/interop/server.cc7
-rw-r--r--test/cpp/qps/qps_test.cc4
-rw-r--r--test/cpp/qps/server_async.cc1
-rw-r--r--test/cpp/qps/server_sync.cc13
-rw-r--r--test/cpp/qps/timer.cc2
-rw-r--r--test/cpp/server/dynamic_thread_pool_test.cc (renamed from test/cpp/util/fake_credentials.cc)53
-rw-r--r--test/cpp/util/cli_call_test.cc4
-rw-r--r--test/cpp/util/fake_credentials.h51
-rw-r--r--test/cpp/util/messages.proto3
23 files changed, 698 insertions, 166 deletions
diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc
index bbf7705f0a..6fb24d71e5 100644
--- a/test/cpp/client/credentials_test.cc
+++ b/test/cpp/client/credentials_test.cc
@@ -47,7 +47,7 @@ class CredentialsTest : public ::testing::Test {
TEST_F(CredentialsTest, InvalidServiceAccountCreds) {
std::shared_ptr<Credentials> bad1 = ServiceAccountCredentials("", "", 1);
- EXPECT_EQ(static_cast<Credentials *>(nullptr), bad1.get());
+ EXPECT_EQ(static_cast<Credentials*>(nullptr), bad1.get());
}
} // namespace testing
diff --git a/test/cpp/common/auth_property_iterator_test.cc b/test/cpp/common/auth_property_iterator_test.cc
index 3d983fa310..74b18ced0d 100644
--- a/test/cpp/common/auth_property_iterator_test.cc
+++ b/test/cpp/common/auth_property_iterator_test.cc
@@ -31,10 +31,14 @@
*
*/
+#include <grpc/grpc_security.h>
#include <grpc++/auth_context.h>
#include <gtest/gtest.h>
#include "src/cpp/common/secure_auth_context.h"
+
+extern "C" {
#include "src/core/security/security_context.h"
+}
namespace grpc {
namespace {
@@ -50,14 +54,15 @@ class TestAuthPropertyIterator : public AuthPropertyIterator {
class AuthPropertyIteratorTest : public ::testing::Test {
protected:
void SetUp() GRPC_OVERRIDE {
- ctx_ = grpc_auth_context_create(NULL, 3);
- ctx_->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
- ctx_->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
- ctx_->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
- ctx_->peer_identity_property_name = ctx_->properties[0].name;
+ ctx_ = grpc_auth_context_create(NULL);
+ grpc_auth_context_add_cstring_property(ctx_, "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx_, "name", "chapo");
+ grpc_auth_context_add_cstring_property(ctx_, "foo", "bar");
+ EXPECT_EQ(1,
+ grpc_auth_context_set_peer_identity_property_name(ctx_, "name"));
}
void TearDown() GRPC_OVERRIDE {
- GRPC_AUTH_CONTEXT_UNREF(ctx_, "AuthPropertyIteratorTest");
+ grpc_auth_context_release(ctx_);
}
grpc_auth_context* ctx_;
diff --git a/test/cpp/common/secure_auth_context_test.cc b/test/cpp/common/secure_auth_context_test.cc
index d0243a5432..075d4ce8c9 100644
--- a/test/cpp/common/secure_auth_context_test.cc
+++ b/test/cpp/common/secure_auth_context_test.cc
@@ -31,10 +31,14 @@
*
*/
+#include <grpc/grpc_security.h>
#include <grpc++/auth_context.h>
#include <gtest/gtest.h>
#include "src/cpp/common/secure_auth_context.h"
+
+extern "C" {
#include "src/core/security/security_context.h"
+}
namespace grpc {
namespace {
@@ -52,11 +56,11 @@ TEST_F(SecureAuthContextTest, EmptyContext) {
}
TEST_F(SecureAuthContextTest, Properties) {
- grpc_auth_context* ctx = grpc_auth_context_create(NULL, 3);
- ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
- ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
- ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
- ctx->peer_identity_property_name = ctx->properties[0].name;
+ grpc_auth_context* ctx = grpc_auth_context_create(NULL);
+ grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
+ grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
+ EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx, "name"));
SecureAuthContext context(ctx);
std::vector<grpc::string> peer_identity = context.GetPeerIdentity();
@@ -70,11 +74,11 @@ TEST_F(SecureAuthContextTest, Properties) {
}
TEST_F(SecureAuthContextTest, Iterators) {
- grpc_auth_context* ctx = grpc_auth_context_create(NULL, 3);
- ctx->properties[0] = grpc_auth_property_init_from_cstring("name", "chapi");
- ctx->properties[1] = grpc_auth_property_init_from_cstring("name", "chapo");
- ctx->properties[2] = grpc_auth_property_init_from_cstring("foo", "bar");
- ctx->peer_identity_property_name = ctx->properties[0].name;
+ grpc_auth_context* ctx = grpc_auth_context_create(NULL);
+ grpc_auth_context_add_cstring_property(ctx, "name", "chapi");
+ grpc_auth_context_add_cstring_property(ctx, "name", "chapo");
+ grpc_auth_context_add_cstring_property(ctx, "foo", "bar");
+ EXPECT_EQ(1, grpc_auth_context_set_peer_identity_property_name(ctx, "name"));
SecureAuthContext context(ctx);
AuthPropertyIterator iter = context.begin();
diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc
index b95bdf6b9b..9b53bdc999 100644
--- a/test/cpp/end2end/async_end2end_test.cc
+++ b/test/cpp/end2end/async_end2end_test.cc
@@ -592,6 +592,80 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) {
EXPECT_EQ(meta6.second, server_trailing_metadata.find(meta6.first)->second);
EXPECT_GE(server_trailing_metadata.size(), static_cast<size_t>(2));
}
+
+// Server uses AsyncNotifyWhenDone API to check for cancellation
+TEST_F(AsyncEnd2endTest, ServerCheckCancellation) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+ send_request.set_message("Hello");
+ std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+ stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
+
+ srv_ctx.AsyncNotifyWhenDone(tag(5));
+ service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
+ cq_.get(), tag(2));
+
+ Verifier().Expect(2, true).Verify(cq_.get());
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ cli_ctx.TryCancel();
+ Verifier().Expect(5, true).Verify(cq_.get());
+ EXPECT_TRUE(srv_ctx.IsCancelled());
+
+ response_reader->Finish(&recv_response, &recv_status, tag(4));
+ Verifier().Expect(4, false).Verify(cq_.get());
+
+ EXPECT_EQ(StatusCode::CANCELLED, recv_status.error_code());
+}
+
+// Server uses AsyncNotifyWhenDone API to check for normal finish
+TEST_F(AsyncEnd2endTest, ServerCheckDone) {
+ ResetStub();
+
+ EchoRequest send_request;
+ EchoRequest recv_request;
+ EchoResponse send_response;
+ EchoResponse recv_response;
+ Status recv_status;
+
+ ClientContext cli_ctx;
+ ServerContext srv_ctx;
+ grpc::ServerAsyncResponseWriter<EchoResponse> response_writer(&srv_ctx);
+
+ send_request.set_message("Hello");
+ std::unique_ptr<ClientAsyncResponseReader<EchoResponse> > response_reader(
+ stub_->AsyncEcho(&cli_ctx, send_request, cq_.get()));
+
+ srv_ctx.AsyncNotifyWhenDone(tag(5));
+ service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, cq_.get(),
+ cq_.get(), tag(2));
+
+ Verifier().Expect(2, true).Verify(cq_.get());
+ EXPECT_EQ(send_request.message(), recv_request.message());
+
+ send_response.set_message(recv_request.message());
+ response_writer.Finish(send_response, Status::OK, tag(3));
+ Verifier().Expect(3, true).Verify(cq_.get());
+ Verifier().Expect(5, true).Verify(cq_.get());
+ EXPECT_FALSE(srv_ctx.IsCancelled());
+
+ response_reader->Finish(&recv_response, &recv_status, tag(4));
+ Verifier().Expect(4, true).Verify(cq_.get());
+
+ EXPECT_EQ(send_response.message(), recv_response.message());
+ EXPECT_TRUE(recv_status.ok());
+}
+
} // namespace
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 20e4c4ed55..5f0749daa5 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -35,17 +35,17 @@
#include <thread>
#include "src/core/security/credentials.h"
+#include "test/core/end2end/data/ssl_test_data.h"
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
#include "test/cpp/util/echo_duplicate.grpc.pb.h"
#include "test/cpp/util/echo.grpc.pb.h"
-#include "test/cpp/util/fake_credentials.h"
#include <grpc++/channel_arguments.h>
#include <grpc++/channel_interface.h>
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -83,19 +83,43 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
}
}
-template <typename T>
-void CheckAuthContext(T* context) {
+void CheckServerAuthContext(const ServerContext* context) {
std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
- std::vector<grpc::string> fake =
+ std::vector<grpc::string> ssl =
auth_ctx->FindPropertyValues("transport_security_type");
- EXPECT_EQ(1u, fake.size());
- EXPECT_EQ("fake", fake[0]);
+ EXPECT_EQ(1u, ssl.size());
+ EXPECT_EQ("ssl", ssl[0]);
EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
}
+bool CheckIsLocalhost(const grpc::string& addr) {
+ const grpc::string kIpv6("ipv6:[::1]:");
+ const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
+ const grpc::string kIpv4("ipv4:127.0.0.1:");
+ return addr.substr(0, kIpv4.size()) == kIpv4 ||
+ addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 ||
+ addr.substr(0, kIpv6.size()) == kIpv6;
+}
+
} // namespace
+class Proxy : public ::grpc::cpp::test::util::TestService::Service {
+ public:
+ Proxy(std::shared_ptr<ChannelInterface> channel)
+ : stub_(grpc::cpp::test::util::TestService::NewStub(channel)) {}
+
+ Status Echo(ServerContext* server_context, const EchoRequest* request,
+ EchoResponse* response) GRPC_OVERRIDE {
+ std::unique_ptr<ClientContext> client_context =
+ ClientContext::FromServerContext(*server_context);
+ return stub_->Echo(client_context.get(), *request, response);
+ }
+
+ private:
+ std::unique_ptr<::grpc::cpp::test::util::TestService::Stub> stub_;
+};
+
class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
public:
TestServiceImpl() : signal_client_(false), host_() {}
@@ -142,7 +166,15 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
}
}
if (request->has_param() && request->param().check_auth_context()) {
- CheckAuthContext(context);
+ CheckServerAuthContext(context);
+ }
+ if (request->has_param() &&
+ request->param().response_message_length() > 0) {
+ response->set_message(
+ grpc::string(request->param().response_message_length(), '\0'));
+ }
+ if (request->has_param() && request->param().echo_peer()) {
+ response->mutable_param()->set_peer(context->peer());
}
return Status::OK;
}
@@ -225,20 +257,27 @@ class TestServiceImplDupPkg
}
};
-class End2endTest : public ::testing::Test {
+/* Param is whether or not to use a proxy -- some tests use TEST_F as they don't
+ need this functionality */
+class End2endTest : public ::testing::TestWithParam<bool> {
protected:
End2endTest()
: kMaxMessageSize_(8192), special_service_("special"), thread_pool_(2) {}
void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die();
- server_address_ << "localhost:" << port;
+ server_address_ << "127.0.0.1:" << port;
// Setup server
ServerBuilder builder;
+ SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
+ test_server1_cert};
+ SslServerCredentialsOptions ssl_opts;
+ ssl_opts.pem_root_certs = "";
+ ssl_opts.pem_key_cert_pairs.push_back(pkcp);
builder.AddListeningPort(server_address_.str(),
- FakeTransportSecurityServerCredentials());
+ SslServerCredentials(ssl_opts));
builder.RegisterService(&service_);
- builder.RegisterService("special", &special_service_);
+ builder.RegisterService("foo.test.youtube.com", &special_service_);
builder.SetMaxMessageSize(
kMaxMessageSize_); // For testing max message size.
builder.RegisterService(&dup_pkg_service_);
@@ -246,24 +285,47 @@ class End2endTest : public ::testing::Test {
server_ = builder.BuildAndStart();
}
- void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
+ void TearDown() GRPC_OVERRIDE {
+ server_->Shutdown();
+ if (proxy_server_) proxy_server_->Shutdown();
+ }
- void ResetStub() {
+ void ResetStub(bool use_proxy) {
+ SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
ChannelArguments args;
+ args.SetSslTargetNameOverride("foo.test.google.fr");
args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
- std::shared_ptr<ChannelInterface> channel = CreateChannel(
- server_address_.str(), FakeTransportSecurityCredentials(), args);
- stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
+ channel_ = CreateChannel(server_address_.str(), SslCredentials(ssl_opts),
+ args);
+ if (use_proxy) {
+ proxy_service_.reset(new Proxy(channel_));
+ int port = grpc_pick_unused_port_or_die();
+ std::ostringstream proxyaddr;
+ proxyaddr << "localhost:" << port;
+ ServerBuilder builder;
+ builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials());
+ builder.RegisterService(proxy_service_.get());
+ builder.SetThreadPool(&thread_pool_);
+ proxy_server_ = builder.BuildAndStart();
+
+ channel_ = CreateChannel(proxyaddr.str(), InsecureCredentials(),
+ ChannelArguments());
+ }
+
+ stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel_));
}
+ std::shared_ptr<ChannelInterface> channel_;
std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
std::unique_ptr<Server> server_;
+ std::unique_ptr<Server> proxy_server_;
+ std::unique_ptr<Proxy> proxy_service_;
std::ostringstream server_address_;
const int kMaxMessageSize_;
TestServiceImpl service_;
TestServiceImpl special_service_;
TestServiceImplDupPkg dup_pkg_service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
@@ -282,28 +344,28 @@ static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
}
TEST_F(End2endTest, SimpleRpcWithHost) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
ClientContext context;
- context.set_authority("special");
+ context.set_authority("foo.test.youtube.com");
Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(response.has_param());
- EXPECT_EQ(response.param().host(), "special");
+ EXPECT_EQ("special", response.param().host());
EXPECT_TRUE(s.ok());
}
-TEST_F(End2endTest, SimpleRpc) {
- ResetStub();
+TEST_P(End2endTest, SimpleRpc) {
+ ResetStub(GetParam());
SendRpc(stub_.get(), 1);
}
-TEST_F(End2endTest, MultipleRpcs) {
- ResetStub();
+TEST_P(End2endTest, MultipleRpcs) {
+ ResetStub(GetParam());
std::vector<std::thread*> threads;
for (int i = 0; i < 10; ++i) {
threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
@@ -315,8 +377,8 @@ TEST_F(End2endTest, MultipleRpcs) {
}
// Set a 10us deadline and make sure proper error is returned.
-TEST_F(End2endTest, RpcDeadlineExpires) {
- ResetStub();
+TEST_P(End2endTest, RpcDeadlineExpires) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -330,8 +392,8 @@ TEST_F(End2endTest, RpcDeadlineExpires) {
}
// Set a long but finite deadline.
-TEST_F(End2endTest, RpcLongDeadline) {
- ResetStub();
+TEST_P(End2endTest, RpcLongDeadline) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -346,8 +408,8 @@ TEST_F(End2endTest, RpcLongDeadline) {
}
// Ask server to echo back the deadline it sees.
-TEST_F(End2endTest, EchoDeadline) {
- ResetStub();
+TEST_P(End2endTest, EchoDeadline) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -368,8 +430,8 @@ TEST_F(End2endTest, EchoDeadline) {
}
// Ask server to echo back the deadline it sees. The rpc has no deadline.
-TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
- ResetStub();
+TEST_P(End2endTest, EchoDeadlineForNoDeadlineRpc) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -383,8 +445,8 @@ TEST_F(End2endTest, EchoDeadlineForNoDeadlineRpc) {
gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
}
-TEST_F(End2endTest, UnimplementedRpc) {
- ResetStub();
+TEST_P(End2endTest, UnimplementedRpc) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -398,7 +460,7 @@ TEST_F(End2endTest, UnimplementedRpc) {
}
TEST_F(End2endTest, RequestStreamOneRequest) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -413,7 +475,7 @@ TEST_F(End2endTest, RequestStreamOneRequest) {
}
TEST_F(End2endTest, RequestStreamTwoRequests) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -429,7 +491,7 @@ TEST_F(End2endTest, RequestStreamTwoRequests) {
}
TEST_F(End2endTest, ResponseStream) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -449,7 +511,7 @@ TEST_F(End2endTest, ResponseStream) {
}
TEST_F(End2endTest, BidiStream) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -482,24 +544,19 @@ TEST_F(End2endTest, BidiStream) {
// Talk to the two services with the same name but different package names.
// The two stubs are created on the same channel.
TEST_F(End2endTest, DiffPackageServices) {
- std::shared_ptr<ChannelInterface> channel =
- CreateChannel(server_address_.str(), FakeTransportSecurityCredentials(),
- ChannelArguments());
-
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
- std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
- grpc::cpp::test::util::TestService::NewStub(channel));
ClientContext context;
- Status s = stub->Echo(&context, request, &response);
+ Status s = stub_->Echo(&context, request, &response);
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.ok());
std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
dup_pkg_stub(
- grpc::cpp::test::util::duplicate::TestService::NewStub(channel));
+ grpc::cpp::test::util::duplicate::TestService::NewStub(channel_));
ClientContext context2;
s = dup_pkg_stub->Echo(&context2, request, &response);
EXPECT_EQ("no package", response.message());
@@ -509,7 +566,7 @@ TEST_F(End2endTest, DiffPackageServices) {
// rpc and stream should fail on bad credentials.
TEST_F(End2endTest, BadCredentials) {
std::shared_ptr<Credentials> bad_creds = ServiceAccountCredentials("", "", 1);
- EXPECT_EQ(static_cast<Credentials *>(nullptr), bad_creds.get());
+ EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
std::shared_ptr<ChannelInterface> channel =
CreateChannel(server_address_.str(), bad_creds, ChannelArguments());
std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
@@ -542,8 +599,8 @@ void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
}
// Client cancels rpc after 10ms
-TEST_F(End2endTest, ClientCancelsRpc) {
- ResetStub();
+TEST_P(End2endTest, ClientCancelsRpc) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -559,8 +616,8 @@ TEST_F(End2endTest, ClientCancelsRpc) {
}
// Server cancels rpc after 1ms
-TEST_F(End2endTest, ServerCancelsRpc) {
- ResetStub();
+TEST_P(End2endTest, ServerCancelsRpc) {
+ ResetStub(GetParam());
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -574,7 +631,7 @@ TEST_F(End2endTest, ServerCancelsRpc) {
// Client cancels request stream after sending two messages
TEST_F(End2endTest, ClientCancelsRequestStream) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -594,7 +651,7 @@ TEST_F(End2endTest, ClientCancelsRequestStream) {
// Client cancels server stream after sending some messages
TEST_F(End2endTest, ClientCancelsResponseStream) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -626,7 +683,7 @@ TEST_F(End2endTest, ClientCancelsResponseStream) {
// Client cancels bidi stream after sending some messages
TEST_F(End2endTest, ClientCancelsBidi) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -658,7 +715,7 @@ TEST_F(End2endTest, ClientCancelsBidi) {
}
TEST_F(End2endTest, RpcMaxMessageSize) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
request.set_message(string(kMaxMessageSize_ * 2, 'a'));
@@ -683,7 +740,7 @@ bool MetadataContains(const std::multimap<grpc::string, grpc::string>& metadata,
}
TEST_F(End2endTest, SetPerCallCredentials) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -705,7 +762,7 @@ TEST_F(End2endTest, SetPerCallCredentials) {
}
TEST_F(End2endTest, InsecurePerCallCredentials) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -720,7 +777,7 @@ TEST_F(End2endTest, InsecurePerCallCredentials) {
}
TEST_F(End2endTest, OverridePerCallCredentials) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -753,7 +810,7 @@ TEST_F(End2endTest, OverridePerCallCredentials) {
// Client sends 20 requests and the server returns CANCELLED status after
// reading 10 requests.
TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -772,7 +829,7 @@ TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) {
}
TEST_F(End2endTest, ClientAuthContext) {
- ResetStub();
+ ResetStub(false);
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -783,9 +840,98 @@ TEST_F(End2endTest, ClientAuthContext) {
EXPECT_EQ(response.message(), request.message());
EXPECT_TRUE(s.ok());
- CheckAuthContext(&context);
+ std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
+ std::vector<grpc::string> ssl =
+ auth_ctx->FindPropertyValues("transport_security_type");
+ EXPECT_EQ(1u, ssl.size());
+ EXPECT_EQ("ssl", ssl[0]);
+ EXPECT_EQ("x509_subject_alternative_name",
+ auth_ctx->GetPeerIdentityPropertyName());
+ EXPECT_EQ(3u, auth_ctx->GetPeerIdentity().size());
+ EXPECT_EQ("*.test.google.fr", auth_ctx->GetPeerIdentity()[0]);
+ EXPECT_EQ("waterzooi.test.google.be", auth_ctx->GetPeerIdentity()[1]);
+ EXPECT_EQ("*.test.youtube.com", auth_ctx->GetPeerIdentity()[2]);
}
+// Make the response larger than the flow control window.
+TEST_P(End2endTest, HugeResponse) {
+ ResetStub(GetParam());
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("huge response");
+ const size_t kResponseSize = 1024 * (1024 + 10);
+ request.mutable_param()->set_response_message_length(kResponseSize);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(kResponseSize, response.message().size());
+ EXPECT_TRUE(s.ok());
+}
+
+namespace {
+void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
+ gpr_event *ev) {
+ EchoResponse resp;
+ gpr_event_set(ev, (void*)1);
+ while (stream->Read(&resp)) {
+ gpr_log(GPR_INFO, "Read message");
+ }
+}
+} // namespace
+
+// Run a Read and a WritesDone simultaneously.
+TEST_F(End2endTest, SimultaneousReadWritesDone) {
+ ResetStub(false);
+ ClientContext context;
+ gpr_event ev;
+ gpr_event_init(&ev);
+ auto stream = stub_->BidiStream(&context);
+ std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
+ gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
+ stream->WritesDone();
+ Status s = stream->Finish();
+ EXPECT_TRUE(s.ok());
+ reader_thread.join();
+}
+
+TEST_P(End2endTest, Peer) {
+ ResetStub(GetParam());
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("hello");
+ request.mutable_param()->set_echo_peer(true);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+ EXPECT_TRUE(CheckIsLocalhost(response.param().peer()));
+ EXPECT_TRUE(CheckIsLocalhost(context.peer()));
+}
+
+TEST_F(End2endTest, ChannelState) {
+ ResetStub(false);
+ // Start IDLE
+ EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
+
+ // Did not ask to connect, no state change.
+ CompletionQueue cq;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::milliseconds(10);
+ channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL);
+ void* tag;
+ bool ok = true;
+ cq.Next(&tag, &ok);
+ EXPECT_FALSE(ok);
+
+ EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true));
+ EXPECT_TRUE(channel_->WaitForStateChange(
+ GRPC_CHANNEL_IDLE, gpr_inf_future(GPR_CLOCK_REALTIME)));
+ EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel_->GetState(false));
+}
+
+INSTANTIATE_TEST_CASE_P(End2end, End2endTest, ::testing::Values(false, true));
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/end2end/generic_end2end_test.cc b/test/cpp/end2end/generic_end2end_test.cc
index 4951c82b9a..b53c32144b 100644
--- a/test/cpp/end2end/generic_end2end_test.cc
+++ b/test/cpp/end2end/generic_end2end_test.cc
@@ -100,11 +100,11 @@ std::unique_ptr<ByteBuffer> SerializeToByteBuffer(
class GenericEnd2endTest : public ::testing::Test {
protected:
- GenericEnd2endTest() : generic_service_("*") {}
+ GenericEnd2endTest() : generic_service_("*"), server_host_("localhost") {}
void SetUp() GRPC_OVERRIDE {
int port = grpc_pick_unused_port_or_die();
- server_address_ << "localhost:" << port;
+ server_address_ << server_host_ << ":" << port;
// Setup server
ServerBuilder builder;
builder.AddListeningPort(server_address_.str(), InsecureServerCredentials());
@@ -165,7 +165,7 @@ class GenericEnd2endTest : public ::testing::Test {
srv_cq_.get(), tag(4));
verify_ok(srv_cq_.get(), 4, true);
- EXPECT_EQ(server_address_.str(), srv_ctx.host());
+ EXPECT_EQ(server_host_, srv_ctx.host());
EXPECT_EQ(kMethodName, srv_ctx.method());
ByteBuffer recv_buffer;
stream.Read(&recv_buffer, tag(5));
@@ -200,6 +200,7 @@ class GenericEnd2endTest : public ::testing::Test {
std::unique_ptr<grpc::GenericStub> generic_stub_;
std::unique_ptr<Server> server_;
AsyncGenericService generic_service_;
+ const grpc::string server_host_;
std::ostringstream server_address_;
};
@@ -237,7 +238,7 @@ TEST_F(GenericEnd2endTest, SimpleBidiStreaming) {
srv_cq_.get(), tag(2));
verify_ok(srv_cq_.get(), 2, true);
- EXPECT_EQ(server_address_.str(), srv_ctx.host());
+ EXPECT_EQ(server_host_, srv_ctx.host());
EXPECT_EQ(kMethodName, srv_ctx.method());
std::unique_ptr<ByteBuffer> send_buffer =
diff --git a/test/cpp/end2end/mock_test.cc b/test/cpp/end2end/mock_test.cc
index 74b40d54d8..32130e24e9 100644
--- a/test/cpp/end2end/mock_test.cc
+++ b/test/cpp/end2end/mock_test.cc
@@ -42,7 +42,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -260,7 +260,7 @@ class MockTest : public ::testing::Test {
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
// Do one real rpc and one mocked one
diff --git a/test/cpp/end2end/thread_stress_test.cc b/test/cpp/end2end/thread_stress_test.cc
index e47139641b..ff9c945c7c 100644
--- a/test/cpp/end2end/thread_stress_test.cc
+++ b/test/cpp/end2end/thread_stress_test.cc
@@ -43,7 +43,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -208,7 +208,7 @@ class End2endTest : public ::testing::Test {
const int kMaxMessageSize_;
TestServiceImpl service_;
TestServiceImplDupPkg dup_pkg_service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc
index d0393fafb2..ebc5cfc85a 100644
--- a/test/cpp/interop/client.cc
+++ b/test/cpp/interop/client.cc
@@ -70,6 +70,7 @@ DEFINE_string(test_case, "large_unary",
"jwt_token_creds: large_unary with JWT token auth; "
"oauth2_auth_token: raw oauth2 access token auth; "
"per_rpc_creds: raw oauth2 access token on a single rpc; "
+ "status_code_and_message: verify status code & message; "
"all : all of above.");
DEFINE_string(default_service_account, "",
"Email of GCE default service account");
@@ -82,7 +83,7 @@ using grpc::testing::GetServiceAccountJsonKey;
int main(int argc, char** argv) {
grpc::testing::InitTest(&argc, &argv, true);
-
+ gpr_log(GPR_INFO, "Testing these cases: %s", FLAGS_test_case.c_str());
int ret = 0;
grpc::testing::InteropClient client(
CreateChannelForTestCase(FLAGS_test_case));
@@ -121,6 +122,8 @@ int main(int argc, char** argv) {
} else if (FLAGS_test_case == "per_rpc_creds") {
grpc::string json_key = GetServiceAccountJsonKey();
client.DoPerRpcCreds(json_key, FLAGS_oauth_scope);
+ } else if (FLAGS_test_case == "status_code_and_message") {
+ client.DoStatusWithMessage();
} else if (FLAGS_test_case == "all") {
client.DoEmpty();
client.DoLargeUnary();
@@ -131,6 +134,7 @@ int main(int argc, char** argv) {
client.DoCancelAfterBegin();
client.DoCancelAfterFirstResponse();
client.DoTimeoutOnSleepingServer();
+ client.DoStatusWithMessage();
// service_account_creds and jwt_token_creds can only run with ssl.
if (FLAGS_enable_ssl) {
grpc::string json_key = GetServiceAccountJsonKey();
diff --git a/test/cpp/interop/client_helper.cc b/test/cpp/interop/client_helper.cc
index 48b1b2e864..73d82f7b88 100644
--- a/test/cpp/interop/client_helper.cc
+++ b/test/cpp/interop/client_helper.cc
@@ -123,7 +123,8 @@ std::shared_ptr<ChannelInterface> CreateChannelForTestCase(
GPR_ASSERT(FLAGS_enable_ssl);
grpc::string json_key = GetServiceAccountJsonKey();
std::chrono::seconds token_lifetime = std::chrono::hours(1);
- creds = JWTCredentials(json_key, token_lifetime.count());
+ creds =
+ ServiceAccountJWTAccessCredentials(json_key, token_lifetime.count());
return CreateTestChannel(host_port, FLAGS_server_host_override,
FLAGS_enable_ssl, FLAGS_use_prod_roots, creds);
} else if (test_case == "oauth2_auth_token") {
diff --git a/test/cpp/interop/interop_client.cc b/test/cpp/interop/interop_client.cc
index e5c0e4631f..dfb90fadc2 100644
--- a/test/cpp/interop/interop_client.cc
+++ b/test/cpp/interop/interop_client.cc
@@ -423,5 +423,24 @@ void InteropClient::DoTimeoutOnSleepingServer() {
gpr_log(GPR_INFO, "Pingpong streaming timeout done.");
}
+void InteropClient::DoStatusWithMessage() {
+ gpr_log(GPR_INFO, "Sending RPC with a request for status code 2 and message");
+ std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
+
+ ClientContext context;
+ SimpleRequest request;
+ SimpleResponse response;
+ EchoStatus *requested_status = request.mutable_response_status();
+ requested_status->set_code(grpc::StatusCode::UNKNOWN);
+ grpc::string test_msg = "This is a test message";
+ requested_status->set_message(test_msg);
+
+ Status s = stub->UnaryCall(&context, request, &response);
+
+ GPR_ASSERT(s.error_code() == grpc::StatusCode::UNKNOWN);
+ GPR_ASSERT(s.error_message() == test_msg);
+ gpr_log(GPR_INFO, "Done testing Status and Message");
+}
+
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/interop/interop_client.h b/test/cpp/interop/interop_client.h
index bf8188325e..6e26c49e5d 100644
--- a/test/cpp/interop/interop_client.h
+++ b/test/cpp/interop/interop_client.h
@@ -60,6 +60,7 @@ class InteropClient {
void DoCancelAfterBegin();
void DoCancelAfterFirstResponse();
void DoTimeoutOnSleepingServer();
+ void DoStatusWithMessage();
// Auth tests.
// username is a string containing the user email
void DoJwtTokenCreds(const grpc::string& username);
diff --git a/test/cpp/interop/reconnect_interop_client.cc b/test/cpp/interop/reconnect_interop_client.cc
new file mode 100644
index 0000000000..65f098050e
--- /dev/null
+++ b/test/cpp/interop/reconnect_interop_client.cc
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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 <sstream>
+
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <gflags/gflags.h>
+#include <grpc++/channel_interface.h>
+#include <grpc++/client_context.h>
+#include <grpc++/status.h>
+#include "test/cpp/util/create_test_channel.h"
+#include "test/cpp/util/test_config.h"
+#include "test/proto/test.grpc.pb.h"
+#include "test/proto/empty.grpc.pb.h"
+#include "test/proto/messages.grpc.pb.h"
+
+DEFINE_int32(server_control_port, 0, "Server port for control rpcs.");
+DEFINE_int32(server_retry_port, 0, "Server port for testing reconnection.");
+DEFINE_string(server_host, "127.0.0.1", "Server host to connect to");
+
+using grpc::ChannelInterface;
+using grpc::ClientContext;
+using grpc::CreateTestChannel;
+using grpc::Status;
+using grpc::testing::Empty;
+using grpc::testing::ReconnectInfo;
+using grpc::testing::ReconnectService;
+
+int main(int argc, char** argv) {
+ grpc::testing::InitTest(&argc, &argv, true);
+ GPR_ASSERT(FLAGS_server_control_port);
+ GPR_ASSERT(FLAGS_server_retry_port);
+
+ std::ostringstream server_address;
+ server_address << FLAGS_server_host << ':' << FLAGS_server_control_port;
+ std::unique_ptr<ReconnectService::Stub> control_stub(
+ ReconnectService::NewStub(
+ CreateTestChannel(server_address.str(), false)));
+ ClientContext start_context;
+ Empty empty_request;
+ Empty empty_response;
+ Status start_status =
+ control_stub->Start(&start_context, empty_request, &empty_response);
+ GPR_ASSERT(start_status.ok());
+
+ gpr_log(GPR_INFO, "Starting connections with retries.");
+ server_address.str("");
+ server_address << FLAGS_server_host << ':' << FLAGS_server_retry_port;
+ std::shared_ptr<ChannelInterface> retry_channel =
+ CreateTestChannel(server_address.str(), true);
+ // About 13 retries.
+ const int kDeadlineSeconds = 540;
+ // Use any rpc to test retry.
+ std::unique_ptr<ReconnectService::Stub> retry_stub(
+ ReconnectService::NewStub(retry_channel));
+ ClientContext retry_context;
+ retry_context.set_deadline(std::chrono::system_clock::now() +
+ std::chrono::seconds(kDeadlineSeconds));
+ Status retry_status =
+ retry_stub->Start(&retry_context, empty_request, &empty_response);
+ GPR_ASSERT(retry_status.error_code() == grpc::StatusCode::DEADLINE_EXCEEDED);
+ gpr_log(GPR_INFO, "Done retrying, getting final data from server");
+
+ ClientContext stop_context;
+ ReconnectInfo response;
+ Status stop_status =
+ control_stub->Stop(&stop_context, empty_request, &response);
+ GPR_ASSERT(stop_status.ok());
+ GPR_ASSERT(response.passed() == true);
+ return 0;
+}
diff --git a/test/cpp/interop/reconnect_interop_server.cc b/test/cpp/interop/reconnect_interop_server.cc
new file mode 100644
index 0000000000..8bc51aa52e
--- /dev/null
+++ b/test/cpp/interop/reconnect_interop_server.cc
@@ -0,0 +1,190 @@
+/*
+ *
+ * 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 <condition_variable>
+#include <memory>
+#include <mutex>
+#include <sstream>
+
+#include <signal.h>
+#include <unistd.h>
+
+#include <gflags/gflags.h>
+#include <grpc/grpc.h>
+#include <grpc/support/log.h>
+#include <grpc++/config.h>
+#include <grpc++/server.h>
+#include <grpc++/server_builder.h>
+#include <grpc++/server_context.h>
+#include <grpc++/server_credentials.h>
+#include <grpc++/status.h>
+#include "test/core/util/reconnect_server.h"
+#include "test/cpp/util/test_config.h"
+#include "test/proto/test.grpc.pb.h"
+#include "test/proto/empty.grpc.pb.h"
+#include "test/proto/messages.grpc.pb.h"
+
+DEFINE_int32(control_port, 0, "Server port for controlling the server.");
+DEFINE_int32(retry_port, 0,
+ "Server port for raw tcp connections. All incoming "
+ "connections will be closed immediately.");
+
+using grpc::Server;
+using grpc::ServerBuilder;
+using grpc::ServerContext;
+using grpc::ServerCredentials;
+using grpc::ServerReader;
+using grpc::ServerReaderWriter;
+using grpc::ServerWriter;
+using grpc::SslServerCredentialsOptions;
+using grpc::Status;
+using grpc::testing::Empty;
+using grpc::testing::ReconnectService;
+using grpc::testing::ReconnectInfo;
+
+static bool got_sigint = false;
+
+class ReconnectServiceImpl : public ReconnectService::Service {
+ public:
+ explicit ReconnectServiceImpl(int retry_port)
+ : retry_port_(retry_port), serving_(false), shutdown_(false) {
+ reconnect_server_init(&tcp_server_);
+ }
+
+ ~ReconnectServiceImpl() {
+ if (tcp_server_.tcp_server) {
+ reconnect_server_destroy(&tcp_server_);
+ }
+ }
+
+ void Poll(int seconds) { reconnect_server_poll(&tcp_server_, seconds); }
+
+ Status Start(ServerContext* context, const Empty* request, Empty* response) {
+ std::unique_lock<std::mutex> lock(mu_);
+ while (serving_ && !shutdown_) {
+ cv_.wait(lock);
+ }
+ if (shutdown_) {
+ return Status(grpc::StatusCode::UNAVAILABLE, "shutting down");
+ }
+ serving_ = true;
+ lock.unlock();
+
+ if (!tcp_server_.tcp_server) {
+ reconnect_server_start(&tcp_server_, retry_port_);
+ } else {
+ reconnect_server_clear_timestamps(&tcp_server_);
+ }
+ return Status::OK;
+ }
+
+ Status Stop(ServerContext* context, const Empty* request,
+ ReconnectInfo* response) {
+ // extract timestamps and set response
+ Verify(response);
+ reconnect_server_clear_timestamps(&tcp_server_);
+ std::lock_guard<std::mutex> lock(mu_);
+ serving_ = false;
+ cv_.notify_one();
+ return Status::OK;
+ }
+
+ void Verify(ReconnectInfo* response) {
+ double expected_backoff = 1000.0;
+ const double kTransmissionDelay = 100.0;
+ const double kBackoffMultiplier = 1.6;
+ const double kJitterFactor = 0.2;
+ const int kMaxBackoffMs = 120 * 1000;
+ bool passed = true;
+ for (timestamp_list* cur = tcp_server_.head; cur && cur->next;
+ cur = cur->next) {
+ double backoff = gpr_time_to_millis(
+ gpr_time_sub(cur->next->timestamp, cur->timestamp));
+ double min_backoff = expected_backoff * (1 - kJitterFactor);
+ double max_backoff = expected_backoff * (1 + kJitterFactor);
+ if (backoff < min_backoff - kTransmissionDelay ||
+ backoff > max_backoff + kTransmissionDelay) {
+ passed = false;
+ }
+ response->add_backoff_ms(static_cast<gpr_int32>(backoff));
+ expected_backoff *= kBackoffMultiplier;
+ expected_backoff =
+ expected_backoff > kMaxBackoffMs ? kMaxBackoffMs : expected_backoff;
+ }
+ response->set_passed(passed);
+ }
+
+ void Shutdown() {
+ std::lock_guard<std::mutex> lock(mu_);
+ shutdown_ = true;
+ cv_.notify_all();
+ }
+
+ private:
+ int retry_port_;
+ reconnect_server tcp_server_;
+ bool serving_;
+ bool shutdown_;
+ std::mutex mu_;
+ std::condition_variable cv_;
+};
+
+void RunServer() {
+ std::ostringstream server_address;
+ server_address << "0.0.0.0:" << FLAGS_control_port;
+ ReconnectServiceImpl service(FLAGS_retry_port);
+
+ ServerBuilder builder;
+ builder.RegisterService(&service);
+ builder.AddListeningPort(server_address.str(),
+ grpc::InsecureServerCredentials());
+ std::unique_ptr<Server> server(builder.BuildAndStart());
+ gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str());
+ while (!got_sigint) {
+ service.Poll(5);
+ }
+ service.Shutdown();
+}
+
+static void sigint_handler(int x) { got_sigint = true; }
+
+int main(int argc, char** argv) {
+ grpc::testing::InitTest(&argc, &argv, true);
+ signal(SIGINT, sigint_handler);
+
+ GPR_ASSERT(FLAGS_control_port != 0);
+ GPR_ASSERT(FLAGS_retry_port != 0);
+ RunServer();
+
+ return 0;
+}
diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc
index db87872cf5..05a10de51e 100644
--- a/test/cpp/interop/server.cc
+++ b/test/cpp/interop/server.cc
@@ -105,6 +105,13 @@ class TestServiceImpl : public TestService::Service {
return Status(grpc::StatusCode::INTERNAL, "Error creating payload.");
}
}
+
+ if (request->has_response_status()) {
+ return Status(static_cast<grpc::StatusCode>
+ (request->response_status().code()),
+ request->response_status().message());
+ }
+
return Status::OK;
}
diff --git a/test/cpp/qps/qps_test.cc b/test/cpp/qps/qps_test.cc
index 7b93443f7c..ba980a6664 100644
--- a/test/cpp/qps/qps_test.cc
+++ b/test/cpp/qps/qps_test.cc
@@ -53,8 +53,8 @@ static void RunQPS() {
ClientConfig client_config;
client_config.set_client_type(ASYNC_CLIENT);
client_config.set_enable_ssl(false);
- client_config.set_outstanding_rpcs_per_channel(10);
- client_config.set_client_channels(800);
+ client_config.set_outstanding_rpcs_per_channel(1000);
+ client_config.set_client_channels(8);
client_config.set_payload_size(1);
client_config.set_async_client_threads(8);
client_config.set_rpc_type(UNARY);
diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc
index 846f8f31b0..33b6fa55c3 100644
--- a/test/cpp/qps/server_async.cc
+++ b/test/cpp/qps/server_async.cc
@@ -45,7 +45,6 @@
#include <grpc/support/host_port.h>
#include <grpc++/async_unary_call.h>
#include <grpc++/config.h>
-#include <grpc++/fixed_size_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc
index d90ff2212b..4c3c9cb497 100644
--- a/test/cpp/qps/server_sync.cc
+++ b/test/cpp/qps/server_sync.cc
@@ -40,6 +40,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/host_port.h>
#include <grpc++/config.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/fixed_size_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
@@ -92,7 +93,13 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service {
class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
public:
SynchronousServer(const ServerConfig& config, int port)
- : thread_pool_(config.threads()), impl_(MakeImpl(port)) {}
+ : thread_pool_(), impl_(MakeImpl(port)) {
+ if (config.threads() > 0) {
+ thread_pool_.reset(new FixedSizeThreadPool(config.threads()));
+ } else {
+ thread_pool_.reset(new DynamicThreadPool(-config.threads()));
+ }
+ }
private:
std::unique_ptr<grpc::Server> MakeImpl(int port) {
@@ -105,13 +112,13 @@ class SynchronousServer GRPC_FINAL : public grpc::testing::Server {
builder.RegisterService(&service_);
- builder.SetThreadPool(&thread_pool_);
+ builder.SetThreadPool(thread_pool_.get());
return builder.BuildAndStart();
}
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ std::unique_ptr<ThreadPoolInterface> thread_pool_;
std::unique_ptr<grpc::Server> impl_;
};
diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc
index 07289f699b..c1ba23decd 100644
--- a/test/cpp/qps/timer.cc
+++ b/test/cpp/qps/timer.cc
@@ -52,7 +52,7 @@ static double time_double(struct timeval* tv) {
Timer::Result Timer::Sample() {
struct rusage usage;
struct timeval tv;
- gettimeofday(&tv, nullptr);
+ gettimeofday(&tv, NULL);
getrusage(RUSAGE_SELF, &usage);
Result r;
diff --git a/test/cpp/util/fake_credentials.cc b/test/cpp/server/dynamic_thread_pool_test.cc
index f5b83b8159..63b603b8f7 100644
--- a/test/cpp/util/fake_credentials.cc
+++ b/test/cpp/server/dynamic_thread_pool_test.cc
@@ -31,28 +31,47 @@
*
*/
-#include <grpc/grpc_security.h>
-#include <grpc++/channel_arguments.h>
-#include <grpc++/credentials.h>
-#include <grpc++/server_credentials.h>
-#include "src/cpp/client/channel.h"
-#include "src/cpp/client/secure_credentials.h"
-#include "src/cpp/server/secure_server_credentials.h"
+#include <condition_variable>
+#include <functional>
+#include <mutex>
+
+#include <grpc++/dynamic_thread_pool.h>
+#include <gtest/gtest.h>
namespace grpc {
-namespace testing {
-std::shared_ptr<Credentials> FakeTransportSecurityCredentials() {
- grpc_credentials* c_creds = grpc_fake_transport_security_credentials_create();
- return std::shared_ptr<Credentials>(new SecureCredentials(c_creds));
+class DynamicThreadPoolTest : public ::testing::Test {
+ public:
+ DynamicThreadPoolTest() : thread_pool_(0) {}
+
+ protected:
+ DynamicThreadPool thread_pool_;
+};
+
+void Callback(std::mutex* mu, std::condition_variable* cv, bool* done) {
+ std::unique_lock<std::mutex> lock(*mu);
+ *done = true;
+ cv->notify_all();
}
-std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials() {
- grpc_server_credentials* c_creds =
- grpc_fake_transport_security_server_credentials_create();
- return std::shared_ptr<ServerCredentials>(
- new SecureServerCredentials(c_creds));
+TEST_F(DynamicThreadPoolTest, Add) {
+ std::mutex mu;
+ std::condition_variable cv;
+ bool done = false;
+ std::function<void()> callback = std::bind(Callback, &mu, &cv, &done);
+ thread_pool_.Add(callback);
+
+ // Wait for the callback to finish.
+ std::unique_lock<std::mutex> lock(mu);
+ while (!done) {
+ cv.wait(lock);
+ }
}
-} // namespace testing
} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ int result = RUN_ALL_TESTS();
+ return result;
+}
diff --git a/test/cpp/util/cli_call_test.cc b/test/cpp/util/cli_call_test.cc
index 00bb821ae6..848a3aee57 100644
--- a/test/cpp/util/cli_call_test.cc
+++ b/test/cpp/util/cli_call_test.cc
@@ -39,7 +39,7 @@
#include <grpc++/client_context.h>
#include <grpc++/create_channel.h>
#include <grpc++/credentials.h>
-#include <grpc++/fixed_size_thread_pool.h>
+#include <grpc++/dynamic_thread_pool.h>
#include <grpc++/server.h>
#include <grpc++/server_builder.h>
#include <grpc++/server_context.h>
@@ -102,7 +102,7 @@ class CliCallTest : public ::testing::Test {
std::unique_ptr<Server> server_;
std::ostringstream server_address_;
TestServiceImpl service_;
- FixedSizeThreadPool thread_pool_;
+ DynamicThreadPool thread_pool_;
};
// Send a rpc with a normal stub and then a CliCall. Verify they match.
diff --git a/test/cpp/util/fake_credentials.h b/test/cpp/util/fake_credentials.h
deleted file mode 100644
index e1ba7bb9e4..0000000000
--- a/test/cpp/util/fake_credentials.h
+++ /dev/null
@@ -1,51 +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.
- *
- */
-
-#ifndef GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
-#define GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
-
-#include <memory>
-
-namespace grpc {
-class Credentials;
-class ServerCredentials;
-
-namespace testing {
-
-std::shared_ptr<Credentials> FakeTransportSecurityCredentials();
-std::shared_ptr<ServerCredentials> FakeTransportSecurityServerCredentials();
-
-} // namespace testing
-} // namespace grpc
-
-#endif // GRPC_TEST_CPP_UTIL_FAKE_CREDENTIALS_H
diff --git a/test/cpp/util/messages.proto b/test/cpp/util/messages.proto
index 3708972b90..24e199b809 100644
--- a/test/cpp/util/messages.proto
+++ b/test/cpp/util/messages.proto
@@ -38,6 +38,8 @@ message RequestParams {
optional int32 server_cancel_after_us = 3;
optional bool echo_metadata = 4;
optional bool check_auth_context = 5;
+ optional int32 response_message_length = 6;
+ optional bool echo_peer = 7;
}
message EchoRequest {
@@ -48,6 +50,7 @@ message EchoRequest {
message ResponseParams {
optional int64 request_deadline = 1;
optional string host = 2;
+ optional string peer = 3;
}
message EchoResponse {