root/chromeos/dbus/shill_client_unittest_base.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. PopStringToStringDictionary
  2. MatchAndExplain
  3. DescribeTo
  4. DescribeNegationTo
  5. GetCallback
  6. GetCallback
  7. MockPropertyChangeObserver
  8. MockPropertyChangeObserver
  9. GetCallback
  10. response_
  11. SetUp
  12. TearDown
  13. PrepareForMethodCall
  14. SendPropertyChangedSignal
  15. ExpectPropertyChanged
  16. ExpectNoArgument
  17. ExpectStringArgument
  18. ExpectArrayOfStringsArgument
  19. ExpectValueArgument
  20. ExpectStringAndValueArguments
  21. ExpectDictionaryValueArgument
  22. CreateExampleServiceProperties
  23. ExpectNoResultValue
  24. ExpectObjectPathResult
  25. ExpectObjectPathResultWithoutStatus
  26. ExpectBoolResultWithoutStatus
  27. ExpectStringResultWithoutStatus
  28. ExpectDictionaryValueResultWithoutStatus
  29. ExpectDictionaryValueResult
  30. OnConnectToSignal
  31. OnCallMethod
  32. OnCallMethodWithErrorCallback

// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chromeos/dbus/shill_client_unittest_base.h"

#include "base/bind.h"
#include "base/json/json_writer.h"
#include "base/values.h"
#include "chromeos/network/shill_property_util.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/values_util.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"

using ::testing::_;
using ::testing::Invoke;
using ::testing::Return;

namespace chromeos {

namespace {

// Pops a string-to-string dictionary from the reader.
base::DictionaryValue* PopStringToStringDictionary(
    dbus::MessageReader* reader) {
  dbus::MessageReader array_reader(NULL);
  if (!reader->PopArray(&array_reader))
    return NULL;
  scoped_ptr<base::DictionaryValue> result(new base::DictionaryValue);
  while (array_reader.HasMoreData()) {
    dbus::MessageReader entry_reader(NULL);
    std::string key;
    std::string value;
    if (!array_reader.PopDictEntry(&entry_reader) ||
        !entry_reader.PopString(&key) ||
        !entry_reader.PopString(&value))
      return NULL;
    result->SetWithoutPathExpansion(key, base::Value::CreateStringValue(value));
  }
  return result.release();
}

}  // namespace

ValueMatcher::ValueMatcher(const base::Value& value)
  : expected_value_(value.DeepCopy()) {}

bool ValueMatcher::MatchAndExplain(const base::Value& value,
                             MatchResultListener* listener) const {
  return expected_value_->Equals(&value);
}

void ValueMatcher::DescribeTo(::std::ostream* os) const {
  std::string expected_value_str;
  base::JSONWriter::WriteWithOptions(expected_value_.get(),
                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
                                     &expected_value_str);
  *os << "value equals " << expected_value_str;
}

void ValueMatcher::DescribeNegationTo(::std::ostream* os) const {
  std::string expected_value_str;
  base::JSONWriter::WriteWithOptions(expected_value_.get(),
                                     base::JSONWriter::OPTIONS_PRETTY_PRINT,
                                     &expected_value_str);
  *os << "value does not equal " << expected_value_str;
}


ShillClientUnittestBase::MockClosure::MockClosure() {}

ShillClientUnittestBase::MockClosure::~MockClosure() {}

base::Closure ShillClientUnittestBase::MockClosure::GetCallback() {
  return base::Bind(&MockClosure::Run, base::Unretained(this));
}


ShillClientUnittestBase::MockListValueCallback::MockListValueCallback() {}

ShillClientUnittestBase::MockListValueCallback::~MockListValueCallback() {}

ShillClientHelper::ListValueCallback
ShillClientUnittestBase::MockListValueCallback::GetCallback() {
  return base::Bind(&MockListValueCallback::Run, base::Unretained(this));
}


ShillClientUnittestBase::MockErrorCallback::MockErrorCallback() {}

ShillClientUnittestBase::MockErrorCallback::~MockErrorCallback() {}

ShillClientUnittestBase::MockPropertyChangeObserver::
  MockPropertyChangeObserver() {}

ShillClientUnittestBase::MockPropertyChangeObserver::
  ~MockPropertyChangeObserver() {}

ShillClientHelper::ErrorCallback
ShillClientUnittestBase::MockErrorCallback::GetCallback() {
  return base::Bind(&MockErrorCallback::Run, base::Unretained(this));
}


ShillClientUnittestBase::ShillClientUnittestBase(
    const std::string& interface_name,
    const dbus::ObjectPath& object_path)
    : interface_name_(interface_name),
      object_path_(object_path),
      response_(NULL) {
}

ShillClientUnittestBase::~ShillClientUnittestBase() {
}

void ShillClientUnittestBase::SetUp() {
  // Create a mock bus.
  dbus::Bus::Options options;
  options.bus_type = dbus::Bus::SYSTEM;
  mock_bus_ = new dbus::MockBus(options);

  // Create a mock proxy.
  mock_proxy_ = new dbus::MockObjectProxy(
      mock_bus_.get(),
      shill::kFlimflamServiceName,
      object_path_);

  // Set an expectation so mock_proxy's CallMethod() will use OnCallMethod()
  // to return responses.
  EXPECT_CALL(*mock_proxy_.get(), CallMethod(_, _, _))
      .WillRepeatedly(Invoke(this, &ShillClientUnittestBase::OnCallMethod));

  // Set an expectation so mock_proxy's CallMethodWithErrorCallback() will use
  // OnCallMethodWithErrorCallback() to return responses.
  EXPECT_CALL(*mock_proxy_.get(), CallMethodWithErrorCallback(_, _, _, _))
      .WillRepeatedly(Invoke(
           this, &ShillClientUnittestBase::OnCallMethodWithErrorCallback));

  // Set an expectation so mock_proxy's ConnectToSignal() will use
  // OnConnectToSignal() to run the callback.
  EXPECT_CALL(
      *mock_proxy_.get(),
      ConnectToSignal(interface_name_, shill::kMonitorPropertyChanged, _, _))
      .WillRepeatedly(
           Invoke(this, &ShillClientUnittestBase::OnConnectToSignal));

  // Set an expectation so mock_bus's GetObjectProxy() for the given
  // service name and the object path will return mock_proxy_.
  EXPECT_CALL(*mock_bus_.get(),
              GetObjectProxy(shill::kFlimflamServiceName, object_path_))
      .WillOnce(Return(mock_proxy_.get()));

  // Set an expectation so mock_bus's GetDBusTaskRunner will return the current
  // task runner.
  EXPECT_CALL(*mock_bus_.get(), GetDBusTaskRunner())
      .WillRepeatedly(Return(message_loop_.message_loop_proxy()));

  // ShutdownAndBlock() will be called in TearDown().
  EXPECT_CALL(*mock_bus_.get(), ShutdownAndBlock()).WillOnce(Return());
}

void ShillClientUnittestBase::TearDown() {
  mock_bus_->ShutdownAndBlock();
}

void ShillClientUnittestBase::PrepareForMethodCall(
    const std::string& method_name,
    const ArgumentCheckCallback& argument_checker,
    dbus::Response* response) {
  expected_method_name_ = method_name;
  argument_checker_ = argument_checker;
  response_ = response;
}

void ShillClientUnittestBase::SendPropertyChangedSignal(
    dbus::Signal* signal) {
  ASSERT_FALSE(property_changed_handler_.is_null());
  property_changed_handler_.Run(signal);
}

// static
void ShillClientUnittestBase::ExpectPropertyChanged(
    const std::string& expected_name,
    const base::Value* expected_value,
    const std::string& name,
    const base::Value& value) {
  EXPECT_EQ(expected_name, name);
  EXPECT_TRUE(expected_value->Equals(&value));
}

// static
void ShillClientUnittestBase::ExpectNoArgument(dbus::MessageReader* reader) {
  EXPECT_FALSE(reader->HasMoreData());
}

// static
void ShillClientUnittestBase::ExpectStringArgument(
    const std::string& expected_string,
    dbus::MessageReader* reader) {
  std::string str;
  ASSERT_TRUE(reader->PopString(&str));
  EXPECT_EQ(expected_string, str);
  EXPECT_FALSE(reader->HasMoreData());
}

// static
void ShillClientUnittestBase::ExpectArrayOfStringsArgument(
    const std::vector<std::string>& expected_strings,
    dbus::MessageReader* reader) {
  std::vector<std::string> strs;
  ASSERT_TRUE(reader->PopArrayOfStrings(&strs));
  EXPECT_EQ(expected_strings, strs);
  EXPECT_FALSE(reader->HasMoreData());
}

// static
void ShillClientUnittestBase::ExpectValueArgument(
    const base::Value* expected_value,
    dbus::MessageReader* reader) {
  scoped_ptr<base::Value> value(dbus::PopDataAsValue(reader));
  ASSERT_TRUE(value.get());
  EXPECT_TRUE(value->Equals(expected_value));
  EXPECT_FALSE(reader->HasMoreData());
}

// static
void ShillClientUnittestBase::ExpectStringAndValueArguments(
    const std::string& expected_string,
    const base::Value* expected_value,
    dbus::MessageReader* reader) {
  std::string str;
  ASSERT_TRUE(reader->PopString(&str));
  EXPECT_EQ(expected_string, str);
  scoped_ptr<base::Value> value(dbus::PopDataAsValue(reader));
  ASSERT_TRUE(value.get());
  EXPECT_TRUE(value->Equals(expected_value));
  EXPECT_FALSE(reader->HasMoreData());
}

// static
void ShillClientUnittestBase::ExpectDictionaryValueArgument(
    const base::DictionaryValue* expected_dictionary,
    dbus::MessageReader* reader) {
  dbus::MessageReader array_reader(NULL);
  ASSERT_TRUE(reader->PopArray(&array_reader));
  while (array_reader.HasMoreData()) {
    dbus::MessageReader entry_reader(NULL);
    ASSERT_TRUE(array_reader.PopDictEntry(&entry_reader));
    std::string key;
    ASSERT_TRUE(entry_reader.PopString(&key));
    dbus::MessageReader variant_reader(NULL);
    ASSERT_TRUE(entry_reader.PopVariant(&variant_reader));
    scoped_ptr<base::Value> value;
    // Variants in the dictionary can be basic types or string-to-string
    // dictinoary.
    switch (variant_reader.GetDataType()) {
      case dbus::Message::ARRAY:
        value.reset(PopStringToStringDictionary(&variant_reader));
        break;
      case dbus::Message::BOOL:
      case dbus::Message::INT32:
      case dbus::Message::STRING:
        value.reset(dbus::PopDataAsValue(&variant_reader));
        break;
      default:
        NOTREACHED();
    }
    ASSERT_TRUE(value.get());
    const base::Value* expected_value = NULL;
    EXPECT_TRUE(expected_dictionary->GetWithoutPathExpansion(key,
                                                             &expected_value));
    EXPECT_TRUE(value->Equals(expected_value));
  }
}

// static
base::DictionaryValue*
ShillClientUnittestBase::CreateExampleServiceProperties() {
  base::DictionaryValue* properties = new base::DictionaryValue;
  properties->SetWithoutPathExpansion(
      shill::kGuidProperty,
      base::Value::CreateStringValue("00000000-0000-0000-0000-000000000000"));
  properties->SetWithoutPathExpansion(
      shill::kModeProperty,
      base::Value::CreateStringValue(shill::kModeManaged));
  properties->SetWithoutPathExpansion(
      shill::kTypeProperty,
      base::Value::CreateStringValue(shill::kTypeWifi));
  shill_property_util::SetSSID("testssid", properties);
  properties->SetWithoutPathExpansion(
      shill::kSecurityProperty,
      base::Value::CreateStringValue(shill::kSecurityPsk));
  return properties;
}


// static
void ShillClientUnittestBase::ExpectNoResultValue(
    DBusMethodCallStatus call_status) {
  EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
}

// static
void ShillClientUnittestBase::ExpectObjectPathResult(
    const dbus::ObjectPath& expected_result,
    DBusMethodCallStatus call_status,
    const dbus::ObjectPath& result) {
  EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
  EXPECT_EQ(expected_result, result);
}

// static
void ShillClientUnittestBase::ExpectObjectPathResultWithoutStatus(
    const dbus::ObjectPath& expected_result,
    const dbus::ObjectPath& result) {
  EXPECT_EQ(expected_result, result);
}

// static
void ShillClientUnittestBase::ExpectBoolResultWithoutStatus(
    bool expected_result,
    bool result) {
  EXPECT_EQ(expected_result, result);
}

// static
void ShillClientUnittestBase::ExpectStringResultWithoutStatus(
    const std::string& expected_result,
    const std::string& result) {
  EXPECT_EQ(expected_result, result);
}

// static
void ShillClientUnittestBase::ExpectDictionaryValueResultWithoutStatus(
    const base::DictionaryValue* expected_result,
    const base::DictionaryValue& result) {
  std::string expected_result_string;
  base::JSONWriter::Write(expected_result, &expected_result_string);
  std::string result_string;
  base::JSONWriter::Write(&result, &result_string);
  EXPECT_EQ(expected_result_string, result_string);
}

// static
void ShillClientUnittestBase::ExpectDictionaryValueResult(
    const base::DictionaryValue* expected_result,
    DBusMethodCallStatus call_status,
    const base::DictionaryValue& result) {
  EXPECT_EQ(DBUS_METHOD_CALL_SUCCESS, call_status);
  ExpectDictionaryValueResultWithoutStatus(expected_result, result);
}

void ShillClientUnittestBase::OnConnectToSignal(
    const std::string& interface_name,
    const std::string& signal_name,
    const dbus::ObjectProxy::SignalCallback& signal_callback,
    const dbus::ObjectProxy::OnConnectedCallback& on_connected_callback) {
  property_changed_handler_ = signal_callback;
  const bool success = true;
  message_loop_.PostTask(FROM_HERE,
                         base::Bind(on_connected_callback,
                                    interface_name,
                                    signal_name,
                                    success));
}

void ShillClientUnittestBase::OnCallMethod(
    dbus::MethodCall* method_call,
    int timeout_ms,
    const dbus::ObjectProxy::ResponseCallback& response_callback) {
  EXPECT_EQ(interface_name_, method_call->GetInterface());
  EXPECT_EQ(expected_method_name_, method_call->GetMember());
  dbus::MessageReader reader(method_call);
  argument_checker_.Run(&reader);
  message_loop_.PostTask(FROM_HERE,
                         base::Bind(response_callback, response_));
}

void ShillClientUnittestBase::OnCallMethodWithErrorCallback(
    dbus::MethodCall* method_call,
    int timeout_ms,
    const dbus::ObjectProxy::ResponseCallback& response_callback,
    const dbus::ObjectProxy::ErrorCallback& error_callback) {
  OnCallMethod(method_call, timeout_ms, response_callback);
}

}  // namespace chromeos

/* [<][>][^][v][top][bottom][index][help] */