blob: fe532641574d5babe5b3d96627ca3f86621eb9dd [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 <base/stl_util.h>
#include <ModemManager/ModemManager.h>
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_dbus_objectmanager_proxy.h"
#include "shill/mock_dbus_service_proxy.h"
#include "shill/mock_manager.h"
#include "shill/mock_modem.h"
#include "shill/mock_modem_info.h"
#include "shill/mock_modem_manager_proxy.h"
#include "shill/mock_proxy_factory.h"
#include "shill/modem.h"
#include "shill/modem_manager.h"
#include "shill/testing.h"
using std::string;
using std::shared_ptr;
using std::vector;
using testing::_;
using testing::Invoke;
using testing::Pointee;
using testing::Return;
using testing::SaveArg;
using testing::StrEq;
using testing::Test;
namespace shill {
class ModemManagerTest : public Test {
public:
ModemManagerTest()
: manager_(&control_, &dispatcher_, NULL, NULL),
modem_info_(&control_, &dispatcher_, NULL, &manager_, NULL),
dbus_service_proxy_(NULL) {}
virtual void SetUp() {
modem_.reset(new StrictModem(kOwner, kService, kModemPath, &modem_info_));
manager_.dbus_manager_.reset(new DBusManager());
dbus_service_proxy_ = new MockDBusServiceProxy();
// Ownership of |dbus_service_proxy_| is transferred to
// |manager_.dbus_manager_|.
manager_.dbus_manager_->proxy_.reset(dbus_service_proxy_);
}
protected:
static const char kService[];
static const char kPath[];
static const char kOwner[];
static const char kModemPath[];
shared_ptr<StrictModem> modem_;
EventDispatcher dispatcher_;
MockControl control_;
MockManager manager_;
MockModemInfo modem_info_;
MockProxyFactory proxy_factory_;
MockDBusServiceProxy *dbus_service_proxy_;
};
const char ModemManagerTest::kService[] = "org.chromium.ModemManager";
const char ModemManagerTest::kPath[] = "/org/chromium/ModemManager";
const char ModemManagerTest::kOwner[] = ":1.17";
const char ModemManagerTest::kModemPath[] = "/org/blah/Modem/blah/0";
class ModemManagerCoreTest : public ModemManagerTest {
public:
ModemManagerCoreTest()
: ModemManagerTest(),
modem_manager_(kService, kPath, &modem_info_) {}
protected:
ModemManager modem_manager_;
};
TEST_F(ModemManagerCoreTest, StartStopWithModemManagerServiceAbsent) {
StringCallback get_name_owner_callback;
EXPECT_CALL(*dbus_service_proxy_, GetNameOwner(kService, _, _, _))
.WillOnce(SaveArg<2>(&get_name_owner_callback));
modem_manager_.Start();
get_name_owner_callback.Run("", Error());
EXPECT_EQ("", modem_manager_.owner_);
modem_manager_.Stop();
EXPECT_EQ("", modem_manager_.owner_);
}
TEST_F(ModemManagerCoreTest, StartStopWithModemManagerServicePresent) {
StringCallback get_name_owner_callback;
EXPECT_CALL(*dbus_service_proxy_, GetNameOwner(kService, _, _, _))
.WillOnce(SaveArg<2>(&get_name_owner_callback));
modem_manager_.Start();
get_name_owner_callback.Run(kOwner, Error());
EXPECT_EQ(kOwner, modem_manager_.owner_);
modem_manager_.Stop();
EXPECT_EQ("", modem_manager_.owner_);
}
TEST_F(ModemManagerCoreTest, OnAppearVanish) {
EXPECT_CALL(*dbus_service_proxy_, GetNameOwner(kService, _, _, _));
modem_manager_.Start();
EXPECT_EQ("", modem_manager_.owner_);
manager_.dbus_manager()->OnNameOwnerChanged(kService, "", kOwner);
EXPECT_EQ(kOwner, modem_manager_.owner_);
manager_.dbus_manager()->OnNameOwnerChanged(kService, kOwner, "");
EXPECT_EQ("", modem_manager_.owner_);
}
TEST_F(ModemManagerCoreTest, ConnectDisconnect) {
EXPECT_EQ("", modem_manager_.owner_);
modem_manager_.Connect(kOwner);
EXPECT_EQ(kOwner, modem_manager_.owner_);
EXPECT_EQ(0, modem_manager_.modems_.size());
modem_manager_.RecordAddedModem(modem_);
EXPECT_EQ(1, modem_manager_.modems_.size());
modem_manager_.ModemManager::Disconnect();
EXPECT_EQ("", modem_manager_.owner_);
EXPECT_EQ(0, modem_manager_.modems_.size());
}
TEST_F(ModemManagerCoreTest, AddRemoveModem) {
modem_manager_.Connect(kOwner);
EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
// Remove non-existent modem path.
modem_manager_.RemoveModem(kModemPath);
EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
modem_manager_.RecordAddedModem(modem_);
EXPECT_TRUE(modem_manager_.ModemExists(kModemPath));
// Add an already added modem.
modem_manager_.RecordAddedModem(modem_);
EXPECT_TRUE(modem_manager_.ModemExists(kModemPath));
modem_manager_.RemoveModem(kModemPath);
EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
// Remove an already removed modem path.
modem_manager_.RemoveModem(kModemPath);
EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
}
class ModemManagerClassicMockInit : public ModemManagerClassic {
public:
ModemManagerClassicMockInit(const string &service,
const string &path,
ModemInfo *modem_info_) :
ModemManagerClassic(service, path, modem_info_) {}
MOCK_METHOD1(InitModemClassic, void(shared_ptr<ModemClassic>));
};
class ModemManagerClassicTest : public ModemManagerTest {
public:
ModemManagerClassicTest()
: ModemManagerTest(),
modem_manager_(kService, kPath, &modem_info_),
proxy_(new MockModemManagerProxy()) {}
protected:
virtual void SetUp() {
modem_manager_.proxy_factory_ = &proxy_factory_;
}
virtual void TearDown() {
modem_manager_.proxy_factory_ = NULL;
}
ModemManagerClassicMockInit modem_manager_;
scoped_ptr<MockModemManagerProxy> proxy_;
};
TEST_F(ModemManagerClassicTest, Connect) {
EXPECT_EQ("", modem_manager_.owner_);
EXPECT_CALL(proxy_factory_, CreateModemManagerProxy(_, kPath, kOwner))
.WillOnce(ReturnAndReleasePointee(&proxy_));
EXPECT_CALL(*proxy_, EnumerateDevices())
.WillOnce(Return(vector<DBus::Path>(1, kModemPath)));
EXPECT_CALL(modem_manager_,
InitModemClassic(
Pointee(Field(&Modem::path_, StrEq(kModemPath)))));
modem_manager_.Connect(kOwner);
EXPECT_EQ(kOwner, modem_manager_.owner_);
EXPECT_EQ(1, modem_manager_.modems_.size());
ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
}
class ModemManager1MockInit : public ModemManager1 {
public:
ModemManager1MockInit(const string &service,
const string &path,
ModemInfo *modem_info_) :
ModemManager1(service, path, modem_info_) {}
MOCK_METHOD2(InitModem1, void(shared_ptr<Modem1>,
const DBusInterfaceToProperties &));
};
class ModemManager1Test : public ModemManagerTest {
public:
ModemManager1Test()
: ModemManagerTest(),
modem_manager_(kService, kPath, &modem_info_),
proxy_(new MockDBusObjectManagerProxy()) {}
protected:
virtual void SetUp() {
modem_manager_.proxy_factory_ = &proxy_factory_;
proxy_->IgnoreSetCallbacks();
}
virtual void TearDown() {
modem_manager_.proxy_factory_ = NULL;
}
void Connect(const DBusObjectsWithProperties &expected_objects) {
EXPECT_CALL(proxy_factory_, CreateDBusObjectManagerProxy(kPath, kOwner))
.WillOnce(ReturnAndReleasePointee(&proxy_));
EXPECT_CALL(*proxy_, set_interfaces_added_callback(_));
EXPECT_CALL(*proxy_, set_interfaces_removed_callback(_));
ManagedObjectsCallback get_managed_objects_callback;
EXPECT_CALL(*proxy_, GetManagedObjects(_, _, _))
.WillOnce(SaveArg<1>(&get_managed_objects_callback));
modem_manager_.Connect(kOwner);
get_managed_objects_callback.Run(expected_objects, Error());
}
static DBusObjectsWithProperties GetModemWithProperties() {
DBusPropertiesMap o_fd_mm1_modem;
DBusInterfaceToProperties properties;
properties[MM_DBUS_INTERFACE_MODEM] = o_fd_mm1_modem;
DBusObjectsWithProperties objects_with_properties;
objects_with_properties[kModemPath] = properties;
return objects_with_properties;
}
ModemManager1MockInit modem_manager_;
scoped_ptr<MockDBusObjectManagerProxy> proxy_;
MockProxyFactory proxy_factory_;
};
TEST_F(ModemManager1Test, Connect) {
Connect(GetModemWithProperties());
EXPECT_EQ(1, modem_manager_.modems_.size());
EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
}
TEST_F(ModemManager1Test, AddRemoveInterfaces) {
// Have nothing come back from GetManagedObjects
Connect(DBusObjectsWithProperties());
EXPECT_EQ(0, modem_manager_.modems_.size());
// Add an object that doesn't have a modem interface. Nothing should be added
EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(0);
modem_manager_.OnInterfacesAddedSignal(kModemPath,
DBusInterfaceToProperties());
EXPECT_EQ(0, modem_manager_.modems_.size());
// Actually add a modem
EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(1);
modem_manager_.OnInterfacesAddedSignal(kModemPath,
GetModemWithProperties()[kModemPath]);
EXPECT_EQ(1, modem_manager_.modems_.size());
// Remove an irrelevant interface
vector<string> not_including_modem_interface;
not_including_modem_interface.push_back("not.a.modem.interface");
modem_manager_.OnInterfacesRemovedSignal(kModemPath,
not_including_modem_interface);
EXPECT_EQ(1, modem_manager_.modems_.size());
// Remove the modem
vector<string> with_modem_interface;
with_modem_interface.push_back(MM_DBUS_INTERFACE_MODEM);
modem_manager_.OnInterfacesRemovedSignal(kModemPath, with_modem_interface);
EXPECT_EQ(0, modem_manager_.modems_.size());
}
} // namespace shill