blob: bc155e75686dc05ce3248bc4524a4d2f981c6056 [file] [log] [blame]
[email protected]20bed012012-02-10 21:45:231// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2ef498f2011-08-23 19:25:202// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "dbus/bus.h"
6
[email protected]e20d39fe2011-09-02 06:56:237#include "base/bind.h"
8#include "base/message_loop.h"
[email protected]2ef498f2011-08-23 19:25:209#include "base/memory/ref_counted.h"
[email protected]e20d39fe2011-09-02 06:56:2310#include "base/threading/thread.h"
[email protected]2ef498f2011-08-23 19:25:2011#include "dbus/exported_object.h"
[email protected]216ed0b2012-02-14 21:29:0612#include "dbus/object_path.h"
[email protected]2ef498f2011-08-23 19:25:2013#include "dbus/object_proxy.h"
14
15#include "testing/gtest/include/gtest/gtest.h"
16
[email protected]12e25992011-10-06 00:20:5317namespace {
18
19// Used to test AddFilterFunction().
20DBusHandlerResult DummyHandler(DBusConnection* connection,
21 DBusMessage* raw_message,
22 void* user_data) {
23 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
24}
25
26} // namespace
27
[email protected]2ef498f2011-08-23 19:25:2028TEST(BusTest, GetObjectProxy) {
29 dbus::Bus::Options options;
30 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
31
32 dbus::ObjectProxy* object_proxy1 =
33 bus->GetObjectProxy("org.chromium.TestService",
[email protected]216ed0b2012-02-14 21:29:0634 dbus::ObjectPath("/org/chromium/TestObject"));
[email protected]2ef498f2011-08-23 19:25:2035 ASSERT_TRUE(object_proxy1);
36
37 // This should return the same object.
38 dbus::ObjectProxy* object_proxy2 =
39 bus->GetObjectProxy("org.chromium.TestService",
[email protected]216ed0b2012-02-14 21:29:0640 dbus::ObjectPath("/org/chromium/TestObject"));
[email protected]2ef498f2011-08-23 19:25:2041 ASSERT_TRUE(object_proxy2);
42 EXPECT_EQ(object_proxy1, object_proxy2);
43
44 // This should not.
45 dbus::ObjectProxy* object_proxy3 =
[email protected]216ed0b2012-02-14 21:29:0646 bus->GetObjectProxy(
47 "org.chromium.TestService",
48 dbus::ObjectPath("/org/chromium/DifferentTestObject"));
[email protected]2ef498f2011-08-23 19:25:2049 ASSERT_TRUE(object_proxy3);
50 EXPECT_NE(object_proxy1, object_proxy3);
[email protected]6477a412011-10-13 00:45:2651
52 bus->ShutdownAndBlock();
[email protected]2ef498f2011-08-23 19:25:2053}
54
[email protected]20bed012012-02-10 21:45:2355TEST(BusTest, GetObjectProxyIgnoreUnknownService) {
56 dbus::Bus::Options options;
57 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
58
59 dbus::ObjectProxy* object_proxy1 =
60 bus->GetObjectProxyWithOptions(
61 "org.chromium.TestService",
[email protected]216ed0b2012-02-14 21:29:0662 dbus::ObjectPath("/org/chromium/TestObject"),
[email protected]20bed012012-02-10 21:45:2363 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
64 ASSERT_TRUE(object_proxy1);
65
66 // This should return the same object.
67 dbus::ObjectProxy* object_proxy2 =
68 bus->GetObjectProxyWithOptions(
69 "org.chromium.TestService",
[email protected]216ed0b2012-02-14 21:29:0670 dbus::ObjectPath("/org/chromium/TestObject"),
[email protected]20bed012012-02-10 21:45:2371 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
72 ASSERT_TRUE(object_proxy2);
73 EXPECT_EQ(object_proxy1, object_proxy2);
74
75 // This should not.
76 dbus::ObjectProxy* object_proxy3 =
77 bus->GetObjectProxyWithOptions(
78 "org.chromium.TestService",
[email protected]216ed0b2012-02-14 21:29:0679 dbus::ObjectPath("/org/chromium/DifferentTestObject"),
[email protected]20bed012012-02-10 21:45:2380 dbus::ObjectProxy::IGNORE_SERVICE_UNKNOWN_ERRORS);
81 ASSERT_TRUE(object_proxy3);
82 EXPECT_NE(object_proxy1, object_proxy3);
83
84 bus->ShutdownAndBlock();
85}
86
[email protected]2ef498f2011-08-23 19:25:2087TEST(BusTest, GetExportedObject) {
88 dbus::Bus::Options options;
89 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
90
91 dbus::ExportedObject* object_proxy1 =
[email protected]15e7b162012-03-10 01:12:5292 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
[email protected]2ef498f2011-08-23 19:25:2093 ASSERT_TRUE(object_proxy1);
94
95 // This should return the same object.
96 dbus::ExportedObject* object_proxy2 =
[email protected]15e7b162012-03-10 01:12:5297 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
[email protected]2ef498f2011-08-23 19:25:2098 ASSERT_TRUE(object_proxy2);
99 EXPECT_EQ(object_proxy1, object_proxy2);
100
101 // This should not.
102 dbus::ExportedObject* object_proxy3 =
[email protected]216ed0b2012-02-14 21:29:06103 bus->GetExportedObject(
[email protected]216ed0b2012-02-14 21:29:06104 dbus::ObjectPath("/org/chromium/DifferentTestObject"));
[email protected]2ef498f2011-08-23 19:25:20105 ASSERT_TRUE(object_proxy3);
106 EXPECT_NE(object_proxy1, object_proxy3);
[email protected]6477a412011-10-13 00:45:26107
108 bus->ShutdownAndBlock();
[email protected]2ef498f2011-08-23 19:25:20109}
[email protected]e20d39fe2011-09-02 06:56:23110
[email protected]bda57352013-01-24 00:58:35111TEST(BusTest, UnregisterExportedObject) {
[email protected]d7361fdc2012-03-14 01:18:35112 // Start the D-Bus thread.
113 base::Thread::Options thread_options;
114 thread_options.message_loop_type = MessageLoop::TYPE_IO;
115 base::Thread dbus_thread("D-Bus thread");
116 dbus_thread.StartWithOptions(thread_options);
117
118 // Create the bus.
119 dbus::Bus::Options options;
120 options.dbus_thread_message_loop_proxy = dbus_thread.message_loop_proxy();
121 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
122 ASSERT_FALSE(bus->shutdown_completed());
123
124 dbus::ExportedObject* object_proxy1 =
125 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
126 ASSERT_TRUE(object_proxy1);
127
[email protected]bda57352013-01-24 00:58:35128 // Increment the reference count to the object proxy to avoid destroying it
129 // calling UnregisterExportedObject. This ensures the dbus::ExportedObject is
130 // not freed from memory. See http://crbug.com/137846 for details.
131 object_proxy1->AddRef();
132
[email protected]d7361fdc2012-03-14 01:18:35133 bus->UnregisterExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
134
[email protected]bda57352013-01-24 00:58:35135 // This should return a new object because the object_proxy1 is still in
136 // alloc'ed memory.
[email protected]d7361fdc2012-03-14 01:18:35137 dbus::ExportedObject* object_proxy2 =
138 bus->GetExportedObject(dbus::ObjectPath("/org/chromium/TestObject"));
139 ASSERT_TRUE(object_proxy2);
140 EXPECT_NE(object_proxy1, object_proxy2);
141
[email protected]bda57352013-01-24 00:58:35142 // Release the incremented reference.
143 object_proxy1->Release();
144
[email protected]d7361fdc2012-03-14 01:18:35145 // Shut down synchronously.
146 bus->ShutdownOnDBusThreadAndBlock();
147 EXPECT_TRUE(bus->shutdown_completed());
148 dbus_thread.Stop();
149}
150
[email protected]e20d39fe2011-09-02 06:56:23151TEST(BusTest, ShutdownAndBlock) {
152 dbus::Bus::Options options;
153 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
154 ASSERT_FALSE(bus->shutdown_completed());
155
156 // Shut down synchronously.
157 bus->ShutdownAndBlock();
158 EXPECT_TRUE(bus->shutdown_completed());
159}
160
161TEST(BusTest, ShutdownAndBlockWithDBusThread) {
162 // Start the D-Bus thread.
163 base::Thread::Options thread_options;
164 thread_options.message_loop_type = MessageLoop::TYPE_IO;
165 base::Thread dbus_thread("D-Bus thread");
166 dbus_thread.StartWithOptions(thread_options);
167
168 // Create the bus.
169 dbus::Bus::Options options;
[email protected]56d82c9c2011-09-06 20:03:24170 options.dbus_thread_message_loop_proxy = dbus_thread.message_loop_proxy();
[email protected]e20d39fe2011-09-02 06:56:23171 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
172 ASSERT_FALSE(bus->shutdown_completed());
173
174 // Shut down synchronously.
175 bus->ShutdownOnDBusThreadAndBlock();
176 EXPECT_TRUE(bus->shutdown_completed());
177 dbus_thread.Stop();
178}
[email protected]12e25992011-10-06 00:20:53179
180TEST(BusTest, AddFilterFunction) {
181 dbus::Bus::Options options;
182 scoped_refptr<dbus::Bus> bus = new dbus::Bus(options);
183 // Should connect before calling AddFilterFunction().
184 bus->Connect();
185
186 int data1 = 100;
187 int data2 = 200;
188 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data1));
189 // Cannot add the same function with the same data.
190 ASSERT_FALSE(bus->AddFilterFunction(&DummyHandler, &data1));
191 // Can add the same function with different data.
192 ASSERT_TRUE(bus->AddFilterFunction(&DummyHandler, &data2));
193
194 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data1));
195 ASSERT_FALSE(bus->RemoveFilterFunction(&DummyHandler, &data1));
196 ASSERT_TRUE(bus->RemoveFilterFunction(&DummyHandler, &data2));
197
198 bus->ShutdownAndBlock();
199}