OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <algorithm> | 5 #include <algorithm> |
6 #include <string> | 6 #include <string> |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
12 #include "base/stl_util.h" | 12 #include "base/stl_util.h" |
13 #include "base/test/test_timeouts.h" | 13 #include "base/test/test_timeouts.h" |
14 #include "base/threading/thread.h" | 14 #include "base/threading/thread.h" |
15 #include "base/threading/thread_restrictions.h" | 15 #include "base/threading/thread_restrictions.h" |
16 #include "dbus/bus.h" | 16 #include "dbus/bus.h" |
17 #include "dbus/message.h" | 17 #include "dbus/message.h" |
18 #include "dbus/object_path.h" | 18 #include "dbus/object_path.h" |
19 #include "dbus/object_proxy.h" | 19 #include "dbus/object_proxy.h" |
20 #include "dbus/test_service.h" | 20 #include "dbus/test_service.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 | 22 |
| 23 namespace dbus { |
| 24 |
23 namespace { | 25 namespace { |
24 | 26 |
25 // See comments in ObjectProxy::RunResponseCallback() for why the number was | 27 // See comments in ObjectProxy::RunResponseCallback() for why the number was |
26 // chosen. | 28 // chosen. |
27 const int kHugePayloadSize = 64 << 20; // 64 MB | 29 const int kHugePayloadSize = 64 << 20; // 64 MB |
28 | 30 |
29 } // namespace | 31 } // namespace |
30 | 32 |
31 // The end-to-end test exercises the asynchronous APIs in ObjectProxy and | 33 // The end-to-end test exercises the asynchronous APIs in ObjectProxy and |
32 // ExportedObject. | 34 // ExportedObject. |
33 class EndToEndAsyncTest : public testing::Test { | 35 class EndToEndAsyncTest : public testing::Test { |
34 public: | 36 public: |
35 EndToEndAsyncTest() : on_disconnected_call_count_(0) {} | 37 EndToEndAsyncTest() : on_disconnected_call_count_(0) {} |
36 | 38 |
37 virtual void SetUp() { | 39 virtual void SetUp() { |
38 // Make the main thread not to allow IO. | 40 // Make the main thread not to allow IO. |
39 base::ThreadRestrictions::SetIOAllowed(false); | 41 base::ThreadRestrictions::SetIOAllowed(false); |
40 | 42 |
41 // Start the D-Bus thread. | 43 // Start the D-Bus thread. |
42 dbus_thread_.reset(new base::Thread("D-Bus Thread")); | 44 dbus_thread_.reset(new base::Thread("D-Bus Thread")); |
43 base::Thread::Options thread_options; | 45 base::Thread::Options thread_options; |
44 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; | 46 thread_options.message_loop_type = base::MessageLoop::TYPE_IO; |
45 ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); | 47 ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); |
46 | 48 |
47 // Start the test service, using the D-Bus thread. | 49 // Start the test service, using the D-Bus thread. |
48 dbus::TestService::Options options; | 50 TestService::Options options; |
49 options.dbus_task_runner = dbus_thread_->message_loop_proxy(); | 51 options.dbus_task_runner = dbus_thread_->message_loop_proxy(); |
50 test_service_.reset(new dbus::TestService(options)); | 52 test_service_.reset(new TestService(options)); |
51 ASSERT_TRUE(test_service_->StartService()); | 53 ASSERT_TRUE(test_service_->StartService()); |
52 ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted()); | 54 ASSERT_TRUE(test_service_->WaitUntilServiceIsStarted()); |
53 ASSERT_TRUE(test_service_->HasDBusThread()); | 55 ASSERT_TRUE(test_service_->HasDBusThread()); |
54 | 56 |
55 // Create the client, using the D-Bus thread. | 57 // Create the client, using the D-Bus thread. |
56 dbus::Bus::Options bus_options; | 58 Bus::Options bus_options; |
57 bus_options.bus_type = dbus::Bus::SESSION; | 59 bus_options.bus_type = Bus::SESSION; |
58 bus_options.connection_type = dbus::Bus::PRIVATE; | 60 bus_options.connection_type = Bus::PRIVATE; |
59 bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy(); | 61 bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy(); |
60 bus_options.disconnected_callback = | 62 bus_options.disconnected_callback = |
61 base::Bind(&EndToEndAsyncTest::OnDisconnected, base::Unretained(this)); | 63 base::Bind(&EndToEndAsyncTest::OnDisconnected, base::Unretained(this)); |
62 bus_ = new dbus::Bus(bus_options); | 64 bus_ = new Bus(bus_options); |
63 object_proxy_ = bus_->GetObjectProxy( | 65 object_proxy_ = bus_->GetObjectProxy( |
64 "org.chromium.TestService", | 66 "org.chromium.TestService", |
65 dbus::ObjectPath("/org/chromium/TestObject")); | 67 ObjectPath("/org/chromium/TestObject")); |
66 ASSERT_TRUE(bus_->HasDBusThread()); | 68 ASSERT_TRUE(bus_->HasDBusThread()); |
67 | 69 |
68 // Connect to the "Test" signal of "org.chromium.TestInterface" from | 70 // Connect to the "Test" signal of "org.chromium.TestInterface" from |
69 // the remote object. | 71 // the remote object. |
70 object_proxy_->ConnectToSignal( | 72 object_proxy_->ConnectToSignal( |
71 "org.chromium.TestInterface", | 73 "org.chromium.TestInterface", |
72 "Test", | 74 "Test", |
73 base::Bind(&EndToEndAsyncTest::OnTestSignal, | 75 base::Bind(&EndToEndAsyncTest::OnTestSignal, |
74 base::Unretained(this)), | 76 base::Unretained(this)), |
75 base::Bind(&EndToEndAsyncTest::OnConnected, | 77 base::Bind(&EndToEndAsyncTest::OnConnected, |
(...skipping 10 matching lines...) Expand all Loading... |
86 "org.chromium.TestInterface", | 88 "org.chromium.TestInterface", |
87 "Test2", | 89 "Test2", |
88 base::Bind(&EndToEndAsyncTest::OnTest2Signal, | 90 base::Bind(&EndToEndAsyncTest::OnTest2Signal, |
89 base::Unretained(this)), | 91 base::Unretained(this)), |
90 base::Bind(&EndToEndAsyncTest::OnConnected, | 92 base::Bind(&EndToEndAsyncTest::OnConnected, |
91 base::Unretained(this))); | 93 base::Unretained(this))); |
92 // Wait until the object proxy is connected to the signal. | 94 // Wait until the object proxy is connected to the signal. |
93 message_loop_.Run(); | 95 message_loop_.Run(); |
94 | 96 |
95 // Create a second object proxy for the root object. | 97 // Create a second object proxy for the root object. |
96 root_object_proxy_ = bus_->GetObjectProxy( | 98 root_object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService", |
97 "org.chromium.TestService", | 99 ObjectPath("/")); |
98 dbus::ObjectPath("/")); | |
99 ASSERT_TRUE(bus_->HasDBusThread()); | 100 ASSERT_TRUE(bus_->HasDBusThread()); |
100 | 101 |
101 // Connect to the "Test" signal of "org.chromium.TestInterface" from | 102 // Connect to the "Test" signal of "org.chromium.TestInterface" from |
102 // the root remote object too. | 103 // the root remote object too. |
103 root_object_proxy_->ConnectToSignal( | 104 root_object_proxy_->ConnectToSignal( |
104 "org.chromium.TestInterface", | 105 "org.chromium.TestInterface", |
105 "Test", | 106 "Test", |
106 base::Bind(&EndToEndAsyncTest::OnRootTestSignal, | 107 base::Bind(&EndToEndAsyncTest::OnRootTestSignal, |
107 base::Unretained(this)), | 108 base::Unretained(this)), |
108 base::Bind(&EndToEndAsyncTest::OnConnected, | 109 base::Bind(&EndToEndAsyncTest::OnConnected, |
(...skipping 17 matching lines...) Expand all Loading... |
126 } | 127 } |
127 | 128 |
128 protected: | 129 protected: |
129 // Replaces the bus with a broken one. | 130 // Replaces the bus with a broken one. |
130 void SetUpBrokenBus() { | 131 void SetUpBrokenBus() { |
131 // Shut down the existing bus. | 132 // Shut down the existing bus. |
132 bus_->ShutdownOnDBusThreadAndBlock(); | 133 bus_->ShutdownOnDBusThreadAndBlock(); |
133 | 134 |
134 // Create new bus with invalid address. | 135 // Create new bus with invalid address. |
135 const char kInvalidAddress[] = ""; | 136 const char kInvalidAddress[] = ""; |
136 dbus::Bus::Options bus_options; | 137 Bus::Options bus_options; |
137 bus_options.bus_type = dbus::Bus::CUSTOM_ADDRESS; | 138 bus_options.bus_type = Bus::CUSTOM_ADDRESS; |
138 bus_options.address = kInvalidAddress; | 139 bus_options.address = kInvalidAddress; |
139 bus_options.connection_type = dbus::Bus::PRIVATE; | 140 bus_options.connection_type = Bus::PRIVATE; |
140 bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy(); | 141 bus_options.dbus_task_runner = dbus_thread_->message_loop_proxy(); |
141 bus_ = new dbus::Bus(bus_options); | 142 bus_ = new Bus(bus_options); |
142 ASSERT_TRUE(bus_->HasDBusThread()); | 143 ASSERT_TRUE(bus_->HasDBusThread()); |
143 | 144 |
144 // Create new object proxy. | 145 // Create new object proxy. |
145 object_proxy_ = bus_->GetObjectProxy( | 146 object_proxy_ = bus_->GetObjectProxy( |
146 "org.chromium.TestService", | 147 "org.chromium.TestService", |
147 dbus::ObjectPath("/org/chromium/TestObject")); | 148 ObjectPath("/org/chromium/TestObject")); |
148 } | 149 } |
149 | 150 |
150 // Calls the method asynchronously. OnResponse() will be called once the | 151 // Calls the method asynchronously. OnResponse() will be called once the |
151 // response is received. | 152 // response is received. |
152 void CallMethod(dbus::MethodCall* method_call, | 153 void CallMethod(MethodCall* method_call, |
153 int timeout_ms) { | 154 int timeout_ms) { |
154 object_proxy_->CallMethod(method_call, | 155 object_proxy_->CallMethod(method_call, |
155 timeout_ms, | 156 timeout_ms, |
156 base::Bind(&EndToEndAsyncTest::OnResponse, | 157 base::Bind(&EndToEndAsyncTest::OnResponse, |
157 base::Unretained(this))); | 158 base::Unretained(this))); |
158 } | 159 } |
159 | 160 |
160 // Calls the method asynchronously. OnResponse() will be called once the | 161 // Calls the method asynchronously. OnResponse() will be called once the |
161 // response is received without error, otherwise OnError() will be called. | 162 // response is received without error, otherwise OnError() will be called. |
162 void CallMethodWithErrorCallback(dbus::MethodCall* method_call, | 163 void CallMethodWithErrorCallback(MethodCall* method_call, |
163 int timeout_ms) { | 164 int timeout_ms) { |
164 object_proxy_->CallMethodWithErrorCallback( | 165 object_proxy_->CallMethodWithErrorCallback( |
165 method_call, | 166 method_call, |
166 timeout_ms, | 167 timeout_ms, |
167 base::Bind(&EndToEndAsyncTest::OnResponse, base::Unretained(this)), | 168 base::Bind(&EndToEndAsyncTest::OnResponse, base::Unretained(this)), |
168 base::Bind(&EndToEndAsyncTest::OnError, base::Unretained(this))); | 169 base::Bind(&EndToEndAsyncTest::OnError, base::Unretained(this))); |
169 } | 170 } |
170 | 171 |
171 // Wait for the give number of responses. | 172 // Wait for the give number of responses. |
172 void WaitForResponses(size_t num_responses) { | 173 void WaitForResponses(size_t num_responses) { |
173 while (response_strings_.size() < num_responses) { | 174 while (response_strings_.size() < num_responses) { |
174 message_loop_.Run(); | 175 message_loop_.Run(); |
175 } | 176 } |
176 } | 177 } |
177 | 178 |
178 // Called when the response is received. | 179 // Called when the response is received. |
179 void OnResponse(dbus::Response* response) { | 180 void OnResponse(Response* response) { |
180 // |response| will be deleted on exit of the function. Copy the | 181 // |response| will be deleted on exit of the function. Copy the |
181 // payload to |response_strings_|. | 182 // payload to |response_strings_|. |
182 if (response) { | 183 if (response) { |
183 dbus::MessageReader reader(response); | 184 MessageReader reader(response); |
184 std::string response_string; | 185 std::string response_string; |
185 ASSERT_TRUE(reader.PopString(&response_string)); | 186 ASSERT_TRUE(reader.PopString(&response_string)); |
186 response_strings_.push_back(response_string); | 187 response_strings_.push_back(response_string); |
187 } else { | 188 } else { |
188 response_strings_.push_back(std::string()); | 189 response_strings_.push_back(std::string()); |
189 } | 190 } |
190 message_loop_.Quit(); | 191 message_loop_.Quit(); |
191 }; | 192 }; |
192 | 193 |
193 // Wait for the given number of errors. | 194 // Wait for the given number of errors. |
194 void WaitForErrors(size_t num_errors) { | 195 void WaitForErrors(size_t num_errors) { |
195 while (error_names_.size() < num_errors) { | 196 while (error_names_.size() < num_errors) { |
196 message_loop_.Run(); | 197 message_loop_.Run(); |
197 } | 198 } |
198 } | 199 } |
199 | 200 |
200 // Called when an error is received. | 201 // Called when an error is received. |
201 void OnError(dbus::ErrorResponse* error) { | 202 void OnError(ErrorResponse* error) { |
202 // |error| will be deleted on exit of the function. Copy the payload to | 203 // |error| will be deleted on exit of the function. Copy the payload to |
203 // |error_names_|. | 204 // |error_names_|. |
204 if (error) { | 205 if (error) { |
205 ASSERT_NE("", error->GetErrorName()); | 206 ASSERT_NE("", error->GetErrorName()); |
206 error_names_.push_back(error->GetErrorName()); | 207 error_names_.push_back(error->GetErrorName()); |
207 } else { | 208 } else { |
208 error_names_.push_back(std::string()); | 209 error_names_.push_back(std::string()); |
209 } | 210 } |
210 message_loop_.Quit(); | 211 message_loop_.Quit(); |
211 } | 212 } |
212 | 213 |
213 // Called when the "Test" signal is received, in the main thread. | 214 // Called when the "Test" signal is received, in the main thread. |
214 // Copy the string payload to |test_signal_string_|. | 215 // Copy the string payload to |test_signal_string_|. |
215 void OnTestSignal(dbus::Signal* signal) { | 216 void OnTestSignal(Signal* signal) { |
216 dbus::MessageReader reader(signal); | 217 MessageReader reader(signal); |
217 ASSERT_TRUE(reader.PopString(&test_signal_string_)); | 218 ASSERT_TRUE(reader.PopString(&test_signal_string_)); |
218 message_loop_.Quit(); | 219 message_loop_.Quit(); |
219 } | 220 } |
220 | 221 |
221 // Called when the "Test" signal is received, in the main thread, by | 222 // Called when the "Test" signal is received, in the main thread, by |
222 // the root object proxy. Copy the string payload to | 223 // the root object proxy. Copy the string payload to |
223 // |root_test_signal_string_|. | 224 // |root_test_signal_string_|. |
224 void OnRootTestSignal(dbus::Signal* signal) { | 225 void OnRootTestSignal(Signal* signal) { |
225 dbus::MessageReader reader(signal); | 226 MessageReader reader(signal); |
226 ASSERT_TRUE(reader.PopString(&root_test_signal_string_)); | 227 ASSERT_TRUE(reader.PopString(&root_test_signal_string_)); |
227 message_loop_.Quit(); | 228 message_loop_.Quit(); |
228 } | 229 } |
229 | 230 |
230 // Called when the "Test2" signal is received, in the main thread. | 231 // Called when the "Test2" signal is received, in the main thread. |
231 void OnTest2Signal(dbus::Signal* signal) { | 232 void OnTest2Signal(Signal* signal) { |
232 dbus::MessageReader reader(signal); | 233 MessageReader reader(signal); |
233 message_loop_.Quit(); | 234 message_loop_.Quit(); |
234 } | 235 } |
235 | 236 |
236 // Called when connected to the signal. | 237 // Called when connected to the signal. |
237 void OnConnected(const std::string& interface_name, | 238 void OnConnected(const std::string& interface_name, |
238 const std::string& signal_name, | 239 const std::string& signal_name, |
239 bool success) { | 240 bool success) { |
240 ASSERT_TRUE(success); | 241 ASSERT_TRUE(success); |
241 message_loop_.Quit(); | 242 message_loop_.Quit(); |
242 } | 243 } |
243 | 244 |
244 // Called when the connection with dbus-daemon is disconnected. | 245 // Called when the connection with dbus-daemon is disconnected. |
245 void OnDisconnected() { | 246 void OnDisconnected() { |
246 message_loop_.Quit(); | 247 message_loop_.Quit(); |
247 ++on_disconnected_call_count_; | 248 ++on_disconnected_call_count_; |
248 } | 249 } |
249 | 250 |
250 // Wait for the hey signal to be received. | 251 // Wait for the hey signal to be received. |
251 void WaitForTestSignal() { | 252 void WaitForTestSignal() { |
252 // OnTestSignal() will quit the message loop. | 253 // OnTestSignal() will quit the message loop. |
253 message_loop_.Run(); | 254 message_loop_.Run(); |
254 } | 255 } |
255 | 256 |
256 base::MessageLoop message_loop_; | 257 base::MessageLoop message_loop_; |
257 std::vector<std::string> response_strings_; | 258 std::vector<std::string> response_strings_; |
258 std::vector<std::string> error_names_; | 259 std::vector<std::string> error_names_; |
259 scoped_ptr<base::Thread> dbus_thread_; | 260 scoped_ptr<base::Thread> dbus_thread_; |
260 scoped_refptr<dbus::Bus> bus_; | 261 scoped_refptr<Bus> bus_; |
261 dbus::ObjectProxy* object_proxy_; | 262 ObjectProxy* object_proxy_; |
262 dbus::ObjectProxy* root_object_proxy_; | 263 ObjectProxy* root_object_proxy_; |
263 scoped_ptr<dbus::TestService> test_service_; | 264 scoped_ptr<TestService> test_service_; |
264 // Text message from "Test" signal. | 265 // Text message from "Test" signal. |
265 std::string test_signal_string_; | 266 std::string test_signal_string_; |
266 // Text message from "Test" signal delivered to root. | 267 // Text message from "Test" signal delivered to root. |
267 std::string root_test_signal_string_; | 268 std::string root_test_signal_string_; |
268 int on_disconnected_call_count_; | 269 int on_disconnected_call_count_; |
269 }; | 270 }; |
270 | 271 |
271 TEST_F(EndToEndAsyncTest, Echo) { | 272 TEST_F(EndToEndAsyncTest, Echo) { |
272 const char* kHello = "hello"; | 273 const char* kHello = "hello"; |
273 | 274 |
274 // Create the method call. | 275 // Create the method call. |
275 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 276 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
276 dbus::MessageWriter writer(&method_call); | 277 MessageWriter writer(&method_call); |
277 writer.AppendString(kHello); | 278 writer.AppendString(kHello); |
278 | 279 |
279 // Call the method. | 280 // Call the method. |
280 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 281 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
281 CallMethod(&method_call, timeout_ms); | 282 CallMethod(&method_call, timeout_ms); |
282 | 283 |
283 // Check the response. | 284 // Check the response. |
284 WaitForResponses(1); | 285 WaitForResponses(1); |
285 EXPECT_EQ(kHello, response_strings_[0]); | 286 EXPECT_EQ(kHello, response_strings_[0]); |
286 } | 287 } |
287 | 288 |
288 TEST_F(EndToEndAsyncTest, EchoWithErrorCallback) { | 289 TEST_F(EndToEndAsyncTest, EchoWithErrorCallback) { |
289 const char* kHello = "hello"; | 290 const char* kHello = "hello"; |
290 | 291 |
291 // Create the method call. | 292 // Create the method call. |
292 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 293 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
293 dbus::MessageWriter writer(&method_call); | 294 MessageWriter writer(&method_call); |
294 writer.AppendString(kHello); | 295 writer.AppendString(kHello); |
295 | 296 |
296 // Call the method. | 297 // Call the method. |
297 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 298 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
298 CallMethodWithErrorCallback(&method_call, timeout_ms); | 299 CallMethodWithErrorCallback(&method_call, timeout_ms); |
299 | 300 |
300 // Check the response. | 301 // Check the response. |
301 WaitForResponses(1); | 302 WaitForResponses(1); |
302 EXPECT_EQ(kHello, response_strings_[0]); | 303 EXPECT_EQ(kHello, response_strings_[0]); |
303 EXPECT_TRUE(error_names_.empty()); | 304 EXPECT_TRUE(error_names_.empty()); |
304 } | 305 } |
305 | 306 |
306 // Call Echo method three times. | 307 // Call Echo method three times. |
307 TEST_F(EndToEndAsyncTest, EchoThreeTimes) { | 308 TEST_F(EndToEndAsyncTest, EchoThreeTimes) { |
308 const char* kMessages[] = { "foo", "bar", "baz" }; | 309 const char* kMessages[] = { "foo", "bar", "baz" }; |
309 | 310 |
310 for (size_t i = 0; i < arraysize(kMessages); ++i) { | 311 for (size_t i = 0; i < arraysize(kMessages); ++i) { |
311 // Create the method call. | 312 // Create the method call. |
312 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 313 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
313 dbus::MessageWriter writer(&method_call); | 314 MessageWriter writer(&method_call); |
314 writer.AppendString(kMessages[i]); | 315 writer.AppendString(kMessages[i]); |
315 | 316 |
316 // Call the method. | 317 // Call the method. |
317 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 318 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
318 CallMethod(&method_call, timeout_ms); | 319 CallMethod(&method_call, timeout_ms); |
319 } | 320 } |
320 | 321 |
321 // Check the responses. | 322 // Check the responses. |
322 WaitForResponses(3); | 323 WaitForResponses(3); |
323 // Sort as the order of the returned messages is not deterministic. | 324 // Sort as the order of the returned messages is not deterministic. |
324 std::sort(response_strings_.begin(), response_strings_.end()); | 325 std::sort(response_strings_.begin(), response_strings_.end()); |
325 EXPECT_EQ("bar", response_strings_[0]); | 326 EXPECT_EQ("bar", response_strings_[0]); |
326 EXPECT_EQ("baz", response_strings_[1]); | 327 EXPECT_EQ("baz", response_strings_[1]); |
327 EXPECT_EQ("foo", response_strings_[2]); | 328 EXPECT_EQ("foo", response_strings_[2]); |
328 } | 329 } |
329 | 330 |
330 TEST_F(EndToEndAsyncTest, Echo_HugePayload) { | 331 TEST_F(EndToEndAsyncTest, Echo_HugePayload) { |
331 const std::string kHugePayload(kHugePayloadSize, 'o'); | 332 const std::string kHugePayload(kHugePayloadSize, 'o'); |
332 | 333 |
333 // Create the method call with a huge payload. | 334 // Create the method call with a huge payload. |
334 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 335 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
335 dbus::MessageWriter writer(&method_call); | 336 MessageWriter writer(&method_call); |
336 writer.AppendString(kHugePayload); | 337 writer.AppendString(kHugePayload); |
337 | 338 |
338 // Call the method. | 339 // Call the method. |
339 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 340 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
340 CallMethod(&method_call, timeout_ms); | 341 CallMethod(&method_call, timeout_ms); |
341 | 342 |
342 // This caused a DCHECK failure before. Ensure that the issue is fixed. | 343 // This caused a DCHECK failure before. Ensure that the issue is fixed. |
343 WaitForResponses(1); | 344 WaitForResponses(1); |
344 EXPECT_EQ(kHugePayload, response_strings_[0]); | 345 EXPECT_EQ(kHugePayload, response_strings_[0]); |
345 } | 346 } |
346 | 347 |
347 TEST_F(EndToEndAsyncTest, BrokenBus) { | 348 TEST_F(EndToEndAsyncTest, BrokenBus) { |
348 const char* kHello = "hello"; | 349 const char* kHello = "hello"; |
349 | 350 |
350 // Set up a broken bus. | 351 // Set up a broken bus. |
351 SetUpBrokenBus(); | 352 SetUpBrokenBus(); |
352 | 353 |
353 // Create the method call. | 354 // Create the method call. |
354 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 355 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
355 dbus::MessageWriter writer(&method_call); | 356 MessageWriter writer(&method_call); |
356 writer.AppendString(kHello); | 357 writer.AppendString(kHello); |
357 | 358 |
358 // Call the method. | 359 // Call the method. |
359 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 360 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
360 CallMethod(&method_call, timeout_ms); | 361 CallMethod(&method_call, timeout_ms); |
361 WaitForResponses(1); | 362 WaitForResponses(1); |
362 | 363 |
363 // Should fail because of the broken bus. | 364 // Should fail because of the broken bus. |
364 ASSERT_EQ("", response_strings_[0]); | 365 ASSERT_EQ("", response_strings_[0]); |
365 } | 366 } |
366 | 367 |
367 TEST_F(EndToEndAsyncTest, BrokenBusWithErrorCallback) { | 368 TEST_F(EndToEndAsyncTest, BrokenBusWithErrorCallback) { |
368 const char* kHello = "hello"; | 369 const char* kHello = "hello"; |
369 | 370 |
370 // Set up a broken bus. | 371 // Set up a broken bus. |
371 SetUpBrokenBus(); | 372 SetUpBrokenBus(); |
372 | 373 |
373 // Create the method call. | 374 // Create the method call. |
374 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 375 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
375 dbus::MessageWriter writer(&method_call); | 376 MessageWriter writer(&method_call); |
376 writer.AppendString(kHello); | 377 writer.AppendString(kHello); |
377 | 378 |
378 // Call the method. | 379 // Call the method. |
379 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 380 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
380 CallMethodWithErrorCallback(&method_call, timeout_ms); | 381 CallMethodWithErrorCallback(&method_call, timeout_ms); |
381 WaitForErrors(1); | 382 WaitForErrors(1); |
382 | 383 |
383 // Should fail because of the broken bus. | 384 // Should fail because of the broken bus. |
384 ASSERT_TRUE(response_strings_.empty()); | 385 ASSERT_TRUE(response_strings_.empty()); |
385 ASSERT_EQ("", error_names_[0]); | 386 ASSERT_EQ("", error_names_[0]); |
386 } | 387 } |
387 | 388 |
388 TEST_F(EndToEndAsyncTest, Timeout) { | 389 TEST_F(EndToEndAsyncTest, Timeout) { |
389 const char* kHello = "hello"; | 390 const char* kHello = "hello"; |
390 | 391 |
391 // Create the method call. | 392 // Create the method call. |
392 dbus::MethodCall method_call("org.chromium.TestInterface", "SlowEcho"); | 393 MethodCall method_call("org.chromium.TestInterface", "SlowEcho"); |
393 dbus::MessageWriter writer(&method_call); | 394 MessageWriter writer(&method_call); |
394 writer.AppendString(kHello); | 395 writer.AppendString(kHello); |
395 | 396 |
396 // Call the method with timeout of 0ms. | 397 // Call the method with timeout of 0ms. |
397 const int timeout_ms = 0; | 398 const int timeout_ms = 0; |
398 CallMethod(&method_call, timeout_ms); | 399 CallMethod(&method_call, timeout_ms); |
399 WaitForResponses(1); | 400 WaitForResponses(1); |
400 | 401 |
401 // Should fail because of timeout. | 402 // Should fail because of timeout. |
402 ASSERT_EQ("", response_strings_[0]); | 403 ASSERT_EQ("", response_strings_[0]); |
403 } | 404 } |
404 | 405 |
405 TEST_F(EndToEndAsyncTest, TimeoutWithErrorCallback) { | 406 TEST_F(EndToEndAsyncTest, TimeoutWithErrorCallback) { |
406 const char* kHello = "hello"; | 407 const char* kHello = "hello"; |
407 | 408 |
408 // Create the method call. | 409 // Create the method call. |
409 dbus::MethodCall method_call("org.chromium.TestInterface", "SlowEcho"); | 410 MethodCall method_call("org.chromium.TestInterface", "SlowEcho"); |
410 dbus::MessageWriter writer(&method_call); | 411 MessageWriter writer(&method_call); |
411 writer.AppendString(kHello); | 412 writer.AppendString(kHello); |
412 | 413 |
413 // Call the method with timeout of 0ms. | 414 // Call the method with timeout of 0ms. |
414 const int timeout_ms = 0; | 415 const int timeout_ms = 0; |
415 CallMethodWithErrorCallback(&method_call, timeout_ms); | 416 CallMethodWithErrorCallback(&method_call, timeout_ms); |
416 WaitForErrors(1); | 417 WaitForErrors(1); |
417 | 418 |
418 // Should fail because of timeout. | 419 // Should fail because of timeout. |
419 ASSERT_TRUE(response_strings_.empty()); | 420 ASSERT_TRUE(response_strings_.empty()); |
420 ASSERT_EQ(DBUS_ERROR_NO_REPLY, error_names_[0]); | 421 ASSERT_EQ(DBUS_ERROR_NO_REPLY, error_names_[0]); |
421 } | 422 } |
422 | 423 |
423 // Tests calling a method that sends its reply asynchronously. | 424 // Tests calling a method that sends its reply asynchronously. |
424 TEST_F(EndToEndAsyncTest, AsyncEcho) { | 425 TEST_F(EndToEndAsyncTest, AsyncEcho) { |
425 const char* kHello = "hello"; | 426 const char* kHello = "hello"; |
426 | 427 |
427 // Create the method call. | 428 // Create the method call. |
428 dbus::MethodCall method_call("org.chromium.TestInterface", "AsyncEcho"); | 429 MethodCall method_call("org.chromium.TestInterface", "AsyncEcho"); |
429 dbus::MessageWriter writer(&method_call); | 430 MessageWriter writer(&method_call); |
430 writer.AppendString(kHello); | 431 writer.AppendString(kHello); |
431 | 432 |
432 // Call the method. | 433 // Call the method. |
433 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 434 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
434 CallMethod(&method_call, timeout_ms); | 435 CallMethod(&method_call, timeout_ms); |
435 | 436 |
436 // Check the response. | 437 // Check the response. |
437 WaitForResponses(1); | 438 WaitForResponses(1); |
438 EXPECT_EQ(kHello, response_strings_[0]); | 439 EXPECT_EQ(kHello, response_strings_[0]); |
439 } | 440 } |
440 | 441 |
441 TEST_F(EndToEndAsyncTest, NonexistentMethod) { | 442 TEST_F(EndToEndAsyncTest, NonexistentMethod) { |
442 dbus::MethodCall method_call("org.chromium.TestInterface", "Nonexistent"); | 443 MethodCall method_call("org.chromium.TestInterface", "Nonexistent"); |
443 | 444 |
444 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 445 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
445 CallMethod(&method_call, timeout_ms); | 446 CallMethod(&method_call, timeout_ms); |
446 WaitForResponses(1); | 447 WaitForResponses(1); |
447 | 448 |
448 // Should fail because the method is nonexistent. | 449 // Should fail because the method is nonexistent. |
449 ASSERT_EQ("", response_strings_[0]); | 450 ASSERT_EQ("", response_strings_[0]); |
450 } | 451 } |
451 | 452 |
452 TEST_F(EndToEndAsyncTest, NonexistentMethodWithErrorCallback) { | 453 TEST_F(EndToEndAsyncTest, NonexistentMethodWithErrorCallback) { |
453 dbus::MethodCall method_call("org.chromium.TestInterface", "Nonexistent"); | 454 MethodCall method_call("org.chromium.TestInterface", "Nonexistent"); |
454 | 455 |
455 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 456 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
456 CallMethodWithErrorCallback(&method_call, timeout_ms); | 457 CallMethodWithErrorCallback(&method_call, timeout_ms); |
457 WaitForErrors(1); | 458 WaitForErrors(1); |
458 | 459 |
459 // Should fail because the method is nonexistent. | 460 // Should fail because the method is nonexistent. |
460 ASSERT_TRUE(response_strings_.empty()); | 461 ASSERT_TRUE(response_strings_.empty()); |
461 ASSERT_EQ(DBUS_ERROR_UNKNOWN_METHOD, error_names_[0]); | 462 ASSERT_EQ(DBUS_ERROR_UNKNOWN_METHOD, error_names_[0]); |
462 } | 463 } |
463 | 464 |
464 TEST_F(EndToEndAsyncTest, BrokenMethod) { | 465 TEST_F(EndToEndAsyncTest, BrokenMethod) { |
465 dbus::MethodCall method_call("org.chromium.TestInterface", "BrokenMethod"); | 466 MethodCall method_call("org.chromium.TestInterface", "BrokenMethod"); |
466 | 467 |
467 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 468 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
468 CallMethod(&method_call, timeout_ms); | 469 CallMethod(&method_call, timeout_ms); |
469 WaitForResponses(1); | 470 WaitForResponses(1); |
470 | 471 |
471 // Should fail because the method is broken. | 472 // Should fail because the method is broken. |
472 ASSERT_EQ("", response_strings_[0]); | 473 ASSERT_EQ("", response_strings_[0]); |
473 } | 474 } |
474 | 475 |
475 TEST_F(EndToEndAsyncTest, BrokenMethodWithErrorCallback) { | 476 TEST_F(EndToEndAsyncTest, BrokenMethodWithErrorCallback) { |
476 dbus::MethodCall method_call("org.chromium.TestInterface", "BrokenMethod"); | 477 MethodCall method_call("org.chromium.TestInterface", "BrokenMethod"); |
477 | 478 |
478 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 479 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
479 CallMethodWithErrorCallback(&method_call, timeout_ms); | 480 CallMethodWithErrorCallback(&method_call, timeout_ms); |
480 WaitForErrors(1); | 481 WaitForErrors(1); |
481 | 482 |
482 // Should fail because the method is broken. | 483 // Should fail because the method is broken. |
483 ASSERT_TRUE(response_strings_.empty()); | 484 ASSERT_TRUE(response_strings_.empty()); |
484 ASSERT_EQ(DBUS_ERROR_FAILED, error_names_[0]); | 485 ASSERT_EQ(DBUS_ERROR_FAILED, error_names_[0]); |
485 } | 486 } |
486 | 487 |
487 TEST_F(EndToEndAsyncTest, InvalidObjectPath) { | 488 TEST_F(EndToEndAsyncTest, InvalidObjectPath) { |
488 // Trailing '/' is only allowed for the root path. | 489 // Trailing '/' is only allowed for the root path. |
489 const dbus::ObjectPath invalid_object_path("/org/chromium/TestObject/"); | 490 const ObjectPath invalid_object_path("/org/chromium/TestObject/"); |
490 | 491 |
491 // Replace object proxy with new one. | 492 // Replace object proxy with new one. |
492 object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService", | 493 object_proxy_ = bus_->GetObjectProxy("org.chromium.TestService", |
493 invalid_object_path); | 494 invalid_object_path); |
494 | 495 |
495 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 496 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
496 | 497 |
497 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 498 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
498 CallMethodWithErrorCallback(&method_call, timeout_ms); | 499 CallMethodWithErrorCallback(&method_call, timeout_ms); |
499 WaitForErrors(1); | 500 WaitForErrors(1); |
500 | 501 |
501 // Should fail because of the invalid path. | 502 // Should fail because of the invalid path. |
502 ASSERT_TRUE(response_strings_.empty()); | 503 ASSERT_TRUE(response_strings_.empty()); |
503 ASSERT_EQ("", error_names_[0]); | 504 ASSERT_EQ("", error_names_[0]); |
504 } | 505 } |
505 | 506 |
506 TEST_F(EndToEndAsyncTest, InvalidServiceName) { | 507 TEST_F(EndToEndAsyncTest, InvalidServiceName) { |
507 // Bus name cannot contain '/'. | 508 // Bus name cannot contain '/'. |
508 const std::string invalid_service_name = ":1/2"; | 509 const std::string invalid_service_name = ":1/2"; |
509 | 510 |
510 // Replace object proxy with new one. | 511 // Replace object proxy with new one. |
511 object_proxy_ = bus_->GetObjectProxy( | 512 object_proxy_ = bus_->GetObjectProxy( |
512 invalid_service_name, dbus::ObjectPath("org.chromium.TestObject")); | 513 invalid_service_name, ObjectPath("org.chromium.TestObject")); |
513 | 514 |
514 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 515 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
515 | 516 |
516 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 517 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
517 CallMethodWithErrorCallback(&method_call, timeout_ms); | 518 CallMethodWithErrorCallback(&method_call, timeout_ms); |
518 WaitForErrors(1); | 519 WaitForErrors(1); |
519 | 520 |
520 // Should fail because of the invalid bus name. | 521 // Should fail because of the invalid bus name. |
521 ASSERT_TRUE(response_strings_.empty()); | 522 ASSERT_TRUE(response_strings_.empty()); |
522 ASSERT_EQ("", error_names_[0]); | 523 ASSERT_EQ("", error_names_[0]); |
523 } | 524 } |
524 | 525 |
525 TEST_F(EndToEndAsyncTest, EmptyResponseCallback) { | 526 TEST_F(EndToEndAsyncTest, EmptyResponseCallback) { |
526 const char* kHello = "hello"; | 527 const char* kHello = "hello"; |
527 | 528 |
528 // Create the method call. | 529 // Create the method call. |
529 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 530 MethodCall method_call("org.chromium.TestInterface", "Echo"); |
530 dbus::MessageWriter writer(&method_call); | 531 MessageWriter writer(&method_call); |
531 writer.AppendString(kHello); | 532 writer.AppendString(kHello); |
532 | 533 |
533 // Call the method with an empty callback. | 534 // Call the method with an empty callback. |
534 const int timeout_ms = dbus::ObjectProxy::TIMEOUT_USE_DEFAULT; | 535 const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT; |
535 object_proxy_->CallMethod(&method_call, | 536 object_proxy_->CallMethod(&method_call, |
536 timeout_ms, | 537 timeout_ms, |
537 dbus::ObjectProxy::EmptyResponseCallback()); | 538 ObjectProxy::EmptyResponseCallback()); |
538 // Post a delayed task to quit the message loop. | 539 // Post a delayed task to quit the message loop. |
539 message_loop_.PostDelayedTask(FROM_HERE, | 540 message_loop_.PostDelayedTask(FROM_HERE, |
540 base::MessageLoop::QuitClosure(), | 541 base::MessageLoop::QuitClosure(), |
541 TestTimeouts::tiny_timeout()); | 542 TestTimeouts::tiny_timeout()); |
542 message_loop_.Run(); | 543 message_loop_.Run(); |
543 // We cannot tell if the empty callback is called, but at least we can | 544 // We cannot tell if the empty callback is called, but at least we can |
544 // check if the test does not crash. | 545 // check if the test does not crash. |
545 } | 546 } |
546 | 547 |
547 TEST_F(EndToEndAsyncTest, TestSignal) { | 548 TEST_F(EndToEndAsyncTest, TestSignal) { |
(...skipping 25 matching lines...) Expand all Loading... |
573 | 574 |
574 // Send the huge signal from the exported object. | 575 // Send the huge signal from the exported object. |
575 test_service_->SendTestSignal(kHugeMessage); | 576 test_service_->SendTestSignal(kHugeMessage); |
576 // This caused a DCHECK failure before. Ensure that the issue is fixed. | 577 // This caused a DCHECK failure before. Ensure that the issue is fixed. |
577 WaitForTestSignal(); | 578 WaitForTestSignal(); |
578 ASSERT_EQ(kHugeMessage, test_signal_string_); | 579 ASSERT_EQ(kHugeMessage, test_signal_string_); |
579 } | 580 } |
580 | 581 |
581 TEST_F(EndToEndAsyncTest, DisconnectedSignal) { | 582 TEST_F(EndToEndAsyncTest, DisconnectedSignal) { |
582 bus_->PostTaskToDBusThread(FROM_HERE, | 583 bus_->PostTaskToDBusThread(FROM_HERE, |
583 base::Bind(&dbus::Bus::ClosePrivateConnection, | 584 base::Bind(&Bus::ClosePrivateConnection, |
584 base::Unretained(bus_.get()))); | 585 base::Unretained(bus_.get()))); |
585 // OnDisconnected callback quits message loop. | 586 // OnDisconnected callback quits message loop. |
586 message_loop_.Run(); | 587 message_loop_.Run(); |
587 EXPECT_EQ(1, on_disconnected_call_count_); | 588 EXPECT_EQ(1, on_disconnected_call_count_); |
588 } | 589 } |
589 | 590 |
590 class SignalMultipleHandlerTest : public EndToEndAsyncTest { | 591 class SignalMultipleHandlerTest : public EndToEndAsyncTest { |
591 public: | 592 public: |
592 SignalMultipleHandlerTest() { | 593 SignalMultipleHandlerTest() { |
593 } | 594 } |
(...skipping 12 matching lines...) Expand all Loading... |
606 base::Unretained(this)), | 607 base::Unretained(this)), |
607 base::Bind(&SignalMultipleHandlerTest::OnAdditionalConnected, | 608 base::Bind(&SignalMultipleHandlerTest::OnAdditionalConnected, |
608 base::Unretained(this))); | 609 base::Unretained(this))); |
609 // Wait until the object proxy is connected to the signal. | 610 // Wait until the object proxy is connected to the signal. |
610 message_loop_.Run(); | 611 message_loop_.Run(); |
611 } | 612 } |
612 | 613 |
613 protected: | 614 protected: |
614 // Called when the "Test" signal is received, in the main thread. | 615 // Called when the "Test" signal is received, in the main thread. |
615 // Copy the string payload to |additional_test_signal_string_|. | 616 // Copy the string payload to |additional_test_signal_string_|. |
616 void OnAdditionalTestSignal(dbus::Signal* signal) { | 617 void OnAdditionalTestSignal(Signal* signal) { |
617 dbus::MessageReader reader(signal); | 618 MessageReader reader(signal); |
618 ASSERT_TRUE(reader.PopString(&additional_test_signal_string_)); | 619 ASSERT_TRUE(reader.PopString(&additional_test_signal_string_)); |
619 message_loop_.Quit(); | 620 message_loop_.Quit(); |
620 } | 621 } |
621 | 622 |
622 // Called when connected to the signal. | 623 // Called when connected to the signal. |
623 void OnAdditionalConnected(const std::string& interface_name, | 624 void OnAdditionalConnected(const std::string& interface_name, |
624 const std::string& signal_name, | 625 const std::string& signal_name, |
625 bool success) { | 626 bool success) { |
626 ASSERT_TRUE(success); | 627 ASSERT_TRUE(success); |
627 message_loop_.Quit(); | 628 message_loop_.Quit(); |
628 } | 629 } |
629 | 630 |
630 // Text message from "Test" signal delivered to additional handler. | 631 // Text message from "Test" signal delivered to additional handler. |
631 std::string additional_test_signal_string_; | 632 std::string additional_test_signal_string_; |
632 }; | 633 }; |
633 | 634 |
634 TEST_F(SignalMultipleHandlerTest, TestMultipleHandlers) { | 635 TEST_F(SignalMultipleHandlerTest, TestMultipleHandlers) { |
635 const char kMessage[] = "hello, world"; | 636 const char kMessage[] = "hello, world"; |
636 // Send the test signal from the exported object. | 637 // Send the test signal from the exported object. |
637 test_service_->SendTestSignal(kMessage); | 638 test_service_->SendTestSignal(kMessage); |
638 // Receive the signal with the object proxy. | 639 // Receive the signal with the object proxy. |
639 WaitForTestSignal(); | 640 WaitForTestSignal(); |
640 // Verify the string WAS received by the original handler. | 641 // Verify the string WAS received by the original handler. |
641 ASSERT_EQ(kMessage, test_signal_string_); | 642 ASSERT_EQ(kMessage, test_signal_string_); |
642 // Verify the signal WAS ALSO received by the additional handler. | 643 // Verify the signal WAS ALSO received by the additional handler. |
643 ASSERT_EQ(kMessage, additional_test_signal_string_); | 644 ASSERT_EQ(kMessage, additional_test_signal_string_); |
644 } | 645 } |
| 646 |
| 647 } // namespace dbus |
OLD | NEW |