OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/allocation_scope.h" | 5 #include "mojo/public/cpp/bindings/allocation_scope.h" |
6 #include "mojo/public/cpp/bindings/remote_ptr.h" | 6 #include "mojo/public/cpp/bindings/tests/test_bindings_utils.h" |
7 #include "mojo/public/cpp/environment/environment.h" | 7 #include "mojo/public/cpp/environment/environment.h" |
8 #include "mojo/public/cpp/test_support/test_utils.h" | 8 #include "mojo/public/cpp/test_support/test_utils.h" |
9 #include "mojo/public/cpp/utility/run_loop.h" | 9 #include "mojo/public/cpp/utility/run_loop.h" |
10 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" | 10 #include "mojo/public/interfaces/bindings/tests/sample_factory.mojom.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 | 12 |
13 namespace mojo { | 13 namespace mojo { |
14 namespace test { | 14 namespace test { |
15 namespace { | 15 namespace { |
16 | 16 |
17 const char kText1[] = "hello"; | 17 const char kText1[] = "hello"; |
18 const char kText2[] = "world"; | 18 const char kText2[] = "world"; |
19 | 19 |
20 class SampleFactoryImpl : public sample::Factory { | 20 class SampleFactoryImpl : public sample::Factory { |
21 public: | 21 public: |
22 explicit SampleFactoryImpl(sample::ScopedFactoryClientHandle handle) | 22 virtual void SetClient(sample::FactoryClient* client) MOJO_OVERRIDE { |
23 : client_(handle.Pass(), this) { | 23 client_ = client; |
24 } | 24 } |
25 | 25 |
26 virtual void DoStuff(const sample::Request& request, | 26 virtual void DoStuff(const sample::Request& request, |
27 ScopedMessagePipeHandle pipe) MOJO_OVERRIDE { | 27 ScopedMessagePipeHandle pipe) MOJO_OVERRIDE { |
28 std::string text1; | 28 std::string text1; |
29 if (pipe.is_valid()) | 29 if (pipe.is_valid()) |
30 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1)); | 30 EXPECT_TRUE(ReadTextMessage(pipe.get(), &text1)); |
31 | 31 |
32 std::string text2; | 32 std::string text2; |
33 if (request.pipe().is_valid()) { | 33 if (request.pipe().is_valid()) { |
(...skipping 29 matching lines...) Expand all Loading... |
63 ASSERT_LT(static_cast<int>(data_size), 64); | 63 ASSERT_LT(static_cast<int>(data_size), 64); |
64 ASSERT_EQ(MOJO_RESULT_OK, | 64 ASSERT_EQ(MOJO_RESULT_OK, |
65 ReadDataRaw(pipe.get(), data, &data_size, | 65 ReadDataRaw(pipe.get(), data, &data_size, |
66 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); | 66 MOJO_READ_DATA_FLAG_ALL_OR_NONE)); |
67 | 67 |
68 AllocationScope scope; | 68 AllocationScope scope; |
69 client_->DidStuff2(String(std::string(data))); | 69 client_->DidStuff2(String(std::string(data))); |
70 } | 70 } |
71 | 71 |
72 private: | 72 private: |
73 RemotePtr<sample::FactoryClient> client_; | 73 sample::FactoryClient* client_; |
74 ScopedMessagePipeHandle pipe1_; | 74 ScopedMessagePipeHandle pipe1_; |
75 }; | 75 }; |
76 | 76 |
77 class SampleFactoryClientImpl : public sample::FactoryClient { | 77 class SampleFactoryClientImpl : public sample::FactoryClient { |
78 public: | 78 public: |
79 explicit SampleFactoryClientImpl(sample::ScopedFactoryHandle handle) | 79 SampleFactoryClientImpl() : got_response_(false) { |
80 : factory_(handle.Pass(), this), | |
81 got_response_(false) { | |
82 } | 80 } |
83 | 81 |
84 void Start() { | 82 void set_expected_text_reply(const std::string& expected_text_reply) { |
85 expected_text_reply_ = kText1; | 83 expected_text_reply_ = expected_text_reply; |
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 } | 84 } |
137 | 85 |
138 bool got_response() const { | 86 bool got_response() const { |
139 return got_response_; | 87 return got_response_; |
140 } | 88 } |
141 | 89 |
142 virtual void DidStuff(const sample::Response& response, | 90 virtual void DidStuff(const sample::Response& response, |
143 const String& text_reply) MOJO_OVERRIDE { | 91 const String& text_reply) MOJO_OVERRIDE { |
144 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); | 92 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); |
145 | 93 |
(...skipping 14 matching lines...) Expand all Loading... |
160 | 108 |
161 got_response_ = true; | 109 got_response_ = true; |
162 } | 110 } |
163 | 111 |
164 virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE { | 112 virtual void DidStuff2(const String& text_reply) MOJO_OVERRIDE { |
165 got_response_ = true; | 113 got_response_ = true; |
166 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); | 114 EXPECT_EQ(expected_text_reply_, text_reply.To<std::string>()); |
167 } | 115 } |
168 | 116 |
169 private: | 117 private: |
170 RemotePtr<sample::Factory> factory_; | |
171 ScopedMessagePipeHandle pipe1_; | 118 ScopedMessagePipeHandle pipe1_; |
172 ScopedMessagePipeHandle pipe3_; | 119 ScopedMessagePipeHandle pipe3_; |
173 std::string expected_text_reply_; | 120 std::string expected_text_reply_; |
174 bool got_response_; | 121 bool got_response_; |
175 }; | 122 }; |
176 | 123 |
177 class HandlePassingTest : public testing::Test { | 124 class HandlePassingTest : public testing::Test { |
178 public: | 125 public: |
| 126 virtual void TearDown() { |
| 127 PumpMessages(); |
| 128 } |
| 129 |
179 void PumpMessages() { | 130 void PumpMessages() { |
180 loop_.RunUntilIdle(); | 131 loop_.RunUntilIdle(); |
181 } | 132 } |
182 | 133 |
183 private: | 134 private: |
184 Environment env_; | 135 Environment env_; |
185 RunLoop loop_; | 136 RunLoop loop_; |
186 }; | 137 }; |
187 | 138 |
188 TEST_F(HandlePassingTest, Basic) { | 139 TEST_F(HandlePassingTest, Basic) { |
189 InterfacePipe<sample::Factory> pipe; | 140 sample::FactoryPtr factory; |
| 141 MakeRemote(new SampleFactoryImpl(), &factory); |
190 | 142 |
191 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 143 SampleFactoryClientImpl factory_client; |
192 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 144 factory_client.set_expected_text_reply(kText1); |
193 | 145 |
194 factory_client.Start(); | 146 factory->SetClient(&factory_client); |
| 147 |
| 148 ScopedMessagePipeHandle pipe0, pipe1; |
| 149 CreateMessagePipe(&pipe0, &pipe1); |
| 150 |
| 151 EXPECT_TRUE(WriteTextMessage(pipe1.get(), kText1)); |
| 152 |
| 153 ScopedMessagePipeHandle pipe2, pipe3; |
| 154 CreateMessagePipe(&pipe2, &pipe3); |
| 155 |
| 156 EXPECT_TRUE(WriteTextMessage(pipe3.get(), kText2)); |
| 157 |
| 158 { |
| 159 AllocationScope scope; |
| 160 sample::Request::Builder request; |
| 161 request.set_x(1); |
| 162 request.set_pipe(pipe2.Pass()); |
| 163 factory->DoStuff(request.Finish(), pipe0.Pass()); |
| 164 } |
195 | 165 |
196 EXPECT_FALSE(factory_client.got_response()); | 166 EXPECT_FALSE(factory_client.got_response()); |
197 | 167 |
198 PumpMessages(); | 168 PumpMessages(); |
199 | 169 |
200 EXPECT_TRUE(factory_client.got_response()); | 170 EXPECT_TRUE(factory_client.got_response()); |
201 } | 171 } |
202 | 172 |
203 TEST_F(HandlePassingTest, PassInvalid) { | 173 TEST_F(HandlePassingTest, PassInvalid) { |
204 InterfacePipe<sample::Factory> pipe; | 174 sample::FactoryPtr factory; |
| 175 MakeRemote(new SampleFactoryImpl(), &factory); |
205 | 176 |
206 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 177 SampleFactoryClientImpl factory_client; |
207 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 178 factory->SetClient(&factory_client); |
208 | 179 |
209 factory_client.StartNoPipes(); | 180 { |
| 181 AllocationScope scope; |
| 182 sample::Request::Builder request; |
| 183 request.set_x(1); |
| 184 factory->DoStuff(request.Finish(), ScopedMessagePipeHandle().Pass()); |
| 185 } |
210 | 186 |
211 EXPECT_FALSE(factory_client.got_response()); | 187 EXPECT_FALSE(factory_client.got_response()); |
212 | 188 |
213 PumpMessages(); | 189 PumpMessages(); |
214 | 190 |
215 EXPECT_TRUE(factory_client.got_response()); | 191 EXPECT_TRUE(factory_client.got_response()); |
216 } | 192 } |
217 | 193 |
218 // Verifies DataPipeConsumer can be passed and read from. | 194 // Verifies DataPipeConsumer can be passed and read from. |
219 TEST_F(HandlePassingTest, DataPipe) { | 195 TEST_F(HandlePassingTest, DataPipe) { |
220 InterfacePipe<sample::Factory> pipe; | 196 sample::FactoryPtr factory; |
| 197 MakeRemote(new SampleFactoryImpl(), &factory); |
221 | 198 |
222 SampleFactoryImpl factory(pipe.handle_to_peer.Pass()); | 199 SampleFactoryClientImpl factory_client; |
223 SampleFactoryClientImpl factory_client(pipe.handle_to_self.Pass()); | 200 factory->SetClient(&factory_client); |
224 | 201 |
225 ASSERT_NO_FATAL_FAILURE(factory_client.StartDataPipe()); | 202 // Writes a string to a data pipe and passes the data pipe (consumer) to the |
| 203 // factory. |
| 204 ScopedDataPipeProducerHandle producer_handle; |
| 205 ScopedDataPipeConsumerHandle consumer_handle; |
| 206 MojoCreateDataPipeOptions options = { |
| 207 sizeof(MojoCreateDataPipeOptions), |
| 208 MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE, |
| 209 1, |
| 210 1024}; |
| 211 ASSERT_EQ(MOJO_RESULT_OK, |
| 212 CreateDataPipe(&options, &producer_handle, &consumer_handle)); |
| 213 std::string expected_text_reply = "got it"; |
| 214 factory_client.set_expected_text_reply(expected_text_reply); |
| 215 // +1 for \0. |
| 216 uint32_t data_size = static_cast<uint32_t>(expected_text_reply.size() + 1); |
| 217 ASSERT_EQ(MOJO_RESULT_OK, |
| 218 WriteDataRaw(producer_handle.get(), expected_text_reply.c_str(), |
| 219 &data_size, MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)); |
| 220 |
| 221 { |
| 222 AllocationScope scope; |
| 223 factory->DoStuff2(consumer_handle.Pass()); |
| 224 } |
226 | 225 |
227 EXPECT_FALSE(factory_client.got_response()); | 226 EXPECT_FALSE(factory_client.got_response()); |
228 | 227 |
229 PumpMessages(); | 228 PumpMessages(); |
230 | 229 |
231 EXPECT_TRUE(factory_client.got_response()); | 230 EXPECT_TRUE(factory_client.got_response()); |
232 } | 231 } |
233 | 232 |
234 TEST_F(HandlePassingTest, PipesAreClosed) { | 233 TEST_F(HandlePassingTest, PipesAreClosed) { |
235 InterfacePipe<sample::Factory> pipe; | 234 sample::FactoryPtr factory; |
236 RemotePtr<sample::Factory> factory(pipe.handle_to_self.Pass(), NULL); | 235 MakeRemote(new SampleFactoryImpl(), &factory); |
| 236 |
| 237 SampleFactoryClientImpl factory_client; |
| 238 factory->SetClient(&factory_client); |
237 | 239 |
238 MessagePipe extra_pipe; | 240 MessagePipe extra_pipe; |
239 | 241 |
240 MojoHandle handle0_value = extra_pipe.handle0.get().value(); | 242 MojoHandle handle0_value = extra_pipe.handle0.get().value(); |
241 MojoHandle handle1_value = extra_pipe.handle1.get().value(); | 243 MojoHandle handle1_value = extra_pipe.handle1.get().value(); |
242 | 244 |
243 { | 245 { |
244 AllocationScope scope; | 246 AllocationScope scope; |
245 | 247 |
246 Array<MessagePipeHandle>::Builder pipes(2); | 248 Array<MessagePipeHandle>::Builder pipes(2); |
(...skipping 13 matching lines...) Expand all Loading... |
260 } | 262 } |
261 | 263 |
262 // We expect the pipes to have been closed. | 264 // We expect the pipes to have been closed. |
263 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value)); | 265 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle0_value)); |
264 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value)); | 266 EXPECT_EQ(MOJO_RESULT_INVALID_ARGUMENT, MojoClose(handle1_value)); |
265 } | 267 } |
266 | 268 |
267 } // namespace | 269 } // namespace |
268 } // namespace test | 270 } // namespace test |
269 } // namespace mojo | 271 } // namespace mojo |
OLD | NEW |