Add unit test to check the re-entrancy of callbacks

pull/19406/head
Karthik Ravi Shankar 6 years ago
parent 7a22143d7a
commit 44160d2b65
  1. 73
      test/cpp/end2end/client_callback_end2end_test.cc

@ -374,6 +374,79 @@ TEST_P(ClientCallbackEnd2endTest, SimpleRpc) {
SendRpcs(1, false);
}
TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) {
MAYBE_SKIP_TEST;
ResetStub();
std::mutex mu1, mu2, mu3;
std::condition_variable cv1, cv2, cv3;
bool done1 = false;
EchoRequest request1, request2, request3;
request1.set_message("Hello locked world1.");
EchoResponse response1;
ClientContext cli_ctx1;
{
std::unique_lock<std::mutex> l(mu1);
stub_->experimental_async()->Echo(
&cli_ctx1, &request1, &response1,
[&mu1, this, &cv1, &done1, &request1, &response1](Status s1) {
std::unique_lock<std::mutex> l1(mu1);
EXPECT_TRUE(s1.ok());
EXPECT_EQ(request1.message(), response1.message());
// start the second level of nesting
std::mutex mu2;
bool done2 = false;
std::condition_variable cv2;
EchoRequest request2;
request2.set_message("Hello locked world2.");
EchoResponse response2;
ClientContext cli_ctx2;
std::unique_lock<std::mutex> l2(mu2);
stub_->experimental_async()->Echo(
&cli_ctx2, &request2, &response2,
[&mu2, this, &cv2, &done2, &request2, &response2](Status s2) {
std::unique_lock<std::mutex> l2(mu2);
EXPECT_TRUE(s2.ok());
EXPECT_EQ(request2.message(), response2.message());
// start the third level of nesting
std::mutex mu3;
bool done3 = false;
std::condition_variable cv3;
EchoRequest request3;
request3.set_message("Hello locked world2.");
EchoResponse response3;
ClientContext cli_ctx3;
std::unique_lock<std::mutex> l3(mu3);
stub_->experimental_async()->Echo(
&cli_ctx3, &request3, &response3,
[&mu3, &cv3, &done3, &request3, &response3](Status s3) {
std::lock_guard<std::mutex> l(mu3);
EXPECT_TRUE(s3.ok());
EXPECT_EQ(request3.message(), response3.message());
done3 = true;
cv3.notify_all();
});
done2 = true;
cv2.notify_all();
// Wait for inner most rpc to return.
while (!done3) {
cv3.wait(l3);
}
});
// Wait for second rpc to return.
while (!done2) {
cv2.wait(l2);
}
done1 = true;
cv1.notify_all();
});
}
std::unique_lock<std::mutex> l1(mu1);
while (!done1) {
cv1.wait(l1);
}
}
TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) {
MAYBE_SKIP_TEST;
ResetStub();

Loading…
Cancel
Save