blob: 0226da672c9fe7c7105706229a42fa29c985b20d [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 }
89 bool Write(const EchoRequest& msg) GRPC_OVERRIDE {
90 gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
91 last_message_ = msg.message();
92 return true;
93 }
94 bool WritesDone() GRPC_OVERRIDE {
95 writes_done_ = true;
96 return true;
97 }
98 Status Finish() GRPC_OVERRIDE { return Status::OK; }
99
100 private:
101 bool writes_done_;
102 grpc::string last_message_;
103};
104
105// Mocked stub.
106class MockStub : public TestService::StubInterface {
107 public:
108 MockStub() {}
109 ~MockStub() {}
110 Status Echo(ClientContext* context, const EchoRequest& request,
111 EchoResponse* response) GRPC_OVERRIDE {
112 response->set_message(request.message());
113 return Status::OK;
114 }
115 Status Unimplemented(ClientContext* context, const EchoRequest& request,
116 EchoResponse* response) GRPC_OVERRIDE {
117 return Status::OK;
118 }
119
120 private:
121 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700122 ClientContext* context, const EchoRequest& request,
123 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700124 return nullptr;
125 }
126 ClientWriterInterface<EchoRequest>* RequestStreamRaw(
127 ClientContext* context, EchoResponse* response) GRPC_OVERRIDE {
128 return nullptr;
129 }
130 ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
131 ClientContext* context, EchoResponse* response, CompletionQueue* cq,
132 void* tag) GRPC_OVERRIDE {
133 return nullptr;
134 }
135 ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
136 ClientContext* context, const EchoRequest& request) GRPC_OVERRIDE {
137 return nullptr;
138 }
139 ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
140 ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
141 void* tag) GRPC_OVERRIDE {
142 return nullptr;
143 }
144 ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
145 ClientContext* context) GRPC_OVERRIDE {
146 return new MockClientReaderWriter<EchoRequest, EchoResponse>();
147 }
148 ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
149 AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
150 void* tag) GRPC_OVERRIDE {
151 return nullptr;
152 }
153 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700154 ClientContext* context, const EchoRequest& request,
155 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700156 return nullptr;
157 }
158};
159
160class FakeClient {
161 public:
162 explicit FakeClient(TestService::StubInterface* stub) : stub_(stub) {}
163
164 void DoEcho() {
165 ClientContext context;
166 EchoRequest request;
167 EchoResponse response;
168 request.set_message("hello world");
169 Status s = stub_->Echo(&context, request, &response);
170 EXPECT_EQ(request.message(), response.message());
171 EXPECT_TRUE(s.IsOk());
172 }
173
174 void DoBidiStream() {
175 EchoRequest request;
176 EchoResponse response;
177 ClientContext context;
178 grpc::string msg("hello");
179
180 std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
181 stream = stub_->BidiStream(&context);
182
183 request.set_message(msg + "0");
184 EXPECT_TRUE(stream->Write(request));
185 EXPECT_TRUE(stream->Read(&response));
186 EXPECT_EQ(response.message(), request.message());
187
188 request.set_message(msg + "1");
189 EXPECT_TRUE(stream->Write(request));
190 EXPECT_TRUE(stream->Read(&response));
191 EXPECT_EQ(response.message(), request.message());
192
193 request.set_message(msg + "2");
194 EXPECT_TRUE(stream->Write(request));
195 EXPECT_TRUE(stream->Read(&response));
196 EXPECT_EQ(response.message(), request.message());
197
198 stream->WritesDone();
199 EXPECT_FALSE(stream->Read(&response));
200
201 Status s = stream->Finish();
202 EXPECT_TRUE(s.IsOk());
203 }
204
205 void ResetStub(TestService::StubInterface* stub) { stub_ = stub; }
206
207 private:
208 TestService::StubInterface* stub_;
209};
210
211class TestServiceImpl : public TestService::Service {
212 public:
213 Status Echo(ServerContext* context, const EchoRequest* request,
214 EchoResponse* response) GRPC_OVERRIDE {
215 response->set_message(request->message());
216 return Status::OK;
217 }
218
219 Status BidiStream(ServerContext* context,
220 ServerReaderWriter<EchoResponse, EchoRequest>* stream)
221 GRPC_OVERRIDE {
222 EchoRequest request;
223 EchoResponse response;
224 while (stream->Read(&request)) {
225 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
226 response.set_message(request.message());
227 stream->Write(response);
228 }
229 return Status::OK;
230 }
231};
232
233class MockTest : public ::testing::Test {
234 protected:
235 MockTest() : thread_pool_(2) {}
236
237 void SetUp() GRPC_OVERRIDE {
238 int port = grpc_pick_unused_port_or_die();
239 server_address_ << "localhost:" << port;
240 // Setup server
241 ServerBuilder builder;
242 builder.AddListeningPort(server_address_.str(),
243 InsecureServerCredentials());
244 builder.RegisterService(&service_);
245 builder.SetThreadPool(&thread_pool_);
246 server_ = builder.BuildAndStart();
247 }
248
249 void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
250
251 void ResetStub() {
252 std::shared_ptr<ChannelInterface> channel = CreateChannel(
253 server_address_.str(), InsecureCredentials(), ChannelArguments());
254 stub_ = std::move(grpc::cpp::test::util::TestService::NewStub(channel));
255 }
256
257 std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
258 std::unique_ptr<Server> server_;
259 std::ostringstream server_address_;
260 TestServiceImpl service_;
261 ThreadPool thread_pool_;
262};
263
264// Do one real rpc and one mocked one
265TEST_F(MockTest, SimpleRpc) {
266 ResetStub();
267 FakeClient client(stub_.get());
268 client.DoEcho();
269 MockStub stub;
270 client.ResetStub(&stub);
271 client.DoEcho();
272}
273
274TEST_F(MockTest, BidiStream) {
275 ResetStub();
276 FakeClient client(stub_.get());
277 client.DoBidiStream();
278 MockStub stub;
279 client.ResetStub(&stub);
280 client.DoBidiStream();
281}
282
283} // namespace
284} // namespace testing
285} // namespace grpc
286
287int main(int argc, char** argv) {
288 grpc_test_init(argc, argv);
289 ::testing::InitGoogleTest(&argc, argv);
290 return RUN_ALL_TESTS();
291}