blob: 22ba368cd6be45166b441c6899aa0049505f2600 [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>
Darin Petkove0a312e2011-07-20 13:45:28 -07007#include <mm/mm-modem.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"
Darin Petkovc90fe522011-07-15 13:59:47 -070015#include "shill/mock_modem_manager_proxy.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070016#include "shill/modem.h"
Darin Petkov887f2982011-07-14 16:10:17 -070017#include "shill/modem_manager.h"
Darin Petkovc90fe522011-07-15 13:59:47 -070018#include "shill/proxy_factory.h"
Darin Petkov887f2982011-07-14 16:10:17 -070019
Darin Petkovc90fe522011-07-15 13:59:47 -070020using std::string;
David Rochberg7cb06f62012-03-05 11:23:44 -050021using std::tr1::shared_ptr;
Darin Petkov5c97ac52011-07-19 16:30:49 -070022using std::vector;
Darin Petkov887f2982011-07-14 16:10:17 -070023using testing::_;
David Rochberg7cb06f62012-03-05 11:23:44 -050024using testing::Invoke;
David Rochbergb6b6ccb2012-03-16 13:40:36 -040025using testing::Pointee;
Darin Petkov887f2982011-07-14 16:10:17 -070026using testing::Return;
27using testing::StrEq;
28using testing::Test;
29
30namespace shill {
31
David Rochberg7cb06f62012-03-05 11:23:44 -050032// A testing subclass of ModemManager.
33class ModemManagerCore : public ModemManager {
34 public:
35 ModemManagerCore(const string &service,
36 const string &path,
37 ControlInterface *control_interface,
38 EventDispatcher *dispatcher,
39 Metrics *metrics,
40 Manager *manager,
41 GLib *glib,
42 mobile_provider_db *provider_db)
43 : ModemManager(service,
44 path,
45 control_interface,
46 dispatcher,
47 metrics,
48 manager,
49 glib,
50 provider_db) {}
51
52 virtual ~ModemManagerCore() {}
53
54 MOCK_METHOD1(Connect, void(const string &owner));
55 MOCK_METHOD0(Disconnect, void());
56 MOCK_METHOD1(InitModem, void(shared_ptr<Modem> modem));
57};
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 }
Darin Petkov887f2982011-07-14 16:10:17 -070064 protected:
65 static const char kService[];
66 static const char kPath[];
Darin Petkov5c97ac52011-07-19 16:30:49 -070067 static const char kOwner[];
68 static const char kModemPath[];
Darin Petkov887f2982011-07-14 16:10:17 -070069
70 MockGLib glib_;
71 MockControl control_interface_;
72 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -080073 MockMetrics metrics_;
Chris Masone2ae797d2011-08-23 20:41:00 -070074 MockManager manager_;
Darin Petkov887f2982011-07-14 16:10:17 -070075};
76
Darin Petkov5c97ac52011-07-19 16:30:49 -070077const char ModemManagerTest::kService[] = "org.chromium.ModemManager";
78const char ModemManagerTest::kPath[] = "/org/chromium/ModemManager";
79const char ModemManagerTest::kOwner[] = ":1.17";
David Rochberg7cb06f62012-03-05 11:23:44 -050080const char ModemManagerTest::kModemPath[] = "/org/blah/Modem/blah/0";
Darin Petkov887f2982011-07-14 16:10:17 -070081
David Rochberg7cb06f62012-03-05 11:23:44 -050082class ModemManagerCoreTest : public ModemManagerTest {
83 public:
84 ModemManagerCoreTest()
85 : ModemManagerTest(),
86 modem_manager_(kService,
87 kPath,
88 &control_interface_,
89 &dispatcher_,
90 &metrics_,
91 &manager_,
92 &glib_,
93 NULL) {}
94 virtual void SetUp() {
95 }
Darin Petkovab565bb2011-10-06 02:55:51 -070096
David Rochberg7cb06f62012-03-05 11:23:44 -050097 virtual void TearDown() {
98 modem_manager_.watcher_id_ = 0;
99 }
Darin Petkove0a312e2011-07-20 13:45:28 -0700100
David Rochberg7cb06f62012-03-05 11:23:44 -0500101 protected:
102 ModemManagerCore modem_manager_;
103};
104
105
106TEST_F(ModemManagerCoreTest, Start) {
Darin Petkov887f2982011-07-14 16:10:17 -0700107 const int kWatcher = 123;
108 EXPECT_CALL(glib_, BusWatchName(G_BUS_TYPE_SYSTEM,
109 StrEq(kService),
110 G_BUS_NAME_WATCHER_FLAGS_NONE,
111 ModemManager::OnAppear,
112 ModemManager::OnVanish,
113 &modem_manager_,
114 NULL))
115 .WillOnce(Return(kWatcher));
116 EXPECT_EQ(0, modem_manager_.watcher_id_);
117 modem_manager_.Start();
118 EXPECT_EQ(kWatcher, modem_manager_.watcher_id_);
119}
120
David Rochberg7cb06f62012-03-05 11:23:44 -0500121TEST_F(ModemManagerCoreTest, Stop) {
Darin Petkov887f2982011-07-14 16:10:17 -0700122 const int kWatcher = 345;
Darin Petkov887f2982011-07-14 16:10:17 -0700123 modem_manager_.watcher_id_ = kWatcher;
124 modem_manager_.owner_ = kOwner;
125 EXPECT_CALL(glib_, BusUnwatchName(kWatcher)).Times(1);
David Rochberg7cb06f62012-03-05 11:23:44 -0500126 EXPECT_CALL(modem_manager_, Disconnect());
Darin Petkov887f2982011-07-14 16:10:17 -0700127 modem_manager_.Stop();
Darin Petkov887f2982011-07-14 16:10:17 -0700128}
129
David Rochberg7cb06f62012-03-05 11:23:44 -0500130TEST_F(ModemManagerCoreTest, OnAppearVanish) {
Darin Petkov887f2982011-07-14 16:10:17 -0700131 EXPECT_EQ("", modem_manager_.owner_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500132 EXPECT_CALL(modem_manager_, Connect(kOwner));
133 EXPECT_CALL(modem_manager_, Disconnect());
Darin Petkov5c97ac52011-07-19 16:30:49 -0700134 ModemManager::OnAppear(NULL, kService, kOwner, &modem_manager_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500135 ModemManager::OnVanish(NULL, kService, &modem_manager_);
136}
137
138TEST_F(ModemManagerCoreTest, Connect) {
139 EXPECT_EQ("", modem_manager_.owner_);
140 modem_manager_.ModemManager::Connect(kOwner);
Darin Petkov887f2982011-07-14 16:10:17 -0700141 EXPECT_EQ(kOwner, modem_manager_.owner_);
142}
143
David Rochberg7cb06f62012-03-05 11:23:44 -0500144TEST_F(ModemManagerCoreTest, Disconnect) {
145 EXPECT_CALL(modem_manager_, InitModem(_));
146
Darin Petkov887f2982011-07-14 16:10:17 -0700147 modem_manager_.owner_ = kOwner;
David Rochberg7cb06f62012-03-05 11:23:44 -0500148 modem_manager_.AddModem(kModemPath);
149 EXPECT_EQ(1, modem_manager_.modems_.size());
150
151 modem_manager_.ModemManager::Disconnect();
Darin Petkov887f2982011-07-14 16:10:17 -0700152 EXPECT_EQ("", modem_manager_.owner_);
David Rochberg7cb06f62012-03-05 11:23:44 -0500153 EXPECT_EQ(0, modem_manager_.modems_.size());
Darin Petkov887f2982011-07-14 16:10:17 -0700154}
155
David Rochberg7cb06f62012-03-05 11:23:44 -0500156TEST_F(ModemManagerCoreTest, AddRemoveModem) {
Darin Petkov5c97ac52011-07-19 16:30:49 -0700157 modem_manager_.owner_ = kOwner;
David Rochberg7cb06f62012-03-05 11:23:44 -0500158 EXPECT_CALL(modem_manager_, InitModem(_));
159
Darin Petkov5c97ac52011-07-19 16:30:49 -0700160 modem_manager_.AddModem(kModemPath);
161 EXPECT_EQ(1, modem_manager_.modems_.size());
Darin Petkova7b89492011-07-27 12:48:17 -0700162 ASSERT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
Darin Petkove0a312e2011-07-20 13:45:28 -0700163
Darin Petkov5c97ac52011-07-19 16:30:49 -0700164 modem_manager_.RemoveModem(kModemPath);
165 EXPECT_EQ(0, modem_manager_.modems_.size());
166}
167
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400168class ModemManagerClassicMockInit : public ModemManagerClassic {
169 public:
170 ModemManagerClassicMockInit(const string &service,
171 const string &path,
172 ControlInterface *control_interface,
173 EventDispatcher *dispatcher,
174 Metrics *metrics,
175 Manager *manager,
176 GLib *glib,
177 mobile_provider_db *provider_db) :
178 ModemManagerClassic(service,
179 path,
180 control_interface,
181 dispatcher,
182 metrics,
183 manager,
184 glib,
185 provider_db) {}
186 MOCK_METHOD1(InitModem, void(shared_ptr<Modem> modem));
187};
David Rochberg7cb06f62012-03-05 11:23:44 -0500188
189class ModemManagerClassicTest : public ModemManagerTest {
190 public:
191 ModemManagerClassicTest()
192 : ModemManagerTest(),
193 modem_manager_(kService,
194 kPath,
195 &control_interface_,
196 &dispatcher_,
197 &metrics_,
198 &manager_,
199 &glib_,
200 NULL),
201 proxy_(new MockModemManagerProxy()),
202 proxy_factory_(this) {
203 }
204
205 protected:
206 class TestProxyFactory : public ProxyFactory {
207 public:
208 explicit TestProxyFactory(ModemManagerClassicTest *test) : test_(test) {}
209
210 virtual ModemManagerProxyInterface *CreateModemManagerProxy(
211 ModemManagerClassic */*manager*/,
212 const string &/*path*/,
213 const string &/*service*/) {
214 return test_->proxy_.release();
215 }
216
217 private:
218 ModemManagerClassicTest *test_;
219 };
220
221 virtual void SetUp() {
222 modem_manager_.proxy_factory_ = &proxy_factory_;
223 }
224
225 virtual void TearDown() {
226 modem_manager_.proxy_factory_ = NULL;
227 }
228
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400229 ModemManagerClassicMockInit modem_manager_;
David Rochberg7cb06f62012-03-05 11:23:44 -0500230 scoped_ptr<MockModemManagerProxy> proxy_;
231 TestProxyFactory proxy_factory_;
232};
233
234TEST_F(ModemManagerClassicTest, Connect) {
235 EXPECT_EQ("", modem_manager_.owner_);
236
237 EXPECT_CALL(*proxy_, EnumerateDevices())
238 .WillOnce(Return(vector<DBus::Path>(1, kModemPath)));
239
David Rochbergb6b6ccb2012-03-16 13:40:36 -0400240 EXPECT_CALL(modem_manager_,
241 InitModem(Pointee(Field(&Modem::path_, StrEq(kModemPath)))));
242
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
250class ModemManager1Test : public ModemManagerTest {
251 public:
252 ModemManager1Test()
253 : ModemManagerTest(),
254 modem_manager_(kService,
255 kPath,
256 &control_interface_,
257 &dispatcher_,
258 &metrics_,
259 &manager_,
260 &glib_,
261 NULL),
262 proxy_(new MockDBusObjectManagerProxy()),
263 proxy_factory_(this) {
264 }
265
266 protected:
267 class TestProxyFactory : public ProxyFactory {
268 public:
269 explicit TestProxyFactory(ModemManager1Test *test) : test_(test) {}
270
271 virtual DBusObjectManagerProxyInterface *CreateDBusObjectManagerProxy(
272 DBusObjectManagerProxyDelegate */*manager*/,
273 const string &/*path*/,
274 const string &/*service*/) {
275 return test_->proxy_.release();
276 }
277
278 private:
279 ModemManager1Test *test_;
280 };
281
282 virtual void SetUp() {
283 modem_manager_.proxy_factory_ = &proxy_factory_;
284 }
285
286 virtual void TearDown() {
287 modem_manager_.proxy_factory_ = NULL;
288 }
289
290 static DBusObjectsWithProperties GetModemWithProperties() {
291 DBusPropertiesMap o_fd_mm1_modem;
292
293 DBusInterfaceToProperties i_to_p;
294 i_to_p[ModemManager1::kDBusInterfaceModem] = o_fd_mm1_modem;
295
296 DBusObjectsWithProperties objects_with_properties;
297 objects_with_properties[kModemPath] = i_to_p;
298
299 return objects_with_properties;
300 }
301
302 ModemManager1 modem_manager_;
303 scoped_ptr<MockDBusObjectManagerProxy> proxy_;
304 TestProxyFactory proxy_factory_;
305};
306
307TEST_F(ModemManager1Test, Connect) {
308 Error e;
309
310 EXPECT_CALL(*proxy_, GetManagedObjects(_, _));
311
312 modem_manager_.Connect(kOwner);
313 modem_manager_.OnGetManagedObjectsCallback(GetModemWithProperties(), e, NULL);
314 EXPECT_EQ(1, modem_manager_.modems_.size());
315 EXPECT_TRUE(ContainsKey(modem_manager_.modems_, kModemPath));
316 // TODO(rochberg): As mm1::connect gets more interesting, this will
317 // need to expand
318}
319
320TEST_F(ModemManager1Test, AddRemoveInterfaces) {
321 EXPECT_CALL(*proxy_, GetManagedObjects(_, _));
322 modem_manager_.Connect(kOwner);
323
324 // Have nothing come back from GetManagedObjects
325 modem_manager_.OnGetManagedObjectsCallback(DBusObjectsWithProperties(),
326 Error(),
327 NULL);
328 EXPECT_EQ(0, modem_manager_.modems_.size());
329
330 // Add an object that doesn't have a modem interface. Nothing should be added
331 modem_manager_.OnInterfacesAdded(kModemPath,
332 DBusInterfaceToProperties());
333 EXPECT_EQ(0, modem_manager_.modems_.size());
334
335 // Actually add a modem
336 modem_manager_.OnInterfacesAdded(kModemPath,
337 GetModemWithProperties()[kModemPath]);
338 EXPECT_EQ(1, modem_manager_.modems_.size());
339
340 // Remove an irrelevant interface
341 vector<string> not_including_modem_interface;
342 not_including_modem_interface.push_back("not.a.modem.interface");
343 modem_manager_.OnInterfacesRemoved(kModemPath,
344 not_including_modem_interface);
345 EXPECT_EQ(1, modem_manager_.modems_.size());
346
347 // Remove the modem
348 vector<string> with_modem_interface;
349 with_modem_interface.push_back(ModemManager1::kDBusInterfaceModem);
350 modem_manager_.OnInterfacesRemoved(kModemPath,
351 with_modem_interface);
352 EXPECT_EQ(0, modem_manager_.modems_.size());
353}
Darin Petkov887f2982011-07-14 16:10:17 -0700354} // namespace shill