blob: d1d5c4447b5634adf3cb263bb6673c0a82fe4219 [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"
Yang Gao196ade32015-05-05 13:31:12 -070040#include <grpc++/channel_arguments.h>
41#include <grpc++/channel_interface.h>
42#include <grpc++/client_context.h>
43#include <grpc++/create_channel.h>
44#include <grpc++/credentials.h>
45#include <grpc++/server.h>
46#include <grpc++/server_builder.h>
47#include <grpc++/server_context.h>
48#include <grpc++/server_credentials.h>
49#include <grpc++/status.h>
50#include <grpc++/stream.h>
51#include <grpc++/time.h>
52#include <gtest/gtest.h>
53
54#include <grpc/grpc.h>
55#include <grpc/support/thd.h>
56#include <grpc/support/time.h>
57
58using grpc::cpp::test::util::EchoRequest;
59using grpc::cpp::test::util::EchoResponse;
60using grpc::cpp::test::util::TestService;
61using std::chrono::system_clock;
62
63namespace grpc {
64namespace testing {
65
66namespace {
67template <class W, class R>
68class MockClientReaderWriter GRPC_FINAL
69 : public ClientReaderWriterInterface<W, R> {
70 public:
71 void WaitForInitialMetadata() {}
72 bool Read(R* msg) GRPC_OVERRIDE { return true; }
73 bool Write(const W& msg) GRPC_OVERRIDE { return true; }
74 bool WritesDone() GRPC_OVERRIDE { return true; }
75 Status Finish() GRPC_OVERRIDE { return Status::OK; }
76};
77template <>
78class MockClientReaderWriter<EchoRequest, EchoResponse> GRPC_FINAL
79 : public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
80 public:
81 MockClientReaderWriter() : writes_done_(false) {}
82 void WaitForInitialMetadata() {}
83 bool Read(EchoResponse* msg) GRPC_OVERRIDE {
84 if (writes_done_) return false;
85 msg->set_message(last_message_);
86 return true;
87 }
David Garcia Quintas6a3cf972015-07-13 13:38:18 -070088
89 bool Write(const EchoRequest& msg,
90 const WriteOptions& options) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -070091 gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
92 last_message_ = msg.message();
93 return true;
94 }
95 bool WritesDone() GRPC_OVERRIDE {
96 writes_done_ = true;
97 return true;
98 }
99 Status Finish() GRPC_OVERRIDE { return Status::OK; }
100
101 private:
102 bool writes_done_;
103 grpc::string last_message_;
104};
105
106// Mocked stub.
107class MockStub : public TestService::StubInterface {
108 public:
109 MockStub() {}
110 ~MockStub() {}
111 Status Echo(ClientContext* context, const EchoRequest& request,
112 EchoResponse* response) GRPC_OVERRIDE {
113 response->set_message(request.message());
114 return Status::OK;
115 }
116 Status Unimplemented(ClientContext* context, const EchoRequest& request,
117 EchoResponse* response) GRPC_OVERRIDE {
118 return Status::OK;
119 }
120
121 private:
122 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700123 ClientContext* context, const EchoRequest& request,
124 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700125 return nullptr;
126 }
127 ClientWriterInterface<EchoRequest>* RequestStreamRaw(
128 ClientContext* context, EchoResponse* response) GRPC_OVERRIDE {
129 return nullptr;
130 }
131 ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
132 ClientContext* context, EchoResponse* response, CompletionQueue* cq,
133 void* tag) GRPC_OVERRIDE {
134 return nullptr;
135 }
136 ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
137 ClientContext* context, const EchoRequest& request) GRPC_OVERRIDE {
138 return nullptr;
139 }
140 ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
141 ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
142 void* tag) GRPC_OVERRIDE {
143 return nullptr;
144 }
145 ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
146 ClientContext* context) GRPC_OVERRIDE {
147 return new MockClientReaderWriter<EchoRequest, EchoResponse>();
148 }
149 ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
150 AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
151 void* tag) GRPC_OVERRIDE {
152 return nullptr;
153 }
154 ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
Craig Tiller5f871ac2015-05-08 13:05:51 -0700155 ClientContext* context, const EchoRequest& request,
156 CompletionQueue* cq) GRPC_OVERRIDE {
Yang Gao196ade32015-05-05 13:31:12 -0700157 return nullptr;
158 }
159};
160
161class FakeClient {
162 public:
163 explicit FakeClient(TestService::StubInterface* stub) : stub_(stub) {}
164
165 void DoEcho() {
166 ClientContext context;
167 EchoRequest request;
168 EchoResponse response;
169 request.set_message("hello world");
170 Status s = stub_->Echo(&context, request, &response);
171 EXPECT_EQ(request.message(), response.message());
Yang Gaoc1a2c312015-06-16 10:59:46 -0700172 EXPECT_TRUE(s.ok());
Yang Gao196ade32015-05-05 13:31:12 -0700173 }
174
175 void DoBidiStream() {
176 EchoRequest request;
177 EchoResponse response;
178 ClientContext context;
179 grpc::string msg("hello");
180
181 std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
182 stream = stub_->BidiStream(&context);
183
184 request.set_message(msg + "0");
185 EXPECT_TRUE(stream->Write(request));
186 EXPECT_TRUE(stream->Read(&response));
187 EXPECT_EQ(response.message(), request.message());
188
189 request.set_message(msg + "1");
190 EXPECT_TRUE(stream->Write(request));
191 EXPECT_TRUE(stream->Read(&response));
192 EXPECT_EQ(response.message(), request.message());
193
194 request.set_message(msg + "2");
195 EXPECT_TRUE(stream->Write(request));
196 EXPECT_TRUE(stream->Read(&response));
197 EXPECT_EQ(response.message(), request.message());
198
199 stream->WritesDone();
200 EXPECT_FALSE(stream->Read(&response));
201
202 Status s = stream->Finish();
Yang Gaoc1a2c312015-06-16 10:59:46 -0700203 EXPECT_TRUE(s.ok());
Yang Gao196ade32015-05-05 13:31:12 -0700204 }
205
206 void ResetStub(TestService::StubInterface* stub) { stub_ = stub; }
207
208 private:
209 TestService::StubInterface* stub_;
210};
211
212class TestServiceImpl : public TestService::Service {
213 public:
214 Status Echo(ServerContext* context, const EchoRequest* request,
215 EchoResponse* response) GRPC_OVERRIDE {
216 response->set_message(request->message());
217 return Status::OK;
218 }
219
220 Status BidiStream(ServerContext* context,
221 ServerReaderWriter<EchoResponse, EchoRequest>* stream)
222 GRPC_OVERRIDE {
223 EchoRequest request;
224 EchoResponse response;
225 while (stream->Read(&request)) {
226 gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
227 response.set_message(request.message());
228 stream->Write(response);
229 }
230 return Status::OK;
231 }
232};
233
234class MockTest : public ::testing::Test {
235 protected:
Vijay Paie8a7e302015-08-24 10:52:33 -0700236 MockTest() {}
Yang Gao196ade32015-05-05 13:31:12 -0700237
238 void SetUp() GRPC_OVERRIDE {
239 int port = grpc_pick_unused_port_or_die();
240 server_address_ << "localhost:" << port;
241 // Setup server
242 ServerBuilder builder;
243 builder.AddListeningPort(server_address_.str(),
244 InsecureServerCredentials());
245 builder.RegisterService(&service_);
Yang Gao196ade32015-05-05 13:31:12 -0700246 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_;
Yang Gao196ade32015-05-05 13:31:12 -0700261};
262
263// Do one real rpc and one mocked one
264TEST_F(MockTest, SimpleRpc) {
265 ResetStub();
266 FakeClient client(stub_.get());
267 client.DoEcho();
268 MockStub stub;
269 client.ResetStub(&stub);
270 client.DoEcho();
271}
272
273TEST_F(MockTest, BidiStream) {
274 ResetStub();
275 FakeClient client(stub_.get());
276 client.DoBidiStream();
277 MockStub stub;
278 client.ResetStub(&stub);
279 client.DoBidiStream();
280}
281
282} // namespace
283} // namespace testing
284} // namespace grpc
285
286int main(int argc, char** argv) {
287 grpc_test_init(argc, argv);
288 ::testing::InitGoogleTest(&argc, argv);
289 return RUN_ALL_TESTS();
290}