xref: /aosp_15_r20/external/grpc-grpc/test/cpp/end2end/mock_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #include <climits>
20*cc02d7e2SAndroid Build Coastguard Worker #include <iostream>
21*cc02d7e2SAndroid Build Coastguard Worker 
22*cc02d7e2SAndroid Build Coastguard Worker #include <gmock/gmock.h>
23*cc02d7e2SAndroid Build Coastguard Worker #include <gtest/gtest.h>
24*cc02d7e2SAndroid Build Coastguard Worker 
25*cc02d7e2SAndroid Build Coastguard Worker #include "absl/types/optional.h"
26*cc02d7e2SAndroid Build Coastguard Worker 
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/grpc.h>
28*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
29*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/time.h>
30*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/channel.h>
31*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/client_context.h>
32*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/create_channel.h>
33*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server.h>
34*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server_builder.h>
35*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server_context.h>
36*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/test/default_reactor_test_peer.h>
37*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/test/mock_stream.h>
38*cc02d7e2SAndroid Build Coastguard Worker 
39*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/crash.h"
40*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
41*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/echo.grpc.pb.h"
42*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
43*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/port.h"
44*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/test_config.h"
45*cc02d7e2SAndroid Build Coastguard Worker 
46*cc02d7e2SAndroid Build Coastguard Worker using std::vector;
47*cc02d7e2SAndroid Build Coastguard Worker using ::testing::_;
48*cc02d7e2SAndroid Build Coastguard Worker using ::testing::AtLeast;
49*cc02d7e2SAndroid Build Coastguard Worker using ::testing::DoAll;
50*cc02d7e2SAndroid Build Coastguard Worker using ::testing::Return;
51*cc02d7e2SAndroid Build Coastguard Worker using ::testing::SaveArg;
52*cc02d7e2SAndroid Build Coastguard Worker using ::testing::SetArgPointee;
53*cc02d7e2SAndroid Build Coastguard Worker using ::testing::WithArg;
54*cc02d7e2SAndroid Build Coastguard Worker 
55*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
56*cc02d7e2SAndroid Build Coastguard Worker namespace testing {
57*cc02d7e2SAndroid Build Coastguard Worker 
58*cc02d7e2SAndroid Build Coastguard Worker namespace {
59*cc02d7e2SAndroid Build Coastguard Worker class FakeClient {
60*cc02d7e2SAndroid Build Coastguard Worker  public:
FakeClient(EchoTestService::StubInterface * stub)61*cc02d7e2SAndroid Build Coastguard Worker   explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {}
62*cc02d7e2SAndroid Build Coastguard Worker 
DoEcho()63*cc02d7e2SAndroid Build Coastguard Worker   void DoEcho() {
64*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
65*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
66*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
67*cc02d7e2SAndroid Build Coastguard Worker     request.set_message("hello world");
68*cc02d7e2SAndroid Build Coastguard Worker     Status s = stub_->Echo(&context, request, &response);
69*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(request.message(), response.message());
70*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(s.ok());
71*cc02d7e2SAndroid Build Coastguard Worker   }
72*cc02d7e2SAndroid Build Coastguard Worker 
DoRequestStream()73*cc02d7e2SAndroid Build Coastguard Worker   void DoRequestStream() {
74*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
75*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
76*cc02d7e2SAndroid Build Coastguard Worker 
77*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
78*cc02d7e2SAndroid Build Coastguard Worker     std::string msg("hello");
79*cc02d7e2SAndroid Build Coastguard Worker     std::string exp(msg);
80*cc02d7e2SAndroid Build Coastguard Worker 
81*cc02d7e2SAndroid Build Coastguard Worker     std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream =
82*cc02d7e2SAndroid Build Coastguard Worker         stub_->RequestStream(&context, &response);
83*cc02d7e2SAndroid Build Coastguard Worker 
84*cc02d7e2SAndroid Build Coastguard Worker     request.set_message(msg);
85*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(cstream->Write(request));
86*cc02d7e2SAndroid Build Coastguard Worker 
87*cc02d7e2SAndroid Build Coastguard Worker     msg = ", world";
88*cc02d7e2SAndroid Build Coastguard Worker     request.set_message(msg);
89*cc02d7e2SAndroid Build Coastguard Worker     exp.append(msg);
90*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(cstream->Write(request));
91*cc02d7e2SAndroid Build Coastguard Worker 
92*cc02d7e2SAndroid Build Coastguard Worker     cstream->WritesDone();
93*cc02d7e2SAndroid Build Coastguard Worker     Status s = cstream->Finish();
94*cc02d7e2SAndroid Build Coastguard Worker 
95*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(exp, response.message());
96*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(s.ok());
97*cc02d7e2SAndroid Build Coastguard Worker   }
98*cc02d7e2SAndroid Build Coastguard Worker 
DoResponseStream()99*cc02d7e2SAndroid Build Coastguard Worker   void DoResponseStream() {
100*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
101*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
102*cc02d7e2SAndroid Build Coastguard Worker     request.set_message("hello world");
103*cc02d7e2SAndroid Build Coastguard Worker 
104*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
105*cc02d7e2SAndroid Build Coastguard Worker     std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream =
106*cc02d7e2SAndroid Build Coastguard Worker         stub_->ResponseStream(&context, request);
107*cc02d7e2SAndroid Build Coastguard Worker 
108*cc02d7e2SAndroid Build Coastguard Worker     std::string exp;
109*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(cstream->Read(&response));
110*cc02d7e2SAndroid Build Coastguard Worker     exp.append(response.message() + " ");
111*cc02d7e2SAndroid Build Coastguard Worker 
112*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(cstream->Read(&response));
113*cc02d7e2SAndroid Build Coastguard Worker     exp.append(response.message());
114*cc02d7e2SAndroid Build Coastguard Worker 
115*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_FALSE(cstream->Read(&response));
116*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(request.message(), exp);
117*cc02d7e2SAndroid Build Coastguard Worker 
118*cc02d7e2SAndroid Build Coastguard Worker     Status s = cstream->Finish();
119*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(s.ok());
120*cc02d7e2SAndroid Build Coastguard Worker   }
121*cc02d7e2SAndroid Build Coastguard Worker 
DoBidiStream()122*cc02d7e2SAndroid Build Coastguard Worker   void DoBidiStream() {
123*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
124*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
125*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
126*cc02d7e2SAndroid Build Coastguard Worker     std::string msg("hello");
127*cc02d7e2SAndroid Build Coastguard Worker 
128*cc02d7e2SAndroid Build Coastguard Worker     std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
129*cc02d7e2SAndroid Build Coastguard Worker         stream = stub_->BidiStream(&context);
130*cc02d7e2SAndroid Build Coastguard Worker 
131*cc02d7e2SAndroid Build Coastguard Worker     request.set_message(msg + "0");
132*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Write(request));
133*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Read(&response));
134*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(response.message(), request.message());
135*cc02d7e2SAndroid Build Coastguard Worker 
136*cc02d7e2SAndroid Build Coastguard Worker     request.set_message(msg + "1");
137*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Write(request));
138*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Read(&response));
139*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(response.message(), request.message());
140*cc02d7e2SAndroid Build Coastguard Worker 
141*cc02d7e2SAndroid Build Coastguard Worker     request.set_message(msg + "2");
142*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Write(request));
143*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(stream->Read(&response));
144*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_EQ(response.message(), request.message());
145*cc02d7e2SAndroid Build Coastguard Worker 
146*cc02d7e2SAndroid Build Coastguard Worker     stream->WritesDone();
147*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_FALSE(stream->Read(&response));
148*cc02d7e2SAndroid Build Coastguard Worker 
149*cc02d7e2SAndroid Build Coastguard Worker     Status s = stream->Finish();
150*cc02d7e2SAndroid Build Coastguard Worker     EXPECT_TRUE(s.ok());
151*cc02d7e2SAndroid Build Coastguard Worker   }
152*cc02d7e2SAndroid Build Coastguard Worker 
ResetStub(EchoTestService::StubInterface * stub)153*cc02d7e2SAndroid Build Coastguard Worker   void ResetStub(EchoTestService::StubInterface* stub) { stub_ = stub; }
154*cc02d7e2SAndroid Build Coastguard Worker 
155*cc02d7e2SAndroid Build Coastguard Worker  private:
156*cc02d7e2SAndroid Build Coastguard Worker   EchoTestService::StubInterface* stub_;
157*cc02d7e2SAndroid Build Coastguard Worker };
158*cc02d7e2SAndroid Build Coastguard Worker 
159*cc02d7e2SAndroid Build Coastguard Worker class CallbackTestServiceImpl : public EchoTestService::CallbackService {
160*cc02d7e2SAndroid Build Coastguard Worker  public:
Echo(CallbackServerContext * context,const EchoRequest * request,EchoResponse * response)161*cc02d7e2SAndroid Build Coastguard Worker   ServerUnaryReactor* Echo(CallbackServerContext* context,
162*cc02d7e2SAndroid Build Coastguard Worker                            const EchoRequest* request,
163*cc02d7e2SAndroid Build Coastguard Worker                            EchoResponse* response) override {
164*cc02d7e2SAndroid Build Coastguard Worker     // Make the mock service explicitly treat empty input messages as invalid
165*cc02d7e2SAndroid Build Coastguard Worker     // arguments so that we can test various results of status. In general, a
166*cc02d7e2SAndroid Build Coastguard Worker     // mocked service should just use the original service methods, but we are
167*cc02d7e2SAndroid Build Coastguard Worker     // adding this variance in Status return value just to improve coverage in
168*cc02d7e2SAndroid Build Coastguard Worker     // this test.
169*cc02d7e2SAndroid Build Coastguard Worker     auto* reactor = context->DefaultReactor();
170*cc02d7e2SAndroid Build Coastguard Worker     if (request->message().length() > 0) {
171*cc02d7e2SAndroid Build Coastguard Worker       response->set_message(request->message());
172*cc02d7e2SAndroid Build Coastguard Worker       reactor->Finish(Status::OK);
173*cc02d7e2SAndroid Build Coastguard Worker     } else {
174*cc02d7e2SAndroid Build Coastguard Worker       reactor->Finish(Status(StatusCode::INVALID_ARGUMENT, "Invalid request"));
175*cc02d7e2SAndroid Build Coastguard Worker     }
176*cc02d7e2SAndroid Build Coastguard Worker     return reactor;
177*cc02d7e2SAndroid Build Coastguard Worker   }
178*cc02d7e2SAndroid Build Coastguard Worker };
179*cc02d7e2SAndroid Build Coastguard Worker 
180*cc02d7e2SAndroid Build Coastguard Worker class MockCallbackTest : public ::testing::Test {
181*cc02d7e2SAndroid Build Coastguard Worker  protected:
182*cc02d7e2SAndroid Build Coastguard Worker   CallbackTestServiceImpl service_;
183*cc02d7e2SAndroid Build Coastguard Worker   ServerContext context_;
184*cc02d7e2SAndroid Build Coastguard Worker };
185*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockCallbackTest,MockedCallSucceedsWithWait)186*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockCallbackTest, MockedCallSucceedsWithWait) {
187*cc02d7e2SAndroid Build Coastguard Worker   CallbackServerContext ctx;
188*cc02d7e2SAndroid Build Coastguard Worker   EchoRequest req;
189*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp;
190*cc02d7e2SAndroid Build Coastguard Worker   struct {
191*cc02d7e2SAndroid Build Coastguard Worker     grpc::internal::Mutex mu;
192*cc02d7e2SAndroid Build Coastguard Worker     grpc::internal::CondVar cv;
193*cc02d7e2SAndroid Build Coastguard Worker     absl::optional<grpc::Status> ABSL_GUARDED_BY(mu) status;
194*cc02d7e2SAndroid Build Coastguard Worker   } status;
195*cc02d7e2SAndroid Build Coastguard Worker   DefaultReactorTestPeer peer(&ctx, [&](grpc::Status s) {
196*cc02d7e2SAndroid Build Coastguard Worker     grpc::internal::MutexLock l(&status.mu);
197*cc02d7e2SAndroid Build Coastguard Worker     status.status = std::move(s);
198*cc02d7e2SAndroid Build Coastguard Worker     status.cv.Signal();
199*cc02d7e2SAndroid Build Coastguard Worker   });
200*cc02d7e2SAndroid Build Coastguard Worker 
201*cc02d7e2SAndroid Build Coastguard Worker   req.set_message("mock 1");
202*cc02d7e2SAndroid Build Coastguard Worker   auto* reactor = service_.Echo(&ctx, &req, &resp);
203*cc02d7e2SAndroid Build Coastguard Worker 
204*cc02d7e2SAndroid Build Coastguard Worker   grpc::internal::MutexLock l(&status.mu);
205*cc02d7e2SAndroid Build Coastguard Worker   while (!status.status.has_value()) {
206*cc02d7e2SAndroid Build Coastguard Worker     status.cv.Wait(&status.mu);
207*cc02d7e2SAndroid Build Coastguard Worker   }
208*cc02d7e2SAndroid Build Coastguard Worker 
209*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_EQ(reactor, peer.reactor());
210*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(peer.test_status_set());
211*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(peer.test_status().ok());
212*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(status.status.has_value());
213*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(status.status.value().ok());
214*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_EQ(req.message(), resp.message());
215*cc02d7e2SAndroid Build Coastguard Worker }
216*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockCallbackTest,MockedCallSucceeds)217*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockCallbackTest, MockedCallSucceeds) {
218*cc02d7e2SAndroid Build Coastguard Worker   CallbackServerContext ctx;
219*cc02d7e2SAndroid Build Coastguard Worker   EchoRequest req;
220*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp;
221*cc02d7e2SAndroid Build Coastguard Worker   DefaultReactorTestPeer peer(&ctx);
222*cc02d7e2SAndroid Build Coastguard Worker 
223*cc02d7e2SAndroid Build Coastguard Worker   req.set_message("ha ha, consider yourself mocked.");
224*cc02d7e2SAndroid Build Coastguard Worker   auto* reactor = service_.Echo(&ctx, &req, &resp);
225*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_EQ(reactor, peer.reactor());
226*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(peer.test_status_set());
227*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(peer.test_status().ok());
228*cc02d7e2SAndroid Build Coastguard Worker }
229*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockCallbackTest,MockedCallFails)230*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockCallbackTest, MockedCallFails) {
231*cc02d7e2SAndroid Build Coastguard Worker   CallbackServerContext ctx;
232*cc02d7e2SAndroid Build Coastguard Worker   EchoRequest req;
233*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp;
234*cc02d7e2SAndroid Build Coastguard Worker   DefaultReactorTestPeer peer(&ctx);
235*cc02d7e2SAndroid Build Coastguard Worker 
236*cc02d7e2SAndroid Build Coastguard Worker   auto* reactor = service_.Echo(&ctx, &req, &resp);
237*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_EQ(reactor, peer.reactor());
238*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_TRUE(peer.test_status_set());
239*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_EQ(peer.test_status().error_code(), StatusCode::INVALID_ARGUMENT);
240*cc02d7e2SAndroid Build Coastguard Worker }
241*cc02d7e2SAndroid Build Coastguard Worker 
242*cc02d7e2SAndroid Build Coastguard Worker class TestServiceImpl : public EchoTestService::Service {
243*cc02d7e2SAndroid Build Coastguard Worker  public:
Echo(ServerContext *,const EchoRequest * request,EchoResponse * response)244*cc02d7e2SAndroid Build Coastguard Worker   Status Echo(ServerContext* /*context*/, const EchoRequest* request,
245*cc02d7e2SAndroid Build Coastguard Worker               EchoResponse* response) override {
246*cc02d7e2SAndroid Build Coastguard Worker     response->set_message(request->message());
247*cc02d7e2SAndroid Build Coastguard Worker     return Status::OK;
248*cc02d7e2SAndroid Build Coastguard Worker   }
249*cc02d7e2SAndroid Build Coastguard Worker 
RequestStream(ServerContext *,ServerReader<EchoRequest> * reader,EchoResponse * response)250*cc02d7e2SAndroid Build Coastguard Worker   Status RequestStream(ServerContext* /*context*/,
251*cc02d7e2SAndroid Build Coastguard Worker                        ServerReader<EchoRequest>* reader,
252*cc02d7e2SAndroid Build Coastguard Worker                        EchoResponse* response) override {
253*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
254*cc02d7e2SAndroid Build Coastguard Worker     std::string resp;
255*cc02d7e2SAndroid Build Coastguard Worker     while (reader->Read(&request)) {
256*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
257*cc02d7e2SAndroid Build Coastguard Worker       resp.append(request.message());
258*cc02d7e2SAndroid Build Coastguard Worker     }
259*cc02d7e2SAndroid Build Coastguard Worker     response->set_message(resp);
260*cc02d7e2SAndroid Build Coastguard Worker     return Status::OK;
261*cc02d7e2SAndroid Build Coastguard Worker   }
262*cc02d7e2SAndroid Build Coastguard Worker 
ResponseStream(ServerContext *,const EchoRequest * request,ServerWriter<EchoResponse> * writer)263*cc02d7e2SAndroid Build Coastguard Worker   Status ResponseStream(ServerContext* /*context*/, const EchoRequest* request,
264*cc02d7e2SAndroid Build Coastguard Worker                         ServerWriter<EchoResponse>* writer) override {
265*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
266*cc02d7e2SAndroid Build Coastguard Worker     vector<std::string> tokens = split(request->message());
267*cc02d7e2SAndroid Build Coastguard Worker     for (const std::string& token : tokens) {
268*cc02d7e2SAndroid Build Coastguard Worker       response.set_message(token);
269*cc02d7e2SAndroid Build Coastguard Worker       writer->Write(response);
270*cc02d7e2SAndroid Build Coastguard Worker     }
271*cc02d7e2SAndroid Build Coastguard Worker     return Status::OK;
272*cc02d7e2SAndroid Build Coastguard Worker   }
273*cc02d7e2SAndroid Build Coastguard Worker 
BidiStream(ServerContext *,ServerReaderWriter<EchoResponse,EchoRequest> * stream)274*cc02d7e2SAndroid Build Coastguard Worker   Status BidiStream(
275*cc02d7e2SAndroid Build Coastguard Worker       ServerContext* /*context*/,
276*cc02d7e2SAndroid Build Coastguard Worker       ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
277*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
278*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
279*cc02d7e2SAndroid Build Coastguard Worker     while (stream->Read(&request)) {
280*cc02d7e2SAndroid Build Coastguard Worker       gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
281*cc02d7e2SAndroid Build Coastguard Worker       response.set_message(request.message());
282*cc02d7e2SAndroid Build Coastguard Worker       stream->Write(response);
283*cc02d7e2SAndroid Build Coastguard Worker     }
284*cc02d7e2SAndroid Build Coastguard Worker     return Status::OK;
285*cc02d7e2SAndroid Build Coastguard Worker   }
286*cc02d7e2SAndroid Build Coastguard Worker 
287*cc02d7e2SAndroid Build Coastguard Worker  private:
split(const std::string & input)288*cc02d7e2SAndroid Build Coastguard Worker   vector<std::string> split(const std::string& input) {
289*cc02d7e2SAndroid Build Coastguard Worker     std::string buff;
290*cc02d7e2SAndroid Build Coastguard Worker     vector<std::string> result;
291*cc02d7e2SAndroid Build Coastguard Worker 
292*cc02d7e2SAndroid Build Coastguard Worker     for (auto n : input) {
293*cc02d7e2SAndroid Build Coastguard Worker       if (n != ' ') {
294*cc02d7e2SAndroid Build Coastguard Worker         buff += n;
295*cc02d7e2SAndroid Build Coastguard Worker         continue;
296*cc02d7e2SAndroid Build Coastguard Worker       }
297*cc02d7e2SAndroid Build Coastguard Worker       if (buff.empty()) continue;
298*cc02d7e2SAndroid Build Coastguard Worker       result.push_back(buff);
299*cc02d7e2SAndroid Build Coastguard Worker       buff = "";
300*cc02d7e2SAndroid Build Coastguard Worker     }
301*cc02d7e2SAndroid Build Coastguard Worker     if (!buff.empty()) result.push_back(buff);
302*cc02d7e2SAndroid Build Coastguard Worker 
303*cc02d7e2SAndroid Build Coastguard Worker     return result;
304*cc02d7e2SAndroid Build Coastguard Worker   }
305*cc02d7e2SAndroid Build Coastguard Worker };
306*cc02d7e2SAndroid Build Coastguard Worker 
307*cc02d7e2SAndroid Build Coastguard Worker class MockTest : public ::testing::Test {
308*cc02d7e2SAndroid Build Coastguard Worker  protected:
MockTest()309*cc02d7e2SAndroid Build Coastguard Worker   MockTest() {}
310*cc02d7e2SAndroid Build Coastguard Worker 
SetUp()311*cc02d7e2SAndroid Build Coastguard Worker   void SetUp() override {
312*cc02d7e2SAndroid Build Coastguard Worker     int port = grpc_pick_unused_port_or_die();
313*cc02d7e2SAndroid Build Coastguard Worker     server_address_ << "localhost:" << port;
314*cc02d7e2SAndroid Build Coastguard Worker     // Setup server
315*cc02d7e2SAndroid Build Coastguard Worker     ServerBuilder builder;
316*cc02d7e2SAndroid Build Coastguard Worker     builder.AddListeningPort(server_address_.str(),
317*cc02d7e2SAndroid Build Coastguard Worker                              InsecureServerCredentials());
318*cc02d7e2SAndroid Build Coastguard Worker     builder.RegisterService(&service_);
319*cc02d7e2SAndroid Build Coastguard Worker     server_ = builder.BuildAndStart();
320*cc02d7e2SAndroid Build Coastguard Worker   }
321*cc02d7e2SAndroid Build Coastguard Worker 
TearDown()322*cc02d7e2SAndroid Build Coastguard Worker   void TearDown() override { server_->Shutdown(); }
323*cc02d7e2SAndroid Build Coastguard Worker 
ResetStub()324*cc02d7e2SAndroid Build Coastguard Worker   void ResetStub() {
325*cc02d7e2SAndroid Build Coastguard Worker     std::shared_ptr<Channel> channel = grpc::CreateChannel(
326*cc02d7e2SAndroid Build Coastguard Worker         server_address_.str(), InsecureChannelCredentials());
327*cc02d7e2SAndroid Build Coastguard Worker     stub_ = grpc::testing::EchoTestService::NewStub(channel);
328*cc02d7e2SAndroid Build Coastguard Worker   }
329*cc02d7e2SAndroid Build Coastguard Worker 
330*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
331*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<Server> server_;
332*cc02d7e2SAndroid Build Coastguard Worker   std::ostringstream server_address_;
333*cc02d7e2SAndroid Build Coastguard Worker   TestServiceImpl service_;
334*cc02d7e2SAndroid Build Coastguard Worker };
335*cc02d7e2SAndroid Build Coastguard Worker 
336*cc02d7e2SAndroid Build Coastguard Worker // Do one real rpc and one mocked one
TEST_F(MockTest,SimpleRpc)337*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockTest, SimpleRpc) {
338*cc02d7e2SAndroid Build Coastguard Worker   ResetStub();
339*cc02d7e2SAndroid Build Coastguard Worker   FakeClient client(stub_.get());
340*cc02d7e2SAndroid Build Coastguard Worker   client.DoEcho();
341*cc02d7e2SAndroid Build Coastguard Worker   MockEchoTestServiceStub stub;
342*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp;
343*cc02d7e2SAndroid Build Coastguard Worker   resp.set_message("hello world");
344*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(stub, Echo(_, _, _))
345*cc02d7e2SAndroid Build Coastguard Worker       .Times(AtLeast(1))
346*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK)));
347*cc02d7e2SAndroid Build Coastguard Worker   client.ResetStub(&stub);
348*cc02d7e2SAndroid Build Coastguard Worker   client.DoEcho();
349*cc02d7e2SAndroid Build Coastguard Worker }
350*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockTest,ClientStream)351*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockTest, ClientStream) {
352*cc02d7e2SAndroid Build Coastguard Worker   ResetStub();
353*cc02d7e2SAndroid Build Coastguard Worker   FakeClient client(stub_.get());
354*cc02d7e2SAndroid Build Coastguard Worker   client.DoRequestStream();
355*cc02d7e2SAndroid Build Coastguard Worker 
356*cc02d7e2SAndroid Build Coastguard Worker   MockEchoTestServiceStub stub;
357*cc02d7e2SAndroid Build Coastguard Worker   auto w = new MockClientWriter<EchoRequest>();
358*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp;
359*cc02d7e2SAndroid Build Coastguard Worker   resp.set_message("hello, world");
360*cc02d7e2SAndroid Build Coastguard Worker 
361*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true));
362*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*w, WritesDone());
363*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK));
364*cc02d7e2SAndroid Build Coastguard Worker 
365*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(stub, RequestStreamRaw(_, _))
366*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<1>(resp), Return(w)));
367*cc02d7e2SAndroid Build Coastguard Worker   client.ResetStub(&stub);
368*cc02d7e2SAndroid Build Coastguard Worker   client.DoRequestStream();
369*cc02d7e2SAndroid Build Coastguard Worker }
370*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockTest,ServerStream)371*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockTest, ServerStream) {
372*cc02d7e2SAndroid Build Coastguard Worker   ResetStub();
373*cc02d7e2SAndroid Build Coastguard Worker   FakeClient client(stub_.get());
374*cc02d7e2SAndroid Build Coastguard Worker   client.DoResponseStream();
375*cc02d7e2SAndroid Build Coastguard Worker 
376*cc02d7e2SAndroid Build Coastguard Worker   MockEchoTestServiceStub stub;
377*cc02d7e2SAndroid Build Coastguard Worker   auto r = new MockClientReader<EchoResponse>();
378*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp1;
379*cc02d7e2SAndroid Build Coastguard Worker   resp1.set_message("hello");
380*cc02d7e2SAndroid Build Coastguard Worker   EchoResponse resp2;
381*cc02d7e2SAndroid Build Coastguard Worker   resp2.set_message("world");
382*cc02d7e2SAndroid Build Coastguard Worker 
383*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*r, Read(_))
384*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true)))
385*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true)))
386*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(Return(false));
387*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK));
388*cc02d7e2SAndroid Build Coastguard Worker 
389*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r));
390*cc02d7e2SAndroid Build Coastguard Worker 
391*cc02d7e2SAndroid Build Coastguard Worker   client.ResetStub(&stub);
392*cc02d7e2SAndroid Build Coastguard Worker   client.DoResponseStream();
393*cc02d7e2SAndroid Build Coastguard Worker }
394*cc02d7e2SAndroid Build Coastguard Worker 
ACTION_P(copy,msg)395*cc02d7e2SAndroid Build Coastguard Worker ACTION_P(copy, msg) { arg0->set_message(msg->message()); }
396*cc02d7e2SAndroid Build Coastguard Worker 
TEST_F(MockTest,BidiStream)397*cc02d7e2SAndroid Build Coastguard Worker TEST_F(MockTest, BidiStream) {
398*cc02d7e2SAndroid Build Coastguard Worker   ResetStub();
399*cc02d7e2SAndroid Build Coastguard Worker   FakeClient client(stub_.get());
400*cc02d7e2SAndroid Build Coastguard Worker   client.DoBidiStream();
401*cc02d7e2SAndroid Build Coastguard Worker   MockEchoTestServiceStub stub;
402*cc02d7e2SAndroid Build Coastguard Worker   auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>();
403*cc02d7e2SAndroid Build Coastguard Worker   EchoRequest msg;
404*cc02d7e2SAndroid Build Coastguard Worker 
405*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*rw, Write(_, _))
406*cc02d7e2SAndroid Build Coastguard Worker       .Times(3)
407*cc02d7e2SAndroid Build Coastguard Worker       .WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true)));
408*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*rw, Read(_))
409*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
410*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
411*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
412*cc02d7e2SAndroid Build Coastguard Worker       .WillOnce(Return(false));
413*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*rw, WritesDone());
414*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK));
415*cc02d7e2SAndroid Build Coastguard Worker 
416*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw));
417*cc02d7e2SAndroid Build Coastguard Worker   client.ResetStub(&stub);
418*cc02d7e2SAndroid Build Coastguard Worker   client.DoBidiStream();
419*cc02d7e2SAndroid Build Coastguard Worker }
420*cc02d7e2SAndroid Build Coastguard Worker 
421*cc02d7e2SAndroid Build Coastguard Worker }  // namespace
422*cc02d7e2SAndroid Build Coastguard Worker }  // namespace testing
423*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
424*cc02d7e2SAndroid Build Coastguard Worker 
main(int argc,char ** argv)425*cc02d7e2SAndroid Build Coastguard Worker int main(int argc, char** argv) {
426*cc02d7e2SAndroid Build Coastguard Worker   grpc::testing::TestEnvironment env(&argc, argv);
427*cc02d7e2SAndroid Build Coastguard Worker   ::testing::InitGoogleTest(&argc, argv);
428*cc02d7e2SAndroid Build Coastguard Worker   return RUN_ALL_TESTS();
429*cc02d7e2SAndroid Build Coastguard Worker }
430