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 class DisconnectableBusForTesting : public Bus { | |
25 public: | |
26 explicit DisconnectableBusForTesting(const Options& options) | |
27 : Bus(options) {} | |
28 | |
29 // Disconnects on-going connection. | |
30 void CloseConnection() { | |
31 CHECK(is_connected()) << "There is no on-going connection."; | |
32 dbus_connection_close(connection_); | |
33 } | |
34 | |
35 protected: | |
36 ~DisconnectableBusForTesting() {} | |
37 | |
38 private: | |
39 DISALLOW_COPY_AND_ASSIGN(DisconnectableBusForTesting); | |
40 }; | |
41 } // namespace dbus | |
42 | |
23 namespace { | 43 namespace { |
24 | 44 |
25 // See comments in ObjectProxy::RunResponseCallback() for why the number was | 45 // See comments in ObjectProxy::RunResponseCallback() for why the number was |
26 // chosen. | 46 // chosen. |
27 const int kHugePayloadSize = 64 << 20; // 64 MB | 47 const int kHugePayloadSize = 64 << 20; // 64 MB |
28 | 48 |
29 } // namespace | 49 } // namespace |
30 | 50 |
31 // The end-to-end test exercises the asynchronous APIs in ObjectProxy and | 51 // The end-to-end test exercises the asynchronous APIs in ObjectProxy and |
32 // ExportedObject. | 52 // ExportedObject. |
33 class EndToEndAsyncTest : public testing::Test { | 53 class EndToEndAsyncTest : public testing::Test { |
34 public: | 54 public: |
35 EndToEndAsyncTest() { | 55 EndToEndAsyncTest() : on_disconnected_callcount_(0) {} |
satorux1
2013/02/13 08:06:53
callcount -> call_count
Seigo Nonaka
2013/02/13 09:45:29
Done.
| |
36 } | |
37 | 56 |
38 virtual void SetUp() { | 57 virtual void SetUp() { |
58 // Reset function call count. | |
59 on_disconnected_callcount_ = 0; | |
60 | |
39 // Make the main thread not to allow IO. | 61 // Make the main thread not to allow IO. |
40 base::ThreadRestrictions::SetIOAllowed(false); | 62 base::ThreadRestrictions::SetIOAllowed(false); |
41 | 63 |
42 // Start the D-Bus thread. | 64 // Start the D-Bus thread. |
43 dbus_thread_.reset(new base::Thread("D-Bus Thread")); | 65 dbus_thread_.reset(new base::Thread("D-Bus Thread")); |
44 base::Thread::Options thread_options; | 66 base::Thread::Options thread_options; |
45 thread_options.message_loop_type = MessageLoop::TYPE_IO; | 67 thread_options.message_loop_type = MessageLoop::TYPE_IO; |
46 ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); | 68 ASSERT_TRUE(dbus_thread_->StartWithOptions(thread_options)); |
47 | 69 |
48 // Start the test service, using the D-Bus thread. | 70 // Start the test service, using the D-Bus thread. |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 test_service_->ShutdownAndBlock(); | 140 test_service_->ShutdownAndBlock(); |
119 | 141 |
120 // Reset to the default. | 142 // Reset to the default. |
121 base::ThreadRestrictions::SetIOAllowed(true); | 143 base::ThreadRestrictions::SetIOAllowed(true); |
122 | 144 |
123 // Stopping a thread is considered an IO operation, so do this after | 145 // Stopping a thread is considered an IO operation, so do this after |
124 // allowing IO. | 146 // allowing IO. |
125 test_service_->Stop(); | 147 test_service_->Stop(); |
126 } | 148 } |
127 | 149 |
150 // Callback function for "Disconnected" signal. | |
151 void OnDisconnected() { | |
152 ++on_disconnected_callcount_; | |
153 message_loop_.Quit(); | |
154 } | |
155 | |
128 protected: | 156 protected: |
129 // Replaces the bus with a broken one. | 157 // Replaces the bus with a broken one. |
130 void SetUpBrokenBus() { | 158 void SetUpBrokenBus() { |
131 // Shut down the existing bus. | 159 // Shut down the existing bus. |
132 bus_->ShutdownOnDBusThreadAndBlock(); | 160 bus_->ShutdownOnDBusThreadAndBlock(); |
133 | 161 |
134 // Create new bus with invalid address. | 162 // Create new bus with invalid address. |
135 const char kInvalidAddress[] = ""; | 163 const char kInvalidAddress[] = ""; |
136 dbus::Bus::Options bus_options; | 164 dbus::Bus::Options bus_options; |
137 bus_options.bus_type = dbus::Bus::CUSTOM_ADDRESS; | 165 bus_options.bus_type = dbus::Bus::CUSTOM_ADDRESS; |
138 bus_options.address = kInvalidAddress; | 166 bus_options.address = kInvalidAddress; |
139 bus_options.connection_type = dbus::Bus::PRIVATE; | 167 bus_options.connection_type = dbus::Bus::PRIVATE; |
140 bus_options.dbus_thread_message_loop_proxy = | 168 bus_options.dbus_thread_message_loop_proxy = |
141 dbus_thread_->message_loop_proxy(); | 169 dbus_thread_->message_loop_proxy(); |
142 bus_ = new dbus::Bus(bus_options); | 170 bus_ = new dbus::Bus(bus_options); |
143 ASSERT_TRUE(bus_->HasDBusThread()); | 171 ASSERT_TRUE(bus_->HasDBusThread()); |
144 | 172 |
145 // Create new object proxy. | 173 // Create new object proxy. |
146 object_proxy_ = bus_->GetObjectProxy( | 174 object_proxy_ = bus_->GetObjectProxy( |
147 "org.chromium.TestService", | 175 "org.chromium.TestService", |
148 dbus::ObjectPath("/org/chromium/TestObject")); | 176 dbus::ObjectPath("/org/chromium/TestObject")); |
149 } | 177 } |
150 | 178 |
179 // Replace the bus with DisconnectableBusFOrTesting. | |
180 void SetUpDisconnectableBus() { | |
181 // Shut down the existing bus. | |
182 bus_->ShutdownOnDBusThreadAndBlock(); | |
183 | |
184 // Create new disconnectable bus. | |
185 dbus::Bus::Options bus_options; | |
186 bus_options.bus_type = dbus::Bus::SESSION; | |
187 bus_options.connection_type = dbus::Bus::PRIVATE; | |
188 bus_options.dbus_thread_message_loop_proxy = | |
189 dbus_thread_->message_loop_proxy(); | |
190 bus_ = new dbus::DisconnectableBusForTesting(bus_options); | |
191 ASSERT_TRUE(bus_->HasDBusThread()); | |
192 | |
193 // Create new object proxy. | |
194 object_proxy_ = bus_->GetObjectProxy( | |
195 "org.chromium.TestService", | |
196 dbus::ObjectPath("/org/chromium/TestObject")); | |
197 | |
198 // Connect to the "Test" signal of "org.chromium.TestInterface" from | |
199 // the remote object. | |
200 object_proxy_->ConnectToSignal( | |
201 "org.chromium.TestInterface", | |
202 "Test", | |
203 base::Bind(&EndToEndAsyncTest::OnTestSignal, | |
204 base::Unretained(this)), | |
205 base::Bind(&EndToEndAsyncTest::OnConnected, | |
206 base::Unretained(this))); | |
207 // Wait until the object proxy is connected to the signal. | |
208 message_loop_.Run(); | |
209 } | |
210 | |
151 // Calls the method asynchronously. OnResponse() will be called once the | 211 // Calls the method asynchronously. OnResponse() will be called once the |
152 // response is received. | 212 // response is received. |
153 void CallMethod(dbus::MethodCall* method_call, | 213 void CallMethod(dbus::MethodCall* method_call, |
154 int timeout_ms) { | 214 int timeout_ms) { |
155 object_proxy_->CallMethod(method_call, | 215 object_proxy_->CallMethod(method_call, |
156 timeout_ms, | 216 timeout_ms, |
157 base::Bind(&EndToEndAsyncTest::OnResponse, | 217 base::Bind(&EndToEndAsyncTest::OnResponse, |
158 base::Unretained(this))); | 218 base::Unretained(this))); |
159 } | 219 } |
160 | 220 |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
253 std::vector<std::string> error_names_; | 313 std::vector<std::string> error_names_; |
254 scoped_ptr<base::Thread> dbus_thread_; | 314 scoped_ptr<base::Thread> dbus_thread_; |
255 scoped_refptr<dbus::Bus> bus_; | 315 scoped_refptr<dbus::Bus> bus_; |
256 dbus::ObjectProxy* object_proxy_; | 316 dbus::ObjectProxy* object_proxy_; |
257 dbus::ObjectProxy* root_object_proxy_; | 317 dbus::ObjectProxy* root_object_proxy_; |
258 scoped_ptr<dbus::TestService> test_service_; | 318 scoped_ptr<dbus::TestService> test_service_; |
259 // Text message from "Test" signal. | 319 // Text message from "Test" signal. |
260 std::string test_signal_string_; | 320 std::string test_signal_string_; |
261 // Text message from "Test" signal delivered to root. | 321 // Text message from "Test" signal delivered to root. |
262 std::string root_test_signal_string_; | 322 std::string root_test_signal_string_; |
323 int on_disconnected_callcount_; | |
263 }; | 324 }; |
264 | 325 |
265 TEST_F(EndToEndAsyncTest, Echo) { | 326 TEST_F(EndToEndAsyncTest, Echo) { |
266 const char* kHello = "hello"; | 327 const char* kHello = "hello"; |
267 | 328 |
268 // Create the method call. | 329 // Create the method call. |
269 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); | 330 dbus::MethodCall method_call("org.chromium.TestInterface", "Echo"); |
270 dbus::MessageWriter writer(&method_call); | 331 dbus::MessageWriter writer(&method_call); |
271 writer.AppendString(kHello); | 332 writer.AppendString(kHello); |
272 | 333 |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
565 TEST_F(EndToEndAsyncTest, TestHugeSignal) { | 626 TEST_F(EndToEndAsyncTest, TestHugeSignal) { |
566 const std::string kHugeMessage(kHugePayloadSize, 'o'); | 627 const std::string kHugeMessage(kHugePayloadSize, 'o'); |
567 | 628 |
568 // Send the huge signal from the exported object. | 629 // Send the huge signal from the exported object. |
569 test_service_->SendTestSignal(kHugeMessage); | 630 test_service_->SendTestSignal(kHugeMessage); |
570 // This caused a DCHECK failure before. Ensure that the issue is fixed. | 631 // This caused a DCHECK failure before. Ensure that the issue is fixed. |
571 WaitForTestSignal(); | 632 WaitForTestSignal(); |
572 ASSERT_EQ(kHugeMessage, test_signal_string_); | 633 ASSERT_EQ(kHugeMessage, test_signal_string_); |
573 } | 634 } |
574 | 635 |
636 TEST_F(EndToEndAsyncTest, DisconnectedSignal) { | |
637 // Set up a disconnectable bus. | |
638 SetUpDisconnectableBus(); | |
639 dbus::DisconnectableBusForTesting* disconnectable_bus = | |
640 static_cast<dbus::DisconnectableBusForTesting*>(bus_.get()); | |
641 | |
642 disconnectable_bus->SetDisconnectedCallback( | |
643 base::Bind(&EndToEndAsyncTest::OnDisconnected, | |
644 base::Unretained(this))); | |
645 | |
646 // Request diconnect from daemon. | |
647 disconnectable_bus->PostTaskToDBusThread( | |
648 FROM_HERE, | |
649 base::Bind( | |
650 &dbus::DisconnectableBusForTesting::CloseConnection, | |
651 base::Unretained(disconnectable_bus))); | |
652 | |
653 // OnDisconnected will quit message loop. | |
654 message_loop_.Run(); | |
655 | |
656 EXPECT_EQ(1, on_disconnected_callcount_); | |
657 } | |
658 | |
575 class SignalReplacementTest : public EndToEndAsyncTest { | 659 class SignalReplacementTest : public EndToEndAsyncTest { |
576 public: | 660 public: |
577 SignalReplacementTest() { | 661 SignalReplacementTest() { |
578 } | 662 } |
579 | 663 |
580 virtual void SetUp() { | 664 virtual void SetUp() { |
581 // Set up base class. | 665 // Set up base class. |
582 EndToEndAsyncTest::SetUp(); | 666 EndToEndAsyncTest::SetUp(); |
583 | 667 |
584 // Reconnect the root object proxy's signal handler to a new handler | 668 // Reconnect the root object proxy's signal handler to a new handler |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
620 const char kMessage[] = "hello, world"; | 704 const char kMessage[] = "hello, world"; |
621 // Send the test signal from the exported object. | 705 // Send the test signal from the exported object. |
622 test_service_->SendTestSignal(kMessage); | 706 test_service_->SendTestSignal(kMessage); |
623 // Receive the signal with the object proxy. | 707 // Receive the signal with the object proxy. |
624 WaitForTestSignal(); | 708 WaitForTestSignal(); |
625 // Verify the string WAS NOT received by the original handler. | 709 // Verify the string WAS NOT received by the original handler. |
626 ASSERT_TRUE(test_signal_string_.empty()); | 710 ASSERT_TRUE(test_signal_string_.empty()); |
627 // Verify the signal WAS received by the replacement handler. | 711 // Verify the signal WAS received by the replacement handler. |
628 ASSERT_EQ(kMessage, replacement_test_signal_string_); | 712 ASSERT_EQ(kMessage, replacement_test_signal_string_); |
629 } | 713 } |
OLD | NEW |