blob: 9e609e2b60f8b539dbfe3bc84d4f7289f1f47ad1 [file] [log] [blame]
Darin Petkov41c0e0a2012-01-09 16:38:53 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkove0a312e2011-07-20 13:45:28 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Darin Petkov6f9eaa32011-08-09 15:26:44 -07005#include <vector>
6
Chris Masone626719f2011-08-18 16:58:48 -07007#include <gmock/gmock.h>
Darin Petkove0a312e2011-07-20 13:45:28 -07008#include <gtest/gtest.h>
9#include <mm/mm-modem.h>
10#include <net/if.h>
11#include <sys/ioctl.h>
12
13#include "shill/cellular.h"
Darin Petkov721ac932011-11-16 15:43:09 +010014#include "shill/cellular_capability_gsm.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040015#include "shill/dbus_property_matchers.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070016#include "shill/event_dispatcher.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070017#include "shill/manager.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040018#include "shill/mock_cellular.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070019#include "shill/mock_control.h"
20#include "shill/mock_dbus_properties_proxy.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040021#include "shill/mock_device_info.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070022#include "shill/mock_glib.h"
Chris Masone626719f2011-08-18 16:58:48 -070023#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080024#include "shill/mock_metrics.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040025#include "shill/mock_modem.h"
26#include "shill/mock_rtnl_handler.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070027#include "shill/modem.h"
28#include "shill/proxy_factory.h"
29#include "shill/rtnl_handler.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070030
31using std::string;
Darin Petkov6f9eaa32011-08-09 15:26:44 -070032using std::vector;
Darin Petkove0a312e2011-07-20 13:45:28 -070033using testing::_;
34using testing::DoAll;
35using testing::Return;
Chris Masone626719f2011-08-18 16:58:48 -070036using testing::SetArgumentPointee;
David Rochbergfa1d31d2012-03-20 10:38:07 -040037using testing::StrEq;
Darin Petkove0a312e2011-07-20 13:45:28 -070038using testing::StrictMock;
39using testing::Test;
40
41namespace shill {
42
43namespace {
44
45const int kTestInterfaceIndex = 5;
David Rochbergfa1d31d2012-03-20 10:38:07 -040046const char kLinkName[] = "usb0";
47const char kOwner[] = ":1.18";
48const char kPath[] = "/org/chromium/ModemManager/Gobi/0";
49const unsigned char kAddress[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
50const char kAddressAsString[] = "000102030405";
Darin Petkove0a312e2011-07-20 13:45:28 -070051
52ACTION(SetInterfaceIndex) {
53 if (arg2) {
54 reinterpret_cast<struct ifreq *>(arg2)->ifr_ifindex = kTestInterfaceIndex;
55 }
56}
57
58} // namespace
59
60class ModemTest : public Test {
61 public:
62 ModemTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080063 : manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Jason Glasgowe9089492012-02-23 17:57:37 -050064 info_(&control_interface_, &dispatcher_, &metrics_, &manager_),
Darin Petkov3b292332011-07-28 14:17:24 -070065 proxy_(new MockDBusPropertiesProxy()),
66 proxy_factory_(this),
David Rochbergfa1d31d2012-03-20 10:38:07 -040067 modem_(
68 new StrictModem(
69 kOwner,
70 kPath,
71 &control_interface_,
72 &dispatcher_,
73 &metrics_,
74 &manager_,
75 static_cast<mobile_provider_db *>(NULL))) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070076 virtual void SetUp();
77 virtual void TearDown();
78
David Rochbergfa1d31d2012-03-20 10:38:07 -040079 void ReplaceSingletons() {
80 modem_->rtnl_handler_ = &rtnl_handler_;
Darin Petkove0a312e2011-07-20 13:45:28 -070081 }
82
David Rochbergfa1d31d2012-03-20 10:38:07 -040083 void ExpectLinkRelatedCalls();
84
Darin Petkove0a312e2011-07-20 13:45:28 -070085 protected:
86 class TestProxyFactory : public ProxyFactory {
87 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070088 explicit TestProxyFactory(ModemTest *test) : test_(test) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070089
90 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
Darin Petkov580c7af2011-10-24 12:32:50 +020091 DBusPropertiesProxyDelegate */*delegate*/,
mukesh agrawal1830fa12011-09-26 14:31:40 -070092 const string &/*path*/,
93 const string &/*service*/) {
Darin Petkov3b292332011-07-28 14:17:24 -070094 return test_->proxy_.release();
Darin Petkove0a312e2011-07-20 13:45:28 -070095 }
96
97 private:
Darin Petkov3b292332011-07-28 14:17:24 -070098 ModemTest *test_;
Darin Petkove0a312e2011-07-20 13:45:28 -070099 };
100
Darin Petkov721ac932011-11-16 15:43:09 +0100101 CellularCapabilityGSM *GetCapabilityGSM() {
102 return dynamic_cast<CellularCapabilityGSM *>(
Jason Glasgowe9089492012-02-23 17:57:37 -0500103 modem_->device_->capability_.get());
Darin Petkov721ac932011-11-16 15:43:09 +0100104 }
105
Darin Petkove0a312e2011-07-20 13:45:28 -0700106 MockGLib glib_;
107 MockControl control_interface_;
108 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800109 MockMetrics metrics_;
Chris Masone626719f2011-08-18 16:58:48 -0700110 MockManager manager_;
Jason Glasgowe9089492012-02-23 17:57:37 -0500111 MockDeviceInfo info_;
Darin Petkov3b292332011-07-28 14:17:24 -0700112 scoped_ptr<MockDBusPropertiesProxy> proxy_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700113 TestProxyFactory proxy_factory_;
David Rochbergfa1d31d2012-03-20 10:38:07 -0400114 scoped_ptr<StrictModem> modem_;
115 MockRTNLHandler rtnl_handler_;
116 ByteString expected_address_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700117};
118
Darin Petkove0a312e2011-07-20 13:45:28 -0700119void ModemTest::SetUp() {
Jason Glasgowe9089492012-02-23 17:57:37 -0500120 EXPECT_EQ(kOwner, modem_->owner_);
121 EXPECT_EQ(kPath, modem_->path_);
David Rochbergfa1d31d2012-03-20 10:38:07 -0400122 ReplaceSingletons();
123 expected_address_ = ByteString(kAddress, arraysize(kAddress));
124
125 EXPECT_CALL(rtnl_handler_, GetInterfaceIndex(kLinkName)).
126 WillRepeatedly(Return(kTestInterfaceIndex));
127
128 EXPECT_CALL(*modem_, ConvertMmToCellularModemState(_)).
129 WillRepeatedly(Return(Cellular::kModemStateUnknown));
130
131 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&info_));
Darin Petkove0a312e2011-07-20 13:45:28 -0700132}
133
134void ModemTest::TearDown() {
Jason Glasgowe9089492012-02-23 17:57:37 -0500135 modem_.reset();
Darin Petkove0a312e2011-07-20 13:45:28 -0700136}
137
David Rochbergfa1d31d2012-03-20 10:38:07 -0400138TEST_F(ModemTest, PendingDevicePropertiesAndCreate) {
139 static const char kSentinel[] = "sentinel";
140 static const uint32 kSentinelValue = 17;
Darin Petkove0a312e2011-07-20 13:45:28 -0700141
David Rochbergfa1d31d2012-03-20 10:38:07 -0400142 DBusPropertiesMap properties;
143 properties[kSentinel].writer().append_uint32(kSentinelValue);
144
145 EXPECT_CALL(*modem_, GetLinkName(_, _)).WillRepeatedly(DoAll(
146 SetArgumentPointee<1>(string(kLinkName)),
147 Return(true)));
148 EXPECT_CALL(rtnl_handler_, GetInterfaceIndex(StrEq(kLinkName))).
149 WillRepeatedly(Return(kTestInterfaceIndex));
150
151 // The first time we call CreateDeviceFromModemProperties,
152 // GetMACAddress will fail.
153 EXPECT_CALL(info_, GetMACAddress(kTestInterfaceIndex, _)).
154 WillOnce(Return(false));
155 modem_->CreateDeviceFromModemProperties(properties);
Jason Glasgowe9089492012-02-23 17:57:37 -0500156 EXPECT_FALSE(modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700157
David Rochbergfa1d31d2012-03-20 10:38:07 -0400158 // On the second time, we allow GetMACAddress to succeed. Now we
159 // expect a device to be built
160 EXPECT_CALL(info_, GetMACAddress(kTestInterfaceIndex, _)).
161 WillOnce(DoAll(SetArgumentPointee<1>(expected_address_),
162 Return(true)));
163
164 // modem will take ownership
165 MockCellular* cellular = new MockCellular(
166 &control_interface_,
167 &dispatcher_,
168 &metrics_,
169 &manager_,
170 kLinkName,
171 kAddressAsString,
172 kTestInterfaceIndex,
173 Cellular::kTypeGSM,
174 kOwner,
175 kPath,
176 static_cast<mobile_provider_db *>(NULL));
177
178 EXPECT_CALL(*modem_,
179 ConstructCellular(StrEq(kLinkName),
180 StrEq(kAddressAsString),
181 kTestInterfaceIndex)).
182 WillOnce(Return(cellular));
183
184 EXPECT_CALL(*cellular, OnModemManagerPropertiesChanged(
185 HasDBusPropertyWithValueU32(kSentinel, kSentinelValue)));
186 EXPECT_CALL(info_, RegisterDevice(_));
187 EXPECT_CALL(info_, DeregisterDevice(_));
188 modem_->OnDeviceInfoAvailable(kLinkName);
189
190 EXPECT_TRUE(modem_->device_.get());
191}
192
193TEST_F(ModemTest, EarlyDeviceProperties) {
194 // OnDeviceInfoAvailable called before
195 // CreateDeviceFromModemProperties: Do nothing
196 modem_->OnDeviceInfoAvailable(kLinkName);
197 EXPECT_FALSE(modem_->device_.get());
198}
199
200TEST_F(ModemTest, CreateDeviceEarlyFailures) {
201 DBusPropertiesMap properties;
202
203 EXPECT_CALL(*modem_, ConstructCellular(_, _, _)).Times(0);
204
205 // No link name: no device created
206 EXPECT_CALL(*modem_, GetLinkName(_, _)).WillOnce(Return(false));
207 modem_->CreateDeviceFromModemProperties(properties);
Jason Glasgowe9089492012-02-23 17:57:37 -0500208 EXPECT_FALSE(modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700209
David Rochbergfa1d31d2012-03-20 10:38:07 -0400210 // Link name, but no ifindex: no device created
211 EXPECT_CALL(*modem_, GetLinkName(_, _)).WillOnce(DoAll(
212 SetArgumentPointee<1>(string(kLinkName)),
213 Return(true)));
214 EXPECT_CALL(rtnl_handler_, GetInterfaceIndex(StrEq(kLinkName))).WillOnce(
215 Return(-1));
216 modem_->CreateDeviceFromModemProperties(properties);
Jason Glasgowe9089492012-02-23 17:57:37 -0500217 EXPECT_FALSE(modem_->device_.get());
David Rochbergfa1d31d2012-03-20 10:38:07 -0400218}
Darin Petkove0a312e2011-07-20 13:45:28 -0700219
David Rochbergfa1d31d2012-03-20 10:38:07 -0400220TEST_F(ModemTest, RejectPPPModem) {
221 // TODO(rochberg): Port this to ModemClassic
Darin Petkove0a312e2011-07-20 13:45:28 -0700222}
223
224} // namespace shill