2020#include " trpc/client/make_client_context.h"
2121#include " trpc/client/service_proxy_option_setter.h"
2222#include " trpc/codec/codec_manager.h"
23+ #include " trpc/filter/filter_manager.h"
2324#include " trpc/future/future_utility.h"
2425#include " trpc/naming/trpc_naming_registry.h"
2526#include " trpc/proto/testing/helloworld.pb.h"
2829
2930namespace trpc ::testing {
3031
32+ class TestClientFilter : public trpc ::MessageClientFilter {
33+ public:
34+ std::string Name () override { return " test_filter" ; }
35+
36+ std::vector<trpc::FilterPoint> GetFilterPoint () override {
37+ std::vector<FilterPoint> points = {trpc::FilterPoint::CLIENT_PRE_RPC_INVOKE ,
38+ trpc::FilterPoint::CLIENT_POST_RPC_INVOKE };
39+ return points;
40+ }
41+
42+ void operator ()(trpc::FilterStatus& status, trpc::FilterPoint point, const trpc::ClientContextPtr& context) override {
43+ status = FilterStatus::CONTINUE ;
44+ // record the status upon entering the CLIENT_POST_RPC_INVOKE point
45+ if (point == FilterPoint::CLIENT_POST_RPC_INVOKE ) {
46+ status_ = context->GetStatus ();
47+ }
48+ }
49+
50+ void SetStatus (trpc::Status&& status) { status_ = std::move (status); }
51+
52+ Status GetStatus () { return status_; }
53+
54+ private:
55+ trpc::Status status_;
56+ };
57+
3158class HttpServiceProxyTest : public ::testing::Test {
3259 public:
3360 static void SetUpTestCase () {
@@ -46,6 +73,10 @@ class HttpServiceProxyTest : public ::testing::Test {
4673 codec::Init ();
4774 serialization::Init ();
4875 naming::Init ();
76+
77+ filter_ = std::make_shared<TestClientFilter>();
78+ trpc::FilterManager::GetInstance ()->AddMessageClientFilter (filter_);
79+ option_->service_filters .push_back (filter_->Name ());
4980 }
5081
5182 static void TearDownTestCase () {
@@ -58,9 +89,11 @@ class HttpServiceProxyTest : public ::testing::Test {
5889
5990 protected:
6091 static std::shared_ptr<ServiceProxyOption> option_;
92+ static std::shared_ptr<TestClientFilter> filter_;
6193};
6294
6395std::shared_ptr<ServiceProxyOption> HttpServiceProxyTest::option_ = std::make_shared<ServiceProxyOption>();
96+ std::shared_ptr<TestClientFilter> HttpServiceProxyTest::filter_;
6497
6598class MockHttpServiceProxy : public trpc ::http::HttpServiceProxy {
6699 public:
@@ -3891,4 +3924,107 @@ TEST_F(HttpServiceProxyTest, ConstructPBRequest) {
38913924 }
38923925}
38933926
3927+ TEST_F (HttpServiceProxyTest, FilterExecWhenSuccess) {
3928+ auto proxy = std::make_shared<MockHttpServiceProxy>();
3929+ proxy->SetMockServiceProxyOption (option_);
3930+ auto ctx = MakeClientContext (proxy);
3931+ ctx->SetStatus (Status ());
3932+ ctx->SetAddr (" 127.0.0.1" , 10002 );
3933+
3934+ trpc::http::HttpResponse reply;
3935+ reply.SetVersion (" 1.1" );
3936+ reply.SetStatus (trpc::http::HttpResponse::StatusCode::kOk );
3937+ proxy->SetReplyError (false );
3938+ proxy->SetReply (reply);
3939+
3940+ std::string rspStr;
3941+ filter_->SetStatus (Status ());
3942+ auto st = proxy->GetString (ctx, " http://127.0.0.1:10002/hello" , &rspStr);
3943+ ASSERT_TRUE (st.OK ());
3944+ // verify that the status is OK upon entering the RPC post-filter point
3945+ ASSERT_TRUE (filter_->GetStatus ().OK ());
3946+
3947+ proxy->SetReplyError (false );
3948+ proxy->SetReply (reply);
3949+ ctx = MakeClientContext (proxy);
3950+ ctx->SetStatus (Status ());
3951+ ctx->SetAddr (" 127.0.0.1" , 10002 );
3952+ filter_->SetStatus (Status ());
3953+ auto async_get_string_fut =
3954+ proxy->AsyncGetString (ctx, " http://127.0.0.1:10002/hello" ).Then ([](Future<std::string>&& future) {
3955+ EXPECT_TRUE (future.IsReady ());
3956+ // verify that the status is OK upon entering the RPC post-filter point
3957+ EXPECT_TRUE (filter_->GetStatus ().OK ());
3958+
3959+ return MakeReadyFuture<>();
3960+ });
3961+ future::BlockingGet (std::move (async_get_string_fut));
3962+ }
3963+
3964+ TEST_F (HttpServiceProxyTest, FilterExecWithFrameworkErr) {
3965+ auto proxy = std::make_shared<MockHttpServiceProxy>();
3966+ proxy->SetMockServiceProxyOption (option_);
3967+ auto ctx = MakeClientContext (proxy);
3968+ ctx->SetStatus (Status ());
3969+ ctx->SetAddr (" 127.0.0.1" , 10002 );
3970+
3971+ proxy->SetReplyError (true );
3972+ std::string rspStr;
3973+ filter_->SetStatus (Status ());
3974+ auto st = proxy->GetString (ctx, " http://127.0.0.1:10002/hello" , &rspStr);
3975+ ASSERT_FALSE (st.OK ());
3976+ // verify that the status is already failed upon entering the RPC post-filter point
3977+ ASSERT_FALSE (filter_->GetStatus ().OK ());
3978+
3979+ proxy->SetReplyError (true );
3980+ ctx = MakeClientContext (proxy);
3981+ ctx->SetStatus (Status ());
3982+ ctx->SetAddr (" 127.0.0.1" , 10002 );
3983+ filter_->SetStatus (Status ());
3984+ auto async_get_string_fut =
3985+ proxy->AsyncGetString (ctx, " http://127.0.0.1:10002/hello" ).Then ([](Future<std::string>&& future) {
3986+ EXPECT_TRUE (future.IsFailed ());
3987+ // verify that the status is already failed upon entering the RPC post-filter point
3988+ EXPECT_FALSE (filter_->GetStatus ().OK ());
3989+ return MakeReadyFuture<>();
3990+ });
3991+ future::BlockingGet (std::move (async_get_string_fut));
3992+ }
3993+
3994+ TEST_F (HttpServiceProxyTest, FilterExecWithHttpErr) {
3995+ auto proxy = std::make_shared<MockHttpServiceProxy>();
3996+ proxy->SetMockServiceProxyOption (option_);
3997+ auto ctx = MakeClientContext (proxy);
3998+ ctx->SetStatus (Status ());
3999+ ctx->SetAddr (" 127.0.0.1" , 10002 );
4000+
4001+ trpc::http::HttpResponse reply;
4002+ reply.SetVersion (" 1.1" );
4003+ reply.SetStatus (trpc::http::HttpResponse::StatusCode::kForbidden );
4004+ proxy->SetReplyError (false );
4005+ proxy->SetReply (reply);
4006+
4007+ std::string rspStr;
4008+ filter_->SetStatus (Status ());
4009+ auto st = proxy->GetString (ctx, " http://127.0.0.1:10002/hello" , &rspStr);
4010+ ASSERT_FALSE (st.OK ());
4011+ // verify that the status is already failed upon entering the RPC post-filter point
4012+ ASSERT_FALSE (filter_->GetStatus ().OK ());
4013+
4014+ proxy->SetReplyError (false );
4015+ proxy->SetReply (reply);
4016+ ctx = MakeClientContext (proxy);
4017+ ctx->SetStatus (Status ());
4018+ ctx->SetAddr (" 127.0.0.1" , 10002 );
4019+ filter_->SetStatus (Status ());
4020+ auto async_get_string_fut =
4021+ proxy->AsyncGetString (ctx, " http://127.0.0.1:10002/hello" ).Then ([](Future<std::string>&& future) {
4022+ EXPECT_TRUE (future.IsFailed ());
4023+ // verify that the status is already failed upon entering the RPC post-filter point
4024+ EXPECT_FALSE (filter_->GetStatus ().OK ());
4025+ return MakeReadyFuture<>();
4026+ });
4027+ future::BlockingGet (std::move (async_get_string_fut));
4028+ }
4029+
38944030} // namespace trpc::testing
0 commit comments