Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / mojo / public / 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/bindings/allocation_scope.h"
6 #include "mojo/public/bindings/remote_ptr.h"
7 #include "mojo/public/environment/environment.h"
8 #include "mojo/public/tests/test_utils.h"
9 #include "mojo/public/utility/run_loop.h"
10 #include "mojom/sample_factory.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace mojo {
14 namespace test {
15 namespace {
16
17 const char kText1[] = "hello";
18 const char kText2[] = "world";
19
20 class SampleFactoryImpl : public sample::Factory {
21  public:
22   explicit SampleFactoryImpl(sample::ScopedFactoryClientHandle handle)
23       : client_(handle.Pass(), this) {
24   }
25
26   virtual void DoStuff(const sample::Request& request,
27                        ScopedMessagePipeHandle pipe) MOJO_OVERRIDE {
28     std::string text1;
29     if (pipe.is_valid())
30       EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1));
31
32     std::string text2;
33     if (request.pipe().is_valid()) {
34       EXPECT_TRUE(ReadTextMessage(request.pipe().get(), &text2));
35
36       // Ensure that simply accessing request.pipe() does not close it.
37       EXPECT_TRUE(request.pipe().is_valid());
38     }
39
40     ScopedMessagePipeHandle pipe0;
41     if (!text2.empty()) {
42       CreateMessagePipe(&pipe0, &pipe1_);
43       EXPECT_TRUE(WriteTextMessage(pipe1_.get(), text2));
44     }
45
46     AllocationScope scope;
47     sample::Response::Builder response;
48     response.set_x(2);
49     response.set_pipe(pipe0.Pass());
50     client_->DidStuff(response.Finish(), text1);
51   }
52
53   virtual void DoStuff2(ScopedDataPipeConsumerHandle pipe) MOJO_OVERRIDE {
54     // Read the data from the pipe, writing the response (as a string) to
55     // DidStuff2().
56     ASSERT_TRUE(pipe.is_valid());
57     uint32_t data_size = 0;
58     ASSERT_EQ(MOJO_RESULT_OK,
59               ReadDataRaw(pipe.get(), NULL, &data_size,
60                           MOJO_READ_DATA_FLAG_QUERY));
61     ASSERT_NE(0, static_cast<int>(data_size));
62     char data[64];
63     ASSERT_LT(static_cast<int>(data_size), 64);
64     ASSERT_EQ(MOJO_RESULT_OK,
65               ReadDataRaw(pipe.get(), data, &data_size,
66                           MOJO_READ_DATA_FLAG_ALL_OR_NONE));
67
68     AllocationScope scope;
69     client_->DidStuff2(String(std::string(data)));
70   }
71
72  private:
73   RemotePtr<sample::FactoryClient> client_;
74   ScopedMessagePipeHandle pipe1_;
75 };
76
77 class SampleFactoryClientImpl : public sample::FactoryClient {
78  public:
79   explicit SampleFactoryClientImpl(sample::ScopedFactoryHandle handle)
80       : factory_(handle.Pass(), this),
81         got_response_(false) {
82   }
83
84   void Start() {
85     expected_text_reply_ = kText1;
86
87     ScopedMessagePipeHandle pipe0;
88     CreateMessagePipe(&pipe0, &pipe1_);
89
90     EXPECT_TRUE(WriteTextMessage(pipe1_.get(), kText1));
91
92     ScopedMessagePipeHandle pipe2;
93     CreateMessagePipe(&pipe2, &pipe3_);
94
95     EXPECT_TRUE(WriteTextMessage(pipe3_.get(), kText2));
96
97     AllocationScope scope;
98     sample::Request::Builder request;
99     request.set_x(1);
100     request.set_pipe(pipe2.Pass());
101     factory_->DoStuff(request.Finish(), pipe0.Pass());
102   }
103
104   void StartNoPipes() {
105     expected_text_reply_.clear();
106
107     AllocationScope scope;
108     sample::Request::Builder request;
109     request.set_x(1);
110     factory_->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass());
111   }
112
113   // Writes a string to a data pipe and passes the data pipe (consumer) to the
114   // factory.
115   void StartDataPipe() {
116     expected_text_reply_.clear();
117
118     ScopedDataPipeProducerHandle producer_handle;
119     ScopedDataPipeConsumerHandle consumer_handle;
120     MojoCreateDataPipeOptions options = {
121         sizeof(MojoCreateDataPipeOptions),
122         MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE,
123         1,
124         1024};
125     ASSERT_EQ(MOJO_RESULT_OK,
126               CreateDataPipe(&options, &producer_handle, &consumer_handle));
127     expected_text_reply_ = "got it";
128     // +1 for \0.
129     uint32_t data_size = static_cast<uint32_t>(expected_text_reply_.size() + 1);
130     ASSERT_EQ(MOJO_RESULT_OK,
131               WriteDataRaw(producer_handle.get(), expected_text_reply_.c_str(),
132                            &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE));
133
134     AllocationScope scope;
135     factory_->DoStuff2(consumer_handle.Pass());
136   }
137
138   bool got_response() const {
139     return got_response_;
140   }
141
142   virtual void DidStuff(const sample::Response& response,
143                         const String& text_reply) MOJO_OVERRIDE {
144     EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>());
145
146     if (response.pipe().is_valid()) {
147       std::string text2;
148       EXPECT_TRUE(ReadTextMessage(response.pipe().get(), &text2));
149
150       // Ensure that simply accessing response.pipe() does not close it.
151       EXPECT_TRUE(response.pipe().is_valid());
152
153       EXPECT_EQ(std::string(kText2), text2);
154
155       // Do some more tests of handle passing:
156       ScopedMessagePipeHandle p = response.pipe().Pass();
157       EXPECT_TRUE(p.is_valid());
158       EXPECT_FALSE(response.pipe().is_valid());
159     }
160
161     got_response_ = true;
162   }
163
164   virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE {
165     got_response_ = true;
166     EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>());
167   }
168
169  private:
170   RemotePtr<sample::Factory> factory_;
171   ScopedMessagePipeHandle pipe1_;
172   ScopedMessagePipeHandle pipe3_;
173   std::string expected_text_reply_;
174   bool got_response_;
175 };
176
177 }  // namespace
178
179 class HandlePassingTest : public testing::Test {
180  public:
181   void PumpMessages() {
182     loop_.RunUntilIdle();
183   }
184
185  private:
186   Environment env_;
187   RunLoop loop_;
188 };
189
190 TEST_F(HandlePassingTest, Basic) {
191   InterfacePipe<sample::Factory> pipe;
192
193   SampleFactoryImpl factory(pipe.handle_to_peer.Pass());
194   SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass());
195
196   factory_client.Start();
197
198   EXPECT_FALSE(factory_client.got_response());
199
200   PumpMessages();
201
202   EXPECT_TRUE(factory_client.got_response());
203 }
204
205 TEST_F(HandlePassingTest, PassInvalid) {
206   InterfacePipe<sample::Factory> pipe;
207
208   SampleFactoryImpl factory(pipe.handle_to_peer.Pass());
209   SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass());
210
211   factory_client.StartNoPipes();
212
213   EXPECT_FALSE(factory_client.got_response());
214
215   PumpMessages();
216
217   EXPECT_TRUE(factory_client.got_response());
218 }
219
220 // Verifies DataPipeConsumer can be passed and read from.
221 TEST_F(HandlePassingTest, DataPipe) {
222   InterfacePipe<sample::Factory> pipe;
223
224   SampleFactoryImpl factory(pipe.handle_to_peer.Pass());
225   SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass());
226
227   ASSERT_NO_FATAL_FAILURE(factory_client.StartDataPipe());
228
229   EXPECT_FALSE(factory_client.got_response());
230
231   PumpMessages();
232
233   EXPECT_TRUE(factory_client.got_response());
234 }
235
236 }  // namespace test
237 }  // namespace mojo