blob: a46f9f268bc6bfa74d6eb94fddb51fa6c63e64a1 [file] [log] [blame]
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001/*
2 *
Craig Tiller6169d5f2016-03-31 07:46:18 -07003 * 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++/channel.h>
38#include <grpc++/client_context.h>
39#include <grpc++/create_channel.h>
Julien Boeuf5be92a32015-08-28 16:28:18 -070040#include <grpc++/security/auth_metadata_processor.h>
41#include <grpc++/security/credentials.h>
42#include <grpc++/security/server_credentials.h>
yang-g9e2f90c2015-08-21 15:35:03 -070043#include <grpc++/server.h>
44#include <grpc++/server_builder.h>
45#include <grpc++/server_context.h>
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080046#include <grpc/grpc.h>
David Garcia Quintasc79b0652016-07-27 21:11:58 -070047#include <grpc/support/log.h>
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080048#include <grpc/support/thd.h>
49#include <grpc/support/time.h>
yang-g9e2f90c2015-08-21 15:35:03 -070050#include <gtest/gtest.h>
51
Julien Boeuf8ca294e2016-05-02 14:56:30 -070052#include "src/core/lib/security/credentials/credentials.h"
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080053#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
54#include "src/proto/grpc/testing/echo.grpc.pb.h"
Nicolas Noble89219162015-04-07 18:01:18 -070055#include "test/core/util/port.h"
Craig Tiller14e60e92015-01-13 17:26:46 -080056#include "test/core/util/test_config.h"
yang-g7b0edbd2016-02-02 16:05:21 -080057#include "test/cpp/end2end/test_service_impl.h"
yang-ge21908f2015-08-25 13:47:51 -070058#include "test/cpp/util/string_ref_helper.h"
yang-g7d2a3e12016-02-18 15:41:56 -080059#include "test/cpp/util/test_credentials_provider.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080060
Craig Tiller1b4e3302015-12-17 16:35:00 -080061using grpc::testing::EchoRequest;
62using grpc::testing::EchoResponse;
Dan Bornf2f7d572016-03-03 17:26:12 -080063using grpc::testing::kTlsCredentialsType;
yangged5e7e02015-01-06 10:16:15 -080064using std::chrono::system_clock;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080065
66namespace grpc {
yangged5e7e02015-01-06 10:16:15 -080067namespace testing {
yangged5e7e02015-01-06 10:16:15 -080068namespace {
69
yang-gd7ead692015-07-30 10:57:45 -070070bool CheckIsLocalhost(const grpc::string& addr) {
71 const grpc::string kIpv6("ipv6:[::1]:");
72 const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
73 const grpc::string kIpv4("ipv4:127.0.0.1:");
74 return addr.substr(0, kIpv4.size()) == kIpv4 ||
75 addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 ||
76 addr.substr(0, kIpv6.size()) == kIpv6;
77}
78
Julien Boeuf38c0cde2016-06-06 14:46:08 +020079const char kTestCredsPluginErrorMsg[] = "Could not find plugin metadata.";
80
Julien Boeuf1928d492015-09-15 15:20:11 -070081class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin {
82 public:
yang-gc580af32016-09-15 15:28:38 -070083 static const char kGoodMetadataKey[];
84 static const char kBadMetadataKey[];
Julien Boeuf1928d492015-09-15 15:20:11 -070085
yang-gc580af32016-09-15 15:28:38 -070086 TestMetadataCredentialsPlugin(grpc::string_ref metadata_key,
87 grpc::string_ref metadata_value,
Julien Boeuf1928d492015-09-15 15:20:11 -070088 bool is_blocking, bool is_successful)
yang-gc580af32016-09-15 15:28:38 -070089 : metadata_key_(metadata_key.data(), metadata_key.length()),
90 metadata_value_(metadata_value.data(), metadata_value.length()),
Julien Boeuf1928d492015-09-15 15:20:11 -070091 is_blocking_(is_blocking),
92 is_successful_(is_successful) {}
93
94 bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
95
Julien Boeuf114f3942015-11-19 21:45:52 -080096 Status GetMetadata(grpc::string_ref service_url, grpc::string_ref method_name,
97 const grpc::AuthContext& channel_auth_context,
Julien Boeuf8b0b6f42015-09-22 13:31:16 -070098 std::multimap<grpc::string, grpc::string>* metadata)
Julien Boeuf1928d492015-09-15 15:20:11 -070099 GRPC_OVERRIDE {
100 EXPECT_GT(service_url.length(), 0UL);
Julien Boeuf114f3942015-11-19 21:45:52 -0800101 EXPECT_GT(method_name.length(), 0UL);
102 EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated());
Julien Boeuf1928d492015-09-15 15:20:11 -0700103 EXPECT_TRUE(metadata != nullptr);
104 if (is_successful_) {
yang-gc580af32016-09-15 15:28:38 -0700105 metadata->insert(std::make_pair(metadata_key_, metadata_value_));
Julien Boeuf1928d492015-09-15 15:20:11 -0700106 return Status::OK;
107 } else {
Julien Boeuf38c0cde2016-06-06 14:46:08 +0200108 return Status(StatusCode::NOT_FOUND, kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -0700109 }
110 }
111
112 private:
yang-gc580af32016-09-15 15:28:38 -0700113 grpc::string metadata_key_;
Julien Boeuf1928d492015-09-15 15:20:11 -0700114 grpc::string metadata_value_;
115 bool is_blocking_;
116 bool is_successful_;
117};
118
yang-gc580af32016-09-15 15:28:38 -0700119const char TestMetadataCredentialsPlugin::kBadMetadataKey[] =
120 "TestPluginMetadata";
121const char TestMetadataCredentialsPlugin::kGoodMetadataKey[] =
122 "test-plugin-metadata";
Julien Boeuf1928d492015-09-15 15:20:11 -0700123
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700124class TestAuthMetadataProcessor : public AuthMetadataProcessor {
125 public:
126 static const char kGoodGuy[];
127
128 TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
129
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700130 std::shared_ptr<CallCredentials> GetCompatibleClientCreds() {
Julien Boeuf1928d492015-09-15 15:20:11 -0700131 return MetadataCredentialsFromPlugin(
132 std::unique_ptr<MetadataCredentialsPlugin>(
yang-gc580af32016-09-15 15:28:38 -0700133 new TestMetadataCredentialsPlugin(
134 TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy,
135 is_blocking_, true)));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700136 }
Julien Boeuf1928d492015-09-15 15:20:11 -0700137
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700138 std::shared_ptr<CallCredentials> GetIncompatibleClientCreds() {
Julien Boeuf1928d492015-09-15 15:20:11 -0700139 return MetadataCredentialsFromPlugin(
140 std::unique_ptr<MetadataCredentialsPlugin>(
yang-gc580af32016-09-15 15:28:38 -0700141 new TestMetadataCredentialsPlugin(
142 TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde",
143 is_blocking_, true)));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700144 }
145
146 // Interface implementation
147 bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
148
149 Status Process(const InputMetadata& auth_metadata, AuthContext* context,
150 OutputMetadata* consumed_auth_metadata,
151 OutputMetadata* response_metadata) GRPC_OVERRIDE {
152 EXPECT_TRUE(consumed_auth_metadata != nullptr);
153 EXPECT_TRUE(context != nullptr);
154 EXPECT_TRUE(response_metadata != nullptr);
Julien Boeuf1928d492015-09-15 15:20:11 -0700155 auto auth_md =
yang-gc580af32016-09-15 15:28:38 -0700156 auth_metadata.find(TestMetadataCredentialsPlugin::kGoodMetadataKey);
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700157 EXPECT_NE(auth_md, auth_metadata.end());
158 string_ref auth_md_value = auth_md->second;
Julien Boeuf1928d492015-09-15 15:20:11 -0700159 if (auth_md_value == kGoodGuy) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700160 context->AddProperty(kIdentityPropName, kGoodGuy);
161 context->SetPeerIdentityPropertyName(kIdentityPropName);
Julien Boeuf8b0b6f42015-09-22 13:31:16 -0700162 consumed_auth_metadata->insert(std::make_pair(
163 string(auth_md->first.data(), auth_md->first.length()),
164 string(auth_md->second.data(), auth_md->second.length())));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700165 return Status::OK;
166 } else {
167 return Status(StatusCode::UNAUTHENTICATED,
168 string("Invalid principal: ") +
169 string(auth_md_value.data(), auth_md_value.length()));
170 }
171 }
172
Julien Boeuf1928d492015-09-15 15:20:11 -0700173 private:
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700174 static const char kIdentityPropName[];
175 bool is_blocking_;
176};
177
178const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll";
179const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
180
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800181class Proxy : public ::grpc::testing::EchoTestService::Service {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700182 public:
yang-g8c2be9f2015-08-19 16:28:09 -0700183 Proxy(std::shared_ptr<Channel> channel)
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800184 : stub_(grpc::testing::EchoTestService::NewStub(channel)) {}
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700185
186 Status Echo(ServerContext* server_context, const EchoRequest* request,
187 EchoResponse* response) GRPC_OVERRIDE {
188 std::unique_ptr<ClientContext> client_context =
189 ClientContext::FromServerContext(*server_context);
190 return stub_->Echo(client_context.get(), *request, response);
191 }
192
193 private:
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800194 std::unique_ptr< ::grpc::testing::EchoTestService::Stub> stub_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700195};
196
yangg1456d152015-01-08 15:39:58 -0800197class TestServiceImplDupPkg
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800198 : public ::grpc::testing::duplicate::EchoTestService::Service {
yangg1456d152015-01-08 15:39:58 -0800199 public:
200 Status Echo(ServerContext* context, const EchoRequest* request,
Craig Tillercf133f42015-02-26 14:05:56 -0800201 EchoResponse* response) GRPC_OVERRIDE {
yangg1456d152015-01-08 15:39:58 -0800202 response->set_message("no package");
203 return Status::OK;
204 }
205};
206
yang-g88d5d522015-09-29 12:46:54 -0700207class TestScenario {
208 public:
yang-g17197dd2016-02-19 00:04:22 -0800209 TestScenario(bool proxy, const grpc::string& creds_type)
210 : use_proxy(proxy), credentials_type(creds_type) {}
yang-g88d5d522015-09-29 12:46:54 -0700211 void Log() const {
yang-g7d2a3e12016-02-18 15:41:56 -0800212 gpr_log(GPR_INFO, "Scenario: proxy %d, credentials %s", use_proxy,
yang-g17197dd2016-02-19 00:04:22 -0800213 credentials_type.c_str());
yang-g88d5d522015-09-29 12:46:54 -0700214 }
215 bool use_proxy;
Vijay Pai679c75f2016-06-15 13:08:00 -0700216 // Although the below grpc::string is logically const, we can't declare
217 // them const because of a limitation in the way old compilers (e.g., gcc-4.4)
218 // manage vector insertion using a copy constructor
219 grpc::string credentials_type;
yang-g88d5d522015-09-29 12:46:54 -0700220};
221
222class End2endTest : public ::testing::TestWithParam<TestScenario> {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800223 protected:
Vijay Pai181ef452015-07-14 13:52:48 -0700224 End2endTest()
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700225 : is_server_started_(false),
226 kMaxMessageSize_(8192),
yang-g88d5d522015-09-29 12:46:54 -0700227 special_service_("special") {
228 GetParam().Log();
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700229
230 sync_server_settings_.max_pollers = INT_MAX;
231 sync_server_settings_.min_pollers = 1;
232 sync_server_settings_.cq_timeout_msec = 10;
233 sync_server_settings_.num_cqs = 4;
yang-g88d5d522015-09-29 12:46:54 -0700234 }
Craig Tiller7418d012015-02-11 15:25:03 -0800235
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700236 void TearDown() GRPC_OVERRIDE {
237 if (is_server_started_) {
238 server_->Shutdown();
239 if (proxy_server_) proxy_server_->Shutdown();
240 }
241 }
242
243 void StartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) {
Craig Tiller35e39712015-01-12 16:41:24 -0800244 int port = grpc_pick_unused_port_or_die();
yang-gd7ead692015-07-30 10:57:45 -0700245 server_address_ << "127.0.0.1:" << port;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800246 // Setup server
247 ServerBuilder builder;
yang-g7d2a3e12016-02-18 15:41:56 -0800248 auto server_creds = GetServerCredentials(GetParam().credentials_type);
yang-g17197dd2016-02-19 00:04:22 -0800249 if (GetParam().credentials_type != kInsecureCredentialsType) {
yang-g88d5d522015-09-29 12:46:54 -0700250 server_creds->SetAuthMetadataProcessor(processor);
251 }
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700252 builder.AddListeningPort(server_address_.str(), server_creds);
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800253 builder.RegisterService(&service_);
yang-g8b25f2a2015-07-21 23:54:36 -0700254 builder.RegisterService("foo.test.youtube.com", &special_service_);
Yang Gaoc71a9d22015-05-04 00:22:12 -0700255 builder.SetMaxMessageSize(
256 kMaxMessageSize_); // For testing max message size.
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800257 builder.RegisterService(&dup_pkg_service_);
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700258
259 builder.SetSyncServerSettings(sync_server_settings_);
260
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800261 server_ = builder.BuildAndStart();
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700262 is_server_started_ = true;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700263 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800264
yang-g9b7757d2015-08-13 11:15:53 -0700265 void ResetChannel() {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700266 if (!is_server_started_) {
267 StartServer(std::shared_ptr<AuthMetadataProcessor>());
268 }
269 EXPECT_TRUE(is_server_started_);
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700270 ChannelArguments args;
yang-g7d2a3e12016-02-18 15:41:56 -0800271 auto channel_creds =
272 GetChannelCredentials(GetParam().credentials_type, &args);
yang-gd59ad7e2016-02-10 12:42:53 -0800273 if (!user_agent_prefix_.empty()) {
274 args.SetUserAgentPrefix(user_agent_prefix_);
275 }
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700276 args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
yang-g88d5d522015-09-29 12:46:54 -0700277 channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args);
yang-g9b7757d2015-08-13 11:15:53 -0700278 }
279
yang-g88d5d522015-09-29 12:46:54 -0700280 void ResetStub() {
yang-g9b7757d2015-08-13 11:15:53 -0700281 ResetChannel();
yang-g88d5d522015-09-29 12:46:54 -0700282 if (GetParam().use_proxy) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700283 proxy_service_.reset(new Proxy(channel_));
284 int port = grpc_pick_unused_port_or_die();
285 std::ostringstream proxyaddr;
286 proxyaddr << "localhost:" << port;
287 ServerBuilder builder;
288 builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials());
289 builder.RegisterService(proxy_service_.get());
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700290 builder.SetSyncServerSettings(sync_server_settings_);
291
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700292 proxy_server_ = builder.BuildAndStart();
293
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700294 channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials());
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700295 }
296
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800297 stub_ = grpc::testing::EchoTestService::NewStub(channel_);
yangg1456d152015-01-08 15:39:58 -0800298 }
299
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700300 bool is_server_started_;
yang-g8c2be9f2015-08-19 16:28:09 -0700301 std::shared_ptr<Channel> channel_;
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800302 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800303 std::unique_ptr<Server> server_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700304 std::unique_ptr<Server> proxy_server_;
305 std::unique_ptr<Proxy> proxy_service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800306 std::ostringstream server_address_;
Yang Gao3921c562015-04-30 16:07:06 -0700307 const int kMaxMessageSize_;
nnoble0c475f02014-12-05 15:37:39 -0800308 TestServiceImpl service_;
Craig Tiller822d2c72015-07-07 16:08:00 -0700309 TestServiceImpl special_service_;
yangg1456d152015-01-08 15:39:58 -0800310 TestServiceImplDupPkg dup_pkg_service_;
yang-gd59ad7e2016-02-10 12:42:53 -0800311 grpc::string user_agent_prefix_;
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700312 ServerBuilder::SyncServerSettings sync_server_settings_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800313};
314
yang-gf8174ea2016-02-01 00:09:13 -0800315static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs,
316 bool with_binary_metadata) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800317 EchoRequest request;
318 EchoResponse response;
David Garcia Quintasd7d9ce22015-06-30 23:29:03 -0700319 request.set_message("Hello hello hello hello");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800320
321 for (int i = 0; i < num_rpcs; ++i) {
322 ClientContext context;
yang-gf8174ea2016-02-01 00:09:13 -0800323 if (with_binary_metadata) {
324 char bytes[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', (char)i};
325 context.AddMetadata("custom-bin", grpc::string(bytes, 8));
326 }
Craig Tillerbf6abee2015-07-19 22:31:04 -0700327 context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800328 Status s = stub->Echo(&context, request, &response);
329 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700330 EXPECT_TRUE(s.ok());
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800331 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800332}
333
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800334// This class is for testing scenarios where RPCs are cancelled on the server
335// by calling ServerContext::TryCancel()
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800336class End2endServerTryCancelTest : public End2endTest {
337 protected:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800338 // Helper for testing client-streaming RPCs which are cancelled on the server.
339 // Depending on the value of server_try_cancel parameter, this will test one
340 // of the following three scenarios:
341 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading
342 // any messages from the client
343 //
344 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading
345 // messages from the client
346 //
347 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all
348 // the messages from the client
349 //
350 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800351 void TestRequestStreamServerCancel(
352 ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) {
353 ResetStub();
354 EchoRequest request;
355 EchoResponse response;
356 ClientContext context;
357
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800358 // Send server_try_cancel value in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800359 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700360 grpc::to_string(server_try_cancel));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800361
362 auto stream = stub_->RequestStream(&context, &response);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800363
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800364 int num_msgs_sent = 0;
365 while (num_msgs_sent < num_msgs_to_send) {
366 request.set_message("hello");
367 if (!stream->Write(request)) {
368 break;
369 }
370 num_msgs_sent++;
371 }
372 gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800373
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800374 stream->WritesDone();
375 Status s = stream->Finish();
376
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800377 // At this point, we know for sure that RPC was cancelled by the server
378 // since we passed server_try_cancel value in the metadata. Depending on the
379 // value of server_try_cancel, the RPC might have been cancelled by the
380 // server at different stages. The following validates our expectations of
381 // number of messages sent in various cancellation scenarios:
382
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800383 switch (server_try_cancel) {
384 case CANCEL_BEFORE_PROCESSING:
385 case CANCEL_DURING_PROCESSING:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800386 // If the RPC is cancelled by server before / during messages from the
387 // client, it means that the client most likely did not get a chance to
388 // send all the messages it wanted to send. i.e num_msgs_sent <=
389 // num_msgs_to_send
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800390 EXPECT_LE(num_msgs_sent, num_msgs_to_send);
391 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800392
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800393 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800394 // If the RPC was cancelled after all messages were read by the server,
395 // the client did get a chance to send all its messages
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800396 EXPECT_EQ(num_msgs_sent, num_msgs_to_send);
397 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800398
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800399 default:
400 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
401 server_try_cancel);
402 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
403 server_try_cancel <= CANCEL_AFTER_PROCESSING);
404 break;
405 }
406
407 EXPECT_FALSE(s.ok());
408 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
409 }
410
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800411 // Helper for testing server-streaming RPCs which are cancelled on the server.
412 // Depending on the value of server_try_cancel parameter, this will test one
413 // of the following three scenarios:
414 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before writing
415 // any messages to the client
416 //
417 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while writing
418 // messages to the client
419 //
420 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after writing all
421 // the messages to the client
422 //
423 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800424 void TestResponseStreamServerCancel(
425 ServerTryCancelRequestPhase server_try_cancel) {
426 ResetStub();
427 EchoRequest request;
428 EchoResponse response;
429 ClientContext context;
430
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800431 // Send server_try_cancel in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800432 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700433 grpc::to_string(server_try_cancel));
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800434
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800435 request.set_message("hello");
436 auto stream = stub_->ResponseStream(&context, request);
437
438 int num_msgs_read = 0;
439 while (num_msgs_read < kNumResponseStreamsMsgs) {
440 if (!stream->Read(&response)) {
441 break;
442 }
443 EXPECT_EQ(response.message(),
Vijay Paia63271c2016-06-15 12:56:38 -0700444 request.message() + grpc::to_string(num_msgs_read));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800445 num_msgs_read++;
446 }
447 gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
448
449 Status s = stream->Finish();
450
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800451 // Depending on the value of server_try_cancel, the RPC might have been
452 // cancelled by the server at different stages. The following validates our
453 // expectations of number of messages read in various cancellation
454 // scenarios:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800455 switch (server_try_cancel) {
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800456 case CANCEL_BEFORE_PROCESSING:
457 // Server cancelled before sending any messages. Which means the client
458 // wouldn't have read any
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800459 EXPECT_EQ(num_msgs_read, 0);
460 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800461
462 case CANCEL_DURING_PROCESSING:
463 // Server cancelled while writing messages. Client must have read less
464 // than or equal to the expected number of messages
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800465 EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
466 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800467
468 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla8d543e82016-02-29 18:22:25 -0800469 // Even though the Server cancelled after writing all messages, the RPC
470 // may be cancelled before the Client got a chance to read all the
471 // messages.
472 EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800473 break;
474
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800475 default: {
476 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
477 server_try_cancel);
478 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
479 server_try_cancel <= CANCEL_AFTER_PROCESSING);
480 break;
481 }
482 }
483
484 EXPECT_FALSE(s.ok());
485 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
486 }
487
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800488 // Helper for testing bidirectional-streaming RPCs which are cancelled on the
489 // server. Depending on the value of server_try_cancel parameter, this will
490 // test one of the following three scenarios:
491 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/
492 // writing any messages from/to the client
493 //
494 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading/
495 // writing messages from/to the client
496 //
497 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading/writing
498 // all the messages from/to the client
499 //
500 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800501 void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel,
502 int num_messages) {
503 ResetStub();
504 EchoRequest request;
505 EchoResponse response;
506 ClientContext context;
507
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800508 // Send server_try_cancel in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800509 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700510 grpc::to_string(server_try_cancel));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800511
512 auto stream = stub_->BidiStream(&context);
513
514 int num_msgs_read = 0;
515 int num_msgs_sent = 0;
516 while (num_msgs_sent < num_messages) {
Vijay Paia63271c2016-06-15 12:56:38 -0700517 request.set_message("hello " + grpc::to_string(num_msgs_sent));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800518 if (!stream->Write(request)) {
519 break;
520 }
521 num_msgs_sent++;
522
523 if (!stream->Read(&response)) {
524 break;
525 }
526 num_msgs_read++;
527
528 EXPECT_EQ(response.message(), request.message());
529 }
530 gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
531 gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
532
533 stream->WritesDone();
534 Status s = stream->Finish();
535
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800536 // Depending on the value of server_try_cancel, the RPC might have been
537 // cancelled by the server at different stages. The following validates our
538 // expectations of number of messages read in various cancellation
539 // scenarios:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800540 switch (server_try_cancel) {
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800541 case CANCEL_BEFORE_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800542 EXPECT_EQ(num_msgs_read, 0);
543 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800544
545 case CANCEL_DURING_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800546 EXPECT_LE(num_msgs_sent, num_messages);
547 EXPECT_LE(num_msgs_read, num_msgs_sent);
548 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800549
550 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800551 EXPECT_EQ(num_msgs_sent, num_messages);
Sree Kuchibhotla8d543e82016-02-29 18:22:25 -0800552
553 // The Server cancelled after reading the last message and after writing
554 // the message to the client. However, the RPC cancellation might have
555 // taken effect before the client actually read the response.
556 EXPECT_LE(num_msgs_read, num_msgs_sent);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800557 break;
558
559 default:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800560 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
561 server_try_cancel);
562 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
563 server_try_cancel <= CANCEL_AFTER_PROCESSING);
564 break;
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800565 }
566
567 EXPECT_FALSE(s.ok());
568 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
569 }
570};
571
572TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) {
573 ResetStub();
574 EchoRequest request;
575 EchoResponse response;
576 ClientContext context;
577
578 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700579 grpc::to_string(CANCEL_BEFORE_PROCESSING));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800580 Status s = stub_->Echo(&context, request, &response);
581 EXPECT_FALSE(s.ok());
582 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
583}
584
585// Server to cancel before doing reading the request
586TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelBeforeReads) {
587 TestRequestStreamServerCancel(CANCEL_BEFORE_PROCESSING, 1);
588}
589
590// Server to cancel while reading a request from the stream in parallel
591TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelDuringRead) {
592 TestRequestStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
593}
594
595// Server to cancel after reading all the requests but before returning to the
596// client
597TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelAfterReads) {
598 TestRequestStreamServerCancel(CANCEL_AFTER_PROCESSING, 4);
599}
600
601// Server to cancel before sending any response messages
602TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelBefore) {
603 TestResponseStreamServerCancel(CANCEL_BEFORE_PROCESSING);
604}
605
606// Server to cancel while writing a response to the stream in parallel
607TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelDuring) {
608 TestResponseStreamServerCancel(CANCEL_DURING_PROCESSING);
609}
610
611// Server to cancel after writing all the respones to the stream but before
612// returning to the client
613TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelAfter) {
614 TestResponseStreamServerCancel(CANCEL_AFTER_PROCESSING);
615}
616
617// Server to cancel before reading/writing any requests/responses on the stream
618TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelBefore) {
619 TestBidiStreamServerCancel(CANCEL_BEFORE_PROCESSING, 2);
620}
621
622// Server to cancel while reading/writing requests/responses on the stream in
623// parallel
624TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelDuring) {
625 TestBidiStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
626}
627
628// Server to cancel after reading/writing all requests/responses on the stream
629// but before returning to the client
630TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) {
631 TestBidiStreamServerCancel(CANCEL_AFTER_PROCESSING, 5);
632}
633
yang-gd59ad7e2016-02-10 12:42:53 -0800634TEST_P(End2endTest, SimpleRpcWithCustomeUserAgentPrefix) {
635 user_agent_prefix_ = "custom_prefix";
636 ResetStub();
637 EchoRequest request;
638 EchoResponse response;
639 request.set_message("Hello hello hello hello");
640 request.mutable_param()->set_echo_metadata(true);
641
642 ClientContext context;
643 Status s = stub_->Echo(&context, request, &response);
644 EXPECT_EQ(response.message(), request.message());
645 EXPECT_TRUE(s.ok());
646 const auto& trailing_metadata = context.GetServerTrailingMetadata();
647 auto iter = trailing_metadata.find("user-agent");
648 EXPECT_TRUE(iter != trailing_metadata.end());
649 grpc::string expected_prefix = user_agent_prefix_ + " grpc-c++/";
650 EXPECT_TRUE(iter->second.starts_with(expected_prefix));
651}
652
yang-gf8174ea2016-02-01 00:09:13 -0800653TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
654 ResetStub();
655 std::vector<std::thread*> threads;
656 for (int i = 0; i < 10; ++i) {
657 threads.push_back(new std::thread(SendRpc, stub_.get(), 10, true));
658 }
659 for (int i = 0; i < 10; ++i) {
660 threads[i]->join();
661 delete threads[i];
662 }
663}
664
665TEST_P(End2endTest, MultipleRpcs) {
666 ResetStub();
667 std::vector<std::thread*> threads;
668 for (int i = 0; i < 10; ++i) {
669 threads.push_back(new std::thread(SendRpc, stub_.get(), 10, false));
670 }
671 for (int i = 0; i < 10; ++i) {
672 threads[i]->join();
673 delete threads[i];
674 }
675}
676
yang-g88d5d522015-09-29 12:46:54 -0700677TEST_P(End2endTest, RequestStreamOneRequest) {
678 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800679 EchoRequest request;
680 EchoResponse response;
681 ClientContext context;
682
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800683 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800684 request.set_message("hello");
685 EXPECT_TRUE(stream->Write(request));
686 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800687 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800688 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700689 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800690}
691
yang-g88d5d522015-09-29 12:46:54 -0700692TEST_P(End2endTest, RequestStreamTwoRequests) {
693 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800694 EchoRequest request;
695 EchoResponse response;
696 ClientContext context;
697
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800698 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800699 request.set_message("hello");
700 EXPECT_TRUE(stream->Write(request));
701 EXPECT_TRUE(stream->Write(request));
702 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800703 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800704 EXPECT_EQ(response.message(), "hellohello");
Yang Gaoc1a2c312015-06-16 10:59:46 -0700705 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800706}
707
yang-g88d5d522015-09-29 12:46:54 -0700708TEST_P(End2endTest, ResponseStream) {
709 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800710 EchoRequest request;
711 EchoResponse response;
712 ClientContext context;
713 request.set_message("hello");
714
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800715 auto stream = stub_->ResponseStream(&context, request);
nnoble0c475f02014-12-05 15:37:39 -0800716 EXPECT_TRUE(stream->Read(&response));
717 EXPECT_EQ(response.message(), request.message() + "0");
718 EXPECT_TRUE(stream->Read(&response));
719 EXPECT_EQ(response.message(), request.message() + "1");
720 EXPECT_TRUE(stream->Read(&response));
721 EXPECT_EQ(response.message(), request.message() + "2");
722 EXPECT_FALSE(stream->Read(&response));
723
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800724 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700725 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800726}
727
yang-g88d5d522015-09-29 12:46:54 -0700728TEST_P(End2endTest, BidiStream) {
729 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800730 EchoRequest request;
731 EchoResponse response;
732 ClientContext context;
733 grpc::string msg("hello");
734
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800735 auto stream = stub_->BidiStream(&context);
nnoble0c475f02014-12-05 15:37:39 -0800736
737 request.set_message(msg + "0");
738 EXPECT_TRUE(stream->Write(request));
739 EXPECT_TRUE(stream->Read(&response));
740 EXPECT_EQ(response.message(), request.message());
741
742 request.set_message(msg + "1");
743 EXPECT_TRUE(stream->Write(request));
744 EXPECT_TRUE(stream->Read(&response));
745 EXPECT_EQ(response.message(), request.message());
746
747 request.set_message(msg + "2");
748 EXPECT_TRUE(stream->Write(request));
749 EXPECT_TRUE(stream->Read(&response));
750 EXPECT_EQ(response.message(), request.message());
751
752 stream->WritesDone();
753 EXPECT_FALSE(stream->Read(&response));
Craig Tillerca9a6372015-12-15 18:16:28 -0800754 EXPECT_FALSE(stream->Read(&response));
nnoble0c475f02014-12-05 15:37:39 -0800755
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800756 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700757 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800758}
759
760// Talk to the two services with the same name but different package names.
761// The two stubs are created on the same channel.
yang-g88d5d522015-09-29 12:46:54 -0700762TEST_P(End2endTest, DiffPackageServices) {
763 ResetStub();
yangg1456d152015-01-08 15:39:58 -0800764 EchoRequest request;
765 EchoResponse response;
766 request.set_message("Hello");
767
yangg1456d152015-01-08 15:39:58 -0800768 ClientContext context;
yang-g8b25f2a2015-07-21 23:54:36 -0700769 Status s = stub_->Echo(&context, request, &response);
yangg1456d152015-01-08 15:39:58 -0800770 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700771 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800772
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800773 std::unique_ptr<grpc::testing::duplicate::EchoTestService::Stub> dup_pkg_stub(
774 grpc::testing::duplicate::EchoTestService::NewStub(channel_));
yangg1456d152015-01-08 15:39:58 -0800775 ClientContext context2;
776 s = dup_pkg_stub->Echo(&context2, request, &response);
777 EXPECT_EQ("no package", response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700778 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800779}
780
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700781void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
Craig Tiller20b5fe92015-07-06 10:43:50 -0700782 gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
Craig Tiller677c50c2015-07-13 10:49:06 -0700783 gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700784 while (!service->signal_client()) {
785 }
786 context->TryCancel();
787}
788
yang-ga89bf502015-11-17 14:19:17 -0800789TEST_P(End2endTest, CancelRpcBeforeStart) {
790 ResetStub();
791 EchoRequest request;
792 EchoResponse response;
793 ClientContext context;
794 request.set_message("hello");
795 context.TryCancel();
796 Status s = stub_->Echo(&context, request, &response);
797 EXPECT_EQ("", response.message());
798 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
799}
800
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700801// Client cancels request stream after sending two messages
yang-g88d5d522015-09-29 12:46:54 -0700802TEST_P(End2endTest, ClientCancelsRequestStream) {
803 ResetStub();
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700804 EchoRequest request;
805 EchoResponse response;
806 ClientContext context;
807 request.set_message("hello");
808
809 auto stream = stub_->RequestStream(&context, &response);
810 EXPECT_TRUE(stream->Write(request));
811 EXPECT_TRUE(stream->Write(request));
Yang Gaoc71a9d22015-05-04 00:22:12 -0700812
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700813 context.TryCancel();
814
815 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700816 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700817
Yang Gaoc71a9d22015-05-04 00:22:12 -0700818 EXPECT_EQ(response.message(), "");
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700819}
820
Abhishek Kumare41d0402015-04-17 14:12:33 -0700821// Client cancels server stream after sending some messages
yang-g88d5d522015-09-29 12:46:54 -0700822TEST_P(End2endTest, ClientCancelsResponseStream) {
823 ResetStub();
Abhishek Kumare41d0402015-04-17 14:12:33 -0700824 EchoRequest request;
825 EchoResponse response;
826 ClientContext context;
827 request.set_message("hello");
828
829 auto stream = stub_->ResponseStream(&context, request);
830
831 EXPECT_TRUE(stream->Read(&response));
832 EXPECT_EQ(response.message(), request.message() + "0");
833 EXPECT_TRUE(stream->Read(&response));
834 EXPECT_EQ(response.message(), request.message() + "1");
835
836 context.TryCancel();
837
838 // The cancellation races with responses, so there might be zero or
839 // one responses pending, read till failure
840
841 if (stream->Read(&response)) {
842 EXPECT_EQ(response.message(), request.message() + "2");
843 // Since we have cancelled, we expect the next attempt to read to fail
844 EXPECT_FALSE(stream->Read(&response));
845 }
846
847 Status s = stream->Finish();
Abhishek Kumar18298a72015-04-17 15:00:25 -0700848 // The final status could be either of CANCELLED or OK depending on
849 // who won the race.
Yang Gaoc1a2c312015-06-16 10:59:46 -0700850 EXPECT_GE(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumare41d0402015-04-17 14:12:33 -0700851}
852
Abhishek Kumar82a83312015-04-17 13:30:51 -0700853// Client cancels bidi stream after sending some messages
yang-g88d5d522015-09-29 12:46:54 -0700854TEST_P(End2endTest, ClientCancelsBidi) {
855 ResetStub();
Abhishek Kumar82a83312015-04-17 13:30:51 -0700856 EchoRequest request;
857 EchoResponse response;
858 ClientContext context;
859 grpc::string msg("hello");
860
861 auto stream = stub_->BidiStream(&context);
862
863 request.set_message(msg + "0");
864 EXPECT_TRUE(stream->Write(request));
865 EXPECT_TRUE(stream->Read(&response));
866 EXPECT_EQ(response.message(), request.message());
867
868 request.set_message(msg + "1");
869 EXPECT_TRUE(stream->Write(request));
870
871 context.TryCancel();
872
873 // The cancellation races with responses, so there might be zero or
874 // one responses pending, read till failure
875
876 if (stream->Read(&response)) {
877 EXPECT_EQ(response.message(), request.message());
878 // Since we have cancelled, we expect the next attempt to read to fail
879 EXPECT_FALSE(stream->Read(&response));
880 }
881
882 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700883 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumar82a83312015-04-17 13:30:51 -0700884}
885
yang-g88d5d522015-09-29 12:46:54 -0700886TEST_P(End2endTest, RpcMaxMessageSize) {
887 ResetStub();
Yang Gao3921c562015-04-30 16:07:06 -0700888 EchoRequest request;
889 EchoResponse response;
Yang Gaoc71a9d22015-05-04 00:22:12 -0700890 request.set_message(string(kMaxMessageSize_ * 2, 'a'));
Yang Gao3921c562015-04-30 16:07:06 -0700891
892 ClientContext context;
893 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700894 EXPECT_FALSE(s.ok());
Yang Gao3921c562015-04-30 16:07:06 -0700895}
Abhishek Kumar82a83312015-04-17 13:30:51 -0700896
yang-g88d5d522015-09-29 12:46:54 -0700897// Client sends 20 requests and the server returns CANCELLED status after
898// reading 10 requests.
899TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
900 ResetStub();
901 EchoRequest request;
902 EchoResponse response;
903 ClientContext context;
904
905 context.AddMetadata(kServerCancelAfterReads, "10");
906 auto stream = stub_->RequestStream(&context, &response);
907 request.set_message("hello");
908 int send_messages = 20;
yang-gc0461032015-10-02 16:22:43 -0700909 while (send_messages > 10) {
yang-g88d5d522015-09-29 12:46:54 -0700910 EXPECT_TRUE(stream->Write(request));
911 send_messages--;
912 }
yang-gc0461032015-10-02 16:22:43 -0700913 while (send_messages > 0) {
914 stream->Write(request);
915 send_messages--;
916 }
yang-g88d5d522015-09-29 12:46:54 -0700917 stream->WritesDone();
918 Status s = stream->Finish();
919 EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
920}
921
yang-g88d5d522015-09-29 12:46:54 -0700922void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
923 gpr_event* ev) {
924 EchoResponse resp;
925 gpr_event_set(ev, (void*)1);
926 while (stream->Read(&resp)) {
927 gpr_log(GPR_INFO, "Read message");
928 }
929}
yang-g88d5d522015-09-29 12:46:54 -0700930
931// Run a Read and a WritesDone simultaneously.
932TEST_P(End2endTest, SimultaneousReadWritesDone) {
933 ResetStub();
934 ClientContext context;
935 gpr_event ev;
936 gpr_event_init(&ev);
937 auto stream = stub_->BidiStream(&context);
938 std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
939 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
940 stream->WritesDone();
Vijay Paibdfec2c2016-02-25 11:51:21 -0800941 reader_thread.join();
yang-g88d5d522015-09-29 12:46:54 -0700942 Status s = stream->Finish();
943 EXPECT_TRUE(s.ok());
yang-g88d5d522015-09-29 12:46:54 -0700944}
945
946TEST_P(End2endTest, ChannelState) {
947 ResetStub();
948 // Start IDLE
949 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
950
951 // Did not ask to connect, no state change.
952 CompletionQueue cq;
953 std::chrono::system_clock::time_point deadline =
954 std::chrono::system_clock::now() + std::chrono::milliseconds(10);
955 channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL);
956 void* tag;
957 bool ok = true;
958 cq.Next(&tag, &ok);
959 EXPECT_FALSE(ok);
960
961 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true));
962 EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE,
963 gpr_inf_future(GPR_CLOCK_REALTIME)));
yang-g0d557502015-10-01 11:30:12 -0700964 auto state = channel_->GetState(false);
965 EXPECT_TRUE(state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_READY);
yang-g88d5d522015-09-29 12:46:54 -0700966}
967
968// Takes 10s.
969TEST_P(End2endTest, ChannelStateTimeout) {
yang-g17197dd2016-02-19 00:04:22 -0800970 if (GetParam().credentials_type != kInsecureCredentialsType) {
yang-g88d5d522015-09-29 12:46:54 -0700971 return;
972 }
973 int port = grpc_pick_unused_port_or_die();
974 std::ostringstream server_address;
975 server_address << "127.0.0.1:" << port;
976 // Channel to non-existing server
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700977 auto channel =
978 CreateChannel(server_address.str(), InsecureChannelCredentials());
yang-g88d5d522015-09-29 12:46:54 -0700979 // Start IDLE
980 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
981
982 auto state = GRPC_CHANNEL_IDLE;
983 for (int i = 0; i < 10; i++) {
984 channel->WaitForStateChange(
985 state, std::chrono::system_clock::now() + std::chrono::seconds(1));
986 state = channel->GetState(false);
987 }
988}
989
990// Talking to a non-existing service.
991TEST_P(End2endTest, NonExistingService) {
992 ResetChannel();
murgatroid997c5befd2016-09-01 17:09:47 -0700993 std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
994 stub = grpc::testing::UnimplementedEchoService::NewStub(channel_);
yang-g88d5d522015-09-29 12:46:54 -0700995
996 EchoRequest request;
997 EchoResponse response;
998 request.set_message("Hello");
999
1000 ClientContext context;
1001 Status s = stub->Unimplemented(&context, request, &response);
1002 EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
1003 EXPECT_EQ("", s.error_message());
1004}
1005
yang-g4c070082016-05-05 23:27:13 -07001006// Ask the server to send back a serialized proto in trailer.
1007// This is an example of setting error details.
1008TEST_P(End2endTest, BinaryTrailerTest) {
1009 ResetStub();
1010 EchoRequest request;
1011 EchoResponse response;
1012 ClientContext context;
1013
1014 request.mutable_param()->set_echo_metadata(true);
1015 DebugInfo* info = request.mutable_param()->mutable_debug_info();
1016 info->add_stack_entries("stack_entry_1");
1017 info->add_stack_entries("stack_entry_2");
1018 info->add_stack_entries("stack_entry_3");
1019 info->set_detail("detailed debug info");
1020 grpc::string expected_string = info->SerializeAsString();
1021 request.set_message("Hello");
1022
1023 Status s = stub_->Echo(&context, request, &response);
1024 EXPECT_FALSE(s.ok());
1025 auto trailers = context.GetServerTrailingMetadata();
yang-g39e71c32016-05-10 10:21:41 -07001026 EXPECT_EQ(1u, trailers.count(kDebugInfoTrailerKey));
yang-g4c070082016-05-05 23:27:13 -07001027 auto iter = trailers.find(kDebugInfoTrailerKey);
1028 EXPECT_EQ(expected_string, iter->second);
yang-g080528a2016-05-06 13:12:00 -07001029 // Parse the returned trailer into a DebugInfo proto.
1030 DebugInfo returned_info;
1031 EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second)));
yang-g4c070082016-05-05 23:27:13 -07001032}
1033
yang-g88d5d522015-09-29 12:46:54 -07001034//////////////////////////////////////////////////////////////////////////
1035// Test with and without a proxy.
1036class ProxyEnd2endTest : public End2endTest {
1037 protected:
1038};
1039
1040TEST_P(ProxyEnd2endTest, SimpleRpc) {
1041 ResetStub();
yang-gf8174ea2016-02-01 00:09:13 -08001042 SendRpc(stub_.get(), 1, false);
yang-g88d5d522015-09-29 12:46:54 -07001043}
1044
yang-g000aa452016-06-07 13:08:39 -07001045TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) {
1046 ResetStub();
1047 EchoRequest request;
1048 EchoResponse response;
1049
1050 ClientContext context;
1051 Status s = stub_->Echo(&context, request, &response);
1052 EXPECT_TRUE(s.ok());
1053}
1054
yang-g88d5d522015-09-29 12:46:54 -07001055TEST_P(ProxyEnd2endTest, MultipleRpcs) {
1056 ResetStub();
1057 std::vector<std::thread*> threads;
1058 for (int i = 0; i < 10; ++i) {
yang-gf8174ea2016-02-01 00:09:13 -08001059 threads.push_back(new std::thread(SendRpc, stub_.get(), 10, false));
yang-g88d5d522015-09-29 12:46:54 -07001060 }
1061 for (int i = 0; i < 10; ++i) {
1062 threads[i]->join();
1063 delete threads[i];
1064 }
1065}
1066
1067// Set a 10us deadline and make sure proper error is returned.
1068TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) {
1069 ResetStub();
1070 EchoRequest request;
1071 EchoResponse response;
1072 request.set_message("Hello");
Craig Tillerb0f275e2016-01-27 10:45:50 -08001073 request.mutable_param()->set_skip_cancelled_check(true);
yang-g88d5d522015-09-29 12:46:54 -07001074
1075 ClientContext context;
1076 std::chrono::system_clock::time_point deadline =
1077 std::chrono::system_clock::now() + std::chrono::microseconds(10);
1078 context.set_deadline(deadline);
1079 Status s = stub_->Echo(&context, request, &response);
1080 EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
1081}
1082
1083// Set a long but finite deadline.
1084TEST_P(ProxyEnd2endTest, RpcLongDeadline) {
1085 ResetStub();
1086 EchoRequest request;
1087 EchoResponse response;
1088 request.set_message("Hello");
1089
1090 ClientContext context;
1091 std::chrono::system_clock::time_point deadline =
1092 std::chrono::system_clock::now() + std::chrono::hours(1);
1093 context.set_deadline(deadline);
1094 Status s = stub_->Echo(&context, request, &response);
1095 EXPECT_EQ(response.message(), request.message());
1096 EXPECT_TRUE(s.ok());
1097}
1098
1099// Ask server to echo back the deadline it sees.
1100TEST_P(ProxyEnd2endTest, EchoDeadline) {
1101 ResetStub();
1102 EchoRequest request;
1103 EchoResponse response;
1104 request.set_message("Hello");
1105 request.mutable_param()->set_echo_deadline(true);
1106
1107 ClientContext context;
1108 std::chrono::system_clock::time_point deadline =
1109 std::chrono::system_clock::now() + std::chrono::seconds(100);
1110 context.set_deadline(deadline);
1111 Status s = stub_->Echo(&context, request, &response);
1112 EXPECT_EQ(response.message(), request.message());
1113 EXPECT_TRUE(s.ok());
1114 gpr_timespec sent_deadline;
1115 Timepoint2Timespec(deadline, &sent_deadline);
1116 // Allow 1 second error.
1117 EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
1118 EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
1119}
1120
1121// Ask server to echo back the deadline it sees. The rpc has no deadline.
1122TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) {
1123 ResetStub();
1124 EchoRequest request;
1125 EchoResponse response;
1126 request.set_message("Hello");
1127 request.mutable_param()->set_echo_deadline(true);
1128
1129 ClientContext context;
1130 Status s = stub_->Echo(&context, request, &response);
1131 EXPECT_EQ(response.message(), request.message());
1132 EXPECT_TRUE(s.ok());
1133 EXPECT_EQ(response.param().request_deadline(),
1134 gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
1135}
1136
1137TEST_P(ProxyEnd2endTest, UnimplementedRpc) {
1138 ResetStub();
1139 EchoRequest request;
1140 EchoResponse response;
1141 request.set_message("Hello");
1142
1143 ClientContext context;
1144 Status s = stub_->Unimplemented(&context, request, &response);
1145 EXPECT_FALSE(s.ok());
1146 EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
1147 EXPECT_EQ(s.error_message(), "");
1148 EXPECT_EQ(response.message(), "");
1149}
1150
1151// Client cancels rpc after 10ms
1152TEST_P(ProxyEnd2endTest, ClientCancelsRpc) {
1153 ResetStub();
1154 EchoRequest request;
1155 EchoResponse response;
1156 request.set_message("Hello");
1157 const int kCancelDelayUs = 10 * 1000;
1158 request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
1159
1160 ClientContext context;
1161 std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
1162 Status s = stub_->Echo(&context, request, &response);
1163 cancel_thread.join();
1164 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
1165 EXPECT_EQ(s.error_message(), "Cancelled");
1166}
1167
1168// Server cancels rpc after 1ms
1169TEST_P(ProxyEnd2endTest, ServerCancelsRpc) {
1170 ResetStub();
1171 EchoRequest request;
1172 EchoResponse response;
1173 request.set_message("Hello");
1174 request.mutable_param()->set_server_cancel_after_us(1000);
1175
1176 ClientContext context;
1177 Status s = stub_->Echo(&context, request, &response);
1178 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
1179 EXPECT_TRUE(s.error_message().empty());
1180}
1181
1182// Make the response larger than the flow control window.
1183TEST_P(ProxyEnd2endTest, HugeResponse) {
1184 ResetStub();
1185 EchoRequest request;
1186 EchoResponse response;
1187 request.set_message("huge response");
1188 const size_t kResponseSize = 1024 * (1024 + 10);
1189 request.mutable_param()->set_response_message_length(kResponseSize);
1190
1191 ClientContext context;
Craig Tiller6c8619b2016-07-07 10:41:48 -07001192 std::chrono::system_clock::time_point deadline =
1193 std::chrono::system_clock::now() + std::chrono::seconds(20);
1194 context.set_deadline(deadline);
yang-g88d5d522015-09-29 12:46:54 -07001195 Status s = stub_->Echo(&context, request, &response);
1196 EXPECT_EQ(kResponseSize, response.message().size());
1197 EXPECT_TRUE(s.ok());
1198}
1199
1200TEST_P(ProxyEnd2endTest, Peer) {
1201 ResetStub();
1202 EchoRequest request;
1203 EchoResponse response;
1204 request.set_message("hello");
1205 request.mutable_param()->set_echo_peer(true);
1206
1207 ClientContext context;
1208 Status s = stub_->Echo(&context, request, &response);
1209 EXPECT_EQ(response.message(), request.message());
1210 EXPECT_TRUE(s.ok());
1211 EXPECT_TRUE(CheckIsLocalhost(response.param().peer()));
1212 EXPECT_TRUE(CheckIsLocalhost(context.peer()));
1213}
1214
1215//////////////////////////////////////////////////////////////////////////
1216class SecureEnd2endTest : public End2endTest {
1217 protected:
1218 SecureEnd2endTest() {
1219 GPR_ASSERT(!GetParam().use_proxy);
yang-g17197dd2016-02-19 00:04:22 -08001220 GPR_ASSERT(GetParam().credentials_type != kInsecureCredentialsType);
yang-g88d5d522015-09-29 12:46:54 -07001221 }
1222};
1223
1224TEST_P(SecureEnd2endTest, SimpleRpcWithHost) {
1225 ResetStub();
1226
1227 EchoRequest request;
1228 EchoResponse response;
1229 request.set_message("Hello");
1230
1231 ClientContext context;
1232 context.set_authority("foo.test.youtube.com");
1233 Status s = stub_->Echo(&context, request, &response);
1234 EXPECT_EQ(response.message(), request.message());
1235 EXPECT_TRUE(response.has_param());
1236 EXPECT_EQ("special", response.param().host());
1237 EXPECT_TRUE(s.ok());
1238}
1239
yang-ge21908f2015-08-25 13:47:51 -07001240bool MetadataContains(
1241 const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
1242 const grpc::string& key, const grpc::string& value) {
Yang Gao26a49122015-05-15 17:02:56 -07001243 int count = 0;
1244
yang-ge21908f2015-08-25 13:47:51 -07001245 for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
Yang Gao26a49122015-05-15 17:02:56 -07001246 metadata.begin();
1247 iter != metadata.end(); ++iter) {
yang-ge21908f2015-08-25 13:47:51 -07001248 if (ToString(iter->first) == key && ToString(iter->second) == value) {
Yang Gao26a49122015-05-15 17:02:56 -07001249 count++;
1250 }
1251 }
1252 return count == 1;
1253}
1254
yang-g88d5d522015-09-29 12:46:54 -07001255TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) {
1256 auto* processor = new TestAuthMetadataProcessor(true);
1257 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
1258 ResetStub();
1259 EchoRequest request;
1260 EchoResponse response;
1261 ClientContext context;
1262 context.set_credentials(processor->GetCompatibleClientCreds());
1263 request.set_message("Hello");
1264 request.mutable_param()->set_echo_metadata(true);
1265 request.mutable_param()->set_expected_client_identity(
1266 TestAuthMetadataProcessor::kGoodGuy);
Dan Bornf2f7d572016-03-03 17:26:12 -08001267 request.mutable_param()->set_expected_transport_security_type(
1268 GetParam().credentials_type);
yang-g88d5d522015-09-29 12:46:54 -07001269
1270 Status s = stub_->Echo(&context, request, &response);
1271 EXPECT_EQ(request.message(), response.message());
1272 EXPECT_TRUE(s.ok());
1273
1274 // Metadata should have been consumed by the processor.
1275 EXPECT_FALSE(MetadataContains(
1276 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
1277 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
1278}
1279
1280TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) {
1281 auto* processor = new TestAuthMetadataProcessor(true);
1282 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
1283 ResetStub();
1284 EchoRequest request;
1285 EchoResponse response;
1286 ClientContext context;
1287 context.set_credentials(processor->GetIncompatibleClientCreds());
1288 request.set_message("Hello");
1289
1290 Status s = stub_->Echo(&context, request, &response);
1291 EXPECT_FALSE(s.ok());
1292 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1293}
1294TEST_P(SecureEnd2endTest, SetPerCallCredentials) {
1295 ResetStub();
Yang Gaoa8938922015-05-14 11:51:07 -07001296 EchoRequest request;
1297 EchoResponse response;
1298 ClientContext context;
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001299 std::shared_ptr<CallCredentials> creds =
Julien Boeuf510a9202015-08-25 21:51:07 -07001300 GoogleIAMCredentials("fake_token", "fake_selector");
Yang Gaoa8938922015-05-14 11:51:07 -07001301 context.set_credentials(creds);
Yang Gao26a49122015-05-15 17:02:56 -07001302 request.set_message("Hello");
1303 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -07001304
1305 Status s = stub_->Echo(&context, request, &response);
Yang Gaoa8938922015-05-14 11:51:07 -07001306 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -07001307 EXPECT_TRUE(s.ok());
Yang Gao26a49122015-05-15 17:02:56 -07001308 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1309 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1310 "fake_token"));
1311 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1312 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1313 "fake_selector"));
Yang Gaoa8938922015-05-14 11:51:07 -07001314}
1315
yang-g88d5d522015-09-29 12:46:54 -07001316TEST_P(SecureEnd2endTest, OverridePerCallCredentials) {
1317 ResetStub();
Yang Gaoa8938922015-05-14 11:51:07 -07001318 EchoRequest request;
1319 EchoResponse response;
1320 ClientContext context;
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001321 std::shared_ptr<CallCredentials> creds1 =
Julien Boeuf510a9202015-08-25 21:51:07 -07001322 GoogleIAMCredentials("fake_token1", "fake_selector1");
Yang Gaoa8938922015-05-14 11:51:07 -07001323 context.set_credentials(creds1);
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001324 std::shared_ptr<CallCredentials> creds2 =
Julien Boeuf510a9202015-08-25 21:51:07 -07001325 GoogleIAMCredentials("fake_token2", "fake_selector2");
Yang Gaoa8938922015-05-14 11:51:07 -07001326 context.set_credentials(creds2);
Yang Gao26a49122015-05-15 17:02:56 -07001327 request.set_message("Hello");
1328 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -07001329
1330 Status s = stub_->Echo(&context, request, &response);
Yang Gao26a49122015-05-15 17:02:56 -07001331 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1332 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1333 "fake_token2"));
1334 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1335 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1336 "fake_selector2"));
Yang Gaob57f72d2015-05-17 21:54:54 -07001337 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
1338 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1339 "fake_token1"));
1340 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
1341 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1342 "fake_selector1"));
Yang Gaoa8938922015-05-14 11:51:07 -07001343 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -07001344 EXPECT_TRUE(s.ok());
Yang Gaoa8938922015-05-14 11:51:07 -07001345}
1346
yang-gc580af32016-09-15 15:28:38 -07001347TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) {
1348 ResetStub();
1349 EchoRequest request;
1350 EchoResponse response;
1351 ClientContext context;
1352 context.set_credentials(
1353 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1354 new TestMetadataCredentialsPlugin(
1355 TestMetadataCredentialsPlugin::kBadMetadataKey,
1356 "Does not matter, will fail the key is invalid.", false, true))));
1357 request.set_message("Hello");
1358
1359 Status s = stub_->Echo(&context, request, &response);
1360 EXPECT_FALSE(s.ok());
1361 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1362}
1363
yang-g4b4571a2016-09-15 23:01:09 -07001364TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) {
1365 ResetStub();
1366 EchoRequest request;
1367 EchoResponse response;
1368 ClientContext context;
1369 context.set_credentials(
1370 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1371 new TestMetadataCredentialsPlugin(
1372 TestMetadataCredentialsPlugin::kGoodMetadataKey,
yang-gd5fba282016-09-16 10:29:16 -07001373 "With illegal \n value.", false, true))));
yang-g4b4571a2016-09-15 23:01:09 -07001374 request.set_message("Hello");
1375
1376 Status s = stub_->Echo(&context, request, &response);
1377 EXPECT_FALSE(s.ok());
1378 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1379}
1380
yang-g88d5d522015-09-29 12:46:54 -07001381TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) {
1382 ResetStub();
Julien Boeuf1928d492015-09-15 15:20:11 -07001383 EchoRequest request;
1384 EchoResponse response;
1385 ClientContext context;
1386 context.set_credentials(
1387 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1388 new TestMetadataCredentialsPlugin(
yang-gc580af32016-09-15 15:28:38 -07001389 TestMetadataCredentialsPlugin::kGoodMetadataKey,
Julien Boeuf1928d492015-09-15 15:20:11 -07001390 "Does not matter, will fail anyway (see 3rd param)", false,
1391 false))));
1392 request.set_message("Hello");
1393
1394 Status s = stub_->Echo(&context, request, &response);
1395 EXPECT_FALSE(s.ok());
1396 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
Julien Boeuf38c0cde2016-06-06 14:46:08 +02001397 EXPECT_EQ(s.error_message(), kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -07001398}
1399
yang-g88d5d522015-09-29 12:46:54 -07001400TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001401 auto* processor = new TestAuthMetadataProcessor(false);
1402 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
yang-g88d5d522015-09-29 12:46:54 -07001403 ResetStub();
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001404 EchoRequest request;
1405 EchoResponse response;
1406 ClientContext context;
1407 context.set_credentials(processor->GetCompatibleClientCreds());
1408 request.set_message("Hello");
1409 request.mutable_param()->set_echo_metadata(true);
1410 request.mutable_param()->set_expected_client_identity(
1411 TestAuthMetadataProcessor::kGoodGuy);
Dan Bornf2f7d572016-03-03 17:26:12 -08001412 request.mutable_param()->set_expected_transport_security_type(
1413 GetParam().credentials_type);
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001414
1415 Status s = stub_->Echo(&context, request, &response);
1416 EXPECT_EQ(request.message(), response.message());
1417 EXPECT_TRUE(s.ok());
1418
1419 // Metadata should have been consumed by the processor.
1420 EXPECT_FALSE(MetadataContains(
1421 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
1422 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
1423}
1424
yang-g88d5d522015-09-29 12:46:54 -07001425TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001426 auto* processor = new TestAuthMetadataProcessor(false);
1427 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
yang-g88d5d522015-09-29 12:46:54 -07001428 ResetStub();
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001429 EchoRequest request;
1430 EchoResponse response;
1431 ClientContext context;
1432 context.set_credentials(processor->GetIncompatibleClientCreds());
1433 request.set_message("Hello");
1434
1435 Status s = stub_->Echo(&context, request, &response);
1436 EXPECT_FALSE(s.ok());
1437 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1438}
1439
yang-g88d5d522015-09-29 12:46:54 -07001440TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) {
1441 ResetStub();
Julien Boeuf1928d492015-09-15 15:20:11 -07001442 EchoRequest request;
1443 EchoResponse response;
1444 ClientContext context;
1445 context.set_credentials(
1446 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1447 new TestMetadataCredentialsPlugin(
yang-gc580af32016-09-15 15:28:38 -07001448 TestMetadataCredentialsPlugin::kGoodMetadataKey,
Julien Boeuf1928d492015-09-15 15:20:11 -07001449 "Does not matter, will fail anyway (see 3rd param)", true,
1450 false))));
1451 request.set_message("Hello");
1452
1453 Status s = stub_->Echo(&context, request, &response);
1454 EXPECT_FALSE(s.ok());
1455 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
Julien Boeuf38c0cde2016-06-06 14:46:08 +02001456 EXPECT_EQ(s.error_message(), kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -07001457}
1458
yang-g88d5d522015-09-29 12:46:54 -07001459TEST_P(SecureEnd2endTest, ClientAuthContext) {
1460 ResetStub();
yang-gc4eef2e2015-07-06 23:26:58 -07001461 EchoRequest request;
1462 EchoResponse response;
1463 request.set_message("Hello");
Dan Bornf2f7d572016-03-03 17:26:12 -08001464 request.mutable_param()->set_check_auth_context(GetParam().credentials_type ==
1465 kTlsCredentialsType);
1466 request.mutable_param()->set_expected_transport_security_type(
1467 GetParam().credentials_type);
yang-gc4eef2e2015-07-06 23:26:58 -07001468 ClientContext context;
1469 Status s = stub_->Echo(&context, request, &response);
1470 EXPECT_EQ(response.message(), request.message());
1471 EXPECT_TRUE(s.ok());
1472
yang-g8b25f2a2015-07-21 23:54:36 -07001473 std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
Dan Bornf2f7d572016-03-03 17:26:12 -08001474 std::vector<grpc::string_ref> tst =
yang-g8b25f2a2015-07-21 23:54:36 -07001475 auth_ctx->FindPropertyValues("transport_security_type");
Robbie Shade820c1f32016-06-23 14:31:28 -04001476 ASSERT_EQ(1u, tst.size());
Dan Bornf2f7d572016-03-03 17:26:12 -08001477 EXPECT_EQ(GetParam().credentials_type, ToString(tst[0]));
1478 if (GetParam().credentials_type == kTlsCredentialsType) {
1479 EXPECT_EQ("x509_subject_alternative_name",
1480 auth_ctx->GetPeerIdentityPropertyName());
Paul Querna47d841d2016-03-10 11:19:17 -08001481 EXPECT_EQ(4u, auth_ctx->GetPeerIdentity().size());
Dan Bornf2f7d572016-03-03 17:26:12 -08001482 EXPECT_EQ("*.test.google.fr", ToString(auth_ctx->GetPeerIdentity()[0]));
1483 EXPECT_EQ("waterzooi.test.google.be",
1484 ToString(auth_ctx->GetPeerIdentity()[1]));
1485 EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2]));
Paul Querna47d841d2016-03-10 11:19:17 -08001486 EXPECT_EQ("192.168.1.3", ToString(auth_ctx->GetPeerIdentity()[3]));
Dan Bornf2f7d572016-03-03 17:26:12 -08001487 }
yang-gc4eef2e2015-07-06 23:26:58 -07001488}
1489
yang-g4c8aed32016-02-19 00:19:39 -08001490std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
1491 bool test_insecure,
1492 bool test_secure) {
1493 std::vector<TestScenario> scenarios;
1494 std::vector<grpc::string> credentials_types;
1495 if (test_secure) {
1496 credentials_types = GetSecureCredentialsTypeList();
1497 }
1498 if (test_insecure) {
1499 credentials_types.push_back(kInsecureCredentialsType);
1500 }
1501 for (auto it = credentials_types.begin(); it != credentials_types.end();
1502 ++it) {
Vijay Pai679c75f2016-06-15 13:08:00 -07001503 scenarios.emplace_back(false, *it);
yang-g4c8aed32016-02-19 00:19:39 -08001504 if (use_proxy) {
Vijay Pai679c75f2016-06-15 13:08:00 -07001505 scenarios.emplace_back(true, *it);
yang-g4c8aed32016-02-19 00:19:39 -08001506 }
1507 }
1508 return scenarios;
1509}
yang-g6f30dec2015-07-22 23:11:56 -07001510
yang-g4c8aed32016-02-19 00:19:39 -08001511INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
1512 ::testing::ValuesIn(CreateTestScenarios(false, true,
1513 true)));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -08001514
yang-g4c8aed32016-02-19 00:19:39 -08001515INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
1516 ::testing::ValuesIn(CreateTestScenarios(false, true,
1517 false)));
1518
1519INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
1520 ::testing::ValuesIn(CreateTestScenarios(true, true,
1521 true)));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001522
yang-g88d5d522015-09-29 12:46:54 -07001523INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
yang-g4c8aed32016-02-19 00:19:39 -08001524 ::testing::ValuesIn(CreateTestScenarios(false, false,
1525 true)));
yang-g88d5d522015-09-29 12:46:54 -07001526
yang-g8ab38362015-07-31 14:05:33 -07001527} // namespace
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001528} // namespace testing
1529} // namespace grpc
1530
1531int main(int argc, char** argv) {
1532 grpc_test_init(argc, argv);
1533 ::testing::InitGoogleTest(&argc, argv);
1534 return RUN_ALL_TESTS();
David Garcia Quintas2bf574f2016-01-14 15:27:08 -08001535}