Line data Source code
1 : /*
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 <grpc/grpc.h>
37 : #include <grpc/support/thd.h>
38 : #include <grpc/support/time.h>
39 : #include <grpc++/channel.h>
40 : #include <grpc++/client_context.h>
41 : #include <grpc++/create_channel.h>
42 : #include <grpc++/server.h>
43 : #include <grpc++/server_builder.h>
44 : #include <grpc++/server_context.h>
45 : #include <gtest/gtest.h>
46 :
47 : #include "test/core/util/port.h"
48 : #include "test/core/util/test_config.h"
49 : #include "test/cpp/util/echo_duplicate.grpc.pb.h"
50 : #include "test/cpp/util/echo.grpc.pb.h"
51 :
52 : using grpc::cpp::test::util::EchoRequest;
53 : using grpc::cpp::test::util::EchoResponse;
54 : using grpc::cpp::test::util::TestService;
55 : using std::chrono::system_clock;
56 :
57 : namespace grpc {
58 : namespace testing {
59 :
60 : namespace {
61 : template <class W, class R>
62 : class MockClientReaderWriter GRPC_FINAL
63 : : public ClientReaderWriterInterface<W, R> {
64 : public:
65 : void WaitForInitialMetadata() {}
66 : bool Read(R* msg) GRPC_OVERRIDE { return true; }
67 : bool Write(const W& msg) GRPC_OVERRIDE { return true; }
68 : bool WritesDone() GRPC_OVERRIDE { return true; }
69 : Status Finish() GRPC_OVERRIDE { return Status::OK; }
70 : };
71 : template <>
72 2 : class MockClientReaderWriter<EchoRequest, EchoResponse> GRPC_FINAL
73 : : public ClientReaderWriterInterface<EchoRequest, EchoResponse> {
74 : public:
75 1 : MockClientReaderWriter() : writes_done_(false) {}
76 0 : void WaitForInitialMetadata() {}
77 4 : bool Read(EchoResponse* msg) GRPC_OVERRIDE {
78 4 : if (writes_done_) return false;
79 3 : msg->set_message(last_message_);
80 3 : return true;
81 : }
82 :
83 3 : bool Write(const EchoRequest& msg,
84 : const WriteOptions& options) GRPC_OVERRIDE {
85 3 : gpr_log(GPR_INFO, "mock recv msg %s", msg.message().c_str());
86 3 : last_message_ = msg.message();
87 3 : return true;
88 : }
89 1 : bool WritesDone() GRPC_OVERRIDE {
90 1 : writes_done_ = true;
91 1 : return true;
92 : }
93 1 : Status Finish() GRPC_OVERRIDE { return Status::OK; }
94 :
95 : private:
96 : bool writes_done_;
97 : grpc::string last_message_;
98 : };
99 :
100 : // Mocked stub.
101 : class MockStub : public TestService::StubInterface {
102 : public:
103 2 : MockStub() {}
104 2 : ~MockStub() {}
105 1 : Status Echo(ClientContext* context, const EchoRequest& request,
106 : EchoResponse* response) GRPC_OVERRIDE {
107 1 : response->set_message(request.message());
108 1 : return Status::OK;
109 : }
110 0 : Status Unimplemented(ClientContext* context, const EchoRequest& request,
111 : EchoResponse* response) GRPC_OVERRIDE {
112 0 : return Status::OK;
113 : }
114 :
115 : private:
116 0 : ClientAsyncResponseReaderInterface<EchoResponse>* AsyncEchoRaw(
117 : ClientContext* context, const EchoRequest& request,
118 : CompletionQueue* cq) GRPC_OVERRIDE {
119 0 : return nullptr;
120 : }
121 0 : ClientWriterInterface<EchoRequest>* RequestStreamRaw(
122 : ClientContext* context, EchoResponse* response) GRPC_OVERRIDE {
123 0 : return nullptr;
124 : }
125 0 : ClientAsyncWriterInterface<EchoRequest>* AsyncRequestStreamRaw(
126 : ClientContext* context, EchoResponse* response, CompletionQueue* cq,
127 : void* tag) GRPC_OVERRIDE {
128 0 : return nullptr;
129 : }
130 0 : ClientReaderInterface<EchoResponse>* ResponseStreamRaw(
131 : ClientContext* context, const EchoRequest& request) GRPC_OVERRIDE {
132 0 : return nullptr;
133 : }
134 0 : ClientAsyncReaderInterface<EchoResponse>* AsyncResponseStreamRaw(
135 : ClientContext* context, const EchoRequest& request, CompletionQueue* cq,
136 : void* tag) GRPC_OVERRIDE {
137 0 : return nullptr;
138 : }
139 1 : ClientReaderWriterInterface<EchoRequest, EchoResponse>* BidiStreamRaw(
140 : ClientContext* context) GRPC_OVERRIDE {
141 1 : return new MockClientReaderWriter<EchoRequest, EchoResponse>();
142 : }
143 : ClientAsyncReaderWriterInterface<EchoRequest, EchoResponse>*
144 0 : AsyncBidiStreamRaw(ClientContext* context, CompletionQueue* cq,
145 : void* tag) GRPC_OVERRIDE {
146 0 : return nullptr;
147 : }
148 0 : ClientAsyncResponseReaderInterface<EchoResponse>* AsyncUnimplementedRaw(
149 : ClientContext* context, const EchoRequest& request,
150 : CompletionQueue* cq) GRPC_OVERRIDE {
151 0 : return nullptr;
152 : }
153 : };
154 :
155 : class FakeClient {
156 : public:
157 2 : explicit FakeClient(TestService::StubInterface* stub) : stub_(stub) {}
158 :
159 2 : void DoEcho() {
160 2 : ClientContext context;
161 4 : EchoRequest request;
162 4 : EchoResponse response;
163 2 : request.set_message("hello world");
164 4 : Status s = stub_->Echo(&context, request, &response);
165 2 : EXPECT_EQ(request.message(), response.message());
166 4 : EXPECT_TRUE(s.ok());
167 2 : }
168 :
169 2 : void DoBidiStream() {
170 2 : EchoRequest request;
171 4 : EchoResponse response;
172 4 : ClientContext context;
173 4 : grpc::string msg("hello");
174 :
175 : std::unique_ptr<ClientReaderWriterInterface<EchoRequest, EchoResponse>>
176 4 : stream = stub_->BidiStream(&context);
177 :
178 2 : request.set_message(msg + "0");
179 2 : EXPECT_TRUE(stream->Write(request));
180 2 : EXPECT_TRUE(stream->Read(&response));
181 2 : EXPECT_EQ(response.message(), request.message());
182 :
183 2 : request.set_message(msg + "1");
184 2 : EXPECT_TRUE(stream->Write(request));
185 2 : EXPECT_TRUE(stream->Read(&response));
186 2 : EXPECT_EQ(response.message(), request.message());
187 :
188 2 : request.set_message(msg + "2");
189 2 : EXPECT_TRUE(stream->Write(request));
190 2 : EXPECT_TRUE(stream->Read(&response));
191 2 : EXPECT_EQ(response.message(), request.message());
192 :
193 2 : stream->WritesDone();
194 2 : EXPECT_FALSE(stream->Read(&response));
195 :
196 2 : Status s = stream->Finish();
197 4 : EXPECT_TRUE(s.ok());
198 2 : }
199 :
200 2 : void ResetStub(TestService::StubInterface* stub) { stub_ = stub; }
201 :
202 : private:
203 : TestService::StubInterface* stub_;
204 : };
205 :
206 4 : class TestServiceImpl : public TestService::Service {
207 : public:
208 1 : Status Echo(ServerContext* context, const EchoRequest* request,
209 : EchoResponse* response) GRPC_OVERRIDE {
210 1 : response->set_message(request->message());
211 1 : return Status::OK;
212 : }
213 :
214 1 : Status BidiStream(ServerContext* context,
215 : ServerReaderWriter<EchoResponse, EchoRequest>* stream)
216 : GRPC_OVERRIDE {
217 1 : EchoRequest request;
218 2 : EchoResponse response;
219 5 : while (stream->Read(&request)) {
220 3 : gpr_log(GPR_INFO, "recv msg %s", request.message().c_str());
221 3 : response.set_message(request.message());
222 3 : stream->Write(response);
223 : }
224 2 : return Status::OK;
225 : }
226 : };
227 :
228 2 : class MockTest : public ::testing::Test {
229 : protected:
230 2 : MockTest() {}
231 :
232 2 : void SetUp() GRPC_OVERRIDE {
233 2 : int port = grpc_pick_unused_port_or_die();
234 2 : server_address_ << "localhost:" << port;
235 : // Setup server
236 2 : ServerBuilder builder;
237 : builder.AddListeningPort(server_address_.str(),
238 2 : InsecureServerCredentials());
239 2 : builder.RegisterService(&service_);
240 2 : server_ = builder.BuildAndStart();
241 2 : }
242 :
243 2 : void TearDown() GRPC_OVERRIDE { server_->Shutdown(); }
244 :
245 2 : void ResetStub() {
246 : std::shared_ptr<Channel> channel =
247 2 : CreateChannel(server_address_.str(), InsecureCredentials());
248 2 : stub_ = grpc::cpp::test::util::TestService::NewStub(channel);
249 2 : }
250 :
251 : std::unique_ptr<grpc::cpp::test::util::TestService::Stub> stub_;
252 : std::unique_ptr<Server> server_;
253 : std::ostringstream server_address_;
254 : TestServiceImpl service_;
255 : };
256 :
257 : // Do one real rpc and one mocked one
258 5 : TEST_F(MockTest, SimpleRpc) {
259 1 : ResetStub();
260 1 : FakeClient client(stub_.get());
261 1 : client.DoEcho();
262 1 : MockStub stub;
263 1 : client.ResetStub(&stub);
264 1 : client.DoEcho();
265 1 : }
266 :
267 5 : TEST_F(MockTest, BidiStream) {
268 1 : ResetStub();
269 1 : FakeClient client(stub_.get());
270 1 : client.DoBidiStream();
271 1 : MockStub stub;
272 1 : client.ResetStub(&stub);
273 1 : client.DoBidiStream();
274 1 : }
275 :
276 : } // namespace
277 : } // namespace testing
278 : } // namespace grpc
279 :
280 1 : int main(int argc, char** argv) {
281 1 : grpc_test_init(argc, argv);
282 1 : ::testing::InitGoogleTest(&argc, argv);
283 1 : return RUN_ALL_TESTS();
284 3 : }
|