blob: eb6c3b9d8a343997eb8d6e37aba715027c94b22b [file] [log] [blame]
//
// Copyright (C) 2012 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
#include "shill/cellular/modem_manager.h"
#include <base/stl_util.h>
#include <ModemManager/ModemManager.h>
#include "shill/cellular/mock_dbus_objectmanager_proxy.h"
#include "shill/cellular/mock_modem.h"
#include "shill/cellular/mock_modem_info.h"
#include "shill/cellular/mock_modem_manager_proxy.h"
#include "shill/manager.h"
#include "shill/mock_control.h"
#include "shill/mock_manager.h"
#include "shill/test_event_dispatcher.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_, nullptr),
modem_info_(&control_, &dispatcher_, nullptr, &manager_) {}
virtual void SetUp() {
modem_.reset(
new StrictModem(kService, kModemPath, &modem_info_, &control_));
}
protected:
static const char kService[];
static const char kPath[];
static const char kModemPath[];
shared_ptr<StrictModem> modem_;
EventDispatcherForTest dispatcher_;
MockControl control_;
MockManager manager_;
MockModemInfo modem_info_;
};
const char ModemManagerTest::kService[] = "org.chromium.ModemManager";
const char ModemManagerTest::kPath[] = "/org/chromium/ModemManager";
const char ModemManagerTest::kModemPath[] = "/org/blah/Modem/blah/0";
class ModemManagerForTest : public ModemManager {
public:
ModemManagerForTest(ControlInterface* control_interface,
const string& service,
const string& path,
ModemInfo* modem_info)
: ModemManager(control_interface, service, path, modem_info) {}
MOCK_METHOD0(Start, void());
MOCK_METHOD0(Stop, void());
};
class ModemManagerCoreTest : public ModemManagerTest {
public:
ModemManagerCoreTest()
: ModemManagerTest(),
modem_manager_(&control_, kService, kPath, &modem_info_) {}
protected:
ModemManagerForTest modem_manager_;
};
TEST_F(ModemManagerCoreTest, ConnectDisconnect) {
EXPECT_FALSE(modem_manager_.service_connected_);
modem_manager_.Connect();
EXPECT_TRUE(modem_manager_.service_connected_);
modem_manager_.RecordAddedModem(modem_);
EXPECT_EQ(1, modem_manager_.modems_.size());
modem_manager_.ModemManager::Disconnect();
EXPECT_EQ(0, modem_manager_.modems_.size());
EXPECT_FALSE(modem_manager_.service_connected_);
}
TEST_F(ModemManagerCoreTest, AddRemoveModem) {
modem_manager_.Connect();
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(ControlInterface* control_interface,
const string& service,
const string& path,
ModemInfo* modem_info_) :
ModemManagerClassic(control_interface, service, path, modem_info_) {}
MOCK_METHOD1(InitModemClassic, void(shared_ptr<ModemClassic>));
};
class ModemManagerClassicTest : public ModemManagerTest {
public:
ModemManagerClassicTest()
: ModemManagerTest(),
modem_manager_(&control_, kService, kPath, &modem_info_),
proxy_(new MockModemManagerProxy()) {}
protected:
ModemManagerClassicMockInit modem_manager_;
MockModemManagerProxy* proxy_;
};
TEST_F(ModemManagerClassicTest, StartStop) {
EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
EXPECT_CALL(control_, CreateModemManagerProxy(_, kPath, kService, _, _))
.WillOnce(Return(proxy_));
modem_manager_.Start();
EXPECT_NE(nullptr, modem_manager_.proxy_.get());
modem_manager_.Stop();
EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
}
TEST_F(ModemManagerClassicTest, Connect) {
// Setup proxy.
modem_manager_.proxy_.reset(proxy_);
EXPECT_CALL(*proxy_, EnumerateDevices())
.WillOnce(Return(vector<string>(1, kModemPath)));
EXPECT_CALL(modem_manager_,
InitModemClassic(
Pointee(Field(&Modem::path_, StrEq(kModemPath)))));
modem_manager_.Connect();
EXPECT_EQ(1, modem_manager_.modems_.size());
ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
}
class ModemManager1MockInit : public ModemManager1 {
public:
ModemManager1MockInit(ControlInterface* control_interface,
const string& service,
const string& path,
ModemInfo* modem_info_) :
ModemManager1(control_interface, service, path, modem_info_) {}
MOCK_METHOD2(InitModem1, void(shared_ptr<Modem1>,
const InterfaceToProperties&));
};
class ModemManager1Test : public ModemManagerTest {
public:
ModemManager1Test()
: ModemManagerTest(),
modem_manager_(&control_, kService, kPath, &modem_info_),
proxy_(new MockDBusObjectManagerProxy()) {}
protected:
virtual void SetUp() {
proxy_->IgnoreSetCallbacks();
}
void Connect(const ObjectsWithProperties& expected_objects) {
ManagedObjectsCallback get_managed_objects_callback;
EXPECT_CALL(*proxy_, GetManagedObjects(_, _, _))
.WillOnce(SaveArg<1>(&get_managed_objects_callback));
modem_manager_.Connect();
get_managed_objects_callback.Run(expected_objects, Error());
}
static ObjectsWithProperties GetModemWithProperties() {
KeyValueStore o_fd_mm1_modem;
InterfaceToProperties properties;
properties[MM_DBUS_INTERFACE_MODEM] = o_fd_mm1_modem;
ObjectsWithProperties objects_with_properties;
objects_with_properties[kModemPath] = properties;
return objects_with_properties;
}
ModemManager1MockInit modem_manager_;
MockDBusObjectManagerProxy* proxy_;
MockControl control_;
};
TEST_F(ModemManager1Test, StartStop) {
EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
EXPECT_CALL(control_, CreateDBusObjectManagerProxy(kPath, kService, _, _))
.WillOnce(Return(proxy_));
EXPECT_CALL(*proxy_, set_interfaces_added_callback(_));
EXPECT_CALL(*proxy_, set_interfaces_removed_callback(_));
modem_manager_.Start();
EXPECT_NE(nullptr, modem_manager_.proxy_.get());
modem_manager_.Stop();
EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
}
TEST_F(ModemManager1Test, Connect) {
// Setup proxy.
modem_manager_.proxy_.reset(proxy_);
Connect(GetModemWithProperties());
EXPECT_EQ(1, modem_manager_.modems_.size());
EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
}
TEST_F(ModemManager1Test, AddRemoveInterfaces) {
// Setup proxy.
modem_manager_.proxy_.reset(proxy_);
// Have nothing come back from GetManagedObjects
Connect(ObjectsWithProperties());
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,
InterfaceToProperties());
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