57cdbeb7b7696500390b6805f089d41c9f55b0e8
[platform/upstream/grpc.git] / test / cpp / util / grpc_tool_test.cc
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18
19 #include "test/cpp/util/grpc_tool.h"
20
21 #include <sstream>
22
23 #include <gflags/gflags.h>
24 #include <grpc/grpc.h>
25 #include <grpc/support/alloc.h>
26 #include <grpcpp/channel.h>
27 #include <grpcpp/client_context.h>
28 #include <grpcpp/create_channel.h>
29 #include <grpcpp/ext/proto_server_reflection_plugin.h>
30 #include <grpcpp/server.h>
31 #include <grpcpp/server_builder.h>
32 #include <grpcpp/server_context.h>
33 #include <gtest/gtest.h>
34
35 #include "src/core/lib/gpr/env.h"
36 #include "src/proto/grpc/testing/echo.grpc.pb.h"
37 #include "src/proto/grpc/testing/echo.pb.h"
38 #include "test/core/end2end/data/ssl_test_data.h"
39 #include "test/core/util/port.h"
40 #include "test/core/util/test_config.h"
41 #include "test/cpp/util/cli_credentials.h"
42 #include "test/cpp/util/string_ref_helper.h"
43
44 using grpc::testing::EchoRequest;
45 using grpc::testing::EchoResponse;
46
47 #define USAGE_REGEX "(  grpc_cli .+\n){2,10}"
48
49 #define ECHO_TEST_SERVICE_SUMMARY \
50   "Echo\n"                        \
51   "CheckClientInitialMetadata\n"  \
52   "RequestStream\n"               \
53   "ResponseStream\n"              \
54   "BidiStream\n"                  \
55   "Unimplemented\n"
56
57 #define ECHO_TEST_SERVICE_DESCRIPTION                                         \
58   "filename: src/proto/grpc/testing/echo.proto\n"                             \
59   "package: grpc.testing;\n"                                                  \
60   "service EchoTestService {\n"                                               \
61   "  rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
62   "{}\n"                                                                      \
63   "  rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns "     \
64   "(grpc.testing.SimpleResponse) {}\n"                                        \
65   "  rpc RequestStream(stream grpc.testing.EchoRequest) returns "             \
66   "(grpc.testing.EchoResponse) {}\n"                                          \
67   "  rpc ResponseStream(grpc.testing.EchoRequest) returns (stream "           \
68   "grpc.testing.EchoResponse) {}\n"                                           \
69   "  rpc BidiStream(stream grpc.testing.EchoRequest) returns (stream "        \
70   "grpc.testing.EchoResponse) {}\n"                                           \
71   "  rpc Unimplemented(grpc.testing.EchoRequest) returns "                    \
72   "(grpc.testing.EchoResponse) {}\n"                                          \
73   "}\n"                                                                       \
74   "\n"
75
76 #define ECHO_METHOD_DESCRIPTION                                               \
77   "  rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
78   "{}\n"
79
80 #define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \
81   "message: \"echo\"\n"                   \
82   "param {\n"                             \
83   "  host: \"localhost\"\n"               \
84   "  peer: \"peer\"\n"                    \
85   "}\n\n"
86
87 #define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \
88   "{\n"                                   \
89   " \"message\": \"echo\",\n"             \
90   " \"param\": {\n"                       \
91   "  \"host\": \"localhost\",\n"          \
92   "  \"peer\": \"peer\"\n"                \
93   " }\n"                                  \
94   "}\n\n"
95
96 DECLARE_string(channel_creds_type);
97 DECLARE_string(ssl_target);
98
99 namespace grpc {
100 namespace testing {
101
102 DECLARE_bool(binary_input);
103 DECLARE_bool(binary_output);
104 DECLARE_bool(json_input);
105 DECLARE_bool(json_output);
106 DECLARE_bool(l);
107 DECLARE_bool(batch);
108 DECLARE_string(metadata);
109 DECLARE_string(protofiles);
110 DECLARE_string(proto_path);
111
112 namespace {
113
114 const int kServerDefaultResponseStreamsToSend = 3;
115
116 class TestCliCredentials final : public grpc::testing::CliCredentials {
117  public:
118   TestCliCredentials(bool secure = false) : secure_(secure) {}
119   std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials()
120       const override {
121     if (!secure_) {
122       return InsecureChannelCredentials();
123     }
124     SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
125     return SslCredentials(grpc::SslCredentialsOptions(ssl_opts));
126   }
127   const grpc::string GetCredentialUsage() const override { return ""; }
128
129  private:
130   const bool secure_;
131 };
132
133 bool PrintStream(std::stringstream* ss, const grpc::string& output) {
134   (*ss) << output;
135   return true;
136 }
137
138 template <typename T>
139 size_t ArraySize(T& a) {
140   return ((sizeof(a) / sizeof(*(a))) /
141           static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))));
142 }
143
144 class TestServiceImpl : public ::grpc::testing::EchoTestService::Service {
145  public:
146   Status Echo(ServerContext* context, const EchoRequest* request,
147               EchoResponse* response) override {
148     if (!context->client_metadata().empty()) {
149       for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
150                iter = context->client_metadata().begin();
151            iter != context->client_metadata().end(); ++iter) {
152         context->AddInitialMetadata(ToString(iter->first),
153                                     ToString(iter->second));
154       }
155     }
156     context->AddTrailingMetadata("trailing_key", "trailing_value");
157     response->set_message(request->message());
158     return Status::OK;
159   }
160
161   Status RequestStream(ServerContext* context,
162                        ServerReader<EchoRequest>* reader,
163                        EchoResponse* response) override {
164     EchoRequest request;
165     response->set_message("");
166     if (!context->client_metadata().empty()) {
167       for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
168                iter = context->client_metadata().begin();
169            iter != context->client_metadata().end(); ++iter) {
170         context->AddInitialMetadata(ToString(iter->first),
171                                     ToString(iter->second));
172       }
173     }
174     context->AddTrailingMetadata("trailing_key", "trailing_value");
175     while (reader->Read(&request)) {
176       response->mutable_message()->append(request.message());
177     }
178
179     return Status::OK;
180   }
181
182   Status ResponseStream(ServerContext* context, const EchoRequest* request,
183                         ServerWriter<EchoResponse>* writer) override {
184     if (!context->client_metadata().empty()) {
185       for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
186                iter = context->client_metadata().begin();
187            iter != context->client_metadata().end(); ++iter) {
188         context->AddInitialMetadata(ToString(iter->first),
189                                     ToString(iter->second));
190       }
191     }
192     context->AddTrailingMetadata("trailing_key", "trailing_value");
193
194     EchoResponse response;
195     for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
196       response.set_message(request->message() + grpc::to_string(i));
197       writer->Write(response);
198     }
199
200     return Status::OK;
201   }
202
203   Status BidiStream(
204       ServerContext* context,
205       ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
206     EchoRequest request;
207     EchoResponse response;
208     if (!context->client_metadata().empty()) {
209       for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
210                iter = context->client_metadata().begin();
211            iter != context->client_metadata().end(); ++iter) {
212         context->AddInitialMetadata(ToString(iter->first),
213                                     ToString(iter->second));
214       }
215     }
216     context->AddTrailingMetadata("trailing_key", "trailing_value");
217
218     while (stream->Read(&request)) {
219       response.set_message(request.message());
220       stream->Write(response);
221     }
222
223     return Status::OK;
224   }
225 };
226
227 }  // namespace
228
229 class GrpcToolTest : public ::testing::Test {
230  protected:
231   GrpcToolTest() {}
232
233   // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die()
234   // uses atexit() to free chosen ports, and it will spawn a new thread in
235   // resolve_address_posix.c:192 at exit time.
236   const grpc::string SetUpServer(bool secure = false) {
237     std::ostringstream server_address;
238     int port = grpc_pick_unused_port_or_die();
239     server_address << "localhost:" << port;
240     // Setup server
241     ServerBuilder builder;
242     std::shared_ptr<grpc::ServerCredentials> creds;
243     if (secure) {
244       SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key,
245                                                           test_server1_cert};
246       SslServerCredentialsOptions ssl_opts;
247       ssl_opts.pem_root_certs = "";
248       ssl_opts.pem_key_cert_pairs.push_back(pkcp);
249       creds = SslServerCredentials(ssl_opts);
250     } else {
251       creds = InsecureServerCredentials();
252     }
253     builder.AddListeningPort(server_address.str(), creds);
254     builder.RegisterService(&service_);
255     server_ = builder.BuildAndStart();
256     return server_address.str();
257   }
258
259   void ShutdownServer() { server_->Shutdown(); }
260
261   std::unique_ptr<Server> server_;
262   TestServiceImpl service_;
263   reflection::ProtoServerReflectionPlugin plugin_;
264 };
265
266 TEST_F(GrpcToolTest, NoCommand) {
267   // Test input "grpc_cli"
268   std::stringstream output_stream;
269   const char* argv[] = {"grpc_cli"};
270   // Exit with 1, print usage instruction in stderr
271   EXPECT_EXIT(
272       GrpcToolMainLib(
273           ArraySize(argv), argv, TestCliCredentials(),
274           std::bind(PrintStream, &output_stream, std::placeholders::_1)),
275       ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX);
276   // No output
277   EXPECT_TRUE(0 == output_stream.tellp());
278 }
279
280 TEST_F(GrpcToolTest, InvalidCommand) {
281   // Test input "grpc_cli"
282   std::stringstream output_stream;
283   const char* argv[] = {"grpc_cli", "abc"};
284   // Exit with 1, print usage instruction in stderr
285   EXPECT_EXIT(
286       GrpcToolMainLib(
287           ArraySize(argv), argv, TestCliCredentials(),
288           std::bind(PrintStream, &output_stream, std::placeholders::_1)),
289       ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX);
290   // No output
291   EXPECT_TRUE(0 == output_stream.tellp());
292 }
293
294 TEST_F(GrpcToolTest, HelpCommand) {
295   // Test input "grpc_cli help"
296   std::stringstream output_stream;
297   const char* argv[] = {"grpc_cli", "help"};
298   // Exit with 1, print usage instruction in stderr
299   EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
300                               std::bind(PrintStream, &output_stream,
301                                         std::placeholders::_1)),
302               ::testing::ExitedWithCode(1), USAGE_REGEX);
303   // No output
304   EXPECT_TRUE(0 == output_stream.tellp());
305 }
306
307 TEST_F(GrpcToolTest, ListCommand) {
308   // Test input "grpc_cli list localhost:<port>"
309   std::stringstream output_stream;
310
311   const grpc::string server_address = SetUpServer();
312   const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
313
314   FLAGS_l = false;
315   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
316                                    std::bind(PrintStream, &output_stream,
317                                              std::placeholders::_1)));
318   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
319                           "grpc.testing.EchoTestService\n"
320                           "grpc.reflection.v1alpha.ServerReflection\n"));
321
322   ShutdownServer();
323 }
324
325 TEST_F(GrpcToolTest, ListOneService) {
326   // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService"
327   std::stringstream output_stream;
328
329   const grpc::string server_address = SetUpServer();
330   const char* argv[] = {"grpc_cli", "ls", server_address.c_str(),
331                         "grpc.testing.EchoTestService"};
332   // without -l flag
333   FLAGS_l = false;
334   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
335                                    std::bind(PrintStream, &output_stream,
336                                              std::placeholders::_1)));
337   // Expected output: ECHO_TEST_SERVICE_SUMMARY
338   EXPECT_TRUE(0 ==
339               strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY));
340
341   // with -l flag
342   output_stream.str(grpc::string());
343   output_stream.clear();
344   FLAGS_l = true;
345   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
346                                    std::bind(PrintStream, &output_stream,
347                                              std::placeholders::_1)));
348   // Expected output: ECHO_TEST_SERVICE_DESCRIPTION
349   EXPECT_TRUE(
350       0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION));
351
352   ShutdownServer();
353 }
354
355 TEST_F(GrpcToolTest, TypeCommand) {
356   // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest"
357   std::stringstream output_stream;
358
359   const grpc::string server_address = SetUpServer();
360   const char* argv[] = {"grpc_cli", "type", server_address.c_str(),
361                         "grpc.testing.EchoRequest"};
362
363   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
364                                    std::bind(PrintStream, &output_stream,
365                                              std::placeholders::_1)));
366   const grpc::protobuf::Descriptor* desc =
367       grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(
368           "grpc.testing.EchoRequest");
369   // Expected output: the DebugString of grpc.testing.EchoRequest
370   EXPECT_TRUE(0 ==
371               strcmp(output_stream.str().c_str(), desc->DebugString().c_str()));
372
373   ShutdownServer();
374 }
375
376 TEST_F(GrpcToolTest, ListOneMethod) {
377   // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService"
378   std::stringstream output_stream;
379
380   const grpc::string server_address = SetUpServer();
381   const char* argv[] = {"grpc_cli", "ls", server_address.c_str(),
382                         "grpc.testing.EchoTestService.Echo"};
383   // without -l flag
384   FLAGS_l = false;
385   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
386                                    std::bind(PrintStream, &output_stream,
387                                              std::placeholders::_1)));
388   // Expected output: "Echo"
389   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n"));
390
391   // with -l flag
392   output_stream.str(grpc::string());
393   output_stream.clear();
394   FLAGS_l = true;
395   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
396                                    std::bind(PrintStream, &output_stream,
397                                              std::placeholders::_1)));
398   // Expected output: ECHO_METHOD_DESCRIPTION
399   EXPECT_TRUE(0 ==
400               strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION));
401
402   ShutdownServer();
403 }
404
405 TEST_F(GrpcToolTest, TypeNotFound) {
406   // Test input "grpc_cli type localhost:<port> grpc.testing.DummyRequest"
407   std::stringstream output_stream;
408
409   const grpc::string server_address = SetUpServer();
410   const char* argv[] = {"grpc_cli", "type", server_address.c_str(),
411                         "grpc.testing.DummyRequest"};
412
413   EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
414                                    std::bind(PrintStream, &output_stream,
415                                              std::placeholders::_1)));
416   ShutdownServer();
417 }
418
419 TEST_F(GrpcToolTest, CallCommand) {
420   // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'"
421   std::stringstream output_stream;
422
423   const grpc::string server_address = SetUpServer();
424   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
425                         "message: 'Hello'"};
426
427   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
428                                    std::bind(PrintStream, &output_stream,
429                                              std::placeholders::_1)));
430   // Expected output: "message: \"Hello\""
431   EXPECT_TRUE(nullptr !=
432               strstr(output_stream.str().c_str(), "message: \"Hello\""));
433
434   // with json_output
435   output_stream.str(grpc::string());
436   output_stream.clear();
437
438   FLAGS_json_output = true;
439   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
440                                    std::bind(PrintStream, &output_stream,
441                                              std::placeholders::_1)));
442   FLAGS_json_output = false;
443
444   // Expected output:
445   // {
446   //  "message": "Hello"
447   // }
448   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
449                                 "{\n \"message\": \"Hello\"\n}"));
450
451   ShutdownServer();
452 }
453
454 TEST_F(GrpcToolTest, CallCommandJsonInput) {
455   // Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}"
456   std::stringstream output_stream;
457
458   const grpc::string server_address = SetUpServer();
459   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
460                         "{ \"message\": \"Hello\"}"};
461
462   FLAGS_json_input = true;
463   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
464                                    std::bind(PrintStream, &output_stream,
465                                              std::placeholders::_1)));
466   // Expected output: "message: \"Hello\""
467   EXPECT_TRUE(nullptr !=
468               strstr(output_stream.str().c_str(), "message: \"Hello\""));
469
470   // with json_output
471   output_stream.str(grpc::string());
472   output_stream.clear();
473
474   FLAGS_json_output = true;
475   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
476                                    std::bind(PrintStream, &output_stream,
477                                              std::placeholders::_1)));
478   FLAGS_json_output = false;
479   FLAGS_json_input = false;
480
481   // Expected output:
482   // {
483   //  "message": "Hello"
484   // }
485   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
486                                 "{\n \"message\": \"Hello\"\n}"));
487
488   ShutdownServer();
489 }
490
491 TEST_F(GrpcToolTest, CallCommandBatch) {
492   // Test input "grpc_cli call Echo"
493   std::stringstream output_stream;
494
495   const grpc::string server_address = SetUpServer();
496   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
497                         "message: 'Hello0'"};
498
499   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
500   std::streambuf* orig = std::cin.rdbuf();
501   std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
502   std::cin.rdbuf(ss.rdbuf());
503
504   FLAGS_batch = true;
505   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
506                                    std::bind(PrintStream, &output_stream,
507                                              std::placeholders::_1)));
508   FLAGS_batch = false;
509
510   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
511   // "Hello2"\n"
512   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
513                                 "message: \"Hello0\"\nmessage: "
514                                 "\"Hello1\"\nmessage: \"Hello2\"\n"));
515   // with json_output
516   output_stream.str(grpc::string());
517   output_stream.clear();
518   ss.clear();
519   ss.seekg(0);
520   std::cin.rdbuf(ss.rdbuf());
521
522   FLAGS_batch = true;
523   FLAGS_json_output = true;
524   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
525                                    std::bind(PrintStream, &output_stream,
526                                              std::placeholders::_1)));
527   FLAGS_json_output = false;
528   FLAGS_batch = false;
529
530   // Expected output:
531   // {
532   //  "message": "Hello0"
533   // }
534   // {
535   //  "message": "Hello1"
536   // }
537   // {
538   //  "message": "Hello2"
539   // }
540   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
541   // "Hello2"\n"
542   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
543                                 "{\n \"message\": \"Hello0\"\n}\n"
544                                 "{\n \"message\": \"Hello1\"\n}\n"
545                                 "{\n \"message\": \"Hello2\"\n}\n"));
546
547   std::cin.rdbuf(orig);
548   ShutdownServer();
549 }
550
551 TEST_F(GrpcToolTest, CallCommandBatchJsonInput) {
552   // Test input "grpc_cli call Echo"
553   std::stringstream output_stream;
554
555   const grpc::string server_address = SetUpServer();
556   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
557                         "{\"message\": \"Hello0\"}"};
558
559   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
560   std::streambuf* orig = std::cin.rdbuf();
561   std::istringstream ss(
562       "{\"message\": \"Hello1\"}\n\n{\"message\": \"Hello2\" }\n\n");
563   std::cin.rdbuf(ss.rdbuf());
564
565   FLAGS_json_input = true;
566   FLAGS_batch = true;
567   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
568                                    std::bind(PrintStream, &output_stream,
569                                              std::placeholders::_1)));
570   FLAGS_batch = false;
571
572   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
573   // "Hello2"\n"
574   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
575                                 "message: \"Hello0\"\nmessage: "
576                                 "\"Hello1\"\nmessage: \"Hello2\"\n"));
577   // with json_output
578   output_stream.str(grpc::string());
579   output_stream.clear();
580   ss.clear();
581   ss.seekg(0);
582   std::cin.rdbuf(ss.rdbuf());
583
584   FLAGS_batch = true;
585   FLAGS_json_output = true;
586   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
587                                    std::bind(PrintStream, &output_stream,
588                                              std::placeholders::_1)));
589   FLAGS_json_output = false;
590   FLAGS_batch = false;
591   FLAGS_json_input = false;
592
593   // Expected output:
594   // {
595   //  "message": "Hello0"
596   // }
597   // {
598   //  "message": "Hello1"
599   // }
600   // {
601   //  "message": "Hello2"
602   // }
603   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
604   // "Hello2"\n"
605   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
606                                 "{\n \"message\": \"Hello0\"\n}\n"
607                                 "{\n \"message\": \"Hello1\"\n}\n"
608                                 "{\n \"message\": \"Hello2\"\n}\n"));
609
610   std::cin.rdbuf(orig);
611   ShutdownServer();
612 }
613
614 TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) {
615   // Test input "grpc_cli call Echo"
616   std::stringstream output_stream;
617
618   const grpc::string server_address = SetUpServer();
619   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
620                         "message: 'Hello0'"};
621
622   // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n"
623   std::streambuf* orig = std::cin.rdbuf();
624   std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n");
625   std::cin.rdbuf(ss.rdbuf());
626
627   FLAGS_batch = true;
628   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
629                                    std::bind(PrintStream, &output_stream,
630                                              std::placeholders::_1)));
631   FLAGS_batch = false;
632
633   // Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
634   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
635                                 "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
636
637   // with json_output
638   output_stream.str(grpc::string());
639   output_stream.clear();
640   ss.clear();
641   ss.seekg(0);
642   std::cin.rdbuf(ss.rdbuf());
643
644   FLAGS_batch = true;
645   FLAGS_json_output = true;
646   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
647                                    std::bind(PrintStream, &output_stream,
648                                              std::placeholders::_1)));
649   FLAGS_json_output = false;
650   FLAGS_batch = false;
651
652   // Expected output:
653   // {
654   //  "message": "Hello0"
655   // }
656   // {
657   //  "message": "Hello2"
658   // }
659   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
660   // "Hello2"\n"
661   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
662                                 "{\n \"message\": \"Hello0\"\n}\n"
663                                 "{\n \"message\": \"Hello2\"\n}\n"));
664
665   std::cin.rdbuf(orig);
666   ShutdownServer();
667 }
668
669 TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) {
670   // Test input "grpc_cli call Echo"
671   std::stringstream output_stream;
672
673   const grpc::string server_address = SetUpServer();
674   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
675                         "{ \"message\": \"Hello0\"}"};
676
677   // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n"
678   std::streambuf* orig = std::cin.rdbuf();
679   std::istringstream ss(
680       "{ \"message\": 1 }\n\n { \"message\": \"Hello2\" }\n\n");
681   std::cin.rdbuf(ss.rdbuf());
682
683   FLAGS_batch = true;
684   FLAGS_json_input = true;
685   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
686                                    std::bind(PrintStream, &output_stream,
687                                              std::placeholders::_1)));
688   FLAGS_json_input = false;
689   FLAGS_batch = false;
690
691   // Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
692   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
693                                 "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
694
695   // with json_output
696   output_stream.str(grpc::string());
697   output_stream.clear();
698   ss.clear();
699   ss.seekg(0);
700   std::cin.rdbuf(ss.rdbuf());
701
702   FLAGS_batch = true;
703   FLAGS_json_input = true;
704   FLAGS_json_output = true;
705   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
706                                    std::bind(PrintStream, &output_stream,
707                                              std::placeholders::_1)));
708   FLAGS_json_output = false;
709   FLAGS_json_input = false;
710   FLAGS_batch = false;
711
712   // Expected output:
713   // {
714   //  "message": "Hello0"
715   // }
716   // {
717   //  "message": "Hello2"
718   // }
719   // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
720   // "Hello2"\n"
721   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
722                                 "{\n \"message\": \"Hello0\"\n}\n"
723                                 "{\n \"message\": \"Hello2\"\n}\n"));
724
725   std::cin.rdbuf(orig);
726   ShutdownServer();
727 }
728
729 TEST_F(GrpcToolTest, CallCommandRequestStream) {
730   // Test input: grpc_cli call localhost:<port> RequestStream "message:
731   // 'Hello0'"
732   std::stringstream output_stream;
733
734   const grpc::string server_address = SetUpServer();
735   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
736                         "RequestStream", "message: 'Hello0'"};
737
738   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
739   std::streambuf* orig = std::cin.rdbuf();
740   std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
741   std::cin.rdbuf(ss.rdbuf());
742
743   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
744                                    std::bind(PrintStream, &output_stream,
745                                              std::placeholders::_1)));
746
747   // Expected output: "message: \"Hello0Hello1Hello2\""
748   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
749                                 "message: \"Hello0Hello1Hello2\""));
750   std::cin.rdbuf(orig);
751   ShutdownServer();
752 }
753
754 TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) {
755   // Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\":
756   // \"Hello0\"}"
757   std::stringstream output_stream;
758
759   const grpc::string server_address = SetUpServer();
760   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
761                         "RequestStream", "{ \"message\": \"Hello0\" }"};
762
763   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
764   std::streambuf* orig = std::cin.rdbuf();
765   std::istringstream ss(
766       "{ \"message\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
767   std::cin.rdbuf(ss.rdbuf());
768
769   FLAGS_json_input = true;
770   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
771                                    std::bind(PrintStream, &output_stream,
772                                              std::placeholders::_1)));
773   FLAGS_json_input = false;
774
775   // Expected output: "message: \"Hello0Hello1Hello2\""
776   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
777                                 "message: \"Hello0Hello1Hello2\""));
778   std::cin.rdbuf(orig);
779   ShutdownServer();
780 }
781
782 TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) {
783   // Test input: grpc_cli call localhost:<port> RequestStream "message:
784   // 'Hello0'"
785   std::stringstream output_stream;
786
787   const grpc::string server_address = SetUpServer();
788   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
789                         "RequestStream", "message: 'Hello0'"};
790
791   // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"
792   std::streambuf* orig = std::cin.rdbuf();
793   std::istringstream ss("bad_field: 'Hello1'\n\n message: 'Hello2'\n\n");
794   std::cin.rdbuf(ss.rdbuf());
795
796   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
797                                    std::bind(PrintStream, &output_stream,
798                                              std::placeholders::_1)));
799
800   // Expected output: "message: \"Hello0Hello2\""
801   EXPECT_TRUE(nullptr !=
802               strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\""));
803   std::cin.rdbuf(orig);
804   ShutdownServer();
805 }
806
807 TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) {
808   // Test input: grpc_cli call localhost:<port> RequestStream "message:
809   // 'Hello0'"
810   std::stringstream output_stream;
811
812   const grpc::string server_address = SetUpServer();
813   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
814                         "RequestStream", "{ \"message\": \"Hello0\" }"};
815
816   // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"
817   std::streambuf* orig = std::cin.rdbuf();
818   std::istringstream ss(
819       "{ \"bad_field\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
820   std::cin.rdbuf(ss.rdbuf());
821
822   FLAGS_json_input = true;
823   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
824                                    std::bind(PrintStream, &output_stream,
825                                              std::placeholders::_1)));
826   FLAGS_json_input = false;
827
828   // Expected output: "message: \"Hello0Hello2\""
829   EXPECT_TRUE(nullptr !=
830               strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\""));
831   std::cin.rdbuf(orig);
832   ShutdownServer();
833 }
834
835 TEST_F(GrpcToolTest, CallCommandResponseStream) {
836   // Test input: grpc_cli call localhost:<port> ResponseStream "message:
837   // 'Hello'"
838   std::stringstream output_stream;
839
840   const grpc::string server_address = SetUpServer();
841   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
842                         "ResponseStream", "message: 'Hello'"};
843
844   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
845                                    std::bind(PrintStream, &output_stream,
846                                              std::placeholders::_1)));
847
848   // Expected output: "message: \"Hello{n}\""
849   for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
850     grpc::string expected_response_text =
851         "message: \"Hello" + grpc::to_string(i) + "\"\n";
852     EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
853                                   expected_response_text.c_str()));
854   }
855
856   // with json_output
857   output_stream.str(grpc::string());
858   output_stream.clear();
859
860   FLAGS_json_output = true;
861   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
862                                    std::bind(PrintStream, &output_stream,
863                                              std::placeholders::_1)));
864   FLAGS_json_output = false;
865
866   // Expected output: "{\n \"message\": \"Hello{n}\"\n}\n"
867   for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
868     grpc::string expected_response_text =
869         "{\n \"message\": \"Hello" + grpc::to_string(i) + "\"\n}\n";
870     EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
871                                   expected_response_text.c_str()));
872   }
873
874   ShutdownServer();
875 }
876
877 TEST_F(GrpcToolTest, CallCommandBidiStream) {
878   // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'"
879   std::stringstream output_stream;
880
881   const grpc::string server_address = SetUpServer();
882   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
883                         "BidiStream", "message: 'Hello0'"};
884
885   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
886   std::streambuf* orig = std::cin.rdbuf();
887   std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
888   std::cin.rdbuf(ss.rdbuf());
889
890   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
891                                    std::bind(PrintStream, &output_stream,
892                                              std::placeholders::_1)));
893
894   // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage:
895   // \"Hello2\"\n\n"
896   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
897                                 "message: \"Hello0\"\nmessage: "
898                                 "\"Hello1\"\nmessage: \"Hello2\"\n"));
899   std::cin.rdbuf(orig);
900   ShutdownServer();
901 }
902
903 TEST_F(GrpcToolTest, CallCommandBidiStreamWithBadRequest) {
904   // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'"
905   std::stringstream output_stream;
906
907   const grpc::string server_address = SetUpServer();
908   const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
909                         "BidiStream", "message: 'Hello0'"};
910
911   // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
912   std::streambuf* orig = std::cin.rdbuf();
913   std::istringstream ss("message: 1.0\n\n message: 'Hello2'\n\n");
914   std::cin.rdbuf(ss.rdbuf());
915
916   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
917                                    std::bind(PrintStream, &output_stream,
918                                              std::placeholders::_1)));
919
920   // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage:
921   // \"Hello2\"\n\n"
922   EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
923                                 "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
924   std::cin.rdbuf(orig);
925
926   ShutdownServer();
927 }
928
929 TEST_F(GrpcToolTest, ParseCommand) {
930   // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
931   // ECHO_RESPONSE_MESSAGE"
932   std::stringstream output_stream;
933   std::stringstream binary_output_stream;
934
935   const grpc::string server_address = SetUpServer();
936   const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
937                         "grpc.testing.EchoResponse",
938                         ECHO_RESPONSE_MESSAGE_TEXT_FORMAT};
939
940   FLAGS_binary_input = false;
941   FLAGS_binary_output = false;
942   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
943                                    std::bind(PrintStream, &output_stream,
944                                              std::placeholders::_1)));
945   // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
946   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
947                           ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
948
949   // with json_output
950   output_stream.str(grpc::string());
951   output_stream.clear();
952
953   FLAGS_json_output = true;
954   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
955                                    std::bind(PrintStream, &output_stream,
956                                              std::placeholders::_1)));
957   FLAGS_json_output = false;
958
959   // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
960   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
961                           ECHO_RESPONSE_MESSAGE_JSON_FORMAT));
962
963   // Parse text message to binary message and then parse it back to text message
964   output_stream.str(grpc::string());
965   output_stream.clear();
966   FLAGS_binary_output = true;
967   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
968                                    std::bind(PrintStream, &output_stream,
969                                              std::placeholders::_1)));
970   grpc::string binary_data = output_stream.str();
971   output_stream.str(grpc::string());
972   output_stream.clear();
973   argv[4] = binary_data.c_str();
974   FLAGS_binary_input = true;
975   FLAGS_binary_output = false;
976   EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(),
977                                    std::bind(PrintStream, &output_stream,
978                                              std::placeholders::_1)));
979
980   // Expected output: ECHO_RESPONSE_MESSAGE
981   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
982                           ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
983
984   FLAGS_binary_input = false;
985   FLAGS_binary_output = false;
986   ShutdownServer();
987 }
988
989 TEST_F(GrpcToolTest, ParseCommandJsonFormat) {
990   // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
991   // ECHO_RESPONSE_MESSAGE_JSON_FORMAT"
992   std::stringstream output_stream;
993   std::stringstream binary_output_stream;
994
995   const grpc::string server_address = SetUpServer();
996   const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
997                         "grpc.testing.EchoResponse",
998                         ECHO_RESPONSE_MESSAGE_JSON_FORMAT};
999
1000   FLAGS_json_input = true;
1001   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1002                                    std::bind(PrintStream, &output_stream,
1003                                              std::placeholders::_1)));
1004
1005   // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
1006   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1007                           ECHO_RESPONSE_MESSAGE_TEXT_FORMAT));
1008
1009   // with json_output
1010   output_stream.str(grpc::string());
1011   output_stream.clear();
1012
1013   FLAGS_json_output = true;
1014   EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1015                                    std::bind(PrintStream, &output_stream,
1016                                              std::placeholders::_1)));
1017   FLAGS_json_output = false;
1018   FLAGS_json_input = false;
1019
1020   // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
1021   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1022                           ECHO_RESPONSE_MESSAGE_JSON_FORMAT));
1023
1024   ShutdownServer();
1025 }
1026
1027 TEST_F(GrpcToolTest, TooFewArguments) {
1028   // Test input "grpc_cli call Echo"
1029   std::stringstream output_stream;
1030   const char* argv[] = {"grpc_cli", "call", "Echo"};
1031
1032   // Exit with 1
1033   EXPECT_EXIT(
1034       GrpcToolMainLib(
1035           ArraySize(argv), argv, TestCliCredentials(),
1036           std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1037       ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
1038   // No output
1039   EXPECT_TRUE(0 == output_stream.tellp());
1040 }
1041
1042 TEST_F(GrpcToolTest, TooManyArguments) {
1043   // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'"
1044   std::stringstream output_stream;
1045   const char* argv[] = {"grpc_cli", "call", "localhost:10000",
1046                         "Echo",     "Echo", "message: 'Hello'"};
1047
1048   // Exit with 1
1049   EXPECT_EXIT(
1050       GrpcToolMainLib(
1051           ArraySize(argv), argv, TestCliCredentials(),
1052           std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1053       ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
1054   // No output
1055   EXPECT_TRUE(0 == output_stream.tellp());
1056 }
1057
1058 TEST_F(GrpcToolTest, CallCommandWithMetadata) {
1059   // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'"
1060   const grpc::string server_address = SetUpServer();
1061   const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
1062                         "message: 'Hello'"};
1063
1064   {
1065     std::stringstream output_stream;
1066     FLAGS_metadata = "key0:val0:key1:valq:key2:val2";
1067     EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1068                                      TestCliCredentials(),
1069                                      std::bind(PrintStream, &output_stream,
1070                                                std::placeholders::_1)));
1071     // Expected output: "message: \"Hello\""
1072     EXPECT_TRUE(nullptr !=
1073                 strstr(output_stream.str().c_str(), "message: \"Hello\""));
1074   }
1075
1076   {
1077     std::stringstream output_stream;
1078     FLAGS_metadata = "key:val\\:val";
1079     EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1080                                      TestCliCredentials(),
1081                                      std::bind(PrintStream, &output_stream,
1082                                                std::placeholders::_1)));
1083     // Expected output: "message: \"Hello\""
1084     EXPECT_TRUE(nullptr !=
1085                 strstr(output_stream.str().c_str(), "message: \"Hello\""));
1086   }
1087
1088   {
1089     std::stringstream output_stream;
1090     FLAGS_metadata = "key:val\\\\val";
1091     EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1092                                      TestCliCredentials(),
1093                                      std::bind(PrintStream, &output_stream,
1094                                                std::placeholders::_1)));
1095     // Expected output: "message: \"Hello\""
1096     EXPECT_TRUE(nullptr !=
1097                 strstr(output_stream.str().c_str(), "message: \"Hello\""));
1098   }
1099
1100   FLAGS_metadata = "";
1101   ShutdownServer();
1102 }
1103
1104 TEST_F(GrpcToolTest, CallCommandWithBadMetadata) {
1105   // Test input "grpc_cli call localhost:10000 Echo "message: 'Hello'"
1106   const char* argv[] = {"grpc_cli", "call", "localhost:10000", "Echo",
1107                         "message: 'Hello'"};
1108   FLAGS_protofiles = "src/proto/grpc/testing/echo.proto";
1109   char* test_srcdir = gpr_getenv("TEST_SRCDIR");
1110   if (test_srcdir != nullptr) {
1111     FLAGS_proto_path = test_srcdir + std::string("/com_github_grpc_grpc");
1112   }
1113
1114   {
1115     std::stringstream output_stream;
1116     FLAGS_metadata = "key0:val0:key1";
1117     // Exit with 1
1118     EXPECT_EXIT(
1119         GrpcToolMainLib(
1120             ArraySize(argv), argv, TestCliCredentials(),
1121             std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1122         ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*");
1123   }
1124
1125   {
1126     std::stringstream output_stream;
1127     FLAGS_metadata = "key:val\\val";
1128     // Exit with 1
1129     EXPECT_EXIT(
1130         GrpcToolMainLib(
1131             ArraySize(argv), argv, TestCliCredentials(),
1132             std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1133         ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*");
1134   }
1135
1136   FLAGS_metadata = "";
1137   FLAGS_protofiles = "";
1138
1139   gpr_free(test_srcdir);
1140 }
1141
1142 TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) {
1143   const grpc::string server_address = SetUpServer(true);
1144
1145   // Test input "grpc_cli ls localhost:<port> --channel_creds_type=ssl
1146   // --ssl_target=z.test.google.fr"
1147   std::stringstream output_stream;
1148   const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
1149   FLAGS_l = false;
1150   FLAGS_channel_creds_type = "ssl";
1151   FLAGS_ssl_target = "z.test.google.fr";
1152   EXPECT_TRUE(
1153       0 == GrpcToolMainLib(
1154                ArraySize(argv), argv, TestCliCredentials(true),
1155                std::bind(PrintStream, &output_stream, std::placeholders::_1)));
1156   EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1157                           "grpc.testing.EchoTestService\n"
1158                           "grpc.reflection.v1alpha.ServerReflection\n"));
1159
1160   FLAGS_channel_creds_type = "";
1161   FLAGS_ssl_target = "";
1162   ShutdownServer();
1163 }
1164
1165 }  // namespace testing
1166 }  // namespace grpc
1167
1168 int main(int argc, char** argv) {
1169   grpc::testing::TestEnvironment env(argc, argv);
1170   ::testing::InitGoogleTest(&argc, argv);
1171   ::testing::FLAGS_gtest_death_test_style = "threadsafe";
1172   return RUN_ALL_TESTS();
1173 }