blob: 9ed54f74c4c48e2c4ec7bce70d41398fc5e59b7b [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkov887f2982011-07-14 16:10:17 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Eric Shienbrood3e20a232012-02-16 11:35:56 -05005#include <base/stl_util.h>
Darin Petkov887f2982011-07-14 16:10:17 -07006#include <gtest/gtest.h>
David Rochbergfa1d31d2012-03-20 10:38:07 -04007#include <mm/ModemManager-names.h>
Darin Petkov887f2982011-07-14 16:10:17 -07008
9#include "shill/manager.h"
10#include "shill/mock_control.h"
David Rochberg7cb06f62012-03-05 11:23:44 -050011#include "shill/mock_dbus_objectmanager_proxy.h"
Darin Petkov887f2982011-07-14 16:10:17 -070012#include "shill/mock_glib.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070013#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080014#include "shill/mock_metrics.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040015#include "shill/mock_modem.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070016#include "shill/mock_modem_manager_proxy.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070017#include "shill/modem.h"
Darin Petkov887f2982011-07-14 16:10:17 -070018#include "shill/modem_manager.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070019#include "shill/proxy_factory.h"
Darin Petkov887f2982011-07-14 16:10:17 -070020
Darin Petkovc90fe522011-07-15 13:59:47 -070021using std::string;
David Rochberg7cb06f62012-03-05 11:23:44 -050022using std::tr1::shared_ptr;
Darin Petkov5c97ac52011-07-19 16:30:49 -070023using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070024using testing::_;
David Rochberg7cb06f62012-03-05 11:23:44 -050025using testing::Invoke;
David Rochbergb6b6ccb2012-03-16 13:40:36 -040026using testing::Pointee;
Darin Petkov887f2982011-07-14 16:10:17 -070027using testing::Return;
28using testing::StrEq;
29using testing::Test;
30
31namespace shill {
32
David Rochberg7cb06f62012-03-05 11:23:44 -050033// A testing subclass of ModemManager.
34class ModemManagerCore : public ModemManager {
35 public:
36 ModemManagerCore(const string &service,
37 const string &path,
38 ControlInterface *control_interface,
39 EventDispatcher *dispatcher,
40 Metrics *metrics,
41 Manager *manager,
42 GLib *glib,
43 mobile_provider_db *provider_db)
44 : ModemManager(service,
45 path,
46 control_interface,
47 dispatcher,
48 metrics,
49 manager,
50 glib,
51 provider_db) {}
52
53 virtual ~ModemManagerCore() {}
54
55 MOCK_METHOD1(Connect, void(const string &owner));
56 MOCK_METHOD0(Disconnect, void());
David Rochberg7cb06f62012-03-05 11:23:44 -050057};
58
Darin Petkov887f2982011-07-14 16:10:17 -070059class ModemManagerTest : public Test {
60 public:
61 ModemManagerTest()
David Rochberg7cb06f62012-03-05 11:23:44 -050062 : manager_(&control_interface_, &dispatcher_, &metrics_, &glib_) {
Darin Petkovc90fe522011-07-15 13:59:47 -070063 }
David Rochbergfa1d31d2012-03-20 10:38:07 -040064
65 virtual void SetUp() {
66 modem_.reset(new StrictModem(
67 kOwner, kModemPath, &control_interface_, &dispatcher_, &metrics_,
68 &manager_, static_cast<mobile_provider_db *>(NULL)));
69 }
Darin Petkov887f2982011-07-14 16:10:17 -070070 protected:
71 static const char kService[];
72 static const char kPath[];
Darin Petkov5c97ac52011-07-19 16:30:49 -070073 static const char kOwner[];
74 static const char kModemPath[];
Darin Petkov887f2982011-07-14 16:10:17 -070075
David Rochbergfa1d31d2012-03-20 10:38:07 -040076 shared_ptr<StrictModem> modem_;
77
Darin Petkov887f2982011-07-14 16:10:17 -070078 MockGLib glib_;
79 MockControl control_interface_;
80 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -080081 MockMetrics metrics_;
Chris Masone2ae797d2011-08-23 20:41:00 -070082 MockManager manager_;
Darin Petkov887f2982011-07-14 16:10:17 -070083};
84
Darin Petkov5c97ac52011-07-19 16:30:49 -070085const char ModemManagerTest::kService[] = "org.chromium.ModemManager";
86const char ModemManagerTest::kPath[] = "/org/chromium/ModemManager";
87const char ModemManagerTest::kOwner[] = ":1.17";
David Rochberg7cb06f62012-03-05 11:23:44 -050088const char ModemManagerTest::kModemPath[] = "/org/blah/Modem/blah/0";
Darin Petkov887f2982011-07-14 16:10:17 -070089
David Rochberg7cb06f62012-03-05 11:23:44 -050090class ModemManagerCoreTest : public ModemManagerTest {
91 public:
92 ModemManagerCoreTest()
93 : ModemManagerTest(),
94 modem_manager_(kService,
95 kPath,
96 &control_interface_,
97 &dispatcher_,
98 &metrics_,
99 &manager_,
100 &glib_,
101 NULL) {}
Darin Petkovab565bb2011-10-06 02:55:51 -0700102
David Rochberg7cb06f62012-03-05 11:23:44 -0500103 virtual void TearDown() {
104 modem_manager_.watcher_id_ = 0;
105 }
Darin Petkove0a312e2011-07-20 13:45:28 -0700106
David Rochberg7cb06f62012-03-05 11:23:44 -0500107 protected:
108 ModemManagerCore modem_manager_;
109};
110
David Rochberg7cb06f62012-03-05 11:23:44 -0500111TEST_F(ModemManagerCoreTest, Start) {
Darin Petkov887f2982011-07-14 16:10:17 -0700112 const int kWatcher = 123;
113 EXPECT_CALL(glib_, BusWatchName(G_BUS_TYPE_SYSTEM,
114 StrEq(kService),
115 G_BUS_NAME_WATCHER_FLAGS_NONE,
116 ModemManager::OnAppear,
117 ModemManager::OnVanish,
118 &modem_manager_,
119 NULL))
120 .WillOnce(Return(kWatcher));
121 EXPECT_EQ(0, modem_manager_.watcher_id_);
122 modem_manager_.Start();
123 EXPECT_EQ(kWatcher, modem_manager_.watcher_id_);
124}
125
David Rochberg7cb06f62012-03-05 11:23:44 -0500126TEST_F(ModemManagerCoreTest, Stop) {
Darin Petkov887f2982011-07-14 16:10:17 -0700127 const int kWatcher = 345;
Darin Petkov887f2982011-07-14 16:10:17 -0700128 modem_manager_.watcher_id_ = kWatcher;
129 modem_manager_.owner_ = kOwner;
130 EXPECT_CALL(glib_, BusUnwatchName(kWatcher)).Times(1);
David Rochberg7cb06f62012-03-05 11:23:44 -0500131 EXPECT_CALL(modem_manager_, Disconnect());
Darin Petkov887f2982011-07-14 16:10:17 -0700132 modem_manager_.Stop();
Darin Petkov887f2982011-07-14 16:10:17 -0700133}
134
David Rochberg7cb06f62012-03-05 11:23:44 -0500135TEST_F(ModemManagerCoreTest, OnAppearVanish) {
Darin Petkov887f2982011-07-14 16:10:17 -0700136 EXPECT_EQ("", modem_manager_.owner_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500137 EXPECT_CALL(modem_manager_, Connect(kOwner));
138 EXPECT_CALL(modem_manager_, Disconnect());
Darin Petkov5c97ac52011-07-19 16:30:49 -0700139 ModemManager::OnAppear(NULL, kService, kOwner, &modem_manager_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500140 ModemManager::OnVanish(NULL, kService, &modem_manager_);
141}
142
143TEST_F(ModemManagerCoreTest, Connect) {
144 EXPECT_EQ("", modem_manager_.owner_);
145 modem_manager_.ModemManager::Connect(kOwner);
Darin Petkov887f2982011-07-14 16:10:17 -0700146 EXPECT_EQ(kOwner, modem_manager_.owner_);
147}
148
David Rochberg7cb06f62012-03-05 11:23:44 -0500149TEST_F(ModemManagerCoreTest, Disconnect) {
Darin Petkov887f2982011-07-14 16:10:17 -0700150 modem_manager_.owner_ = kOwner;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400151 modem_manager_.RecordAddedModem(modem_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500152 EXPECT_EQ(1, modem_manager_.modems_.size());
153
154 modem_manager_.ModemManager::Disconnect();
Darin Petkov887f2982011-07-14 16:10:17 -0700155 EXPECT_EQ("", modem_manager_.owner_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500156 EXPECT_EQ(0, modem_manager_.modems_.size());
Darin Petkov887f2982011-07-14 16:10:17 -0700157}
158
David Rochbergfa1d31d2012-03-20 10:38:07 -0400159TEST_F(ModemManagerCoreTest, ModemExists) {
Darin Petkov5c97ac52011-07-19 16:30:49 -0700160 modem_manager_.owner_ = kOwner;
David Rochberg7cb06f62012-03-05 11:23:44 -0500161
David Rochbergfa1d31d2012-03-20 10:38:07 -0400162 EXPECT_FALSE(modem_manager_.ModemExists(kModemPath));
163 modem_manager_.RecordAddedModem(modem_);
164 EXPECT_TRUE(modem_manager_.ModemExists(kModemPath));
Darin Petkov5c97ac52011-07-19 16:30:49 -0700165}
166
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400167class ModemManagerClassicMockInit : public ModemManagerClassic {
168 public:
169 ModemManagerClassicMockInit(const string &service,
170 const string &path,
171 ControlInterface *control_interface,
172 EventDispatcher *dispatcher,
173 Metrics *metrics,
174 Manager *manager,
175 GLib *glib,
176 mobile_provider_db *provider_db) :
177 ModemManagerClassic(service,
178 path,
179 control_interface,
180 dispatcher,
181 metrics,
182 manager,
183 glib,
184 provider_db) {}
David Rochbergfa1d31d2012-03-20 10:38:07 -0400185 MOCK_METHOD1(InitModemClassic, void(shared_ptr<ModemClassic>));
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400186};
David Rochberg7cb06f62012-03-05 11:23:44 -0500187
188class ModemManagerClassicTest : public ModemManagerTest {
189 public:
190 ModemManagerClassicTest()
191 : ModemManagerTest(),
192 modem_manager_(kService,
193 kPath,
194 &control_interface_,
195 &dispatcher_,
196 &metrics_,
197 &manager_,
198 &glib_,
199 NULL),
200 proxy_(new MockModemManagerProxy()),
201 proxy_factory_(this) {
202 }
203
204 protected:
205 class TestProxyFactory : public ProxyFactory {
206 public:
207 explicit TestProxyFactory(ModemManagerClassicTest *test) : test_(test) {}
208
209 virtual ModemManagerProxyInterface *CreateModemManagerProxy(
210 ModemManagerClassic */*manager*/,
211 const string &/*path*/,
212 const string &/*service*/) {
213 return test_->proxy_.release();
214 }
215
216 private:
217 ModemManagerClassicTest *test_;
218 };
219
220 virtual void SetUp() {
221 modem_manager_.proxy_factory_ = &proxy_factory_;
222 }
223
224 virtual void TearDown() {
225 modem_manager_.proxy_factory_ = NULL;
226 }
227
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400228 ModemManagerClassicMockInit modem_manager_;
David Rochberg7cb06f62012-03-05 11:23:44 -0500229 scoped_ptr<MockModemManagerProxy> proxy_;
230 TestProxyFactory proxy_factory_;
231};
232
233TEST_F(ModemManagerClassicTest, Connect) {
234 EXPECT_EQ("", modem_manager_.owner_);
235
236 EXPECT_CALL(*proxy_, EnumerateDevices())
237 .WillOnce(Return(vector<DBus::Path>(1, kModemPath)));
238
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400239 EXPECT_CALL(modem_manager_,
David Rochbergfa1d31d2012-03-20 10:38:07 -0400240 InitModemClassic(
241 Pointee(Field(&Modem::path_, StrEq(kModemPath)))));
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400242
David Rochberg7cb06f62012-03-05 11:23:44 -0500243 modem_manager_.Connect(kOwner);
244 EXPECT_EQ(kOwner, modem_manager_.owner_);
245 EXPECT_EQ(1, modem_manager_.modems_.size());
246 ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
247}
248
249
David Rochbergfa1d31d2012-03-20 10:38:07 -0400250class ModemManager1MockInit : public ModemManager1 {
251 public:
252 ModemManager1MockInit(const string &service,
253 const string &path,
254 ControlInterface *control_interface,
255 EventDispatcher *dispatcher,
256 Metrics *metrics,
257 Manager *manager,
258 GLib *glib,
259 mobile_provider_db *provider_db) :
260 ModemManager1(service,
261 path,
262 control_interface,
263 dispatcher,
264 metrics,
265 manager,
266 glib,
267 provider_db) {}
268 MOCK_METHOD2(InitModem1, void(shared_ptr<Modem1>,
269 const DBusInterfaceToProperties &));
270};
271
272
David Rochberg7cb06f62012-03-05 11:23:44 -0500273class ModemManager1Test : public ModemManagerTest {
274 public:
275 ModemManager1Test()
276 : ModemManagerTest(),
277 modem_manager_(kService,
278 kPath,
279 &control_interface_,
280 &dispatcher_,
281 &metrics_,
282 &manager_,
283 &glib_,
284 NULL),
285 proxy_(new MockDBusObjectManagerProxy()),
286 proxy_factory_(this) {
287 }
288
289 protected:
290 class TestProxyFactory : public ProxyFactory {
291 public:
292 explicit TestProxyFactory(ModemManager1Test *test) : test_(test) {}
293
294 virtual DBusObjectManagerProxyInterface *CreateDBusObjectManagerProxy(
David Rochberg7cb06f62012-03-05 11:23:44 -0500295 const string &/*path*/,
296 const string &/*service*/) {
297 return test_->proxy_.release();
298 }
299
300 private:
301 ModemManager1Test *test_;
302 };
303
304 virtual void SetUp() {
305 modem_manager_.proxy_factory_ = &proxy_factory_;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400306 proxy_->IgnoreSetCallbacks();
David Rochberg7cb06f62012-03-05 11:23:44 -0500307 }
308
309 virtual void TearDown() {
310 modem_manager_.proxy_factory_ = NULL;
311 }
312
313 static DBusObjectsWithProperties GetModemWithProperties() {
314 DBusPropertiesMap o_fd_mm1_modem;
315
316 DBusInterfaceToProperties i_to_p;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400317 i_to_p[MM_DBUS_INTERFACE_MODEM] = o_fd_mm1_modem;
David Rochberg7cb06f62012-03-05 11:23:44 -0500318
319 DBusObjectsWithProperties objects_with_properties;
320 objects_with_properties[kModemPath] = i_to_p;
321
322 return objects_with_properties;
323 }
324
David Rochbergfa1d31d2012-03-20 10:38:07 -0400325 ModemManager1MockInit modem_manager_;
David Rochberg7cb06f62012-03-05 11:23:44 -0500326 scoped_ptr<MockDBusObjectManagerProxy> proxy_;
327 TestProxyFactory proxy_factory_;
328};
329
330TEST_F(ModemManager1Test, Connect) {
331 Error e;
332
Eric Shienbrood9a245532012-03-07 14:20:39 -0500333 EXPECT_CALL(*proxy_, GetManagedObjects(_, _, _));
David Rochbergfa1d31d2012-03-20 10:38:07 -0400334 EXPECT_CALL(modem_manager_,
335 InitModem1(
336 Pointee(Field(&Modem::path_, StrEq(kModemPath))),
337 _));
David Rochberg7cb06f62012-03-05 11:23:44 -0500338
339 modem_manager_.Connect(kOwner);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500340 modem_manager_.OnGetManagedObjectsReply(GetModemWithProperties(), e);
David Rochberg7cb06f62012-03-05 11:23:44 -0500341 EXPECT_EQ(1, modem_manager_.modems_.size());
342 EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
David Rochberg7cb06f62012-03-05 11:23:44 -0500343}
344
David Rochbergfa1d31d2012-03-20 10:38:07 -0400345
David Rochberg7cb06f62012-03-05 11:23:44 -0500346TEST_F(ModemManager1Test, AddRemoveInterfaces) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500347 EXPECT_CALL(*proxy_, GetManagedObjects(_, _, _));
David Rochberg7cb06f62012-03-05 11:23:44 -0500348 modem_manager_.Connect(kOwner);
349
350 // Have nothing come back from GetManagedObjects
Eric Shienbrood9a245532012-03-07 14:20:39 -0500351 modem_manager_.OnGetManagedObjectsReply(DBusObjectsWithProperties(), Error());
David Rochberg7cb06f62012-03-05 11:23:44 -0500352 EXPECT_EQ(0, modem_manager_.modems_.size());
353
354 // Add an object that doesn't have a modem interface. Nothing should be added
David Rochbergfa1d31d2012-03-20 10:38:07 -0400355 EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(0);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500356 modem_manager_.OnInterfacesAddedSignal(kModemPath,
357 DBusInterfaceToProperties());
David Rochberg7cb06f62012-03-05 11:23:44 -0500358 EXPECT_EQ(0, modem_manager_.modems_.size());
359
360 // Actually add a modem
David Rochbergfa1d31d2012-03-20 10:38:07 -0400361 EXPECT_CALL(modem_manager_, InitModem1(_, _)).Times(1);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500362 modem_manager_.OnInterfacesAddedSignal(kModemPath,
363 GetModemWithProperties()[kModemPath]);
David Rochberg7cb06f62012-03-05 11:23:44 -0500364 EXPECT_EQ(1, modem_manager_.modems_.size());
365
366 // Remove an irrelevant interface
367 vector<string> not_including_modem_interface;
368 not_including_modem_interface.push_back("not.a.modem.interface");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500369 modem_manager_.OnInterfacesRemovedSignal(kModemPath,
370 not_including_modem_interface);
David Rochberg7cb06f62012-03-05 11:23:44 -0500371 EXPECT_EQ(1, modem_manager_.modems_.size());
372
373 // Remove the modem
374 vector<string> with_modem_interface;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400375 with_modem_interface.push_back(MM_DBUS_INTERFACE_MODEM);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500376 modem_manager_.OnInterfacesRemovedSignal(kModemPath,
377 with_modem_interface);
David Rochberg7cb06f62012-03-05 11:23:44 -0500378 EXPECT_EQ(0, modem_manager_.modems_.size());
379}
David Rochbergfa1d31d2012-03-20 10:38:07 -0400380
Darin Petkov887f2982011-07-14 16:10:17 -0700381} // namespace shill