signal_sender_verification_unittest.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  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
  3. // found in the LICENSE file.
  4. #include <memory>
  5. #include "base/bind.h"
  6. #include "base/memory/raw_ptr.h"
  7. #include "base/message_loop/message_pump_type.h"
  8. #include "base/metrics/histogram_macros.h"
  9. #include "base/metrics/histogram_samples.h"
  10. #include "base/run_loop.h"
  11. #include "base/task/single_thread_task_runner.h"
  12. #include "base/test/task_environment.h"
  13. #include "base/test/test_timeouts.h"
  14. #include "base/threading/platform_thread.h"
  15. #include "base/threading/thread_restrictions.h"
  16. #include "base/time/time.h"
  17. #include "dbus/bus.h"
  18. #include "dbus/message.h"
  19. #include "dbus/object_proxy.h"
  20. #include "dbus/test_service.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. namespace dbus {
  23. // The test for sender verification in ObjectProxy.
  24. class SignalSenderVerificationTest : public testing::Test {
  25. public:
  26. SignalSenderVerificationTest()
  27. : on_name_owner_changed_called_(false),
  28. on_ownership_called_(false) {
  29. }
  30. void SetUp() override {
  31. // Start the D-Bus thread.
  32. dbus_thread_ = std::make_unique<base::Thread>("D-Bus Thread");
  33. base::Thread::Options thread_options;
  34. thread_options.message_pump_type = base::MessagePumpType::IO;
  35. ASSERT_TRUE(dbus_thread_->StartWithOptions(std::move(thread_options)));
  36. // Create the test service, using the D-Bus thread.
  37. TestService::Options options;
  38. options.dbus_task_runner = dbus_thread_->task_runner();
  39. test_service_ = std::make_unique<TestService>(options);
  40. // Create the client, using the D-Bus thread.
  41. Bus::Options bus_options;
  42. bus_options.bus_type = Bus::SESSION;
  43. bus_options.connection_type = Bus::PRIVATE;
  44. bus_options.dbus_task_runner = dbus_thread_->task_runner();
  45. bus_ = new Bus(bus_options);
  46. object_proxy_ = bus_->GetObjectProxy(
  47. test_service_->service_name(),
  48. ObjectPath("/org/chromium/TestObject"));
  49. ASSERT_TRUE(bus_->HasDBusThread());
  50. object_proxy_->SetNameOwnerChangedCallback(base::BindRepeating(
  51. &SignalSenderVerificationTest::OnNameOwnerChanged,
  52. base::Unretained(this), &on_name_owner_changed_called_));
  53. // Connect to the "Test" signal of "org.chromium.TestInterface" from
  54. // the remote object.
  55. object_proxy_->ConnectToSignal(
  56. "org.chromium.TestInterface", "Test",
  57. base::BindRepeating(&SignalSenderVerificationTest::OnTestSignal,
  58. base::Unretained(this)),
  59. base::BindOnce(&SignalSenderVerificationTest::OnConnected,
  60. base::Unretained(this)));
  61. // Wait until the object proxy is connected to the signal.
  62. run_loop_ = std::make_unique<base::RunLoop>();
  63. run_loop_->Run();
  64. // Start the test service.
  65. ASSERT_TRUE(test_service_->StartService());
  66. test_service_->WaitUntilServiceIsStarted();
  67. ASSERT_TRUE(test_service_->HasDBusThread());
  68. ASSERT_TRUE(test_service_->has_ownership());
  69. // Same setup for the second TestService. This service should not have the
  70. // ownership of the name at this point.
  71. options.service_name = test_service_->service_name();
  72. test_service2_ = std::make_unique<TestService>(options);
  73. ASSERT_TRUE(test_service2_->StartService());
  74. test_service2_->WaitUntilServiceIsStarted();
  75. ASSERT_TRUE(test_service2_->HasDBusThread());
  76. ASSERT_FALSE(test_service2_->has_ownership());
  77. // The name should be owned and known at this point.
  78. if (!on_name_owner_changed_called_) {
  79. run_loop_ = std::make_unique<base::RunLoop>();
  80. run_loop_->Run();
  81. }
  82. ASSERT_FALSE(latest_name_owner_.empty());
  83. }
  84. void TearDown() override {
  85. bus_->ShutdownOnDBusThreadAndBlock();
  86. // Shut down the service.
  87. test_service_->ShutdownAndBlock();
  88. test_service2_->ShutdownAndBlock();
  89. SafeServiceStop(test_service_.get());
  90. SafeServiceStop(test_service2_.get());
  91. }
  92. void OnOwnership(bool expected, bool success) {
  93. ASSERT_EQ(expected, success);
  94. // PostTask to quit the RunLoop as this is called from D-Bus thread.
  95. task_environment_.GetMainThreadTaskRunner()->PostTask(
  96. FROM_HERE,
  97. base::BindOnce(&SignalSenderVerificationTest::OnOwnershipInternal,
  98. base::Unretained(this)));
  99. }
  100. void OnOwnershipInternal() {
  101. on_ownership_called_ = true;
  102. run_loop_->Quit();
  103. }
  104. void OnNameOwnerChanged(bool* called_flag,
  105. const std::string& old_owner,
  106. const std::string& new_owner) {
  107. latest_name_owner_ = new_owner;
  108. *called_flag = true;
  109. run_loop_->Quit();
  110. }
  111. // Called when the "Test" signal is received, in the main thread.
  112. // Copy the string payload to |test_signal_string_|.
  113. void OnTestSignal(Signal* signal) {
  114. MessageReader reader(signal);
  115. ASSERT_TRUE(reader.PopString(&test_signal_string_));
  116. run_loop_->Quit();
  117. }
  118. // Called when connected to the signal.
  119. void OnConnected(const std::string& interface_name,
  120. const std::string& signal_name,
  121. bool success) {
  122. ASSERT_TRUE(success);
  123. run_loop_->Quit();
  124. }
  125. protected:
  126. // Wait for the hey signal to be received.
  127. void WaitForTestSignal() {
  128. // OnTestSignal() will quit the message loop.
  129. run_loop_ = std::make_unique<base::RunLoop>();
  130. run_loop_->Run();
  131. }
  132. // Stopping a thread is a blocking IO operation, so we need to fiddle with
  133. // thread restrictions to call Stop() on a TestService.
  134. void SafeServiceStop(TestService* test_service) {
  135. base::ScopedAllowBlockingForTesting allow_blocking;
  136. test_service->Stop();
  137. }
  138. base::test::SingleThreadTaskEnvironment task_environment_;
  139. // Make the main thread not to allow IO.
  140. base::ScopedDisallowBlocking disallow_blocking_;
  141. std::unique_ptr<base::RunLoop> run_loop_;
  142. std::unique_ptr<base::Thread> dbus_thread_;
  143. scoped_refptr<Bus> bus_;
  144. raw_ptr<ObjectProxy> object_proxy_;
  145. std::unique_ptr<TestService> test_service_;
  146. std::unique_ptr<TestService> test_service2_;
  147. // Text message from "Test" signal.
  148. std::string test_signal_string_;
  149. // The known latest name owner of TestService. Updated in OnNameOwnerChanged.
  150. std::string latest_name_owner_;
  151. // Boolean flags to record callback calls.
  152. bool on_name_owner_changed_called_;
  153. bool on_ownership_called_;
  154. };
  155. TEST_F(SignalSenderVerificationTest, TestSignalAccepted) {
  156. const char kMessage[] = "hello, world";
  157. // Send the test signal from the exported object.
  158. test_service_->SendTestSignal(kMessage);
  159. // Receive the signal with the object proxy. The signal is handled in
  160. // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  161. WaitForTestSignal();
  162. ASSERT_EQ(kMessage, test_signal_string_);
  163. }
  164. TEST_F(SignalSenderVerificationTest, TestSignalRejected) {
  165. const char kNewMessage[] = "hello, new world";
  166. test_service2_->SendTestSignal(kNewMessage);
  167. // This test tests that our callback is NOT called by the ObjectProxy.
  168. // Sleep to have message delivered to the client via the D-Bus service.
  169. base::PlatformThread::Sleep(TestTimeouts::tiny_timeout());
  170. ASSERT_EQ("", test_signal_string_);
  171. }
  172. // Flaky. https://crbug.com/785555
  173. TEST_F(SignalSenderVerificationTest, DISABLED_TestOwnerChanged) {
  174. const char kMessage[] = "hello, world";
  175. // Send the test signal from the exported object.
  176. test_service_->SendTestSignal(kMessage);
  177. // Receive the signal with the object proxy. The signal is handled in
  178. // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  179. WaitForTestSignal();
  180. ASSERT_EQ(kMessage, test_signal_string_);
  181. // Release and acquire the name ownership.
  182. // latest_name_owner_ should be non empty as |test_service_| owns the name.
  183. ASSERT_FALSE(latest_name_owner_.empty());
  184. test_service_->ShutdownAndBlock();
  185. // OnNameOwnerChanged will PostTask to quit the message loop.
  186. run_loop_ = std::make_unique<base::RunLoop>();
  187. run_loop_->Run();
  188. // latest_name_owner_ should be empty as the owner is gone.
  189. ASSERT_TRUE(latest_name_owner_.empty());
  190. // Reset the flag as NameOwnerChanged is already received in setup.
  191. on_name_owner_changed_called_ = false;
  192. on_ownership_called_ = false;
  193. test_service2_->RequestOwnership(
  194. base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
  195. base::Unretained(this), true));
  196. // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  197. // but there's no expected order of those 2 event.
  198. run_loop_ = std::make_unique<base::RunLoop>();
  199. run_loop_->Run();
  200. if (!on_name_owner_changed_called_ || !on_ownership_called_) {
  201. run_loop_ = std::make_unique<base::RunLoop>();
  202. run_loop_->Run();
  203. }
  204. ASSERT_TRUE(on_name_owner_changed_called_);
  205. ASSERT_TRUE(on_ownership_called_);
  206. // latest_name_owner_ becomes non empty as the new owner appears.
  207. ASSERT_FALSE(latest_name_owner_.empty());
  208. // Now the second service owns the name.
  209. const char kNewMessage[] = "hello, new world";
  210. test_service2_->SendTestSignal(kNewMessage);
  211. WaitForTestSignal();
  212. ASSERT_EQ(kNewMessage, test_signal_string_);
  213. }
  214. // Flaky. https://crbug.com/785555
  215. TEST_F(SignalSenderVerificationTest, DISABLED_TestOwnerStealing) {
  216. // Release and acquire the name ownership.
  217. // latest_name_owner_ should be non empty as |test_service_| owns the name.
  218. ASSERT_FALSE(latest_name_owner_.empty());
  219. test_service_->ShutdownAndBlock();
  220. // OnNameOwnerChanged will PostTask to quit the message loop.
  221. run_loop_ = std::make_unique<base::RunLoop>();
  222. run_loop_->Run();
  223. // latest_name_owner_ should be empty as the owner is gone.
  224. ASSERT_TRUE(latest_name_owner_.empty());
  225. // Reset the flag as NameOwnerChanged is already received in setup.
  226. on_name_owner_changed_called_ = false;
  227. // Start a test service that allows theft, using the D-Bus thread.
  228. TestService::Options options;
  229. options.dbus_task_runner = dbus_thread_->task_runner();
  230. options.request_ownership_options = Bus::REQUIRE_PRIMARY_ALLOW_REPLACEMENT;
  231. options.service_name = test_service_->service_name();
  232. TestService stealable_test_service(options);
  233. ASSERT_TRUE(stealable_test_service.StartService());
  234. stealable_test_service.WaitUntilServiceIsStarted();
  235. ASSERT_TRUE(stealable_test_service.HasDBusThread());
  236. ASSERT_TRUE(stealable_test_service.has_ownership());
  237. // OnNameOwnerChanged will PostTask to quit the message loop.
  238. run_loop_ = std::make_unique<base::RunLoop>();
  239. run_loop_->Run();
  240. // Send a signal to check that the service is correctly owned.
  241. const char kMessage[] = "hello, world";
  242. // Send the test signal from the exported object.
  243. stealable_test_service.SendTestSignal(kMessage);
  244. // Receive the signal with the object proxy. The signal is handled in
  245. // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  246. WaitForTestSignal();
  247. ASSERT_EQ(kMessage, test_signal_string_);
  248. // Reset the flag as NameOwnerChanged was called above.
  249. on_name_owner_changed_called_ = false;
  250. test_service2_->RequestOwnership(
  251. base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
  252. base::Unretained(this), true));
  253. // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  254. // but there's no expected order of those 2 event.
  255. run_loop_ = std::make_unique<base::RunLoop>();
  256. run_loop_->Run();
  257. if (!on_name_owner_changed_called_ || !on_ownership_called_) {
  258. run_loop_ = std::make_unique<base::RunLoop>();
  259. run_loop_->Run();
  260. }
  261. ASSERT_TRUE(on_name_owner_changed_called_);
  262. ASSERT_TRUE(on_ownership_called_);
  263. // Now the second service owns the name.
  264. const char kNewMessage[] = "hello, new world";
  265. test_service2_->SendTestSignal(kNewMessage);
  266. WaitForTestSignal();
  267. ASSERT_EQ(kNewMessage, test_signal_string_);
  268. SafeServiceStop(&stealable_test_service);
  269. }
  270. // Fails on Linux ChromiumOS Tests
  271. TEST_F(SignalSenderVerificationTest, DISABLED_TestMultipleObjects) {
  272. const char kMessage[] = "hello, world";
  273. ObjectProxy* object_proxy2 = bus_->GetObjectProxy(
  274. test_service_->service_name(),
  275. ObjectPath("/org/chromium/DifferentObject"));
  276. bool second_name_owner_changed_called = false;
  277. object_proxy2->SetNameOwnerChangedCallback(base::BindRepeating(
  278. &SignalSenderVerificationTest::OnNameOwnerChanged, base::Unretained(this),
  279. &second_name_owner_changed_called));
  280. // Connect to a signal on the additional remote object to trigger the
  281. // name owner matching.
  282. object_proxy2->ConnectToSignal(
  283. "org.chromium.DifferentTestInterface", "Test",
  284. base::BindRepeating(&SignalSenderVerificationTest::OnTestSignal,
  285. base::Unretained(this)),
  286. base::BindOnce(&SignalSenderVerificationTest::OnConnected,
  287. base::Unretained(this)));
  288. // Wait until the object proxy is connected to the signal.
  289. run_loop_ = std::make_unique<base::RunLoop>();
  290. run_loop_->Run();
  291. // Send the test signal from the exported object.
  292. test_service_->SendTestSignal(kMessage);
  293. // Receive the signal with the object proxy. The signal is handled in
  294. // SignalSenderVerificationTest::OnTestSignal() in the main thread.
  295. WaitForTestSignal();
  296. ASSERT_EQ(kMessage, test_signal_string_);
  297. // Release and acquire the name ownership.
  298. // latest_name_owner_ should be non empty as |test_service_| owns the name.
  299. ASSERT_FALSE(latest_name_owner_.empty());
  300. test_service_->ShutdownAndBlock();
  301. // OnNameOwnerChanged will PostTask to quit the message loop.
  302. run_loop_ = std::make_unique<base::RunLoop>();
  303. run_loop_->Run();
  304. // latest_name_owner_ should be empty as the owner is gone.
  305. ASSERT_TRUE(latest_name_owner_.empty());
  306. // Reset the flag as NameOwnerChanged is already received in setup.
  307. on_name_owner_changed_called_ = false;
  308. second_name_owner_changed_called = false;
  309. test_service2_->RequestOwnership(
  310. base::BindOnce(&SignalSenderVerificationTest::OnOwnership,
  311. base::Unretained(this), true));
  312. // Both of OnNameOwnerChanged() and OnOwnership() should quit the MessageLoop,
  313. // but there's no expected order of those 2 event.
  314. while (!on_name_owner_changed_called_ || !second_name_owner_changed_called ||
  315. !on_ownership_called_) {
  316. run_loop_ = std::make_unique<base::RunLoop>();
  317. run_loop_->Run();
  318. }
  319. ASSERT_TRUE(on_name_owner_changed_called_);
  320. ASSERT_TRUE(second_name_owner_changed_called);
  321. ASSERT_TRUE(on_ownership_called_);
  322. // latest_name_owner_ becomes non empty as the new owner appears.
  323. ASSERT_FALSE(latest_name_owner_.empty());
  324. // Now the second service owns the name.
  325. const char kNewMessage[] = "hello, new world";
  326. test_service2_->SendTestSignal(kNewMessage);
  327. WaitForTestSignal();
  328. ASSERT_EQ(kNewMessage, test_signal_string_);
  329. }
  330. } // namespace dbus