blob: 59a8edf5092a6c269d2df62b199cfc03f46fcc1a [file] [log] [blame]
Yang Gao196ade32015-05-05 13:31:12 -07001/*
2 *
3 * Copyright 2015, Google Inc.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 *
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above
13 * copyright notice, this list of conditions and the following disclaimer
14 * in the documentation and/or other materials provided with the
15 * distribution.
16 * * Neither the name of Google Inc. nor the names of its
17 * contributors may be used to endorse or promote products derived from
18 * this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34#include <thread>
35
36#include "test/core/util/port.h"
37#include "test/core/util/test_config.h"
38#include "test/cpp/util/echo_duplicate.grpc.pb.h"
39#include "test/cpp/util/echo.grpc.pb.h"
40#include "src/cpp/server/thread_pool.h"
41#include <grpc++/channel_arguments.h>
42#include <grpc++/channel_interface.h>
43#include <grpc++/client_context.h>
44#include <grpc++/create_channel.h>
45#include <grpc++/credentials.h>
46#include <grpc++/server.h>
47#include <grpc++/server_builder.h>
48#include <grpc++/server_context.h>
49#include <grpc++/server_credentials.h>
50#include <grpc++/status.h>
51#include <grpc++/stream.h>
52#include <grpc++/time.h>
53#include <gtest/gtest.h>
54
55#include <grpc/grpc.h>
56#include <grpc/support/thd.h>
57#include <grpc/support/time.h>
58
59using grpc::cpp::test::util::EchoRequest;
60using grpc::cpp::test::util::EchoResponse;
61using grpc::cpp::test::util::TestService;
62using std::chrono::system_clock;
63
64namespace grpc {
65namespace testing {
66
67namespace {
68template <class W, class R>
69class MockClientReaderWriter GRPC_FINAL
70 : public ClientReaderWriterInterface<W, R> {
71 public:
72 void WaitForInitialMetadata() {}
73 bool Read(R* msg) GRPC_OVERRIDE { return true; }
74 bool Write(const W& msg) GRPC_OVERRIDE { return true; }
75 bool WritesDone() GRPC_OVERRIDE { return true; }
76 Status Finish() GRPC_OVERRIDE { return Status::OK; }
77};
78template <>
79class MockClientReaderWriter<EchoRequest, EchoResponse> GRPC_FINAL
80 : public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
81 public:
82 MockClientReaderWriter() : writes_done_(false) {}
83 void WaitForInitialMetadata() {}
84 bool Read(EchoResponse* msg) GRPC_OVERRIDE {
85 if (writes_done_) return false;
86 msg->set_message(last_message_);
87 return true;
88 }
David Garcia Quintas6a3cf972015-07-13 13:38:18 -070089
90 bool Write(const EchoRequest& msg,
91 const WriteOptions& options) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -070092 gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
93 last_message_ = msg.message();
94 return true;
95 }
96 bool WritesDone() GRPC_OVERRIDE {
97 writes_done_ = true;
98 return true;
99 }
100 Status Finish() GRPC_OVERRIDE { return Status::OK; }
101
102 private:
103 bool writes_done_;
104 grpc::string last_message_;
105};
106
107// Mocked stub.
108class MockStub : public TestService::StubInterface {
109 public:
110 MockStub() {}
111 ~MockStub() {}
112 Status Echo(ClientContext* context, const EchoRequest& request,
113 EchoResponse* response) GRPC_OVERRIDE {
114 response->set_message(request.message());
115 return Status::OK;
116 }
117 Status Unimplemented(ClientContext* context, const EchoRequest& request,
118 EchoResponse* response) GRPC_OVERRIDE {
119 return Status::OK;
120 }
121
122 private:
123 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700124 ClientContext* context, const EchoRequest& request,
125 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700126 return nullptr;
127 }
128 ClientWriterInterface<EchoRequest>* RequestStreamRaw(
129 ClientContext* context, EchoResponse* response) GRPC_OVERRIDE {
130 return nullptr;
131 }
132 ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
133 ClientContext* context, EchoResponse* response, CompletionQueue* cq,
134 void* tag) GRPC_OVERRIDE {
135 return nullptr;
136 }
137 ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
138 ClientContext* context, const EchoRequest& request) GRPC_OVERRIDE {
139 return nullptr;
140 }
141 ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
142 ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
143 void* tag) GRPC_OVERRIDE {
144 return nullptr;
145 }
146 ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
147 ClientContext* context) GRPC_OVERRIDE {
148 return new MockClientReaderWriter<EchoRequest, EchoResponse>();
149 }
150 ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
151 AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
152 void* tag) GRPC_OVERRIDE {
153 return nullptr;
154 }
155 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700156 ClientContext* context, const EchoRequest& request,
157 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700158 return nullptr;
159 }
160};
161
162class FakeClient {
163 public:
164 explicit FakeClient(TestService::StubInterface* stub) : stub_(stub) {}
165
166 void DoEcho() {
167 ClientContext context;
168 EchoRequest request;
169 EchoResponse response;
170 request.set_message("hello world");
171 Status s = stub_->Echo(&context, request, &response);
172 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700173 EXPECT_TRUE(s.ok());
Yang Gao196ade32015-05-05 13:31:12 -0700174 }
175
176 void DoBidiStream() {
177 EchoRequest request;
178 EchoResponse response;
179 ClientContext context;
180 grpc::string msg("hello");
181
182 std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
183 stream = stub_->BidiStream(&context);
184
185 request.set_message(msg + "0");
186 EXPECT_TRUE(stream->Write(request));
187 EXPECT_TRUE(stream->Read(&response));
188 EXPECT_EQ(response.message(), request.message());
189
190 request.set_message(msg + "1");
191 EXPECT_TRUE(stream->Write(request));
192 EXPECT_TRUE(stream->Read(&response));
193 EXPECT_EQ(response.message(), request.message());
194
195 request.set_message(msg + "2");
196 EXPECT_TRUE(stream->Write(request));
197 EXPECT_TRUE(stream->Read(&response));
198 EXPECT_EQ(response.message(), request.message());
199
200 stream->WritesDone();
201 EXPECT_FALSE(stream->Read(&response));
202
203 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700204 EXPECT_TRUE(s.ok());
Yang Gao196ade32015-05-05 13:31:12 -0700205 }
206
207 void ResetStub(TestService::StubInterface* stub) { stub_ = stub; }
208
209 private:
210 TestService::StubInterface* stub_;
211};
212
213class TestServiceImpl : public TestService::Service {
214 public:
215 Status Echo(ServerContext* context, const EchoRequest* request,
216 EchoResponse* response) GRPC_OVERRIDE {
217 response->set_message(request->message());
218 return Status::OK;
219 }
220
221 Status BidiStream(ServerContext* context,
222 ServerReaderWriter<EchoResponse, EchoRequest>* stream)
223 GRPC_OVERRIDE {
224 EchoRequest request;
225 EchoResponse response;
226 while (stream->Read(&request)) {
227 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
228 response.set_message(request.message());
229 stream->Write(response);
230 }
231 return Status::OK;
232 }
233};
234
235class MockTest : public ::testing::Test {
236 protected:
237 MockTest() : thread_pool_(2) {}
238
239 void SetUp() GRPC_OVERRIDE {
240 int port = grpc_pick_unused_port_or_die();
241 server_address_ << "localhost:" << port;
242 // Setup server
243 ServerBuilder builder;
244 builder.AddListeningPort(server_address_.str(),
245 InsecureServerCredentials());
246 builder.RegisterService(&service_);
247 builder.SetThreadPool(&thread_pool_);
248 server_ = builder.BuildAndStart();
249 }
250
251 void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
252
253 void ResetStub() {
254 std::shared_ptr<ChannelInterface> channel = CreateChannel(
255 server_address_.str(), InsecureCredentials(), ChannelArguments());
256 stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
257 }
258
259 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
260 std::unique_ptr<Server> server_;
261 std::ostringstream server_address_;
262 TestServiceImpl service_;
263 ThreadPool thread_pool_;
264};
265
266// Do one real rpc and one mocked one
267TEST_F(MockTest, SimpleRpc) {
268 ResetStub();
269 FakeClient client(stub_.get());
270 client.DoEcho();
271 MockStub stub;
272 client.ResetStub(&stub);
273 client.DoEcho();
274}
275
276TEST_F(MockTest, BidiStream) {
277 ResetStub();
278 FakeClient client(stub_.get());
279 client.DoBidiStream();
280 MockStub stub;
281 client.ResetStub(&stub);
282 client.DoBidiStream();
283}
284
285} // namespace
286} // namespace testing
287} // namespace grpc
288
289int main(int argc, char** argv) {
290 grpc_test_init(argc, argv);
291 ::testing::InitGoogleTest(&argc, argv);
292 return RUN_ALL_TESTS();
293}