blob: 0e991ef6f56034e09e3b0877e72fdf0df425ac2b [file] [log] [blame]
// 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/network/network_connection_handler.h"
#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/shill_manager_client.h"
#include "chromeos/dbus/shill_service_client.h"
#include "chromeos/network/network_configuration_handler.h"
#include "chromeos/network/network_state_handler.h"
#include "chromeos/network/onc/onc_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/cros_system_api/dbus/service_constants.h"
namespace {
const char* kSuccessResult = "success";
void ConfigureCallback(const dbus::ObjectPath& result) {
}
void ConfigureErrorCallback(const std::string& error_name,
const std::string& error_message) {
}
} // namespace
namespace chromeos {
class NetworkConnectionHandlerTest : public testing::Test {
public:
NetworkConnectionHandlerTest() {
}
virtual ~NetworkConnectionHandlerTest() {
}
virtual void SetUp() OVERRIDE {
// Initialize DBusThreadManager with a stub implementation.
DBusThreadManager::InitializeWithStub();
message_loop_.RunUntilIdle();
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()
->ClearServices();
message_loop_.RunUntilIdle();
LoginState::Initialize();
network_state_handler_.reset(NetworkStateHandler::InitializeForTest());
network_configuration_handler_.reset(
NetworkConfigurationHandler::InitializeForTest(
network_state_handler_.get()));
network_connection_handler_.reset(new NetworkConnectionHandler);
// TODO(stevenjb): Test integration with CertLoader using a stub or mock.
network_connection_handler_->Init(network_state_handler_.get(),
network_configuration_handler_.get());
}
virtual void TearDown() OVERRIDE {
network_connection_handler_.reset();
network_configuration_handler_.reset();
network_state_handler_.reset();
LoginState::Shutdown();
DBusThreadManager::Shutdown();
}
protected:
bool Configure(const std::string& json_string) {
scoped_ptr<base::DictionaryValue> json_dict =
onc::ReadDictionaryFromJson(json_string);
if (!json_dict) {
LOG(ERROR) << "Error parsing json: " << json_string;
return false;
}
DBusThreadManager::Get()->GetShillManagerClient()->ConfigureService(
*json_dict,
base::Bind(&ConfigureCallback),
base::Bind(&ConfigureErrorCallback));
message_loop_.RunUntilIdle();
return true;
}
void Connect(const std::string& service_path) {
const bool check_error_state = true;
network_connection_handler_->ConnectToNetwork(
service_path,
base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
base::Unretained(this)),
check_error_state);
message_loop_.RunUntilIdle();
}
void Disconnect(const std::string& service_path) {
network_connection_handler_->DisconnectNetwork(
service_path,
base::Bind(&NetworkConnectionHandlerTest::SuccessCallback,
base::Unretained(this)),
base::Bind(&NetworkConnectionHandlerTest::ErrorCallback,
base::Unretained(this)));
message_loop_.RunUntilIdle();
}
void SuccessCallback() {
result_ = kSuccessResult;
}
void ErrorCallback(const std::string& error_name,
scoped_ptr<base::DictionaryValue> error_data) {
result_ = error_name;
}
std::string GetResultAndReset() {
std::string result;
result.swap(result_);
return result;
}
std::string GetServiceStringProperty(const std::string& service_path,
const std::string& key) {
std::string result;
const base::DictionaryValue* properties =
DBusThreadManager::Get()->GetShillServiceClient()->GetTestInterface()->
GetServiceProperties(service_path);
if (properties)
properties->GetStringWithoutPathExpansion(key, &result);
return result;
}
scoped_ptr<NetworkStateHandler> network_state_handler_;
scoped_ptr<NetworkConfigurationHandler> network_configuration_handler_;
scoped_ptr<NetworkConnectionHandler> network_connection_handler_;
base::MessageLoopForUI message_loop_;
std::string result_;
private:
DISALLOW_COPY_AND_ASSIGN(NetworkConnectionHandlerTest);
};
namespace {
const char* kConfigConnectable =
"{ \"GUID\": \"wifi0\", \"Type\": \"wifi\", \"State\": \"idle\", "
" \"Connectable\": true }";
const char* kConfigConnected =
"{ \"GUID\": \"wifi1\", \"Type\": \"wifi\", \"State\": \"online\" }";
const char* kConfigConnecting =
"{ \"GUID\": \"wifi2\", \"Type\": \"wifi\", \"State\": \"association\" }";
const char* kConfigRequiresPassphrase =
"{ \"GUID\": \"wifi3\", \"Type\": \"wifi\", "
" \"PassphraseRequired\": true }";
const char* kConfigRequiresActivation =
"{ \"GUID\": \"cellular1\", \"Type\": \"cellular\","
" \"Cellular.ActivationState\": \"not-activated\" }";
} // namespace
TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectSuccess) {
EXPECT_TRUE(Configure(kConfigConnectable));
Connect("wifi0");
EXPECT_EQ(kSuccessResult, GetResultAndReset());
EXPECT_EQ(shill::kStateOnline,
GetServiceStringProperty("wifi0", shill::kStateProperty));
}
// Handles basic failure cases.
TEST_F(NetworkConnectionHandlerTest, NetworkConnectionHandlerConnectFailure) {
Connect("no-network");
EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
GetResultAndReset());
EXPECT_TRUE(Configure(kConfigConnected));
Connect("wifi1");
EXPECT_EQ(NetworkConnectionHandler::kErrorConnected, GetResultAndReset());
EXPECT_TRUE(Configure(kConfigConnecting));
Connect("wifi2");
EXPECT_EQ(NetworkConnectionHandler::kErrorConnecting, GetResultAndReset());
EXPECT_TRUE(Configure(kConfigRequiresPassphrase));
Connect("wifi3");
EXPECT_EQ(NetworkConnectionHandler::kErrorPassphraseRequired,
GetResultAndReset());
EXPECT_TRUE(Configure(kConfigRequiresActivation));
Connect("cellular1");
EXPECT_EQ(NetworkConnectionHandler::kErrorActivationRequired,
GetResultAndReset());
}
namespace {
const char* kConfigRequiresCertificate =
"{ \"GUID\": \"wifi4\", \"Type\": \"wifi\", \"Connectable\": false,"
" \"Security\": \"802_1x\","
" \"UIData\": \"{"
" \\\"certificate_type\\\": \\\"pattern\\\","
" \\\"certificate_pattern\\\": {"
" \\\"Subject\\\": { \\\"CommonName\\\": \\\"Foo\\\" }"
" } }\" }";
} // namespace
// Handle certificates. TODO(stevenjb): Add certificate stubs to improve
// test coverage.
TEST_F(NetworkConnectionHandlerTest,
NetworkConnectionHandlerConnectCertificate) {
EXPECT_TRUE(Configure(kConfigRequiresCertificate));
Connect("wifi4");
EXPECT_EQ(NetworkConnectionHandler::kErrorCertificateRequired,
GetResultAndReset());
}
TEST_F(NetworkConnectionHandlerTest,
NetworkConnectionHandlerDisconnectSuccess) {
EXPECT_TRUE(Configure(kConfigConnected));
Disconnect("wifi1");
EXPECT_EQ(kSuccessResult, GetResultAndReset());
}
TEST_F(NetworkConnectionHandlerTest,
NetworkConnectionHandlerDisconnectFailure) {
Connect("no-network");
EXPECT_EQ(NetworkConnectionHandler::kErrorConfigureFailed,
GetResultAndReset());
EXPECT_TRUE(Configure(kConfigConnectable));
Disconnect("wifi0");
EXPECT_EQ(NetworkConnectionHandler::kErrorNotConnected, GetResultAndReset());
}
} // namespace chromeos