Upstream version 7.36.149.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/bindings/allocation_scope.h"
6 #include "mojo/public/cpp/environment/environment.h"
7 #include "mojo/public/cpp/test_support/test_utils.h"
8 #include "mojo/public/cpp/utility/run_loop.h"
9 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace mojo {
13 namespace test {
14 namespace {
15
16 const char kText1[] = "hello";
17 const char kText2[] = "world";
18
19 class SampleFactoryImpl : public InterfaceImpl<sample::Factory> {
20  public:
21   virtual void OnConnectionError() MOJO_OVERRIDE {
22     delete this;
23   }
24
25   virtual void SetClient(sample::FactoryClient* client) MOJO_OVERRIDE {
26     client_ = client;
27   }
28
29   virtual void DoStuff(const sample::Request& request,
30                        ScopedMessagePipeHandle pipe) MOJO_OVERRIDE {
31     std::string text1;
32     if (pipe.is_valid())
33       EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1));
34
35     std::string text2;
36     if (request.pipe().is_valid()) {
37       EXPECT_TRUE(ReadTextMessage(request.pipe().get(), &text2));
38
39       // Ensure that simply accessing request.pipe() does not close it.
40       EXPECT_TRUE(request.pipe().is_valid());
41     }
42
43     ScopedMessagePipeHandle pipe0;
44     if (!text2.empty()) {
45       CreateMessagePipe(&pipe0, &pipe1_);
46       EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
47     }
48
49     AllocationScope scope;
50     sample::Response::Builder response;
51     response.set_x(2);
52     response.set_pipe(pipe0.Pass());
53     client_->DidStuff(response.Finish(), text1);
54   }
55
56   virtual void DoStuff2(ScopedDataPipeConsumerHandle pipe) MOJO_OVERRIDE {
57     // Read the data from the pipe, writing the response (as a string) to
58     // DidStuff2().
59     ASSERT_TRUE(pipe.is_valid());
60     uint32_t data_size = 0;
61     ASSERT_EQ(MOJO_RESULT_OK,
62               ReadDataRaw(pipe.get(), NULL, &data_size,
63                           MOJO_READ_DATA_FLAG_QUERY));
64     ASSERT_NE(0, static_cast<int>(data_size));
65     char data[64];
66     ASSERT_LT(static_cast<int>(data_size), 64);
67     ASSERT_EQ(MOJO_RESULT_OK,
68               ReadDataRaw(pipe.get(), data, &data_size,
69                           MOJO_READ_DATA_FLAG_ALL_OR_NONE));
70
71     AllocationScope scope;
72     client_->DidStuff2(String(std::string(data)));
73   }
74
75  private:
76   sample::FactoryClient* client_;
77   ScopedMessagePipeHandle pipe1_;
78 };
79
80 class SampleFactoryClientImpl : public sample::FactoryClient {
81  public:
82   SampleFactoryClientImpl() : got_response_(false) {
83   }
84
85   void set_expected_text_reply(const std::string& expected_text_reply) {
86     expected_text_reply_ = expected_text_reply;
87   }
88
89   bool got_response() const {
90     return got_response_;
91   }
92
93   virtual void DidStuff(const sample::Response& response,
94                         const String& text_reply) MOJO_OVERRIDE {
95     EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>());
96
97     if (response.pipe().is_valid()) {
98       std::string text2;
99       EXPECT_TRUE(ReadTextMessage(response.pipe().get(), &text2));
100
101       // Ensure that simply accessing response.pipe() does not close it.
102       EXPECT_TRUE(response.pipe().is_valid());
103
104       EXPECT_EQ(std::string(kText2), text2);
105
106       // Do some more tests of handle passing:
107       ScopedMessagePipeHandle p = response.pipe().Pass();
108       EXPECT_TRUE(p.is_valid());
109       EXPECT_FALSE(response.pipe().is_valid());
110     }
111
112     got_response_ = true;
113   }
114
115   virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE {
116     got_response_ = true;
117     EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>());
118   }
119
120  private:
121   ScopedMessagePipeHandle pipe1_;
122   ScopedMessagePipeHandle pipe3_;
123   std::string expected_text_reply_;
124   bool got_response_;
125 };
126
127 class HandlePassingTest : public testing::Test {
128  public:
129   virtual void TearDown() {
130     PumpMessages();
131   }
132
133   void PumpMessages() {
134     loop_.RunUntilIdle();
135   }
136
137  private:
138   Environment env_;
139   RunLoop loop_;
140 };
141
142 TEST_F(HandlePassingTest, Basic) {
143   sample::FactoryPtr factory;
144   BindToProxy(new SampleFactoryImpl(), &factory);
145
146   SampleFactoryClientImpl factory_client;
147   factory_client.set_expected_text_reply(kText1);
148
149   factory->SetClient(&factory_client);
150
151   ScopedMessagePipeHandle pipe0, pipe1;
152   CreateMessagePipe(&pipe0, &pipe1);
153
154   EXPECT_TRUE(WriteTextMessage(pipe1.get(), kText1));
155
156   ScopedMessagePipeHandle pipe2, pipe3;
157   CreateMessagePipe(&pipe2, &pipe3);
158
159   EXPECT_TRUE(WriteTextMessage(pipe3.get(), kText2));
160
161   {
162     AllocationScope scope;
163     sample::Request::Builder request;
164     request.set_x(1);
165     request.set_pipe(pipe2.Pass());
166     factory->DoStuff(request.Finish(), pipe0.Pass());
167   }
168
169   EXPECT_FALSE(factory_client.got_response());
170
171   PumpMessages();
172
173   EXPECT_TRUE(factory_client.got_response());
174 }
175
176 TEST_F(HandlePassingTest, PassInvalid) {
177   sample::FactoryPtr factory;
178   BindToProxy(new SampleFactoryImpl(), &factory);
179
180   SampleFactoryClientImpl factory_client;
181   factory->SetClient(&factory_client);
182
183   {
184     AllocationScope scope;
185     sample::Request::Builder request;
186     request.set_x(1);
187     factory->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass());
188   }
189
190   EXPECT_FALSE(factory_client.got_response());
191
192   PumpMessages();
193
194   EXPECT_TRUE(factory_client.got_response());
195 }
196
197 // Verifies DataPipeConsumer can be passed and read from.
198 TEST_F(HandlePassingTest, DataPipe) {
199   sample::FactoryPtr factory;
200   BindToProxy(new SampleFactoryImpl(), &factory);
201
202   SampleFactoryClientImpl factory_client;
203   factory->SetClient(&factory_client);
204
205   // Writes a string to a data pipe and passes the data pipe (consumer) to the
206   // factory.
207   ScopedDataPipeProducerHandle producer_handle;
208   ScopedDataPipeConsumerHandle consumer_handle;
209   MojoCreateDataPipeOptions options = {
210       sizeof(MojoCreateDataPipeOptions),
211       MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
212       1,
213       1024};
214   ASSERT_EQ(MOJO_RESULT_OK,
215             CreateDataPipe(&options, &producer_handle, &consumer_handle));
216   std::string expected_text_reply = "got it";
217   factory_client.set_expected_text_reply(expected_text_reply);
218   // +1 for \0.
219   uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1);
220   ASSERT_EQ(MOJO_RESULT_OK,
221             WriteDataRaw(producer_handle.get(), expected_text_reply.c_str(),
222                          &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
223
224   {
225     AllocationScope scope;
226     factory->DoStuff2(consumer_handle.Pass());
227   }
228
229   EXPECT_FALSE(factory_client.got_response());
230
231   PumpMessages();
232
233   EXPECT_TRUE(factory_client.got_response());
234 }
235
236 TEST_F(HandlePassingTest, PipesAreClosed) {
237   sample::FactoryPtr factory;
238   BindToProxy(new SampleFactoryImpl(), &factory);
239
240   SampleFactoryClientImpl factory_client;
241   factory->SetClient(&factory_client);
242
243   MessagePipe extra_pipe;
244
245   MojoHandle handle0_value = extra_pipe.handle0.get().value();
246   MojoHandle handle1_value = extra_pipe.handle1.get().value();
247
248   {
249     AllocationScope scope;
250
251     Array<MessagePipeHandle>::Builder pipes(2);
252     pipes[0] = extra_pipe.handle0.Pass();
253     pipes[1] = extra_pipe.handle1.Pass();
254
255     sample::Request::Builder request_builder;
256     request_builder.set_more_pipes(pipes.Finish());
257
258     sample::Request request = request_builder.Finish();
259
260     factory->DoStuff(request, ScopedMessagePipeHandle());
261
262     // The handles should have been transferred to the underlying Message.
263     EXPECT_EQ(MOJO_HANDLE_INVALID, request.more_pipes()[0].get().value());
264     EXPECT_EQ(MOJO_HANDLE_INVALID, request.more_pipes()[1].get().value());
265   }
266
267   // We expect the pipes to have been closed.
268   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value));
269   EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value));
270 }
271
272 }  // namespace
273 }  // namespace test
274 }  // namespace mojo