|
|
@ -83,10 +83,30 @@ void MaybeEchoDeadline(ServerContext* context, const EchoRequest* request, |
|
|
|
|
|
|
|
|
|
|
|
class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { |
|
|
|
class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { |
|
|
|
public: |
|
|
|
public: |
|
|
|
|
|
|
|
TestServiceImpl() : signal_client_(false) {} |
|
|
|
|
|
|
|
|
|
|
|
Status Echo(ServerContext* context, const EchoRequest* request, |
|
|
|
Status Echo(ServerContext* context, const EchoRequest* request, |
|
|
|
EchoResponse* response) GRPC_OVERRIDE { |
|
|
|
EchoResponse* response) GRPC_OVERRIDE { |
|
|
|
response->set_message(request->message()); |
|
|
|
response->set_message(request->message()); |
|
|
|
MaybeEchoDeadline(context, request, response); |
|
|
|
MaybeEchoDeadline(context, request, response); |
|
|
|
|
|
|
|
if (request->has_param() && request->param().client_cancel_after_us()) { |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> lock(mu_); |
|
|
|
|
|
|
|
signal_client_ = true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
while (!context->IsCancelled()) { |
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds( |
|
|
|
|
|
|
|
request->param().client_cancel_after_us())); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return Status::Cancelled; |
|
|
|
|
|
|
|
} else if (request->has_param() && |
|
|
|
|
|
|
|
request->param().server_cancel_after_us()) { |
|
|
|
|
|
|
|
std::this_thread::sleep_for( |
|
|
|
|
|
|
|
std::chrono::microseconds(request->param().server_cancel_after_us())); |
|
|
|
|
|
|
|
return Status::Cancelled; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
EXPECT_FALSE(context->IsCancelled()); |
|
|
|
|
|
|
|
} |
|
|
|
return Status::OK; |
|
|
|
return Status::OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -130,6 +150,15 @@ class TestServiceImpl : public ::grpc::cpp::test::util::TestService::Service { |
|
|
|
} |
|
|
|
} |
|
|
|
return Status::OK; |
|
|
|
return Status::OK; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool signal_client() { |
|
|
|
|
|
|
|
std::unique_lock<std::mutex> lock(mu_); |
|
|
|
|
|
|
|
return signal_client_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
|
|
|
bool signal_client_; |
|
|
|
|
|
|
|
std::mutex mu_; |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
class TestServiceImplDupPkg |
|
|
|
class TestServiceImplDupPkg |
|
|
@ -151,7 +180,8 @@ class End2endTest : public ::testing::Test { |
|
|
|
server_address_ << "localhost:" << port; |
|
|
|
server_address_ << "localhost:" << port; |
|
|
|
// Setup server
|
|
|
|
// Setup server
|
|
|
|
ServerBuilder builder; |
|
|
|
ServerBuilder builder; |
|
|
|
builder.AddListeningPort(server_address_.str(), InsecureServerCredentials()); |
|
|
|
builder.AddListeningPort(server_address_.str(), |
|
|
|
|
|
|
|
InsecureServerCredentials()); |
|
|
|
builder.RegisterService(&service_); |
|
|
|
builder.RegisterService(&service_); |
|
|
|
builder.RegisterService(&dup_pkg_service_); |
|
|
|
builder.RegisterService(&dup_pkg_service_); |
|
|
|
builder.SetThreadPool(&thread_pool_); |
|
|
|
builder.SetThreadPool(&thread_pool_); |
|
|
@ -423,6 +453,44 @@ TEST_F(End2endTest, BadCredentials) { |
|
|
|
EXPECT_EQ("Rpc sent on a lame channel.", s.details()); |
|
|
|
EXPECT_EQ("Rpc sent on a lame channel.", s.details()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CancelRpc(ClientContext* context, int delay_us, TestServiceImpl* service) { |
|
|
|
|
|
|
|
std::this_thread::sleep_for(std::chrono::microseconds(delay_us)); |
|
|
|
|
|
|
|
while (!service->signal_client()) { |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
context->TryCancel(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Client cancels rpc after 10ms
|
|
|
|
|
|
|
|
TEST_F(End2endTest, ClientCancelsRpc) { |
|
|
|
|
|
|
|
ResetStub(); |
|
|
|
|
|
|
|
EchoRequest request; |
|
|
|
|
|
|
|
EchoResponse response; |
|
|
|
|
|
|
|
request.set_message("Hello"); |
|
|
|
|
|
|
|
const int kCancelDelayUs = 10 * 1000; |
|
|
|
|
|
|
|
request.mutable_param()->set_client_cancel_after_us(kCancelDelayUs); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClientContext context; |
|
|
|
|
|
|
|
std::thread cancel_thread(CancelRpc, &context, kCancelDelayUs, &service_); |
|
|
|
|
|
|
|
Status s = stub_->Echo(&context, request, &response); |
|
|
|
|
|
|
|
cancel_thread.join(); |
|
|
|
|
|
|
|
EXPECT_EQ(StatusCode::CANCELLED, s.code()); |
|
|
|
|
|
|
|
EXPECT_TRUE(s.details().empty()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Server cancels rpc after 1ms
|
|
|
|
|
|
|
|
TEST_F(End2endTest, ServerCancelsRpc) { |
|
|
|
|
|
|
|
ResetStub(); |
|
|
|
|
|
|
|
EchoRequest request; |
|
|
|
|
|
|
|
EchoResponse response; |
|
|
|
|
|
|
|
request.set_message("Hello"); |
|
|
|
|
|
|
|
request.mutable_param()->set_server_cancel_after_us(1000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ClientContext context; |
|
|
|
|
|
|
|
Status s = stub_->Echo(&context, request, &response); |
|
|
|
|
|
|
|
EXPECT_EQ(StatusCode::CANCELLED, s.code()); |
|
|
|
|
|
|
|
EXPECT_TRUE(s.details().empty()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} // namespace testing
|
|
|
|
} // namespace testing
|
|
|
|
} // namespace grpc
|
|
|
|
} // namespace grpc
|
|
|
|
|
|
|
|
|
|
|
|