mock_test.cc
Go to the documentation of this file.
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 <iostream>
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include "absl/types/optional.h"
26 
27 #include <grpc/grpc.h>
28 #include <grpc/support/log.h>
29 #include <grpc/support/time.h>
30 #include <grpcpp/channel.h>
31 #include <grpcpp/client_context.h>
32 #include <grpcpp/create_channel.h>
33 #include <grpcpp/server.h>
34 #include <grpcpp/server_builder.h>
35 #include <grpcpp/server_context.h>
38 
39 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
40 #include "src/proto/grpc/testing/echo.grpc.pb.h"
41 #include "src/proto/grpc/testing/echo_mock.grpc.pb.h"
42 #include "test/core/util/port.h"
44 
46 using grpc::testing::EchoRequest;
47 using grpc::testing::EchoResponse;
48 using grpc::testing::EchoTestService;
50 using std::vector;
58 
59 namespace grpc {
60 namespace testing {
61 
62 namespace {
63 class FakeClient {
64  public:
65  explicit FakeClient(EchoTestService::StubInterface* stub) : stub_(stub) {}
66 
67  void DoEcho() {
68  ClientContext context;
69  EchoRequest request;
70  EchoResponse response;
71  request.set_message("hello world");
72  Status s = stub_->Echo(&context, request, &response);
73  EXPECT_EQ(request.message(), response.message());
74  EXPECT_TRUE(s.ok());
75  }
76 
77  void DoRequestStream() {
78  EchoRequest request;
79  EchoResponse response;
80 
81  ClientContext context;
82  std::string msg("hello");
83  std::string exp(msg);
84 
85  std::unique_ptr<ClientWriterInterface<EchoRequest>> cstream =
86  stub_->RequestStream(&context, &response);
87 
88  request.set_message(msg);
89  EXPECT_TRUE(cstream->Write(request));
90 
91  msg = ", world";
92  request.set_message(msg);
93  exp.append(msg);
94  EXPECT_TRUE(cstream->Write(request));
95 
96  cstream->WritesDone();
97  Status s = cstream->Finish();
98 
99  EXPECT_EQ(exp, response.message());
100  EXPECT_TRUE(s.ok());
101  }
102 
103  void DoResponseStream() {
104  EchoRequest request;
105  EchoResponse response;
106  request.set_message("hello world");
107 
108  ClientContext context;
109  std::unique_ptr<ClientReaderInterface<EchoResponse>> cstream =
110  stub_->ResponseStream(&context, request);
111 
112  std::string exp = "";
113  EXPECT_TRUE(cstream->Read(&response));
114  exp.append(response.message() + " ");
115 
116  EXPECT_TRUE(cstream->Read(&response));
117  exp.append(response.message());
118 
119  EXPECT_FALSE(cstream->Read(&response));
120  EXPECT_EQ(request.message(), exp);
121 
122  Status s = cstream->Finish();
123  EXPECT_TRUE(s.ok());
124  }
125 
126  void DoBidiStream() {
127  EchoRequest request;
128  EchoResponse response;
129  ClientContext context;
130  std::string msg("hello");
131 
132  std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
133  stream = stub_->BidiStream(&context);
134 
135  request.set_message(msg + "0");
136  EXPECT_TRUE(stream->Write(request));
137  EXPECT_TRUE(stream->Read(&response));
138  EXPECT_EQ(response.message(), request.message());
139 
140  request.set_message(msg + "1");
141  EXPECT_TRUE(stream->Write(request));
142  EXPECT_TRUE(stream->Read(&response));
143  EXPECT_EQ(response.message(), request.message());
144 
145  request.set_message(msg + "2");
146  EXPECT_TRUE(stream->Write(request));
147  EXPECT_TRUE(stream->Read(&response));
148  EXPECT_EQ(response.message(), request.message());
149 
150  stream->WritesDone();
151  EXPECT_FALSE(stream->Read(&response));
152 
153  Status s = stream->Finish();
154  EXPECT_TRUE(s.ok());
155  }
156 
157  void ResetStub(EchoTestService::StubInterface* stub) { stub_ = stub; }
158 
159  private:
160  EchoTestService::StubInterface* stub_;
161 };
162 
163 class CallbackTestServiceImpl : public EchoTestService::CallbackService {
164  public:
165  ServerUnaryReactor* Echo(CallbackServerContext* context,
166  const EchoRequest* request,
167  EchoResponse* response) override {
168  // Make the mock service explicitly treat empty input messages as invalid
169  // arguments so that we can test various results of status. In general, a
170  // mocked service should just use the original service methods, but we are
171  // adding this variance in Status return value just to improve coverage in
172  // this test.
173  auto* reactor = context->DefaultReactor();
174  if (request->message().length() > 0) {
175  response->set_message(request->message());
176  reactor->Finish(Status::OK);
177  } else {
178  reactor->Finish(Status(StatusCode::INVALID_ARGUMENT, "Invalid request"));
179  }
180  return reactor;
181  }
182 };
183 
184 class MockCallbackTest : public ::testing::Test {
185  protected:
186  CallbackTestServiceImpl service_;
187  ServerContext context_;
188 };
189 
190 TEST_F(MockCallbackTest, MockedCallSucceedsWithWait) {
191  CallbackServerContext ctx;
192  EchoRequest req;
193  EchoResponse resp;
194  struct {
198  } status;
199  DefaultReactorTestPeer peer(&ctx, [&](grpc::Status s) {
201  status.status = std::move(s);
202  status.cv.Signal();
203  });
204 
205  req.set_message("mock 1");
206  auto* reactor = service_.Echo(&ctx, &req, &resp);
207 
209  while (!status.status.has_value()) {
210  status.cv.Wait(&status.mu);
211  }
212 
213  EXPECT_EQ(reactor, peer.reactor());
214  EXPECT_TRUE(peer.test_status_set());
215  EXPECT_TRUE(peer.test_status().ok());
216  EXPECT_TRUE(status.status.has_value());
217  EXPECT_TRUE(status.status.value().ok());
218  EXPECT_EQ(req.message(), resp.message());
219 }
220 
221 TEST_F(MockCallbackTest, MockedCallSucceeds) {
222  CallbackServerContext ctx;
223  EchoRequest req;
224  EchoResponse resp;
226 
227  req.set_message("ha ha, consider yourself mocked.");
228  auto* reactor = service_.Echo(&ctx, &req, &resp);
229  EXPECT_EQ(reactor, peer.reactor());
230  EXPECT_TRUE(peer.test_status_set());
231  EXPECT_TRUE(peer.test_status().ok());
232 }
233 
234 TEST_F(MockCallbackTest, MockedCallFails) {
235  CallbackServerContext ctx;
236  EchoRequest req;
237  EchoResponse resp;
239 
240  auto* reactor = service_.Echo(&ctx, &req, &resp);
241  EXPECT_EQ(reactor, peer.reactor());
242  EXPECT_TRUE(peer.test_status_set());
243  EXPECT_EQ(peer.test_status().error_code(), StatusCode::INVALID_ARGUMENT);
244 }
245 
246 class TestServiceImpl : public EchoTestService::Service {
247  public:
248  Status Echo(ServerContext* /*context*/, const EchoRequest* request,
249  EchoResponse* response) override {
250  response->set_message(request->message());
251  return Status::OK;
252  }
253 
254  Status RequestStream(ServerContext* /*context*/,
255  ServerReader<EchoRequest>* reader,
256  EchoResponse* response) override {
257  EchoRequest request;
258  std::string resp("");
259  while (reader->Read(&request)) {
260  gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
261  resp.append(request.message());
262  }
263  response->set_message(resp);
264  return Status::OK;
265  }
266 
267  Status ResponseStream(ServerContext* /*context*/, const EchoRequest* request,
268  ServerWriter<EchoResponse>* writer) override {
269  EchoResponse response;
270  vector<std::string> tokens = split(request->message());
271  for (const std::string& token : tokens) {
272  response.set_message(token);
273  writer->Write(response);
274  }
275  return Status::OK;
276  }
277 
279  ServerContext* /*context*/,
280  ServerReaderWriter<EchoResponse, EchoRequest>* stream) override {
281  EchoRequest request;
282  EchoResponse response;
283  while (stream->Read(&request)) {
284  gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
285  response.set_message(request.message());
286  stream->Write(response);
287  }
288  return Status::OK;
289  }
290 
291  private:
292  vector<std::string> split(const std::string& input) {
293  std::string buff("");
294  vector<std::string> result;
295 
296  for (auto n : input) {
297  if (n != ' ') {
298  buff += n;
299  continue;
300  }
301  if (buff.empty()) continue;
302  result.push_back(buff);
303  buff = "";
304  }
305  if (!buff.empty()) result.push_back(buff);
306 
307  return result;
308  }
309 };
310 
311 class MockTest : public ::testing::Test {
312  protected:
313  MockTest() {}
314 
315  void SetUp() override {
317  server_address_ << "localhost:" << port;
318  // Setup server
319  ServerBuilder builder;
320  builder.AddListeningPort(server_address_.str(),
322  builder.RegisterService(&service_);
323  server_ = builder.BuildAndStart();
324  }
325 
326  void TearDown() override { server_->Shutdown(); }
327 
328  void ResetStub() {
329  std::shared_ptr<Channel> channel = grpc::CreateChannel(
331  stub_ = grpc::testing::EchoTestService::NewStub(channel);
332  }
333 
334  std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
335  std::unique_ptr<Server> server_;
336  std::ostringstream server_address_;
338 };
339 
340 // Do one real rpc and one mocked one
341 TEST_F(MockTest, SimpleRpc) {
342  ResetStub();
343  FakeClient client(stub_.get());
344  client.DoEcho();
345  MockEchoTestServiceStub stub;
346  EchoResponse resp;
347  resp.set_message("hello world");
348  EXPECT_CALL(stub, Echo(_, _, _))
349  .Times(AtLeast(1))
350  .WillOnce(DoAll(SetArgPointee<2>(resp), Return(Status::OK)));
351  client.ResetStub(&stub);
352  client.DoEcho();
353 }
354 
355 TEST_F(MockTest, ClientStream) {
356  ResetStub();
357  FakeClient client(stub_.get());
358  client.DoRequestStream();
359 
360  MockEchoTestServiceStub stub;
361  auto w = new MockClientWriter<EchoRequest>();
362  EchoResponse resp;
363  resp.set_message("hello, world");
364 
365  EXPECT_CALL(*w, Write(_, _)).Times(2).WillRepeatedly(Return(true));
366  EXPECT_CALL(*w, WritesDone());
367  EXPECT_CALL(*w, Finish()).WillOnce(Return(Status::OK));
368 
369  EXPECT_CALL(stub, RequestStreamRaw(_, _))
370  .WillOnce(DoAll(SetArgPointee<1>(resp), Return(w)));
371  client.ResetStub(&stub);
372  client.DoRequestStream();
373 }
374 
375 TEST_F(MockTest, ServerStream) {
376  ResetStub();
377  FakeClient client(stub_.get());
378  client.DoResponseStream();
379 
380  MockEchoTestServiceStub stub;
381  auto r = new MockClientReader<EchoResponse>();
382  EchoResponse resp1;
383  resp1.set_message("hello");
384  EchoResponse resp2;
385  resp2.set_message("world");
386 
387  EXPECT_CALL(*r, Read(_))
388  .WillOnce(DoAll(SetArgPointee<0>(resp1), Return(true)))
389  .WillOnce(DoAll(SetArgPointee<0>(resp2), Return(true)))
390  .WillOnce(Return(false));
391  EXPECT_CALL(*r, Finish()).WillOnce(Return(Status::OK));
392 
393  EXPECT_CALL(stub, ResponseStreamRaw(_, _)).WillOnce(Return(r));
394 
395  client.ResetStub(&stub);
396  client.DoResponseStream();
397 }
398 
399 ACTION_P(copy, msg) { arg0->set_message(msg->message()); }
400 
401 TEST_F(MockTest, BidiStream) {
402  ResetStub();
403  FakeClient client(stub_.get());
404  client.DoBidiStream();
405  MockEchoTestServiceStub stub;
407  EchoRequest msg;
408 
409  EXPECT_CALL(*rw, Write(_, _))
410  .Times(3)
411  .WillRepeatedly(DoAll(SaveArg<0>(&msg), Return(true)));
412  EXPECT_CALL(*rw, Read(_))
413  .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
414  .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
415  .WillOnce(DoAll(WithArg<0>(copy(&msg)), Return(true)))
416  .WillOnce(Return(false));
417  EXPECT_CALL(*rw, WritesDone());
418  EXPECT_CALL(*rw, Finish()).WillOnce(Return(Status::OK));
419 
420  EXPECT_CALL(stub, BidiStreamRaw(_)).WillOnce(Return(rw));
421  client.ResetStub(&stub);
422  client.DoBidiStream();
423 }
424 
425 } // namespace
426 } // namespace testing
427 } // namespace grpc
428 
429 int main(int argc, char** argv) {
430  grpc::testing::TestEnvironment env(&argc, argv);
431  ::testing::InitGoogleTest(&argc, argv);
432  return RUN_ALL_TESTS();
433 }
EXPECT_FALSE
#define EXPECT_FALSE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1970
_gevent_test_main.result
result
Definition: _gevent_test_main.py:96
GPR_INFO
#define GPR_INFO
Definition: include/grpc/impl/codegen/log.h:56
testing
Definition: aws_request_signer_test.cc:25
grpc::status
auto status
Definition: cpp/client/credentials_test.cc:200
log.h
port.h
ctx
Definition: benchmark-async.c:30
generate.env
env
Definition: generate.py:37
grpc::internal::Mutex
Definition: include/grpcpp/impl/codegen/sync.h:59
grpc
Definition: grpcpp/alarm.h:33
main
int main(int argc, char **argv)
Definition: mock_test.cc:429
testing::Return
internal::ReturnAction< R > Return(R value)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:1004
client
Definition: examples/python/async_streaming/client.py:1
copy
static int copy(grpc_slice_buffer *input, grpc_slice_buffer *output)
Definition: message_compress.cc:145
benchmark.request
request
Definition: benchmark.py:77
service_
CallbackTestServiceImpl service_
Definition: mock_test.cc:186
server_
std::unique_ptr< Server > server_
Definition: mock_test.cc:335
grpc::testing::MockClientReaderWriter
Definition: grpcpp/test/mock_stream.h:66
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
ABSL_GUARDED_BY
#define ABSL_GUARDED_BY(x)
Definition: abseil-cpp/absl/base/thread_annotations.h:62
default_reactor_test_peer.h
ctx
static struct test_ctx ctx
Definition: test-ipc-send-recv.c:65
absl::FormatConversionChar::s
@ s
time.h
async_greeter_client.stub
stub
Definition: hellostreamingworld/async_greeter_client.py:26
grpc::internal::MutexLock
Definition: include/grpcpp/impl/codegen/sync.h:86
testing::WithArg
internal::WithArgsAction< typename std::decay< InnerAction >::type, k > WithArg(InnerAction &&action)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:976
testing::Test
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:402
grpc::testing::CallbackTestServiceImpl::Echo
ServerUnaryReactor * Echo(CallbackServerContext *context, const EchoRequest *request, EchoResponse *response) override
Definition: test_service_impl.cc:128
client
static uv_tcp_t client
Definition: test-callback-stack.c:33
ACTION_P
#define ACTION_P(name, p0)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-generated-actions.h:764
profile_analyzer.builder
builder
Definition: profile_analyzer.py:159
channel
wrapped_grpc_channel * channel
Definition: src/php/ext/grpc/call.h:33
absl::move
constexpr absl::remove_reference_t< T > && move(T &&t) noexcept
Definition: abseil-cpp/absl/utility/utility.h:221
testing::internal::posix::Read
int Read(int fd, void *buf, unsigned int count)
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:2044
req
static uv_connect_t req
Definition: test-connection-fail.c:30
stub_
EchoTestService::StubInterface * stub_
Definition: mock_test.cc:160
gpr_log
GPRAPI void gpr_log(const char *file, int line, gpr_log_severity severity, const char *format,...) GPR_PRINT_FORMAT_CHECK(4
http2_server_health_check.resp
resp
Definition: http2_server_health_check.py:31
testing::SaveArg
internal::SaveArgAction< k, Ptr > SaveArg(Ptr pointer)
Definition: googletest/googlemock/include/gmock/gmock-actions.h:1413
testing::DoAll
internal::DoAllAction< typename std::decay< Action >::type... > DoAll(Action &&... action)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:964
grpc.h
gmock_output_test._
_
Definition: bloaty/third_party/googletest/googlemock/test/gmock_output_test.py:175
server_address_
std::ostringstream server_address_
Definition: mock_test.cc:336
absl::optional
Definition: abseil-cpp/absl/types/internal/optional.h:61
channel.h
grpc::Status::OK
static const Status & OK
An OK pre-defined instance.
Definition: include/grpcpp/impl/codegen/status.h:113
grpc::CreateChannel
std::shared_ptr< Channel > CreateChannel(const grpc::string &target, const std::shared_ptr< ChannelCredentials > &creds)
RUN_ALL_TESTS
int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:2471
grpc_pick_unused_port_or_die
int grpc_pick_unused_port_or_die(void)
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
msg
std::string msg
Definition: client_interceptors_end2end_test.cc:372
grpc::testing::DefaultReactorTestPeer
Definition: default_reactor_test_peer.h:35
EXPECT_CALL
#define EXPECT_CALL(obj, call)
writer
void writer(void *n)
Definition: libuv/docs/code/locks/main.c:22
tests.unit._exit_scenarios.port
port
Definition: _exit_scenarios.py:179
test_config.h
client_context.h
testing::InitGoogleTest
GTEST_API_ void InitGoogleTest(int *argc, char **argv)
Definition: bloaty/third_party/googletest/googletest/src/gtest.cc:6106
testing::internal::posix::Write
int Write(int fd, const void *buf, unsigned int count)
Definition: bloaty/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:2047
grpc::testing::cv
static gpr_cv cv
Definition: bm_cq.cc:163
grpc::testing::TEST_F
TEST_F(ChannelArgumentsTest, SetInt)
Definition: channel_arguments_test.cc:134
benchmark::internal::Finish
double Finish(Counter const &c, IterationCount iterations, double cpu_time, double num_threads)
Definition: benchmark/src/counter.cc:20
server_context.h
fix_build_deps.r
r
Definition: fix_build_deps.py:491
asyncio_get_stats.response
response
Definition: asyncio_get_stats.py:28
grpc::testing::TestEnvironment
Definition: test/core/util/test_config.h:54
grpc::protobuf::util::Status
GRPC_CUSTOM_UTIL_STATUS Status
Definition: include/grpcpp/impl/codegen/config_protobuf.h:93
grpc.StatusCode.INVALID_ARGUMENT
tuple INVALID_ARGUMENT
Definition: src/python/grpcio/grpc/__init__.py:263
grpc::Status
Definition: include/grpcpp/impl/codegen/status.h:35
grpc::testing::TestServiceImpl::BidiStream
Status BidiStream(ServerContext *, ServerReaderWriter< EchoResponse, EchoRequest > *stream) override
Definition: streaming_throughput_test.cc:108
grpc::testing::EXPECT_EQ
EXPECT_EQ(options.token_exchange_service_uri, "https://foo/exchange")
input
std::string input
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/tokenizer_unittest.cc:197
grpc::InsecureServerCredentials
std::shared_ptr< ServerCredentials > InsecureServerCredentials()
Definition: insecure_server_credentials.cc:52
grpc::internal::CondVar
Definition: include/grpcpp/impl/codegen/sync.h:124
grpc::testing::TestServiceImpl::Echo
Status Echo(ServerContext *context, const EchoRequest *, EchoResponse *) override
Definition: shutdown_test.cc:49
context
grpc::ClientContext context
Definition: istio_echo_server_lib.cc:61
mock_stream.h
grpc::testing::EXPECT_TRUE
EXPECT_TRUE(grpc::experimental::StsCredentialsOptionsFromJson(minimum_valid_json, &options) .ok())
server.h
grpc::InsecureChannelCredentials
std::shared_ptr< ChannelCredentials > InsecureChannelCredentials()
Credentials for an unencrypted, unauthenticated channel.
Definition: cpp/client/insecure_credentials.cc:69
run_grpclb_interop_tests.l
dictionary l
Definition: run_grpclb_interop_tests.py:410
split
static void split(const char *s, char ***ss, size_t *ns)
Definition: debug/trace.cc:111
context_
ServerContext context_
Definition: mock_test.cc:187
TestServiceImpl
Definition: interop_server.cc:139
testing::AtLeast
GTEST_API_ Cardinality AtLeast(int n)
Definition: bloaty/third_party/googletest/googlemock/src/gmock-cardinalities.cc:139
testing::SetArgPointee
internal::SetArgumentPointeeAction< N, T > SetArgPointee(T x)
Definition: bloaty/third_party/googletest/googlemock/include/gmock/gmock-actions.h:1049
server_builder.h
reader
void reader(void *n)
Definition: libuv/docs/code/locks/main.c:8
create_channel.h
grpc::testing::mu
static gpr_mu mu
Definition: bm_cq.cc:162
stream
voidpf stream
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136


grpc
Author(s):
autogenerated on Thu Mar 13 2025 03:00:40