blocking_method_caller_unittest.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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 "chromeos/dbus/common/blocking_method_caller.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include "base/callback.h"
  9. #include "base/logging.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "base/task/single_thread_task_runner.h"
  12. #include "dbus/message.h"
  13. #include "dbus/mock_bus.h"
  14. #include "dbus/mock_object_proxy.h"
  15. #include "dbus/object_path.h"
  16. #include "testing/gmock/include/gmock/gmock.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. using ::testing::_;
  19. using ::testing::Invoke;
  20. using ::testing::Return;
  21. namespace chromeos {
  22. namespace {
  23. class FakeTaskRunner : public base::SingleThreadTaskRunner {
  24. public:
  25. // base::SingleThreadTaskRunner:
  26. bool PostDelayedTask(const base::Location& from_here,
  27. base::OnceClosure task,
  28. base::TimeDelta delay) override {
  29. std::move(task).Run();
  30. return true;
  31. }
  32. bool PostNonNestableDelayedTask(const base::Location& from_here,
  33. base::OnceClosure task,
  34. base::TimeDelta delay) override {
  35. return PostDelayedTask(from_here, std::move(task), delay);
  36. }
  37. bool RunsTasksInCurrentSequence() const override { return true; }
  38. protected:
  39. ~FakeTaskRunner() override = default;
  40. };
  41. } // namespace
  42. class BlockingMethodCallerTest : public testing::Test {
  43. public:
  44. BlockingMethodCallerTest() : task_runner_(new FakeTaskRunner) {}
  45. void SetUp() override {
  46. // Create a mock bus.
  47. dbus::Bus::Options options;
  48. options.bus_type = dbus::Bus::SYSTEM;
  49. mock_bus_ = new dbus::MockBus(options);
  50. // Create a mock proxy.
  51. mock_proxy_ =
  52. new dbus::MockObjectProxy(mock_bus_.get(), "org.chromium.TestService",
  53. dbus::ObjectPath("/org/chromium/TestObject"));
  54. // Set an expectation so mock_proxy's CallMethodAndBlock() will use
  55. // CreateMockProxyResponse() to return responses.
  56. EXPECT_CALL(*mock_proxy_.get(), CallMethodAndBlockWithErrorDetails(_, _, _))
  57. .WillRepeatedly(
  58. Invoke(this, &BlockingMethodCallerTest::CreateMockProxyResponse));
  59. // Set an expectation so mock_bus's GetObjectProxy() for the given
  60. // service name and the object path will return mock_proxy_.
  61. EXPECT_CALL(*mock_bus_.get(),
  62. GetObjectProxy("org.chromium.TestService",
  63. dbus::ObjectPath("/org/chromium/TestObject")))
  64. .WillOnce(Return(mock_proxy_.get()));
  65. // Set an expectation so mock_bus's GetDBusTaskRunner will return the fake
  66. // task runner.
  67. EXPECT_CALL(*mock_bus_.get(), GetDBusTaskRunner())
  68. .WillRepeatedly(Return(task_runner_.get()));
  69. // ShutdownAndBlock() will be called in TearDown().
  70. EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
  71. }
  72. void TearDown() override { mock_bus_->ShutdownAndBlock(); }
  73. protected:
  74. scoped_refptr<FakeTaskRunner> task_runner_;
  75. scoped_refptr<dbus::MockBus> mock_bus_;
  76. scoped_refptr<dbus::MockObjectProxy> mock_proxy_;
  77. private:
  78. // Returns a response for the given method call. Used to implement
  79. // CallMethodAndBlock() for |mock_proxy_|.
  80. std::unique_ptr<dbus::Response> CreateMockProxyResponse(
  81. dbus::MethodCall* method_call,
  82. int timeout_ms,
  83. dbus::ScopedDBusError* error) {
  84. if (method_call->GetInterface() == "org.chromium.TestInterface" &&
  85. method_call->GetMember() == "Echo") {
  86. dbus::MessageReader reader(method_call);
  87. std::string text_message;
  88. if (reader.PopString(&text_message)) {
  89. std::unique_ptr<dbus::Response> response =
  90. dbus::Response::CreateEmpty();
  91. dbus::MessageWriter writer(response.get());
  92. writer.AppendString(text_message);
  93. return response;
  94. }
  95. }
  96. LOG(ERROR) << "Unexpected method call: " << method_call->ToString();
  97. return nullptr;
  98. }
  99. };
  100. TEST_F(BlockingMethodCallerTest, Echo) {
  101. const char kHello[] = "Hello";
  102. // Get an object proxy from the mock bus.
  103. dbus::ObjectProxy* proxy = mock_bus_->GetObjectProxy(
  104. "org.chromium.TestService", dbus::ObjectPath("/org/chromium/TestObject"));
  105. // Create a method call.
  106. dbus::MethodCall method_call("org.chromium.TestInterface", "Echo");
  107. dbus::MessageWriter writer(&method_call);
  108. writer.AppendString(kHello);
  109. // Call the method.
  110. BlockingMethodCaller blocking_method_caller(mock_bus_.get(), proxy);
  111. std::unique_ptr<dbus::Response> response(
  112. blocking_method_caller.CallMethodAndBlock(&method_call));
  113. // Check the response.
  114. ASSERT_TRUE(response.get());
  115. dbus::MessageReader reader(response.get());
  116. std::string text_message;
  117. ASSERT_TRUE(reader.PopString(&text_message));
  118. // The text message should be echo'ed back.
  119. EXPECT_EQ(kHello, text_message);
  120. }
  121. } // namespace chromeos