aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp/end2end
diff options
context:
space:
mode:
authorGravatar yang-g <yangg@google.com>2015-09-29 12:46:54 -0700
committerGravatar yang-g <yangg@google.com>2015-09-29 12:47:51 -0700
commit88d5d52d73eaf45716ccea4797493db209964e66 (patch)
tree04a6389d3bba85e7f38dc2be2c1ce5eb8c174e8b /test/cpp/end2end
parentdcda6e8052332779eab8f3cbbc504d7965e617ae (diff)
add tls and proxy as dimensions of end2end test
Diffstat (limited to 'test/cpp/end2end')
-rw-r--r--test/cpp/end2end/end2end_test.cc835
1 files changed, 439 insertions, 396 deletions
diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc
index 2659b0e213..448ea253c2 100644
--- a/test/cpp/end2end/end2end_test.cc
+++ b/test/cpp/end2end/end2end_test.cc
@@ -195,8 +195,6 @@ const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll";
const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
-} // namespace
-
class Proxy : public ::grpc::cpp::test::util::TestService::Service {
public:
Proxy(std::shared_ptr<Channel> channel)
@@ -353,14 +351,24 @@ class TestServiceImplDupPkg
}
};
-/* 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> {
+class TestScenario {
+ public:
+ TestScenario(bool proxy, bool tls) : use_proxy(proxy), use_tls(tls) {}
+ void Log() const {
+ gpr_log(GPR_INFO, "Scenario: proxy %d, tls %d", use_proxy, use_tls);
+ }
+ bool use_proxy;
+ bool use_tls;
+};
+
+class End2endTest : public ::testing::TestWithParam<TestScenario> {
protected:
End2endTest()
: is_server_started_(false),
kMaxMessageSize_(8192),
- special_service_("special") {}
+ special_service_("special") {
+ GetParam().Log();
+ }
void TearDown() GRPC_OVERRIDE {
if (is_server_started_) {
@@ -374,13 +382,16 @@ class End2endTest : public ::testing::TestWithParam<bool> {
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);
- auto server_creds = SslServerCredentials(ssl_opts);
- server_creds->SetAuthMetadataProcessor(processor);
+ auto server_creds = InsecureServerCredentials();
+ if (GetParam().use_tls) {
+ 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);
+ server_creds = SslServerCredentials(ssl_opts);
+ server_creds->SetAuthMetadataProcessor(processor);
+ }
builder.AddListeningPort(server_address_.str(), server_creds);
builder.RegisterService(&service_);
builder.RegisterService("foo.test.youtube.com", &special_service_);
@@ -396,17 +407,20 @@ class End2endTest : public ::testing::TestWithParam<bool> {
StartServer(std::shared_ptr<AuthMetadataProcessor>());
}
EXPECT_TRUE(is_server_started_);
- SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
ChannelArguments args;
- args.SetSslTargetNameOverride("foo.test.google.fr");
+ auto channel_creds = InsecureCredentials();
+ if (GetParam().use_tls) {
+ SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
+ args.SetSslTargetNameOverride("foo.test.google.fr");
+ channel_creds = SslCredentials(ssl_opts);
+ }
args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
- channel_ = CreateCustomChannel(server_address_.str(),
- SslCredentials(ssl_opts), args);
+ channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args);
}
- void ResetStub(bool use_proxy) {
+ void ResetStub() {
ResetChannel();
- if (use_proxy) {
+ if (GetParam().use_proxy) {
proxy_service_.reset(new Proxy(channel_));
int port = grpc_pick_unused_port_or_die();
std::ostringstream proxyaddr;
@@ -450,124 +464,8 @@ static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
}
}
-TEST_F(End2endTest, SimpleRpcWithHost) {
- ResetStub(false);
-
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
-
- ClientContext context;
- 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("special", response.param().host());
- EXPECT_TRUE(s.ok());
-}
-
-TEST_P(End2endTest, SimpleRpc) {
- ResetStub(GetParam());
- SendRpc(stub_.get(), 1);
-}
-
-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));
- }
- for (int i = 0; i < 10; ++i) {
- threads[i]->join();
- delete threads[i];
- }
-}
-
-// Set a 10us deadline and make sure proper error is returned.
-TEST_P(End2endTest, RpcDeadlineExpires) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
-
- ClientContext context;
- std::chrono::system_clock::time_point deadline =
- std::chrono::system_clock::now() + std::chrono::microseconds(10);
- context.set_deadline(deadline);
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
-}
-
-// Set a long but finite deadline.
-TEST_P(End2endTest, RpcLongDeadline) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
-
- ClientContext context;
- std::chrono::system_clock::time_point deadline =
- std::chrono::system_clock::now() + std::chrono::hours(1);
- context.set_deadline(deadline);
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(response.message(), request.message());
- EXPECT_TRUE(s.ok());
-}
-
-// Ask server to echo back the deadline it sees.
-TEST_P(End2endTest, EchoDeadline) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
- request.mutable_param()->set_echo_deadline(true);
-
- ClientContext context;
- std::chrono::system_clock::time_point deadline =
- std::chrono::system_clock::now() + std::chrono::seconds(100);
- context.set_deadline(deadline);
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(response.message(), request.message());
- EXPECT_TRUE(s.ok());
- gpr_timespec sent_deadline;
- Timepoint2Timespec(deadline, &sent_deadline);
- // Allow 1 second error.
- EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
- EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
-}
-
-// Ask server to echo back the deadline it sees. The rpc has no deadline.
-TEST_P(End2endTest, EchoDeadlineForNoDeadlineRpc) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
- request.mutable_param()->set_echo_deadline(true);
-
- ClientContext context;
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(response.message(), request.message());
- EXPECT_TRUE(s.ok());
- EXPECT_EQ(response.param().request_deadline(),
- gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
-}
-
-TEST_P(End2endTest, UnimplementedRpc) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
-
- ClientContext context;
- Status s = stub_->Unimplemented(&context, request, &response);
- EXPECT_FALSE(s.ok());
- EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
- EXPECT_EQ(s.error_message(), "");
- EXPECT_EQ(response.message(), "");
-}
-
-TEST_F(End2endTest, RequestStreamOneRequest) {
- ResetStub(false);
+TEST_P(End2endTest, RequestStreamOneRequest) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -581,8 +479,8 @@ TEST_F(End2endTest, RequestStreamOneRequest) {
EXPECT_TRUE(s.ok());
}
-TEST_F(End2endTest, RequestStreamTwoRequests) {
- ResetStub(false);
+TEST_P(End2endTest, RequestStreamTwoRequests) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -597,8 +495,8 @@ TEST_F(End2endTest, RequestStreamTwoRequests) {
EXPECT_TRUE(s.ok());
}
-TEST_F(End2endTest, ResponseStream) {
- ResetStub(false);
+TEST_P(End2endTest, ResponseStream) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -617,8 +515,8 @@ TEST_F(End2endTest, ResponseStream) {
EXPECT_TRUE(s.ok());
}
-TEST_F(End2endTest, BidiStream) {
- ResetStub(false);
+TEST_P(End2endTest, BidiStream) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -650,8 +548,8 @@ 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) {
- ResetStub(false);
+TEST_P(End2endTest, DiffPackageServices) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -670,33 +568,6 @@ TEST_F(End2endTest, DiffPackageServices) {
EXPECT_TRUE(s.ok());
}
-// rpc and stream should fail on bad credentials.
-TEST_F(End2endTest, BadCredentials) {
- std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials("");
- EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
- std::shared_ptr<Channel> channel =
- CreateChannel(server_address_.str(), bad_creds);
- std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
- grpc::cpp::test::util::TestService::NewStub(channel));
- EchoRequest request;
- EchoResponse response;
- ClientContext context;
- request.set_message("Hello");
-
- Status s = stub->Echo(&context, request, &response);
- EXPECT_EQ("", response.message());
- EXPECT_FALSE(s.ok());
- EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
- EXPECT_EQ("Invalid credentials.", s.error_message());
-
- ClientContext context2;
- auto stream = stub->BidiStream(&context2);
- s = stream->Finish();
- EXPECT_FALSE(s.ok());
- EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
- EXPECT_EQ("Invalid credentials.", s.error_message());
-}
-
void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
@@ -705,40 +576,9 @@ void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
context->TryCancel();
}
-// Client cancels rpc after 10ms
-TEST_P(End2endTest, ClientCancelsRpc) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
- const int kCancelDelayUs = 10 * 1000;
- request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
-
- ClientContext context;
- std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
- Status s = stub_->Echo(&context, request, &response);
- cancel_thread.join();
- EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
- EXPECT_EQ(s.error_message(), "Cancelled");
-}
-
-// Server cancels rpc after 1ms
-TEST_P(End2endTest, ServerCancelsRpc) {
- ResetStub(GetParam());
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
- request.mutable_param()->set_server_cancel_after_us(1000);
-
- ClientContext context;
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
- EXPECT_TRUE(s.error_message().empty());
-}
-
// Client cancels request stream after sending two messages
-TEST_F(End2endTest, ClientCancelsRequestStream) {
- ResetStub(false);
+TEST_P(End2endTest, ClientCancelsRequestStream) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -757,8 +597,8 @@ TEST_F(End2endTest, ClientCancelsRequestStream) {
}
// Client cancels server stream after sending some messages
-TEST_F(End2endTest, ClientCancelsResponseStream) {
- ResetStub(false);
+TEST_P(End2endTest, ClientCancelsResponseStream) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -789,8 +629,8 @@ TEST_F(End2endTest, ClientCancelsResponseStream) {
}
// Client cancels bidi stream after sending some messages
-TEST_F(End2endTest, ClientCancelsBidi) {
- ResetStub(false);
+TEST_P(End2endTest, ClientCancelsBidi) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -821,8 +661,8 @@ TEST_F(End2endTest, ClientCancelsBidi) {
EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
}
-TEST_F(End2endTest, RpcMaxMessageSize) {
- ResetStub(false);
+TEST_P(End2endTest, RpcMaxMessageSize) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
request.set_message(string(kMaxMessageSize_ * 2, 'a'));
@@ -832,6 +672,330 @@ TEST_F(End2endTest, RpcMaxMessageSize) {
EXPECT_FALSE(s.ok());
}
+// Client sends 20 requests and the server returns CANCELLED status after
+// reading 10 requests.
+TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+
+ context.AddMetadata(kServerCancelAfterReads, "10");
+ auto stream = stub_->RequestStream(&context, &response);
+ request.set_message("hello");
+ int send_messages = 20;
+ while (send_messages > 0) {
+ EXPECT_TRUE(stream->Write(request));
+ send_messages--;
+ }
+ stream->WritesDone();
+ Status s = stream->Finish();
+ EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
+}
+
+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_P(End2endTest, SimultaneousReadWritesDone) {
+ ResetStub();
+ 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, ChannelState) {
+ ResetStub();
+ // 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));
+}
+
+// Takes 10s.
+TEST_P(End2endTest, ChannelStateTimeout) {
+ if (GetParam().use_tls) {
+ return;
+ }
+ int port = grpc_pick_unused_port_or_die();
+ std::ostringstream server_address;
+ server_address << "127.0.0.1:" << port;
+ // Channel to non-existing server
+ auto channel = CreateChannel(server_address.str(), InsecureCredentials());
+ // Start IDLE
+ EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
+
+ auto state = GRPC_CHANNEL_IDLE;
+ for (int i = 0; i < 10; i++) {
+ channel->WaitForStateChange(
+ state, std::chrono::system_clock::now() + std::chrono::seconds(1));
+ state = channel->GetState(false);
+ }
+}
+
+// Talking to a non-existing service.
+TEST_P(End2endTest, NonExistingService) {
+ ResetChannel();
+ std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub;
+ stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_);
+
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ Status s = stub->Unimplemented(&context, request, &response);
+ EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
+ EXPECT_EQ("", s.error_message());
+}
+
+//////////////////////////////////////////////////////////////////////////
+// Test with and without a proxy.
+class ProxyEnd2endTest : public End2endTest {
+ protected:
+};
+
+TEST_P(ProxyEnd2endTest, SimpleRpc) {
+ ResetStub();
+ SendRpc(stub_.get(), 1);
+}
+
+TEST_P(ProxyEnd2endTest, MultipleRpcs) {
+ ResetStub();
+ std::vector<std::thread*> threads;
+ for (int i = 0; i < 10; ++i) {
+ threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
+ }
+ for (int i = 0; i < 10; ++i) {
+ threads[i]->join();
+ delete threads[i];
+ }
+}
+
+// Set a 10us deadline and make sure proper error is returned.
+TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::microseconds(10);
+ context.set_deadline(deadline);
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
+}
+
+// Set a long but finite deadline.
+TEST_P(ProxyEnd2endTest, RpcLongDeadline) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::hours(1);
+ context.set_deadline(deadline);
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+}
+
+// Ask server to echo back the deadline it sees.
+TEST_P(ProxyEnd2endTest, EchoDeadline) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_echo_deadline(true);
+
+ ClientContext context;
+ std::chrono::system_clock::time_point deadline =
+ std::chrono::system_clock::now() + std::chrono::seconds(100);
+ context.set_deadline(deadline);
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+ gpr_timespec sent_deadline;
+ Timepoint2Timespec(deadline, &sent_deadline);
+ // Allow 1 second error.
+ EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
+ EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
+}
+
+// Ask server to echo back the deadline it sees. The rpc has no deadline.
+TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_echo_deadline(true);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(response.message(), request.message());
+ EXPECT_TRUE(s.ok());
+ EXPECT_EQ(response.param().request_deadline(),
+ gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
+}
+
+TEST_P(ProxyEnd2endTest, UnimplementedRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ Status s = stub_->Unimplemented(&context, request, &response);
+ EXPECT_FALSE(s.ok());
+ EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
+ EXPECT_EQ(s.error_message(), "");
+ EXPECT_EQ(response.message(), "");
+}
+
+// Client cancels rpc after 10ms
+TEST_P(ProxyEnd2endTest, ClientCancelsRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ const int kCancelDelayUs = 10 * 1000;
+ request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
+
+ ClientContext context;
+ std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
+ Status s = stub_->Echo(&context, request, &response);
+ cancel_thread.join();
+ EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
+ EXPECT_EQ(s.error_message(), "Cancelled");
+}
+
+// Server cancels rpc after 1ms
+TEST_P(ProxyEnd2endTest, ServerCancelsRpc) {
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+ request.mutable_param()->set_server_cancel_after_us(1000);
+
+ ClientContext context;
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
+ EXPECT_TRUE(s.error_message().empty());
+}
+
+// Make the response larger than the flow control window.
+TEST_P(ProxyEnd2endTest, HugeResponse) {
+ ResetStub();
+ 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());
+}
+
+TEST_P(ProxyEnd2endTest, Peer) {
+ ResetStub();
+ 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()));
+}
+
+//////////////////////////////////////////////////////////////////////////
+class SecureEnd2endTest : public End2endTest {
+ protected:
+ SecureEnd2endTest() {
+ GPR_ASSERT(!GetParam().use_proxy);
+ GPR_ASSERT(GetParam().use_tls);
+ }
+};
+
+TEST_P(SecureEnd2endTest, SimpleRpcWithHost) {
+ ResetStub();
+
+ EchoRequest request;
+ EchoResponse response;
+ request.set_message("Hello");
+
+ ClientContext context;
+ 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("special", response.param().host());
+ EXPECT_TRUE(s.ok());
+}
+
+// rpc and stream should fail on bad credentials.
+TEST_P(SecureEnd2endTest, BadCredentials) {
+ std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials("");
+ EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
+ std::shared_ptr<Channel> channel =
+ CreateChannel(server_address_.str(), bad_creds);
+ std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
+ grpc::cpp::test::util::TestService::NewStub(channel));
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ request.set_message("Hello");
+
+ Status s = stub->Echo(&context, request, &response);
+ EXPECT_EQ("", response.message());
+ EXPECT_FALSE(s.ok());
+ EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
+ EXPECT_EQ("Invalid credentials.", s.error_message());
+
+ ClientContext context2;
+ auto stream = stub->BidiStream(&context2);
+ s = stream->Finish();
+ EXPECT_FALSE(s.ok());
+ EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
+ EXPECT_EQ("Invalid credentials.", s.error_message());
+}
+
bool MetadataContains(
const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
const grpc::string& key, const grpc::string& value) {
@@ -847,8 +1011,45 @@ bool MetadataContains(
return count == 1;
}
-TEST_F(End2endTest, SetPerCallCredentials) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) {
+ auto* processor = new TestAuthMetadataProcessor(true);
+ StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ context.set_credentials(processor->GetCompatibleClientCreds());
+ request.set_message("Hello");
+ request.mutable_param()->set_echo_metadata(true);
+ request.mutable_param()->set_expected_client_identity(
+ TestAuthMetadataProcessor::kGoodGuy);
+
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_EQ(request.message(), response.message());
+ EXPECT_TRUE(s.ok());
+
+ // Metadata should have been consumed by the processor.
+ EXPECT_FALSE(MetadataContains(
+ context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
+ grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
+}
+
+TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) {
+ auto* processor = new TestAuthMetadataProcessor(true);
+ StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
+ ResetStub();
+ EchoRequest request;
+ EchoResponse response;
+ ClientContext context;
+ context.set_credentials(processor->GetIncompatibleClientCreds());
+ request.set_message("Hello");
+
+ Status s = stub_->Echo(&context, request, &response);
+ EXPECT_FALSE(s.ok());
+ EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
+}
+TEST_P(SecureEnd2endTest, SetPerCallCredentials) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -869,8 +1070,8 @@ TEST_F(End2endTest, SetPerCallCredentials) {
"fake_selector"));
}
-TEST_F(End2endTest, InsecurePerCallCredentials) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, InsecurePerCallCredentials) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -884,8 +1085,8 @@ TEST_F(End2endTest, InsecurePerCallCredentials) {
EXPECT_EQ("Failed to set credentials to rpc.", s.error_message());
}
-TEST_F(End2endTest, OverridePerCallCredentials) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, OverridePerCallCredentials) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -915,8 +1116,8 @@ TEST_F(End2endTest, OverridePerCallCredentials) {
EXPECT_TRUE(s.ok());
}
-TEST_F(End2endTest, NonBlockingAuthMetadataPluginFailure) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -932,10 +1133,10 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginFailure) {
EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
}
-TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
+TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
auto* processor = new TestAuthMetadataProcessor(false);
StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
- ResetStub(false);
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -955,10 +1156,10 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
}
-TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
+TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
auto* processor = new TestAuthMetadataProcessor(false);
StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
- ResetStub(false);
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -970,8 +1171,8 @@ TEST_F(End2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
}
-TEST_F(End2endTest, BlockingAuthMetadataPluginFailure) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
ClientContext context;
@@ -987,67 +1188,8 @@ TEST_F(End2endTest, BlockingAuthMetadataPluginFailure) {
EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
}
-TEST_F(End2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) {
- auto* processor = new TestAuthMetadataProcessor(true);
- StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
- ResetStub(false);
- EchoRequest request;
- EchoResponse response;
- ClientContext context;
- context.set_credentials(processor->GetCompatibleClientCreds());
- request.set_message("Hello");
- request.mutable_param()->set_echo_metadata(true);
- request.mutable_param()->set_expected_client_identity(
- TestAuthMetadataProcessor::kGoodGuy);
-
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(request.message(), response.message());
- EXPECT_TRUE(s.ok());
-
- // Metadata should have been consumed by the processor.
- EXPECT_FALSE(MetadataContains(
- context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
- grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
-}
-
-TEST_F(End2endTest, BlockingAuthMetadataPluginAndProcessorFailure) {
- auto* processor = new TestAuthMetadataProcessor(true);
- StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
- ResetStub(false);
- EchoRequest request;
- EchoResponse response;
- ClientContext context;
- context.set_credentials(processor->GetIncompatibleClientCreds());
- request.set_message("Hello");
-
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_FALSE(s.ok());
- EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
-}
-
-// Client sends 20 requests and the server returns CANCELLED status after
-// reading 10 requests.
-TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) {
- ResetStub(false);
- EchoRequest request;
- EchoResponse response;
- ClientContext context;
-
- context.AddMetadata(kServerCancelAfterReads, "10");
- auto stream = stub_->RequestStream(&context, &response);
- request.set_message("hello");
- int send_messages = 20;
- while (send_messages > 0) {
- EXPECT_TRUE(stream->Write(request));
- send_messages--;
- }
- stream->WritesDone();
- Status s = stream->Finish();
- EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
-}
-
-TEST_F(End2endTest, ClientAuthContext) {
- ResetStub(false);
+TEST_P(SecureEnd2endTest, ClientAuthContext) {
+ ResetStub();
EchoRequest request;
EchoResponse response;
request.set_message("Hello");
@@ -1072,119 +1214,20 @@ TEST_F(End2endTest, ClientAuthContext) {
EXPECT_EQ("*.test.youtube.com", ToString(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);
+INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
+ ::testing::Values(TestScenario(false, true),
+ TestScenario(false, false)));
- ClientContext context;
- Status s = stub_->Echo(&context, request, &response);
- EXPECT_EQ(kResponseSize, response.message().size());
- EXPECT_TRUE(s.ok());
-}
+INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
+ ::testing::Values(TestScenario(true, true),
+ TestScenario(true, false),
+ TestScenario(false, true),
+ TestScenario(false, false)));
-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));
-}
-
-// Takes 10s.
-TEST_F(End2endTest, ChannelStateTimeout) {
- int port = grpc_pick_unused_port_or_die();
- std::ostringstream server_address;
- server_address << "127.0.0.1:" << port;
- // Channel to non-existing server
- auto channel = CreateChannel(server_address.str(), InsecureCredentials());
- // Start IDLE
- EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
-
- auto state = GRPC_CHANNEL_IDLE;
- for (int i = 0; i < 10; i++) {
- channel->WaitForStateChange(
- state, std::chrono::system_clock::now() + std::chrono::seconds(1));
- state = channel->GetState(false);
- }
-}
-
-// Talking to a non-existing service.
-TEST_F(End2endTest, NonExistingService) {
- ResetChannel();
- std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub;
- stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_);
-
- EchoRequest request;
- EchoResponse response;
- request.set_message("Hello");
-
- ClientContext context;
- Status s = stub->Unimplemented(&context, request, &response);
- EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
- EXPECT_EQ("", s.error_message());
-}
-
-INSTANTIATE_TEST_CASE_P(End2end, End2endTest, ::testing::Values(false, true));
+INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
+ ::testing::Values(TestScenario(false, true)));
+} // namespace
} // namespace testing
} // namespace grpc