Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / mojo / public / cpp / bindings / tests / handle_passing_unittest.cc
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