|
|
|
@ -34,6 +34,7 @@ |
|
|
|
|
#include "test/core/util/test_config.h" |
|
|
|
|
#include "test/cpp/end2end/test_service_impl.h" |
|
|
|
|
#include "test/cpp/util/byte_buffer_proto_helper.h" |
|
|
|
|
#include "test/cpp/util/string_ref_helper.h" |
|
|
|
|
|
|
|
|
|
#include <gtest/gtest.h> |
|
|
|
|
|
|
|
|
@ -41,6 +42,44 @@ namespace grpc { |
|
|
|
|
namespace testing { |
|
|
|
|
namespace { |
|
|
|
|
|
|
|
|
|
class EchoTestServiceStreamingImpl : public EchoTestService::Service { |
|
|
|
|
public: |
|
|
|
|
~EchoTestServiceStreamingImpl() override {} |
|
|
|
|
|
|
|
|
|
Status BidiStream( |
|
|
|
|
ServerContext* context, |
|
|
|
|
grpc::ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { |
|
|
|
|
EchoRequest req; |
|
|
|
|
EchoResponse resp; |
|
|
|
|
auto client_metadata = context->client_metadata(); |
|
|
|
|
for (const auto& pair : client_metadata) { |
|
|
|
|
context->AddTrailingMetadata(ToString(pair.first), ToString(pair.second)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
while (stream->Read(&req)) { |
|
|
|
|
resp.set_message(req.message()); |
|
|
|
|
stream->Write(resp, grpc::WriteOptions()); |
|
|
|
|
} |
|
|
|
|
return Status::OK; |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class ClientInterceptorsStreamingEnd2EndTest : public ::testing::Test { |
|
|
|
|
protected: |
|
|
|
|
ClientInterceptorsStreamingEnd2EndTest() { |
|
|
|
|
int port = grpc_pick_unused_port_or_die(); |
|
|
|
|
|
|
|
|
|
ServerBuilder builder; |
|
|
|
|
server_address_ = "localhost:" + std::to_string(port); |
|
|
|
|
builder.AddListeningPort(server_address_, InsecureServerCredentials()); |
|
|
|
|
builder.RegisterService(&service_); |
|
|
|
|
server_ = builder.BuildAndStart(); |
|
|
|
|
} |
|
|
|
|
std::string server_address_; |
|
|
|
|
EchoTestServiceStreamingImpl service_; |
|
|
|
|
std::unique_ptr<Server> server_; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
class ClientInterceptorsEnd2endTest : public ::testing::Test { |
|
|
|
|
protected: |
|
|
|
|
ClientInterceptorsEnd2endTest() { |
|
|
|
@ -115,7 +154,7 @@ class HijackingInterceptor : public experimental::Interceptor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
virtual void Intercept(experimental::InterceptorBatchMethods* methods) { |
|
|
|
|
gpr_log(GPR_ERROR, "ran this"); |
|
|
|
|
// gpr_log(GPR_ERROR, "ran this");
|
|
|
|
|
bool hijack = false; |
|
|
|
|
if (methods->QueryInterceptionHookPoint( |
|
|
|
|
experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { |
|
|
|
@ -219,7 +258,7 @@ class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
virtual void Intercept(experimental::InterceptorBatchMethods* methods) { |
|
|
|
|
gpr_log(GPR_ERROR, "ran this"); |
|
|
|
|
// gpr_log(GPR_ERROR, "ran this");
|
|
|
|
|
if (methods->QueryInterceptionHookPoint( |
|
|
|
|
experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { |
|
|
|
|
auto* map = methods->GetSendInitialMetadata(); |
|
|
|
@ -331,14 +370,10 @@ class HijackingInterceptorMakesAnotherCallFactory |
|
|
|
|
|
|
|
|
|
class LoggingInterceptor : public experimental::Interceptor { |
|
|
|
|
public: |
|
|
|
|
LoggingInterceptor(experimental::ClientRpcInfo* info) { |
|
|
|
|
info_ = info; |
|
|
|
|
// Make sure it is the right method
|
|
|
|
|
EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0); |
|
|
|
|
} |
|
|
|
|
LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; } |
|
|
|
|
|
|
|
|
|
virtual void Intercept(experimental::InterceptorBatchMethods* methods) { |
|
|
|
|
gpr_log(GPR_ERROR, "ran this"); |
|
|
|
|
// gpr_log(GPR_ERROR, "ran this");
|
|
|
|
|
if (methods->QueryInterceptionHookPoint( |
|
|
|
|
experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) { |
|
|
|
|
auto* map = methods->GetSendInitialMetadata(); |
|
|
|
@ -354,7 +389,7 @@ class LoggingInterceptor : public experimental::Interceptor { |
|
|
|
|
auto* buffer = methods->GetSendMessage(); |
|
|
|
|
auto copied_buffer = *buffer; |
|
|
|
|
SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req); |
|
|
|
|
EXPECT_EQ(req.message(), "Hello"); |
|
|
|
|
EXPECT_TRUE(req.message().find("Hello") == 0); |
|
|
|
|
} |
|
|
|
|
if (methods->QueryInterceptionHookPoint( |
|
|
|
|
experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) { |
|
|
|
@ -370,7 +405,7 @@ class LoggingInterceptor : public experimental::Interceptor { |
|
|
|
|
experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) { |
|
|
|
|
EchoResponse* resp = |
|
|
|
|
static_cast<EchoResponse*>(methods->GetRecvMessage()); |
|
|
|
|
EXPECT_EQ(resp->message(), "Hello"); |
|
|
|
|
EXPECT_TRUE(resp->message().find("Hello") == 0); |
|
|
|
|
} |
|
|
|
|
if (methods->QueryInterceptionHookPoint( |
|
|
|
|
experimental::InterceptionHookPoints::POST_RECV_STATUS)) { |
|
|
|
@ -402,7 +437,7 @@ class LoggingInterceptorFactory |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
void MakeCall(const std::shared_ptr<Channel> channel) { |
|
|
|
|
void MakeCall(const std::shared_ptr<Channel>& channel) { |
|
|
|
|
auto stub = grpc::testing::EchoTestService::NewStub(channel); |
|
|
|
|
ClientContext ctx; |
|
|
|
|
EchoRequest req; |
|
|
|
@ -415,7 +450,7 @@ void MakeCall(const std::shared_ptr<Channel> channel) { |
|
|
|
|
EXPECT_EQ(resp.message(), "Hello"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MakeCallbackCall(const std::shared_ptr<Channel> channel) { |
|
|
|
|
void MakeCallbackCall(const std::shared_ptr<Channel>& channel) { |
|
|
|
|
auto stub = grpc::testing::EchoTestService::NewStub(channel); |
|
|
|
|
ClientContext ctx; |
|
|
|
|
EchoRequest req; |
|
|
|
@ -428,7 +463,7 @@ void MakeCallbackCall(const std::shared_ptr<Channel> channel) { |
|
|
|
|
EchoResponse resp; |
|
|
|
|
stub->experimental_async()->Echo(&ctx, &req, &resp, |
|
|
|
|
[&resp, &mu, &done, &cv](Status s) { |
|
|
|
|
gpr_log(GPR_ERROR, "got the callback"); |
|
|
|
|
// gpr_log(GPR_ERROR, "got the callback");
|
|
|
|
|
EXPECT_EQ(s.ok(), true); |
|
|
|
|
EXPECT_EQ(resp.message(), "Hello"); |
|
|
|
|
std::lock_guard<std::mutex> l(mu); |
|
|
|
@ -441,6 +476,24 @@ void MakeCallbackCall(const std::shared_ptr<Channel> channel) { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MakeStreamingCall(const std::shared_ptr<Channel>& channel) { |
|
|
|
|
auto stub = grpc::testing::EchoTestService::NewStub(channel); |
|
|
|
|
ClientContext ctx; |
|
|
|
|
EchoRequest req; |
|
|
|
|
EchoResponse resp; |
|
|
|
|
ctx.AddMetadata("testkey", "testvalue"); |
|
|
|
|
auto stream = stub->BidiStream(&ctx); |
|
|
|
|
for (auto i = 0; i < 10; i++) { |
|
|
|
|
req.set_message("Hello" + std::to_string(i)); |
|
|
|
|
stream->Write(req); |
|
|
|
|
stream->Read(&resp); |
|
|
|
|
EXPECT_EQ(req.message(), resp.message()); |
|
|
|
|
} |
|
|
|
|
ASSERT_TRUE(stream->WritesDone()); |
|
|
|
|
Status s = stream->Finish(); |
|
|
|
|
EXPECT_EQ(s.ok(), true); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) { |
|
|
|
|
ChannelArguments args; |
|
|
|
|
DummyInterceptor::Reset(); |
|
|
|
@ -560,6 +613,27 @@ TEST_F(ClientInterceptorsEnd2endTest, |
|
|
|
|
EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
TEST_F(ClientInterceptorsStreamingEnd2EndTest, ClientInterceptorLoggingTest) { |
|
|
|
|
ChannelArguments args; |
|
|
|
|
DummyInterceptor::Reset(); |
|
|
|
|
auto creators = std::unique_ptr<std::vector< |
|
|
|
|
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>>( |
|
|
|
|
new std::vector< |
|
|
|
|
std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>()); |
|
|
|
|
creators->push_back(std::unique_ptr<LoggingInterceptorFactory>( |
|
|
|
|
new LoggingInterceptorFactory())); |
|
|
|
|
// Add 20 dummy interceptors
|
|
|
|
|
for (auto i = 0; i < 20; i++) { |
|
|
|
|
creators->push_back(std::unique_ptr<DummyInterceptorFactory>( |
|
|
|
|
new DummyInterceptorFactory())); |
|
|
|
|
} |
|
|
|
|
auto channel = experimental::CreateCustomChannelWithInterceptors( |
|
|
|
|
server_address_, InsecureChannelCredentials(), args, std::move(creators)); |
|
|
|
|
MakeStreamingCall(channel); |
|
|
|
|
// Make sure all 20 dummy interceptors were run
|
|
|
|
|
EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
} // namespace testing
|
|
|
|
|
} // namespace grpc
|
|
|
|
|