grpc_tool_test.cc
Go to the documentation of this file.
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 
20 
21 #include <chrono>
22 #include <sstream>
23 
24 #include <gtest/gtest.h>
25 
26 #include "absl/flags/declare.h"
27 #include "absl/flags/flag.h"
28 
29 #include <grpc/grpc.h>
30 #include <grpc/support/alloc.h>
31 #include <grpcpp/channel.h>
32 #include <grpcpp/client_context.h>
33 #include <grpcpp/create_channel.h>
35 #include <grpcpp/server.h>
36 #include <grpcpp/server_builder.h>
37 #include <grpcpp/server_context.h>
38 
39 #include "src/core/lib/gpr/env.h"
41 #include "src/proto/grpc/testing/echo.grpc.pb.h"
42 #include "src/proto/grpc/testing/echo.pb.h"
43 #include "test/core/util/port.h"
48 
49 #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem"
50 #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem"
51 #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key"
52 
53 using grpc::testing::EchoRequest;
54 using grpc::testing::EchoResponse;
55 
56 #define USAGE_REGEX "( grpc_cli .+\n){2,10}"
57 
58 #define ECHO_TEST_SERVICE_SUMMARY \
59  "Echo\n" \
60  "Echo1\n" \
61  "Echo2\n" \
62  "CheckDeadlineUpperBound\n" \
63  "CheckDeadlineSet\n" \
64  "CheckClientInitialMetadata\n" \
65  "RequestStream\n" \
66  "ResponseStream\n" \
67  "BidiStream\n" \
68  "Unimplemented\n" \
69  "UnimplementedBidi\n"
70 
71 #define ECHO_TEST_SERVICE_DESCRIPTION \
72  "filename: src/proto/grpc/testing/echo.proto\n" \
73  "package: grpc.testing;\n" \
74  "service EchoTestService {\n" \
75  " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
76  "{}\n" \
77  " rpc Echo1(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
78  "{}\n" \
79  " rpc Echo2(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
80  "{}\n" \
81  " rpc CheckDeadlineUpperBound(grpc.testing.SimpleRequest) returns " \
82  "(grpc.testing.StringValue) {}\n" \
83  " rpc CheckDeadlineSet(grpc.testing.SimpleRequest) returns " \
84  "(grpc.testing.StringValue) {}\n" \
85  " rpc CheckClientInitialMetadata(grpc.testing.SimpleRequest) returns " \
86  "(grpc.testing.SimpleResponse) {}\n" \
87  " rpc RequestStream(stream grpc.testing.EchoRequest) returns " \
88  "(grpc.testing.EchoResponse) {}\n" \
89  " rpc ResponseStream(grpc.testing.EchoRequest) returns (stream " \
90  "grpc.testing.EchoResponse) {}\n" \
91  " rpc BidiStream(stream grpc.testing.EchoRequest) returns (stream " \
92  "grpc.testing.EchoResponse) {}\n" \
93  " rpc Unimplemented(grpc.testing.EchoRequest) returns " \
94  "(grpc.testing.EchoResponse) {}\n" \
95  " rpc UnimplementedBidi(stream grpc.testing.EchoRequest) returns (stream " \
96  "grpc.testing.EchoResponse) {}\n" \
97  "}\n" \
98  "\n"
99 
100 #define ECHO_METHOD_DESCRIPTION \
101  " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \
102  "{}\n"
103 
104 #define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \
105  "message: \"echo\"\n" \
106  "param {\n" \
107  " host: \"localhost\"\n" \
108  " peer: \"peer\"\n" \
109  "}\n\n"
110 
111 #define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \
112  "{\n" \
113  " \"message\": \"echo\",\n" \
114  " \"param\": {\n" \
115  " \"host\": \"localhost\",\n" \
116  " \"peer\": \"peer\"\n" \
117  " }\n" \
118  "}\n\n"
119 
120 ABSL_DECLARE_FLAG(std::string, channel_creds_type);
121 ABSL_DECLARE_FLAG(std::string, ssl_target);
122 ABSL_DECLARE_FLAG(bool, binary_input);
123 ABSL_DECLARE_FLAG(bool, binary_output);
124 ABSL_DECLARE_FLAG(bool, json_input);
125 ABSL_DECLARE_FLAG(bool, json_output);
126 ABSL_DECLARE_FLAG(bool, l);
127 ABSL_DECLARE_FLAG(bool, batch);
129 ABSL_DECLARE_FLAG(std::string, protofiles);
130 ABSL_DECLARE_FLAG(std::string, proto_path);
131 ABSL_DECLARE_FLAG(std::string, default_service_config);
132 ABSL_DECLARE_FLAG(double, timeout);
133 
134 namespace grpc {
135 namespace testing {
136 namespace {
137 
139 
140 class TestCliCredentials final : public grpc::testing::CliCredentials {
141  public:
142  explicit TestCliCredentials(bool secure = false) : secure_(secure) {}
143  std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials()
144  const override {
145  if (!secure_) {
147  }
148  grpc_slice ca_slice;
149  GPR_ASSERT(GRPC_LOG_IF_ERROR("load_file",
150  grpc_load_file(CA_CERT_PATH, 1, &ca_slice)));
151  const char* test_root_cert =
152  reinterpret_cast<const char*> GRPC_SLICE_START_PTR(ca_slice);
153  SslCredentialsOptions ssl_opts = {test_root_cert, "", ""};
154  std::shared_ptr<grpc::ChannelCredentials> credential_ptr =
156  grpc_slice_unref(ca_slice);
157  return credential_ptr;
158  }
159  std::string GetCredentialUsage() const override { return ""; }
160 
161  private:
162  const bool secure_;
163 };
164 
165 bool PrintStream(std::stringstream* ss, const std::string& output) {
166  (*ss) << output;
167  return true;
168 }
169 
170 template <typename T>
171 size_t ArraySize(T& a) {
172  return ((sizeof(a) / sizeof(*(a))) /
173  static_cast<size_t>(!(sizeof(a) % sizeof(*(a)))));
174 }
175 
176 class TestServiceImpl : public grpc::testing::EchoTestService::Service {
177  public:
178  Status Echo(ServerContext* context, const EchoRequest* request,
179  EchoResponse* response) override {
180  if (!context->client_metadata().empty()) {
181  for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
182  iter = context->client_metadata().begin();
183  iter != context->client_metadata().end(); ++iter) {
184  context->AddInitialMetadata(ToString(iter->first),
185  ToString(iter->second));
186  }
187  }
188  context->AddTrailingMetadata("trailing_key", "trailing_value");
189  response->set_message(request->message());
190  return Status::OK;
191  }
192 
193  Status CheckDeadlineSet(ServerContext* context,
194  const SimpleRequest* /*request*/,
195  StringValue* response) override {
196  response->set_message(context->deadline() !=
198  ? "true"
199  : "false");
200  return Status::OK;
201  }
202 
203  // Check if deadline - current time <= timeout
204  // If deadline set, timeout + current time should be an upper bound for it
205  Status CheckDeadlineUpperBound(ServerContext* context,
206  const SimpleRequest* /*request*/,
207  StringValue* response) override {
208  auto seconds = std::chrono::duration_cast<std::chrono::seconds>(
210 
211  // Returning string instead of bool to avoid using embedded messages in
212  // proto3
213  response->set_message(
214  seconds.count() <= absl::GetFlag(FLAGS_timeout) ? "true" : "false");
215  return Status::OK;
216  }
217 
218  Status RequestStream(ServerContext* context,
219  ServerReader<EchoRequest>* reader,
220  EchoResponse* response) override {
221  EchoRequest request;
222  response->set_message("");
223  if (!context->client_metadata().empty()) {
224  for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
225  iter = context->client_metadata().begin();
226  iter != context->client_metadata().end(); ++iter) {
227  context->AddInitialMetadata(ToString(iter->first),
228  ToString(iter->second));
229  }
230  }
231  context->AddTrailingMetadata("trailing_key", "trailing_value");
232  while (reader->Read(&request)) {
233  response->mutable_message()->append(request.message());
234  }
235 
236  return Status::OK;
237  }
238 
239  Status ResponseStream(ServerContext* context, const EchoRequest* request,
240  ServerWriter<EchoResponse>* writer) override {
241  if (!context->client_metadata().empty()) {
242  for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
243  iter = context->client_metadata().begin();
244  iter != context->client_metadata().end(); ++iter) {
245  context->AddInitialMetadata(ToString(iter->first),
246  ToString(iter->second));
247  }
248  }
249  context->AddTrailingMetadata("trailing_key", "trailing_value");
250 
251  EchoResponse response;
252  for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
253  response.set_message(request->message() + std::to_string(i));
254  writer->Write(response);
255  }
256 
257  return Status::OK;
258  }
259 
261  ServerContext* context,
262  ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
263  EchoRequest request;
264  EchoResponse response;
265  if (!context->client_metadata().empty()) {
266  for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator
267  iter = context->client_metadata().begin();
268  iter != context->client_metadata().end(); ++iter) {
269  context->AddInitialMetadata(ToString(iter->first),
270  ToString(iter->second));
271  }
272  }
273  context->AddTrailingMetadata("trailing_key", "trailing_value");
274 
275  while (stream->Read(&request)) {
276  response.set_message(request.message());
277  stream->Write(response);
278  }
279 
280  return Status::OK;
281  }
282 };
283 
284 } // namespace
285 
287  protected:
289 
290  // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die()
291  // uses atexit() to free chosen ports, and it will spawn a new thread in
292  // resolve_address_posix.c:192 at exit time.
293  std::string SetUpServer(bool secure = false) {
294  std::ostringstream server_address;
296  server_address << "localhost:" << port;
297  // Setup server
299  std::shared_ptr<grpc::ServerCredentials> creds;
300  grpc_slice cert_slice, key_slice;
302  "load_file", grpc_load_file(SERVER_CERT_PATH, 1, &cert_slice)));
304  "load_file", grpc_load_file(SERVER_KEY_PATH, 1, &key_slice)));
305  const char* server_cert =
306  reinterpret_cast<const char*> GRPC_SLICE_START_PTR(cert_slice);
307  const char* server_key =
308  reinterpret_cast<const char*> GRPC_SLICE_START_PTR(key_slice);
310  server_cert};
311  if (secure) {
313  ssl_opts.pem_root_certs = "";
314  ssl_opts.pem_key_cert_pairs.push_back(pkcp);
315  creds = SslServerCredentials(ssl_opts);
316  } else {
317  creds = InsecureServerCredentials();
318  }
319  builder.AddListeningPort(server_address.str(), creds);
320  builder.RegisterService(&service_);
321  server_ = builder.BuildAndStart();
322  grpc_slice_unref(cert_slice);
323  grpc_slice_unref(key_slice);
324  return server_address.str();
325  }
326 
327  void ShutdownServer() { server_->Shutdown(); }
328 
329  std::unique_ptr<Server> server_;
332 };
333 
334 TEST_F(GrpcToolTest, NoCommand) {
335  // Test input "grpc_cli"
336  std::stringstream output_stream;
337  const char* argv[] = {"grpc_cli"};
338  // Exit with 1, print usage instruction in stderr
339  EXPECT_EXIT(
341  ArraySize(argv), argv, TestCliCredentials(),
342  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
343  ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX);
344  // No output
345  EXPECT_TRUE(0 == output_stream.tellp());
346 }
347 
348 TEST_F(GrpcToolTest, InvalidCommand) {
349  // Test input "grpc_cli"
350  std::stringstream output_stream;
351  const char* argv[] = {"grpc_cli", "abc"};
352  // Exit with 1, print usage instruction in stderr
353  EXPECT_EXIT(
355  ArraySize(argv), argv, TestCliCredentials(),
356  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
357  ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX);
358  // No output
359  EXPECT_TRUE(0 == output_stream.tellp());
360 }
361 
362 TEST_F(GrpcToolTest, HelpCommand) {
363  // Test input "grpc_cli help"
364  std::stringstream output_stream;
365  const char* argv[] = {"grpc_cli", "help"};
366  // Exit with 1, print usage instruction in stderr
367  EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
368  std::bind(PrintStream, &output_stream,
369  std::placeholders::_1)),
370  ::testing::ExitedWithCode(1), USAGE_REGEX);
371  // No output
372  EXPECT_TRUE(0 == output_stream.tellp());
373 }
374 
375 TEST_F(GrpcToolTest, ListCommand) {
376  // Test input "grpc_cli list localhost:<port>"
377  std::stringstream output_stream;
378 
379  const std::string server_address = SetUpServer();
380  const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
381 
382  absl::SetFlag(&FLAGS_l, false);
383  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
384  std::bind(PrintStream, &output_stream,
385  std::placeholders::_1)));
386  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
387  "grpc.testing.EchoTestService\n"
388  "grpc.reflection.v1alpha.ServerReflection\n"));
389 
390  ShutdownServer();
391 }
392 
393 TEST_F(GrpcToolTest, ListOneService) {
394  // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService"
395  std::stringstream output_stream;
396 
397  const std::string server_address = SetUpServer();
398  const char* argv[] = {"grpc_cli", "ls", server_address.c_str(),
399  "grpc.testing.EchoTestService"};
400  // without -l flag
401  absl::SetFlag(&FLAGS_l, false);
402  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
403  std::bind(PrintStream, &output_stream,
404  std::placeholders::_1)));
405  // Expected output: ECHO_TEST_SERVICE_SUMMARY
406  EXPECT_TRUE(0 ==
407  strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY));
408 
409  // with -l flag
410  output_stream.str(std::string());
411  output_stream.clear();
412  absl::SetFlag(&FLAGS_l, true);
413  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
414  std::bind(PrintStream, &output_stream,
415  std::placeholders::_1)));
416  // Expected output: ECHO_TEST_SERVICE_DESCRIPTION
417  EXPECT_TRUE(
418  0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION));
419 
420  ShutdownServer();
421 }
422 
423 TEST_F(GrpcToolTest, TypeCommand) {
424  // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest"
425  std::stringstream output_stream;
426 
427  const std::string server_address = SetUpServer();
428  const char* argv[] = {"grpc_cli", "type", server_address.c_str(),
429  "grpc.testing.EchoRequest"};
430 
431  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
432  std::bind(PrintStream, &output_stream,
433  std::placeholders::_1)));
435  grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(
436  "grpc.testing.EchoRequest");
437  // Expected output: the DebugString of grpc.testing.EchoRequest
438  EXPECT_TRUE(0 ==
439  strcmp(output_stream.str().c_str(), desc->DebugString().c_str()));
440 
441  ShutdownServer();
442 }
443 
444 TEST_F(GrpcToolTest, ListOneMethod) {
445  // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService"
446  std::stringstream output_stream;
447 
448  const std::string server_address = SetUpServer();
449  const char* argv[] = {"grpc_cli", "ls", server_address.c_str(),
450  "grpc.testing.EchoTestService.Echo"};
451  // without -l flag
452  absl::SetFlag(&FLAGS_l, false);
453  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
454  std::bind(PrintStream, &output_stream,
455  std::placeholders::_1)));
456  // Expected output: "Echo"
457  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n"));
458 
459  // with -l flag
460  output_stream.str(std::string());
461  output_stream.clear();
462  absl::SetFlag(&FLAGS_l, true);
463  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
464  std::bind(PrintStream, &output_stream,
465  std::placeholders::_1)));
466  // Expected output: ECHO_METHOD_DESCRIPTION
467  EXPECT_TRUE(0 ==
468  strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION));
469 
470  ShutdownServer();
471 }
472 
473 TEST_F(GrpcToolTest, TypeNotFound) {
474  // Test input "grpc_cli type localhost:<port> grpc.testing.PhonyRequest"
475  std::stringstream output_stream;
476 
477  const std::string server_address = SetUpServer();
478  const char* argv[] = {"grpc_cli", "type", server_address.c_str(),
479  "grpc.testing.PhonyRequest"};
480 
481  EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
482  std::bind(PrintStream, &output_stream,
483  std::placeholders::_1)));
484  ShutdownServer();
485 }
486 
487 TEST_F(GrpcToolTest, CallCommand) {
488  // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'"
489  std::stringstream output_stream;
490 
491  const std::string server_address = SetUpServer();
492  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
493  "message: 'Hello'"};
494 
495  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
496  std::bind(PrintStream, &output_stream,
497  std::placeholders::_1)));
498  // Expected output: "message: \"Hello\""
499  EXPECT_TRUE(nullptr !=
500  strstr(output_stream.str().c_str(), "message: \"Hello\""));
501 
502  // with json_output
503  output_stream.str(std::string());
504  output_stream.clear();
505 
506  // TODO(Capstan): Consider using absl::FlagSaver
507  absl::SetFlag(&FLAGS_json_output, true);
508  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
509  std::bind(PrintStream, &output_stream,
510  std::placeholders::_1)));
511  absl::SetFlag(&FLAGS_json_output, false);
512 
513  // Expected output:
514  // {
515  // "message": "Hello"
516  // }
517  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
518  "{\n \"message\": \"Hello\"\n}"));
519 
520  ShutdownServer();
521 }
522 
523 TEST_F(GrpcToolTest, CallCommandJsonInput) {
524  // Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}"
525  std::stringstream output_stream;
526 
527  const std::string server_address = SetUpServer();
528  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
529  "{ \"message\": \"Hello\"}"};
530 
531  absl::SetFlag(&FLAGS_json_input, true);
532  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
533  std::bind(PrintStream, &output_stream,
534  std::placeholders::_1)));
535  // Expected output: "message: \"Hello\""
536  EXPECT_TRUE(nullptr !=
537  strstr(output_stream.str().c_str(), "message: \"Hello\""));
538 
539  // with json_output
540  output_stream.str(std::string());
541  output_stream.clear();
542 
543  absl::SetFlag(&FLAGS_json_output, true);
544  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
545  std::bind(PrintStream, &output_stream,
546  std::placeholders::_1)));
547  absl::SetFlag(&FLAGS_json_output, false);
548  absl::SetFlag(&FLAGS_json_input, false);
549 
550  // Expected output:
551  // {
552  // "message": "Hello"
553  // }
554  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
555  "{\n \"message\": \"Hello\"\n}"));
556 
557  ShutdownServer();
558 }
559 
560 TEST_F(GrpcToolTest, CallCommandBatch) {
561  // Test input "grpc_cli call Echo"
562  std::stringstream output_stream;
563 
564  const std::string server_address = SetUpServer();
565  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
566  "message: 'Hello0'"};
567 
568  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
569  std::streambuf* orig = std::cin.rdbuf();
570  std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
571  std::cin.rdbuf(ss.rdbuf());
572 
573  absl::SetFlag(&FLAGS_batch, true);
574  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
575  std::bind(PrintStream, &output_stream,
576  std::placeholders::_1)));
577  absl::SetFlag(&FLAGS_batch, false);
578 
579  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
580  // "Hello2"\n"
581  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
582  "message: \"Hello0\"\nmessage: "
583  "\"Hello1\"\nmessage: \"Hello2\"\n"));
584  // with json_output
585  output_stream.str(std::string());
586  output_stream.clear();
587  ss.clear();
588  ss.seekg(0);
589  std::cin.rdbuf(ss.rdbuf());
590 
591  absl::SetFlag(&FLAGS_batch, true);
592  absl::SetFlag(&FLAGS_json_output, true);
593  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
594  std::bind(PrintStream, &output_stream,
595  std::placeholders::_1)));
596  absl::SetFlag(&FLAGS_json_output, false);
597  absl::SetFlag(&FLAGS_batch, false);
598 
599  // Expected output:
600  // {
601  // "message": "Hello0"
602  // }
603  // {
604  // "message": "Hello1"
605  // }
606  // {
607  // "message": "Hello2"
608  // }
609  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
610  // "Hello2"\n"
611  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
612  "{\n \"message\": \"Hello0\"\n}\n"
613  "{\n \"message\": \"Hello1\"\n}\n"
614  "{\n \"message\": \"Hello2\"\n}\n"));
615 
616  std::cin.rdbuf(orig);
617  ShutdownServer();
618 }
619 
620 TEST_F(GrpcToolTest, CallCommandBatchJsonInput) {
621  // Test input "grpc_cli call Echo"
622  std::stringstream output_stream;
623 
624  const std::string server_address = SetUpServer();
625  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
626  "{\"message\": \"Hello0\"}"};
627 
628  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
629  std::streambuf* orig = std::cin.rdbuf();
630  std::istringstream ss(
631  "{\"message\": \"Hello1\"}\n\n{\"message\": \"Hello2\" }\n\n");
632  std::cin.rdbuf(ss.rdbuf());
633 
634  absl::SetFlag(&FLAGS_json_input, true);
635  absl::SetFlag(&FLAGS_batch, true);
636  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
637  std::bind(PrintStream, &output_stream,
638  std::placeholders::_1)));
639  absl::SetFlag(&FLAGS_batch, false);
640 
641  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
642  // "Hello2"\n"
643  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
644  "message: \"Hello0\"\nmessage: "
645  "\"Hello1\"\nmessage: \"Hello2\"\n"));
646  // with json_output
647  output_stream.str(std::string());
648  output_stream.clear();
649  ss.clear();
650  ss.seekg(0);
651  std::cin.rdbuf(ss.rdbuf());
652 
653  absl::SetFlag(&FLAGS_batch, true);
654  absl::SetFlag(&FLAGS_json_output, true);
655  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
656  std::bind(PrintStream, &output_stream,
657  std::placeholders::_1)));
658  absl::SetFlag(&FLAGS_json_output, false);
659  absl::SetFlag(&FLAGS_batch, false);
660  absl::SetFlag(&FLAGS_json_input, false);
661 
662  // Expected output:
663  // {
664  // "message": "Hello0"
665  // }
666  // {
667  // "message": "Hello1"
668  // }
669  // {
670  // "message": "Hello2"
671  // }
672  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
673  // "Hello2"\n"
674  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
675  "{\n \"message\": \"Hello0\"\n}\n"
676  "{\n \"message\": \"Hello1\"\n}\n"
677  "{\n \"message\": \"Hello2\"\n}\n"));
678 
679  std::cin.rdbuf(orig);
680  ShutdownServer();
681 }
682 
683 TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) {
684  // Test input "grpc_cli call Echo"
685  std::stringstream output_stream;
686 
687  const std::string server_address = SetUpServer();
688  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
689  "message: 'Hello0'"};
690 
691  // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n"
692  std::streambuf* orig = std::cin.rdbuf();
693  std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n");
694  std::cin.rdbuf(ss.rdbuf());
695 
696  absl::SetFlag(&FLAGS_batch, true);
697  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
698  std::bind(PrintStream, &output_stream,
699  std::placeholders::_1)));
700  absl::SetFlag(&FLAGS_batch, false);
701 
702  // Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
703  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
704  "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
705 
706  // with json_output
707  output_stream.str(std::string());
708  output_stream.clear();
709  ss.clear();
710  ss.seekg(0);
711  std::cin.rdbuf(ss.rdbuf());
712 
713  absl::SetFlag(&FLAGS_batch, true);
714  absl::SetFlag(&FLAGS_json_output, true);
715  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
716  std::bind(PrintStream, &output_stream,
717  std::placeholders::_1)));
718  absl::SetFlag(&FLAGS_json_output, false);
719  absl::SetFlag(&FLAGS_batch, false);
720 
721  // Expected output:
722  // {
723  // "message": "Hello0"
724  // }
725  // {
726  // "message": "Hello2"
727  // }
728  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
729  // "Hello2"\n"
730  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
731  "{\n \"message\": \"Hello0\"\n}\n"
732  "{\n \"message\": \"Hello2\"\n}\n"));
733 
734  std::cin.rdbuf(orig);
735  ShutdownServer();
736 }
737 
738 TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) {
739  // Test input "grpc_cli call Echo"
740  std::stringstream output_stream;
741 
742  const std::string server_address = SetUpServer();
743  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
744  "{ \"message\": \"Hello0\"}"};
745 
746  // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n"
747  std::streambuf* orig = std::cin.rdbuf();
748  std::istringstream ss(
749  "{ \"message\": 1 }\n\n { \"message\": \"Hello2\" }\n\n");
750  std::cin.rdbuf(ss.rdbuf());
751 
752  absl::SetFlag(&FLAGS_batch, true);
753  absl::SetFlag(&FLAGS_json_input, true);
754  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
755  std::bind(PrintStream, &output_stream,
756  std::placeholders::_1)));
757  absl::SetFlag(&FLAGS_json_input, false);
758  absl::SetFlag(&FLAGS_batch, false);
759 
760  // Expected output: "message: "Hello0"\nmessage: "Hello2"\n"
761  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
762  "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
763 
764  // with json_output
765  output_stream.str(std::string());
766  output_stream.clear();
767  ss.clear();
768  ss.seekg(0);
769  std::cin.rdbuf(ss.rdbuf());
770 
771  absl::SetFlag(&FLAGS_batch, true);
772  absl::SetFlag(&FLAGS_json_input, true);
773  absl::SetFlag(&FLAGS_json_output, true);
774  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
775  std::bind(PrintStream, &output_stream,
776  std::placeholders::_1)));
777  absl::SetFlag(&FLAGS_json_output, false);
778  absl::SetFlag(&FLAGS_json_input, false);
779  absl::SetFlag(&FLAGS_batch, false);
780 
781  // Expected output:
782  // {
783  // "message": "Hello0"
784  // }
785  // {
786  // "message": "Hello2"
787  // }
788  // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage:
789  // "Hello2"\n"
790  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
791  "{\n \"message\": \"Hello0\"\n}\n"
792  "{\n \"message\": \"Hello2\"\n}\n"));
793 
794  std::cin.rdbuf(orig);
795  ShutdownServer();
796 }
797 
798 TEST_F(GrpcToolTest, CallCommandRequestStream) {
799  // Test input: grpc_cli call localhost:<port> RequestStream "message:
800  // 'Hello0'"
801  std::stringstream output_stream;
802 
803  const std::string server_address = SetUpServer();
804  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
805  "RequestStream", "message: 'Hello0'"};
806 
807  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
808  std::streambuf* orig = std::cin.rdbuf();
809  std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
810  std::cin.rdbuf(ss.rdbuf());
811 
812  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
813  std::bind(PrintStream, &output_stream,
814  std::placeholders::_1)));
815 
816  // Expected output: "message: \"Hello0Hello1Hello2\""
817  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
818  "message: \"Hello0Hello1Hello2\""));
819  std::cin.rdbuf(orig);
820  ShutdownServer();
821 }
822 
823 TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) {
824  // Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\":
825  // \"Hello0\"}"
826  std::stringstream output_stream;
827 
828  const std::string server_address = SetUpServer();
829  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
830  "RequestStream", "{ \"message\": \"Hello0\" }"};
831 
832  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
833  std::streambuf* orig = std::cin.rdbuf();
834  std::istringstream ss(
835  "{ \"message\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
836  std::cin.rdbuf(ss.rdbuf());
837 
838  absl::SetFlag(&FLAGS_json_input, true);
839  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
840  std::bind(PrintStream, &output_stream,
841  std::placeholders::_1)));
842  absl::SetFlag(&FLAGS_json_input, false);
843 
844  // Expected output: "message: \"Hello0Hello1Hello2\""
845  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
846  "message: \"Hello0Hello1Hello2\""));
847  std::cin.rdbuf(orig);
848  ShutdownServer();
849 }
850 
851 TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) {
852  // Test input: grpc_cli call localhost:<port> RequestStream "message:
853  // 'Hello0'"
854  std::stringstream output_stream;
855 
856  const std::string server_address = SetUpServer();
857  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
858  "RequestStream", "message: 'Hello0'"};
859 
860  // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"
861  std::streambuf* orig = std::cin.rdbuf();
862  std::istringstream ss("bad_field: 'Hello1'\n\n message: 'Hello2'\n\n");
863  std::cin.rdbuf(ss.rdbuf());
864 
865  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
866  std::bind(PrintStream, &output_stream,
867  std::placeholders::_1)));
868 
869  // Expected output: "message: \"Hello0Hello2\""
870  EXPECT_TRUE(nullptr !=
871  strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\""));
872  std::cin.rdbuf(orig);
873  ShutdownServer();
874 }
875 
876 TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) {
877  // Test input: grpc_cli call localhost:<port> RequestStream "message:
878  // 'Hello0'"
879  std::stringstream output_stream;
880 
881  const std::string server_address = SetUpServer();
882  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
883  "RequestStream", "{ \"message\": \"Hello0\" }"};
884 
885  // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"
886  std::streambuf* orig = std::cin.rdbuf();
887  std::istringstream ss(
888  "{ \"bad_field\": \"Hello1\" }\n\n{ \"message\": \"Hello2\" }\n\n");
889  std::cin.rdbuf(ss.rdbuf());
890 
891  absl::SetFlag(&FLAGS_json_input, true);
892  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
893  std::bind(PrintStream, &output_stream,
894  std::placeholders::_1)));
895  absl::SetFlag(&FLAGS_json_input, false);
896 
897  // Expected output: "message: \"Hello0Hello2\""
898  EXPECT_TRUE(nullptr !=
899  strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\""));
900  std::cin.rdbuf(orig);
901  ShutdownServer();
902 }
903 
904 TEST_F(GrpcToolTest, CallCommandWithTimeoutDeadlineSet) {
905  // Test input "grpc_cli call CheckDeadlineSet --timeout=5000.25"
906  std::stringstream output_stream;
907 
908  const std::string server_address = SetUpServer();
909  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
910  "CheckDeadlineSet"};
911 
912  // Set timeout to 5000.25 seconds
913  absl::SetFlag(&FLAGS_timeout, 5000.25);
914 
915  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
916  std::bind(PrintStream, &output_stream,
917  std::placeholders::_1)));
918 
919  // Expected output: "message: "true"", deadline set
920  EXPECT_TRUE(nullptr !=
921  strstr(output_stream.str().c_str(), "message: \"true\""));
922  ShutdownServer();
923 }
924 
925 TEST_F(GrpcToolTest, CallCommandWithTimeoutDeadlineUpperBound) {
926  // Test input "grpc_cli call CheckDeadlineUpperBound --timeout=900"
927  std::stringstream output_stream;
928 
929  const std::string server_address = SetUpServer();
930  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
931  "CheckDeadlineUpperBound"};
932 
933  // Set timeout to 900 seconds
934  absl::SetFlag(&FLAGS_timeout, 900);
935 
936  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
937  std::bind(PrintStream, &output_stream,
938  std::placeholders::_1)));
939 
940  std::string output = output_stream.str();
941 
942  // Expected output: "message: "true""
943  // deadline not greater than timeout + current time
944  EXPECT_TRUE(nullptr != strstr(output.c_str(), "message: \"true\"")) << output;
945  ShutdownServer();
946 }
947 
948 TEST_F(GrpcToolTest, CallCommandWithNegativeTimeoutValue) {
949  // Test input "grpc_cli call CheckDeadlineSet --timeout=-5"
950  std::stringstream output_stream;
951 
952  const std::string server_address = SetUpServer();
953  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
954  "CheckDeadlineSet"};
955 
956  // Set timeout to -5 (deadline not set)
957  absl::SetFlag(&FLAGS_timeout, -5);
958 
959  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
960  std::bind(PrintStream, &output_stream,
961  std::placeholders::_1)));
962 
963  // Expected output: "message: "false"", deadline not set
964  EXPECT_TRUE(nullptr !=
965  strstr(output_stream.str().c_str(), "message: \"false\""));
966 
967  ShutdownServer();
968 }
969 
970 TEST_F(GrpcToolTest, CallCommandWithDefaultTimeoutValue) {
971  // Test input "grpc_cli call CheckDeadlineSet --timeout=-1"
972  std::stringstream output_stream;
973 
974  const std::string server_address = SetUpServer();
975  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
976  "CheckDeadlineSet"};
977 
978  // Set timeout to -1 (default value, deadline not set)
979  absl::SetFlag(&FLAGS_timeout, -1);
980 
981  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
982  std::bind(PrintStream, &output_stream,
983  std::placeholders::_1)));
984 
985  // Expected output: "message: "false"", deadline not set
986  EXPECT_TRUE(nullptr !=
987  strstr(output_stream.str().c_str(), "message: \"false\""));
988 
989  ShutdownServer();
990 }
991 
992 TEST_F(GrpcToolTest, CallCommandResponseStream) {
993  // Test input: grpc_cli call localhost:<port> ResponseStream "message:
994  // 'Hello'"
995  std::stringstream output_stream;
996 
997  const std::string server_address = SetUpServer();
998  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
999  "ResponseStream", "message: 'Hello'"};
1000 
1001  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1002  std::bind(PrintStream, &output_stream,
1003  std::placeholders::_1)));
1004 
1005  // Expected output: "message: \"Hello{n}\""
1006  for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
1007  std::string expected_response_text =
1008  "message: \"Hello" + std::to_string(i) + "\"\n";
1009  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
1010  expected_response_text.c_str()));
1011  }
1012 
1013  // with json_output
1014  output_stream.str(std::string());
1015  output_stream.clear();
1016 
1017  absl::SetFlag(&FLAGS_json_output, true);
1018  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1019  std::bind(PrintStream, &output_stream,
1020  std::placeholders::_1)));
1021  absl::SetFlag(&FLAGS_json_output, false);
1022 
1023  // Expected output: "{\n \"message\": \"Hello{n}\"\n}\n"
1024  for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) {
1025  std::string expected_response_text =
1026  "{\n \"message\": \"Hello" + std::to_string(i) + "\"\n}\n";
1027  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
1028  expected_response_text.c_str()));
1029  }
1030 
1031  ShutdownServer();
1032 }
1033 
1034 TEST_F(GrpcToolTest, CallCommandBidiStream) {
1035  // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'"
1036  std::stringstream output_stream;
1037 
1038  const std::string server_address = SetUpServer();
1039  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
1040  "BidiStream", "message: 'Hello0'"};
1041 
1042  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
1043  std::streambuf* orig = std::cin.rdbuf();
1044  std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n");
1045  std::cin.rdbuf(ss.rdbuf());
1046 
1047  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1048  std::bind(PrintStream, &output_stream,
1049  std::placeholders::_1)));
1050 
1051  // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage:
1052  // \"Hello2\"\n\n"
1053  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
1054  "message: \"Hello0\"\nmessage: "
1055  "\"Hello1\"\nmessage: \"Hello2\"\n"));
1056  std::cin.rdbuf(orig);
1057  ShutdownServer();
1058 }
1059 
1060 TEST_F(GrpcToolTest, CallCommandBidiStreamWithBadRequest) {
1061  // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'"
1062  std::stringstream output_stream;
1063 
1064  const std::string server_address = SetUpServer();
1065  const char* argv[] = {"grpc_cli", "call", server_address.c_str(),
1066  "BidiStream", "message: 'Hello0'"};
1067 
1068  // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n"
1069  std::streambuf* orig = std::cin.rdbuf();
1070  std::istringstream ss("message: 1.0\n\n message: 'Hello2'\n\n");
1071  std::cin.rdbuf(ss.rdbuf());
1072 
1073  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1074  std::bind(PrintStream, &output_stream,
1075  std::placeholders::_1)));
1076 
1077  // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage:
1078  // \"Hello2\"\n\n"
1079  EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(),
1080  "message: \"Hello0\"\nmessage: \"Hello2\"\n"));
1081  std::cin.rdbuf(orig);
1082 
1083  ShutdownServer();
1084 }
1085 
1086 TEST_F(GrpcToolTest, ParseCommand) {
1087  // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
1088  // ECHO_RESPONSE_MESSAGE"
1089  std::stringstream output_stream;
1090  std::stringstream binary_output_stream;
1091 
1092  const std::string server_address = SetUpServer();
1093  const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
1094  "grpc.testing.EchoResponse",
1096 
1097  absl::SetFlag(&FLAGS_binary_input, false);
1098  absl::SetFlag(&FLAGS_binary_output, false);
1099  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1100  std::bind(PrintStream, &output_stream,
1101  std::placeholders::_1)));
1102  // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
1103  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1105 
1106  // with json_output
1107  output_stream.str(std::string());
1108  output_stream.clear();
1109 
1110  absl::SetFlag(&FLAGS_json_output, true);
1111  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1112  std::bind(PrintStream, &output_stream,
1113  std::placeholders::_1)));
1114  absl::SetFlag(&FLAGS_json_output, false);
1115 
1116  // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
1117  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1119 
1120  // Parse text message to binary message and then parse it back to text message
1121  output_stream.str(std::string());
1122  output_stream.clear();
1123  absl::SetFlag(&FLAGS_binary_output, true);
1124  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1125  std::bind(PrintStream, &output_stream,
1126  std::placeholders::_1)));
1127  std::string binary_data = output_stream.str();
1128  output_stream.str(std::string());
1129  output_stream.clear();
1130  argv[4] = binary_data.c_str();
1131  absl::SetFlag(&FLAGS_binary_input, true);
1132  absl::SetFlag(&FLAGS_binary_output, false);
1133  EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(),
1134  std::bind(PrintStream, &output_stream,
1135  std::placeholders::_1)));
1136 
1137  // Expected output: ECHO_RESPONSE_MESSAGE
1138  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1140 
1141  absl::SetFlag(&FLAGS_binary_input, false);
1142  absl::SetFlag(&FLAGS_binary_output, false);
1143  ShutdownServer();
1144 }
1145 
1146 TEST_F(GrpcToolTest, ParseCommandJsonFormat) {
1147  // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse
1148  // ECHO_RESPONSE_MESSAGE_JSON_FORMAT"
1149  std::stringstream output_stream;
1150  std::stringstream binary_output_stream;
1151 
1152  const std::string server_address = SetUpServer();
1153  const char* argv[] = {"grpc_cli", "parse", server_address.c_str(),
1154  "grpc.testing.EchoResponse",
1156 
1157  absl::SetFlag(&FLAGS_json_input, true);
1158  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1159  std::bind(PrintStream, &output_stream,
1160  std::placeholders::_1)));
1161 
1162  // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
1163  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1165 
1166  // with json_output
1167  output_stream.str(std::string());
1168  output_stream.clear();
1169 
1170  absl::SetFlag(&FLAGS_json_output, true);
1171  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1172  std::bind(PrintStream, &output_stream,
1173  std::placeholders::_1)));
1174  absl::SetFlag(&FLAGS_json_output, false);
1175  absl::SetFlag(&FLAGS_json_input, false);
1176 
1177  // Expected output: ECHO_RESPONSE_MESSAGE_JSON_FORMAT
1178  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1180 
1181  ShutdownServer();
1182 }
1183 
1184 TEST_F(GrpcToolTest, TooFewArguments) {
1185  // Test input "grpc_cli call Echo"
1186  std::stringstream output_stream;
1187  const char* argv[] = {"grpc_cli", "call", "Echo"};
1188 
1189  // Exit with 1
1190  EXPECT_EXIT(
1192  ArraySize(argv), argv, TestCliCredentials(),
1193  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1194  ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
1195  // No output
1196  EXPECT_TRUE(0 == output_stream.tellp());
1197 }
1198 
1199 TEST_F(GrpcToolTest, TooManyArguments) {
1200  // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'"
1201  std::stringstream output_stream;
1202  const char* argv[] = {"grpc_cli", "call", "localhost:10000",
1203  "Echo", "Echo", "message: 'Hello'"};
1204 
1205  // Exit with 1
1206  EXPECT_EXIT(
1208  ArraySize(argv), argv, TestCliCredentials(),
1209  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1210  ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*");
1211  // No output
1212  EXPECT_TRUE(0 == output_stream.tellp());
1213 }
1214 
1215 TEST_F(GrpcToolTest, CallCommandWithMetadata) {
1216  // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'"
1217  const std::string server_address = SetUpServer();
1218  const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo",
1219  "message: 'Hello'"};
1220 
1221  {
1222  std::stringstream output_stream;
1223  absl::SetFlag(&FLAGS_metadata, "key0:val0:key1:valq:key2:val2");
1224  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1225  TestCliCredentials(),
1226  std::bind(PrintStream, &output_stream,
1227  std::placeholders::_1)));
1228  // Expected output: "message: \"Hello\""
1229  EXPECT_TRUE(nullptr !=
1230  strstr(output_stream.str().c_str(), "message: \"Hello\""));
1231  }
1232 
1233  {
1234  std::stringstream output_stream;
1235  absl::SetFlag(&FLAGS_metadata, "key:val\\:val");
1236  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1237  TestCliCredentials(),
1238  std::bind(PrintStream, &output_stream,
1239  std::placeholders::_1)));
1240  // Expected output: "message: \"Hello\""
1241  EXPECT_TRUE(nullptr !=
1242  strstr(output_stream.str().c_str(), "message: \"Hello\""));
1243  }
1244 
1245  {
1246  std::stringstream output_stream;
1247  absl::SetFlag(&FLAGS_metadata, "key:val\\\\val");
1248  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv,
1249  TestCliCredentials(),
1250  std::bind(PrintStream, &output_stream,
1251  std::placeholders::_1)));
1252  // Expected output: "message: \"Hello\""
1253  EXPECT_TRUE(nullptr !=
1254  strstr(output_stream.str().c_str(), "message: \"Hello\""));
1255  }
1256 
1257  absl::SetFlag(&FLAGS_metadata, "");
1258  ShutdownServer();
1259 }
1260 
1261 TEST_F(GrpcToolTest, CallCommandWithBadMetadata) {
1262  // Test input "grpc_cli call localhost:10000 Echo "message: 'Hello'"
1263  const char* argv[] = {"grpc_cli", "call", "localhost:10000",
1264  "grpc.testing.EchoTestService.Echo",
1265  "message: 'Hello'"};
1266  absl::SetFlag(&FLAGS_protofiles, "src/proto/grpc/testing/echo.proto");
1267  char* test_srcdir = gpr_getenv("TEST_SRCDIR");
1268  if (test_srcdir != nullptr) {
1269  absl::SetFlag(&FLAGS_proto_path,
1270  test_srcdir + std::string("/com_github_grpc_grpc"));
1271  }
1272 
1273  {
1274  std::stringstream output_stream;
1275  absl::SetFlag(&FLAGS_metadata, "key0:val0:key1");
1276  // Exit with 1
1277  EXPECT_EXIT(
1279  ArraySize(argv), argv, TestCliCredentials(),
1280  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1281  ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*");
1282  }
1283 
1284  {
1285  std::stringstream output_stream;
1286  absl::SetFlag(&FLAGS_metadata, "key:val\\val");
1287  // Exit with 1
1288  EXPECT_EXIT(
1290  ArraySize(argv), argv, TestCliCredentials(),
1291  std::bind(PrintStream, &output_stream, std::placeholders::_1)),
1292  ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*");
1293  }
1294 
1295  absl::SetFlag(&FLAGS_metadata, "");
1296  absl::SetFlag(&FLAGS_protofiles, "");
1297 
1298  gpr_free(test_srcdir);
1299 }
1300 
1301 TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) {
1302  const std::string server_address = SetUpServer(true);
1303 
1304  // Test input "grpc_cli ls localhost:<port> --channel_creds_type=ssl
1305  // --ssl_target=z.test.google.fr"
1306  std::stringstream output_stream;
1307  const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
1308  absl::SetFlag(&FLAGS_l, false);
1309  absl::SetFlag(&FLAGS_channel_creds_type, "ssl");
1310  absl::SetFlag(&FLAGS_ssl_target, "z.test.google.fr");
1311  EXPECT_TRUE(
1312  0 == GrpcToolMainLib(
1313  ArraySize(argv), argv, TestCliCredentials(true),
1314  std::bind(PrintStream, &output_stream, std::placeholders::_1)));
1315  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1316  "grpc.testing.EchoTestService\n"
1317  "grpc.reflection.v1alpha.ServerReflection\n"));
1318 
1319  absl::SetFlag(&FLAGS_channel_creds_type, "");
1320  absl::SetFlag(&FLAGS_ssl_target, "");
1321  ShutdownServer();
1322 }
1323 
1324 TEST_F(GrpcToolTest, ConfiguringDefaultServiceConfig) {
1325  // Test input "grpc_cli list localhost:<port>
1326  // --default_service_config={\"loadBalancingConfig\":[{\"pick_first\":{}}]}"
1327  std::stringstream output_stream;
1328  const std::string server_address = SetUpServer();
1329  const char* argv[] = {"grpc_cli", "ls", server_address.c_str()};
1330  // Just check that the tool is still operational when --default_service_config
1331  // is configured. This particular service config is in reality redundant with
1332  // the channel's default configuration.
1333  absl::SetFlag(&FLAGS_l, false);
1334  absl::SetFlag(&FLAGS_default_service_config,
1335  "{\"loadBalancingConfig\":[{\"pick_first\":{}}]}");
1336  EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(),
1337  std::bind(PrintStream, &output_stream,
1338  std::placeholders::_1)));
1339  absl::SetFlag(&FLAGS_default_service_config, "");
1340  EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(),
1341  "grpc.testing.EchoTestService\n"
1342  "grpc.reflection.v1alpha.ServerReflection\n"));
1343  ShutdownServer();
1344 }
1345 
1346 } // namespace testing
1347 } // namespace grpc
1348 
1349 int main(int argc, char** argv) {
1350  grpc::testing::TestEnvironment env(&argc, argv);
1351  ::testing::InitGoogleTest(&argc, argv);
1352  GTEST_FLAG_SET(death_test_style, "threadsafe");
1353  return RUN_ALL_TESTS();
1354 }
SERVER_KEY_PATH
#define SERVER_KEY_PATH
Definition: grpc_tool_test.cc:51
grpc_slice_unref
GPRAPI void grpc_slice_unref(grpc_slice s)
Definition: slice_api.cc:32
messages_pb2.SimpleRequest
SimpleRequest
Definition: messages_pb2.py:597
absl::time_internal::cctz::seconds
std::chrono::duration< std::int_fast64_t > seconds
Definition: abseil-cpp/absl/time/internal/cctz/include/cctz/time_zone.h:40
testing
Definition: aws_request_signer_test.cc:25
GTEST_FLAG_SET
#define GTEST_FLAG_SET(name, value)
Definition: googletest/googletest/include/gtest/internal/gtest-port.h:2219
absl::SetFlag
void SetFlag(absl::Flag< T > *flag, const T &v)
Definition: abseil-cpp/absl/flags/flag.h:110
now
static double now(void)
Definition: test/core/fling/client.cc:130
secure_
const bool secure_
Definition: grpc_tool_test.cc:162
port.h
grpc_load_file
grpc_error_handle grpc_load_file(const char *filename, int add_null_terminator, grpc_slice *output)
Definition: load_file.cc:33
generate.env
env
Definition: generate.py:37
grpc::testing::GrpcToolMainLib
int GrpcToolMainLib(int argc, const char **argv, const CliCredentials &cred, const GrpcToolOutputCallback &callback)
Definition: grpc_tool.cc:295
metadata
Definition: cq_verifier.cc:48
grpc::gpr_free
gpr_free(creds_file_name)
load_file.h
grpc::testing::GrpcToolTest
Definition: grpc_tool_test.cc:286
grpc
Definition: grpcpp/alarm.h:33
proto_server_reflection_plugin.h
grpc::SslCredentials
std::shared_ptr< ChannelCredentials > SslCredentials(const SslCredentialsOptions &options)
Builds SSL Credentials given SSL specific options.
Definition: secure_credentials.cc:129
benchmark.request
request
Definition: benchmark.py:77
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
grpc::SslServerCredentialsOptions::pem_key_cert_pairs
std::vector< PemKeyCertPair > pem_key_cert_pairs
Definition: include/grpcpp/security/server_credentials.h:52
env.h
ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
#define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT
Definition: grpc_tool_test.cc:104
GRPC_LOG_IF_ERROR
#define GRPC_LOG_IF_ERROR(what, error)
Definition: error.h:398
grpc::testing::GrpcToolTest::GrpcToolTest
GrpcToolTest()
Definition: grpc_tool_test.cc:288
ECHO_METHOD_DESCRIPTION
#define ECHO_METHOD_DESCRIPTION
Definition: grpc_tool_test.cc:100
grpc::testing::TestServiceImpl
TestMultipleServiceImpl< grpc::testing::EchoTestService::Service > TestServiceImpl
Definition: test_service_impl.h:498
USAGE_REGEX
#define USAGE_REGEX
Definition: grpc_tool_test.cc:56
grpc_tool.h
server_address
std::string server_address("0.0.0.0:10000")
T
#define T(upbtypeconst, upbtype, ctype, default_value)
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
grpc::SslServerCredentialsOptions::pem_root_certs
std::string pem_root_certs
Definition: include/grpcpp/security/server_credentials.h:51
ABSL_DECLARE_FLAG
ABSL_DECLARE_FLAG(std::string, channel_creds_type)
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
grpc::testing::kServerDefaultResponseStreamsToSend
const int kServerDefaultResponseStreamsToSend
Definition: test_service_impl.h:42
gpr_getenv
char * gpr_getenv(const char *name)
GPR_ASSERT
#define GPR_ASSERT(x)
Definition: include/grpc/impl/codegen/log.h:94
grpc::SslCredentialsOptions
Options used to build SslCredentials.
Definition: include/grpcpp/security/credentials.h:156
max
int max
Definition: bloaty/third_party/zlib/examples/enough.c:170
gmock_output_test.output
output
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
grpc::ServerBuilder
A builder class for the creation and startup of grpc::Server instances.
Definition: grpcpp/server_builder.h:86
grpc::testing::CliCredentials
Definition: cli_credentials.h:28
grpc::testing::GrpcToolTest::service_
TestServiceImpl service_
Definition: grpc_tool_test.cc:330
grpc::SslServerCredentials
std::shared_ptr< ServerCredentials > SslServerCredentials(const grpc::SslServerCredentialsOptions &options)
Builds SSL ServerCredentials given SSL specific options.
Definition: secure_server_credentials.cc:114
grpc::testing::GrpcToolTest::plugin_
reflection::ProtoServerReflectionPlugin plugin_
Definition: grpc_tool_test.cc:331
grpc.h
grpc::SslServerCredentialsOptions
Options to create ServerCredentials with SSL.
Definition: include/grpcpp/security/server_credentials.h:38
CA_CERT_PATH
#define CA_CERT_PATH
Definition: grpc_tool_test.cc:49
GRPC_SLICE_START_PTR
#define GRPC_SLICE_START_PTR(slice)
Definition: include/grpc/impl/codegen/slice.h:101
channel.h
grpc_slice
Definition: include/grpc/impl/codegen/slice.h:65
StringValue
Definition: bloaty/third_party/protobuf/src/google/protobuf/wrappers.pb.h:1158
generated_pool
InternalDescriptorPool * generated_pool
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/def.c:582
grpc::Status::OK
static const Status & OK
An OK pre-defined instance.
Definition: include/grpcpp/impl/codegen/status.h:113
absl::GetFlag
ABSL_MUST_USE_RESULT T GetFlag(const absl::Flag< T > &flag)
Definition: abseil-cpp/absl/flags/flag.h:98
batch
grpc_transport_stream_op_batch * batch
Definition: retry_filter.cc:243
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
ECHO_RESPONSE_MESSAGE_JSON_FORMAT
#define ECHO_RESPONSE_MESSAGE_JSON_FORMAT
Definition: grpc_tool_test.cc:111
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
grpc::testing::GrpcToolTest::server_
std::unique_ptr< Server > server_
Definition: grpc_tool_test.cc:329
writer
void writer(void *n)
Definition: libuv/docs/code/locks/main.c:22
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
test_config.h
grpc::reflection::ProtoServerReflectionPlugin
Definition: grpcpp/ext/proto_server_reflection_plugin.h:31
client_context.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
ECHO_TEST_SERVICE_DESCRIPTION
#define ECHO_TEST_SERVICE_DESCRIPTION
Definition: grpc_tool_test.cc:71
grpc::testing::GrpcToolTest::SetUpServer
std::string SetUpServer(bool secure=false)
Definition: grpc_tool_test.cc:293
grpc::SslServerCredentialsOptions::PemKeyCertPair
Definition: include/grpcpp/security/server_credentials.h:47
grpc::testing::GrpcToolTest::ShutdownServer
void ShutdownServer()
Definition: grpc_tool_test.cc:327
grpc::testing::TEST_F
TEST_F(ChannelArgumentsTest, SetInt)
Definition: channel_arguments_test.cc:134
grpc::ClientContext::deadline
std::chrono::system_clock::time_point deadline() const
Return the deadline for the client call.
Definition: grpcpp/impl/codegen/client_context.h:294
grpc::testing::ToString
std::string ToString(const grpc::string_ref &r)
Definition: string_ref_helper.cc:24
alloc.h
server_context.h
main
int main(int argc, char **argv)
Definition: grpc_tool_test.cc:1349
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
desc
#define desc
Definition: bloaty/third_party/protobuf/src/google/protobuf/extension_set.h:338
grpc::testing::TestServiceImpl::BidiStream
Status BidiStream(ServerContext *, ServerReaderWriter< EchoResponse, EchoRequest > *stream) override
Definition: streaming_throughput_test.cc:108
test_config.h
grpc::InsecureServerCredentials
std::shared_ptr< ServerCredentials > InsecureServerCredentials()
Definition: insecure_server_credentials.cc:52
grpc::testing::TestServiceImpl::Echo
Status Echo(ServerContext *context, const EchoRequest *, EchoResponse *) override
Definition: shutdown_test.cc:49
test_root_cert
const char test_root_cert[]
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
iter
Definition: test_winkernel.cpp:47
grpc::testing::EXPECT_TRUE
EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson(minimum_valid_json, &options) .ok())
server.h
SERVER_CERT_PATH
#define SERVER_CERT_PATH
Definition: grpc_tool_test.cc:50
grpc::InsecureChannelCredentials
std::shared_ptr< ChannelCredentials > InsecureChannelCredentials()
Credentials for an unencrypted, unauthenticated channel.
Definition: cpp/client/insecure_credentials.cc:69
grpc::protobuf::Descriptor
GRPC_CUSTOM_DESCRIPTOR Descriptor
Definition: include/grpcpp/impl/codegen/config_protobuf.h:81
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
ECHO_TEST_SERVICE_SUMMARY
#define ECHO_TEST_SERVICE_SUMMARY
Definition: grpc_tool_test.cc:58
string_ref_helper.h
to_string
static bool to_string(zval *from)
Definition: protobuf/php/ext/google/protobuf/convert.c:333
TestServiceImpl
Definition: interop_server.cc:139
server_builder.h
timeout
uv_timer_t timeout
Definition: libuv/docs/code/uvwget/main.c:9
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
create_channel.h
cli_credentials.h
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Thu Mar 13 2025 02:59:48