mock_test.cc 12 KB

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