Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(430)

Side by Side Diff: mojo/public/cpp/bindings/tests/handle_passing_unittest.cc

Issue 814543006: Move //mojo/{public, edk} underneath //third_party (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/public/cpp/environment/environment.h"
6 #include "mojo/public/cpp/test_support/test_utils.h"
7 #include "mojo/public/cpp/utility/run_loop.h"
8 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10
11 namespace mojo {
12 namespace test {
13 namespace {
14
15 const char kText1[] = "hello";
16 const char kText2[] = "world";
17
18 class StringRecorder {
19 public:
20 explicit StringRecorder(std::string* buf) : buf_(buf) {}
21 void Run(const String& a) const { *buf_ = a.To<std::string>(); }
22
23 private:
24 std::string* buf_;
25 };
26
27 class ImportedInterfaceImpl
28 : public InterfaceImpl<imported::ImportedInterface> {
29 public:
30 void DoSomething() override { do_something_count_++; }
31
32 static int do_something_count() { return do_something_count_; }
33
34 private:
35 static int do_something_count_;
36 };
37 int ImportedInterfaceImpl::do_something_count_ = 0;
38
39 class SampleNamedObjectImpl : public InterfaceImpl<sample::NamedObject> {
40 public:
41 void SetName(const mojo::String& name) override { name_ = name; }
42
43 void GetName(const mojo::Callback<void(mojo::String)>& callback) override {
44 callback.Run(name_);
45 }
46
47 private:
48 std::string name_;
49 };
50
51 class SampleFactoryImpl : public InterfaceImpl<sample::Factory> {
52 public:
53 void DoStuff(sample::RequestPtr request,
54 ScopedMessagePipeHandle pipe) override {
55 std::string text1;
56 if (pipe.is_valid())
57 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1));
58
59 std::string text2;
60 if (request->pipe.is_valid()) {
61 EXPECT_TRUE(ReadTextMessage(request->pipe.get(), &text2));
62
63 // Ensure that simply accessing request->pipe does not close it.
64 EXPECT_TRUE(request->pipe.is_valid());
65 }
66
67 ScopedMessagePipeHandle pipe0;
68 if (!text2.empty()) {
69 CreateMessagePipe(nullptr, &pipe0, &pipe1_);
70 EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
71 }
72
73 sample::ResponsePtr response(sample::Response::New());
74 response->x = 2;
75 response->pipe = pipe0.Pass();
76 client()->DidStuff(response.Pass(), text1);
77
78 if (request->obj)
79 request->obj->DoSomething();
80 }
81
82 void DoStuff2(ScopedDataPipeConsumerHandle pipe) override {
83 // Read the data from the pipe, writing the response (as a string) to
84 // DidStuff2().
85 ASSERT_TRUE(pipe.is_valid());
86 uint32_t data_size = 0;
87 ASSERT_EQ(MOJO_RESULT_OK,
88 ReadDataRaw(
89 pipe.get(), nullptr, &data_size, MOJO_READ_DATA_FLAG_QUERY));
90 ASSERT_NE(0, static_cast<int>(data_size));
91 char data[64];
92 ASSERT_LT(static_cast<int>(data_size), 64);
93 ASSERT_EQ(
94 MOJO_RESULT_OK,
95 ReadDataRaw(
96 pipe.get(), data, &data_size, MOJO_READ_DATA_FLAG_ALL_OR_NONE));
97
98 client()->DidStuff2(data);
99 }
100
101 void CreateNamedObject(
102 InterfaceRequest<sample::NamedObject> object_request) override {
103 EXPECT_TRUE(object_request.is_pending());
104 BindToRequest(new SampleNamedObjectImpl(), &object_request);
105 }
106
107 // These aren't called or implemented, but exist here to test that the
108 // methods are generated with the correct argument types for imported
109 // interfaces.
110 void RequestImportedInterface(
111 InterfaceRequest<imported::ImportedInterface> imported,
112 const mojo::Callback<void(InterfaceRequest<imported::ImportedInterface>)>&
113 callback) override {}
114 void TakeImportedInterface(
115 imported::ImportedInterfacePtr imported,
116 const mojo::Callback<void(imported::ImportedInterfacePtr)>& callback)
117 override {}
118
119 private:
120 ScopedMessagePipeHandle pipe1_;
121 };
122
123 class SampleFactoryClientImpl : public sample::FactoryClient {
124 public:
125 SampleFactoryClientImpl() : got_response_(false) {}
126
127 void set_expected_text_reply(const std::string& expected_text_reply) {
128 expected_text_reply_ = expected_text_reply;
129 }
130
131 bool got_response() const { return got_response_; }
132
133 void DidStuff(sample::ResponsePtr response,
134 const String& text_reply) override {
135 EXPECT_EQ(expected_text_reply_, text_reply);
136
137 if (response->pipe.is_valid()) {
138 std::string text2;
139 EXPECT_TRUE(ReadTextMessage(response->pipe.get(), &text2));
140
141 // Ensure that simply accessing response.pipe does not close it.
142 EXPECT_TRUE(response->pipe.is_valid());
143
144 EXPECT_EQ(std::string(kText2), text2);
145
146 // Do some more tests of handle passing:
147 ScopedMessagePipeHandle p = response->pipe.Pass();
148 EXPECT_TRUE(p.is_valid());
149 EXPECT_FALSE(response->pipe.is_valid());
150 }
151
152 got_response_ = true;
153 }
154
155 void DidStuff2(const String& text_reply) override {
156 got_response_ = true;
157 EXPECT_EQ(expected_text_reply_, text_reply);
158 }
159
160 private:
161 ScopedMessagePipeHandle pipe1_;
162 ScopedMessagePipeHandle pipe3_;
163 std::string expected_text_reply_;
164 bool got_response_;
165 };
166
167 class HandlePassingTest : public testing::Test {
168 public:
169 void TearDown() override { PumpMessages(); }
170
171 void PumpMessages() { loop_.RunUntilIdle(); }
172
173 private:
174 Environment env_;
175 RunLoop loop_;
176 };
177
178 TEST_F(HandlePassingTest, Basic) {
179 sample::FactoryPtr factory;
180 BindToProxy(new SampleFactoryImpl(), &factory);
181
182 SampleFactoryClientImpl factory_client;
183 factory_client.set_expected_text_reply(kText1);
184
185 factory.set_client(&factory_client);
186
187 MessagePipe pipe0;
188 EXPECT_TRUE(WriteTextMessage(pipe0.handle1.get(), kText1));
189
190 MessagePipe pipe1;
191 EXPECT_TRUE(WriteTextMessage(pipe1.handle1.get(), kText2));
192
193 imported::ImportedInterfacePtr imported;
194 BindToProxy(new ImportedInterfaceImpl(), &imported);
195
196 sample::RequestPtr request(sample::Request::New());
197 request->x = 1;
198 request->pipe = pipe1.handle0.Pass();
199 request->obj = imported.Pass();
200 factory->DoStuff(request.Pass(), pipe0.handle0.Pass());
201
202 EXPECT_FALSE(factory_client.got_response());
203 int count_before = ImportedInterfaceImpl::do_something_count();
204
205 PumpMessages();
206
207 EXPECT_TRUE(factory_client.got_response());
208 EXPECT_EQ(1, ImportedInterfaceImpl::do_something_count() - count_before);
209 }
210
211 TEST_F(HandlePassingTest, PassInvalid) {
212 sample::FactoryPtr factory;
213 BindToProxy(new SampleFactoryImpl(), &factory);
214
215 SampleFactoryClientImpl factory_client;
216 factory.set_client(&factory_client);
217
218 sample::RequestPtr request(sample::Request::New());
219 request->x = 1;
220 factory->DoStuff(request.Pass(), ScopedMessagePipeHandle().Pass());
221
222 EXPECT_FALSE(factory_client.got_response());
223
224 PumpMessages();
225
226 EXPECT_TRUE(factory_client.got_response());
227 }
228
229 // Verifies DataPipeConsumer can be passed and read from.
230 TEST_F(HandlePassingTest, DataPipe) {
231 sample::FactoryPtr factory;
232 BindToProxy(new SampleFactoryImpl(), &factory);
233
234 SampleFactoryClientImpl factory_client;
235 factory.set_client(&factory_client);
236
237 // Writes a string to a data pipe and passes the data pipe (consumer) to the
238 // factory.
239 ScopedDataPipeProducerHandle producer_handle;
240 ScopedDataPipeConsumerHandle consumer_handle;
241 MojoCreateDataPipeOptions options = {sizeof(MojoCreateDataPipeOptions),
242 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
243 1,
244 1024};
245 ASSERT_EQ(MOJO_RESULT_OK,
246 CreateDataPipe(&options, &producer_handle, &consumer_handle));
247 std::string expected_text_reply = "got it";
248 factory_client.set_expected_text_reply(expected_text_reply);
249 // +1 for \0.
250 uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1);
251 ASSERT_EQ(MOJO_RESULT_OK,
252 WriteDataRaw(producer_handle.get(),
253 expected_text_reply.c_str(),
254 &data_size,
255 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
256
257 factory->DoStuff2(consumer_handle.Pass());
258
259 EXPECT_FALSE(factory_client.got_response());
260
261 PumpMessages();
262
263 EXPECT_TRUE(factory_client.got_response());
264 }
265
266 TEST_F(HandlePassingTest, PipesAreClosed) {
267 sample::FactoryPtr factory;
268 BindToProxy(new SampleFactoryImpl(), &factory);
269
270 SampleFactoryClientImpl factory_client;
271 factory.set_client(&factory_client);
272
273 MessagePipe extra_pipe;
274
275 MojoHandle handle0_value = extra_pipe.handle0.get().value();
276 MojoHandle handle1_value = extra_pipe.handle1.get().value();
277
278 {
279 Array<ScopedMessagePipeHandle> pipes(2);
280 pipes[0] = extra_pipe.handle0.Pass();
281 pipes[1] = extra_pipe.handle1.Pass();
282
283 sample::RequestPtr request(sample::Request::New());
284 request->more_pipes = pipes.Pass();
285
286 factory->DoStuff(request.Pass(), ScopedMessagePipeHandle());
287 }
288
289 // We expect the pipes to have been closed.
290 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value));
291 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value));
292 }
293
294 TEST_F(HandlePassingTest, IsHandle) {
295 // Validate that mojo::internal::IsHandle<> works as expected since this.
296 // template is key to ensuring that we don't leak handles.
297 EXPECT_TRUE(internal::IsHandle<Handle>::value);
298 EXPECT_TRUE(internal::IsHandle<MessagePipeHandle>::value);
299 EXPECT_TRUE(internal::IsHandle<DataPipeConsumerHandle>::value);
300 EXPECT_TRUE(internal::IsHandle<DataPipeProducerHandle>::value);
301 EXPECT_TRUE(internal::IsHandle<SharedBufferHandle>::value);
302
303 // Basic sanity checks...
304 EXPECT_FALSE(internal::IsHandle<int>::value);
305 EXPECT_FALSE(internal::IsHandle<sample::FactoryPtr>::value);
306 EXPECT_FALSE(internal::IsHandle<String>::value);
307 }
308
309 TEST_F(HandlePassingTest, CreateNamedObject) {
310 sample::FactoryPtr factory;
311 BindToProxy(new SampleFactoryImpl(), &factory);
312
313 sample::NamedObjectPtr object1;
314 EXPECT_FALSE(object1);
315
316 InterfaceRequest<sample::NamedObject> object1_request = GetProxy(&object1);
317 EXPECT_TRUE(object1_request.is_pending());
318 factory->CreateNamedObject(object1_request.Pass());
319 EXPECT_FALSE(object1_request.is_pending()); // We've passed the request.
320
321 ASSERT_TRUE(object1);
322 object1->SetName("object1");
323
324 sample::NamedObjectPtr object2;
325 factory->CreateNamedObject(GetProxy(&object2));
326 object2->SetName("object2");
327
328 std::string name1;
329 object1->GetName(StringRecorder(&name1));
330
331 std::string name2;
332 object2->GetName(StringRecorder(&name2));
333
334 PumpMessages(); // Yield for results.
335
336 EXPECT_EQ(std::string("object1"), name1);
337 EXPECT_EQ(std::string("object2"), name2);
338 }
339
340 } // namespace
341 } // namespace test
342 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/equals_unittest.cc ('k') | mojo/public/cpp/bindings/tests/interface_ptr_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698