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