1 /*
2 *
3 * Copyright 2015 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 #include <climits>
20 #include <thread>
21
22 #include <grpc/grpc.h>
23 #include <grpc/support/log.h>
24 #include <grpc/support/time.h>
25 #include <grpcpp/channel.h>
26 #include <grpcpp/client_context.h>
27 #include <grpcpp/create_channel.h>
28 #include <grpcpp/server.h>
29 #include <grpcpp/server_builder.h>
30 #include <grpcpp/server_context.h>
31
32 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
33 #include "src/proto/grpc/testing/echo.grpc.pb.h"
34 #include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
35 #include "test/core/util/port.h"
36 #include "test/core/util/test_config.h"
37
38 #include <grpcpp/test/mock_stream.h>
39
40 #include <gmock/gmock.h>
41 #include <gtest/gtest.h>
42
43 #include <iostream>
44
45 using ::testing::AtLeast;
46 using ::testing::DoAll;
47 using ::testing::Invoke;
48 using ::testing::Return;
49 using ::testing::SaveArg;
50 using ::testing::SetArgPointee;
51 using ::testing::WithArg;
52 using ::testing::_;
53 using grpc::testing::EchoRequest;
54 using grpc::testing::EchoResponse;
55 using grpc::testing::EchoTestService;
56 using grpc::testing::MockClientReaderWriter;
57 using std::chrono::system_clock;
58 using std::vector;
59
60 namespace grpc {
61 namespace testing {
62
63 namespace {
64 class FakeClient {
65 public:
FakeClient(EchoTestService::StubInterface * stub)66 explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {}
67
DoEcho()68 void DoEcho() {
69 ClientContext context;
70 EchoRequest request;
71 EchoResponse response;
72 request.set_message("hello world");
73 Status s = stub_->Echo(&context, request, &response);
74 EXPECT_EQ(request.message(), response.message());
75 EXPECT_TRUE(s.ok());
76 }
77
DoRequestStream()78 void DoRequestStream() {
79 EchoRequest request;
80 EchoResponse response;
81
82 ClientContext context;
83 grpc::string msg("hello");
84 grpc::string exp(msg);
85
86 std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream =
87 stub_->RequestStream(&context, &response);
88
89 request.set_message(msg);
90 EXPECT_TRUE(cstream->Write(request));
91
92 msg = ", world";
93 request.set_message(msg);
94 exp.append(msg);
95 EXPECT_TRUE(cstream->Write(request));
96
97 cstream->WritesDone();
98 Status s = cstream->Finish();
99
100 EXPECT_EQ(exp, response.message());
101 EXPECT_TRUE(s.ok());
102 }
103
DoResponseStream()104 void DoResponseStream() {
105 EchoRequest request;
106 EchoResponse response;
107 request.set_message("hello world");
108
109 ClientContext context;
110 std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream =
111 stub_->ResponseStream(&context, request);
112
113 grpc::string exp = "";
114 EXPECT_TRUE(cstream->Read(&response));
115 exp.append(response.message() + " ");
116
117 EXPECT_TRUE(cstream->Read(&response));
118 exp.append(response.message());
119
120 EXPECT_FALSE(cstream->Read(&response));
121 EXPECT_EQ(request.message(), exp);
122
123 Status s = cstream->Finish();
124 EXPECT_TRUE(s.ok());
125 }
126
DoBidiStream()127 void DoBidiStream() {
128 EchoRequest request;
129 EchoResponse response;
130 ClientContext context;
131 grpc::string msg("hello");
132
133 std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
134 stream = stub_->BidiStream(&context);
135
136 request.set_message(msg + "0");
137 EXPECT_TRUE(stream->Write(request));
138 EXPECT_TRUE(stream->Read(&response));
139 EXPECT_EQ(response.message(), request.message());
140
141 request.set_message(msg + "1");
142 EXPECT_TRUE(stream->Write(request));
143 EXPECT_TRUE(stream->Read(&response));
144 EXPECT_EQ(response.message(), request.message());
145
146 request.set_message(msg + "2");
147 EXPECT_TRUE(stream->Write(request));
148 EXPECT_TRUE(stream->Read(&response));
149 EXPECT_EQ(response.message(), request.message());
150
151 stream->WritesDone();
152 EXPECT_FALSE(stream->Read(&response));
153
154 Status s = stream->Finish();
155 EXPECT_TRUE(s.ok());
156 }
157
ResetStub(EchoTestService::StubInterface * stub)158 void ResetStub(EchoTestService::StubInterface* stub) { stub_ = stub; }
159
160 private:
161 EchoTestService::StubInterface* stub_;
162 };
163
164 class TestServiceImpl : public EchoTestService::Service {
165 public:
Echo(ServerContext * context,const EchoRequest * request,EchoResponse * response)166 Status Echo(ServerContext* context, const EchoRequest* request,
167 EchoResponse* response) override {
168 response->set_message(request->message());
169 return Status::OK;
170 }
171
RequestStream(ServerContext * context,ServerReader<EchoRequest> * reader,EchoResponse * response)172 Status RequestStream(ServerContext* context,
173 ServerReader<EchoRequest>* reader,
174 EchoResponse* response) override {
175 EchoRequest request;
176 grpc::string resp("");
177 while (reader->Read(&request)) {
178 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
179 resp.append(request.message());
180 }
181 response->set_message(resp);
182 return Status::OK;
183 }
184
ResponseStream(ServerContext * context,const EchoRequest * request,ServerWriter<EchoResponse> * writer)185 Status ResponseStream(ServerContext* context, const EchoRequest* request,
186 ServerWriter<EchoResponse>* writer) override {
187 EchoResponse response;
188 vector<grpc::string> tokens = split(request->message());
189 for (const grpc::string& token : tokens) {
190 response.set_message(token);
191 writer->Write(response);
192 }
193 return Status::OK;
194 }
195
BidiStream(ServerContext * context,ServerReaderWriter<EchoResponse,EchoRequest> * stream)196 Status BidiStream(
197 ServerContext* context,
198 ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
199 EchoRequest request;
200 EchoResponse response;
201 while (stream->Read(&request)) {
202 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
203 response.set_message(request.message());
204 stream->Write(response);
205 }
206 return Status::OK;
207 }
208
209 private:
split(const grpc::string & input)210 const vector<grpc::string> split(const grpc::string& input) {
211 grpc::string buff("");
212 vector<grpc::string> result;
213
214 for (auto n : input) {
215 if (n != ' ') {
216 buff += n;
217 continue;
218 }
219 if (buff == "") continue;
220 result.push_back(buff);
221 buff = "";
222 }
223 if (buff != "") result.push_back(buff);
224
225 return result;
226 }
227 };
228
229 class MockTest : public ::testing::Test {
230 protected:
MockTest()231 MockTest() {}
232
SetUp()233 void SetUp() override {
234 int port = grpc_pick_unused_port_or_die();
235 server_address_ << "localhost:" << port;
236 // Setup server
237 ServerBuilder builder;
238 builder.AddListeningPort(server_address_.str(),
239 InsecureServerCredentials());
240 builder.RegisterService(&service_);
241 server_ = builder.BuildAndStart();
242 }
243
TearDown()244 void TearDown() override { server_->Shutdown(); }
245
ResetStub()246 void ResetStub() {
247 std::shared_ptr<Channel> channel =
248 CreateChannel(server_address_.str(), InsecureChannelCredentials());
249 stub_ = grpc::testing::EchoTestService::NewStub(channel);
250 }
251
252 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
253 std::unique_ptr<Server> server_;
254 std::ostringstream server_address_;
255 TestServiceImpl service_;
256 };
257
258 // Do one real rpc and one mocked one
TEST_F(MockTest,SimpleRpc)259 TEST_F(MockTest, SimpleRpc) {
260 ResetStub();
261 FakeClient client(stub_.get());
262 client.DoEcho();
263 MockEchoTestServiceStub stub;
264 EchoResponse resp;
265 resp.set_message("hello world");
266 EXPECT_CALL(stub, Echo(_, _, _))
267 .Times(AtLeast(1))
268 .WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK)));
269 client.ResetStub(&stub);
270 client.DoEcho();
271 }
272
TEST_F(MockTest,ClientStream)273 TEST_F(MockTest, ClientStream) {
274 ResetStub();
275 FakeClient client(stub_.get());
276 client.DoRequestStream();
277
278 MockEchoTestServiceStub stub;
279 auto w = new MockClientWriter<EchoRequest>();
280 EchoResponse resp;
281 resp.set_message("hello, world");
282
283 EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true));
284 EXPECT_CALL(*w, WritesDone());
285 EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK));
286
287 EXPECT_CALL(stub, RequestStreamRaw(_, _))
288 .WillOnce(DoAll(SetArgPointee<1>(resp), Return(w)));
289 client.ResetStub(&stub);
290 client.DoRequestStream();
291 }
292
TEST_F(MockTest,ServerStream)293 TEST_F(MockTest, ServerStream) {
294 ResetStub();
295 FakeClient client(stub_.get());
296 client.DoResponseStream();
297
298 MockEchoTestServiceStub stub;
299 auto r = new MockClientReader<EchoResponse>();
300 EchoResponse resp1;
301 resp1.set_message("hello");
302 EchoResponse resp2;
303 resp2.set_message("world");
304
305 EXPECT_CALL(*r, Read(_))
306 .WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true)))
307 .WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true)))
308 .WillOnce(Return(false));
309 EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK));
310
311 EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r));
312
313 client.ResetStub(&stub);
314 client.DoResponseStream();
315 }
316
ACTION_P(copy,msg)317 ACTION_P(copy, msg) { arg0->set_message(msg->message()); }
318
TEST_F(MockTest,BidiStream)319 TEST_F(MockTest, BidiStream) {
320 ResetStub();
321 FakeClient client(stub_.get());
322 client.DoBidiStream();
323 MockEchoTestServiceStub stub;
324 auto rw = new MockClientReaderWriter<EchoRequest, EchoResponse>();
325 EchoRequest msg;
326
327 EXPECT_CALL(*rw, Write(_, _))
328 .Times(3)
329 .WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true)));
330 EXPECT_CALL(*rw, Read(_))
331 .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
332 .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
333 .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
334 .WillOnce(Return(false));
335 EXPECT_CALL(*rw, WritesDone());
336 EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK));
337
338 EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw));
339 client.ResetStub(&stub);
340 client.DoBidiStream();
341 }
342
343 } // namespace
344 } // namespace testing
345 } // namespace grpc
346
main(int argc,char ** argv)347 int main(int argc, char** argv) {
348 grpc_test_init(argc, argv);
349 ::testing::InitGoogleTest(&argc, argv);
350 return RUN_ALL_TESTS();
351 }
352