blob: 43df3b21d676aff1932ccf54423e7732e23f1bce [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS 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 "shill/wimax_service.h"
#include <base/string_util.h>
#include <chromeos/dbus/service_constants.h>
#include <gtest/gtest.h>
#include "shill/error.h"
#include "shill/nice_mock_control.h"
#include "shill/mock_adaptors.h"
#include "shill/mock_manager.h"
#include "shill/mock_metrics.h"
#include "shill/mock_store.h"
#include "shill/mock_wimax.h"
#include "shill/mock_wimax_network_proxy.h"
#include "shill/mock_wimax_provider.h"
using std::string;
using testing::_;
using testing::NiceMock;
using testing::Return;
using wimax_manager::kEAPAnonymousIdentity;
using wimax_manager::kEAPUserIdentity;
using wimax_manager::kEAPUserPassword;
namespace shill {
namespace {
const char kTestLinkName[] = "wm0";
const char kTestAddress[] = "0123456789AB";
const int kTestInterfaceIndex = 5;
const char kTestPath[] = "/org/chromium/WiMaxManager/Device/wm7";
const char kTestName[] = "Test WiMAX Network";
const char kTestNetworkId[] = "1234abcd";
} // namespace
class WiMaxServiceTest : public testing::Test {
public:
WiMaxServiceTest()
: proxy_(new MockWiMaxNetworkProxy()),
manager_(&control_, NULL, NULL, NULL),
metrics_(static_cast<EventDispatcher *>(NULL)),
device_(new MockWiMax(&control_, NULL, &metrics_, &manager_,
kTestLinkName, kTestAddress, kTestInterfaceIndex,
kTestPath)),
service_(new WiMaxService(&control_, NULL, &metrics_, &manager_)) {
service_->set_friendly_name(kTestName);
service_->set_network_id(kTestNetworkId);
service_->InitStorageIdentifier();
}
virtual ~WiMaxServiceTest() {}
protected:
virtual void TearDown() {
service_->device_ = NULL;
}
void ExpectUpdateService() {
EXPECT_CALL(manager_, HasService(_)).WillOnce(Return(true));
EXPECT_CALL(manager_, UpdateService(_));
}
void SetConnectable(bool connectable) {
service_->connectable_ = connectable;
}
scoped_ptr<MockWiMaxNetworkProxy> proxy_;
NiceMockControl control_;
MockManager manager_;
NiceMock<MockMetrics> metrics_;
scoped_refptr<MockWiMax> device_;
WiMaxServiceRefPtr service_;
};
TEST_F(WiMaxServiceTest, GetConnectParameters) {
{
KeyValueStore parameters;
service_->GetConnectParameters(&parameters);
EXPECT_FALSE(parameters.ContainsString(kEAPAnonymousIdentity));
EXPECT_FALSE(parameters.ContainsString(kEAPUserIdentity));
EXPECT_FALSE(parameters.ContainsString(kEAPUserPassword));
}
{
Service::EapCredentials eap;
eap.anonymous_identity = "TestAnonymousIdentity";
eap.identity = "TestUserIdentity";
eap.password = "TestPassword";
service_->set_eap(eap);
KeyValueStore parameters;
service_->GetConnectParameters(&parameters);
EXPECT_EQ(eap.anonymous_identity,
parameters.LookupString(kEAPAnonymousIdentity, ""));
EXPECT_EQ(eap.identity, parameters.LookupString(kEAPUserIdentity, ""));
EXPECT_EQ(eap.password, parameters.LookupString(kEAPUserPassword, ""));
}
}
TEST_F(WiMaxServiceTest, GetDeviceRpcId) {
Error error;
EXPECT_EQ("/", service_->GetDeviceRpcId(&error));
EXPECT_EQ(Error::kNotSupported, error.type());
service_->device_ = device_;
error.Reset();
EXPECT_EQ(DeviceMockAdaptor::kRpcId, service_->GetDeviceRpcId(&error));
EXPECT_TRUE(error.IsSuccess());
}
TEST_F(WiMaxServiceTest, OnSignalStrengthChanged) {
const int kStrength = 55;
service_->OnSignalStrengthChanged(kStrength);
EXPECT_EQ(kStrength, service_->strength());
}
TEST_F(WiMaxServiceTest, StartStop) {
static const char kName[] = "My WiMAX Network";
const uint32 kIdentifier = 0x1234abcd;
const int kStrength = 66;
EXPECT_FALSE(service_->connectable());
EXPECT_FALSE(service_->IsStarted());
EXPECT_EQ(0, service_->strength());
EXPECT_FALSE(service_->proxy_.get());
EXPECT_CALL(*proxy_, Name(_)).WillOnce(Return(kName));
EXPECT_CALL(*proxy_, Identifier(_)).WillOnce(Return(kIdentifier));
EXPECT_CALL(*proxy_, SignalStrength(_)).WillOnce(Return(kStrength));
EXPECT_CALL(*proxy_, set_signal_strength_changed_callback(_));
ExpectUpdateService();
service_->need_passphrase_ = false;
EXPECT_TRUE(service_->Start(proxy_.release()));
EXPECT_TRUE(service_->IsStarted());
EXPECT_EQ(kStrength, service_->strength());
EXPECT_EQ(kName, service_->network_name());
EXPECT_EQ(kTestName, service_->friendly_name());
EXPECT_EQ(kTestNetworkId, service_->network_id());
EXPECT_TRUE(service_->connectable());
EXPECT_TRUE(service_->proxy_.get());
service_->device_ = device_;
EXPECT_CALL(*device_, OnServiceStopped(_));
ExpectUpdateService();
service_->Stop();
EXPECT_FALSE(service_->IsStarted());
EXPECT_EQ(0, service_->strength());
EXPECT_FALSE(service_->proxy_.get());
}
TEST_F(WiMaxServiceTest, SetEAP) {
ServiceRefPtr base_service = service_;
EXPECT_TRUE(base_service->Is8021x());
EXPECT_TRUE(service_->need_passphrase_);
EXPECT_FALSE(base_service->connectable());
// No password.
Service::EapCredentials eap;
eap.identity = "TestIdentity";
base_service->set_eap(eap);
EXPECT_TRUE(service_->need_passphrase_);
EXPECT_FALSE(base_service->connectable());
// Not started.
eap.password = "TestPassword";
base_service->set_eap(eap);
EXPECT_FALSE(service_->need_passphrase_);
EXPECT_FALSE(base_service->connectable());
// Connectable.
service_->proxy_.reset(proxy_.release());
ExpectUpdateService();
base_service->set_eap(eap);
EXPECT_FALSE(service_->need_passphrase_);
EXPECT_TRUE(base_service->connectable());
// Reset password.
ExpectUpdateService();
service_->ClearPassphrase();
EXPECT_TRUE(service_->need_passphrase_);
EXPECT_FALSE(base_service->connectable());
EXPECT_TRUE(base_service->eap().password.empty());
}
TEST_F(WiMaxServiceTest, ConvertIdentifierToNetworkId) {
EXPECT_EQ("00000000", WiMaxService::ConvertIdentifierToNetworkId(0));
EXPECT_EQ("abcd1234", WiMaxService::ConvertIdentifierToNetworkId(0xabcd1234));
EXPECT_EQ("ffffffff", WiMaxService::ConvertIdentifierToNetworkId(0xffffffff));
}
TEST_F(WiMaxServiceTest, StorageIdentifier) {
static const char kStorageId[] = "wimax_test_wimax_network_1234abcd";
EXPECT_EQ(kStorageId, service_->GetStorageIdentifier());
EXPECT_EQ(kStorageId,
WiMaxService::CreateStorageIdentifier(kTestNetworkId, kTestName));
}
TEST_F(WiMaxServiceTest, Save) {
NiceMock<MockStore> storage;
string storage_id = service_->GetStorageIdentifier();
EXPECT_CALL(storage, SetString(storage_id, _, _))
.WillRepeatedly(Return(true));
EXPECT_CALL(storage, DeleteKey(storage_id, _)).WillRepeatedly(Return(true));
EXPECT_CALL(storage, SetString(storage_id,
WiMaxService::kStorageNetworkId,
kTestNetworkId));
EXPECT_TRUE(service_->Save(&storage));
}
TEST_F(WiMaxServiceTest, Connect) {
// Connect but not connectable.
Error error;
EXPECT_FALSE(service_->connectable());
service_->Connect(&error);
EXPECT_EQ(Error::kOperationFailed, error.type());
SetConnectable(true);
// No carrier device available.
MockWiMaxProvider provider;
scoped_refptr<MockWiMax> null_device;
EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(null_device));
error.Reset();
service_->Connect(&error);
EXPECT_EQ(Error::kNoCarrier, error.type());
// Successful connect.
EXPECT_CALL(manager_, wimax_provider()).WillOnce(Return(&provider));
EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
EXPECT_CALL(*device_, ConnectTo(_, _));
error.Reset();
service_->Connect(&error);
EXPECT_TRUE(error.IsSuccess());
// Connect while already connected.
// TODO(benchan): Check for error if we populate error again after changing
// the way that Chrome handles Error::kAlreadyConnected situation.
service_->Connect(&error);
// Successful disconnect.
EXPECT_CALL(*device_, DisconnectFrom(_, _));
error.Reset();
ExpectUpdateService();
service_->Disconnect(&error);
EXPECT_TRUE(error.IsSuccess());
// Disconnect while not connected.
service_->Disconnect(&error);
EXPECT_EQ(Error::kNotConnected, error.type());
}
TEST_F(WiMaxServiceTest, Unload) {
MockWiMaxProvider provider;
EXPECT_CALL(manager_, wimax_provider())
.Times(2)
.WillRepeatedly(Return(&provider));
Service::EapCredentials eap;
eap.identity = "TestUserIdentity";
service_->set_eap(eap);
EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(false));
EXPECT_FALSE(service_->Unload());
EXPECT_TRUE(service_->eap().identity.empty());
eap.identity = "TestUserIdentity";
service_->set_eap(eap);
EXPECT_CALL(provider, OnServiceUnloaded(_)).WillOnce(Return(true));
EXPECT_TRUE(service_->Unload());
EXPECT_TRUE(service_->eap().identity.empty());
}
TEST_F(WiMaxServiceTest, SetState) {
service_->device_ = device_;
ServiceRefPtr base_service = service_;
EXPECT_EQ(Service::kStateIdle, service_->state());
EXPECT_CALL(manager_, UpdateService(_));
base_service->SetState(Service::kStateAssociating);
EXPECT_EQ(Service::kStateAssociating, service_->state());
EXPECT_TRUE(service_->device_);
EXPECT_CALL(manager_, UpdateService(_));
base_service->SetState(Service::kStateFailure);
EXPECT_EQ(Service::kStateFailure, service_->state());
EXPECT_FALSE(service_->device_);
}
TEST_F(WiMaxServiceTest, IsAutoConnectable) {
EXPECT_FALSE(service_->connectable());
const char *reason = "";
EXPECT_FALSE(service_->IsAutoConnectable(&reason));
MockWiMaxProvider provider;
EXPECT_CALL(manager_, wimax_provider())
.Times(2)
.WillRepeatedly(Return(&provider));
SetConnectable(true);
EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(false));
reason = "";
EXPECT_FALSE(service_->IsAutoConnectable(&reason));
EXPECT_EQ(WiMaxService::kAutoConnBusy, reason);
EXPECT_CALL(provider, SelectCarrier(_)).WillOnce(Return(device_));
EXPECT_CALL(*device_, IsIdle()).WillOnce(Return(true));
reason = "";
EXPECT_TRUE(service_->IsAutoConnectable(&reason));
EXPECT_STREQ("", reason);
}
} // namespace shill