blob: 620b3ae7bcb9e58dc85c8a5e2530779de53cf023 [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>
Craig Tiller20afa3d2016-10-17 14:52:14 -070040#include <grpc++/resource_quota.h>
Julien Boeuf5be92a32015-08-28 16:28:18 -070041#include <grpc++/security/auth_metadata_processor.h>
42#include <grpc++/security/credentials.h>
43#include <grpc++/security/server_credentials.h>
yang-g9e2f90c2015-08-21 15:35:03 -070044#include <grpc++/server.h>
45#include <grpc++/server_builder.h>
46#include <grpc++/server_context.h>
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080047#include <grpc/grpc.h>
David Garcia Quintasc79b0652016-07-27 21:11:58 -070048#include <grpc/support/log.h>
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080049#include <grpc/support/thd.h>
50#include <grpc/support/time.h>
yang-g9e2f90c2015-08-21 15:35:03 -070051#include <gtest/gtest.h>
52
Julien Boeuf8ca294e2016-05-02 14:56:30 -070053#include "src/core/lib/security/credentials/credentials.h"
Sree Kuchibhotlab0d0c8e2016-01-13 22:52:17 -080054#include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
55#include "src/proto/grpc/testing/echo.grpc.pb.h"
Nicolas Noble89219162015-04-07 18:01:18 -070056#include "test/core/util/port.h"
Craig Tiller14e60e92015-01-13 17:26:46 -080057#include "test/core/util/test_config.h"
yang-g7b0edbd2016-02-02 16:05:21 -080058#include "test/cpp/end2end/test_service_impl.h"
yang-ge21908f2015-08-25 13:47:51 -070059#include "test/cpp/util/string_ref_helper.h"
yang-g7d2a3e12016-02-18 15:41:56 -080060#include "test/cpp/util/test_credentials_provider.h"
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080061
Craig Tiller1b4e3302015-12-17 16:35:00 -080062using grpc::testing::EchoRequest;
63using grpc::testing::EchoResponse;
Dan Bornf2f7d572016-03-03 17:26:12 -080064using grpc::testing::kTlsCredentialsType;
yangged5e7e02015-01-06 10:16:15 -080065using std::chrono::system_clock;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -080066
67namespace grpc {
yangged5e7e02015-01-06 10:16:15 -080068namespace testing {
yangged5e7e02015-01-06 10:16:15 -080069namespace {
70
yang-gd7ead692015-07-30 10:57:45 -070071bool CheckIsLocalhost(const grpc::string& addr) {
72 const grpc::string kIpv6("ipv6:[::1]:");
73 const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
74 const grpc::string kIpv4("ipv4:127.0.0.1:");
75 return addr.substr(0, kIpv4.size()) == kIpv4 ||
76 addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 ||
77 addr.substr(0, kIpv6.size()) == kIpv6;
78}
79
Julien Boeuf38c0cde2016-06-06 14:46:08 +020080const char kTestCredsPluginErrorMsg[] = "Could not find plugin metadata.";
81
Julien Boeuf1928d492015-09-15 15:20:11 -070082class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin {
83 public:
yang-gc580af32016-09-15 15:28:38 -070084 static const char kGoodMetadataKey[];
85 static const char kBadMetadataKey[];
Julien Boeuf1928d492015-09-15 15:20:11 -070086
yang-gc580af32016-09-15 15:28:38 -070087 TestMetadataCredentialsPlugin(grpc::string_ref metadata_key,
88 grpc::string_ref metadata_value,
Julien Boeuf1928d492015-09-15 15:20:11 -070089 bool is_blocking, bool is_successful)
yang-gc580af32016-09-15 15:28:38 -070090 : metadata_key_(metadata_key.data(), metadata_key.length()),
91 metadata_value_(metadata_value.data(), metadata_value.length()),
Julien Boeuf1928d492015-09-15 15:20:11 -070092 is_blocking_(is_blocking),
93 is_successful_(is_successful) {}
94
Vijay Paic0b2acb2016-11-01 16:31:56 -070095 bool IsBlocking() const override { return is_blocking_; }
Julien Boeuf1928d492015-09-15 15:20:11 -070096
Vijay Pai713c7b82016-11-01 16:33:18 -070097 Status GetMetadata(
98 grpc::string_ref service_url, grpc::string_ref method_name,
99 const grpc::AuthContext& channel_auth_context,
100 std::multimap<grpc::string, grpc::string>* metadata) override {
Julien Boeuf1928d492015-09-15 15:20:11 -0700101 EXPECT_GT(service_url.length(), 0UL);
Julien Boeuf114f3942015-11-19 21:45:52 -0800102 EXPECT_GT(method_name.length(), 0UL);
103 EXPECT_TRUE(channel_auth_context.IsPeerAuthenticated());
Julien Boeuf1928d492015-09-15 15:20:11 -0700104 EXPECT_TRUE(metadata != nullptr);
105 if (is_successful_) {
yang-gc580af32016-09-15 15:28:38 -0700106 metadata->insert(std::make_pair(metadata_key_, metadata_value_));
Julien Boeuf1928d492015-09-15 15:20:11 -0700107 return Status::OK;
108 } else {
Julien Boeuf38c0cde2016-06-06 14:46:08 +0200109 return Status(StatusCode::NOT_FOUND, kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -0700110 }
111 }
112
113 private:
yang-gc580af32016-09-15 15:28:38 -0700114 grpc::string metadata_key_;
Julien Boeuf1928d492015-09-15 15:20:11 -0700115 grpc::string metadata_value_;
116 bool is_blocking_;
117 bool is_successful_;
118};
119
yang-gc580af32016-09-15 15:28:38 -0700120const char TestMetadataCredentialsPlugin::kBadMetadataKey[] =
121 "TestPluginMetadata";
122const char TestMetadataCredentialsPlugin::kGoodMetadataKey[] =
123 "test-plugin-metadata";
Julien Boeuf1928d492015-09-15 15:20:11 -0700124
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700125class TestAuthMetadataProcessor : public AuthMetadataProcessor {
126 public:
127 static const char kGoodGuy[];
128
129 TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
130
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700131 std::shared_ptr<CallCredentials> GetCompatibleClientCreds() {
Julien Boeuf1928d492015-09-15 15:20:11 -0700132 return MetadataCredentialsFromPlugin(
133 std::unique_ptr<MetadataCredentialsPlugin>(
yang-gc580af32016-09-15 15:28:38 -0700134 new TestMetadataCredentialsPlugin(
135 TestMetadataCredentialsPlugin::kGoodMetadataKey, kGoodGuy,
136 is_blocking_, true)));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700137 }
Julien Boeuf1928d492015-09-15 15:20:11 -0700138
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700139 std::shared_ptr<CallCredentials> GetIncompatibleClientCreds() {
Julien Boeuf1928d492015-09-15 15:20:11 -0700140 return MetadataCredentialsFromPlugin(
141 std::unique_ptr<MetadataCredentialsPlugin>(
yang-gc580af32016-09-15 15:28:38 -0700142 new TestMetadataCredentialsPlugin(
143 TestMetadataCredentialsPlugin::kGoodMetadataKey, "Mr Hyde",
144 is_blocking_, true)));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700145 }
146
147 // Interface implementation
Vijay Paic0b2acb2016-11-01 16:31:56 -0700148 bool IsBlocking() const override { return is_blocking_; }
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700149
150 Status Process(const InputMetadata& auth_metadata, AuthContext* context,
151 OutputMetadata* consumed_auth_metadata,
Vijay Paic0b2acb2016-11-01 16:31:56 -0700152 OutputMetadata* response_metadata) override {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700153 EXPECT_TRUE(consumed_auth_metadata != nullptr);
154 EXPECT_TRUE(context != nullptr);
155 EXPECT_TRUE(response_metadata != nullptr);
Julien Boeuf1928d492015-09-15 15:20:11 -0700156 auto auth_md =
yang-gc580af32016-09-15 15:28:38 -0700157 auth_metadata.find(TestMetadataCredentialsPlugin::kGoodMetadataKey);
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700158 EXPECT_NE(auth_md, auth_metadata.end());
159 string_ref auth_md_value = auth_md->second;
Julien Boeuf1928d492015-09-15 15:20:11 -0700160 if (auth_md_value == kGoodGuy) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700161 context->AddProperty(kIdentityPropName, kGoodGuy);
162 context->SetPeerIdentityPropertyName(kIdentityPropName);
Julien Boeuf8b0b6f42015-09-22 13:31:16 -0700163 consumed_auth_metadata->insert(std::make_pair(
164 string(auth_md->first.data(), auth_md->first.length()),
165 string(auth_md->second.data(), auth_md->second.length())));
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700166 return Status::OK;
167 } else {
168 return Status(StatusCode::UNAUTHENTICATED,
169 string("Invalid principal: ") +
170 string(auth_md_value.data(), auth_md_value.length()));
171 }
172 }
173
Julien Boeuf1928d492015-09-15 15:20:11 -0700174 private:
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700175 static const char kIdentityPropName[];
176 bool is_blocking_;
177};
178
179const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll";
180const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
181
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800182class Proxy : public ::grpc::testing::EchoTestService::Service {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700183 public:
yang-g8c2be9f2015-08-19 16:28:09 -0700184 Proxy(std::shared_ptr<Channel> channel)
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800185 : stub_(grpc::testing::EchoTestService::NewStub(channel)) {}
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700186
187 Status Echo(ServerContext* server_context, const EchoRequest* request,
Vijay Paic0b2acb2016-11-01 16:31:56 -0700188 EchoResponse* response) override {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700189 std::unique_ptr<ClientContext> client_context =
190 ClientContext::FromServerContext(*server_context);
191 return stub_->Echo(client_context.get(), *request, response);
192 }
193
194 private:
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800195 std::unique_ptr< ::grpc::testing::EchoTestService::Stub> stub_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700196};
197
yangg1456d152015-01-08 15:39:58 -0800198class TestServiceImplDupPkg
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800199 : public ::grpc::testing::duplicate::EchoTestService::Service {
yangg1456d152015-01-08 15:39:58 -0800200 public:
201 Status Echo(ServerContext* context, const EchoRequest* request,
Vijay Paic0b2acb2016-11-01 16:31:56 -0700202 EchoResponse* response) override {
yangg1456d152015-01-08 15:39:58 -0800203 response->set_message("no package");
204 return Status::OK;
205 }
206};
207
yang-g88d5d522015-09-29 12:46:54 -0700208class TestScenario {
209 public:
yang-g17197dd2016-02-19 00:04:22 -0800210 TestScenario(bool proxy, const grpc::string& creds_type)
211 : use_proxy(proxy), credentials_type(creds_type) {}
Craig Tillerf658bf02016-12-08 14:11:47 -0800212 void Log() const;
yang-g88d5d522015-09-29 12:46:54 -0700213 bool use_proxy;
Vijay Pai679c75f2016-06-15 13:08:00 -0700214 // Although the below grpc::string is logically const, we can't declare
215 // them const because of a limitation in the way old compilers (e.g., gcc-4.4)
216 // manage vector insertion using a copy constructor
217 grpc::string credentials_type;
yang-g88d5d522015-09-29 12:46:54 -0700218};
219
Craig Tillerf658bf02016-12-08 14:11:47 -0800220static std::ostream& operator<<(std::ostream& out,
221 const TestScenario& scenario) {
222 return out << "TestScenario{use_proxy="
223 << (scenario.use_proxy ? "true" : "false") << ", credentials='"
224 << scenario.credentials_type << "'}";
225}
226
227void TestScenario::Log() const {
228 std::ostringstream out;
229 out << *this;
230 gpr_log(GPR_DEBUG, "%s", out.str().c_str());
231}
232
yang-g88d5d522015-09-29 12:46:54 -0700233class End2endTest : public ::testing::TestWithParam<TestScenario> {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800234 protected:
Vijay Pai181ef452015-07-14 13:52:48 -0700235 End2endTest()
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700236 : is_server_started_(false),
237 kMaxMessageSize_(8192),
yang-g88d5d522015-09-29 12:46:54 -0700238 special_service_("special") {
239 GetParam().Log();
240 }
Craig Tiller7418d012015-02-11 15:25:03 -0800241
Vijay Paic0b2acb2016-11-01 16:31:56 -0700242 void TearDown() override {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700243 if (is_server_started_) {
244 server_->Shutdown();
245 if (proxy_server_) proxy_server_->Shutdown();
246 }
247 }
248
249 void StartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) {
Craig Tiller35e39712015-01-12 16:41:24 -0800250 int port = grpc_pick_unused_port_or_die();
yang-gd7ead692015-07-30 10:57:45 -0700251 server_address_ << "127.0.0.1:" << port;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800252 // Setup server
253 ServerBuilder builder;
Craig Tillerdb1a5cc2016-09-28 14:22:12 -0700254 ConfigureServerBuilder(&builder);
yang-g7d2a3e12016-02-18 15:41:56 -0800255 auto server_creds = GetServerCredentials(GetParam().credentials_type);
yang-g17197dd2016-02-19 00:04:22 -0800256 if (GetParam().credentials_type != kInsecureCredentialsType) {
yang-g88d5d522015-09-29 12:46:54 -0700257 server_creds->SetAuthMetadataProcessor(processor);
258 }
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700259 builder.AddListeningPort(server_address_.str(), server_creds);
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800260 builder.RegisterService(&service_);
yang-g8b25f2a2015-07-21 23:54:36 -0700261 builder.RegisterService("foo.test.youtube.com", &special_service_);
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800262 builder.RegisterService(&dup_pkg_service_);
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700263
Sree Kuchibhotlac37a8a52016-10-13 15:40:15 -0700264 builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4);
265 builder.SetSyncServerOption(
266 ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10);
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700267
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800268 server_ = builder.BuildAndStart();
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700269 is_server_started_ = true;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700270 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800271
Craig Tillerdb1a5cc2016-09-28 14:22:12 -0700272 virtual void ConfigureServerBuilder(ServerBuilder* builder) {
273 builder->SetMaxMessageSize(
274 kMaxMessageSize_); // For testing max message size.
275 }
276
yang-g9b7757d2015-08-13 11:15:53 -0700277 void ResetChannel() {
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700278 if (!is_server_started_) {
279 StartServer(std::shared_ptr<AuthMetadataProcessor>());
280 }
281 EXPECT_TRUE(is_server_started_);
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700282 ChannelArguments args;
yang-g7d2a3e12016-02-18 15:41:56 -0800283 auto channel_creds =
284 GetChannelCredentials(GetParam().credentials_type, &args);
yang-gd59ad7e2016-02-10 12:42:53 -0800285 if (!user_agent_prefix_.empty()) {
286 args.SetUserAgentPrefix(user_agent_prefix_);
287 }
Craig Tiller0dc5e6c2015-07-10 10:07:53 -0700288 args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
yang-g88d5d522015-09-29 12:46:54 -0700289 channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args);
yang-g9b7757d2015-08-13 11:15:53 -0700290 }
291
yang-g88d5d522015-09-29 12:46:54 -0700292 void ResetStub() {
yang-g9b7757d2015-08-13 11:15:53 -0700293 ResetChannel();
yang-g88d5d522015-09-29 12:46:54 -0700294 if (GetParam().use_proxy) {
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700295 proxy_service_.reset(new Proxy(channel_));
296 int port = grpc_pick_unused_port_or_die();
297 std::ostringstream proxyaddr;
298 proxyaddr << "localhost:" << port;
299 ServerBuilder builder;
300 builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials());
301 builder.RegisterService(proxy_service_.get());
Sree Kuchibhotlac37a8a52016-10-13 15:40:15 -0700302
303 builder.SetSyncServerOption(ServerBuilder::SyncServerOption::NUM_CQS, 4);
304 builder.SetSyncServerOption(
305 ServerBuilder::SyncServerOption::CQ_TIMEOUT_MSEC, 10);
Sree Kuchibhotla892dbf42016-09-27 19:42:27 -0700306
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700307 proxy_server_ = builder.BuildAndStart();
308
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700309 channel_ = CreateChannel(proxyaddr.str(), InsecureChannelCredentials());
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700310 }
311
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800312 stub_ = grpc::testing::EchoTestService::NewStub(channel_);
yangg1456d152015-01-08 15:39:58 -0800313 }
314
Julien Boeuf0c711ad2015-08-28 14:10:58 -0700315 bool is_server_started_;
yang-g8c2be9f2015-08-19 16:28:09 -0700316 std::shared_ptr<Channel> channel_;
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800317 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800318 std::unique_ptr<Server> server_;
Craig Tiller2c3be1d2015-08-05 15:59:27 -0700319 std::unique_ptr<Server> proxy_server_;
320 std::unique_ptr<Proxy> proxy_service_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800321 std::ostringstream server_address_;
Yang Gao3921c562015-04-30 16:07:06 -0700322 const int kMaxMessageSize_;
nnoble0c475f02014-12-05 15:37:39 -0800323 TestServiceImpl service_;
Craig Tiller822d2c72015-07-07 16:08:00 -0700324 TestServiceImpl special_service_;
yangg1456d152015-01-08 15:39:58 -0800325 TestServiceImplDupPkg dup_pkg_service_;
yang-gd59ad7e2016-02-10 12:42:53 -0800326 grpc::string user_agent_prefix_;
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800327};
328
yang-gf8174ea2016-02-01 00:09:13 -0800329static void SendRpc(grpc::testing::EchoTestService::Stub* stub, int num_rpcs,
330 bool with_binary_metadata) {
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800331 EchoRequest request;
332 EchoResponse response;
David Garcia Quintasd7d9ce22015-06-30 23:29:03 -0700333 request.set_message("Hello hello hello hello");
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800334
335 for (int i = 0; i < num_rpcs; ++i) {
336 ClientContext context;
yang-gf8174ea2016-02-01 00:09:13 -0800337 if (with_binary_metadata) {
338 char bytes[8] = {'\0', '\1', '\2', '\3', '\4', '\5', '\6', (char)i};
339 context.AddMetadata("custom-bin", grpc::string(bytes, 8));
340 }
Craig Tillerbf6abee2015-07-19 22:31:04 -0700341 context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800342 Status s = stub->Echo(&context, request, &response);
343 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700344 EXPECT_TRUE(s.ok());
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800345 }
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -0800346}
347
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800348// This class is for testing scenarios where RPCs are cancelled on the server
349// by calling ServerContext::TryCancel()
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800350class End2endServerTryCancelTest : public End2endTest {
351 protected:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800352 // Helper for testing client-streaming RPCs which are cancelled on the server.
353 // Depending on the value of server_try_cancel parameter, this will test one
354 // of the following three scenarios:
355 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading
356 // any messages from the client
357 //
358 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading
359 // messages from the client
360 //
361 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading all
362 // the messages from the client
363 //
364 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800365 void TestRequestStreamServerCancel(
366 ServerTryCancelRequestPhase server_try_cancel, int num_msgs_to_send) {
367 ResetStub();
368 EchoRequest request;
369 EchoResponse response;
370 ClientContext context;
371
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800372 // Send server_try_cancel value in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800373 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700374 grpc::to_string(server_try_cancel));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800375
376 auto stream = stub_->RequestStream(&context, &response);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800377
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800378 int num_msgs_sent = 0;
379 while (num_msgs_sent < num_msgs_to_send) {
380 request.set_message("hello");
381 if (!stream->Write(request)) {
382 break;
383 }
384 num_msgs_sent++;
385 }
386 gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800387
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800388 stream->WritesDone();
389 Status s = stream->Finish();
390
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800391 // At this point, we know for sure that RPC was cancelled by the server
392 // since we passed server_try_cancel value in the metadata. Depending on the
393 // value of server_try_cancel, the RPC might have been cancelled by the
394 // server at different stages. The following validates our expectations of
395 // number of messages sent in various cancellation scenarios:
396
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800397 switch (server_try_cancel) {
398 case CANCEL_BEFORE_PROCESSING:
399 case CANCEL_DURING_PROCESSING:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800400 // If the RPC is cancelled by server before / during messages from the
401 // client, it means that the client most likely did not get a chance to
402 // send all the messages it wanted to send. i.e num_msgs_sent <=
403 // num_msgs_to_send
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800404 EXPECT_LE(num_msgs_sent, num_msgs_to_send);
405 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800406
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800407 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800408 // If the RPC was cancelled after all messages were read by the server,
409 // the client did get a chance to send all its messages
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800410 EXPECT_EQ(num_msgs_sent, num_msgs_to_send);
411 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800412
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800413 default:
414 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
415 server_try_cancel);
416 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
417 server_try_cancel <= CANCEL_AFTER_PROCESSING);
418 break;
419 }
420
421 EXPECT_FALSE(s.ok());
422 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
423 }
424
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800425 // Helper for testing server-streaming RPCs which are cancelled on the server.
426 // Depending on the value of server_try_cancel parameter, this will test one
427 // of the following three scenarios:
428 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before writing
429 // any messages to the client
430 //
431 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while writing
432 // messages to the client
433 //
434 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after writing all
435 // the messages to the client
436 //
437 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800438 void TestResponseStreamServerCancel(
439 ServerTryCancelRequestPhase server_try_cancel) {
440 ResetStub();
441 EchoRequest request;
442 EchoResponse response;
443 ClientContext context;
444
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800445 // Send server_try_cancel in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800446 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700447 grpc::to_string(server_try_cancel));
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800448
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800449 request.set_message("hello");
450 auto stream = stub_->ResponseStream(&context, request);
451
452 int num_msgs_read = 0;
453 while (num_msgs_read < kNumResponseStreamsMsgs) {
454 if (!stream->Read(&response)) {
455 break;
456 }
457 EXPECT_EQ(response.message(),
Vijay Paia63271c2016-06-15 12:56:38 -0700458 request.message() + grpc::to_string(num_msgs_read));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800459 num_msgs_read++;
460 }
461 gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
462
463 Status s = stream->Finish();
464
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800465 // Depending on the value of server_try_cancel, the RPC might have been
466 // cancelled by the server at different stages. The following validates our
467 // expectations of number of messages read in various cancellation
468 // scenarios:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800469 switch (server_try_cancel) {
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800470 case CANCEL_BEFORE_PROCESSING:
471 // Server cancelled before sending any messages. Which means the client
472 // wouldn't have read any
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800473 EXPECT_EQ(num_msgs_read, 0);
474 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800475
476 case CANCEL_DURING_PROCESSING:
477 // Server cancelled while writing messages. Client must have read less
478 // than or equal to the expected number of messages
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800479 EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
480 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800481
482 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla8d543e82016-02-29 18:22:25 -0800483 // Even though the Server cancelled after writing all messages, the RPC
484 // may be cancelled before the Client got a chance to read all the
485 // messages.
486 EXPECT_LE(num_msgs_read, kNumResponseStreamsMsgs);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800487 break;
488
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800489 default: {
490 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
491 server_try_cancel);
492 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
493 server_try_cancel <= CANCEL_AFTER_PROCESSING);
494 break;
495 }
496 }
497
498 EXPECT_FALSE(s.ok());
499 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
500 }
501
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800502 // Helper for testing bidirectional-streaming RPCs which are cancelled on the
503 // server. Depending on the value of server_try_cancel parameter, this will
504 // test one of the following three scenarios:
505 // CANCEL_BEFORE_PROCESSING: Rpc is cancelled by the server before reading/
506 // writing any messages from/to the client
507 //
508 // CANCEL_DURING_PROCESSING: Rpc is cancelled by the server while reading/
509 // writing messages from/to the client
510 //
511 // CANCEL_AFTER PROCESSING: Rpc is cancelled by server after reading/writing
512 // all the messages from/to the client
513 //
514 // NOTE: Do not call this function with server_try_cancel == DO_NOT_CANCEL.
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800515 void TestBidiStreamServerCancel(ServerTryCancelRequestPhase server_try_cancel,
516 int num_messages) {
517 ResetStub();
518 EchoRequest request;
519 EchoResponse response;
520 ClientContext context;
521
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800522 // Send server_try_cancel in the client metadata
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800523 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700524 grpc::to_string(server_try_cancel));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800525
526 auto stream = stub_->BidiStream(&context);
527
528 int num_msgs_read = 0;
529 int num_msgs_sent = 0;
530 while (num_msgs_sent < num_messages) {
Vijay Paia63271c2016-06-15 12:56:38 -0700531 request.set_message("hello " + grpc::to_string(num_msgs_sent));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800532 if (!stream->Write(request)) {
533 break;
534 }
535 num_msgs_sent++;
536
537 if (!stream->Read(&response)) {
538 break;
539 }
540 num_msgs_read++;
541
542 EXPECT_EQ(response.message(), request.message());
543 }
544 gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent);
545 gpr_log(GPR_INFO, "Read %d messages", num_msgs_read);
546
547 stream->WritesDone();
548 Status s = stream->Finish();
549
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800550 // Depending on the value of server_try_cancel, the RPC might have been
551 // cancelled by the server at different stages. The following validates our
552 // expectations of number of messages read in various cancellation
553 // scenarios:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800554 switch (server_try_cancel) {
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800555 case CANCEL_BEFORE_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800556 EXPECT_EQ(num_msgs_read, 0);
557 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800558
559 case CANCEL_DURING_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800560 EXPECT_LE(num_msgs_sent, num_messages);
561 EXPECT_LE(num_msgs_read, num_msgs_sent);
562 break;
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800563
564 case CANCEL_AFTER_PROCESSING:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800565 EXPECT_EQ(num_msgs_sent, num_messages);
Sree Kuchibhotla8d543e82016-02-29 18:22:25 -0800566
567 // The Server cancelled after reading the last message and after writing
568 // the message to the client. However, the RPC cancellation might have
569 // taken effect before the client actually read the response.
570 EXPECT_LE(num_msgs_read, num_msgs_sent);
Sree Kuchibhotla0f242ac2016-01-29 18:12:19 -0800571 break;
572
573 default:
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800574 gpr_log(GPR_ERROR, "Invalid server_try_cancel value: %d",
575 server_try_cancel);
576 EXPECT_TRUE(server_try_cancel > DO_NOT_CANCEL &&
577 server_try_cancel <= CANCEL_AFTER_PROCESSING);
578 break;
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800579 }
580
581 EXPECT_FALSE(s.ok());
582 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
583 }
584};
585
586TEST_P(End2endServerTryCancelTest, RequestEchoServerCancel) {
587 ResetStub();
588 EchoRequest request;
589 EchoResponse response;
590 ClientContext context;
591
592 context.AddMetadata(kServerTryCancelRequest,
Vijay Paia63271c2016-06-15 12:56:38 -0700593 grpc::to_string(CANCEL_BEFORE_PROCESSING));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -0800594 Status s = stub_->Echo(&context, request, &response);
595 EXPECT_FALSE(s.ok());
596 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
597}
598
599// Server to cancel before doing reading the request
600TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelBeforeReads) {
601 TestRequestStreamServerCancel(CANCEL_BEFORE_PROCESSING, 1);
602}
603
604// Server to cancel while reading a request from the stream in parallel
605TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelDuringRead) {
606 TestRequestStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
607}
608
609// Server to cancel after reading all the requests but before returning to the
610// client
611TEST_P(End2endServerTryCancelTest, RequestStreamServerCancelAfterReads) {
612 TestRequestStreamServerCancel(CANCEL_AFTER_PROCESSING, 4);
613}
614
615// Server to cancel before sending any response messages
616TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelBefore) {
617 TestResponseStreamServerCancel(CANCEL_BEFORE_PROCESSING);
618}
619
620// Server to cancel while writing a response to the stream in parallel
621TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelDuring) {
622 TestResponseStreamServerCancel(CANCEL_DURING_PROCESSING);
623}
624
625// Server to cancel after writing all the respones to the stream but before
626// returning to the client
627TEST_P(End2endServerTryCancelTest, ResponseStreamServerCancelAfter) {
628 TestResponseStreamServerCancel(CANCEL_AFTER_PROCESSING);
629}
630
631// Server to cancel before reading/writing any requests/responses on the stream
632TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelBefore) {
633 TestBidiStreamServerCancel(CANCEL_BEFORE_PROCESSING, 2);
634}
635
636// Server to cancel while reading/writing requests/responses on the stream in
637// parallel
638TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelDuring) {
639 TestBidiStreamServerCancel(CANCEL_DURING_PROCESSING, 10);
640}
641
642// Server to cancel after reading/writing all requests/responses on the stream
643// but before returning to the client
644TEST_P(End2endServerTryCancelTest, BidiStreamServerCancelAfter) {
645 TestBidiStreamServerCancel(CANCEL_AFTER_PROCESSING, 5);
646}
647
Craig Tillerf658bf02016-12-08 14:11:47 -0800648TEST_P(End2endTest, SimpleRpcWithCustomUserAgentPrefix) {
yang-gd59ad7e2016-02-10 12:42:53 -0800649 user_agent_prefix_ = "custom_prefix";
650 ResetStub();
651 EchoRequest request;
652 EchoResponse response;
653 request.set_message("Hello hello hello hello");
654 request.mutable_param()->set_echo_metadata(true);
655
656 ClientContext context;
657 Status s = stub_->Echo(&context, request, &response);
658 EXPECT_EQ(response.message(), request.message());
659 EXPECT_TRUE(s.ok());
660 const auto& trailing_metadata = context.GetServerTrailingMetadata();
661 auto iter = trailing_metadata.find("user-agent");
662 EXPECT_TRUE(iter != trailing_metadata.end());
663 grpc::string expected_prefix = user_agent_prefix_ + " grpc-c++/";
Mark D. Rothe3a21002016-10-24 13:29:05 -0700664 EXPECT_TRUE(iter->second.starts_with(expected_prefix)) << iter->second;
yang-gd59ad7e2016-02-10 12:42:53 -0800665}
666
yang-gf8174ea2016-02-01 00:09:13 -0800667TEST_P(End2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
668 ResetStub();
Vijay Paib0a6be22016-11-03 12:45:02 -0700669 std::vector<std::thread> threads;
yang-gf8174ea2016-02-01 00:09:13 -0800670 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -0700671 threads.emplace_back(SendRpc, stub_.get(), 10, true);
yang-gf8174ea2016-02-01 00:09:13 -0800672 }
673 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -0700674 threads[i].join();
yang-gf8174ea2016-02-01 00:09:13 -0800675 }
676}
677
678TEST_P(End2endTest, MultipleRpcs) {
679 ResetStub();
Vijay Paib0a6be22016-11-03 12:45:02 -0700680 std::vector<std::thread> threads;
yang-gf8174ea2016-02-01 00:09:13 -0800681 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -0700682 threads.emplace_back(SendRpc, stub_.get(), 10, false);
yang-gf8174ea2016-02-01 00:09:13 -0800683 }
684 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -0700685 threads[i].join();
yang-gf8174ea2016-02-01 00:09:13 -0800686 }
687}
688
yang-g88d5d522015-09-29 12:46:54 -0700689TEST_P(End2endTest, RequestStreamOneRequest) {
690 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800691 EchoRequest request;
692 EchoResponse response;
693 ClientContext context;
694
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800695 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800696 request.set_message("hello");
697 EXPECT_TRUE(stream->Write(request));
698 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800699 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800700 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700701 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800702}
703
yang-g88d5d522015-09-29 12:46:54 -0700704TEST_P(End2endTest, RequestStreamTwoRequests) {
705 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800706 EchoRequest request;
707 EchoResponse response;
708 ClientContext context;
709
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800710 auto stream = stub_->RequestStream(&context, &response);
nnoble0c475f02014-12-05 15:37:39 -0800711 request.set_message("hello");
712 EXPECT_TRUE(stream->Write(request));
713 EXPECT_TRUE(stream->Write(request));
714 stream->WritesDone();
Craig Tillerf8ac5d82015-02-09 16:24:20 -0800715 Status s = stream->Finish();
nnoble0c475f02014-12-05 15:37:39 -0800716 EXPECT_EQ(response.message(), "hellohello");
Yang Gaoc1a2c312015-06-16 10:59:46 -0700717 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800718}
719
yang-g88d5d522015-09-29 12:46:54 -0700720TEST_P(End2endTest, ResponseStream) {
721 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800722 EchoRequest request;
723 EchoResponse response;
724 ClientContext context;
725 request.set_message("hello");
726
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800727 auto stream = stub_->ResponseStream(&context, request);
nnoble0c475f02014-12-05 15:37:39 -0800728 EXPECT_TRUE(stream->Read(&response));
729 EXPECT_EQ(response.message(), request.message() + "0");
730 EXPECT_TRUE(stream->Read(&response));
731 EXPECT_EQ(response.message(), request.message() + "1");
732 EXPECT_TRUE(stream->Read(&response));
733 EXPECT_EQ(response.message(), request.message() + "2");
734 EXPECT_FALSE(stream->Read(&response));
735
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800736 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700737 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800738}
739
yang-g88d5d522015-09-29 12:46:54 -0700740TEST_P(End2endTest, BidiStream) {
741 ResetStub();
nnoble0c475f02014-12-05 15:37:39 -0800742 EchoRequest request;
743 EchoResponse response;
744 ClientContext context;
745 grpc::string msg("hello");
746
Craig Tillerfd1b49b2015-02-23 12:53:39 -0800747 auto stream = stub_->BidiStream(&context);
nnoble0c475f02014-12-05 15:37:39 -0800748
749 request.set_message(msg + "0");
750 EXPECT_TRUE(stream->Write(request));
751 EXPECT_TRUE(stream->Read(&response));
752 EXPECT_EQ(response.message(), request.message());
753
754 request.set_message(msg + "1");
755 EXPECT_TRUE(stream->Write(request));
756 EXPECT_TRUE(stream->Read(&response));
757 EXPECT_EQ(response.message(), request.message());
758
759 request.set_message(msg + "2");
760 EXPECT_TRUE(stream->Write(request));
761 EXPECT_TRUE(stream->Read(&response));
762 EXPECT_EQ(response.message(), request.message());
763
764 stream->WritesDone();
765 EXPECT_FALSE(stream->Read(&response));
Craig Tillerca9a6372015-12-15 18:16:28 -0800766 EXPECT_FALSE(stream->Read(&response));
nnoble0c475f02014-12-05 15:37:39 -0800767
Craig Tiller4d0fb5f2015-02-09 16:27:22 -0800768 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700769 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800770}
771
772// Talk to the two services with the same name but different package names.
773// The two stubs are created on the same channel.
yang-g88d5d522015-09-29 12:46:54 -0700774TEST_P(End2endTest, DiffPackageServices) {
775 ResetStub();
yangg1456d152015-01-08 15:39:58 -0800776 EchoRequest request;
777 EchoResponse response;
778 request.set_message("Hello");
779
yangg1456d152015-01-08 15:39:58 -0800780 ClientContext context;
yang-g8b25f2a2015-07-21 23:54:36 -0700781 Status s = stub_->Echo(&context, request, &response);
yangg1456d152015-01-08 15:39:58 -0800782 EXPECT_EQ(response.message(), request.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700783 EXPECT_TRUE(s.ok());
yangg1456d152015-01-08 15:39:58 -0800784
Sree Kuchibhotla5a05f512016-01-13 22:43:20 -0800785 std::unique_ptr<grpc::testing::duplicate::EchoTestService::Stub> dup_pkg_stub(
786 grpc::testing::duplicate::EchoTestService::NewStub(channel_));
yangg1456d152015-01-08 15:39:58 -0800787 ClientContext context2;
788 s = dup_pkg_stub->Echo(&context2, request, &response);
789 EXPECT_EQ("no package", response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700790 EXPECT_TRUE(s.ok());
nnoble0c475f02014-12-05 15:37:39 -0800791}
792
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700793void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
Craig Tiller20b5fe92015-07-06 10:43:50 -0700794 gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
Craig Tiller677c50c2015-07-13 10:49:06 -0700795 gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
Yang Gao0c4b0dd2015-03-30 13:08:34 -0700796 while (!service->signal_client()) {
797 }
798 context->TryCancel();
799}
800
yang-ga89bf502015-11-17 14:19:17 -0800801TEST_P(End2endTest, CancelRpcBeforeStart) {
802 ResetStub();
803 EchoRequest request;
804 EchoResponse response;
805 ClientContext context;
806 request.set_message("hello");
807 context.TryCancel();
808 Status s = stub_->Echo(&context, request, &response);
809 EXPECT_EQ("", response.message());
810 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
811}
812
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700813// Client cancels request stream after sending two messages
yang-g88d5d522015-09-29 12:46:54 -0700814TEST_P(End2endTest, ClientCancelsRequestStream) {
815 ResetStub();
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700816 EchoRequest request;
817 EchoResponse response;
818 ClientContext context;
819 request.set_message("hello");
820
821 auto stream = stub_->RequestStream(&context, &response);
822 EXPECT_TRUE(stream->Write(request));
823 EXPECT_TRUE(stream->Write(request));
Yang Gaoc71a9d22015-05-04 00:22:12 -0700824
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700825 context.TryCancel();
826
827 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700828 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700829
Yang Gaoc71a9d22015-05-04 00:22:12 -0700830 EXPECT_EQ(response.message(), "");
Abhishek Kumard774c5c2015-04-23 14:59:49 -0700831}
832
Abhishek Kumare41d0402015-04-17 14:12:33 -0700833// Client cancels server stream after sending some messages
yang-g88d5d522015-09-29 12:46:54 -0700834TEST_P(End2endTest, ClientCancelsResponseStream) {
835 ResetStub();
Abhishek Kumare41d0402015-04-17 14:12:33 -0700836 EchoRequest request;
837 EchoResponse response;
838 ClientContext context;
839 request.set_message("hello");
840
841 auto stream = stub_->ResponseStream(&context, request);
842
843 EXPECT_TRUE(stream->Read(&response));
844 EXPECT_EQ(response.message(), request.message() + "0");
845 EXPECT_TRUE(stream->Read(&response));
846 EXPECT_EQ(response.message(), request.message() + "1");
847
848 context.TryCancel();
849
850 // The cancellation races with responses, so there might be zero or
851 // one responses pending, read till failure
852
853 if (stream->Read(&response)) {
854 EXPECT_EQ(response.message(), request.message() + "2");
855 // Since we have cancelled, we expect the next attempt to read to fail
856 EXPECT_FALSE(stream->Read(&response));
857 }
858
859 Status s = stream->Finish();
Abhishek Kumar18298a72015-04-17 15:00:25 -0700860 // The final status could be either of CANCELLED or OK depending on
861 // who won the race.
Yang Gaoc1a2c312015-06-16 10:59:46 -0700862 EXPECT_GE(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumare41d0402015-04-17 14:12:33 -0700863}
864
Abhishek Kumar82a83312015-04-17 13:30:51 -0700865// Client cancels bidi stream after sending some messages
yang-g88d5d522015-09-29 12:46:54 -0700866TEST_P(End2endTest, ClientCancelsBidi) {
867 ResetStub();
Abhishek Kumar82a83312015-04-17 13:30:51 -0700868 EchoRequest request;
869 EchoResponse response;
870 ClientContext context;
871 grpc::string msg("hello");
872
873 auto stream = stub_->BidiStream(&context);
874
875 request.set_message(msg + "0");
876 EXPECT_TRUE(stream->Write(request));
877 EXPECT_TRUE(stream->Read(&response));
878 EXPECT_EQ(response.message(), request.message());
879
880 request.set_message(msg + "1");
881 EXPECT_TRUE(stream->Write(request));
882
883 context.TryCancel();
884
885 // The cancellation races with responses, so there might be zero or
886 // one responses pending, read till failure
887
888 if (stream->Read(&response)) {
889 EXPECT_EQ(response.message(), request.message());
890 // Since we have cancelled, we expect the next attempt to read to fail
891 EXPECT_FALSE(stream->Read(&response));
892 }
893
894 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700895 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
Abhishek Kumar82a83312015-04-17 13:30:51 -0700896}
897
yang-g88d5d522015-09-29 12:46:54 -0700898TEST_P(End2endTest, RpcMaxMessageSize) {
899 ResetStub();
Yang Gao3921c562015-04-30 16:07:06 -0700900 EchoRequest request;
901 EchoResponse response;
Yang Gaoc71a9d22015-05-04 00:22:12 -0700902 request.set_message(string(kMaxMessageSize_ * 2, 'a'));
Yang Gao3921c562015-04-30 16:07:06 -0700903
904 ClientContext context;
905 Status s = stub_->Echo(&context, request, &response);
Yang Gaoc1a2c312015-06-16 10:59:46 -0700906 EXPECT_FALSE(s.ok());
Yang Gao3921c562015-04-30 16:07:06 -0700907}
Abhishek Kumar82a83312015-04-17 13:30:51 -0700908
yang-g88d5d522015-09-29 12:46:54 -0700909// Client sends 20 requests and the server returns CANCELLED status after
910// reading 10 requests.
911TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
912 ResetStub();
913 EchoRequest request;
914 EchoResponse response;
915 ClientContext context;
916
917 context.AddMetadata(kServerCancelAfterReads, "10");
918 auto stream = stub_->RequestStream(&context, &response);
919 request.set_message("hello");
920 int send_messages = 20;
yang-gc0461032015-10-02 16:22:43 -0700921 while (send_messages > 10) {
yang-g88d5d522015-09-29 12:46:54 -0700922 EXPECT_TRUE(stream->Write(request));
923 send_messages--;
924 }
yang-gc0461032015-10-02 16:22:43 -0700925 while (send_messages > 0) {
926 stream->Write(request);
927 send_messages--;
928 }
yang-g88d5d522015-09-29 12:46:54 -0700929 stream->WritesDone();
930 Status s = stream->Finish();
931 EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
932}
933
yang-g88d5d522015-09-29 12:46:54 -0700934void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
935 gpr_event* ev) {
936 EchoResponse resp;
937 gpr_event_set(ev, (void*)1);
938 while (stream->Read(&resp)) {
939 gpr_log(GPR_INFO, "Read message");
940 }
941}
yang-g88d5d522015-09-29 12:46:54 -0700942
943// Run a Read and a WritesDone simultaneously.
944TEST_P(End2endTest, SimultaneousReadWritesDone) {
945 ResetStub();
946 ClientContext context;
947 gpr_event ev;
948 gpr_event_init(&ev);
949 auto stream = stub_->BidiStream(&context);
950 std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
951 gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
952 stream->WritesDone();
Vijay Paibdfec2c2016-02-25 11:51:21 -0800953 reader_thread.join();
yang-g88d5d522015-09-29 12:46:54 -0700954 Status s = stream->Finish();
955 EXPECT_TRUE(s.ok());
yang-g88d5d522015-09-29 12:46:54 -0700956}
957
958TEST_P(End2endTest, ChannelState) {
959 ResetStub();
960 // Start IDLE
961 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
962
963 // Did not ask to connect, no state change.
964 CompletionQueue cq;
965 std::chrono::system_clock::time_point deadline =
966 std::chrono::system_clock::now() + std::chrono::milliseconds(10);
967 channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL);
968 void* tag;
969 bool ok = true;
970 cq.Next(&tag, &ok);
971 EXPECT_FALSE(ok);
972
973 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true));
974 EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE,
975 gpr_inf_future(GPR_CLOCK_REALTIME)));
yang-g0d557502015-10-01 11:30:12 -0700976 auto state = channel_->GetState(false);
977 EXPECT_TRUE(state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_READY);
yang-g88d5d522015-09-29 12:46:54 -0700978}
979
980// Takes 10s.
981TEST_P(End2endTest, ChannelStateTimeout) {
yang-g17197dd2016-02-19 00:04:22 -0800982 if (GetParam().credentials_type != kInsecureCredentialsType) {
yang-g88d5d522015-09-29 12:46:54 -0700983 return;
984 }
985 int port = grpc_pick_unused_port_or_die();
986 std::ostringstream server_address;
987 server_address << "127.0.0.1:" << port;
988 // Channel to non-existing server
Julien Boeufe5adc0e2015-10-12 14:08:10 -0700989 auto channel =
990 CreateChannel(server_address.str(), InsecureChannelCredentials());
yang-g88d5d522015-09-29 12:46:54 -0700991 // Start IDLE
992 EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
993
994 auto state = GRPC_CHANNEL_IDLE;
995 for (int i = 0; i < 10; i++) {
996 channel->WaitForStateChange(
997 state, std::chrono::system_clock::now() + std::chrono::seconds(1));
998 state = channel->GetState(false);
999 }
1000}
1001
1002// Talking to a non-existing service.
1003TEST_P(End2endTest, NonExistingService) {
1004 ResetChannel();
murgatroid997c5befd2016-09-01 17:09:47 -07001005 std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
1006 stub = grpc::testing::UnimplementedEchoService::NewStub(channel_);
yang-g88d5d522015-09-29 12:46:54 -07001007
1008 EchoRequest request;
1009 EchoResponse response;
1010 request.set_message("Hello");
1011
1012 ClientContext context;
1013 Status s = stub->Unimplemented(&context, request, &response);
1014 EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
1015 EXPECT_EQ("", s.error_message());
1016}
1017
yang-g4c070082016-05-05 23:27:13 -07001018// Ask the server to send back a serialized proto in trailer.
1019// This is an example of setting error details.
1020TEST_P(End2endTest, BinaryTrailerTest) {
1021 ResetStub();
1022 EchoRequest request;
1023 EchoResponse response;
1024 ClientContext context;
1025
1026 request.mutable_param()->set_echo_metadata(true);
1027 DebugInfo* info = request.mutable_param()->mutable_debug_info();
1028 info->add_stack_entries("stack_entry_1");
1029 info->add_stack_entries("stack_entry_2");
1030 info->add_stack_entries("stack_entry_3");
1031 info->set_detail("detailed debug info");
1032 grpc::string expected_string = info->SerializeAsString();
1033 request.set_message("Hello");
1034
1035 Status s = stub_->Echo(&context, request, &response);
1036 EXPECT_FALSE(s.ok());
1037 auto trailers = context.GetServerTrailingMetadata();
yang-g39e71c32016-05-10 10:21:41 -07001038 EXPECT_EQ(1u, trailers.count(kDebugInfoTrailerKey));
yang-g4c070082016-05-05 23:27:13 -07001039 auto iter = trailers.find(kDebugInfoTrailerKey);
1040 EXPECT_EQ(expected_string, iter->second);
yang-g080528a2016-05-06 13:12:00 -07001041 // Parse the returned trailer into a DebugInfo proto.
1042 DebugInfo returned_info;
1043 EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second)));
yang-g4c070082016-05-05 23:27:13 -07001044}
1045
yang-g88d5d522015-09-29 12:46:54 -07001046//////////////////////////////////////////////////////////////////////////
1047// Test with and without a proxy.
1048class ProxyEnd2endTest : public End2endTest {
1049 protected:
1050};
1051
1052TEST_P(ProxyEnd2endTest, SimpleRpc) {
1053 ResetStub();
yang-gf8174ea2016-02-01 00:09:13 -08001054 SendRpc(stub_.get(), 1, false);
yang-g88d5d522015-09-29 12:46:54 -07001055}
1056
yang-g000aa452016-06-07 13:08:39 -07001057TEST_P(ProxyEnd2endTest, SimpleRpcWithEmptyMessages) {
1058 ResetStub();
1059 EchoRequest request;
1060 EchoResponse response;
1061
1062 ClientContext context;
1063 Status s = stub_->Echo(&context, request, &response);
1064 EXPECT_TRUE(s.ok());
1065}
1066
yang-g88d5d522015-09-29 12:46:54 -07001067TEST_P(ProxyEnd2endTest, MultipleRpcs) {
1068 ResetStub();
Vijay Paib0a6be22016-11-03 12:45:02 -07001069 std::vector<std::thread> threads;
yang-g88d5d522015-09-29 12:46:54 -07001070 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -07001071 threads.emplace_back(SendRpc, stub_.get(), 10, false);
yang-g88d5d522015-09-29 12:46:54 -07001072 }
1073 for (int i = 0; i < 10; ++i) {
Vijay Paib0a6be22016-11-03 12:45:02 -07001074 threads[i].join();
yang-g88d5d522015-09-29 12:46:54 -07001075 }
1076}
1077
1078// Set a 10us deadline and make sure proper error is returned.
1079TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) {
1080 ResetStub();
1081 EchoRequest request;
1082 EchoResponse response;
1083 request.set_message("Hello");
Craig Tillerb0f275e2016-01-27 10:45:50 -08001084 request.mutable_param()->set_skip_cancelled_check(true);
yang-g88d5d522015-09-29 12:46:54 -07001085
1086 ClientContext context;
1087 std::chrono::system_clock::time_point deadline =
1088 std::chrono::system_clock::now() + std::chrono::microseconds(10);
1089 context.set_deadline(deadline);
1090 Status s = stub_->Echo(&context, request, &response);
1091 EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
1092}
1093
1094// Set a long but finite deadline.
1095TEST_P(ProxyEnd2endTest, RpcLongDeadline) {
1096 ResetStub();
1097 EchoRequest request;
1098 EchoResponse response;
1099 request.set_message("Hello");
1100
1101 ClientContext context;
1102 std::chrono::system_clock::time_point deadline =
1103 std::chrono::system_clock::now() + std::chrono::hours(1);
1104 context.set_deadline(deadline);
1105 Status s = stub_->Echo(&context, request, &response);
1106 EXPECT_EQ(response.message(), request.message());
1107 EXPECT_TRUE(s.ok());
1108}
1109
1110// Ask server to echo back the deadline it sees.
1111TEST_P(ProxyEnd2endTest, EchoDeadline) {
1112 ResetStub();
1113 EchoRequest request;
1114 EchoResponse response;
1115 request.set_message("Hello");
1116 request.mutable_param()->set_echo_deadline(true);
1117
1118 ClientContext context;
1119 std::chrono::system_clock::time_point deadline =
1120 std::chrono::system_clock::now() + std::chrono::seconds(100);
1121 context.set_deadline(deadline);
1122 Status s = stub_->Echo(&context, request, &response);
1123 EXPECT_EQ(response.message(), request.message());
1124 EXPECT_TRUE(s.ok());
1125 gpr_timespec sent_deadline;
1126 Timepoint2Timespec(deadline, &sent_deadline);
1127 // Allow 1 second error.
1128 EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
1129 EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
1130}
1131
1132// Ask server to echo back the deadline it sees. The rpc has no deadline.
1133TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) {
1134 ResetStub();
1135 EchoRequest request;
1136 EchoResponse response;
1137 request.set_message("Hello");
1138 request.mutable_param()->set_echo_deadline(true);
1139
1140 ClientContext context;
1141 Status s = stub_->Echo(&context, request, &response);
1142 EXPECT_EQ(response.message(), request.message());
1143 EXPECT_TRUE(s.ok());
1144 EXPECT_EQ(response.param().request_deadline(),
1145 gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
1146}
1147
1148TEST_P(ProxyEnd2endTest, UnimplementedRpc) {
1149 ResetStub();
1150 EchoRequest request;
1151 EchoResponse response;
1152 request.set_message("Hello");
1153
1154 ClientContext context;
1155 Status s = stub_->Unimplemented(&context, request, &response);
1156 EXPECT_FALSE(s.ok());
1157 EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
1158 EXPECT_EQ(s.error_message(), "");
1159 EXPECT_EQ(response.message(), "");
1160}
1161
1162// Client cancels rpc after 10ms
1163TEST_P(ProxyEnd2endTest, ClientCancelsRpc) {
1164 ResetStub();
1165 EchoRequest request;
1166 EchoResponse response;
1167 request.set_message("Hello");
1168 const int kCancelDelayUs = 10 * 1000;
1169 request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
1170
1171 ClientContext context;
1172 std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
1173 Status s = stub_->Echo(&context, request, &response);
1174 cancel_thread.join();
1175 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
1176 EXPECT_EQ(s.error_message(), "Cancelled");
1177}
1178
1179// Server cancels rpc after 1ms
1180TEST_P(ProxyEnd2endTest, ServerCancelsRpc) {
1181 ResetStub();
1182 EchoRequest request;
1183 EchoResponse response;
1184 request.set_message("Hello");
1185 request.mutable_param()->set_server_cancel_after_us(1000);
1186
1187 ClientContext context;
1188 Status s = stub_->Echo(&context, request, &response);
1189 EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
1190 EXPECT_TRUE(s.error_message().empty());
1191}
1192
1193// Make the response larger than the flow control window.
1194TEST_P(ProxyEnd2endTest, HugeResponse) {
1195 ResetStub();
1196 EchoRequest request;
1197 EchoResponse response;
1198 request.set_message("huge response");
1199 const size_t kResponseSize = 1024 * (1024 + 10);
1200 request.mutable_param()->set_response_message_length(kResponseSize);
1201
1202 ClientContext context;
Craig Tiller6c8619b2016-07-07 10:41:48 -07001203 std::chrono::system_clock::time_point deadline =
1204 std::chrono::system_clock::now() + std::chrono::seconds(20);
1205 context.set_deadline(deadline);
yang-g88d5d522015-09-29 12:46:54 -07001206 Status s = stub_->Echo(&context, request, &response);
1207 EXPECT_EQ(kResponseSize, response.message().size());
1208 EXPECT_TRUE(s.ok());
1209}
1210
1211TEST_P(ProxyEnd2endTest, Peer) {
1212 ResetStub();
1213 EchoRequest request;
1214 EchoResponse response;
1215 request.set_message("hello");
1216 request.mutable_param()->set_echo_peer(true);
1217
1218 ClientContext context;
1219 Status s = stub_->Echo(&context, request, &response);
1220 EXPECT_EQ(response.message(), request.message());
1221 EXPECT_TRUE(s.ok());
1222 EXPECT_TRUE(CheckIsLocalhost(response.param().peer()));
1223 EXPECT_TRUE(CheckIsLocalhost(context.peer()));
1224}
1225
1226//////////////////////////////////////////////////////////////////////////
1227class SecureEnd2endTest : public End2endTest {
1228 protected:
1229 SecureEnd2endTest() {
1230 GPR_ASSERT(!GetParam().use_proxy);
yang-g17197dd2016-02-19 00:04:22 -08001231 GPR_ASSERT(GetParam().credentials_type != kInsecureCredentialsType);
yang-g88d5d522015-09-29 12:46:54 -07001232 }
1233};
1234
1235TEST_P(SecureEnd2endTest, SimpleRpcWithHost) {
1236 ResetStub();
1237
1238 EchoRequest request;
1239 EchoResponse response;
1240 request.set_message("Hello");
1241
1242 ClientContext context;
1243 context.set_authority("foo.test.youtube.com");
1244 Status s = stub_->Echo(&context, request, &response);
1245 EXPECT_EQ(response.message(), request.message());
1246 EXPECT_TRUE(response.has_param());
1247 EXPECT_EQ("special", response.param().host());
1248 EXPECT_TRUE(s.ok());
1249}
1250
yang-ge21908f2015-08-25 13:47:51 -07001251bool MetadataContains(
1252 const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
1253 const grpc::string& key, const grpc::string& value) {
Yang Gao26a49122015-05-15 17:02:56 -07001254 int count = 0;
1255
yang-ge21908f2015-08-25 13:47:51 -07001256 for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
Yang Gao26a49122015-05-15 17:02:56 -07001257 metadata.begin();
1258 iter != metadata.end(); ++iter) {
yang-ge21908f2015-08-25 13:47:51 -07001259 if (ToString(iter->first) == key && ToString(iter->second) == value) {
Yang Gao26a49122015-05-15 17:02:56 -07001260 count++;
1261 }
1262 }
1263 return count == 1;
1264}
1265
yang-g88d5d522015-09-29 12:46:54 -07001266TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) {
1267 auto* processor = new TestAuthMetadataProcessor(true);
1268 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
1269 ResetStub();
1270 EchoRequest request;
1271 EchoResponse response;
1272 ClientContext context;
1273 context.set_credentials(processor->GetCompatibleClientCreds());
1274 request.set_message("Hello");
1275 request.mutable_param()->set_echo_metadata(true);
1276 request.mutable_param()->set_expected_client_identity(
1277 TestAuthMetadataProcessor::kGoodGuy);
Dan Bornf2f7d572016-03-03 17:26:12 -08001278 request.mutable_param()->set_expected_transport_security_type(
1279 GetParam().credentials_type);
yang-g88d5d522015-09-29 12:46:54 -07001280
1281 Status s = stub_->Echo(&context, request, &response);
1282 EXPECT_EQ(request.message(), response.message());
1283 EXPECT_TRUE(s.ok());
1284
1285 // Metadata should have been consumed by the processor.
1286 EXPECT_FALSE(MetadataContains(
1287 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
1288 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
1289}
1290
1291TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) {
1292 auto* processor = new TestAuthMetadataProcessor(true);
1293 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
1294 ResetStub();
1295 EchoRequest request;
1296 EchoResponse response;
1297 ClientContext context;
1298 context.set_credentials(processor->GetIncompatibleClientCreds());
1299 request.set_message("Hello");
1300
1301 Status s = stub_->Echo(&context, request, &response);
1302 EXPECT_FALSE(s.ok());
1303 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1304}
1305TEST_P(SecureEnd2endTest, SetPerCallCredentials) {
1306 ResetStub();
Yang Gaoa8938922015-05-14 11:51:07 -07001307 EchoRequest request;
1308 EchoResponse response;
1309 ClientContext context;
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001310 std::shared_ptr<CallCredentials> creds =
Julien Boeuf510a9202015-08-25 21:51:07 -07001311 GoogleIAMCredentials("fake_token", "fake_selector");
Yang Gaoa8938922015-05-14 11:51:07 -07001312 context.set_credentials(creds);
Yang Gao26a49122015-05-15 17:02:56 -07001313 request.set_message("Hello");
1314 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -07001315
1316 Status s = stub_->Echo(&context, request, &response);
Yang Gaoa8938922015-05-14 11:51:07 -07001317 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -07001318 EXPECT_TRUE(s.ok());
Yang Gao26a49122015-05-15 17:02:56 -07001319 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1320 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1321 "fake_token"));
1322 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1323 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1324 "fake_selector"));
Yang Gaoa8938922015-05-14 11:51:07 -07001325}
1326
yang-g88d5d522015-09-29 12:46:54 -07001327TEST_P(SecureEnd2endTest, OverridePerCallCredentials) {
1328 ResetStub();
Yang Gaoa8938922015-05-14 11:51:07 -07001329 EchoRequest request;
1330 EchoResponse response;
1331 ClientContext context;
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001332 std::shared_ptr<CallCredentials> creds1 =
Julien Boeuf510a9202015-08-25 21:51:07 -07001333 GoogleIAMCredentials("fake_token1", "fake_selector1");
Yang Gaoa8938922015-05-14 11:51:07 -07001334 context.set_credentials(creds1);
Julien Boeufe5adc0e2015-10-12 14:08:10 -07001335 std::shared_ptr<CallCredentials> creds2 =
Julien Boeuf510a9202015-08-25 21:51:07 -07001336 GoogleIAMCredentials("fake_token2", "fake_selector2");
Yang Gaoa8938922015-05-14 11:51:07 -07001337 context.set_credentials(creds2);
Yang Gao26a49122015-05-15 17:02:56 -07001338 request.set_message("Hello");
1339 request.mutable_param()->set_echo_metadata(true);
Yang Gaoa8938922015-05-14 11:51:07 -07001340
1341 Status s = stub_->Echo(&context, request, &response);
Yang Gao26a49122015-05-15 17:02:56 -07001342 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1343 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1344 "fake_token2"));
1345 EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
1346 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1347 "fake_selector2"));
Yang Gaob57f72d2015-05-17 21:54:54 -07001348 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
1349 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
1350 "fake_token1"));
1351 EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
1352 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
1353 "fake_selector1"));
Yang Gaoa8938922015-05-14 11:51:07 -07001354 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -07001355 EXPECT_TRUE(s.ok());
Yang Gaoa8938922015-05-14 11:51:07 -07001356}
1357
yang-gc580af32016-09-15 15:28:38 -07001358TEST_P(SecureEnd2endTest, AuthMetadataPluginKeyFailure) {
1359 ResetStub();
1360 EchoRequest request;
1361 EchoResponse response;
1362 ClientContext context;
1363 context.set_credentials(
1364 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1365 new TestMetadataCredentialsPlugin(
1366 TestMetadataCredentialsPlugin::kBadMetadataKey,
1367 "Does not matter, will fail the key is invalid.", false, true))));
1368 request.set_message("Hello");
1369
1370 Status s = stub_->Echo(&context, request, &response);
1371 EXPECT_FALSE(s.ok());
1372 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1373}
1374
yang-g4b4571a2016-09-15 23:01:09 -07001375TEST_P(SecureEnd2endTest, AuthMetadataPluginValueFailure) {
1376 ResetStub();
1377 EchoRequest request;
1378 EchoResponse response;
1379 ClientContext context;
1380 context.set_credentials(
1381 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1382 new TestMetadataCredentialsPlugin(
1383 TestMetadataCredentialsPlugin::kGoodMetadataKey,
yang-gd5fba282016-09-16 10:29:16 -07001384 "With illegal \n value.", false, true))));
yang-g4b4571a2016-09-15 23:01:09 -07001385 request.set_message("Hello");
1386
1387 Status s = stub_->Echo(&context, request, &response);
1388 EXPECT_FALSE(s.ok());
1389 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1390}
1391
yang-g88d5d522015-09-29 12:46:54 -07001392TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) {
1393 ResetStub();
Julien Boeuf1928d492015-09-15 15:20:11 -07001394 EchoRequest request;
1395 EchoResponse response;
1396 ClientContext context;
1397 context.set_credentials(
1398 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1399 new TestMetadataCredentialsPlugin(
yang-gc580af32016-09-15 15:28:38 -07001400 TestMetadataCredentialsPlugin::kGoodMetadataKey,
Julien Boeuf1928d492015-09-15 15:20:11 -07001401 "Does not matter, will fail anyway (see 3rd param)", false,
1402 false))));
1403 request.set_message("Hello");
1404
1405 Status s = stub_->Echo(&context, request, &response);
1406 EXPECT_FALSE(s.ok());
1407 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
Julien Boeuf38c0cde2016-06-06 14:46:08 +02001408 EXPECT_EQ(s.error_message(), kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -07001409}
1410
yang-g88d5d522015-09-29 12:46:54 -07001411TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001412 auto* processor = new TestAuthMetadataProcessor(false);
1413 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
yang-g88d5d522015-09-29 12:46:54 -07001414 ResetStub();
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001415 EchoRequest request;
1416 EchoResponse response;
1417 ClientContext context;
1418 context.set_credentials(processor->GetCompatibleClientCreds());
1419 request.set_message("Hello");
1420 request.mutable_param()->set_echo_metadata(true);
1421 request.mutable_param()->set_expected_client_identity(
1422 TestAuthMetadataProcessor::kGoodGuy);
Dan Bornf2f7d572016-03-03 17:26:12 -08001423 request.mutable_param()->set_expected_transport_security_type(
1424 GetParam().credentials_type);
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001425
1426 Status s = stub_->Echo(&context, request, &response);
1427 EXPECT_EQ(request.message(), response.message());
1428 EXPECT_TRUE(s.ok());
1429
1430 // Metadata should have been consumed by the processor.
1431 EXPECT_FALSE(MetadataContains(
1432 context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
1433 grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
1434}
1435
yang-g88d5d522015-09-29 12:46:54 -07001436TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001437 auto* processor = new TestAuthMetadataProcessor(false);
1438 StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
yang-g88d5d522015-09-29 12:46:54 -07001439 ResetStub();
Julien Boeuf0c711ad2015-08-28 14:10:58 -07001440 EchoRequest request;
1441 EchoResponse response;
1442 ClientContext context;
1443 context.set_credentials(processor->GetIncompatibleClientCreds());
1444 request.set_message("Hello");
1445
1446 Status s = stub_->Echo(&context, request, &response);
1447 EXPECT_FALSE(s.ok());
1448 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
1449}
1450
yang-g88d5d522015-09-29 12:46:54 -07001451TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) {
1452 ResetStub();
Julien Boeuf1928d492015-09-15 15:20:11 -07001453 EchoRequest request;
1454 EchoResponse response;
1455 ClientContext context;
1456 context.set_credentials(
1457 MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
1458 new TestMetadataCredentialsPlugin(
yang-gc580af32016-09-15 15:28:38 -07001459 TestMetadataCredentialsPlugin::kGoodMetadataKey,
Julien Boeuf1928d492015-09-15 15:20:11 -07001460 "Does not matter, will fail anyway (see 3rd param)", true,
1461 false))));
1462 request.set_message("Hello");
1463
1464 Status s = stub_->Echo(&context, request, &response);
1465 EXPECT_FALSE(s.ok());
1466 EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
Julien Boeuf38c0cde2016-06-06 14:46:08 +02001467 EXPECT_EQ(s.error_message(), kTestCredsPluginErrorMsg);
Julien Boeuf1928d492015-09-15 15:20:11 -07001468}
1469
yang-g88d5d522015-09-29 12:46:54 -07001470TEST_P(SecureEnd2endTest, ClientAuthContext) {
1471 ResetStub();
yang-gc4eef2e2015-07-06 23:26:58 -07001472 EchoRequest request;
1473 EchoResponse response;
1474 request.set_message("Hello");
Dan Bornf2f7d572016-03-03 17:26:12 -08001475 request.mutable_param()->set_check_auth_context(GetParam().credentials_type ==
1476 kTlsCredentialsType);
1477 request.mutable_param()->set_expected_transport_security_type(
1478 GetParam().credentials_type);
yang-gc4eef2e2015-07-06 23:26:58 -07001479 ClientContext context;
1480 Status s = stub_->Echo(&context, request, &response);
1481 EXPECT_EQ(response.message(), request.message());
1482 EXPECT_TRUE(s.ok());
1483
yang-g8b25f2a2015-07-21 23:54:36 -07001484 std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
Dan Bornf2f7d572016-03-03 17:26:12 -08001485 std::vector<grpc::string_ref> tst =
yang-g8b25f2a2015-07-21 23:54:36 -07001486 auth_ctx->FindPropertyValues("transport_security_type");
Robbie Shade820c1f32016-06-23 14:31:28 -04001487 ASSERT_EQ(1u, tst.size());
Dan Bornf2f7d572016-03-03 17:26:12 -08001488 EXPECT_EQ(GetParam().credentials_type, ToString(tst[0]));
1489 if (GetParam().credentials_type == kTlsCredentialsType) {
1490 EXPECT_EQ("x509_subject_alternative_name",
1491 auth_ctx->GetPeerIdentityPropertyName());
Paul Querna47d841d2016-03-10 11:19:17 -08001492 EXPECT_EQ(4u, auth_ctx->GetPeerIdentity().size());
Dan Bornf2f7d572016-03-03 17:26:12 -08001493 EXPECT_EQ("*.test.google.fr", ToString(auth_ctx->GetPeerIdentity()[0]));
1494 EXPECT_EQ("waterzooi.test.google.be",
1495 ToString(auth_ctx->GetPeerIdentity()[1]));
1496 EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2]));
Paul Querna47d841d2016-03-10 11:19:17 -08001497 EXPECT_EQ("192.168.1.3", ToString(auth_ctx->GetPeerIdentity()[3]));
Dan Bornf2f7d572016-03-03 17:26:12 -08001498 }
yang-gc4eef2e2015-07-06 23:26:58 -07001499}
1500
Craig Tiller20afa3d2016-10-17 14:52:14 -07001501class ResourceQuotaEnd2endTest : public End2endTest {
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001502 public:
Craig Tiller20afa3d2016-10-17 14:52:14 -07001503 ResourceQuotaEnd2endTest()
1504 : server_resource_quota_("server_resource_quota") {}
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001505
Vijay Paic0b2acb2016-11-01 16:31:56 -07001506 virtual void ConfigureServerBuilder(ServerBuilder* builder) override {
Craig Tiller20afa3d2016-10-17 14:52:14 -07001507 builder->SetResourceQuota(server_resource_quota_);
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001508 }
1509
1510 private:
Craig Tiller20afa3d2016-10-17 14:52:14 -07001511 ResourceQuota server_resource_quota_;
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001512};
1513
Craig Tiller20afa3d2016-10-17 14:52:14 -07001514TEST_P(ResourceQuotaEnd2endTest, SimpleRequest) {
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001515 ResetStub();
1516
1517 EchoRequest request;
1518 EchoResponse response;
1519 request.set_message("Hello");
1520
1521 ClientContext context;
1522 Status s = stub_->Echo(&context, request, &response);
1523 EXPECT_EQ(response.message(), request.message());
1524 EXPECT_TRUE(s.ok());
1525}
1526
yang-g4c8aed32016-02-19 00:19:39 -08001527std::vector<TestScenario> CreateTestScenarios(bool use_proxy,
1528 bool test_insecure,
1529 bool test_secure) {
1530 std::vector<TestScenario> scenarios;
1531 std::vector<grpc::string> credentials_types;
1532 if (test_secure) {
1533 credentials_types = GetSecureCredentialsTypeList();
1534 }
1535 if (test_insecure) {
1536 credentials_types.push_back(kInsecureCredentialsType);
1537 }
1538 for (auto it = credentials_types.begin(); it != credentials_types.end();
1539 ++it) {
Vijay Pai679c75f2016-06-15 13:08:00 -07001540 scenarios.emplace_back(false, *it);
yang-g4c8aed32016-02-19 00:19:39 -08001541 if (use_proxy) {
Vijay Pai679c75f2016-06-15 13:08:00 -07001542 scenarios.emplace_back(true, *it);
yang-g4c8aed32016-02-19 00:19:39 -08001543 }
1544 }
1545 return scenarios;
1546}
yang-g6f30dec2015-07-22 23:11:56 -07001547
yang-g4c8aed32016-02-19 00:19:39 -08001548INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
1549 ::testing::ValuesIn(CreateTestScenarios(false, true,
1550 true)));
Sree Kuchibhotla944f4cf2016-01-27 14:37:26 -08001551
yang-g4c8aed32016-02-19 00:19:39 -08001552INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest,
1553 ::testing::ValuesIn(CreateTestScenarios(false, true,
1554 false)));
1555
1556INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
1557 ::testing::ValuesIn(CreateTestScenarios(true, true,
1558 true)));
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001559
yang-g88d5d522015-09-29 12:46:54 -07001560INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
yang-g4c8aed32016-02-19 00:19:39 -08001561 ::testing::ValuesIn(CreateTestScenarios(false, false,
1562 true)));
yang-g88d5d522015-09-29 12:46:54 -07001563
Craig Tiller20afa3d2016-10-17 14:52:14 -07001564INSTANTIATE_TEST_CASE_P(ResourceQuotaEnd2end, ResourceQuotaEnd2endTest,
Craig Tillerdb1a5cc2016-09-28 14:22:12 -07001565 ::testing::ValuesIn(CreateTestScenarios(false, true,
1566 true)));
1567
yang-g8ab38362015-07-31 14:05:33 -07001568} // namespace
Nicolas Nobleb7ebd3b2014-11-26 16:33:03 -08001569} // namespace testing
1570} // namespace grpc
1571
1572int main(int argc, char** argv) {
1573 grpc_test_init(argc, argv);
1574 ::testing::InitGoogleTest(&argc, argv);
1575 return RUN_ALL_TESTS();
David Garcia Quintas2bf574f2016-01-14 15:27:08 -08001576}