blob: f658c2103e8d68269a7cfe2fc9befa4e28cc8463 [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"
Paul Stewart26b327e2011-10-19 11:38:09 -070015#include "shill/event_dispatcher.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070016#include "shill/manager.h"
17#include "shill/mock_control.h"
Chris Masone626719f2011-08-18 16:58:48 -070018#include "shill/mock_device_info.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070019#include "shill/mock_dbus_properties_proxy.h"
20#include "shill/mock_glib.h"
Chris Masone626719f2011-08-18 16:58:48 -070021#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080022#include "shill/mock_metrics.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070023#include "shill/mock_sockets.h"
24#include "shill/modem.h"
25#include "shill/proxy_factory.h"
26#include "shill/rtnl_handler.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070027
28using std::string;
Darin Petkov6f9eaa32011-08-09 15:26:44 -070029using std::vector;
Darin Petkove0a312e2011-07-20 13:45:28 -070030using testing::_;
31using testing::DoAll;
32using testing::Return;
Chris Masone626719f2011-08-18 16:58:48 -070033using testing::SetArgumentPointee;
Darin Petkove0a312e2011-07-20 13:45:28 -070034using testing::StrictMock;
35using testing::Test;
36
37namespace shill {
38
39namespace {
40
41const int kTestInterfaceIndex = 5;
42
43ACTION(SetInterfaceIndex) {
44 if (arg2) {
45 reinterpret_cast<struct ifreq *>(arg2)->ifr_ifindex = kTestInterfaceIndex;
46 }
47}
48
49} // namespace
50
51class ModemTest : public Test {
52 public:
53 ModemTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080054 : manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Jason Glasgowe9089492012-02-23 17:57:37 -050055 info_(&control_interface_, &dispatcher_, &metrics_, &manager_),
Darin Petkov3b292332011-07-28 14:17:24 -070056 proxy_(new MockDBusPropertiesProxy()),
57 proxy_factory_(this),
Jason Glasgowe9089492012-02-23 17:57:37 -050058 modem_(new Modem(kOwner,
59 kPath,
60 &control_interface_,
61 &dispatcher_,
62 &metrics_,
63 &manager_,
64 NULL)) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070065
66 virtual void SetUp();
67 virtual void TearDown();
68
69 void SetSockets(Sockets *sockets) {
70 RTNLHandler::GetInstance()->sockets_ = sockets;
71 }
72
73 protected:
74 class TestProxyFactory : public ProxyFactory {
75 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070076 explicit TestProxyFactory(ModemTest *test) : test_(test) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070077
78 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
Darin Petkov580c7af2011-10-24 12:32:50 +020079 DBusPropertiesProxyDelegate */*delegate*/,
mukesh agrawal1830fa12011-09-26 14:31:40 -070080 const string &/*path*/,
81 const string &/*service*/) {
Darin Petkov3b292332011-07-28 14:17:24 -070082 return test_->proxy_.release();
Darin Petkove0a312e2011-07-20 13:45:28 -070083 }
84
85 private:
Darin Petkov3b292332011-07-28 14:17:24 -070086 ModemTest *test_;
Darin Petkove0a312e2011-07-20 13:45:28 -070087 };
88
89 static const char kOwner[];
90 static const char kPath[];
91
Darin Petkov721ac932011-11-16 15:43:09 +010092 CellularCapabilityGSM *GetCapabilityGSM() {
93 return dynamic_cast<CellularCapabilityGSM *>(
Jason Glasgowe9089492012-02-23 17:57:37 -050094 modem_->device_->capability_.get());
Darin Petkov721ac932011-11-16 15:43:09 +010095 }
96
Darin Petkove0a312e2011-07-20 13:45:28 -070097 MockGLib glib_;
98 MockControl control_interface_;
99 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800100 MockMetrics metrics_;
Chris Masone626719f2011-08-18 16:58:48 -0700101 MockManager manager_;
Jason Glasgowe9089492012-02-23 17:57:37 -0500102 MockDeviceInfo info_;
Darin Petkov3b292332011-07-28 14:17:24 -0700103 scoped_ptr<MockDBusPropertiesProxy> proxy_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700104 TestProxyFactory proxy_factory_;
Jason Glasgowe9089492012-02-23 17:57:37 -0500105 scoped_ptr<Modem> modem_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700106 StrictMock<MockSockets> sockets_;
107};
108
109const char ModemTest::kOwner[] = ":1.18";
110const char ModemTest::kPath[] = "/org/chromium/ModemManager/Gobi/0";
111
112void ModemTest::SetUp() {
Jason Glasgowe9089492012-02-23 17:57:37 -0500113 EXPECT_EQ(kOwner, modem_->owner_);
114 EXPECT_EQ(kPath, modem_->path_);
115 modem_->proxy_factory_ = &proxy_factory_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700116}
117
118void ModemTest::TearDown() {
Jason Glasgowe9089492012-02-23 17:57:37 -0500119 modem_.reset();
Darin Petkove0a312e2011-07-20 13:45:28 -0700120 SetSockets(NULL);
121}
122
Darin Petkove0a312e2011-07-20 13:45:28 -0700123TEST_F(ModemTest, Init) {
Darin Petkove0a312e2011-07-20 13:45:28 -0700124 DBusPropertiesMap props;
Jason Glasgowe9089492012-02-23 17:57:37 -0500125
126 SetSockets(&sockets_);
Darin Petkove0a312e2011-07-20 13:45:28 -0700127 props[Modem::kPropertyIPMethod].writer().append_uint32(
128 MM_MODEM_IP_METHOD_DHCP);
129 props[Modem::kPropertyLinkName].writer().append_string("usb1");
Darin Petkov3b292332011-07-28 14:17:24 -0700130 EXPECT_CALL(*proxy_, GetAll(MM_MODEM_INTERFACE)).WillOnce(Return(props));
Jason Glasgowe9089492012-02-23 17:57:37 -0500131 EXPECT_TRUE(modem_->task_factory_.empty());
132 modem_->Init();
133 EXPECT_FALSE(modem_->task_factory_.empty());
Darin Petkov67d8ecf2011-07-26 16:03:30 -0700134
135 EXPECT_CALL(sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).WillOnce(Return(-1));
136 dispatcher_.DispatchPendingEvents();
Darin Petkove0a312e2011-07-20 13:45:28 -0700137}
138
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100139TEST_F(ModemTest, CreateDeviceFromProperties) {
Darin Petkove0a312e2011-07-20 13:45:28 -0700140 DBusPropertiesMap props;
141
Jason Glasgowe9089492012-02-23 17:57:37 -0500142 modem_->CreateDeviceFromProperties(props);
143 EXPECT_FALSE(modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700144
145 props[Modem::kPropertyIPMethod].writer().append_uint32(
146 MM_MODEM_IP_METHOD_PPP);
Jason Glasgowe9089492012-02-23 17:57:37 -0500147 modem_->CreateDeviceFromProperties(props);
148 EXPECT_FALSE(modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700149
150 props.erase(Modem::kPropertyIPMethod);
151 props[Modem::kPropertyIPMethod].writer().append_uint32(
152 MM_MODEM_IP_METHOD_DHCP);
Jason Glasgowe9089492012-02-23 17:57:37 -0500153 modem_->CreateDeviceFromProperties(props);
154 EXPECT_FALSE(modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700155
156 static const char kLinkName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700157 static const unsigned char kAddress[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
Darin Petkove0a312e2011-07-20 13:45:28 -0700158 const int kTestSocket = 10;
Jason Glasgowe9089492012-02-23 17:57:37 -0500159 const int kTestLinkSocket = 11;
Darin Petkove0a312e2011-07-20 13:45:28 -0700160 props[Modem::kPropertyLinkName].writer().append_string(kLinkName);
161 EXPECT_CALL(sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
Darin Petkove9d12e02011-07-27 15:09:37 -0700162 .Times(2)
163 .WillRepeatedly(Return(kTestSocket));
Darin Petkove0a312e2011-07-20 13:45:28 -0700164 EXPECT_CALL(sockets_, Ioctl(kTestSocket, SIOCGIFINDEX, _))
Darin Petkove9d12e02011-07-27 15:09:37 -0700165 .WillRepeatedly(DoAll(SetInterfaceIndex(), Return(0)));
Darin Petkove0a312e2011-07-20 13:45:28 -0700166 EXPECT_CALL(sockets_, Close(kTestSocket))
Darin Petkove9d12e02011-07-27 15:09:37 -0700167 .WillRepeatedly(Return(0));
Chris Masone626719f2011-08-18 16:58:48 -0700168
Jason Glasgowe9089492012-02-23 17:57:37 -0500169 EXPECT_CALL(sockets_, Socket(PF_NETLINK, _, _))
170 .WillRepeatedly(Return(kTestLinkSocket));
171 EXPECT_CALL(sockets_, Bind(kTestLinkSocket, _, _))
172 .WillRepeatedly(Return(0));
173 EXPECT_CALL(sockets_, Send(kTestLinkSocket, _, _, _))
174 .WillRepeatedly(Return(0));
175 RTNLHandler::GetInstance()->Start(&dispatcher_, &sockets_);
176
Chris Masone626719f2011-08-18 16:58:48 -0700177 ByteString expected_address(kAddress, arraysize(kAddress));
Paul Stewart32852962011-08-30 14:06:53 -0700178 EXPECT_CALL(info_, GetMACAddress(kTestInterfaceIndex, _))
Chris Masone626719f2011-08-18 16:58:48 -0700179 .WillOnce(DoAll(SetArgumentPointee<1>(expected_address), Return(true)))
180 .WillOnce(DoAll(SetArgumentPointee<1>(expected_address), Return(true)));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800181 EXPECT_CALL(info_, GetDevice(kTestInterfaceIndex))
Jason Glasgowe9089492012-02-23 17:57:37 -0500182 .WillRepeatedly(Return(modem_->device_));
Chris Masone626719f2011-08-18 16:58:48 -0700183 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&info_));
184
Jason Glasgowe9089492012-02-23 17:57:37 -0500185 modem_->CreateDeviceFromProperties(props);
186 EXPECT_FALSE(modem_->device_.get());
Darin Petkove9d12e02011-07-27 15:09:37 -0700187
Darin Petkov721ac932011-11-16 15:43:09 +0100188 props[Modem::kPropertyType].writer().append_uint32(MM_MODEM_TYPE_GSM);
Darin Petkovbac96002011-08-09 13:22:00 -0700189 props[Modem::kPropertyState].writer().append_uint32(
190 Cellular::kModemStateDisabled);
Darin Petkov721ac932011-11-16 15:43:09 +0100191 static const char kLockType[] = "sim-pin";
192 const int kRetries = 2;
Darin Petkov63138a92012-02-06 14:09:15 +0100193 props[CellularCapabilityGSM::kPropertyEnabledFacilityLocks].writer().
194 append_uint32(MM_MODEM_GSM_FACILITY_SIM);
Darin Petkov721ac932011-11-16 15:43:09 +0100195 props[CellularCapabilityGSM::kPropertyUnlockRequired].writer().append_string(
196 kLockType);
197 props[CellularCapabilityGSM::kPropertyUnlockRetries].writer().append_uint32(
198 kRetries);
Jason Glasgowe9089492012-02-23 17:57:37 -0500199 modem_->CreateDeviceFromProperties(props);
200 ASSERT_TRUE(modem_->device_.get());
201 EXPECT_EQ(kLinkName, modem_->device_->link_name());
202 EXPECT_EQ(kTestInterfaceIndex, modem_->device_->interface_index());
203 EXPECT_EQ(Cellular::kModemStateDisabled, modem_->device_->modem_state());
Darin Petkov63138a92012-02-06 14:09:15 +0100204 EXPECT_TRUE(GetCapabilityGSM()->sim_lock_status_.enabled);
205 EXPECT_EQ(kLockType, GetCapabilityGSM()->sim_lock_status_.lock_type);
206 EXPECT_EQ(kRetries, GetCapabilityGSM()->sim_lock_status_.retries_left);
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700207
208 vector<DeviceRefPtr> devices;
Paul Stewartfdd16072011-09-16 12:41:35 -0700209 manager_.FilterByTechnology(Technology::kCellular, &devices);
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700210 EXPECT_EQ(1, devices.size());
Jason Glasgowe9089492012-02-23 17:57:37 -0500211 EXPECT_TRUE(devices[0].get() == modem_->device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700212}
213
214} // namespace shill