1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
7 #include "base/functional/bind.h"
8 #include "base/memory/raw_ptr.h"
9 #include "base/message_loop/message_pump_type.h"
10 #include "base/metrics/histogram_macros.h"
11 #include "base/metrics/histogram_samples.h"
12 #include "base/run_loop.h"
13 #include "base/task/single_thread_task_runner.h"
14 #include "base/test/task_environment.h"
15 #include "base/test/test_timeouts.h"
16 #include "base/threading/platform_thread.h"
17 #include "base/threading/thread_restrictions.h"
18 #include "base/time/time.h"
20 #include "dbus/message.h"
21 #include "dbus/object_proxy.h"
22 #include "dbus/test_service.h"
23 #include "testing/gtest/include/gtest/gtest.h"
27 // The test for sender verification in ObjectProxy.
28 class SignalSenderVerificationTest : public testing::Test {
30 SignalSenderVerificationTest()
31 : on_name_owner_changed_called_(false),
32 on_ownership_called_(false) {
35 void SetUp() override {
36 // Start the D-Bus thread.
37 dbus_thread_ = std::make_unique<base::Thread>("D-Bus Thread");
38 base::Thread::Options thread_options;
39 thread_options.message_pump_type = base::MessagePumpType::IO;
40 ASSERT_TRUE(dbus_thread_->StartWithOptions(std::move(thread_options)));
42 // Create the test service, using the D-Bus thread.
43 TestService::Options options;
44 options.dbus_task_runner = dbus_thread_->task_runner();
45 test_service_ = std::make_unique<TestService>(options);
47 // Create the client, using the D-Bus thread.
48 Bus::Options bus_options;
49 bus_options.bus_type = Bus::SESSION;
50 bus_options.connection_type = Bus::PRIVATE;
51 bus_options.dbus_task_runner = dbus_thread_->task_runner();
52 bus_ = new Bus(bus_options);
53 object_proxy_ = bus_->GetObjectProxy(
54 test_service_->service_name(),
55 ObjectPath("/org/chromium/TestObject"));
56 ASSERT_TRUE(bus_->HasDBusThread());
58 object_proxy_->SetNameOwnerChangedCallback(base::BindRepeating(
59 &SignalSenderVerificationTest::OnNameOwnerChanged,
60 base::Unretained(this), &on_name_owner_changed_called_));
62 // Connect to the "Test" signal of "org.chromium.TestInterface" from
64 object_proxy_->ConnectToSignal(
65 "org.chromium.TestInterface", "Test",
66 base::BindRepeating(&SignalSenderVerificationTest::OnTestSignal,
67 base::Unretained(this)),
68 base::BindOnce(&SignalSenderVerificationTest::OnConnected,
69 base::Unretained(this)));
70 // Wait until the object proxy is connected to the signal.
71 run_loop_ = std::make_unique<base::RunLoop>();
74 // Start the test service.
75 ASSERT_TRUE(test_service_->StartService());
76 test_service_->WaitUntilServiceIsStarted();
77 ASSERT_TRUE(test_service_->HasDBusThread());
78 ASSERT_TRUE(test_service_->has_ownership());
80 // Same setup for the second TestService. This service should not have the
81 // ownership of the name at this point.
82 options.service_name = test_service_->service_name();
83 test_service2_ = std::make_unique<TestService>(options);
84 ASSERT_TRUE(test_service2_->StartService());
85 test_service2_->WaitUntilServiceIsStarted();
86 ASSERT_TRUE(test_service2_->HasDBusThread());
87 ASSERT_FALSE(test_service2_->has_ownership());
89 // The name should be owned and known at this point.
90 if (!on_name_owner_changed_called_) {
91 run_loop_ = std::make_unique<base::RunLoop>();
94 ASSERT_FALSE(latest_name_owner_.empty());
97 void TearDown() override {
98 bus_->ShutdownOnDBusThreadAndBlock();
100 // Shut down the service.
101 test_service_->ShutdownAndBlock();
102 test_service2_->ShutdownAndBlock();
104 SafeServiceStop(test_service_.get());
105 SafeServiceStop(test_service2_.get());
108 void OnOwnership(bool expected, bool success) {
109 ASSERT_EQ(expected, success);
110 // PostTask to quit the RunLoop as this is called from D-Bus thread.
111 task_environment_.GetMainThreadTaskRunner()->PostTask(
113 base::BindOnce(&SignalSenderVerificationTest::OnOwnershipInternal,
114 base::Unretained(this)));
117 void OnOwnershipInternal() {
118 on_ownership_called_ = true;
122 void OnNameOwnerChanged(bool* called_flag,
123 const std::string& old_owner,
124 const std::string& new_owner) {
125 latest_name_owner_ = new_owner;
130 // Called when the "Test" signal is received, in the main thread.
131 // Copy the string payload to |test_signal_string_|.
132 void OnTestSignal(Signal* signal) {
133 MessageReader reader(signal);
134 ASSERT_TRUE(reader.PopString(&test_signal_string_));
138 // Called when connected to the signal.
139 void OnConnected(const std::string& interface_name,
140 const std::string& signal_name,
142 ASSERT_TRUE(success);
147 // Wait for the hey signal to be received.
148 void WaitForTestSignal() {
149 // OnTestSignal() will quit the message loop.
150 run_loop_ = std::make_unique<base::RunLoop>();
154 // Stopping a thread is a blocking IO operation, so we need to fiddle with
155 // thread restrictions to call Stop() on a TestService.
156 void SafeServiceStop(TestService* test_service) {
157 base::ScopedAllowBlockingForTesting allow_blocking;
158 test_service->Stop();
161 base::test::SingleThreadTaskEnvironment task_environment_;
162 // Make the main thread not to allow IO.
163 base::ScopedDisallowBlocking disallow_blocking_;
164 std::unique_ptr<base::RunLoop> run_loop_;
165 std::unique_ptr<base::Thread> dbus_thread_;
166 scoped_refptr<Bus> bus_;
167 raw_ptr<ObjectProxy, AcrossTasksDanglingUntriaged> object_proxy_;
168 std::unique_ptr<TestService> test_service_;
169 std::unique_ptr<TestService> test_service2_;
170 // Text message from "Test" signal.
171 std::string test_signal_string_;
173 // The known latest name owner of TestService. Updated in OnNameOwnerChanged.
174 std::string latest_name_owner_;
176 // Boolean flags to record callback calls.
177 bool on_name_owner_changed_called_;
178 bool on_ownership_called_;
181 TEST_F(SignalSenderVerificationTest, TestSignalAccepted) {
182 const char kMessage[] = "hello, world";
183 // Send the test signal from the exported object.
184 test_service_->SendTestSignal(kMessage);
185 // Receive the signal with the object proxy. The signal is handled in
186 // SignalSenderVerificationTest::OnTestSignal() in the main thread.
188 ASSERT_EQ(kMessage, test_signal_string_);
191 TEST_F(SignalSenderVerificationTest, TestSignalRejected) {
192 const char kNewMessage[] = "hello, new world";
193 test_service2_->SendTestSignal(kNewMessage);
195 // This test tests that our callback is NOT called by the ObjectProxy.
196 // Sleep to have message delivered to the client via the D-Bus service.
197 base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
199 ASSERT_EQ("", test_signal_string_);
202 // Flaky. https://crbug.com/785555
203 TEST_F(SignalSenderVerificationTest, DISABLED_TestOwnerChanged) {
204 const char kMessage[] = "hello, world";
206 // Send the test signal from the exported object.
207 test_service_->SendTestSignal(kMessage);
208 // Receive the signal with the object proxy. The signal is handled in
209 // SignalSenderVerificationTest::OnTestSignal() in the main thread.
211 ASSERT_EQ(kMessage, test_signal_string_);
213 // Release and acquire the name ownership.
214 // latest_name_owner_ should be non empty as |test_service_| owns the name.
215 ASSERT_FALSE(latest_name_owner_.empty());
216 test_service_->ShutdownAndBlock();
217 // OnNameOwnerChanged will PostTask to quit the message loop.
218 run_loop_ = std::make_unique<base::RunLoop>();
220 // latest_name_owner_ should be empty as the owner is gone.
221 ASSERT_TRUE(latest_name_owner_.empty());
223 // Reset the flag as NameOwnerChanged is already received in setup.
224 on_name_owner_changed_called_ = false;
225 on_ownership_called_ = false;
226 test_service2_->RequestOwnership(
227 base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
228 base::Unretained(this), true));
229 // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
230 // but there's no expected order of those 2 event.
231 run_loop_ = std::make_unique<base::RunLoop>();
233 if (!on_name_owner_changed_called_ || !on_ownership_called_) {
234 run_loop_ = std::make_unique<base::RunLoop>();
237 ASSERT_TRUE(on_name_owner_changed_called_);
238 ASSERT_TRUE(on_ownership_called_);
240 // latest_name_owner_ becomes non empty as the new owner appears.
241 ASSERT_FALSE(latest_name_owner_.empty());
243 // Now the second service owns the name.
244 const char kNewMessage[] = "hello, new world";
246 test_service2_->SendTestSignal(kNewMessage);
248 ASSERT_EQ(kNewMessage, test_signal_string_);
251 // Flaky. https://crbug.com/785555
252 TEST_F(SignalSenderVerificationTest, DISABLED_TestOwnerStealing) {
253 // Release and acquire the name ownership.
254 // latest_name_owner_ should be non empty as |test_service_| owns the name.
255 ASSERT_FALSE(latest_name_owner_.empty());
256 test_service_->ShutdownAndBlock();
257 // OnNameOwnerChanged will PostTask to quit the message loop.
258 run_loop_ = std::make_unique<base::RunLoop>();
260 // latest_name_owner_ should be empty as the owner is gone.
261 ASSERT_TRUE(latest_name_owner_.empty());
262 // Reset the flag as NameOwnerChanged is already received in setup.
263 on_name_owner_changed_called_ = false;
265 // Start a test service that allows theft, using the D-Bus thread.
266 TestService::Options options;
267 options.dbus_task_runner = dbus_thread_->task_runner();
268 options.request_ownership_options = Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT;
269 options.service_name = test_service_->service_name();
270 TestService stealable_test_service(options);
271 ASSERT_TRUE(stealable_test_service.StartService());
272 stealable_test_service.WaitUntilServiceIsStarted();
273 ASSERT_TRUE(stealable_test_service.HasDBusThread());
274 ASSERT_TRUE(stealable_test_service.has_ownership());
276 // OnNameOwnerChanged will PostTask to quit the message loop.
277 run_loop_ = std::make_unique<base::RunLoop>();
280 // Send a signal to check that the service is correctly owned.
281 const char kMessage[] = "hello, world";
283 // Send the test signal from the exported object.
284 stealable_test_service.SendTestSignal(kMessage);
285 // Receive the signal with the object proxy. The signal is handled in
286 // SignalSenderVerificationTest::OnTestSignal() in the main thread.
288 ASSERT_EQ(kMessage, test_signal_string_);
290 // Reset the flag as NameOwnerChanged was called above.
291 on_name_owner_changed_called_ = false;
292 test_service2_->RequestOwnership(
293 base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
294 base::Unretained(this), true));
295 // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
296 // but there's no expected order of those 2 event.
297 run_loop_ = std::make_unique<base::RunLoop>();
299 if (!on_name_owner_changed_called_ || !on_ownership_called_) {
300 run_loop_ = std::make_unique<base::RunLoop>();
303 ASSERT_TRUE(on_name_owner_changed_called_);
304 ASSERT_TRUE(on_ownership_called_);
306 // Now the second service owns the name.
307 const char kNewMessage[] = "hello, new world";
309 test_service2_->SendTestSignal(kNewMessage);
311 ASSERT_EQ(kNewMessage, test_signal_string_);
313 SafeServiceStop(&stealable_test_service);
316 // Fails on Linux ChromiumOS Tests
317 TEST_F(SignalSenderVerificationTest, DISABLED_TestMultipleObjects) {
318 const char kMessage[] = "hello, world";
320 ObjectProxy* object_proxy2 = bus_->GetObjectProxy(
321 test_service_->service_name(),
322 ObjectPath("/org/chromium/DifferentObject"));
324 bool second_name_owner_changed_called = false;
325 object_proxy2->SetNameOwnerChangedCallback(base::BindRepeating(
326 &SignalSenderVerificationTest::OnNameOwnerChanged, base::Unretained(this),
327 &second_name_owner_changed_called));
329 // Connect to a signal on the additional remote object to trigger the
330 // name owner matching.
331 object_proxy2->ConnectToSignal(
332 "org.chromium.DifferentTestInterface", "Test",
333 base::BindRepeating(&SignalSenderVerificationTest::OnTestSignal,
334 base::Unretained(this)),
335 base::BindOnce(&SignalSenderVerificationTest::OnConnected,
336 base::Unretained(this)));
337 // Wait until the object proxy is connected to the signal.
338 run_loop_ = std::make_unique<base::RunLoop>();
341 // Send the test signal from the exported object.
342 test_service_->SendTestSignal(kMessage);
343 // Receive the signal with the object proxy. The signal is handled in
344 // SignalSenderVerificationTest::OnTestSignal() in the main thread.
346 ASSERT_EQ(kMessage, test_signal_string_);
348 // Release and acquire the name ownership.
349 // latest_name_owner_ should be non empty as |test_service_| owns the name.
350 ASSERT_FALSE(latest_name_owner_.empty());
351 test_service_->ShutdownAndBlock();
352 // OnNameOwnerChanged will PostTask to quit the message loop.
353 run_loop_ = std::make_unique<base::RunLoop>();
355 // latest_name_owner_ should be empty as the owner is gone.
356 ASSERT_TRUE(latest_name_owner_.empty());
358 // Reset the flag as NameOwnerChanged is already received in setup.
359 on_name_owner_changed_called_ = false;
360 second_name_owner_changed_called = false;
361 test_service2_->RequestOwnership(
362 base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
363 base::Unretained(this), true));
364 // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
365 // but there's no expected order of those 2 event.
366 while (!on_name_owner_changed_called_ || !second_name_owner_changed_called ||
367 !on_ownership_called_) {
368 run_loop_ = std::make_unique<base::RunLoop>();
371 ASSERT_TRUE(on_name_owner_changed_called_);
372 ASSERT_TRUE(second_name_owner_changed_called);
373 ASSERT_TRUE(on_ownership_called_);
375 // latest_name_owner_ becomes non empty as the new owner appears.
376 ASSERT_FALSE(latest_name_owner_.empty());
378 // Now the second service owns the name.
379 const char kNewMessage[] = "hello, new world";
381 test_service2_->SendTestSignal(kNewMessage);
383 ASSERT_EQ(kNewMessage, test_signal_string_);