Make use of alarm in test service more robust

pull/21747/head
Vijay Pai 5 years ago
parent 749b50d938
commit 3ade3e84a9
  1. 90
      test/cpp/end2end/test_service_impl.cc
  2. 1
      test/cpp/end2end/test_service_impl.h

@ -19,6 +19,7 @@
#include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/end2end/test_service_impl.h"
#include <grpc/support/log.h> #include <grpc/support/log.h>
#include <grpcpp/alarm.h>
#include <grpcpp/security/credentials.h> #include <grpcpp/security/credentials.h>
#include <grpcpp/server_context.h> #include <grpcpp/server_context.h>
#include <gtest/gtest.h> #include <gtest/gtest.h>
@ -120,7 +121,7 @@ void ServerTryCancel(ServerContext* context) {
void ServerTryCancelNonblocking(experimental::CallbackServerContext* context) { void ServerTryCancelNonblocking(experimental::CallbackServerContext* context) {
EXPECT_FALSE(context->IsCancelled()); EXPECT_FALSE(context->IsCancelled());
context->TryCancel(); context->TryCancel();
gpr_log(GPR_INFO, "Server called TryCancel() to cancel the request"); gpr_log(GPR_INFO, "Server called TryCancelNB() to cancel the request");
} }
} // namespace } // namespace
@ -444,16 +445,20 @@ experimental::ServerUnaryReactor* CallbackTestServiceImpl::Echo(
} }
void StartRpc() { void StartRpc() {
if (req_->has_param() && req_->param().server_sleep_us() > 0) { {
// Set an alarm for that much time std::lock_guard<std::mutex> l(alarm_mu_);
alarm_.experimental().Set( if (req_->has_param() && req_->param().server_sleep_us() > 0 &&
gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC), !dont_alarm_anymore_) {
gpr_time_from_micros(req_->param().server_sleep_us(), // Set an alarm for that much time
GPR_TIMESPAN)), alarm_.experimental().Set(
[this](bool ok) { NonDelayed(ok); }); gpr_time_add(gpr_now(GPR_CLOCK_MONOTONIC),
} else { gpr_time_from_micros(req_->param().server_sleep_us(),
NonDelayed(true); GPR_TIMESPAN)),
[this](bool ok) { NonDelayed(ok); });
return;
}
} }
NonDelayed(true);
} }
void OnSendInitialMetadataDone(bool ok) override { void OnSendInitialMetadataDone(bool ok) override {
EXPECT_TRUE(ok); EXPECT_TRUE(ok);
@ -462,10 +467,12 @@ experimental::ServerUnaryReactor* CallbackTestServiceImpl::Echo(
void OnCancel() override { void OnCancel() override {
EXPECT_TRUE(started_); EXPECT_TRUE(started_);
EXPECT_TRUE(ctx_->IsCancelled()); EXPECT_TRUE(ctx_->IsCancelled());
// do the actual finish in the main handler only but use this as a chance on_cancel_invoked_ = true;
// Do the actual finish in the main handler only but use this as a chance
// to cancel any alarms. // to cancel any alarms.
std::lock_guard<std::mutex> l(alarm_mu_);
alarm_.Cancel(); alarm_.Cancel();
on_cancel_invoked_ = true; dont_alarm_anymore_ = true;
} }
void OnDone() override { void OnDone() override {
if (req_->has_param() && req_->param().echo_metadata_initially()) { if (req_->has_param() && req_->param().echo_metadata_initially()) {
@ -523,12 +530,17 @@ experimental::ServerUnaryReactor* CallbackTestServiceImpl::Echo(
LoopUntilCancelled(req_->param().client_cancel_after_us()); LoopUntilCancelled(req_->param().client_cancel_after_us());
return; return;
} else if (req_->has_param() && req_->param().server_cancel_after_us()) { } else if (req_->has_param() && req_->param().server_cancel_after_us()) {
alarm_.experimental().Set( std::lock_guard<std::mutex> l(alarm_mu_);
gpr_time_add( if (dont_alarm_anymore_) {
gpr_now(GPR_CLOCK_REALTIME), Finish(Status::CANCELLED);
gpr_time_from_micros(req_->param().server_cancel_after_us(), } else {
GPR_TIMESPAN)), alarm_.experimental().Set(
[this](bool) { Finish(Status::CANCELLED); }); gpr_time_add(
gpr_now(GPR_CLOCK_REALTIME),
gpr_time_from_micros(req_->param().server_cancel_after_us(),
GPR_TIMESPAN)),
[this](bool) { Finish(Status::CANCELLED); });
}
return; return;
} else if (!req_->has_param() || !req_->param().skip_cancelled_check()) { } else if (!req_->has_param() || !req_->param().skip_cancelled_check()) {
EXPECT_FALSE(ctx_->IsCancelled()); EXPECT_FALSE(ctx_->IsCancelled());
@ -579,35 +591,43 @@ experimental::ServerUnaryReactor* CallbackTestServiceImpl::Echo(
Finish(Status::OK); Finish(Status::OK);
} }
void LoopUntilCancelled(int loop_delay_us) { void LoopUntilCancelled(int loop_delay_us) {
if (!ctx_->IsCancelled()) { {
alarm_.experimental().Set( std::lock_guard<std::mutex> l(alarm_mu_);
gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), if (!ctx_->IsCancelled()) {
gpr_time_from_micros(loop_delay_us, GPR_TIMESPAN)), // dont_alarm_anymore_ wouldn't be set either since that is only set
[this, loop_delay_us](bool ok) { // in OnCancel
if (!ok) { EXPECT_FALSE(dont_alarm_anymore_);
EXPECT_TRUE(ctx_->IsCancelled()); alarm_.experimental().Set(
} gpr_time_add(gpr_now(GPR_CLOCK_REALTIME),
LoopUntilCancelled(loop_delay_us); gpr_time_from_micros(loop_delay_us, GPR_TIMESPAN)),
}); [this, loop_delay_us](bool ok) {
} else { if (!ok) {
Finish(Status::CANCELLED); EXPECT_TRUE(ctx_->IsCancelled());
}
LoopUntilCancelled(loop_delay_us);
});
return;
}
} }
Finish(Status::CANCELLED);
} }
CallbackTestServiceImpl* const service_; CallbackTestServiceImpl* const service_;
experimental::CallbackServerContext* const ctx_; experimental::CallbackServerContext* const ctx_;
const EchoRequest* const req_; const EchoRequest* const req_;
EchoResponse* const resp_; EchoResponse* const resp_;
Alarm alarm_; std::mutex alarm_mu_;
bool initial_metadata_sent_{false}; bool dont_alarm_anymore_ /* GUARDED_BY(alarm_mu_) */ = false;
bool started_{false}; Alarm alarm_ /* GUARDED_BY(alarm_mu_) */;
bool on_cancel_invoked_{false}; bool initial_metadata_sent_ = false;
bool started_ = false;
bool on_cancel_invoked_ = false;
std::thread async_cancel_check_; std::thread async_cancel_check_;
std::thread rpc_wait_thread_; std::thread rpc_wait_thread_;
}; };
return new Reactor(this, context, request, response); return new Reactor(this, context, request, response);
} } // namespace testing
experimental::ServerUnaryReactor* experimental::ServerUnaryReactor*
CallbackTestServiceImpl::CheckClientInitialMetadata( CallbackTestServiceImpl::CheckClientInitialMetadata(

@ -23,7 +23,6 @@
#include <mutex> #include <mutex>
#include <grpc/grpc.h> #include <grpc/grpc.h>
#include <grpcpp/alarm.h>
#include <grpcpp/server_context.h> #include <grpcpp/server_context.h>
#include "src/proto/grpc/testing/echo.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h"

Loading…
Cancel
Save