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