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 "chrome/browser/chromeos/dbus/service_provider_test_helper.h" 6 7 #include "base/bind.h" 8 #include "dbus/message.h" 9 #include "dbus/mock_bus.h" 10 #include "testing/gmock/include/gmock/gmock.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 #include "third_party/cros_system_api/dbus/service_constants.h" 13 14 using ::testing::_; 15 using ::testing::AllOf; 16 using ::testing::Invoke; 17 using ::testing::ResultOf; 18 using ::testing::Return; 19 using ::testing::Unused; 20 21 namespace chromeos { 22 23 ServiceProviderTestHelper::ServiceProviderTestHelper() 24 : response_received_(false) { 25 } 26 27 ServiceProviderTestHelper::~ServiceProviderTestHelper() { 28 } 29 30 void ServiceProviderTestHelper::SetUp( 31 const std::string& exported_method_name, 32 CrosDBusService::ServiceProviderInterface* service_provider) { 33 // Create a mock bus. 34 dbus::Bus::Options options; 35 options.bus_type = dbus::Bus::SYSTEM; 36 mock_bus_ = new dbus::MockBus(options); 37 38 // ShutdownAndBlock() will be called in TearDown(). 39 EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return()); 40 41 // Create a mock exported object that behaves as 42 // org.chromium.CrosDBusService. 43 mock_exported_object_ = 44 new dbus::MockExportedObject(mock_bus_.get(), 45 dbus::ObjectPath(kLibCrosServicePath)); 46 47 // |mock_exported_object_|'s ExportMethod() will use 48 // |MockExportedObject(). 49 EXPECT_CALL( 50 *mock_exported_object_.get(), 51 ExportMethod(kLibCrosServiceInterface, exported_method_name, _, _)) 52 .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockExportMethod)); 53 54 // Create a mock object proxy, with which we call a method of 55 // |mock_exported_object_|. 56 mock_object_proxy_ = 57 new dbus::MockObjectProxy(mock_bus_.get(), 58 kLibCrosServiceName, 59 dbus::ObjectPath(kLibCrosServicePath)); 60 // |mock_object_proxy_|'s MockCallMethodAndBlock() will use 61 // MockCallMethodAndBlock() to return responses. 62 EXPECT_CALL(*mock_object_proxy_.get(), 63 MockCallMethodAndBlock( 64 AllOf(ResultOf(std::mem_fun(&dbus::MethodCall::GetInterface), 65 kLibCrosServiceInterface), 66 ResultOf(std::mem_fun(&dbus::MethodCall::GetMember), 67 exported_method_name)), 68 _)) 69 .WillOnce( 70 Invoke(this, &ServiceProviderTestHelper::MockCallMethodAndBlock)); 71 72 service_provider->Start(mock_exported_object_.get()); 73 } 74 75 void ServiceProviderTestHelper::TearDown() { 76 mock_bus_->ShutdownAndBlock(); 77 mock_exported_object_ = NULL; 78 mock_object_proxy_ = NULL; 79 mock_bus_ = NULL; 80 } 81 82 void ServiceProviderTestHelper::SetUpReturnSignal( 83 const std::string& interface_name, 84 const std::string& signal_name, 85 dbus::ObjectProxy::SignalCallback signal_callback, 86 dbus::ObjectProxy::OnConnectedCallback on_connected_callback) { 87 // |mock_exported_object_|'s SendSignal() will use 88 // MockSendSignal(). 89 EXPECT_CALL(*mock_exported_object_.get(), SendSignal(_)) 90 .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockSendSignal)); 91 92 // |mock_object_proxy_|'s ConnectToSignal will use 93 // MockConnectToSignal(). 94 EXPECT_CALL(*mock_object_proxy_.get(), 95 ConnectToSignal(interface_name, signal_name, _, _)) 96 .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockConnectToSignal)); 97 98 mock_object_proxy_->ConnectToSignal(interface_name, signal_name, 99 signal_callback, on_connected_callback); 100 } 101 102 scoped_ptr<dbus::Response> ServiceProviderTestHelper::CallMethod( 103 dbus::MethodCall* method_call) { 104 return mock_object_proxy_->CallMethodAndBlock( 105 method_call, 106 dbus::ObjectProxy::TIMEOUT_USE_DEFAULT); 107 } 108 109 void ServiceProviderTestHelper::MockExportMethod( 110 const std::string& interface_name, 111 const std::string& method_name, 112 dbus::ExportedObject::MethodCallCallback method_callback, 113 dbus::ExportedObject::OnExportedCallback on_exported_callback) { 114 // Tell the call back that the method is exported successfully. 115 on_exported_callback.Run(interface_name, method_name, true); 116 // Capture the callback, so we can run this at a later time. 117 method_callback_ = method_callback; 118 } 119 120 dbus::Response* ServiceProviderTestHelper::MockCallMethodAndBlock( 121 dbus::MethodCall* method_call, 122 Unused) { 123 // Set the serial number to non-zero, so 124 // dbus_message_new_method_return() won't emit a warning. 125 method_call->SetSerial(1); 126 // Run the callback captured in MockExportMethod(). In addition to returning 127 // a response that the caller will ignore, this will send a signal, which 128 // will be received by |on_signal_callback_|. 129 method_callback_.Run(method_call, 130 base::Bind(&ServiceProviderTestHelper::OnResponse, 131 base::Unretained(this))); 132 // Check for a response. 133 if (!response_received_) 134 message_loop_.Run(); 135 // Return response. 136 return response_.release(); 137 } 138 139 void ServiceProviderTestHelper::MockConnectToSignal( 140 const std::string& interface_name, 141 const std::string& signal_name, 142 dbus::ObjectProxy::SignalCallback signal_callback, 143 dbus::ObjectProxy::OnConnectedCallback connected_callback) { 144 // Tell the callback that the object proxy is connected to the signal. 145 connected_callback.Run(interface_name, signal_name, true); 146 // Capture the callback, so we can run this at a later time. 147 on_signal_callback_ = signal_callback; 148 } 149 150 void ServiceProviderTestHelper::MockSendSignal(dbus::Signal* signal) { 151 // Run the callback captured in MockConnectToSignal(). This will call 152 // OnSignalReceived(). 153 on_signal_callback_.Run(signal); 154 } 155 156 void ServiceProviderTestHelper::OnResponse( 157 scoped_ptr<dbus::Response> response) { 158 response_ = response.Pass(); 159 response_received_ = true; 160 if (message_loop_.is_running()) 161 message_loop_.Quit(); 162 } 163 164 } // namespace chromeos 165