LCOV - code coverage report
Current view: top level - test/cpp/end2end - end2end_test.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 784 789 99.4 %
Date: 2015-10-10 Functions: 237 242 97.9 %

          Line data    Source code
       1             : /*
       2             :  *
       3             :  * Copyright 2015, Google Inc.
       4             :  * 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             : 
      34             : #include <mutex>
      35             : #include <thread>
      36             : 
      37             : #include <grpc/grpc.h>
      38             : #include <grpc/support/thd.h>
      39             : #include <grpc/support/time.h>
      40             : #include <grpc++/channel.h>
      41             : #include <grpc++/client_context.h>
      42             : #include <grpc++/create_channel.h>
      43             : #include <grpc++/security/auth_metadata_processor.h>
      44             : #include <grpc++/security/credentials.h>
      45             : #include <grpc++/security/server_credentials.h>
      46             : #include <grpc++/server.h>
      47             : #include <grpc++/server_builder.h>
      48             : #include <grpc++/server_context.h>
      49             : #include <gtest/gtest.h>
      50             : 
      51             : #include "src/core/security/credentials.h"
      52             : #include "test/core/end2end/data/ssl_test_data.h"
      53             : #include "test/core/util/port.h"
      54             : #include "test/core/util/test_config.h"
      55             : #include "test/cpp/util/echo_duplicate.grpc.pb.h"
      56             : #include "test/cpp/util/echo.grpc.pb.h"
      57             : #include "test/cpp/util/string_ref_helper.h"
      58             : 
      59             : using grpc::cpp::test::util::EchoRequest;
      60             : using grpc::cpp::test::util::EchoResponse;
      61             : using std::chrono::system_clock;
      62             : 
      63             : namespace grpc {
      64             : namespace testing {
      65             : namespace {
      66             : 
      67             : const char* kServerCancelAfterReads = "cancel_after_reads";
      68             : 
      69             : // When echo_deadline is requested, deadline seen in the ServerContext is set in
      70             : // the response in seconds.
      71         440 : void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request,
      72             :                        EchoResponse* response) {
      73         440 :   if (request->has_param() && request->param().echo_deadline()) {
      74           8 :     gpr_timespec deadline = gpr_inf_future(GPR_CLOCK_REALTIME);
      75           8 :     if (context->deadline() != system_clock::time_point::max()) {
      76           4 :       Timepoint2Timespec(context->deadline(), &deadline);
      77             :     }
      78           8 :     response->mutable_param()->set_request_deadline(deadline.tv_sec);
      79             :   }
      80         440 : }
      81             : 
      82           3 : void CheckServerAuthContext(const ServerContext* context,
      83             :                             const grpc::string& expected_client_identity) {
      84           3 :   std::shared_ptr<const AuthContext> auth_ctx = context->auth_context();
      85             :   std::vector<grpc::string_ref> ssl =
      86           6 :       auth_ctx->FindPropertyValues("transport_security_type");
      87           3 :   EXPECT_EQ(1u, ssl.size());
      88           3 :   EXPECT_EQ("ssl", ToString(ssl[0]));
      89           3 :   if (expected_client_identity.length() == 0) {
      90           1 :     EXPECT_TRUE(auth_ctx->GetPeerIdentityPropertyName().empty());
      91           1 :     EXPECT_TRUE(auth_ctx->GetPeerIdentity().empty());
      92           1 :     EXPECT_FALSE(auth_ctx->IsPeerAuthenticated());
      93             :   } else {
      94           2 :     auto identity = auth_ctx->GetPeerIdentity();
      95           2 :     EXPECT_TRUE(auth_ctx->IsPeerAuthenticated());
      96           2 :     EXPECT_EQ(1u, identity.size());
      97           2 :     EXPECT_EQ(expected_client_identity, identity[0]);
      98           3 :   }
      99           3 : }
     100             : 
     101           8 : bool CheckIsLocalhost(const grpc::string& addr) {
     102           8 :   const grpc::string kIpv6("ipv6:[::1]:");
     103          16 :   const grpc::string kIpv4MappedIpv6("ipv6:[::ffff:127.0.0.1]:");
     104          16 :   const grpc::string kIpv4("ipv4:127.0.0.1:");
     105          32 :   return addr.substr(0, kIpv4.size()) == kIpv4 ||
     106          32 :          addr.substr(0, kIpv4MappedIpv6.size()) == kIpv4MappedIpv6 ||
     107          16 :          addr.substr(0, kIpv6.size()) == kIpv6;
     108             : }
     109             : 
     110          12 : class TestMetadataCredentialsPlugin : public MetadataCredentialsPlugin {
     111             :  public:
     112             :   static const char kMetadataKey[];
     113             : 
     114           6 :   TestMetadataCredentialsPlugin(grpc::string_ref metadata_value,
     115             :                                 bool is_blocking, bool is_successful)
     116             :       : metadata_value_(metadata_value.data(), metadata_value.length()),
     117             :         is_blocking_(is_blocking),
     118           6 :         is_successful_(is_successful) {}
     119             : 
     120           6 :   bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
     121             : 
     122           6 :   Status GetMetadata(grpc::string_ref service_url,
     123             :                      std::multimap<grpc::string, grpc::string>* metadata)
     124             :       GRPC_OVERRIDE {
     125           6 :     EXPECT_GT(service_url.length(), 0UL);
     126           6 :     EXPECT_TRUE(metadata != nullptr);
     127           6 :     if (is_successful_) {
     128           4 :       metadata->insert(std::make_pair(kMetadataKey, metadata_value_));
     129           4 :       return Status::OK;
     130             :     } else {
     131           2 :       return Status(StatusCode::NOT_FOUND, "Could not find plugin metadata.");
     132             :     }
     133             :   }
     134             : 
     135             :  private:
     136             :   grpc::string metadata_value_;
     137             :   bool is_blocking_;
     138             :   bool is_successful_;
     139             : };
     140             : 
     141             : const char TestMetadataCredentialsPlugin::kMetadataKey[] = "TestPluginMetadata";
     142             : 
     143           8 : class TestAuthMetadataProcessor : public AuthMetadataProcessor {
     144             :  public:
     145             :   static const char kGoodGuy[];
     146             : 
     147           4 :   TestAuthMetadataProcessor(bool is_blocking) : is_blocking_(is_blocking) {}
     148             : 
     149           2 :   std::shared_ptr<Credentials> GetCompatibleClientCreds() {
     150             :     return MetadataCredentialsFromPlugin(
     151             :         std::unique_ptr<MetadataCredentialsPlugin>(
     152           2 :             new TestMetadataCredentialsPlugin(kGoodGuy, is_blocking_, true)));
     153             :   }
     154             : 
     155           2 :   std::shared_ptr<Credentials> GetIncompatibleClientCreds() {
     156             :     return MetadataCredentialsFromPlugin(
     157             :         std::unique_ptr<MetadataCredentialsPlugin>(
     158           2 :             new TestMetadataCredentialsPlugin("Mr Hyde", is_blocking_, true)));
     159             :   }
     160             : 
     161             :   // Interface implementation
     162           4 :   bool IsBlocking() const GRPC_OVERRIDE { return is_blocking_; }
     163             : 
     164           4 :   Status Process(const InputMetadata& auth_metadata, AuthContext* context,
     165             :                  OutputMetadata* consumed_auth_metadata,
     166             :                  OutputMetadata* response_metadata) GRPC_OVERRIDE {
     167           4 :     EXPECT_TRUE(consumed_auth_metadata != nullptr);
     168           4 :     EXPECT_TRUE(context != nullptr);
     169           4 :     EXPECT_TRUE(response_metadata != nullptr);
     170             :     auto auth_md =
     171           4 :         auth_metadata.find(TestMetadataCredentialsPlugin::kMetadataKey);
     172           4 :     EXPECT_NE(auth_md, auth_metadata.end());
     173           4 :     string_ref auth_md_value = auth_md->second;
     174           4 :     if (auth_md_value == kGoodGuy) {
     175           2 :       context->AddProperty(kIdentityPropName, kGoodGuy);
     176           2 :       context->SetPeerIdentityPropertyName(kIdentityPropName);
     177             :       consumed_auth_metadata->insert(std::make_pair(
     178           4 :           string(auth_md->first.data(), auth_md->first.length()),
     179           6 :           string(auth_md->second.data(), auth_md->second.length())));
     180           2 :       return Status::OK;
     181             :     } else {
     182             :       return Status(StatusCode::UNAUTHENTICATED,
     183           4 :                     string("Invalid principal: ") +
     184           2 :                         string(auth_md_value.data(), auth_md_value.length()));
     185             :     }
     186             :   }
     187             : 
     188             :  private:
     189             :   static const char kIdentityPropName[];
     190             :   bool is_blocking_;
     191             : };
     192             : 
     193             : const char TestAuthMetadataProcessor::kGoodGuy[] = "Dr Jekyll";
     194             : const char TestAuthMetadataProcessor::kIdentityPropName[] = "novel identity";
     195             : 
     196          44 : class Proxy : public ::grpc::cpp::test::util::TestService::Service {
     197             :  public:
     198          22 :   Proxy(std::shared_ptr<Channel> channel)
     199          22 :       : stub_(grpc::cpp::test::util::TestService::NewStub(channel)) {}
     200             : 
     201         216 :   Status Echo(ServerContext* server_context, const EchoRequest* request,
     202             :               EchoResponse* response) GRPC_OVERRIDE {
     203             :     std::unique_ptr<ClientContext> client_context =
     204         216 :         ClientContext::FromServerContext(*server_context);
     205         216 :     return stub_->Echo(client_context.get(), *request, response);
     206             :   }
     207             : 
     208             :  private:
     209             :   std::unique_ptr< ::grpc::cpp::test::util::TestService::Stub> stub_;
     210             : };
     211             : 
     212         168 : class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service {
     213             :  public:
     214          84 :   TestServiceImpl() : signal_client_(false), host_() {}
     215          84 :   explicit TestServiceImpl(const grpc::string& host)
     216          84 :       : signal_client_(false), host_(new grpc::string(host)) {}
     217             : 
     218         440 :   Status Echo(ServerContext* context, const EchoRequest* request,
     219             :               EchoResponse* response) GRPC_OVERRIDE {
     220         440 :     response->set_message(request->message());
     221         440 :     MaybeEchoDeadline(context, request, response);
     222         440 :     if (host_) {
     223           1 :       response->mutable_param()->set_host(*host_);
     224             :     }
     225         440 :     if (request->has_param() && request->param().client_cancel_after_us()) {
     226             :       {
     227           4 :         std::unique_lock<std::mutex> lock(mu_);
     228           4 :         signal_client_ = true;
     229             :       }
     230          12 :       while (!context->IsCancelled()) {
     231             :         gpr_sleep_until(gpr_time_add(
     232             :             gpr_now(GPR_CLOCK_REALTIME),
     233           4 :             gpr_time_from_micros(request->param().client_cancel_after_us(),
     234           4 :                                  GPR_TIMESPAN)));
     235             :       }
     236           4 :       return Status::CANCELLED;
     237         461 :     } else if (request->has_param() &&
     238          25 :                request->param().server_cancel_after_us()) {
     239             :       gpr_sleep_until(gpr_time_add(
     240             :           gpr_now(GPR_CLOCK_REALTIME),
     241           4 :           gpr_time_from_micros(request->param().server_cancel_after_us(),
     242           4 :                                GPR_TIMESPAN)));
     243           4 :       return Status::CANCELLED;
     244             :     } else {
     245         432 :       EXPECT_FALSE(context->IsCancelled());
     246             :     }
     247             : 
     248         432 :     if (request->has_param() && request->param().echo_metadata()) {
     249             :       const std::multimap<grpc::string_ref, grpc::string_ref>& client_metadata =
     250           4 :           context->client_metadata();
     251          36 :       for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
     252           4 :                iter = client_metadata.begin();
     253          24 :            iter != client_metadata.end(); ++iter) {
     254           8 :         context->AddTrailingMetadata(ToString(iter->first),
     255          16 :                                      ToString(iter->second));
     256             :       }
     257             :     }
     258         456 :     if (request->has_param() &&
     259          40 :         (request->param().expected_client_identity().length() > 0 ||
     260          19 :          request->param().check_auth_context())) {
     261             :       CheckServerAuthContext(context,
     262           3 :                              request->param().expected_client_identity());
     263             :     }
     264         453 :     if (request->has_param() &&
     265          21 :         request->param().response_message_length() > 0) {
     266             :       response->set_message(
     267           4 :           grpc::string(request->param().response_message_length(), '\0'));
     268             :     }
     269         432 :     if (request->has_param() && request->param().echo_peer()) {
     270           4 :       response->mutable_param()->set_peer(context->peer());
     271             :     }
     272         432 :     return Status::OK;
     273             :   }
     274             : 
     275             :   // Unimplemented is left unimplemented to test the returned error.
     276             : 
     277           8 :   Status RequestStream(ServerContext* context,
     278             :                        ServerReader<EchoRequest>* reader,
     279             :                        EchoResponse* response) GRPC_OVERRIDE {
     280           8 :     EchoRequest request;
     281           8 :     response->set_message("");
     282           8 :     int cancel_after_reads = 0;
     283             :     const std::multimap<grpc::string_ref, grpc::string_ref>&
     284           8 :         client_initial_metadata = context->client_metadata();
     285           8 :     if (client_initial_metadata.find(kServerCancelAfterReads) !=
     286             :         client_initial_metadata.end()) {
     287             :       std::istringstream iss(ToString(
     288           2 :           client_initial_metadata.find(kServerCancelAfterReads)->second));
     289           2 :       iss >> cancel_after_reads;
     290           2 :       gpr_log(GPR_INFO, "cancel_after_reads %d", cancel_after_reads);
     291             :     }
     292          40 :     while (reader->Read(&request)) {
     293          26 :       if (cancel_after_reads == 1) {
     294           2 :         gpr_log(GPR_INFO, "return cancel status");
     295           2 :         return Status::CANCELLED;
     296          24 :       } else if (cancel_after_reads > 0) {
     297          18 :         cancel_after_reads--;
     298             :       }
     299          24 :       response->mutable_message()->append(request.message());
     300             :     }
     301           6 :     return Status::OK;
     302             :   }
     303             : 
     304             :   // Return 3 messages.
     305             :   // TODO(yangg) make it generic by adding a parameter into EchoRequest
     306           4 :   Status ResponseStream(ServerContext* context, const EchoRequest* request,
     307             :                         ServerWriter<EchoResponse>* writer) GRPC_OVERRIDE {
     308           4 :     EchoResponse response;
     309           4 :     response.set_message(request->message() + "0");
     310           4 :     writer->Write(response);
     311           4 :     response.set_message(request->message() + "1");
     312           4 :     writer->Write(response);
     313           4 :     response.set_message(request->message() + "2");
     314           4 :     writer->Write(response);
     315             : 
     316           4 :     return Status::OK;
     317             :   }
     318             : 
     319           6 :   Status BidiStream(ServerContext* context,
     320             :                     ServerReaderWriter<EchoResponse, EchoRequest>* stream)
     321             :       GRPC_OVERRIDE {
     322           6 :     EchoRequest request;
     323          12 :     EchoResponse response;
     324          22 :     while (stream->Read(&request)) {
     325          10 :       gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
     326          10 :       response.set_message(request.message());
     327          10 :       stream->Write(response);
     328             :     }
     329          12 :     return Status::OK;
     330             :   }
     331             : 
     332      125573 :   bool signal_client() {
     333      125573 :     std::unique_lock<std::mutex> lock(mu_);
     334      125573 :     return signal_client_;
     335             :   }
     336             : 
     337             :  private:
     338             :   bool signal_client_;
     339             :   std::mutex mu_;
     340             :   std::unique_ptr<grpc::string> host_;
     341             : };
     342             : 
     343         168 : class TestServiceImplDupPkg
     344             :     : public ::grpc::cpp::test::util::duplicate::TestService::Service {
     345             :  public:
     346           2 :   Status Echo(ServerContext* context, const EchoRequest* request,
     347             :               EchoResponse* response) GRPC_OVERRIDE {
     348           2 :     response->set_message("no package");
     349           2 :     return Status::OK;
     350             :   }
     351             : };
     352             : 
     353             : class TestScenario {
     354             :  public:
     355          84 :   TestScenario(bool proxy, bool tls) : use_proxy(proxy), use_tls(tls) {}
     356          84 :   void Log() const {
     357          84 :     gpr_log(GPR_INFO, "Scenario: proxy %d, tls %d", use_proxy, use_tls);
     358          84 :   }
     359             :   bool use_proxy;
     360             :   bool use_tls;
     361             : };
     362             : 
     363          84 : class End2endTest : public ::testing::TestWithParam<TestScenario> {
     364             :  protected:
     365          84 :   End2endTest()
     366             :       : is_server_started_(false),
     367             :         kMaxMessageSize_(8192),
     368          84 :         special_service_("special") {
     369          84 :     GetParam().Log();
     370          84 :   }
     371             : 
     372          84 :   void TearDown() GRPC_OVERRIDE {
     373          84 :     if (is_server_started_) {
     374          81 :       server_->Shutdown();
     375          81 :       if (proxy_server_) proxy_server_->Shutdown();
     376             :     }
     377          84 :   }
     378             : 
     379          81 :   void StartServer(const std::shared_ptr<AuthMetadataProcessor>& processor) {
     380          81 :     int port = grpc_pick_unused_port_or_die();
     381          81 :     server_address_ << "127.0.0.1:" << port;
     382             :     // Setup server
     383          81 :     ServerBuilder builder;
     384         162 :     auto server_creds = InsecureServerCredentials();
     385          81 :     if (GetParam().use_tls) {
     386             :       SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
     387          46 :                                                           test_server1_cert};
     388          92 :       SslServerCredentialsOptions ssl_opts;
     389          46 :       ssl_opts.pem_root_certs = "";
     390          46 :       ssl_opts.pem_key_cert_pairs.push_back(pkcp);
     391          46 :       server_creds = SslServerCredentials(ssl_opts);
     392          92 :       server_creds->SetAuthMetadataProcessor(processor);
     393             :     }
     394          81 :     builder.AddListeningPort(server_address_.str(), server_creds);
     395          81 :     builder.RegisterService(&service_);
     396          81 :     builder.RegisterService("foo.test.youtube.com", &special_service_);
     397             :     builder.SetMaxMessageSize(
     398          81 :         kMaxMessageSize_);  // For testing max message size.
     399          81 :     builder.RegisterService(&dup_pkg_service_);
     400          81 :     server_ = builder.BuildAndStart();
     401         162 :     is_server_started_ = true;
     402          81 :   }
     403             : 
     404          81 :   void ResetChannel() {
     405          81 :     if (!is_server_started_) {
     406          77 :       StartServer(std::shared_ptr<AuthMetadataProcessor>());
     407             :     }
     408          81 :     EXPECT_TRUE(is_server_started_);
     409          81 :     ChannelArguments args;
     410         162 :     auto channel_creds = InsecureCredentials();
     411          81 :     if (GetParam().use_tls) {
     412          46 :       SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
     413          46 :       args.SetSslTargetNameOverride("foo.test.google.fr");
     414          46 :       channel_creds = SslCredentials(ssl_opts);
     415             :     }
     416          81 :     args.SetString(GRPC_ARG_SECONDARY_USER_AGENT_STRING, "end2end_test");
     417         162 :     channel_ = CreateCustomChannel(server_address_.str(), channel_creds, args);
     418          81 :   }
     419             : 
     420          79 :   void ResetStub() {
     421          79 :     ResetChannel();
     422          79 :     if (GetParam().use_proxy) {
     423          22 :       proxy_service_.reset(new Proxy(channel_));
     424          22 :       int port = grpc_pick_unused_port_or_die();
     425          22 :       std::ostringstream proxyaddr;
     426          22 :       proxyaddr << "localhost:" << port;
     427          44 :       ServerBuilder builder;
     428          22 :       builder.AddListeningPort(proxyaddr.str(), InsecureServerCredentials());
     429          22 :       builder.RegisterService(proxy_service_.get());
     430          22 :       proxy_server_ = builder.BuildAndStart();
     431             : 
     432          44 :       channel_ = CreateChannel(proxyaddr.str(), InsecureCredentials());
     433             :     }
     434             : 
     435          79 :     stub_ = grpc::cpp::test::util::TestService::NewStub(channel_);
     436          79 :   }
     437             : 
     438             :   bool is_server_started_;
     439             :   std::shared_ptr<Channel> channel_;
     440             :   std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
     441             :   std::unique_ptr<Server> server_;
     442             :   std::unique_ptr<Server> proxy_server_;
     443             :   std::unique_ptr<Proxy> proxy_service_;
     444             :   std::ostringstream server_address_;
     445             :   const int kMaxMessageSize_;
     446             :   TestServiceImpl service_;
     447             :   TestServiceImpl special_service_;
     448             :   TestServiceImplDupPkg dup_pkg_service_;
     449             : };
     450             : 
     451          44 : static void SendRpc(grpc::cpp::test::util::TestService::Stub* stub,
     452             :                     int num_rpcs) {
     453          44 :   EchoRequest request;
     454          88 :   EchoResponse response;
     455          44 :   request.set_message("Hello hello hello hello");
     456             : 
     457         448 :   for (int i = 0; i < num_rpcs; ++i) {
     458         404 :     ClientContext context;
     459         404 :     context.set_compression_algorithm(GRPC_COMPRESS_GZIP);
     460         808 :     Status s = stub->Echo(&context, request, &response);
     461         404 :     EXPECT_EQ(response.message(), request.message());
     462         404 :     EXPECT_TRUE(s.ok());
     463         448 :   }
     464          44 : }
     465             : 
     466          10 : TEST_P(End2endTest, RequestStreamOneRequest) {
     467           2 :   ResetStub();
     468           2 :   EchoRequest request;
     469           4 :   EchoResponse response;
     470           4 :   ClientContext context;
     471             : 
     472           4 :   auto stream = stub_->RequestStream(&context, &response);
     473           2 :   request.set_message("hello");
     474           2 :   EXPECT_TRUE(stream->Write(request));
     475           2 :   stream->WritesDone();
     476           2 :   Status s = stream->Finish();
     477           2 :   EXPECT_EQ(response.message(), request.message());
     478           4 :   EXPECT_TRUE(s.ok());
     479           2 : }
     480             : 
     481          10 : TEST_P(End2endTest, RequestStreamTwoRequests) {
     482           2 :   ResetStub();
     483           2 :   EchoRequest request;
     484           4 :   EchoResponse response;
     485           4 :   ClientContext context;
     486             : 
     487           4 :   auto stream = stub_->RequestStream(&context, &response);
     488           2 :   request.set_message("hello");
     489           2 :   EXPECT_TRUE(stream->Write(request));
     490           2 :   EXPECT_TRUE(stream->Write(request));
     491           2 :   stream->WritesDone();
     492           2 :   Status s = stream->Finish();
     493           2 :   EXPECT_EQ(response.message(), "hellohello");
     494           4 :   EXPECT_TRUE(s.ok());
     495           2 : }
     496             : 
     497          10 : TEST_P(End2endTest, ResponseStream) {
     498           2 :   ResetStub();
     499           2 :   EchoRequest request;
     500           4 :   EchoResponse response;
     501           4 :   ClientContext context;
     502           2 :   request.set_message("hello");
     503             : 
     504           4 :   auto stream = stub_->ResponseStream(&context, request);
     505           2 :   EXPECT_TRUE(stream->Read(&response));
     506           2 :   EXPECT_EQ(response.message(), request.message() + "0");
     507           2 :   EXPECT_TRUE(stream->Read(&response));
     508           2 :   EXPECT_EQ(response.message(), request.message() + "1");
     509           2 :   EXPECT_TRUE(stream->Read(&response));
     510           2 :   EXPECT_EQ(response.message(), request.message() + "2");
     511           2 :   EXPECT_FALSE(stream->Read(&response));
     512             : 
     513           2 :   Status s = stream->Finish();
     514           4 :   EXPECT_TRUE(s.ok());
     515           2 : }
     516             : 
     517          10 : TEST_P(End2endTest, BidiStream) {
     518           2 :   ResetStub();
     519           2 :   EchoRequest request;
     520           4 :   EchoResponse response;
     521           4 :   ClientContext context;
     522           4 :   grpc::string msg("hello");
     523             : 
     524           4 :   auto stream = stub_->BidiStream(&context);
     525             : 
     526           2 :   request.set_message(msg + "0");
     527           2 :   EXPECT_TRUE(stream->Write(request));
     528           2 :   EXPECT_TRUE(stream->Read(&response));
     529           2 :   EXPECT_EQ(response.message(), request.message());
     530             : 
     531           2 :   request.set_message(msg + "1");
     532           2 :   EXPECT_TRUE(stream->Write(request));
     533           2 :   EXPECT_TRUE(stream->Read(&response));
     534           2 :   EXPECT_EQ(response.message(), request.message());
     535             : 
     536           2 :   request.set_message(msg + "2");
     537           2 :   EXPECT_TRUE(stream->Write(request));
     538           2 :   EXPECT_TRUE(stream->Read(&response));
     539           2 :   EXPECT_EQ(response.message(), request.message());
     540             : 
     541           2 :   stream->WritesDone();
     542           2 :   EXPECT_FALSE(stream->Read(&response));
     543             : 
     544           2 :   Status s = stream->Finish();
     545           4 :   EXPECT_TRUE(s.ok());
     546           2 : }
     547             : 
     548             : // Talk to the two services with the same name but different package names.
     549             : // The two stubs are created on the same channel.
     550          10 : TEST_P(End2endTest, DiffPackageServices) {
     551           2 :   ResetStub();
     552           2 :   EchoRequest request;
     553           4 :   EchoResponse response;
     554           2 :   request.set_message("Hello");
     555             : 
     556           4 :   ClientContext context;
     557           4 :   Status s = stub_->Echo(&context, request, &response);
     558           2 :   EXPECT_EQ(response.message(), request.message());
     559           2 :   EXPECT_TRUE(s.ok());
     560             : 
     561             :   std::unique_ptr<grpc::cpp::test::util::duplicate::TestService::Stub>
     562             :       dup_pkg_stub(
     563           2 :           grpc::cpp::test::util::duplicate::TestService::NewStub(channel_));
     564           4 :   ClientContext context2;
     565           2 :   s = dup_pkg_stub->Echo(&context2, request, &response);
     566           2 :   EXPECT_EQ("no package", response.message());
     567           6 :   EXPECT_TRUE(s.ok());
     568           2 : }
     569             : 
     570           4 : void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) {
     571             :   gpr_sleep_until(gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
     572           4 :                                gpr_time_from_micros(delay_us, GPR_TIMESPAN)));
     573           4 :   while (!service->signal_client()) {
     574             :   }
     575           4 :   context->TryCancel();
     576           4 : }
     577             : 
     578             : // Client cancels request stream after sending two messages
     579          10 : TEST_P(End2endTest, ClientCancelsRequestStream) {
     580           2 :   ResetStub();
     581           2 :   EchoRequest request;
     582           4 :   EchoResponse response;
     583           4 :   ClientContext context;
     584           2 :   request.set_message("hello");
     585             : 
     586           4 :   auto stream = stub_->RequestStream(&context, &response);
     587           2 :   EXPECT_TRUE(stream->Write(request));
     588           2 :   EXPECT_TRUE(stream->Write(request));
     589             : 
     590           2 :   context.TryCancel();
     591             : 
     592           2 :   Status s = stream->Finish();
     593           2 :   EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
     594             : 
     595           4 :   EXPECT_EQ(response.message(), "");
     596           2 : }
     597             : 
     598             : // Client cancels server stream after sending some messages
     599          10 : TEST_P(End2endTest, ClientCancelsResponseStream) {
     600           2 :   ResetStub();
     601           2 :   EchoRequest request;
     602           4 :   EchoResponse response;
     603           4 :   ClientContext context;
     604           2 :   request.set_message("hello");
     605             : 
     606           4 :   auto stream = stub_->ResponseStream(&context, request);
     607             : 
     608           2 :   EXPECT_TRUE(stream->Read(&response));
     609           2 :   EXPECT_EQ(response.message(), request.message() + "0");
     610           2 :   EXPECT_TRUE(stream->Read(&response));
     611           2 :   EXPECT_EQ(response.message(), request.message() + "1");
     612             : 
     613           2 :   context.TryCancel();
     614             : 
     615             :   // The cancellation races with responses, so there might be zero or
     616             :   // one responses pending, read till failure
     617             : 
     618           2 :   if (stream->Read(&response)) {
     619           0 :     EXPECT_EQ(response.message(), request.message() + "2");
     620             :     // Since we have cancelled, we expect the next attempt to read to fail
     621           0 :     EXPECT_FALSE(stream->Read(&response));
     622             :   }
     623             : 
     624           2 :   Status s = stream->Finish();
     625             :   // The final status could be either of CANCELLED or OK depending on
     626             :   // who won the race.
     627           4 :   EXPECT_GE(grpc::StatusCode::CANCELLED, s.error_code());
     628           2 : }
     629             : 
     630             : // Client cancels bidi stream after sending some messages
     631          10 : TEST_P(End2endTest, ClientCancelsBidi) {
     632           2 :   ResetStub();
     633           2 :   EchoRequest request;
     634           4 :   EchoResponse response;
     635           4 :   ClientContext context;
     636           4 :   grpc::string msg("hello");
     637             : 
     638           4 :   auto stream = stub_->BidiStream(&context);
     639             : 
     640           2 :   request.set_message(msg + "0");
     641           2 :   EXPECT_TRUE(stream->Write(request));
     642           2 :   EXPECT_TRUE(stream->Read(&response));
     643           2 :   EXPECT_EQ(response.message(), request.message());
     644             : 
     645           2 :   request.set_message(msg + "1");
     646           2 :   EXPECT_TRUE(stream->Write(request));
     647             : 
     648           2 :   context.TryCancel();
     649             : 
     650             :   // The cancellation races with responses, so there might be zero or
     651             :   // one responses pending, read till failure
     652             : 
     653           2 :   if (stream->Read(&response)) {
     654           0 :     EXPECT_EQ(response.message(), request.message());
     655             :     // Since we have cancelled, we expect the next attempt to read to fail
     656           0 :     EXPECT_FALSE(stream->Read(&response));
     657             :   }
     658             : 
     659           2 :   Status s = stream->Finish();
     660           4 :   EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
     661           2 : }
     662             : 
     663          10 : TEST_P(End2endTest, RpcMaxMessageSize) {
     664           2 :   ResetStub();
     665           2 :   EchoRequest request;
     666           4 :   EchoResponse response;
     667           2 :   request.set_message(string(kMaxMessageSize_ * 2, 'a'));
     668             : 
     669           4 :   ClientContext context;
     670           4 :   Status s = stub_->Echo(&context, request, &response);
     671           4 :   EXPECT_FALSE(s.ok());
     672           2 : }
     673             : 
     674             : // Client sends 20 requests and the server returns CANCELLED status after
     675             : // reading 10 requests.
     676          10 : TEST_P(End2endTest, RequestStreamServerEarlyCancelTest) {
     677           2 :   ResetStub();
     678           2 :   EchoRequest request;
     679           4 :   EchoResponse response;
     680           4 :   ClientContext context;
     681             : 
     682           2 :   context.AddMetadata(kServerCancelAfterReads, "10");
     683           4 :   auto stream = stub_->RequestStream(&context, &response);
     684           2 :   request.set_message("hello");
     685           2 :   int send_messages = 20;
     686          24 :   while (send_messages > 10) {
     687          20 :     EXPECT_TRUE(stream->Write(request));
     688          20 :     send_messages--;
     689             :   }
     690          24 :   while (send_messages > 0) {
     691          20 :     stream->Write(request);
     692          20 :     send_messages--;
     693             :   }
     694           2 :   stream->WritesDone();
     695           2 :   Status s = stream->Finish();
     696           4 :   EXPECT_EQ(s.error_code(), StatusCode::CANCELLED);
     697           2 : }
     698             : 
     699           2 : void ReaderThreadFunc(ClientReaderWriter<EchoRequest, EchoResponse>* stream,
     700             :                       gpr_event* ev) {
     701           2 :   EchoResponse resp;
     702           2 :   gpr_event_set(ev, (void*)1);
     703           4 :   while (stream->Read(&resp)) {
     704           0 :     gpr_log(GPR_INFO, "Read message");
     705           2 :   }
     706           2 : }
     707             : 
     708             : // Run a Read and a WritesDone simultaneously.
     709          10 : TEST_P(End2endTest, SimultaneousReadWritesDone) {
     710           2 :   ResetStub();
     711           2 :   ClientContext context;
     712             :   gpr_event ev;
     713           2 :   gpr_event_init(&ev);
     714           4 :   auto stream = stub_->BidiStream(&context);
     715           4 :   std::thread reader_thread(ReaderThreadFunc, stream.get(), &ev);
     716           2 :   gpr_event_wait(&ev, gpr_inf_future(GPR_CLOCK_REALTIME));
     717           2 :   stream->WritesDone();
     718           4 :   Status s = stream->Finish();
     719           2 :   EXPECT_TRUE(s.ok());
     720           4 :   reader_thread.join();
     721           2 : }
     722             : 
     723          10 : TEST_P(End2endTest, ChannelState) {
     724           2 :   ResetStub();
     725             :   // Start IDLE
     726           2 :   EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(false));
     727             : 
     728             :   // Did not ask to connect, no state change.
     729           2 :   CompletionQueue cq;
     730             :   std::chrono::system_clock::time_point deadline =
     731           2 :       std::chrono::system_clock::now() + std::chrono::milliseconds(10);
     732           2 :   channel_->NotifyOnStateChange(GRPC_CHANNEL_IDLE, deadline, &cq, NULL);
     733             :   void* tag;
     734           2 :   bool ok = true;
     735           2 :   cq.Next(&tag, &ok);
     736           2 :   EXPECT_FALSE(ok);
     737             : 
     738           2 :   EXPECT_EQ(GRPC_CHANNEL_IDLE, channel_->GetState(true));
     739           2 :   EXPECT_TRUE(channel_->WaitForStateChange(GRPC_CHANNEL_IDLE,
     740           2 :                                            gpr_inf_future(GPR_CLOCK_REALTIME)));
     741           2 :   auto state = channel_->GetState(false);
     742           2 :   EXPECT_TRUE(state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_READY);
     743           2 : }
     744             : 
     745             : // Takes 10s.
     746          10 : TEST_P(End2endTest, ChannelStateTimeout) {
     747           2 :   if (GetParam().use_tls) {
     748           3 :     return;
     749             :   }
     750           1 :   int port = grpc_pick_unused_port_or_die();
     751           1 :   std::ostringstream server_address;
     752           1 :   server_address << "127.0.0.1:" << port;
     753             :   // Channel to non-existing server
     754           2 :   auto channel = CreateChannel(server_address.str(), InsecureCredentials());
     755             :   // Start IDLE
     756           1 :   EXPECT_EQ(GRPC_CHANNEL_IDLE, channel->GetState(true));
     757             : 
     758           1 :   auto state = GRPC_CHANNEL_IDLE;
     759          11 :   for (int i = 0; i < 10; i++) {
     760             :     channel->WaitForStateChange(
     761          10 :         state, std::chrono::system_clock::now() + std::chrono::seconds(1));
     762          10 :     state = channel->GetState(false);
     763           1 :   }
     764             : }
     765             : 
     766             : // Talking to a non-existing service.
     767          10 : TEST_P(End2endTest, NonExistingService) {
     768           2 :   ResetChannel();
     769           2 :   std::unique_ptr<grpc::cpp::test::util::UnimplementedService::Stub> stub;
     770           2 :   stub = grpc::cpp::test::util::UnimplementedService::NewStub(channel_);
     771             : 
     772           4 :   EchoRequest request;
     773           4 :   EchoResponse response;
     774           2 :   request.set_message("Hello");
     775             : 
     776           4 :   ClientContext context;
     777           4 :   Status s = stub->Unimplemented(&context, request, &response);
     778           2 :   EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
     779           4 :   EXPECT_EQ("", s.error_message());
     780           2 : }
     781             : 
     782             : //////////////////////////////////////////////////////////////////////////
     783             : // Test with and without a proxy.
     784          88 : class ProxyEnd2endTest : public End2endTest {
     785             :  protected:
     786             : };
     787             : 
     788          18 : TEST_P(ProxyEnd2endTest, SimpleRpc) {
     789           4 :   ResetStub();
     790           4 :   SendRpc(stub_.get(), 1);
     791           4 : }
     792             : 
     793          18 : TEST_P(ProxyEnd2endTest, MultipleRpcs) {
     794           4 :   ResetStub();
     795           4 :   std::vector<std::thread*> threads;
     796          44 :   for (int i = 0; i < 10; ++i) {
     797          40 :     threads.push_back(new std::thread(SendRpc, stub_.get(), 10));
     798             :   }
     799          44 :   for (int i = 0; i < 10; ++i) {
     800          40 :     threads[i]->join();
     801          40 :     delete threads[i];
     802           4 :   }
     803           4 : }
     804             : 
     805             : // Set a 10us deadline and make sure proper error is returned.
     806          18 : TEST_P(ProxyEnd2endTest, RpcDeadlineExpires) {
     807           4 :   ResetStub();
     808           4 :   EchoRequest request;
     809           8 :   EchoResponse response;
     810           4 :   request.set_message("Hello");
     811             : 
     812           8 :   ClientContext context;
     813             :   std::chrono::system_clock::time_point deadline =
     814           4 :       std::chrono::system_clock::now() + std::chrono::microseconds(10);
     815           4 :   context.set_deadline(deadline);
     816           8 :   Status s = stub_->Echo(&context, request, &response);
     817           8 :   EXPECT_EQ(StatusCode::DEADLINE_EXCEEDED, s.error_code());
     818           4 : }
     819             : 
     820             : // Set a long but finite deadline.
     821          18 : TEST_P(ProxyEnd2endTest, RpcLongDeadline) {
     822           4 :   ResetStub();
     823           4 :   EchoRequest request;
     824           8 :   EchoResponse response;
     825           4 :   request.set_message("Hello");
     826             : 
     827           8 :   ClientContext context;
     828             :   std::chrono::system_clock::time_point deadline =
     829           4 :       std::chrono::system_clock::now() + std::chrono::hours(1);
     830           4 :   context.set_deadline(deadline);
     831           8 :   Status s = stub_->Echo(&context, request, &response);
     832           4 :   EXPECT_EQ(response.message(), request.message());
     833           8 :   EXPECT_TRUE(s.ok());
     834           4 : }
     835             : 
     836             : // Ask server to echo back the deadline it sees.
     837          18 : TEST_P(ProxyEnd2endTest, EchoDeadline) {
     838           4 :   ResetStub();
     839           4 :   EchoRequest request;
     840           8 :   EchoResponse response;
     841           4 :   request.set_message("Hello");
     842           4 :   request.mutable_param()->set_echo_deadline(true);
     843             : 
     844           8 :   ClientContext context;
     845             :   std::chrono::system_clock::time_point deadline =
     846           4 :       std::chrono::system_clock::now() + std::chrono::seconds(100);
     847           4 :   context.set_deadline(deadline);
     848           8 :   Status s = stub_->Echo(&context, request, &response);
     849           4 :   EXPECT_EQ(response.message(), request.message());
     850           4 :   EXPECT_TRUE(s.ok());
     851             :   gpr_timespec sent_deadline;
     852           4 :   Timepoint2Timespec(deadline, &sent_deadline);
     853             :   // Allow 1 second error.
     854           4 :   EXPECT_LE(response.param().request_deadline() - sent_deadline.tv_sec, 1);
     855           8 :   EXPECT_GE(response.param().request_deadline() - sent_deadline.tv_sec, -1);
     856           4 : }
     857             : 
     858             : // Ask server to echo back the deadline it sees. The rpc has no deadline.
     859          18 : TEST_P(ProxyEnd2endTest, EchoDeadlineForNoDeadlineRpc) {
     860           4 :   ResetStub();
     861           4 :   EchoRequest request;
     862           8 :   EchoResponse response;
     863           4 :   request.set_message("Hello");
     864           4 :   request.mutable_param()->set_echo_deadline(true);
     865             : 
     866           8 :   ClientContext context;
     867           8 :   Status s = stub_->Echo(&context, request, &response);
     868           4 :   EXPECT_EQ(response.message(), request.message());
     869           4 :   EXPECT_TRUE(s.ok());
     870           4 :   EXPECT_EQ(response.param().request_deadline(),
     871           8 :             gpr_inf_future(GPR_CLOCK_REALTIME).tv_sec);
     872           4 : }
     873             : 
     874          18 : TEST_P(ProxyEnd2endTest, UnimplementedRpc) {
     875           4 :   ResetStub();
     876           4 :   EchoRequest request;
     877           8 :   EchoResponse response;
     878           4 :   request.set_message("Hello");
     879             : 
     880           8 :   ClientContext context;
     881           8 :   Status s = stub_->Unimplemented(&context, request, &response);
     882           4 :   EXPECT_FALSE(s.ok());
     883           4 :   EXPECT_EQ(s.error_code(), grpc::StatusCode::UNIMPLEMENTED);
     884           4 :   EXPECT_EQ(s.error_message(), "");
     885           8 :   EXPECT_EQ(response.message(), "");
     886           4 : }
     887             : 
     888             : // Client cancels rpc after 10ms
     889          18 : TEST_P(ProxyEnd2endTest, ClientCancelsRpc) {
     890           4 :   ResetStub();
     891           4 :   EchoRequest request;
     892           8 :   EchoResponse response;
     893           4 :   request.set_message("Hello");
     894           4 :   const int kCancelDelayUs = 10 * 1000;
     895           4 :   request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs);
     896             : 
     897           8 :   ClientContext context;
     898           8 :   std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_);
     899           8 :   Status s = stub_->Echo(&context, request, &response);
     900           4 :   cancel_thread.join();
     901           4 :   EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
     902           8 :   EXPECT_EQ(s.error_message(), "Cancelled");
     903           4 : }
     904             : 
     905             : // Server cancels rpc after 1ms
     906          18 : TEST_P(ProxyEnd2endTest, ServerCancelsRpc) {
     907           4 :   ResetStub();
     908           4 :   EchoRequest request;
     909           8 :   EchoResponse response;
     910           4 :   request.set_message("Hello");
     911           4 :   request.mutable_param()->set_server_cancel_after_us(1000);
     912             : 
     913           8 :   ClientContext context;
     914           8 :   Status s = stub_->Echo(&context, request, &response);
     915           4 :   EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
     916           8 :   EXPECT_TRUE(s.error_message().empty());
     917           4 : }
     918             : 
     919             : // Make the response larger than the flow control window.
     920          18 : TEST_P(ProxyEnd2endTest, HugeResponse) {
     921           4 :   ResetStub();
     922           4 :   EchoRequest request;
     923           8 :   EchoResponse response;
     924           4 :   request.set_message("huge response");
     925           4 :   const size_t kResponseSize = 1024 * (1024 + 10);
     926           4 :   request.mutable_param()->set_response_message_length(kResponseSize);
     927             : 
     928           8 :   ClientContext context;
     929           8 :   Status s = stub_->Echo(&context, request, &response);
     930           4 :   EXPECT_EQ(kResponseSize, response.message().size());
     931           8 :   EXPECT_TRUE(s.ok());
     932           4 : }
     933             : 
     934          18 : TEST_P(ProxyEnd2endTest, Peer) {
     935           4 :   ResetStub();
     936           4 :   EchoRequest request;
     937           8 :   EchoResponse response;
     938           4 :   request.set_message("hello");
     939           4 :   request.mutable_param()->set_echo_peer(true);
     940             : 
     941           8 :   ClientContext context;
     942           8 :   Status s = stub_->Echo(&context, request, &response);
     943           4 :   EXPECT_EQ(response.message(), request.message());
     944           4 :   EXPECT_TRUE(s.ok());
     945           4 :   EXPECT_TRUE(CheckIsLocalhost(response.param().peer()));
     946           8 :   EXPECT_TRUE(CheckIsLocalhost(context.peer()));
     947           4 : }
     948             : 
     949             : //////////////////////////////////////////////////////////////////////////
     950          12 : class SecureEnd2endTest : public End2endTest {
     951             :  protected:
     952          12 :   SecureEnd2endTest() {
     953          12 :     GPR_ASSERT(!GetParam().use_proxy);
     954          12 :     GPR_ASSERT(GetParam().use_tls);
     955          12 :   }
     956             : };
     957             : 
     958           6 : TEST_P(SecureEnd2endTest, SimpleRpcWithHost) {
     959           1 :   ResetStub();
     960             : 
     961           1 :   EchoRequest request;
     962           2 :   EchoResponse response;
     963           1 :   request.set_message("Hello");
     964             : 
     965           2 :   ClientContext context;
     966           1 :   context.set_authority("foo.test.youtube.com");
     967           2 :   Status s = stub_->Echo(&context, request, &response);
     968           1 :   EXPECT_EQ(response.message(), request.message());
     969           1 :   EXPECT_TRUE(response.has_param());
     970           1 :   EXPECT_EQ("special", response.param().host());
     971           2 :   EXPECT_TRUE(s.ok());
     972           1 : }
     973             : 
     974             : // rpc and stream should fail on bad credentials.
     975           6 : TEST_P(SecureEnd2endTest, BadCredentials) {
     976           1 :   std::shared_ptr<Credentials> bad_creds = GoogleRefreshTokenCredentials("");
     977           1 :   EXPECT_EQ(static_cast<Credentials*>(nullptr), bad_creds.get());
     978             :   std::shared_ptr<Channel> channel =
     979           1 :       CreateChannel(server_address_.str(), bad_creds);
     980             :   std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub(
     981           2 :       grpc::cpp::test::util::TestService::NewStub(channel));
     982           2 :   EchoRequest request;
     983           2 :   EchoResponse response;
     984           2 :   ClientContext context;
     985           1 :   request.set_message("Hello");
     986             : 
     987           2 :   Status s = stub->Echo(&context, request, &response);
     988           1 :   EXPECT_EQ("", response.message());
     989           1 :   EXPECT_FALSE(s.ok());
     990           1 :   EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
     991           1 :   EXPECT_EQ("Invalid credentials.", s.error_message());
     992             : 
     993           1 :   ClientContext context2;
     994           2 :   auto stream = stub->BidiStream(&context2);
     995           1 :   s = stream->Finish();
     996           1 :   EXPECT_FALSE(s.ok());
     997           1 :   EXPECT_EQ(StatusCode::INVALID_ARGUMENT, s.error_code());
     998           3 :   EXPECT_EQ("Invalid credentials.", s.error_message());
     999           1 : }
    1000             : 
    1001           8 : bool MetadataContains(
    1002             :     const std::multimap<grpc::string_ref, grpc::string_ref>& metadata,
    1003             :     const grpc::string& key, const grpc::string& value) {
    1004           8 :   int count = 0;
    1005             : 
    1006          84 :   for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator iter =
    1007           8 :            metadata.begin();
    1008          56 :        iter != metadata.end(); ++iter) {
    1009          20 :     if (ToString(iter->first) == key && ToString(iter->second) == value) {
    1010           4 :       count++;
    1011             :     }
    1012             :   }
    1013           8 :   return count == 1;
    1014             : }
    1015             : 
    1016           6 : TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorSuccess) {
    1017           1 :   auto* processor = new TestAuthMetadataProcessor(true);
    1018           1 :   StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
    1019           1 :   ResetStub();
    1020           1 :   EchoRequest request;
    1021           2 :   EchoResponse response;
    1022           2 :   ClientContext context;
    1023           1 :   context.set_credentials(processor->GetCompatibleClientCreds());
    1024           1 :   request.set_message("Hello");
    1025           1 :   request.mutable_param()->set_echo_metadata(true);
    1026             :   request.mutable_param()->set_expected_client_identity(
    1027           1 :       TestAuthMetadataProcessor::kGoodGuy);
    1028             : 
    1029           2 :   Status s = stub_->Echo(&context, request, &response);
    1030           1 :   EXPECT_EQ(request.message(), response.message());
    1031           1 :   EXPECT_TRUE(s.ok());
    1032             : 
    1033             :   // Metadata should have been consumed by the processor.
    1034           1 :   EXPECT_FALSE(MetadataContains(
    1035             :       context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
    1036           2 :       grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
    1037           1 : }
    1038             : 
    1039           6 : TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginAndProcessorFailure) {
    1040           1 :   auto* processor = new TestAuthMetadataProcessor(true);
    1041           1 :   StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
    1042           1 :   ResetStub();
    1043           1 :   EchoRequest request;
    1044           2 :   EchoResponse response;
    1045           2 :   ClientContext context;
    1046           1 :   context.set_credentials(processor->GetIncompatibleClientCreds());
    1047           1 :   request.set_message("Hello");
    1048             : 
    1049           2 :   Status s = stub_->Echo(&context, request, &response);
    1050           1 :   EXPECT_FALSE(s.ok());
    1051           2 :   EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
    1052           1 : }
    1053           6 : TEST_P(SecureEnd2endTest, SetPerCallCredentials) {
    1054           1 :   ResetStub();
    1055           1 :   EchoRequest request;
    1056           2 :   EchoResponse response;
    1057           2 :   ClientContext context;
    1058             :   std::shared_ptr<Credentials> creds =
    1059           2 :       GoogleIAMCredentials("fake_token", "fake_selector");
    1060           1 :   context.set_credentials(creds);
    1061           1 :   request.set_message("Hello");
    1062           1 :   request.mutable_param()->set_echo_metadata(true);
    1063             : 
    1064           2 :   Status s = stub_->Echo(&context, request, &response);
    1065           1 :   EXPECT_EQ(request.message(), response.message());
    1066           1 :   EXPECT_TRUE(s.ok());
    1067           1 :   EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
    1068             :                                GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
    1069           1 :                                "fake_token"));
    1070           1 :   EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
    1071             :                                GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
    1072           2 :                                "fake_selector"));
    1073           1 : }
    1074             : 
    1075           6 : TEST_P(SecureEnd2endTest, InsecurePerCallCredentials) {
    1076           1 :   ResetStub();
    1077           1 :   EchoRequest request;
    1078           2 :   EchoResponse response;
    1079           2 :   ClientContext context;
    1080           2 :   std::shared_ptr<Credentials> creds = InsecureCredentials();
    1081           1 :   context.set_credentials(creds);
    1082           1 :   request.set_message("Hello");
    1083           1 :   request.mutable_param()->set_echo_metadata(true);
    1084             : 
    1085           2 :   Status s = stub_->Echo(&context, request, &response);
    1086           1 :   EXPECT_EQ(StatusCode::CANCELLED, s.error_code());
    1087           2 :   EXPECT_EQ("Failed to set credentials to rpc.", s.error_message());
    1088           1 : }
    1089             : 
    1090           6 : TEST_P(SecureEnd2endTest, OverridePerCallCredentials) {
    1091           1 :   ResetStub();
    1092           1 :   EchoRequest request;
    1093           2 :   EchoResponse response;
    1094           2 :   ClientContext context;
    1095             :   std::shared_ptr<Credentials> creds1 =
    1096           2 :       GoogleIAMCredentials("fake_token1", "fake_selector1");
    1097           1 :   context.set_credentials(creds1);
    1098             :   std::shared_ptr<Credentials> creds2 =
    1099           2 :       GoogleIAMCredentials("fake_token2", "fake_selector2");
    1100           1 :   context.set_credentials(creds2);
    1101           1 :   request.set_message("Hello");
    1102           1 :   request.mutable_param()->set_echo_metadata(true);
    1103             : 
    1104           2 :   Status s = stub_->Echo(&context, request, &response);
    1105           1 :   EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
    1106             :                                GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
    1107           1 :                                "fake_token2"));
    1108           1 :   EXPECT_TRUE(MetadataContains(context.GetServerTrailingMetadata(),
    1109             :                                GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
    1110           1 :                                "fake_selector2"));
    1111           1 :   EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
    1112             :                                 GRPC_IAM_AUTHORIZATION_TOKEN_METADATA_KEY,
    1113           1 :                                 "fake_token1"));
    1114           1 :   EXPECT_FALSE(MetadataContains(context.GetServerTrailingMetadata(),
    1115             :                                 GRPC_IAM_AUTHORITY_SELECTOR_METADATA_KEY,
    1116           1 :                                 "fake_selector1"));
    1117           1 :   EXPECT_EQ(request.message(), response.message());
    1118           2 :   EXPECT_TRUE(s.ok());
    1119           1 : }
    1120             : 
    1121           6 : TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginFailure) {
    1122           1 :   ResetStub();
    1123           1 :   EchoRequest request;
    1124           2 :   EchoResponse response;
    1125           2 :   ClientContext context;
    1126             :   context.set_credentials(
    1127             :       MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
    1128             :           new TestMetadataCredentialsPlugin(
    1129             :               "Does not matter, will fail anyway (see 3rd param)", false,
    1130           1 :               false))));
    1131           1 :   request.set_message("Hello");
    1132             : 
    1133           2 :   Status s = stub_->Echo(&context, request, &response);
    1134           1 :   EXPECT_FALSE(s.ok());
    1135           2 :   EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
    1136           1 : }
    1137             : 
    1138           6 : TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorSuccess) {
    1139           1 :   auto* processor = new TestAuthMetadataProcessor(false);
    1140           1 :   StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
    1141           1 :   ResetStub();
    1142           1 :   EchoRequest request;
    1143           2 :   EchoResponse response;
    1144           2 :   ClientContext context;
    1145           1 :   context.set_credentials(processor->GetCompatibleClientCreds());
    1146           1 :   request.set_message("Hello");
    1147           1 :   request.mutable_param()->set_echo_metadata(true);
    1148             :   request.mutable_param()->set_expected_client_identity(
    1149           1 :       TestAuthMetadataProcessor::kGoodGuy);
    1150             : 
    1151           2 :   Status s = stub_->Echo(&context, request, &response);
    1152           1 :   EXPECT_EQ(request.message(), response.message());
    1153           1 :   EXPECT_TRUE(s.ok());
    1154             : 
    1155             :   // Metadata should have been consumed by the processor.
    1156           1 :   EXPECT_FALSE(MetadataContains(
    1157             :       context.GetServerTrailingMetadata(), GRPC_AUTHORIZATION_METADATA_KEY,
    1158           2 :       grpc::string("Bearer ") + TestAuthMetadataProcessor::kGoodGuy));
    1159           1 : }
    1160             : 
    1161           6 : TEST_P(SecureEnd2endTest, NonBlockingAuthMetadataPluginAndProcessorFailure) {
    1162           1 :   auto* processor = new TestAuthMetadataProcessor(false);
    1163           1 :   StartServer(std::shared_ptr<AuthMetadataProcessor>(processor));
    1164           1 :   ResetStub();
    1165           1 :   EchoRequest request;
    1166           2 :   EchoResponse response;
    1167           2 :   ClientContext context;
    1168           1 :   context.set_credentials(processor->GetIncompatibleClientCreds());
    1169           1 :   request.set_message("Hello");
    1170             : 
    1171           2 :   Status s = stub_->Echo(&context, request, &response);
    1172           1 :   EXPECT_FALSE(s.ok());
    1173           2 :   EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
    1174           1 : }
    1175             : 
    1176           6 : TEST_P(SecureEnd2endTest, BlockingAuthMetadataPluginFailure) {
    1177           1 :   ResetStub();
    1178           1 :   EchoRequest request;
    1179           2 :   EchoResponse response;
    1180           2 :   ClientContext context;
    1181             :   context.set_credentials(
    1182             :       MetadataCredentialsFromPlugin(std::unique_ptr<MetadataCredentialsPlugin>(
    1183             :           new TestMetadataCredentialsPlugin(
    1184             :               "Does not matter, will fail anyway (see 3rd param)", true,
    1185           1 :               false))));
    1186           1 :   request.set_message("Hello");
    1187             : 
    1188           2 :   Status s = stub_->Echo(&context, request, &response);
    1189           1 :   EXPECT_FALSE(s.ok());
    1190           2 :   EXPECT_EQ(s.error_code(), StatusCode::UNAUTHENTICATED);
    1191           1 : }
    1192             : 
    1193           6 : TEST_P(SecureEnd2endTest, ClientAuthContext) {
    1194           1 :   ResetStub();
    1195           1 :   EchoRequest request;
    1196           2 :   EchoResponse response;
    1197           1 :   request.set_message("Hello");
    1198           1 :   request.mutable_param()->set_check_auth_context(true);
    1199             : 
    1200           2 :   ClientContext context;
    1201           2 :   Status s = stub_->Echo(&context, request, &response);
    1202           1 :   EXPECT_EQ(response.message(), request.message());
    1203           1 :   EXPECT_TRUE(s.ok());
    1204             : 
    1205           1 :   std::shared_ptr<const AuthContext> auth_ctx = context.auth_context();
    1206             :   std::vector<grpc::string_ref> ssl =
    1207           2 :       auth_ctx->FindPropertyValues("transport_security_type");
    1208           1 :   EXPECT_EQ(1u, ssl.size());
    1209           1 :   EXPECT_EQ("ssl", ToString(ssl[0]));
    1210           1 :   EXPECT_EQ("x509_subject_alternative_name",
    1211           1 :             auth_ctx->GetPeerIdentityPropertyName());
    1212           1 :   EXPECT_EQ(3u, auth_ctx->GetPeerIdentity().size());
    1213           1 :   EXPECT_EQ("*.test.google.fr", ToString(auth_ctx->GetPeerIdentity()[0]));
    1214           1 :   EXPECT_EQ("waterzooi.test.google.be",
    1215           1 :             ToString(auth_ctx->GetPeerIdentity()[1]));
    1216           3 :   EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2]));
    1217           1 : }
    1218             : 
    1219          15 : INSTANTIATE_TEST_CASE_P(End2end, End2endTest,
    1220             :                         ::testing::Values(TestScenario(false, true),
    1221             :                                           TestScenario(false, false)));
    1222             : 
    1223          12 : INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest,
    1224             :                         ::testing::Values(TestScenario(true, true),
    1225             :                                           TestScenario(true, false),
    1226             :                                           TestScenario(false, true),
    1227             :                                           TestScenario(false, false)));
    1228             : 
    1229          13 : INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest,
    1230             :                         ::testing::Values(TestScenario(false, true)));
    1231             : 
    1232             : }  // namespace
    1233             : }  // namespace testing
    1234             : }  // namespace grpc
    1235             : 
    1236           1 : int main(int argc, char** argv) {
    1237           1 :   grpc_test_init(argc, argv);
    1238           1 :   ::testing::InitGoogleTest(&argc, argv);
    1239           1 :   return RUN_ALL_TESTS();
    1240           3 : }

Generated by: LCOV version 1.10