diff options
author | David Garcia Quintas <dgq@google.com> | 2015-08-09 08:52:47 -0700 |
---|---|---|
committer | David Garcia Quintas <dgq@google.com> | 2015-08-09 09:10:56 -0700 |
commit | 10494fcb61d638682fb8e5d28356a1f5125e8d0a (patch) | |
tree | b2ca81762344cd45d5333b732ff8b197e476f958 /test/cpp | |
parent | baa2aa644226b00ad9cb493660356f4473acd212 (diff) | |
parent | 7a75936001478a0f7ea7eaf204c1b19bd55190f9 (diff) |
Merge branch 'master' into compression-accept-encoding
Diffstat (limited to 'test/cpp')
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 { |