stranded_event_test.cc 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451
  1. /*
  2. *
  3. * Copyright 2020 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 <grpc/support/port_platform.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <functional>
  22. #include <set>
  23. #include <thread>
  24. #include <gmock/gmock.h>
  25. #include "absl/strings/str_cat.h"
  26. #include "absl/strings/str_format.h"
  27. #include "absl/types/optional.h"
  28. #include <grpc/grpc.h>
  29. #include <grpc/grpc_security.h>
  30. #include <grpc/impl/codegen/grpc_types.h>
  31. #include <grpc/slice.h>
  32. #include <grpc/support/alloc.h>
  33. #include <grpc/support/log.h>
  34. #include <grpc/support/string_util.h>
  35. #include <grpc/support/time.h>
  36. #include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h"
  37. #include "src/core/lib/address_utils/parse_address.h"
  38. #include "src/core/lib/gpr/useful.h"
  39. #include "src/core/lib/gprpp/host_port.h"
  40. #include "src/core/lib/gprpp/thd.h"
  41. #include "src/core/lib/iomgr/error.h"
  42. #include "src/core/lib/security/credentials/alts/alts_credentials.h"
  43. #include "src/core/lib/security/credentials/credentials.h"
  44. #include "src/core/lib/security/security_connector/alts/alts_security_connector.h"
  45. #include "src/core/lib/slice/slice_string_helpers.h"
  46. #include "src/core/lib/uri/uri_parser.h"
  47. #include "test/core/end2end/cq_verifier.h"
  48. #include "test/core/util/port.h"
  49. #include "test/core/util/test_config.h"
  50. namespace {
  51. const int kNumMessagePingPongsPerCall = 4000;
  52. struct TestCall {
  53. explicit TestCall(grpc_channel* channel, grpc_call* call,
  54. grpc_completion_queue* cq)
  55. : channel(channel), call(call), cq(cq) {}
  56. TestCall(const TestCall& other) = delete;
  57. TestCall& operator=(const TestCall& other) = delete;
  58. ~TestCall() {
  59. grpc_call_cancel(call, nullptr);
  60. grpc_call_unref(call);
  61. grpc_channel_destroy(channel);
  62. grpc_completion_queue_shutdown(cq);
  63. while (grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME),
  64. nullptr)
  65. .type != GRPC_QUEUE_SHUTDOWN) {
  66. }
  67. grpc_completion_queue_destroy(cq);
  68. }
  69. grpc_channel* channel;
  70. grpc_call* call;
  71. grpc_completion_queue* cq;
  72. absl::optional<grpc_status_code>
  73. status; // filled in when the call is finished
  74. };
  75. void StartCall(TestCall* test_call) {
  76. grpc_op ops[6];
  77. grpc_op* op;
  78. memset(ops, 0, sizeof(ops));
  79. op = ops;
  80. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  81. op->data.send_initial_metadata.count = 0;
  82. op->flags = GRPC_INITIAL_METADATA_WAIT_FOR_READY;
  83. op->reserved = nullptr;
  84. op++;
  85. void* tag = test_call;
  86. grpc_call_error error = grpc_call_start_batch(
  87. test_call->call, ops, static_cast<size_t>(op - ops), tag, nullptr);
  88. GPR_ASSERT(GRPC_CALL_OK == error);
  89. cq_verifier* cqv = cq_verifier_create(test_call->cq);
  90. CQ_EXPECT_COMPLETION(cqv, tag, 1);
  91. cq_verify(cqv);
  92. cq_verifier_destroy(cqv);
  93. }
  94. void SendMessage(grpc_call* call, grpc_completion_queue* cq) {
  95. grpc_slice request_payload_slice = grpc_slice_from_copied_string("a");
  96. grpc_byte_buffer* request_payload =
  97. grpc_raw_byte_buffer_create(&request_payload_slice, 1);
  98. grpc_op ops[6];
  99. grpc_op* op;
  100. memset(ops, 0, sizeof(ops));
  101. op = ops;
  102. op->op = GRPC_OP_SEND_MESSAGE;
  103. op->data.send_message.send_message = request_payload;
  104. op->reserved = nullptr;
  105. op++;
  106. void* tag = call;
  107. grpc_call_error error = grpc_call_start_batch(
  108. call, ops, static_cast<size_t>(op - ops), tag, nullptr);
  109. GPR_ASSERT(GRPC_CALL_OK == error);
  110. cq_verifier* cqv = cq_verifier_create(cq);
  111. CQ_EXPECT_COMPLETION(cqv, tag, 1);
  112. cq_verify(cqv);
  113. cq_verifier_destroy(cqv);
  114. grpc_byte_buffer_destroy(request_payload);
  115. }
  116. void ReceiveMessage(grpc_call* call, grpc_completion_queue* cq) {
  117. grpc_byte_buffer* request_payload = nullptr;
  118. grpc_op ops[6];
  119. grpc_op* op;
  120. memset(ops, 0, sizeof(ops));
  121. op = ops;
  122. op->op = GRPC_OP_RECV_MESSAGE;
  123. op->data.recv_message.recv_message = &request_payload;
  124. op->reserved = nullptr;
  125. op++;
  126. void* tag = call;
  127. grpc_call_error error = grpc_call_start_batch(
  128. call, ops, static_cast<size_t>(op - ops), tag, nullptr);
  129. GPR_ASSERT(GRPC_CALL_OK == error);
  130. cq_verifier* cqv = cq_verifier_create(cq);
  131. CQ_EXPECT_COMPLETION(cqv, tag, 1);
  132. cq_verify(cqv);
  133. cq_verifier_destroy(cqv);
  134. grpc_byte_buffer_destroy(request_payload);
  135. }
  136. void ReceiveInitialMetadata(TestCall* test_call, gpr_timespec deadline) {
  137. grpc_metadata_array initial_metadata_recv;
  138. grpc_metadata_array_init(&initial_metadata_recv);
  139. grpc_op ops[6];
  140. grpc_op* op;
  141. memset(ops, 0, sizeof(ops));
  142. op = ops;
  143. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  144. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  145. op->reserved = nullptr;
  146. op++;
  147. void* tag = test_call;
  148. grpc_call_error error = grpc_call_start_batch(
  149. test_call->call, ops, static_cast<size_t>(op - ops), tag, nullptr);
  150. GPR_ASSERT(GRPC_CALL_OK == error);
  151. grpc_event event =
  152. grpc_completion_queue_next(test_call->cq, deadline, nullptr);
  153. if (event.type != GRPC_OP_COMPLETE || !event.success) {
  154. gpr_log(GPR_ERROR,
  155. "Wanted op complete with success, got op type:%d success:%d",
  156. event.type, event.success);
  157. GPR_ASSERT(0);
  158. }
  159. GPR_ASSERT(event.tag == tag);
  160. grpc_metadata_array_destroy(&initial_metadata_recv);
  161. }
  162. void FinishCall(TestCall* test_call) {
  163. grpc_op ops[6];
  164. grpc_op* op;
  165. grpc_metadata_array trailing_metadata_recv;
  166. grpc_status_code status;
  167. grpc_slice details;
  168. grpc_metadata_array_init(&trailing_metadata_recv);
  169. memset(ops, 0, sizeof(ops));
  170. op = ops;
  171. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  172. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  173. op->data.recv_status_on_client.status = &status;
  174. op->data.recv_status_on_client.status_details = &details;
  175. op->flags = 0;
  176. op->reserved = nullptr;
  177. op++;
  178. void* tag = test_call;
  179. grpc_call_error error = grpc_call_start_batch(
  180. test_call->call, ops, static_cast<size_t>(op - ops), tag, nullptr);
  181. GPR_ASSERT(GRPC_CALL_OK == error);
  182. grpc_event event = grpc_completion_queue_next(
  183. test_call->cq, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
  184. GPR_ASSERT(event.type == GRPC_OP_COMPLETE);
  185. GPR_ASSERT(event.success);
  186. GPR_ASSERT(event.tag == tag);
  187. test_call->status = status;
  188. grpc_metadata_array_destroy(&trailing_metadata_recv);
  189. grpc_slice_unref(details);
  190. }
  191. class TestServer {
  192. public:
  193. explicit TestServer() {
  194. cq_ = grpc_completion_queue_create_for_next(nullptr);
  195. server_ = grpc_server_create(nullptr, nullptr);
  196. address_ =
  197. grpc_core::JoinHostPort("127.0.0.1", grpc_pick_unused_port_or_die());
  198. grpc_server_register_completion_queue(server_, cq_, nullptr);
  199. grpc_server_credentials* server_creds =
  200. grpc_insecure_server_credentials_create();
  201. GPR_ASSERT(
  202. grpc_server_add_http2_port(server_, address_.c_str(), server_creds));
  203. grpc_server_credentials_release(server_creds);
  204. grpc_server_start(server_);
  205. thread_ = std::thread(std::bind(&TestServer::AcceptThread, this));
  206. }
  207. ~TestServer() {
  208. thread_.join();
  209. void* shutdown_and_notify_tag = this;
  210. grpc_server_shutdown_and_notify(server_, cq_, shutdown_and_notify_tag);
  211. grpc_event event = grpc_completion_queue_next(
  212. cq_, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
  213. GPR_ASSERT(event.type == GRPC_OP_COMPLETE);
  214. GPR_ASSERT(event.tag == shutdown_and_notify_tag);
  215. GPR_ASSERT(event.success);
  216. grpc_server_destroy(server_);
  217. grpc_completion_queue_shutdown(cq_);
  218. while (grpc_completion_queue_next(cq_, gpr_inf_future(GPR_CLOCK_REALTIME),
  219. nullptr)
  220. .type != GRPC_QUEUE_SHUTDOWN) {
  221. }
  222. grpc_completion_queue_destroy(cq_);
  223. }
  224. std::string address() const { return address_; }
  225. private:
  226. void AcceptThread() {
  227. grpc_call_details call_details;
  228. grpc_call_details_init(&call_details);
  229. grpc_metadata_array request_metadata_recv;
  230. grpc_metadata_array_init(&request_metadata_recv);
  231. void* tag = &call_details;
  232. grpc_call* call;
  233. grpc_call_error error = grpc_server_request_call(
  234. server_, &call, &call_details, &request_metadata_recv, cq_, cq_, tag);
  235. GPR_ASSERT(error == GRPC_CALL_OK);
  236. grpc_event event = grpc_completion_queue_next(
  237. cq_, gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
  238. GPR_ASSERT(event.type == GRPC_OP_COMPLETE);
  239. GPR_ASSERT(event.success);
  240. GPR_ASSERT(event.tag == tag);
  241. grpc_op ops[6];
  242. grpc_op* op;
  243. memset(ops, 0, sizeof(ops));
  244. op = ops;
  245. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  246. op->data.send_initial_metadata.count = 0;
  247. op->reserved = nullptr;
  248. op++;
  249. error = grpc_call_start_batch(call, ops, static_cast<size_t>(op - ops), tag,
  250. nullptr);
  251. GPR_ASSERT(GRPC_CALL_OK == error);
  252. event = grpc_completion_queue_next(cq_, gpr_inf_future(GPR_CLOCK_REALTIME),
  253. nullptr);
  254. GPR_ASSERT(event.type == GRPC_OP_COMPLETE);
  255. GPR_ASSERT(event.success);
  256. GPR_ASSERT(event.tag == tag);
  257. for (int i = 0; i < kNumMessagePingPongsPerCall; i++) {
  258. ReceiveMessage(call, cq_);
  259. SendMessage(call, cq_);
  260. }
  261. grpc_call_cancel_with_status(call, GRPC_STATUS_PERMISSION_DENIED,
  262. "test status", nullptr);
  263. grpc_metadata_array_destroy(&request_metadata_recv);
  264. grpc_call_details_destroy(&call_details);
  265. grpc_call_unref(call);
  266. }
  267. grpc_server* server_;
  268. grpc_completion_queue* cq_;
  269. std::string address_;
  270. std::thread thread_;
  271. };
  272. grpc_core::Resolver::Result BuildResolverResponse(
  273. const std::vector<std::string>& addresses) {
  274. grpc_core::Resolver::Result result;
  275. result.addresses = grpc_core::ServerAddressList();
  276. for (const auto& address_str : addresses) {
  277. absl::StatusOr<grpc_core::URI> uri = grpc_core::URI::Parse(address_str);
  278. if (!uri.ok()) {
  279. gpr_log(GPR_ERROR, "Failed to parse. Error: %s",
  280. uri.status().ToString().c_str());
  281. GPR_ASSERT(uri.ok());
  282. }
  283. grpc_resolved_address address;
  284. GPR_ASSERT(grpc_parse_uri(*uri, &address));
  285. result.addresses->emplace_back(address.addr, address.len, nullptr);
  286. }
  287. return result;
  288. }
  289. // Perform a simple RPC where the server cancels the request with
  290. // grpc_call_cancel_with_status
  291. TEST(Pollers, TestReadabilityNotificationsDontGetStrandedOnOneCq) {
  292. gpr_log(GPR_DEBUG, "test thread");
  293. /* 64 is a somewhat arbitary number, the important thing is that it
  294. * exceeds the value of MAX_EPOLL_EVENTS_HANDLED_EACH_POLL_CALL (16), which
  295. * is enough to repro a bug at time of writing. */
  296. const int kNumCalls = 64;
  297. size_t ping_pong_round = 0;
  298. size_t ping_pongs_done = 0;
  299. grpc_core::Mutex ping_pong_round_mu;
  300. grpc_core::CondVar ping_pong_round_cv;
  301. const std::string kSharedUnconnectableAddress =
  302. grpc_core::JoinHostPort("127.0.0.1", grpc_pick_unused_port_or_die());
  303. gpr_log(GPR_DEBUG, "created unconnectable address:%s",
  304. kSharedUnconnectableAddress.c_str());
  305. std::vector<std::thread> threads;
  306. threads.reserve(kNumCalls);
  307. std::vector<std::unique_ptr<TestServer>> test_servers;
  308. // Instantiate servers inline here, so that we get port allocation out of the
  309. // way and don't depend on it during the actual test. It can sometimes take
  310. // time to allocate kNumCalls ports from the port server, and we don't want to
  311. // hit test timeouts because of that.
  312. test_servers.reserve(kNumCalls);
  313. for (int i = 0; i < kNumCalls; i++) {
  314. test_servers.push_back(absl::make_unique<TestServer>());
  315. }
  316. for (int i = 0; i < kNumCalls; i++) {
  317. auto test_server = test_servers[i].get();
  318. threads.push_back(std::thread([kSharedUnconnectableAddress,
  319. &ping_pong_round, &ping_pongs_done,
  320. &ping_pong_round_mu, &ping_pong_round_cv,
  321. test_server]() {
  322. gpr_log(GPR_DEBUG, "using test_server with address:%s",
  323. test_server->address().c_str());
  324. std::vector<grpc_arg> args;
  325. grpc_arg service_config_arg;
  326. service_config_arg.type = GRPC_ARG_STRING;
  327. service_config_arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG);
  328. service_config_arg.value.string =
  329. const_cast<char*>("{\"loadBalancingConfig\":[{\"round_robin\":{}}]}");
  330. args.push_back(service_config_arg);
  331. auto fake_resolver_response_generator =
  332. grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>();
  333. {
  334. grpc_core::ExecCtx exec_ctx;
  335. fake_resolver_response_generator->SetResponse(BuildResolverResponse(
  336. {absl::StrCat("ipv4:", kSharedUnconnectableAddress),
  337. absl::StrCat("ipv4:", test_server->address())}));
  338. }
  339. args.push_back(grpc_core::FakeResolverResponseGenerator::MakeChannelArg(
  340. fake_resolver_response_generator.get()));
  341. grpc_channel_args* channel_args =
  342. grpc_channel_args_copy_and_add(nullptr, args.data(), args.size());
  343. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  344. grpc_channel* channel =
  345. grpc_channel_create("fake:///test.server.com", creds, channel_args);
  346. grpc_channel_credentials_release(creds);
  347. grpc_channel_args_destroy(channel_args);
  348. grpc_completion_queue* cq =
  349. grpc_completion_queue_create_for_next(nullptr);
  350. grpc_call* call = grpc_channel_create_call(
  351. channel, nullptr, GRPC_PROPAGATE_DEFAULTS, cq,
  352. grpc_slice_from_static_string("/foo"), nullptr,
  353. gpr_inf_future(GPR_CLOCK_REALTIME), nullptr);
  354. auto test_call = absl::make_unique<TestCall>(channel, call, cq);
  355. // Start a call, and ensure that round_robin load balancing is configured
  356. StartCall(test_call.get());
  357. // Make sure the test is doing what it's meant to be doing
  358. grpc_channel_info channel_info;
  359. memset(&channel_info, 0, sizeof(channel_info));
  360. char* lb_policy_name = nullptr;
  361. channel_info.lb_policy_name = &lb_policy_name;
  362. grpc_channel_get_info(channel, &channel_info);
  363. EXPECT_EQ(std::string(lb_policy_name), "round_robin")
  364. << "not using round robin; this test has a low chance of hitting the "
  365. "bug that it's meant to try to hit";
  366. gpr_free(lb_policy_name);
  367. // Receive initial metadata
  368. gpr_log(GPR_DEBUG,
  369. "now receive initial metadata on call with server address:%s",
  370. test_server->address().c_str());
  371. ReceiveInitialMetadata(test_call.get(),
  372. grpc_timeout_seconds_to_deadline(30));
  373. for (int i = 1; i <= kNumMessagePingPongsPerCall; i++) {
  374. {
  375. grpc_core::MutexLock lock(&ping_pong_round_mu);
  376. ping_pong_round_cv.SignalAll();
  377. while (int(ping_pong_round) != i) {
  378. ping_pong_round_cv.Wait(&ping_pong_round_mu);
  379. }
  380. }
  381. SendMessage(test_call->call, test_call->cq);
  382. ReceiveMessage(test_call->call, test_call->cq);
  383. {
  384. grpc_core::MutexLock lock(&ping_pong_round_mu);
  385. ping_pongs_done++;
  386. ping_pong_round_cv.SignalAll();
  387. }
  388. }
  389. gpr_log(GPR_DEBUG, "now receive status on call with server address:%s",
  390. test_server->address().c_str());
  391. FinishCall(test_call.get());
  392. GPR_ASSERT(test_call->status.has_value());
  393. GPR_ASSERT(test_call->status.value() == GRPC_STATUS_PERMISSION_DENIED);
  394. {
  395. grpc_core::ExecCtx exec_ctx;
  396. fake_resolver_response_generator.reset();
  397. }
  398. }));
  399. }
  400. for (size_t i = 1; i <= kNumMessagePingPongsPerCall; i++) {
  401. {
  402. grpc_core::MutexLock lock(&ping_pong_round_mu);
  403. while (ping_pongs_done < ping_pong_round * kNumCalls) {
  404. ping_pong_round_cv.Wait(&ping_pong_round_mu);
  405. }
  406. ping_pong_round++;
  407. ping_pong_round_cv.SignalAll();
  408. gpr_log(GPR_DEBUG, "initiate ping pong round: %ld", ping_pong_round);
  409. }
  410. }
  411. for (auto& thread : threads) {
  412. thread.join();
  413. }
  414. gpr_log(GPR_DEBUG, "All RPCs completed!");
  415. }
  416. } // namespace
  417. int main(int argc, char** argv) {
  418. ::testing::InitGoogleTest(&argc, argv);
  419. grpc::testing::TestEnvironment env(argc, argv);
  420. grpc_init();
  421. auto result = RUN_ALL_TESTS();
  422. grpc_shutdown();
  423. return result;
  424. }