interop_client.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. /*
  2. *
  3. * Copyright 2015, Google Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include "test/cpp/interop/interop_client.h"
  34. #include <memory>
  35. #include <unistd.h>
  36. #include <grpc/grpc.h>
  37. #include <grpc/support/log.h>
  38. #include <grpc++/channel_interface.h>
  39. #include <grpc++/client_context.h>
  40. #include <grpc++/status.h>
  41. #include <grpc++/stream.h>
  42. #include "test/cpp/interop/client_helper.h"
  43. #include "test/proto/test.grpc.pb.h"
  44. #include "test/proto/empty.grpc.pb.h"
  45. #include "test/proto/messages.grpc.pb.h"
  46. namespace grpc {
  47. namespace testing {
  48. namespace {
  49. // The same value is defined by the Java client.
  50. const std::vector<int> request_stream_sizes = {27182, 8, 1828, 45904};
  51. const std::vector<int> response_stream_sizes = {31415, 9, 2653, 58979};
  52. const int kNumResponseMessages = 2000;
  53. const int kResponseMessageSize = 1030;
  54. const int kReceiveDelayMilliSeconds = 20;
  55. const int kLargeRequestSize = 271828;
  56. const int kLargeResponseSize = 314159;
  57. } // namespace
  58. InteropClient::InteropClient(std::shared_ptr<ChannelInterface> channel)
  59. : channel_(channel) {}
  60. void InteropClient::AssertOkOrPrintErrorStatus(const Status& s) {
  61. if (s.ok()) {
  62. return;
  63. }
  64. gpr_log(GPR_INFO, "Error status code: %d, message: %s", s.error_code(),
  65. s.error_message().c_str());
  66. GPR_ASSERT(0);
  67. }
  68. void InteropClient::DoEmpty() {
  69. gpr_log(GPR_INFO, "Sending an empty rpc...");
  70. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  71. Empty request = Empty::default_instance();
  72. Empty response = Empty::default_instance();
  73. ClientContext context;
  74. Status s = stub->EmptyCall(&context, request, &response);
  75. AssertOkOrPrintErrorStatus(s);
  76. gpr_log(GPR_INFO, "Empty rpc done.");
  77. }
  78. // Shared code to set large payload, make rpc and check response payload.
  79. void InteropClient::PerformLargeUnary(SimpleRequest* request,
  80. SimpleResponse* response) {
  81. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  82. ClientContext context;
  83. InteropClientContextInspector inspector(context);
  84. request->set_response_size(kLargeResponseSize);
  85. grpc::string payload(kLargeRequestSize, '\0');
  86. request->mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
  87. Status s = stub->UnaryCall(&context, *request, response);
  88. GPR_ASSERT(request->response_compression() ==
  89. GetInteropCompressionTypeFromCompressionAlgorithm(
  90. inspector.GetCallCompressionAlgorithm()));
  91. AssertOkOrPrintErrorStatus(s);
  92. GPR_ASSERT(response->payload().type() == request->response_type());
  93. GPR_ASSERT(response->payload().body() ==
  94. grpc::string(kLargeResponseSize, '\0'));
  95. }
  96. void InteropClient::DoComputeEngineCreds(
  97. const grpc::string& default_service_account,
  98. const grpc::string& oauth_scope) {
  99. gpr_log(GPR_INFO,
  100. "Sending a large unary rpc with compute engine credentials ...");
  101. SimpleRequest request;
  102. SimpleResponse response;
  103. request.set_fill_username(true);
  104. request.set_fill_oauth_scope(true);
  105. request.set_response_type(PayloadType::COMPRESSABLE);
  106. PerformLargeUnary(&request, &response);
  107. gpr_log(GPR_INFO, "Got username %s", response.username().c_str());
  108. gpr_log(GPR_INFO, "Got oauth_scope %s", response.oauth_scope().c_str());
  109. GPR_ASSERT(!response.username().empty());
  110. GPR_ASSERT(response.username().c_str() == default_service_account);
  111. GPR_ASSERT(!response.oauth_scope().empty());
  112. const char* oauth_scope_str = response.oauth_scope().c_str();
  113. GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
  114. gpr_log(GPR_INFO, "Large unary with compute engine creds done.");
  115. }
  116. void InteropClient::DoServiceAccountCreds(const grpc::string& username,
  117. const grpc::string& oauth_scope) {
  118. gpr_log(GPR_INFO,
  119. "Sending a large unary rpc with service account credentials ...");
  120. SimpleRequest request;
  121. SimpleResponse response;
  122. request.set_fill_username(true);
  123. request.set_fill_oauth_scope(true);
  124. request.set_response_type(PayloadType::COMPRESSABLE);
  125. PerformLargeUnary(&request, &response);
  126. GPR_ASSERT(!response.username().empty());
  127. GPR_ASSERT(!response.oauth_scope().empty());
  128. GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
  129. const char* oauth_scope_str = response.oauth_scope().c_str();
  130. GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
  131. gpr_log(GPR_INFO, "Large unary with service account creds done.");
  132. }
  133. void InteropClient::DoOauth2AuthToken(const grpc::string& username,
  134. const grpc::string& oauth_scope) {
  135. gpr_log(GPR_INFO,
  136. "Sending a unary rpc with raw oauth2 access token credentials ...");
  137. SimpleRequest request;
  138. SimpleResponse response;
  139. request.set_fill_username(true);
  140. request.set_fill_oauth_scope(true);
  141. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  142. ClientContext context;
  143. Status s = stub->UnaryCall(&context, request, &response);
  144. AssertOkOrPrintErrorStatus(s);
  145. GPR_ASSERT(!response.username().empty());
  146. GPR_ASSERT(!response.oauth_scope().empty());
  147. GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
  148. const char* oauth_scope_str = response.oauth_scope().c_str();
  149. GPR_ASSERT(oauth_scope.find(oauth_scope_str) != grpc::string::npos);
  150. gpr_log(GPR_INFO, "Unary with oauth2 access token credentials done.");
  151. }
  152. void InteropClient::DoJwtTokenCreds(const grpc::string& username) {
  153. gpr_log(GPR_INFO, "Sending a large unary rpc with JWT token credentials ...");
  154. SimpleRequest request;
  155. SimpleResponse response;
  156. request.set_fill_username(true);
  157. request.set_response_type(PayloadType::COMPRESSABLE);
  158. PerformLargeUnary(&request, &response);
  159. GPR_ASSERT(!response.username().empty());
  160. GPR_ASSERT(username.find(response.username()) != grpc::string::npos);
  161. gpr_log(GPR_INFO, "Large unary with JWT token creds done.");
  162. }
  163. void InteropClient::DoLargeUnary() {
  164. const CompressionType compression_types[] = {NONE, GZIP, DEFLATE};
  165. const PayloadType payload_types[] = {COMPRESSABLE, UNCOMPRESSABLE, RANDOM};
  166. for (const auto payload_type : payload_types) {
  167. for (const auto compression_type : compression_types) {
  168. gpr_log(GPR_INFO, "Sending a large unary rpc...");
  169. SimpleRequest request;
  170. SimpleResponse response;
  171. request.set_response_type(payload_type);
  172. request.set_response_compression(compression_type);
  173. PerformLargeUnary(&request, &response);
  174. gpr_log(GPR_INFO, "Large unary done.");
  175. }
  176. }
  177. }
  178. void InteropClient::DoRequestStreaming() {
  179. gpr_log(GPR_INFO, "Sending request steaming rpc ...");
  180. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  181. ClientContext context;
  182. StreamingInputCallRequest request;
  183. StreamingInputCallResponse response;
  184. std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
  185. stub->StreamingInputCall(&context, &response));
  186. int aggregated_payload_size = 0;
  187. for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
  188. Payload* payload = request.mutable_payload();
  189. payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
  190. GPR_ASSERT(stream->Write(request));
  191. aggregated_payload_size += request_stream_sizes[i];
  192. }
  193. stream->WritesDone();
  194. Status s = stream->Finish();
  195. GPR_ASSERT(response.aggregated_payload_size() == aggregated_payload_size);
  196. AssertOkOrPrintErrorStatus(s);
  197. gpr_log(GPR_INFO, "Request streaming done.");
  198. }
  199. void InteropClient::DoResponseStreaming() {
  200. gpr_log(GPR_INFO, "Receiving response steaming rpc ...");
  201. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  202. ClientContext context;
  203. StreamingOutputCallRequest request;
  204. request.set_response_type(PayloadType::COMPRESSABLE);
  205. request.set_response_compression(CompressionType::GZIP);
  206. for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
  207. ResponseParameters* response_parameter = request.add_response_parameters();
  208. response_parameter->set_size(response_stream_sizes[i]);
  209. }
  210. StreamingOutputCallResponse response;
  211. std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
  212. stub->StreamingOutputCall(&context, request));
  213. unsigned int i = 0;
  214. while (stream->Read(&response)) {
  215. GPR_ASSERT(response.payload().body() ==
  216. grpc::string(response_stream_sizes[i], '\0'));
  217. ++i;
  218. }
  219. GPR_ASSERT(response_stream_sizes.size() == i);
  220. Status s = stream->Finish();
  221. AssertOkOrPrintErrorStatus(s);
  222. gpr_log(GPR_INFO, "Response streaming done.");
  223. }
  224. void InteropClient::DoResponseStreamingWithSlowConsumer() {
  225. gpr_log(GPR_INFO, "Receiving response steaming rpc with slow consumer ...");
  226. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  227. ClientContext context;
  228. StreamingOutputCallRequest request;
  229. for (int i = 0; i < kNumResponseMessages; ++i) {
  230. ResponseParameters* response_parameter = request.add_response_parameters();
  231. response_parameter->set_size(kResponseMessageSize);
  232. }
  233. StreamingOutputCallResponse response;
  234. std::unique_ptr<ClientReader<StreamingOutputCallResponse>> stream(
  235. stub->StreamingOutputCall(&context, request));
  236. int i = 0;
  237. while (stream->Read(&response)) {
  238. GPR_ASSERT(response.payload().body() ==
  239. grpc::string(kResponseMessageSize, '\0'));
  240. gpr_log(GPR_INFO, "received message %d", i);
  241. usleep(kReceiveDelayMilliSeconds * 1000);
  242. ++i;
  243. }
  244. GPR_ASSERT(kNumResponseMessages == i);
  245. Status s = stream->Finish();
  246. AssertOkOrPrintErrorStatus(s);
  247. gpr_log(GPR_INFO, "Response streaming done.");
  248. }
  249. void InteropClient::DoHalfDuplex() {
  250. gpr_log(GPR_INFO, "Sending half-duplex streaming rpc ...");
  251. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  252. ClientContext context;
  253. std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
  254. StreamingOutputCallResponse>>
  255. stream(stub->HalfDuplexCall(&context));
  256. StreamingOutputCallRequest request;
  257. ResponseParameters* response_parameter = request.add_response_parameters();
  258. for (unsigned int i = 0; i < response_stream_sizes.size(); ++i) {
  259. response_parameter->set_size(response_stream_sizes[i]);
  260. GPR_ASSERT(stream->Write(request));
  261. }
  262. stream->WritesDone();
  263. unsigned int i = 0;
  264. StreamingOutputCallResponse response;
  265. while (stream->Read(&response)) {
  266. GPR_ASSERT(response.payload().has_body());
  267. GPR_ASSERT(response.payload().body() ==
  268. grpc::string(response_stream_sizes[i], '\0'));
  269. ++i;
  270. }
  271. GPR_ASSERT(response_stream_sizes.size() == i);
  272. Status s = stream->Finish();
  273. AssertOkOrPrintErrorStatus(s);
  274. gpr_log(GPR_INFO, "Half-duplex streaming rpc done.");
  275. }
  276. void InteropClient::DoPingPong() {
  277. gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
  278. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  279. ClientContext context;
  280. std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
  281. StreamingOutputCallResponse>>
  282. stream(stub->FullDuplexCall(&context));
  283. StreamingOutputCallRequest request;
  284. request.set_response_type(PayloadType::COMPRESSABLE);
  285. ResponseParameters* response_parameter = request.add_response_parameters();
  286. Payload* payload = request.mutable_payload();
  287. StreamingOutputCallResponse response;
  288. for (unsigned int i = 0; i < request_stream_sizes.size(); ++i) {
  289. response_parameter->set_size(response_stream_sizes[i]);
  290. payload->set_body(grpc::string(request_stream_sizes[i], '\0'));
  291. GPR_ASSERT(stream->Write(request));
  292. GPR_ASSERT(stream->Read(&response));
  293. GPR_ASSERT(response.payload().has_body());
  294. GPR_ASSERT(response.payload().body() ==
  295. grpc::string(response_stream_sizes[i], '\0'));
  296. }
  297. stream->WritesDone();
  298. GPR_ASSERT(!stream->Read(&response));
  299. Status s = stream->Finish();
  300. AssertOkOrPrintErrorStatus(s);
  301. gpr_log(GPR_INFO, "Ping pong streaming done.");
  302. }
  303. void InteropClient::DoCancelAfterBegin() {
  304. gpr_log(GPR_INFO, "Sending request steaming rpc ...");
  305. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  306. ClientContext context;
  307. StreamingInputCallRequest request;
  308. StreamingInputCallResponse response;
  309. std::unique_ptr<ClientWriter<StreamingInputCallRequest>> stream(
  310. stub->StreamingInputCall(&context, &response));
  311. gpr_log(GPR_INFO, "Trying to cancel...");
  312. context.TryCancel();
  313. Status s = stream->Finish();
  314. GPR_ASSERT(s.error_code() == StatusCode::CANCELLED);
  315. gpr_log(GPR_INFO, "Canceling streaming done.");
  316. }
  317. void InteropClient::DoCancelAfterFirstResponse() {
  318. gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc ...");
  319. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  320. ClientContext context;
  321. std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
  322. StreamingOutputCallResponse>>
  323. stream(stub->FullDuplexCall(&context));
  324. StreamingOutputCallRequest request;
  325. request.set_response_type(PayloadType::COMPRESSABLE);
  326. ResponseParameters* response_parameter = request.add_response_parameters();
  327. response_parameter->set_size(31415);
  328. request.mutable_payload()->set_body(grpc::string(27182, '\0'));
  329. StreamingOutputCallResponse response;
  330. GPR_ASSERT(stream->Write(request));
  331. GPR_ASSERT(stream->Read(&response));
  332. GPR_ASSERT(response.payload().has_body());
  333. GPR_ASSERT(response.payload().body() == grpc::string(31415, '\0'));
  334. gpr_log(GPR_INFO, "Trying to cancel...");
  335. context.TryCancel();
  336. Status s = stream->Finish();
  337. gpr_log(GPR_INFO, "Canceling pingpong streaming done.");
  338. }
  339. void InteropClient::DoTimeoutOnSleepingServer() {
  340. gpr_log(GPR_INFO, "Sending Ping Pong streaming rpc with a short deadline...");
  341. std::unique_ptr<TestService::Stub> stub(TestService::NewStub(channel_));
  342. ClientContext context;
  343. std::chrono::system_clock::time_point deadline =
  344. std::chrono::system_clock::now() + std::chrono::milliseconds(1);
  345. context.set_deadline(deadline);
  346. std::unique_ptr<ClientReaderWriter<StreamingOutputCallRequest,
  347. StreamingOutputCallResponse>>
  348. stream(stub->FullDuplexCall(&context));
  349. StreamingOutputCallRequest request;
  350. request.mutable_payload()->set_body(grpc::string(27182, '\0'));
  351. stream->Write(request);
  352. Status s = stream->Finish();
  353. GPR_ASSERT(s.error_code() == StatusCode::DEADLINE_EXCEEDED);
  354. gpr_log(GPR_INFO, "Pingpong streaming timeout done.");
  355. }
  356. } // namespace testing
  357. } // namespace grpc