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