blob: eb6c3b9d8a343997eb8d6e37aba715027c94b22b [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2012 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
Darin Petkov887f2982011-07-14 16:10:17 -070016
Ben Chanc54afe52014-11-05 10:28:08 -080017#include "shill/cellular/modem_manager.h"
Alex Deymocddd2d02014-11-10 19:55:35 -080018
Eric Shienbrood3e20a232012-02-16 11:35:56 -050019#include <base/stl_util.h>
Ben Chan5c853ef2012-10-05 00:05:37 -070020#include <ModemManager/ModemManager.h>
Darin Petkov887f2982011-07-14 16:10:17 -070021
Ben Chanc54afe52014-11-05 10:28:08 -080022#include "shill/cellular/mock_dbus_objectmanager_proxy.h"
23#include "shill/cellular/mock_modem.h"
24#include "shill/cellular/mock_modem_info.h"
25#include "shill/cellular/mock_modem_manager_proxy.h"
Darin Petkov887f2982011-07-14 16:10:17 -070026#include "shill/manager.h"
Ben Chan66174a12014-01-08 21:27:00 -080027#include "shill/mock_control.h"
Ben Chan66174a12014-01-08 21:27:00 -080028#include "shill/mock_manager.h"
Peter Qiu05d87e32015-08-14 23:46:21 -070029#include "shill/test_event_dispatcher.h"
Ben Chan1e2ba232014-01-27 16:35:45 -080030#include "shill/testing.h"
Darin Petkov887f2982011-07-14 16:10:17 -070031
Darin Petkovc90fe522011-07-15 13:59:47 -070032using std::string;
Alex Vakulenko8a532292014-06-16 17:18:44 -070033using std::shared_ptr;
Darin Petkov5c97ac52011-07-19 16:30:49 -070034using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070035using testing::_;
David Rochberg7cb06f62012-03-05 11:23:44 -050036using testing::Invoke;
David Rochbergb6b6ccb2012-03-16 13:40:36 -040037using testing::Pointee;
Darin Petkov887f2982011-07-14 16:10:17 -070038using testing::Return;
Ben Chan66174a12014-01-08 21:27:00 -080039using testing::SaveArg;
Darin Petkov887f2982011-07-14 16:10:17 -070040using testing::StrEq;
41using testing::Test;
42
43namespace shill {
44
45class ModemManagerTest : public Test {
46 public:
47 ModemManagerTest()
mukesh agrawalbad1c102015-09-18 16:15:08 -070048 : manager_(&control_, &dispatcher_, nullptr),
49 modem_info_(&control_, &dispatcher_, nullptr, &manager_) {}
David Rochbergfa1d31d2012-03-20 10:38:07 -040050
51 virtual void SetUp() {
Peter Qiu608ec292015-07-30 15:46:16 -070052 modem_.reset(
Peter Qiu05d87e32015-08-14 23:46:21 -070053 new StrictModem(kService, kModemPath, &modem_info_, &control_));
David Rochbergfa1d31d2012-03-20 10:38:07 -040054 }
Ben Chan62028b22012-11-05 11:20:02 -080055
Darin Petkov887f2982011-07-14 16:10:17 -070056 protected:
57 static const char kService[];
58 static const char kPath[];
Darin Petkov5c97ac52011-07-19 16:30:49 -070059 static const char kModemPath[];
Darin Petkov887f2982011-07-14 16:10:17 -070060
David Rochbergfa1d31d2012-03-20 10:38:07 -040061 shared_ptr<StrictModem> modem_;
62
Peter Qiu05d87e32015-08-14 23:46:21 -070063 EventDispatcherForTest dispatcher_;
Ben Chan66174a12014-01-08 21:27:00 -080064 MockControl control_;
65 MockManager manager_;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070066 MockModemInfo modem_info_;
Darin Petkov887f2982011-07-14 16:10:17 -070067};
68
Darin Petkov5c97ac52011-07-19 16:30:49 -070069const char ModemManagerTest::kService[] = "org.chromium.ModemManager";
70const char ModemManagerTest::kPath[] = "/org/chromium/ModemManager";
David Rochberg7cb06f62012-03-05 11:23:44 -050071const char ModemManagerTest::kModemPath[] = "/org/blah/Modem/blah/0";
Darin Petkov887f2982011-07-14 16:10:17 -070072
Peter Qiu05d87e32015-08-14 23:46:21 -070073class ModemManagerForTest : public ModemManager {
74 public:
75 ModemManagerForTest(ControlInterface* control_interface,
76 const string& service,
77 const string& path,
78 ModemInfo* modem_info)
79 : ModemManager(control_interface, service, path, modem_info) {}
80
81 MOCK_METHOD0(Start, void());
82 MOCK_METHOD0(Stop, void());
83};
84
David Rochberg7cb06f62012-03-05 11:23:44 -050085class ModemManagerCoreTest : public ModemManagerTest {
86 public:
87 ModemManagerCoreTest()
88 : ModemManagerTest(),
Peter Qiu05d87e32015-08-14 23:46:21 -070089 modem_manager_(&control_, kService, kPath, &modem_info_) {}
Darin Petkovab565bb2011-10-06 02:55:51 -070090
David Rochberg7cb06f62012-03-05 11:23:44 -050091 protected:
Peter Qiu05d87e32015-08-14 23:46:21 -070092 ModemManagerForTest modem_manager_;
David Rochberg7cb06f62012-03-05 11:23:44 -050093};
94
Ben Chan66174a12014-01-08 21:27:00 -080095TEST_F(ModemManagerCoreTest, ConnectDisconnect) {
Peter Qiu05d87e32015-08-14 23:46:21 -070096 EXPECT_FALSE(modem_manager_.service_connected_);
97 modem_manager_.Connect();
98 EXPECT_TRUE(modem_manager_.service_connected_);
Ben Chan66174a12014-01-08 21:27:00 -080099
David Rochbergfa1d31d2012-03-20 10:38:07 -0400100 modem_manager_.RecordAddedModem(modem_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500101 EXPECT_EQ(1, modem_manager_.modems_.size());
102
103 modem_manager_.ModemManager::Disconnect();
David Rochberg7cb06f62012-03-05 11:23:44 -0500104 EXPECT_EQ(0, modem_manager_.modems_.size());
Peter Qiu05d87e32015-08-14 23:46:21 -0700105 EXPECT_FALSE(modem_manager_.service_connected_);
Darin Petkov887f2982011-07-14 16:10:17 -0700106}
107
Ben Chan66174a12014-01-08 21:27:00 -0800108TEST_F(ModemManagerCoreTest, AddRemoveModem) {
Peter Qiu05d87e32015-08-14 23:46:21 -0700109 modem_manager_.Connect();
David Rochbergfa1d31d2012-03-20 10:38:07 -0400110 EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
Ben Chan66174a12014-01-08 21:27:00 -0800111
112 // Remove non-existent modem path.
113 modem_manager_.RemoveModem(kModemPath);
114 EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
115
David Rochbergfa1d31d2012-03-20 10:38:07 -0400116 modem_manager_.RecordAddedModem(modem_);
117 EXPECT_TRUE(modem_manager_.ModemExists(kModemPath));
Ben Chan66174a12014-01-08 21:27:00 -0800118
119 // Add an already added modem.
120 modem_manager_.RecordAddedModem(modem_);
121 EXPECT_TRUE(modem_manager_.ModemExists(kModemPath));
122
123 modem_manager_.RemoveModem(kModemPath);
124 EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
125
126 // Remove an already removed modem path.
127 modem_manager_.RemoveModem(kModemPath);
128 EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
Darin Petkov5c97ac52011-07-19 16:30:49 -0700129}
130
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400131class ModemManagerClassicMockInit : public ModemManagerClassic {
132 public:
Peter Qiu608ec292015-07-30 15:46:16 -0700133 ModemManagerClassicMockInit(ControlInterface* control_interface,
134 const string& service,
Paul Stewart2f6c7892015-06-16 13:13:10 -0700135 const string& path,
136 ModemInfo* modem_info_) :
Peter Qiu608ec292015-07-30 15:46:16 -0700137 ModemManagerClassic(control_interface, service, path, modem_info_) {}
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700138
David Rochbergfa1d31d2012-03-20 10:38:07 -0400139 MOCK_METHOD1(InitModemClassic, void(shared_ptr<ModemClassic>));
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400140};
David Rochberg7cb06f62012-03-05 11:23:44 -0500141
142class ModemManagerClassicTest : public ModemManagerTest {
143 public:
144 ModemManagerClassicTest()
145 : ModemManagerTest(),
Peter Qiu608ec292015-07-30 15:46:16 -0700146 modem_manager_(&control_, kService, kPath, &modem_info_),
Ben Chan1e2ba232014-01-27 16:35:45 -0800147 proxy_(new MockModemManagerProxy()) {}
David Rochberg7cb06f62012-03-05 11:23:44 -0500148
149 protected:
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400150 ModemManagerClassicMockInit modem_manager_;
Peter Qiu05d87e32015-08-14 23:46:21 -0700151 MockModemManagerProxy* proxy_;
David Rochberg7cb06f62012-03-05 11:23:44 -0500152};
153
Peter Qiu05d87e32015-08-14 23:46:21 -0700154TEST_F(ModemManagerClassicTest, StartStop) {
155 EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
156
157 EXPECT_CALL(control_, CreateModemManagerProxy(_, kPath, kService, _, _))
158 .WillOnce(Return(proxy_));
159 modem_manager_.Start();
160 EXPECT_NE(nullptr, modem_manager_.proxy_.get());
161
162 modem_manager_.Stop();
163 EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
164}
165
David Rochberg7cb06f62012-03-05 11:23:44 -0500166TEST_F(ModemManagerClassicTest, Connect) {
Peter Qiu05d87e32015-08-14 23:46:21 -0700167 // Setup proxy.
168 modem_manager_.proxy_.reset(proxy_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500169
170 EXPECT_CALL(*proxy_, EnumerateDevices())
Peter Qiu05d87e32015-08-14 23:46:21 -0700171 .WillOnce(Return(vector<string>(1, kModemPath)));
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400172 EXPECT_CALL(modem_manager_,
David Rochbergfa1d31d2012-03-20 10:38:07 -0400173 InitModemClassic(
174 Pointee(Field(&Modem::path_, StrEq(kModemPath)))));
Peter Qiu05d87e32015-08-14 23:46:21 -0700175 modem_manager_.Connect();
David Rochberg7cb06f62012-03-05 11:23:44 -0500176 EXPECT_EQ(1, modem_manager_.modems_.size());
177 ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
178}
179
David Rochbergfa1d31d2012-03-20 10:38:07 -0400180class ModemManager1MockInit : public ModemManager1 {
181 public:
Peter Qiu608ec292015-07-30 15:46:16 -0700182 ModemManager1MockInit(ControlInterface* control_interface,
183 const string& service,
Paul Stewart2f6c7892015-06-16 13:13:10 -0700184 const string& path,
185 ModemInfo* modem_info_) :
Peter Qiu608ec292015-07-30 15:46:16 -0700186 ModemManager1(control_interface, service, path, modem_info_) {}
David Rochbergfa1d31d2012-03-20 10:38:07 -0400187 MOCK_METHOD2(InitModem1, void(shared_ptr<Modem1>,
Peter Qiu05d87e32015-08-14 23:46:21 -0700188 const InterfaceToProperties&));
David Rochbergfa1d31d2012-03-20 10:38:07 -0400189};
190
191
David Rochberg7cb06f62012-03-05 11:23:44 -0500192class ModemManager1Test : public ModemManagerTest {
193 public:
194 ModemManager1Test()
195 : ModemManagerTest(),
Peter Qiu608ec292015-07-30 15:46:16 -0700196 modem_manager_(&control_, kService, kPath, &modem_info_),
Ben Chan1e2ba232014-01-27 16:35:45 -0800197 proxy_(new MockDBusObjectManagerProxy()) {}
David Rochberg7cb06f62012-03-05 11:23:44 -0500198
199 protected:
David Rochberg7cb06f62012-03-05 11:23:44 -0500200 virtual void SetUp() {
David Rochbergfa1d31d2012-03-20 10:38:07 -0400201 proxy_->IgnoreSetCallbacks();
David Rochberg7cb06f62012-03-05 11:23:44 -0500202 }
203
Peter Qiu05d87e32015-08-14 23:46:21 -0700204 void Connect(const ObjectsWithProperties& expected_objects) {
Ben Chan1e2ba232014-01-27 16:35:45 -0800205 ManagedObjectsCallback get_managed_objects_callback;
206 EXPECT_CALL(*proxy_, GetManagedObjects(_, _, _))
207 .WillOnce(SaveArg<1>(&get_managed_objects_callback));
Peter Qiu05d87e32015-08-14 23:46:21 -0700208 modem_manager_.Connect();
Ben Chan1e2ba232014-01-27 16:35:45 -0800209 get_managed_objects_callback.Run(expected_objects, Error());
210 }
211
Peter Qiu05d87e32015-08-14 23:46:21 -0700212 static ObjectsWithProperties GetModemWithProperties() {
213 KeyValueStore o_fd_mm1_modem;
David Rochberg7cb06f62012-03-05 11:23:44 -0500214
Peter Qiu05d87e32015-08-14 23:46:21 -0700215 InterfaceToProperties properties;
Ben Chan876efd32012-09-28 15:25:13 -0700216 properties[MM_DBUS_INTERFACE_MODEM] = o_fd_mm1_modem;
David Rochberg7cb06f62012-03-05 11:23:44 -0500217
Peter Qiu05d87e32015-08-14 23:46:21 -0700218 ObjectsWithProperties objects_with_properties;
Ben Chan876efd32012-09-28 15:25:13 -0700219 objects_with_properties[kModemPath] = properties;
David Rochberg7cb06f62012-03-05 11:23:44 -0500220
221 return objects_with_properties;
222 }
223
David Rochbergfa1d31d2012-03-20 10:38:07 -0400224 ModemManager1MockInit modem_manager_;
Peter Qiu05d87e32015-08-14 23:46:21 -0700225 MockDBusObjectManagerProxy* proxy_;
Peter Qiu608ec292015-07-30 15:46:16 -0700226 MockControl control_;
David Rochberg7cb06f62012-03-05 11:23:44 -0500227};
228
Peter Qiu05d87e32015-08-14 23:46:21 -0700229TEST_F(ModemManager1Test, StartStop) {
230 EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
231
232 EXPECT_CALL(control_, CreateDBusObjectManagerProxy(kPath, kService, _, _))
233 .WillOnce(Return(proxy_));
234 EXPECT_CALL(*proxy_, set_interfaces_added_callback(_));
235 EXPECT_CALL(*proxy_, set_interfaces_removed_callback(_));
236 modem_manager_.Start();
237 EXPECT_NE(nullptr, modem_manager_.proxy_.get());
238
239 modem_manager_.Stop();
240 EXPECT_EQ(nullptr, modem_manager_.proxy_.get());
241}
242
David Rochberg7cb06f62012-03-05 11:23:44 -0500243TEST_F(ModemManager1Test, Connect) {
Peter Qiu05d87e32015-08-14 23:46:21 -0700244 // Setup proxy.
245 modem_manager_.proxy_.reset(proxy_);
246
Ben Chan1e2ba232014-01-27 16:35:45 -0800247 Connect(GetModemWithProperties());
David Rochberg7cb06f62012-03-05 11:23:44 -0500248 EXPECT_EQ(1, modem_manager_.modems_.size());
249 EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
David Rochberg7cb06f62012-03-05 11:23:44 -0500250}
251
252TEST_F(ModemManager1Test, AddRemoveInterfaces) {
Peter Qiu05d87e32015-08-14 23:46:21 -0700253 // Setup proxy.
254 modem_manager_.proxy_.reset(proxy_);
255
David Rochberg7cb06f62012-03-05 11:23:44 -0500256 // Have nothing come back from GetManagedObjects
Peter Qiu05d87e32015-08-14 23:46:21 -0700257 Connect(ObjectsWithProperties());
David Rochberg7cb06f62012-03-05 11:23:44 -0500258 EXPECT_EQ(0, modem_manager_.modems_.size());
259
260 // Add an object that doesn't have a modem interface. Nothing should be added
David Rochbergfa1d31d2012-03-20 10:38:07 -0400261 EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(0);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500262 modem_manager_.OnInterfacesAddedSignal(kModemPath,
Peter Qiu05d87e32015-08-14 23:46:21 -0700263 InterfaceToProperties());
David Rochberg7cb06f62012-03-05 11:23:44 -0500264 EXPECT_EQ(0, modem_manager_.modems_.size());
265
266 // Actually add a modem
David Rochbergfa1d31d2012-03-20 10:38:07 -0400267 EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500268 modem_manager_.OnInterfacesAddedSignal(kModemPath,
269 GetModemWithProperties()[kModemPath]);
David Rochberg7cb06f62012-03-05 11:23:44 -0500270 EXPECT_EQ(1, modem_manager_.modems_.size());
271
272 // Remove an irrelevant interface
273 vector<string> not_including_modem_interface;
274 not_including_modem_interface.push_back("not.a.modem.interface");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500275 modem_manager_.OnInterfacesRemovedSignal(kModemPath,
276 not_including_modem_interface);
David Rochberg7cb06f62012-03-05 11:23:44 -0500277 EXPECT_EQ(1, modem_manager_.modems_.size());
278
279 // Remove the modem
280 vector<string> with_modem_interface;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400281 with_modem_interface.push_back(MM_DBUS_INTERFACE_MODEM);
Ben Chan1e2ba232014-01-27 16:35:45 -0800282 modem_manager_.OnInterfacesRemovedSignal(kModemPath, with_modem_interface);
David Rochberg7cb06f62012-03-05 11:23:44 -0500283 EXPECT_EQ(0, modem_manager_.modems_.size());
284}
David Rochbergfa1d31d2012-03-20 10:38:07 -0400285
Darin Petkov887f2982011-07-14 16:10:17 -0700286} // namespace shill