http2_client.cc 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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/interop/http2_client.h"
  19. #include <thread>
  20. #include "absl/flags/flag.h"
  21. #include <grpc/support/alloc.h>
  22. #include <grpc/support/log.h>
  23. #include <grpcpp/channel.h>
  24. #include <grpcpp/client_context.h>
  25. #include "src/core/lib/gpr/string.h"
  26. #include "src/core/lib/gpr/useful.h"
  27. #include "src/core/lib/transport/byte_stream.h"
  28. #include "src/proto/grpc/testing/messages.pb.h"
  29. #include "src/proto/grpc/testing/test.grpc.pb.h"
  30. #include "test/cpp/util/create_test_channel.h"
  31. #include "test/cpp/util/test_config.h"
  32. namespace grpc {
  33. namespace testing {
  34. namespace {
  35. const int kLargeRequestSize = 271828;
  36. const int kLargeResponseSize = 314159;
  37. } // namespace
  38. Http2Client::ServiceStub::ServiceStub(const std::shared_ptr<Channel>& channel)
  39. : channel_(channel) {
  40. stub_ = TestService::NewStub(channel);
  41. }
  42. TestService::Stub* Http2Client::ServiceStub::Get() { return stub_.get(); }
  43. Http2Client::Http2Client(const std::shared_ptr<Channel>& channel)
  44. : serviceStub_(channel),
  45. channel_(channel),
  46. defaultRequest_(BuildDefaultRequest()) {}
  47. bool Http2Client::AssertStatusCode(const Status& s, StatusCode expected_code) {
  48. if (s.error_code() == expected_code) {
  49. return true;
  50. }
  51. gpr_log(GPR_ERROR, "Error status code: %d (expected: %d), message: %s",
  52. s.error_code(), expected_code, s.error_message().c_str());
  53. abort();
  54. }
  55. Status Http2Client::SendUnaryCall(SimpleResponse* response) {
  56. ClientContext context;
  57. return serviceStub_.Get()->UnaryCall(&context, defaultRequest_, response);
  58. }
  59. SimpleRequest Http2Client::BuildDefaultRequest() {
  60. SimpleRequest request;
  61. request.set_response_size(kLargeResponseSize);
  62. std::string payload(kLargeRequestSize, '\0');
  63. request.mutable_payload()->set_body(payload.c_str(), kLargeRequestSize);
  64. return request;
  65. }
  66. bool Http2Client::DoRstAfterHeader() {
  67. gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after header");
  68. SimpleResponse response;
  69. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
  70. GPR_ASSERT(!response.has_payload()); // no data should be received
  71. gpr_log(GPR_DEBUG, "Done testing reset stream after header");
  72. return true;
  73. }
  74. bool Http2Client::DoRstAfterData() {
  75. gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream after data");
  76. SimpleResponse response;
  77. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
  78. // There is no guarantee that data would be received.
  79. gpr_log(GPR_DEBUG, "Done testing reset stream after data");
  80. return true;
  81. }
  82. bool Http2Client::DoRstDuringData() {
  83. gpr_log(GPR_DEBUG, "Sending RPC and expecting reset stream during data");
  84. SimpleResponse response;
  85. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::INTERNAL);
  86. GPR_ASSERT(!response.has_payload()); // no data should be received
  87. gpr_log(GPR_DEBUG, "Done testing reset stream during data");
  88. return true;
  89. }
  90. bool Http2Client::DoGoaway() {
  91. gpr_log(GPR_DEBUG, "Sending two RPCs and expecting goaway");
  92. SimpleResponse response;
  93. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
  94. GPR_ASSERT(response.payload().body() ==
  95. std::string(kLargeResponseSize, '\0'));
  96. // Sleep for one second to give time for client to receive goaway frame.
  97. gpr_timespec sleep_time = gpr_time_add(
  98. gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(1, GPR_TIMESPAN));
  99. gpr_sleep_until(sleep_time);
  100. response.Clear();
  101. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
  102. GPR_ASSERT(response.payload().body() ==
  103. std::string(kLargeResponseSize, '\0'));
  104. gpr_log(GPR_DEBUG, "Done testing goaway");
  105. return true;
  106. }
  107. bool Http2Client::DoPing() {
  108. gpr_log(GPR_DEBUG, "Sending RPC and expecting ping");
  109. SimpleResponse response;
  110. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
  111. GPR_ASSERT(response.payload().body() ==
  112. std::string(kLargeResponseSize, '\0'));
  113. gpr_log(GPR_DEBUG, "Done testing ping");
  114. return true;
  115. }
  116. void Http2Client::MaxStreamsWorker(
  117. const std::shared_ptr<grpc::Channel>& /*channel*/) {
  118. SimpleResponse response;
  119. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
  120. GPR_ASSERT(response.payload().body() ==
  121. std::string(kLargeResponseSize, '\0'));
  122. }
  123. bool Http2Client::DoMaxStreams() {
  124. gpr_log(GPR_DEBUG, "Testing max streams");
  125. // Make an initial call on the channel to ensure the server's max streams
  126. // setting is received
  127. SimpleResponse response;
  128. AssertStatusCode(SendUnaryCall(&response), grpc::StatusCode::OK);
  129. GPR_ASSERT(response.payload().body() ==
  130. std::string(kLargeResponseSize, '\0'));
  131. std::vector<std::thread> test_threads;
  132. test_threads.reserve(10);
  133. for (int i = 0; i < 10; i++) {
  134. test_threads.emplace_back(
  135. std::thread(&Http2Client::MaxStreamsWorker, this, channel_));
  136. }
  137. for (auto it = test_threads.begin(); it != test_threads.end(); it++) {
  138. it->join();
  139. }
  140. gpr_log(GPR_DEBUG, "Done testing max streams");
  141. return true;
  142. }
  143. } // namespace testing
  144. } // namespace grpc
  145. ABSL_FLAG(int32_t, server_port, 0, "Server port.");
  146. ABSL_FLAG(std::string, server_host, "localhost", "Server host to connect to");
  147. ABSL_FLAG(std::string, test_case, "rst_after_header",
  148. "Configure different test cases. Valid options are:\n\n"
  149. "goaway\n"
  150. "max_streams\n"
  151. "ping\n"
  152. "rst_after_data\n"
  153. "rst_after_header\n"
  154. "rst_during_data\n");
  155. int main(int argc, char** argv) {
  156. grpc::testing::InitTest(&argc, &argv, true);
  157. GPR_ASSERT(absl::GetFlag(FLAGS_server_port));
  158. const int host_port_buf_size = 1024;
  159. char host_port[host_port_buf_size];
  160. snprintf(host_port, host_port_buf_size, "%s:%d",
  161. absl::GetFlag(FLAGS_server_host).c_str(),
  162. absl::GetFlag(FLAGS_server_port));
  163. std::shared_ptr<grpc::Channel> channel =
  164. grpc::CreateTestChannel(host_port, grpc::testing::INSECURE);
  165. GPR_ASSERT(channel->WaitForConnected(gpr_time_add(
  166. gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_seconds(300, GPR_TIMESPAN))));
  167. grpc::testing::Http2Client client(channel);
  168. gpr_log(GPR_INFO, "Testing case: %s", absl::GetFlag(FLAGS_test_case).c_str());
  169. int ret = 0;
  170. if (absl::GetFlag(FLAGS_test_case) == "rst_after_header") {
  171. client.DoRstAfterHeader();
  172. } else if (absl::GetFlag(FLAGS_test_case) == "rst_after_data") {
  173. client.DoRstAfterData();
  174. } else if (absl::GetFlag(FLAGS_test_case) == "rst_during_data") {
  175. client.DoRstDuringData();
  176. } else if (absl::GetFlag(FLAGS_test_case) == "goaway") {
  177. client.DoGoaway();
  178. } else if (absl::GetFlag(FLAGS_test_case) == "ping") {
  179. client.DoPing();
  180. } else if (absl::GetFlag(FLAGS_test_case) == "max_streams") {
  181. client.DoMaxStreams();
  182. } else {
  183. const char* testcases[] = {
  184. "goaway", "max_streams", "ping",
  185. "rst_after_data", "rst_after_header", "rst_during_data"};
  186. char* joined_testcases =
  187. gpr_strjoin_sep(testcases, GPR_ARRAY_SIZE(testcases), "\n", nullptr);
  188. gpr_log(GPR_ERROR, "Unsupported test case %s. Valid options are\n%s",
  189. absl::GetFlag(FLAGS_test_case).c_str(), joined_testcases);
  190. gpr_free(joined_testcases);
  191. ret = 1;
  192. }
  193. return ret;
  194. }