end_to_end_sync_unittest.cc 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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/memory/raw_ptr.h"
  6. #include "base/memory/ref_counted.h"
  7. #include "base/run_loop.h"
  8. #include "base/test/task_environment.h"
  9. #include "dbus/bus.h"
  10. #include "dbus/message.h"
  11. #include "dbus/object_path.h"
  12. #include "dbus/object_proxy.h"
  13. #include "dbus/test_service.h"
  14. #include "testing/gtest/include/gtest/gtest.h"
  15. namespace dbus {
  16. // The end-to-end test exercises the synchronous APIs in ObjectProxy and
  17. // ExportedObject. The test will launch a thread for the service side
  18. // operations (i.e. ExportedObject side).
  19. class EndToEndSyncTest : public testing::Test {
  20. public:
  21. EndToEndSyncTest() = default;
  22. void SetUp() override {
  23. // Start the test service;
  24. TestService::Options options;
  25. test_service_ = std::make_unique<TestService>(options);
  26. ASSERT_TRUE(test_service_->StartService());
  27. test_service_->WaitUntilServiceIsStarted();
  28. ASSERT_FALSE(test_service_->HasDBusThread());
  29. // Create the client.
  30. Bus::Options client_bus_options;
  31. client_bus_options.bus_type = Bus::SESSION;
  32. client_bus_options.connection_type = Bus::PRIVATE;
  33. client_bus_ = new Bus(client_bus_options);
  34. object_proxy_ = client_bus_->GetObjectProxy(
  35. test_service_->service_name(),
  36. ObjectPath("/org/chromium/TestObject"));
  37. ASSERT_FALSE(client_bus_->HasDBusThread());
  38. }
  39. void TearDown() override {
  40. test_service_->ShutdownAndBlock();
  41. test_service_->Stop();
  42. client_bus_->ShutdownAndBlock();
  43. }
  44. protected:
  45. base::test::SingleThreadTaskEnvironment task_environment_{
  46. base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
  47. std::unique_ptr<TestService> test_service_;
  48. scoped_refptr<Bus> client_bus_;
  49. raw_ptr<ObjectProxy> object_proxy_;
  50. };
  51. TEST_F(EndToEndSyncTest, Echo) {
  52. const std::string kHello = "hello";
  53. // Create the method call.
  54. MethodCall method_call("org.chromium.TestInterface", "Echo");
  55. MessageWriter writer(&method_call);
  56. writer.AppendString(kHello);
  57. // Call the method.
  58. const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
  59. std::unique_ptr<Response> response(
  60. object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
  61. ASSERT_TRUE(response.get());
  62. // Check the response. kHello should be echoed back.
  63. MessageReader reader(response.get());
  64. std::string returned_message;
  65. ASSERT_TRUE(reader.PopString(&returned_message));
  66. EXPECT_EQ(kHello, returned_message);
  67. }
  68. TEST_F(EndToEndSyncTest, Timeout) {
  69. const std::string kHello = "hello";
  70. // Create the method call.
  71. MethodCall method_call("org.chromium.TestInterface", "DelayedEcho");
  72. MessageWriter writer(&method_call);
  73. writer.AppendString(kHello);
  74. // Call the method with timeout of 0ms.
  75. const int timeout_ms = 0;
  76. std::unique_ptr<Response> response(
  77. object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
  78. // Should fail because of timeout.
  79. ASSERT_FALSE(response.get());
  80. }
  81. TEST_F(EndToEndSyncTest, NonexistentMethod) {
  82. MethodCall method_call("org.chromium.TestInterface", "Nonexistent");
  83. const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
  84. std::unique_ptr<Response> response(
  85. object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
  86. ASSERT_FALSE(response.get());
  87. }
  88. TEST_F(EndToEndSyncTest, BrokenMethod) {
  89. MethodCall method_call("org.chromium.TestInterface", "BrokenMethod");
  90. const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
  91. std::unique_ptr<Response> response(
  92. object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
  93. ASSERT_FALSE(response.get());
  94. }
  95. TEST_F(EndToEndSyncTest, InvalidServiceName) {
  96. // Bus name cannot contain '/'.
  97. const std::string invalid_service_name = ":1/2";
  98. // Replace object proxy with new one.
  99. object_proxy_ = client_bus_->GetObjectProxy(
  100. invalid_service_name, ObjectPath("/org/chromium/TestObject"));
  101. MethodCall method_call("org.chromium.TestInterface", "Echo");
  102. const int timeout_ms = ObjectProxy::TIMEOUT_USE_DEFAULT;
  103. std::unique_ptr<Response> response(
  104. object_proxy_->CallMethodAndBlock(&method_call, timeout_ms));
  105. ASSERT_FALSE(response.get());
  106. }
  107. TEST_F(EndToEndSyncTest, ConnectToSignalAndBlock) {
  108. constexpr char kMessage[] = "hello";
  109. base::RunLoop run_loop;
  110. std::string test_signal_string;
  111. EXPECT_TRUE(object_proxy_->ConnectToSignalAndBlock(
  112. "org.chromium.TestInterface", "Test",
  113. base::BindRepeating(
  114. [](base::OnceClosure quit_closure, std::string* return_string,
  115. Signal* signal) {
  116. MessageReader reader(signal);
  117. ASSERT_TRUE(reader.PopString(return_string));
  118. std::move(quit_closure).Run();
  119. },
  120. run_loop.QuitClosure(), &test_signal_string)));
  121. test_service_->SendTestSignal(kMessage);
  122. run_loop.Run();
  123. EXPECT_EQ(test_signal_string, kMessage);
  124. // Ensure resources on the DBus thread are cleaned up.
  125. task_environment_.RunUntilIdle();
  126. }
  127. } // namespace dbus