grpc_tool_test.cc 52 KB

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