12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/chromeos/dbus/service_provider_test_helper.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/message.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "dbus/mock_bus.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/cros_system_api/dbus/service_constants.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::_;
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::AllOf;
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Invoke;
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::ResultOf;
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Return;
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using ::testing::Unused;
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace chromeos {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ServiceProviderTestHelper::ServiceProviderTestHelper()
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : response_received_(false) {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ServiceProviderTestHelper::~ServiceProviderTestHelper() {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::SetUp(
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& exported_method_name,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    CrosDBusService::ServiceProviderInterface* service_provider) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a mock bus.
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  dbus::Bus::Options options;
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options.bus_type = dbus::Bus::SYSTEM;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_bus_ = new dbus::MockBus(options);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ShutdownAndBlock() will be called in TearDown().
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a mock exported object that behaves as
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // org.chromium.CrosDBusService.
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_exported_object_ =
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new dbus::MockExportedObject(mock_bus_.get(),
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   dbus::ObjectPath(kLibCrosServicePath));
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |mock_exported_object_|'s ExportMethod() will use
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |MockExportedObject().
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      *mock_exported_object_.get(),
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      ExportMethod(kLibCrosServiceInterface, exported_method_name, _, _))
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockExportMethod));
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a mock object proxy, with which we call a method of
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |mock_exported_object_|.
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_object_proxy_ =
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      new dbus::MockObjectProxy(mock_bus_.get(),
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                kLibCrosServiceName,
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                dbus::ObjectPath(kLibCrosServicePath));
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |mock_object_proxy_|'s MockCallMethodAndBlock() will use
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // MockCallMethodAndBlock() to return responses.
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*mock_object_proxy_.get(),
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              MockCallMethodAndBlock(
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                  AllOf(ResultOf(std::mem_fun(&dbus::MethodCall::GetInterface),
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 kLibCrosServiceInterface),
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                        ResultOf(std::mem_fun(&dbus::MethodCall::GetMember),
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                 exported_method_name)),
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                  _))
697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      .WillOnce(
707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)           Invoke(this, &ServiceProviderTestHelper::MockCallMethodAndBlock));
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_provider->Start(mock_exported_object_.get());
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::TearDown() {
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_bus_->ShutdownAndBlock();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_exported_object_ = NULL;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_object_proxy_ = NULL;
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_bus_ = NULL;
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::SetUpReturnSignal(
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signal_name,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ObjectProxy::SignalCallback signal_callback,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ObjectProxy::OnConnectedCallback on_connected_callback) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |mock_exported_object_|'s SendSignal() will use
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // MockSendSignal().
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*mock_exported_object_.get(), SendSignal(_))
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockSendSignal));
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // |mock_object_proxy_|'s ConnectToSignal will use
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // MockConnectToSignal().
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  EXPECT_CALL(*mock_object_proxy_.get(),
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              ConnectToSignal(interface_name, signal_name, _, _))
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      .WillOnce(Invoke(this, &ServiceProviderTestHelper::MockConnectToSignal));
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  mock_object_proxy_->ConnectToSignal(interface_name, signal_name,
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                      signal_callback, on_connected_callback);
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<dbus::Response> ServiceProviderTestHelper::CallMethod(
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall* method_call) {
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return mock_object_proxy_->CallMethodAndBlock(
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      method_call,
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      dbus::ObjectProxy::TIMEOUT_USE_DEFAULT);
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::MockExportMethod(
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& method_name,
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ExportedObject::MethodCallCallback method_callback,
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ExportedObject::OnExportedCallback on_exported_callback) {
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the call back that the method is exported successfully.
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  on_exported_callback.Run(interface_name, method_name, true);
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Capture the callback, so we can run this at a later time.
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  method_callback_ = method_callback;
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)dbus::Response* ServiceProviderTestHelper::MockCallMethodAndBlock(
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::MethodCall* method_call,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Unused) {
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Set the serial number to non-zero, so
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // dbus_message_new_method_return() won't emit a warning.
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  method_call->SetSerial(1);
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Run the callback captured in MockExportMethod(). In addition to returning
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // a response that the caller will ignore, this will send a signal, which
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // will be received by |on_signal_callback_|.
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  method_callback_.Run(method_call,
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                       base::Bind(&ServiceProviderTestHelper::OnResponse,
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                  base::Unretained(this)));
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Check for a response.
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!response_received_)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_loop_.Run();
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Return response.
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return response_.release();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::MockConnectToSignal(
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& interface_name,
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const std::string& signal_name,
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ObjectProxy::SignalCallback signal_callback,
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    dbus::ObjectProxy::OnConnectedCallback connected_callback) {
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Tell the callback that the object proxy is connected to the signal.
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  connected_callback.Run(interface_name, signal_name, true);
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Capture the callback, so we can run this at a later time.
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  on_signal_callback_ = signal_callback;
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::MockSendSignal(dbus::Signal* signal) {
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Run the callback captured in MockConnectToSignal(). This will call
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // OnSignalReceived().
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  on_signal_callback_.Run(signal);
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ServiceProviderTestHelper::OnResponse(
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    scoped_ptr<dbus::Response> response) {
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_ = response.Pass();
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  response_received_ = true;
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (message_loop_.is_running())
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    message_loop_.Quit();
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace chromeos
165