// 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 "base/bind.h"
#include "base/values.h"
#include "chromeos/dbus/shill_client_unittest_base.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "dbus/message.h"
#include "dbus/object_path.h"
#include "dbus/values_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
using testing::_;
using testing::ByRef;
namespace chromeos {
namespace {
void ExpectStringArguments(const std::vector<std::string>& arguments,
dbus::MessageReader* reader) {
for (std::vector<std::string>::const_iterator iter = arguments.begin();
iter != arguments.end(); ++iter) {
std::string arg_string;
ASSERT_TRUE(reader->PopString(&arg_string));
EXPECT_EQ(*iter, arg_string);
}
EXPECT_FALSE(reader->HasMoreData());
}
void ExpectStringArgumentsFollowedByObjectPath(
const std::vector<std::string>& arguments,
const dbus::ObjectPath& object_path,
dbus::MessageReader* reader) {
for (std::vector<std::string>::const_iterator iter = arguments.begin();
iter != arguments.end(); ++iter) {
std::string arg_string;
ASSERT_TRUE(reader->PopString(&arg_string));
EXPECT_EQ(*iter, arg_string);
}
dbus::ObjectPath path;
ASSERT_TRUE(reader->PopObjectPath(&path));
EXPECT_EQ(object_path, path);
EXPECT_FALSE(reader->HasMoreData());
}
} // namespace
class ShillManagerClientTest : public ShillClientUnittestBase {
public:
ShillManagerClientTest()
: ShillClientUnittestBase(shill::kFlimflamManagerInterface,
dbus::ObjectPath(shill::kFlimflamServicePath)) {
}
virtual void SetUp() {
ShillClientUnittestBase::SetUp();
// Create a client with the mock bus.
client_.reset(ShillManagerClient::Create());
client_->Init(mock_bus_.get());
// Run the message loop to run the signal connection result callback.
message_loop_.RunUntilIdle();
}
virtual void TearDown() {
ShillClientUnittestBase::TearDown();
}
protected:
scoped_ptr<ShillManagerClient> client_;
};
TEST_F(ShillManagerClientTest, PropertyChanged) {
// Create a signal.
base::FundamentalValue kOfflineMode(true);
dbus::Signal signal(shill::kFlimflamManagerInterface,
shill::kMonitorPropertyChanged);
dbus::MessageWriter writer(&signal);
writer.AppendString(shill::kOfflineModeProperty);
dbus::AppendBasicTypeValueData(&writer, kOfflineMode);
// Set expectations.
MockPropertyChangeObserver observer;
EXPECT_CALL(observer,
OnPropertyChanged(shill::kOfflineModeProperty,
ValueEq(ByRef(kOfflineMode)))).Times(1);
// Add the observer
client_->AddPropertyChangedObserver(&observer);
// Run the signal callback.
SendPropertyChangedSignal(&signal);
// Remove the observer.
client_->RemovePropertyChangedObserver(&observer);
// Make sure it's not called anymore.
EXPECT_CALL(observer, OnPropertyChanged(_, _)).Times(0);
// Run the signal callback again and make sure the observer isn't called.
SendPropertyChangedSignal(&signal);
}
TEST_F(ShillManagerClientTest, GetProperties) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
dbus::MessageWriter array_writer(NULL);
writer.OpenArray("{sv}", &array_writer);
dbus::MessageWriter entry_writer(NULL);
array_writer.OpenDictEntry(&entry_writer);
entry_writer.AppendString(shill::kOfflineModeProperty);
entry_writer.AppendVariantOfBool(true);
array_writer.CloseContainer(&entry_writer);
writer.CloseContainer(&array_writer);
// Create the expected value.
base::DictionaryValue value;
value.SetWithoutPathExpansion(shill::kOfflineModeProperty,
base::Value::CreateBooleanValue(true));
// Set expectations.
PrepareForMethodCall(shill::kGetPropertiesFunction,
base::Bind(&ExpectNoArgument),
response.get());
// Call method.
client_->GetProperties(base::Bind(&ExpectDictionaryValueResult, &value));
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, GetNetworksForGeolocation) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
dbus::MessageWriter type_dict_writer(NULL);
writer.OpenArray("{sv}", &type_dict_writer);
dbus::MessageWriter type_entry_writer(NULL);
type_dict_writer.OpenDictEntry(&type_entry_writer);
type_entry_writer.AppendString(shill::kTypeWifi);
dbus::MessageWriter variant_writer(NULL);
type_entry_writer.OpenVariant("aa{ss}", &variant_writer);
dbus::MessageWriter wap_list_writer(NULL);
variant_writer.OpenArray("a{ss}", &wap_list_writer);
dbus::MessageWriter property_dict_writer(NULL);
wap_list_writer.OpenArray("{ss}", &property_dict_writer);
dbus::MessageWriter property_entry_writer(NULL);
property_dict_writer.OpenDictEntry(&property_entry_writer);
property_entry_writer.AppendString(shill::kGeoMacAddressProperty);
property_entry_writer.AppendString("01:23:45:67:89:AB");
property_dict_writer.CloseContainer(&property_entry_writer);
wap_list_writer.CloseContainer(&property_dict_writer);
variant_writer.CloseContainer(&wap_list_writer);
type_entry_writer.CloseContainer(&wap_list_writer);
type_dict_writer.CloseContainer(&type_entry_writer);
writer.CloseContainer(&type_dict_writer);
// Create the expected value.
base::DictionaryValue type_dict_value;
base::ListValue* type_entry_value = new base::ListValue;
base::DictionaryValue* property_dict_value = new base::DictionaryValue;
property_dict_value->SetWithoutPathExpansion(
shill::kGeoMacAddressProperty,
base::Value::CreateStringValue("01:23:45:67:89:AB"));
type_entry_value->Append(property_dict_value);
type_dict_value.SetWithoutPathExpansion("wifi", type_entry_value);
// Set expectations.
PrepareForMethodCall(shill::kGetNetworksForGeolocation,
base::Bind(&ExpectNoArgument),
response.get());
// Call method.
client_->GetNetworksForGeolocation(base::Bind(&ExpectDictionaryValueResult,
&type_dict_value));
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, SetProperty) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
// Set expectations.
base::StringValue value("portal list");
PrepareForMethodCall(shill::kSetPropertyFunction,
base::Bind(ExpectStringAndValueArguments,
shill::kCheckPortalListProperty,
&value),
response.get());
// Call method.
MockClosure mock_closure;
MockErrorCallback mock_error_callback;
client_->SetProperty(shill::kCheckPortalListProperty,
value,
mock_closure.GetCallback(),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_closure, Run()).Times(1);
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, RequestScan) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
// Set expectations.
PrepareForMethodCall(shill::kRequestScanFunction,
base::Bind(&ExpectStringArgument, shill::kTypeWifi),
response.get());
// Call method.
MockClosure mock_closure;
MockErrorCallback mock_error_callback;
client_->RequestScan(shill::kTypeWifi,
mock_closure.GetCallback(),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_closure, Run()).Times(1);
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, EnableTechnology) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
// Set expectations.
PrepareForMethodCall(shill::kEnableTechnologyFunction,
base::Bind(&ExpectStringArgument, shill::kTypeWifi),
response.get());
// Call method.
MockClosure mock_closure;
MockErrorCallback mock_error_callback;
client_->EnableTechnology(shill::kTypeWifi,
mock_closure.GetCallback(),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_closure, Run()).Times(1);
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, DisableTechnology) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
// Set expectations.
PrepareForMethodCall(shill::kDisableTechnologyFunction,
base::Bind(&ExpectStringArgument, shill::kTypeWifi),
response.get());
// Call method.
MockClosure mock_closure;
MockErrorCallback mock_error_callback;
client_->DisableTechnology(shill::kTypeWifi,
mock_closure.GetCallback(),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_closure, Run()).Times(1);
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, ConfigureService) {
// Create response.
const dbus::ObjectPath object_path("/");
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
writer.AppendObjectPath(object_path);
// Create the argument dictionary.
scoped_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties());
// Set expectations.
PrepareForMethodCall(shill::kConfigureServiceFunction,
base::Bind(&ExpectDictionaryValueArgument, arg.get()),
response.get());
// Call method.
MockErrorCallback mock_error_callback;
client_->ConfigureService(*arg,
base::Bind(&ExpectObjectPathResultWithoutStatus,
object_path),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, GetService) {
// Create response.
const dbus::ObjectPath object_path("/");
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
writer.AppendObjectPath(object_path);
// Create the argument dictionary.
scoped_ptr<base::DictionaryValue> arg(CreateExampleServiceProperties());
// Set expectations.
PrepareForMethodCall(shill::kGetServiceFunction,
base::Bind(&ExpectDictionaryValueArgument, arg.get()),
response.get());
// Call method.
MockErrorCallback mock_error_callback;
client_->GetService(*arg,
base::Bind(&ExpectObjectPathResultWithoutStatus,
object_path),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, VerifyDestination) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
bool expected = true;
writer.AppendBool(expected);
// Set expectations.
std::vector<std::string> arguments;
arguments.push_back("certificate");
arguments.push_back("public_key");
arguments.push_back("nonce");
arguments.push_back("signed_data");
arguments.push_back("device_serial");
arguments.push_back("device_ssid");
arguments.push_back("device_bssid");
PrepareForMethodCall(shill::kVerifyDestinationFunction,
base::Bind(&ExpectStringArguments, arguments),
response.get());
// Call method.
MockErrorCallback mock_error_callback;
ShillManagerClient::VerificationProperties properties;
properties.certificate = arguments[0];
properties.public_key = arguments[1];
properties.nonce = arguments[2];
properties.signed_data = arguments[3];
properties.device_serial = arguments[4];
properties.device_ssid = arguments[5];
properties.device_bssid = arguments[6];
client_->VerifyDestination(
properties,
base::Bind(&ExpectBoolResultWithoutStatus, expected),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, VerifyAndEncryptCredentials) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
std::string expected = "encrypted_credentials";
writer.AppendString(expected);
// Set expectations.
std::vector<std::string> arguments;
arguments.push_back("certificate");
arguments.push_back("public_key");
arguments.push_back("nonce");
arguments.push_back("signed_data");
arguments.push_back("device_serial");
arguments.push_back("device_ssid");
arguments.push_back("device_bssid");
std::string service_path = "/";
dbus::ObjectPath service_path_obj(service_path);
PrepareForMethodCall(shill::kVerifyAndEncryptCredentialsFunction,
base::Bind(&ExpectStringArgumentsFollowedByObjectPath,
arguments,
service_path_obj),
response.get());
// Call method.
MockErrorCallback mock_error_callback;
ShillManagerClient::VerificationProperties properties;
properties.certificate = arguments[0];
properties.public_key = arguments[1];
properties.nonce = arguments[2];
properties.signed_data = arguments[3];
properties.device_serial = arguments[4];
properties.device_ssid = arguments[5];
properties.device_bssid = arguments[6];
client_->VerifyAndEncryptCredentials(
properties,
service_path,
base::Bind(&ExpectStringResultWithoutStatus, expected),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
TEST_F(ShillManagerClientTest, VerifyAndEncryptData) {
// Create response.
scoped_ptr<dbus::Response> response(dbus::Response::CreateEmpty());
dbus::MessageWriter writer(response.get());
std::string expected = "encrypted_data";
writer.AppendString(expected);
// Set expectations.
std::vector<std::string> arguments;
arguments.push_back("certificate");
arguments.push_back("public_key");
arguments.push_back("nonce");
arguments.push_back("signed_data");
arguments.push_back("device_serial");
arguments.push_back("device_ssid");
arguments.push_back("device_bssid");
arguments.push_back("data");
PrepareForMethodCall(shill::kVerifyAndEncryptDataFunction,
base::Bind(&ExpectStringArguments, arguments),
response.get());
// Call method.
MockErrorCallback mock_error_callback;
ShillManagerClient::VerificationProperties properties;
properties.certificate = arguments[0];
properties.public_key = arguments[1];
properties.nonce = arguments[2];
properties.signed_data = arguments[3];
properties.device_serial = arguments[4];
properties.device_ssid = arguments[5];
properties.device_bssid = arguments[6];
client_->VerifyAndEncryptData(
properties,
arguments[7],
base::Bind(&ExpectStringResultWithoutStatus, expected),
mock_error_callback.GetCallback());
EXPECT_CALL(mock_error_callback, Run(_, _)).Times(0);
// Run the message loop.
message_loop_.RunUntilIdle();
}
} // namespace chromeos