blob: c294d594541c198b064ded16a634485aea6ff5ea [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller06059952015-02-18 08:34:56 -08003 * Copyright 2015, Google Inc.
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08004 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
Yang Gao69fe0752015-06-01 14:32:38 -070034#include <mutex>
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080035#include <thread>
yangged5e7e02015-01-06 10:16:15 -080036
yang-g9e2f90c2015-08-21 15:35:03 -070037#include <grpc/grpc.h>
38#include <grpc/support/thd.h>
39#include <grpc/support/time.h>
40#include <grpc++/channel.h>
41#include <grpc++/client_context.h>
42#include <grpc++/create_channel.h>
Julien Boeuf5be92a32015-08-28 16:28:18 -070043#include <grpc++/security/auth_metadata_processor.h>
44#include <grpc++/security/credentials.h>
45#include <grpc++/security/server_credentials.h>
yang-g9e2f90c2015-08-21 15:35:03 -070046#include <grpc++/server.h>
47#include <grpc++/server_builder.h>
48#include <grpc++/server_context.h>
yang-g9e2f90c2015-08-21 15:35:03 -070049#include <gtest/gtest.h>
50
Yang Gao26a49122015-05-15 17:02:56 -070051#include "src/core/security/credentials.h"
yang-g8b25f2a2015-07-21 23:54:36 -070052#include "test/core/end2end/data/ssl_test_data.h"
Nicolas Noble89219162015-04-07 18:01:18 -070053#include "test/core/util/port.h"
Craig Tiller14e60e92015-01-13 17:26:46 -080054#include "test/core/util/test_config.h"
Nicolas "Pixel" Noble0caebbf2015-04-09 23:08:51 +020055#include "test/cpp/util/echo_duplicate.grpc.pb.h"
56#include "test/cpp/util/echo.grpc.pb.h"
yang-ge21908f2015-08-25 13:47:51 -070057#include "test/cpp/util/string_ref_helper.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080058
59using grpc::cpp::test::util::EchoRequest;
60using grpc::cpp::test::util::EchoResponse;
yangged5e7e02015-01-06 10:16:15 -080061using std::chrono::system_clock;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080062
63namespace grpc {
yangged5e7e02015-01-06 10:16:15 -080064namespace testing {
65
66namespace {
67
yang-g0b6ad7d2015-06-25 14:39:01 -070068const char* kServerCancelAfterReads = "cancel_after_reads";
69
yangged5e7e02015-01-06 10:16:15 -080070// When echo_deadline is requested, deadline seen in the ServerContext is set in
71// the response in seconds.
72void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
73 EchoResponse* response) {
74 if (request->has_param() && request->param().echo_deadline()) {
Craig Tiller354398f2015-07-13 09:16:03 -070075 gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
Nicolas Noble89219162015-04-07 18:01:18 -070076 if (context->deadline() != system_clock::time_point::max()) {
77 Timepoint2Timespec(context->deadline(), &deadline);
yangged5e7e02015-01-06 10:16:15 -080078 }
79 response->mutable_param()->set_request_deadline(deadline.tv_sec);
80 }
81}
Craig Tiller7418d012015-02-11 15:25:03 -080082
Julien Boeuf0c711ad2015-08-28 14:10:58 -070083void CheckServerAuthContext(const ServerContext* context,
84 const grpc::string& expected_client_identity) {
yang-g85c04f92015-07-07 17:47:31 -070085 std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
yang-gd090fe12015-08-25 16:53:07 -070086 std::vector<grpc::string_ref> ssl =
yang-gc4eef2e2015-07-06 23:26:58 -070087 auth_ctx->FindPropertyValues("transport_security_type");
yang-g8b25f2a2015-07-21 23:54:36 -070088 EXPECT_EQ(1u, ssl.size());
yang-gd090fe12015-08-25 16:53:07 -070089 EXPECT_EQ("ssl", ToString(ssl[0]));
Julien Boeuf0c711ad2015-08-28 14:10:58 -070090 if (expected_client_identity.length() == 0) {
91 EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
92 EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
93 EXPECT_FALSE(auth_ctx->IsPeerAuthenticated());
94 } else {
95 auto identity = auth_ctx->GetPeerIdentity();
96 EXPECT_TRUE(auth_ctx->IsPeerAuthenticated());
97 EXPECT_EQ(1u, identity.size());
98 EXPECT_EQ(expected_client_identity, identity[0]);
99 }
yang-gc4eef2e2015-07-06 23:26:58 -0700100}
101
yang-gd7ead692015-07-30 10:57:45 -0700102bool CheckIsLocalhost(const grpc::string& addr) {
103 const grpc::string kIpv6("ipv6:[::1]:");
104 const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
105 const grpc::string kIpv4("ipv4:127.0.0.1:");
106 return addr.substr(0, kIpv4.size()) == kIpv4 ||
107 addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 ||
108 addr.substr(0, kIpv6.size()) == kIpv6;
109}
110
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700111class TestAuthMetadataProcessor : public AuthMetadataProcessor {
112 public:
113 static const char kGoodGuy[];
114
115 TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
116
117 std::shared_ptr<Credentials> GetCompatibleClientCreds() {
118 return AccessTokenCredentials(kGoodGuy);
119 }
120 std::shared_ptr<Credentials> GetIncompatibleClientCreds() {
121 return AccessTokenCredentials("Mr Hyde");
122 }
123
124 // Interface implementation
125 bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
126
127 Status Process(const InputMetadata& auth_metadata, AuthContext* context,
128 OutputMetadata* consumed_auth_metadata,
129 OutputMetadata* response_metadata) GRPC_OVERRIDE {
130 EXPECT_TRUE(consumed_auth_metadata != nullptr);
131 EXPECT_TRUE(context != nullptr);
132 EXPECT_TRUE(response_metadata != nullptr);
133 auto auth_md = auth_metadata.find(GRPC_AUTHORIZATION_METADATA_KEY);
134 EXPECT_NE(auth_md, auth_metadata.end());
135 string_ref auth_md_value = auth_md->second;
Julien Boeuf821de342015-08-28 16:31:20 -0700136 if (auth_md_value.ends_with(kGoodGuy)) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700137 context->AddProperty(kIdentityPropName, kGoodGuy);
138 context->SetPeerIdentityPropertyName(kIdentityPropName);
139 consumed_auth_metadata->insert(
140 std::make_pair(string(auth_md->first.data(), auth_md->first.length()),
141 auth_md->second));
142 return Status::OK;
143 } else {
144 return Status(StatusCode::UNAUTHENTICATED,
145 string("Invalid principal: ") +
146 string(auth_md_value.data(), auth_md_value.length()));
147 }
148 }
149
150 protected:
151 static const char kIdentityPropName[];
152 bool is_blocking_;
153};
154
155const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll";
156const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
157
158
yangged5e7e02015-01-06 10:16:15 -0800159} // namespace
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800160
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700161class Proxy : public ::grpc::cpp::test::util::TestService::Service {
162 public:
yang-g8c2be9f2015-08-19 16:28:09 -0700163 Proxy(std::shared_ptr<Channel> channel)
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700164 : stub_(grpc::cpp::test::util::TestService::NewStub(channel)) {}
165
166 Status Echo(ServerContext* server_context, const EchoRequest* request,
167 EchoResponse* response) GRPC_OVERRIDE {
168 std::unique_ptr<ClientContext> client_context =
169 ClientContext::FromServerContext(*server_context);
170 return stub_->Echo(client_context.get(), *request, response);
171 }
172
173 private:
David G. Quintas086a9822015-08-11 18:56:10 -0700174 std::unique_ptr< ::grpc::cpp::test::util::TestService::Stub> stub_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700175};
176
yangg1456d152015-01-08 15:39:58 -0800177class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800178 public:
vjpaidf551612015-07-14 13:38:44 -0700179 TestServiceImpl() : signal_client_(false), host_() {}
Vijay Pai181ef452015-07-14 13:52:48 -0700180 explicit TestServiceImpl(const grpc::string& host)
181 : signal_client_(false), host_(new grpc::string(host)) {}
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700182
yangga4b6f5d2014-12-17 15:53:12 -0800183 Status Echo(ServerContext* context, const EchoRequest* request,
Craig Tillercf133f42015-02-26 14:05:56 -0800184 EchoResponse* response) GRPC_OVERRIDE {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800185 response->set_message(request->message());
yangged5e7e02015-01-06 10:16:15 -0800186 MaybeEchoDeadline(context, request, response);
Craig Tiller822d2c72015-07-07 16:08:00 -0700187 if (host_) {
188 response->mutable_param()->set_host(*host_);
189 }
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700190 if (request->has_param() && request->param().client_cancel_after_us()) {
191 {
192 std::unique_lock<std::mutex> lock(mu_);
193 signal_client_ = true;
194 }
195 while (!context->IsCancelled()) {
David Garcia Quintasfeb67f62015-05-20 19:23:25 -0700196 gpr_sleep_until(gpr_time_add(
Craig Tiller20b5fe92015-07-06 10:43:50 -0700197 gpr_now(GPR_CLOCK_REALTIME),
Craig Tiller677c50c2015-07-13 10:49:06 -0700198 gpr_time_from_micros(request->param().client_cancel_after_us(),
199 GPR_TIMESPAN)));
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700200 }
Yang Gaoc1a2c312015-06-16 10:59:46 -0700201 return Status::CANCELLED;
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700202 } else if (request->has_param() &&
203 request->param().server_cancel_after_us()) {
David Garcia Quintasfeb67f62015-05-20 19:23:25 -0700204 gpr_sleep_until(gpr_time_add(
Craig Tiller20b5fe92015-07-06 10:43:50 -0700205 gpr_now(GPR_CLOCK_REALTIME),
Craig Tiller677c50c2015-07-13 10:49:06 -0700206 gpr_time_from_micros(request->param().server_cancel_after_us(),
207 GPR_TIMESPAN)));
Yang Gaoc1a2c312015-06-16 10:59:46 -0700208 return Status::CANCELLED;
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700209 } else {
210 EXPECT_FALSE(context->IsCancelled());
211 }
Yang Gao26a49122015-05-15 17:02:56 -0700212
213 if (request->has_param() && request->param().echo_metadata()) {
yang-ge21908f2015-08-25 13:47:51 -0700214 const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata =
Yang Gao26a49122015-05-15 17:02:56 -0700215 context->client_metadata();
yang-ge21908f2015-08-25 13:47:51 -0700216 for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
217 iter = client_metadata.begin();
Yang Gao26a49122015-05-15 17:02:56 -0700218 iter != client_metadata.end(); ++iter) {
yang-ge21908f2015-08-25 13:47:51 -0700219 context->AddTrailingMetadata(ToString(iter->first),
220 ToString(iter->second));
Yang Gao26a49122015-05-15 17:02:56 -0700221 }
222 }
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700223 if (request->has_param() &&
224 (request->param().expected_client_identity().length() > 0 ||
225 request->param().check_auth_context())) {
226 CheckServerAuthContext(context, request->param().expected_client_identity());
yang-gc4eef2e2015-07-06 23:26:58 -0700227 }
yang-g6f30dec2015-07-22 23:11:56 -0700228 if (request->has_param() &&
229 request->param().response_message_length() > 0) {
230 response->set_message(
231 grpc::string(request->param().response_message_length(), '\0'));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800232 }
yang-gd7ead692015-07-30 10:57:45 -0700233 if (request->has_param() && request->param().echo_peer()) {
234 response->mutable_param()->set_peer(context->peer());
235 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800236 return Status::OK;
237 }
nnoble0c475f02014-12-05 15:37:39 -0800238
239 // Unimplemented is left unimplemented to test the returned error.
240
yangga4b6f5d2014-12-17 15:53:12 -0800241 Status RequestStream(ServerContext* context,
242 ServerReader<EchoRequest>* reader,
Craig Tillercf133f42015-02-26 14:05:56 -0800243 EchoResponse* response) GRPC_OVERRIDE {
nnoble0c475f02014-12-05 15:37:39 -0800244 EchoRequest request;
245 response->set_message("");
yang-g0b6ad7d2015-06-25 14:39:01 -0700246 int cancel_after_reads = 0;
yang-ge21908f2015-08-25 13:47:51 -0700247 const std::multimap<grpc::string_ref, grpc::string_ref>&
248 client_initial_metadata = context->client_metadata();
yang-g0b6ad7d2015-06-25 14:39:01 -0700249 if (client_initial_metadata.find(kServerCancelAfterReads) !=
250 client_initial_metadata.end()) {
yang-ge21908f2015-08-25 13:47:51 -0700251 std::istringstream iss(ToString(
252 client_initial_metadata.find(kServerCancelAfterReads)->second));
yang-g0b6ad7d2015-06-25 14:39:01 -0700253 iss >> cancel_after_reads;
254 gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
255 }
nnoble0c475f02014-12-05 15:37:39 -0800256 while (reader->Read(&request)) {
yang-g0b6ad7d2015-06-25 14:39:01 -0700257 if (cancel_after_reads == 1) {
258 gpr_log(GPR_INFO, "return cancel status");
259 return Status::CANCELLED;
260 } else if (cancel_after_reads > 0) {
261 cancel_after_reads--;
262 }
nnoble0c475f02014-12-05 15:37:39 -0800263 response->mutable_message()->append(request.message());
264 }
265 return Status::OK;
266 }
267
268 // Return 3 messages.
269 // TODO(yangg) make it generic by adding a parameter into EchoRequest
yangga4b6f5d2014-12-17 15:53:12 -0800270 Status ResponseStream(ServerContext* context, const EchoRequest* request,
Craig Tillercf133f42015-02-26 14:05:56 -0800271 ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
nnoble0c475f02014-12-05 15:37:39 -0800272 EchoResponse response;
273 response.set_message(request->message() + "0");
274 writer->Write(response);
275 response.set_message(request->message() + "1");
276 writer->Write(response);
277 response.set_message(request->message() + "2");
278 writer->Write(response);
279
280 return Status::OK;
281 }
282
Craig Tillercf133f42015-02-26 14:05:56 -0800283 Status BidiStream(ServerContext* context,
284 ServerReaderWriter<EchoResponse, EchoRequest>* stream)
285 GRPC_OVERRIDE {
nnoble0c475f02014-12-05 15:37:39 -0800286 EchoRequest request;
287 EchoResponse response;
288 while (stream->Read(&request)) {
289 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
290 response.set_message(request.message());
291 stream->Write(response);
292 }
293 return Status::OK;
294 }
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700295
296 bool signal_client() {
297 std::unique_lock<std::mutex> lock(mu_);
298 return signal_client_;
299 }
300
301 private:
302 bool signal_client_;
303 std::mutex mu_;
Craig Tiller822d2c72015-07-07 16:08:00 -0700304 std::unique_ptr<grpc::string> host_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800305};
306
yangg1456d152015-01-08 15:39:58 -0800307class TestServiceImplDupPkg
308 : public ::grpc::cpp::test::util::duplicate::TestService::Service {
309 public:
310 Status Echo(ServerContext* context, const EchoRequest* request,
Craig Tillercf133f42015-02-26 14:05:56 -0800311 EchoResponse* response) GRPC_OVERRIDE {
yangg1456d152015-01-08 15:39:58 -0800312 response->set_message("no package");
313 return Status::OK;
314 }
315};
316
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700317/* Param is whether or not to use a proxy -- some tests use TEST_F as they don't
318 need this functionality */
319class End2endTest : public ::testing::TestWithParam<bool> {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800320 protected:
Vijay Pai181ef452015-07-14 13:52:48 -0700321 End2endTest()
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700322 : is_server_started_(false),
323 kMaxMessageSize_(8192),
324 special_service_("special") {}
Craig Tiller7418d012015-02-11 15:25:03 -0800325
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700326 void TearDown() GRPC_OVERRIDE {
327 if (is_server_started_) {
328 server_->Shutdown();
329 if (proxy_server_) proxy_server_->Shutdown();
330 }
331 }
332
333 void StartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) {
Craig Tiller35e39712015-01-12 16:41:24 -0800334 int port = grpc_pick_unused_port_or_die();
yang-gd7ead692015-07-30 10:57:45 -0700335 server_address_ << "127.0.0.1:" << port;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800336 // Setup server
337 ServerBuilder builder;
yang-g8b25f2a2015-07-21 23:54:36 -0700338 SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
Craig Tillerd6c98df2015-08-18 09:33:44 -0700339 test_server1_cert};
yang-g8b25f2a2015-07-21 23:54:36 -0700340 SslServerCredentialsOptions ssl_opts;
341 ssl_opts.pem_root_certs = "";
342 ssl_opts.pem_key_cert_pairs.push_back(pkcp);
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700343 auto server_creds = SslServerCredentials(ssl_opts);
344 server_creds->SetAuthMetadataProcessor(processor);
345 builder.AddListeningPort(server_address_.str(), server_creds);
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800346 builder.RegisterService(&service_);
yang-g8b25f2a2015-07-21 23:54:36 -0700347 builder.RegisterService("foo.test.youtube.com", &special_service_);
Yang Gaoc71a9d22015-05-04 00:22:12 -0700348 builder.SetMaxMessageSize(
349 kMaxMessageSize_); // For testing max message size.
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800350 builder.RegisterService(&dup_pkg_service_);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800351 server_ = builder.BuildAndStart();
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700352 is_server_started_ = true;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700353 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800354
yang-g9b7757d2015-08-13 11:15:53 -0700355 void ResetChannel() {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700356 if (!is_server_started_) {
357 StartServer(std::shared_ptr<AuthMetadataProcessor>());
358 }
359 EXPECT_TRUE(is_server_started_);
yang-g8b25f2a2015-07-21 23:54:36 -0700360 SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700361 ChannelArguments args;
yang-g8b25f2a2015-07-21 23:54:36 -0700362 args.SetSslTargetNameOverride("foo.test.google.fr");
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700363 args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
yang-g730055d2015-08-27 12:29:45 -0700364 channel_ = CreateCustomChannel(server_address_.str(),
365 SslCredentials(ssl_opts), args);
yang-g9b7757d2015-08-13 11:15:53 -0700366 }
367
368 void ResetStub(bool use_proxy) {
369 ResetChannel();
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700370 if (use_proxy) {
371 proxy_service_.reset(new Proxy(channel_));
372 int port = grpc_pick_unused_port_or_die();
373 std::ostringstream proxyaddr;
374 proxyaddr << "localhost:" << port;
375 ServerBuilder builder;
376 builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials());
377 builder.RegisterService(proxy_service_.get());
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700378 proxy_server_ = builder.BuildAndStart();
379
yang-g730055d2015-08-27 12:29:45 -0700380 channel_ = CreateChannel(proxyaddr.str(), InsecureCredentials());
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700381 }
382
Nicolas "Pixel" Noble7fa51672015-09-02 02:29:09 +0200383 stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
yangg1456d152015-01-08 15:39:58 -0800384 }
385
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700386 bool is_server_started_;
yang-g8c2be9f2015-08-19 16:28:09 -0700387 std::shared_ptr<Channel> channel_;
yangg1456d152015-01-08 15:39:58 -0800388 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800389 std::unique_ptr<Server> server_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700390 std::unique_ptr<Server> proxy_server_;
391 std::unique_ptr<Proxy> proxy_service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800392 std::ostringstream server_address_;
Yang Gao3921c562015-04-30 16:07:06 -0700393 const int kMaxMessageSize_;
nnoble0c475f02014-12-05 15:37:39 -0800394 TestServiceImpl service_;
Craig Tiller822d2c72015-07-07 16:08:00 -0700395 TestServiceImpl special_service_;
yangg1456d152015-01-08 15:39:58 -0800396 TestServiceImplDupPkg dup_pkg_service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800397};
398
yangg1456d152015-01-08 15:39:58 -0800399static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
400 int num_rpcs) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800401 EchoRequest request;
402 EchoResponse response;
David Garcia Quintasd7d9ce22015-06-30 23:29:03 -0700403 request.set_message("Hello hello hello hello");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800404
405 for (int i = 0; i < num_rpcs; ++i) {
406 ClientContext context;
Craig Tillerbf6abee2015-07-19 22:31:04 -0700407 context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800408 Status s = stub->Echo(&context, request, &response);
409 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700410 EXPECT_TRUE(s.ok());
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800411 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800412}
413
Craig Tiller822d2c72015-07-07 16:08:00 -0700414TEST_F(End2endTest, SimpleRpcWithHost) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700415 ResetStub(false);
Craig Tiller822d2c72015-07-07 16:08:00 -0700416
417 EchoRequest request;
418 EchoResponse response;
419 request.set_message("Hello");
420
421 ClientContext context;
yang-g8b25f2a2015-07-21 23:54:36 -0700422 context.set_authority("foo.test.youtube.com");
Craig Tiller822d2c72015-07-07 16:08:00 -0700423 Status s = stub_->Echo(&context, request, &response);
424 EXPECT_EQ(response.message(), request.message());
425 EXPECT_TRUE(response.has_param());
yang-g8b25f2a2015-07-21 23:54:36 -0700426 EXPECT_EQ("special", response.param().host());
Craig Tiller822d2c72015-07-07 16:08:00 -0700427 EXPECT_TRUE(s.ok());
428}
429
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700430TEST_P(End2endTest, SimpleRpc) {
431 ResetStub(GetParam());
yangg1456d152015-01-08 15:39:58 -0800432 SendRpc(stub_.get(), 1);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800433}
434
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700435TEST_P(End2endTest, MultipleRpcs) {
436 ResetStub(GetParam());
Craig Tiller35e39712015-01-12 16:41:24 -0800437 std::vector<std::thread*> threads;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800438 for (int i = 0; i < 10; ++i) {
yangg1456d152015-01-08 15:39:58 -0800439 threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800440 }
441 for (int i = 0; i < 10; ++i) {
442 threads[i]->join();
443 delete threads[i];
444 }
445}
446
yanggda029e32014-12-18 10:24:04 -0800447// Set a 10us deadline and make sure proper error is returned.
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700448TEST_P(End2endTest, RpcDeadlineExpires) {
449 ResetStub(GetParam());
yanggda029e32014-12-18 10:24:04 -0800450 EchoRequest request;
451 EchoResponse response;
452 request.set_message("Hello");
453
454 ClientContext context;
455 std::chrono::system_clock::time_point deadline =
456 std::chrono::system_clock::now() + std::chrono::microseconds(10);
Nicolas Noble89219162015-04-07 18:01:18 -0700457 context.set_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800458 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700459 EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
yanggda029e32014-12-18 10:24:04 -0800460}
461
yangged5e7e02015-01-06 10:16:15 -0800462// Set a long but finite deadline.
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700463TEST_P(End2endTest, RpcLongDeadline) {
464 ResetStub(GetParam());
yangged5e7e02015-01-06 10:16:15 -0800465 EchoRequest request;
466 EchoResponse response;
467 request.set_message("Hello");
468
469 ClientContext context;
470 std::chrono::system_clock::time_point deadline =
471 std::chrono::system_clock::now() + std::chrono::hours(1);
Nicolas Noble89219162015-04-07 18:01:18 -0700472 context.set_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800473 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800474 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700475 EXPECT_TRUE(s.ok());
yangged5e7e02015-01-06 10:16:15 -0800476}
477
478// Ask server to echo back the deadline it sees.
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700479TEST_P(End2endTest, EchoDeadline) {
480 ResetStub(GetParam());
yangged5e7e02015-01-06 10:16:15 -0800481 EchoRequest request;
482 EchoResponse response;
483 request.set_message("Hello");
484 request.mutable_param()->set_echo_deadline(true);
485
486 ClientContext context;
487 std::chrono::system_clock::time_point deadline =
488 std::chrono::system_clock::now() + std::chrono::seconds(100);
Nicolas Noble89219162015-04-07 18:01:18 -0700489 context.set_deadline(deadline);
yangg1456d152015-01-08 15:39:58 -0800490 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800491 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700492 EXPECT_TRUE(s.ok());
yangged5e7e02015-01-06 10:16:15 -0800493 gpr_timespec sent_deadline;
494 Timepoint2Timespec(deadline, &sent_deadline);
495 // Allow 1 second error.
496 EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
497 EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
yangged5e7e02015-01-06 10:16:15 -0800498}
499
500// Ask server to echo back the deadline it sees. The rpc has no deadline.
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700501TEST_P(End2endTest, EchoDeadlineForNoDeadlineRpc) {
502 ResetStub(GetParam());
yangged5e7e02015-01-06 10:16:15 -0800503 EchoRequest request;
504 EchoResponse response;
505 request.set_message("Hello");
506 request.mutable_param()->set_echo_deadline(true);
507
508 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800509 Status s = stub_->Echo(&context, request, &response);
yangged5e7e02015-01-06 10:16:15 -0800510 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700511 EXPECT_TRUE(s.ok());
Craig Tiller354398f2015-07-13 09:16:03 -0700512 EXPECT_EQ(response.param().request_deadline(),
513 gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
yangged5e7e02015-01-06 10:16:15 -0800514}
515
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700516TEST_P(End2endTest, UnimplementedRpc) {
517 ResetStub(GetParam());
nnoble0c475f02014-12-05 15:37:39 -0800518 EchoRequest request;
519 EchoResponse response;
520 request.set_message("Hello");
521
522 ClientContext context;
yangg1456d152015-01-08 15:39:58 -0800523 Status s = stub_->Unimplemented(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700524 EXPECT_FALSE(s.ok());
525 EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
526 EXPECT_EQ(s.error_message(), "");
nnoble0c475f02014-12-05 15:37:39 -0800527 EXPECT_EQ(response.message(), "");
nnoble0c475f02014-12-05 15:37:39 -0800528}
529
530TEST_F(End2endTest, RequestStreamOneRequest) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700531 ResetStub(false);
nnoble0c475f02014-12-05 15:37:39 -0800532 EchoRequest request;
533 EchoResponse response;
534 ClientContext context;
535
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800536 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800537 request.set_message("hello");
538 EXPECT_TRUE(stream->Write(request));
539 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800540 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800541 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700542 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800543}
544
545TEST_F(End2endTest, RequestStreamTwoRequests) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700546 ResetStub(false);
nnoble0c475f02014-12-05 15:37:39 -0800547 EchoRequest request;
548 EchoResponse response;
549 ClientContext context;
550
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800551 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800552 request.set_message("hello");
553 EXPECT_TRUE(stream->Write(request));
554 EXPECT_TRUE(stream->Write(request));
555 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800556 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800557 EXPECT_EQ(response.message(), "hellohello");
Yang Gaoc1a2c312015-06-16 10:59:46 -0700558 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800559}
560
561TEST_F(End2endTest, ResponseStream) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700562 ResetStub(false);
nnoble0c475f02014-12-05 15:37:39 -0800563 EchoRequest request;
564 EchoResponse response;
565 ClientContext context;
566 request.set_message("hello");
567
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800568 auto stream = stub_->ResponseStream(&context, request);
nnoble0c475f02014-12-05 15:37:39 -0800569 EXPECT_TRUE(stream->Read(&response));
570 EXPECT_EQ(response.message(), request.message() + "0");
571 EXPECT_TRUE(stream->Read(&response));
572 EXPECT_EQ(response.message(), request.message() + "1");
573 EXPECT_TRUE(stream->Read(&response));
574 EXPECT_EQ(response.message(), request.message() + "2");
575 EXPECT_FALSE(stream->Read(&response));
576
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800577 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700578 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800579}
580
581TEST_F(End2endTest, BidiStream) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700582 ResetStub(false);
nnoble0c475f02014-12-05 15:37:39 -0800583 EchoRequest request;
584 EchoResponse response;
585 ClientContext context;
586 grpc::string msg("hello");
587
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800588 auto stream = stub_->BidiStream(&context);
nnoble0c475f02014-12-05 15:37:39 -0800589
590 request.set_message(msg + "0");
591 EXPECT_TRUE(stream->Write(request));
592 EXPECT_TRUE(stream->Read(&response));
593 EXPECT_EQ(response.message(), request.message());
594
595 request.set_message(msg + "1");
596 EXPECT_TRUE(stream->Write(request));
597 EXPECT_TRUE(stream->Read(&response));
598 EXPECT_EQ(response.message(), request.message());
599
600 request.set_message(msg + "2");
601 EXPECT_TRUE(stream->Write(request));
602 EXPECT_TRUE(stream->Read(&response));
603 EXPECT_EQ(response.message(), request.message());
604
605 stream->WritesDone();
606 EXPECT_FALSE(stream->Read(&response));
607
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800608 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700609 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800610}
611
612// Talk to the two services with the same name but different package names.
613// The two stubs are created on the same channel.
614TEST_F(End2endTest, DiffPackageServices) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700615 ResetStub(false);
yangg1456d152015-01-08 15:39:58 -0800616 EchoRequest request;
617 EchoResponse response;
618 request.set_message("Hello");
619
yangg1456d152015-01-08 15:39:58 -0800620 ClientContext context;
yang-g8b25f2a2015-07-21 23:54:36 -0700621 Status s = stub_->Echo(&context, request, &response);
yangg1456d152015-01-08 15:39:58 -0800622 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700623 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800624
625 std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
626 dup_pkg_stub(
yang-g8b25f2a2015-07-21 23:54:36 -0700627 grpc::cpp::test::util::duplicate::TestService::NewStub(channel_));
yangg1456d152015-01-08 15:39:58 -0800628 ClientContext context2;
629 s = dup_pkg_stub->Echo(&context2, request, &response);
630 EXPECT_EQ("no package", response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700631 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800632}
633
yangg4105e2b2015-01-09 14:19:44 -0800634// rpc and stream should fail on bad credentials.
635TEST_F(End2endTest, BadCredentials) {
Julien Boeuf510a9202015-08-25 21:51:07 -0700636 std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials("");
Craig Tillerb256faa2015-07-23 11:28:16 -0700637 EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
yang-g8c2be9f2015-08-19 16:28:09 -0700638 std::shared_ptr<Channel> channel =
yang-g730055d2015-08-27 12:29:45 -0700639 CreateChannel(server_address_.str(), bad_creds);
yangg4105e2b2015-01-09 14:19:44 -0800640 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
641 grpc::cpp::test::util::TestService::NewStub(channel));
642 EchoRequest request;
643 EchoResponse response;
644 ClientContext context;
Yang Gao26a49122015-05-15 17:02:56 -0700645 request.set_message("Hello");
yangg4105e2b2015-01-09 14:19:44 -0800646
647 Status s = stub->Echo(&context, request, &response);
648 EXPECT_EQ("", response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700649 EXPECT_FALSE(s.ok());
yang-gc31cd862015-08-17 15:37:27 -0700650 EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
651 EXPECT_EQ("Invalid credentials.", s.error_message());
yangg4105e2b2015-01-09 14:19:44 -0800652
653 ClientContext context2;
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800654 auto stream = stub->BidiStream(&context2);
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800655 s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700656 EXPECT_FALSE(s.ok());
yang-gc31cd862015-08-17 15:37:27 -0700657 EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
658 EXPECT_EQ("Invalid credentials.", s.error_message());
yangg4105e2b2015-01-09 14:19:44 -0800659}
660
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700661void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
Craig Tiller20b5fe92015-07-06 10:43:50 -0700662 gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
Craig Tiller677c50c2015-07-13 10:49:06 -0700663 gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700664 while (!service->signal_client()) {
665 }
666 context->TryCancel();
667}
668
669// Client cancels rpc after 10ms
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700670TEST_P(End2endTest, ClientCancelsRpc) {
671 ResetStub(GetParam());
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700672 EchoRequest request;
673 EchoResponse response;
674 request.set_message("Hello");
675 const int kCancelDelayUs = 10 * 1000;
676 request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
677
678 ClientContext context;
679 std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
680 Status s = stub_->Echo(&context, request, &response);
681 cancel_thread.join();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700682 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
683 EXPECT_EQ(s.error_message(), "Cancelled");
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700684}
685
686// Server cancels rpc after 1ms
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700687TEST_P(End2endTest, ServerCancelsRpc) {
688 ResetStub(GetParam());
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700689 EchoRequest request;
690 EchoResponse response;
691 request.set_message("Hello");
692 request.mutable_param()->set_server_cancel_after_us(1000);
693
694 ClientContext context;
695 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700696 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
697 EXPECT_TRUE(s.error_message().empty());
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700698}
699
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700700// Client cancels request stream after sending two messages
701TEST_F(End2endTest, ClientCancelsRequestStream) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700702 ResetStub(false);
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700703 EchoRequest request;
704 EchoResponse response;
705 ClientContext context;
706 request.set_message("hello");
707
708 auto stream = stub_->RequestStream(&context, &response);
709 EXPECT_TRUE(stream->Write(request));
710 EXPECT_TRUE(stream->Write(request));
Yang Gaoc71a9d22015-05-04 00:22:12 -0700711
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700712 context.TryCancel();
713
714 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700715 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700716
Yang Gaoc71a9d22015-05-04 00:22:12 -0700717 EXPECT_EQ(response.message(), "");
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700718}
719
Abhishek Kumare41d0402015-04-17 14:12:33 -0700720// Client cancels server stream after sending some messages
Abhishek Kumara1d3a722015-04-23 10:24:04 -0700721TEST_F(End2endTest, ClientCancelsResponseStream) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700722 ResetStub(false);
Abhishek Kumare41d0402015-04-17 14:12:33 -0700723 EchoRequest request;
724 EchoResponse response;
725 ClientContext context;
726 request.set_message("hello");
727
728 auto stream = stub_->ResponseStream(&context, request);
729
730 EXPECT_TRUE(stream->Read(&response));
731 EXPECT_EQ(response.message(), request.message() + "0");
732 EXPECT_TRUE(stream->Read(&response));
733 EXPECT_EQ(response.message(), request.message() + "1");
734
735 context.TryCancel();
736
737 // The cancellation races with responses, so there might be zero or
738 // one responses pending, read till failure
739
740 if (stream->Read(&response)) {
741 EXPECT_EQ(response.message(), request.message() + "2");
742 // Since we have cancelled, we expect the next attempt to read to fail
743 EXPECT_FALSE(stream->Read(&response));
744 }
745
746 Status s = stream->Finish();
Abhishek Kumar18298a72015-04-17 15:00:25 -0700747 // The final status could be either of CANCELLED or OK depending on
748 // who won the race.
Yang Gaoc1a2c312015-06-16 10:59:46 -0700749 EXPECT_GE(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumare41d0402015-04-17 14:12:33 -0700750}
751
Abhishek Kumar82a83312015-04-17 13:30:51 -0700752// Client cancels bidi stream after sending some messages
753TEST_F(End2endTest, ClientCancelsBidi) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700754 ResetStub(false);
Abhishek Kumar82a83312015-04-17 13:30:51 -0700755 EchoRequest request;
756 EchoResponse response;
757 ClientContext context;
758 grpc::string msg("hello");
759
760 auto stream = stub_->BidiStream(&context);
761
762 request.set_message(msg + "0");
763 EXPECT_TRUE(stream->Write(request));
764 EXPECT_TRUE(stream->Read(&response));
765 EXPECT_EQ(response.message(), request.message());
766
767 request.set_message(msg + "1");
768 EXPECT_TRUE(stream->Write(request));
769
770 context.TryCancel();
771
772 // The cancellation races with responses, so there might be zero or
773 // one responses pending, read till failure
774
775 if (stream->Read(&response)) {
776 EXPECT_EQ(response.message(), request.message());
777 // Since we have cancelled, we expect the next attempt to read to fail
778 EXPECT_FALSE(stream->Read(&response));
779 }
780
781 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700782 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumar82a83312015-04-17 13:30:51 -0700783}
784
Yang Gao3921c562015-04-30 16:07:06 -0700785TEST_F(End2endTest, RpcMaxMessageSize) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700786 ResetStub(false);
Yang Gao3921c562015-04-30 16:07:06 -0700787 EchoRequest request;
788 EchoResponse response;
Yang Gaoc71a9d22015-05-04 00:22:12 -0700789 request.set_message(string(kMaxMessageSize_ * 2, 'a'));
Yang Gao3921c562015-04-30 16:07:06 -0700790
791 ClientContext context;
792 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700793 EXPECT_FALSE(s.ok());
Yang Gao3921c562015-04-30 16:07:06 -0700794}
Abhishek Kumar82a83312015-04-17 13:30:51 -0700795
yang-ge21908f2015-08-25 13:47:51 -0700796bool MetadataContains(
797 const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
798 const grpc::string& key, const grpc::string& value) {
Yang Gao26a49122015-05-15 17:02:56 -0700799 int count = 0;
800
yang-ge21908f2015-08-25 13:47:51 -0700801 for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
Yang Gao26a49122015-05-15 17:02:56 -0700802 metadata.begin();
803 iter != metadata.end(); ++iter) {
yang-ge21908f2015-08-25 13:47:51 -0700804 if (ToString(iter->first) == key && ToString(iter->second) == value) {
Yang Gao26a49122015-05-15 17:02:56 -0700805 count++;
806 }
807 }
808 return count == 1;
809}
810
Yang Gaoa8938922015-05-14 11:51:07 -0700811TEST_F(End2endTest, SetPerCallCredentials) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700812 ResetStub(false);
Yang Gaoa8938922015-05-14 11:51:07 -0700813 EchoRequest request;
814 EchoResponse response;
815 ClientContext context;
816 std::shared_ptr<Credentials> creds =
Julien Boeuf510a9202015-08-25 21:51:07 -0700817 GoogleIAMCredentials("fake_token", "fake_selector");
Yang Gaoa8938922015-05-14 11:51:07 -0700818 context.set_credentials(creds);
Yang Gao26a49122015-05-15 17:02:56 -0700819 request.set_message("Hello");
820 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -0700821
822 Status s = stub_->Echo(&context, request, &response);
Yang Gaoa8938922015-05-14 11:51:07 -0700823 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700824 EXPECT_TRUE(s.ok());
Yang Gao26a49122015-05-15 17:02:56 -0700825 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
826 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
827 "fake_token"));
828 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
829 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
830 "fake_selector"));
Yang Gaoa8938922015-05-14 11:51:07 -0700831}
832
833TEST_F(End2endTest, InsecurePerCallCredentials) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700834 ResetStub(false);
Yang Gaoa8938922015-05-14 11:51:07 -0700835 EchoRequest request;
836 EchoResponse response;
837 ClientContext context;
838 std::shared_ptr<Credentials> creds = InsecureCredentials();
839 context.set_credentials(creds);
Yang Gao26a49122015-05-15 17:02:56 -0700840 request.set_message("Hello");
841 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -0700842
843 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700844 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
845 EXPECT_EQ("Failed to set credentials to rpc.", s.error_message());
Yang Gaoa8938922015-05-14 11:51:07 -0700846}
847
848TEST_F(End2endTest, OverridePerCallCredentials) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700849 ResetStub(false);
Yang Gaoa8938922015-05-14 11:51:07 -0700850 EchoRequest request;
851 EchoResponse response;
852 ClientContext context;
Yang Gao26a49122015-05-15 17:02:56 -0700853 std::shared_ptr<Credentials> creds1 =
Julien Boeuf510a9202015-08-25 21:51:07 -0700854 GoogleIAMCredentials("fake_token1", "fake_selector1");
Yang Gaoa8938922015-05-14 11:51:07 -0700855 context.set_credentials(creds1);
856 std::shared_ptr<Credentials> creds2 =
Julien Boeuf510a9202015-08-25 21:51:07 -0700857 GoogleIAMCredentials("fake_token2", "fake_selector2");
Yang Gaoa8938922015-05-14 11:51:07 -0700858 context.set_credentials(creds2);
Yang Gao26a49122015-05-15 17:02:56 -0700859 request.set_message("Hello");
860 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -0700861
862 Status s = stub_->Echo(&context, request, &response);
Yang Gao26a49122015-05-15 17:02:56 -0700863 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
864 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
865 "fake_token2"));
866 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
867 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
868 "fake_selector2"));
Yang Gaob57f72d2015-05-17 21:54:54 -0700869 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
870 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
871 "fake_token1"));
872 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
873 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
874 "fake_selector1"));
Yang Gaoa8938922015-05-14 11:51:07 -0700875 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700876 EXPECT_TRUE(s.ok());
Yang Gaoa8938922015-05-14 11:51:07 -0700877}
878
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700879TEST_F(End2endTest, NonBlockingAuthMetadataProcessorSuccess) {
880 auto* processor = new TestAuthMetadataProcessor(false);
881 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
882 ResetStub(false);
883 EchoRequest request;
884 EchoResponse response;
885 ClientContext context;
886 context.set_credentials(processor->GetCompatibleClientCreds());
887 request.set_message("Hello");
888 request.mutable_param()->set_echo_metadata(true);
889 request.mutable_param()->set_expected_client_identity(
890 TestAuthMetadataProcessor::kGoodGuy);
891
892 Status s = stub_->Echo(&context, request, &response);
893 EXPECT_EQ(request.message(), response.message());
894 EXPECT_TRUE(s.ok());
895
896 // Metadata should have been consumed by the processor.
897 EXPECT_FALSE(MetadataContains(
898 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
899 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
900}
901
902TEST_F(End2endTest, NonBlockingAuthMetadataProcessorFailure) {
903 auto* processor = new TestAuthMetadataProcessor(false);
904 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
905 ResetStub(false);
906 EchoRequest request;
907 EchoResponse response;
908 ClientContext context;
909 context.set_credentials(processor->GetIncompatibleClientCreds());
910 request.set_message("Hello");
911
912 Status s = stub_->Echo(&context, request, &response);
913 EXPECT_FALSE(s.ok());
914 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
915}
916
917TEST_F(End2endTest, BlockingAuthMetadataProcessorSuccess) {
918 auto* processor = new TestAuthMetadataProcessor(true);
919 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
920 ResetStub(false);
921 EchoRequest request;
922 EchoResponse response;
923 ClientContext context;
924 context.set_credentials(processor->GetCompatibleClientCreds());
925 request.set_message("Hello");
926 request.mutable_param()->set_echo_metadata(true);
927 request.mutable_param()->set_expected_client_identity(
928 TestAuthMetadataProcessor::kGoodGuy);
929
930 Status s = stub_->Echo(&context, request, &response);
931 EXPECT_EQ(request.message(), response.message());
932 EXPECT_TRUE(s.ok());
933
934 // Metadata should have been consumed by the processor.
935 EXPECT_FALSE(MetadataContains(
936 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
937 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
938}
939
940TEST_F(End2endTest, BlockingAuthMetadataProcessorFailure) {
941 auto* processor = new TestAuthMetadataProcessor(true);
942 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
943 ResetStub(false);
944 EchoRequest request;
945 EchoResponse response;
946 ClientContext context;
947 context.set_credentials(processor->GetIncompatibleClientCreds());
948 request.set_message("Hello");
949
950 Status s = stub_->Echo(&context, request, &response);
951 EXPECT_FALSE(s.ok());
952 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
953}
954
yang-g0b6ad7d2015-06-25 14:39:01 -0700955// Client sends 20 requests and the server returns CANCELLED status after
956// reading 10 requests.
957TEST_F(End2endTest, RequestStreamServerEarlyCancelTest) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700958 ResetStub(false);
yang-g0b6ad7d2015-06-25 14:39:01 -0700959 EchoRequest request;
960 EchoResponse response;
961 ClientContext context;
962
963 context.AddMetadata(kServerCancelAfterReads, "10");
964 auto stream = stub_->RequestStream(&context, &response);
965 request.set_message("hello");
966 int send_messages = 20;
967 while (send_messages > 0) {
968 EXPECT_TRUE(stream->Write(request));
969 send_messages--;
970 }
971 stream->WritesDone();
972 Status s = stream->Finish();
973 EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
974}
975
yang-gc4eef2e2015-07-06 23:26:58 -0700976TEST_F(End2endTest, ClientAuthContext) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700977 ResetStub(false);
yang-gc4eef2e2015-07-06 23:26:58 -0700978 EchoRequest request;
979 EchoResponse response;
980 request.set_message("Hello");
981 request.mutable_param()->set_check_auth_context(true);
982
983 ClientContext context;
984 Status s = stub_->Echo(&context, request, &response);
985 EXPECT_EQ(response.message(), request.message());
986 EXPECT_TRUE(s.ok());
987
yang-g8b25f2a2015-07-21 23:54:36 -0700988 std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
yang-gd090fe12015-08-25 16:53:07 -0700989 std::vector<grpc::string_ref> ssl =
yang-g8b25f2a2015-07-21 23:54:36 -0700990 auth_ctx->FindPropertyValues("transport_security_type");
991 EXPECT_EQ(1u, ssl.size());
yang-gd090fe12015-08-25 16:53:07 -0700992 EXPECT_EQ("ssl", ToString(ssl[0]));
yang-g8b25f2a2015-07-21 23:54:36 -0700993 EXPECT_EQ("x509_subject_alternative_name",
994 auth_ctx->GetPeerIdentityPropertyName());
995 EXPECT_EQ(3u, auth_ctx->GetPeerIdentity().size());
yang-gd090fe12015-08-25 16:53:07 -0700996 EXPECT_EQ("*.test.google.fr", ToString(auth_ctx->GetPeerIdentity()[0]));
997 EXPECT_EQ("waterzooi.test.google.be",
998 ToString(auth_ctx->GetPeerIdentity()[1]));
999 EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2]));
yang-gc4eef2e2015-07-06 23:26:58 -07001000}
1001
yang-g6f30dec2015-07-22 23:11:56 -07001002// Make the response larger than the flow control window.
Craig Tiller2c3be1d2015-08-05 15:59:27 -07001003TEST_P(End2endTest, HugeResponse) {
1004 ResetStub(GetParam());
yang-g6f30dec2015-07-22 23:11:56 -07001005 EchoRequest request;
1006 EchoResponse response;
1007 request.set_message("huge response");
vjpai51d22752015-07-24 14:11:04 -07001008 const size_t kResponseSize = 1024 * (1024 + 10);
yang-g6f30dec2015-07-22 23:11:56 -07001009 request.mutable_param()->set_response_message_length(kResponseSize);
1010
1011 ClientContext context;
1012 Status s = stub_->Echo(&context, request, &response);
1013 EXPECT_EQ(kResponseSize, response.message().size());
1014 EXPECT_TRUE(s.ok());
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001015}
1016
yang-g8ab38362015-07-31 14:05:33 -07001017namespace {
yang-g36f59652015-08-05 15:15:18 -07001018void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
Craig Tillerd6c98df2015-08-18 09:33:44 -07001019 gpr_event* ev) {
yang-g8ab38362015-07-31 14:05:33 -07001020 EchoResponse resp;
Craig Tiller7c1be052015-07-31 15:38:37 -07001021 gpr_event_set(ev, (void*)1);
yang-g8ab38362015-07-31 14:05:33 -07001022 while (stream->Read(&resp)) {
1023 gpr_log(GPR_INFO, "Read message");
1024 }
1025}
1026} // namespace
1027
1028// Run a Read and a WritesDone simultaneously.
Craig Tillerfb21ae62015-08-03 10:16:11 -07001029TEST_F(End2endTest, SimultaneousReadWritesDone) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -07001030 ResetStub(false);
yang-g8ab38362015-07-31 14:05:33 -07001031 ClientContext context;
Craig Tiller7c1be052015-07-31 15:38:37 -07001032 gpr_event ev;
1033 gpr_event_init(&ev);
yang-g8ab38362015-07-31 14:05:33 -07001034 auto stream = stub_->BidiStream(&context);
Craig Tiller7c1be052015-07-31 15:38:37 -07001035 std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
1036 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
yang-g8ab38362015-07-31 14:05:33 -07001037 stream->WritesDone();
1038 Status s = stream->Finish();
1039 EXPECT_TRUE(s.ok());
1040 reader_thread.join();
1041}
1042
Craig Tiller2c3be1d2015-08-05 15:59:27 -07001043TEST_P(End2endTest, Peer) {
1044 ResetStub(GetParam());
yang-gd7ead692015-07-30 10:57:45 -07001045 EchoRequest request;
1046 EchoResponse response;
1047 request.set_message("hello");
1048 request.mutable_param()->set_echo_peer(true);
1049
1050 ClientContext context;
1051 Status s = stub_->Echo(&context, request, &response);
1052 EXPECT_EQ(response.message(), request.message());
1053 EXPECT_TRUE(s.ok());
1054 EXPECT_TRUE(CheckIsLocalhost(response.param().peer()));
1055 EXPECT_TRUE(CheckIsLocalhost(context.peer()));
1056}
1057
yang-g36f59652015-08-05 15:15:18 -07001058TEST_F(End2endTest, ChannelState) {
yang-gcec757f2015-08-06 22:53:58 -07001059 ResetStub(false);
yang-g36f59652015-08-05 15:15:18 -07001060 // Start IDLE
1061 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
1062
yang-g8708dd72015-08-05 15:57:14 -07001063 // Did not ask to connect, no state change.
yang-g36f59652015-08-05 15:15:18 -07001064 CompletionQueue cq;
1065 std::chrono::system_clock::time_point deadline =
1066 std::chrono::system_clock::now() + std::chrono::milliseconds(10);
yang-g36f59652015-08-05 15:15:18 -07001067 channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL);
1068 void* tag;
1069 bool ok = true;
1070 cq.Next(&tag, &ok);
1071 EXPECT_FALSE(ok);
1072
1073 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true));
Craig Tillerd6c98df2015-08-18 09:33:44 -07001074 EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE,
1075 gpr_inf_future(GPR_CLOCK_REALTIME)));
yang-g36f59652015-08-05 15:15:18 -07001076 EXPECT_EQ(GRPC_CHANNEL_CONNECTING, channel_->GetState(false));
1077}
1078
yang-gd886f332015-09-18 01:24:14 -07001079// Takes 10s.
1080TEST_F(End2endTest, ChannelStateTimeout) {
1081 int port = grpc_pick_unused_port_or_die();
1082 std::ostringstream server_address;
1083 server_address << "127.0.0.1:" << port;
1084 // Channel to non-existing server
1085 auto channel = CreateChannel(server_address.str(), InsecureCredentials());
1086 // Start IDLE
1087 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
1088
1089 auto state = GRPC_CHANNEL_IDLE;
1090 for (int i = 0; i < 10; i++) {
1091 channel->WaitForStateChange(state, std::chrono::system_clock::now() +
1092 std::chrono::milliseconds(1000));
1093 state = channel->GetState(false);
1094 }
1095}
1096
yang-g9b7757d2015-08-13 11:15:53 -07001097// Talking to a non-existing service.
1098TEST_F(End2endTest, NonExistingService) {
1099 ResetChannel();
1100 std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub;
Nicolas "Pixel" Noble7fa51672015-09-02 02:29:09 +02001101 stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_);
yang-g9b7757d2015-08-13 11:15:53 -07001102
1103 EchoRequest request;
1104 EchoResponse response;
1105 request.set_message("Hello");
1106
1107 ClientContext context;
1108 Status s = stub->Unimplemented(&context, request, &response);
1109 EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
1110 EXPECT_EQ("", s.error_message());
1111}
1112
Craig Tiller2c3be1d2015-08-05 15:59:27 -07001113INSTANTIATE_TEST_CASE_P(End2end, End2endTest, ::testing::Values(false, true));
1114
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001115} // namespace testing
1116} // namespace grpc
1117
1118int main(int argc, char** argv) {
1119 grpc_test_init(argc, argv);
1120 ::testing::InitGoogleTest(&argc, argv);
1121 return RUN_ALL_TESTS();
1122}