blob: 1668c4dff7048e1b69b563e1adc93042d4cd3f64 [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"
Darin Petkove0a312e2011-07-20 13:45:28 -070022#include "shill/mock_sockets.h"
23#include "shill/modem.h"
24#include "shill/proxy_factory.h"
25#include "shill/rtnl_handler.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070026
27using std::string;
Darin Petkov6f9eaa32011-08-09 15:26:44 -070028using std::vector;
Darin Petkove0a312e2011-07-20 13:45:28 -070029using testing::_;
30using testing::DoAll;
31using testing::Return;
Chris Masone626719f2011-08-18 16:58:48 -070032using testing::SetArgumentPointee;
Darin Petkove0a312e2011-07-20 13:45:28 -070033using testing::StrictMock;
34using testing::Test;
35
36namespace shill {
37
38namespace {
39
40const int kTestInterfaceIndex = 5;
41
42ACTION(SetInterfaceIndex) {
43 if (arg2) {
44 reinterpret_cast<struct ifreq *>(arg2)->ifr_ifindex = kTestInterfaceIndex;
45 }
46}
47
48} // namespace
49
50class ModemTest : public Test {
51 public:
52 ModemTest()
53 : manager_(&control_interface_, &dispatcher_, &glib_),
Darin Petkov3b292332011-07-28 14:17:24 -070054 proxy_(new MockDBusPropertiesProxy()),
55 proxy_factory_(this),
Darin Petkov137884a2011-10-26 18:52:47 +020056 modem_(kOwner,
57 kPath,
58 &control_interface_,
59 &dispatcher_,
60 &manager_,
61 NULL) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070062
63 virtual void SetUp();
64 virtual void TearDown();
65
66 void SetSockets(Sockets *sockets) {
67 RTNLHandler::GetInstance()->sockets_ = sockets;
68 }
69
70 protected:
71 class TestProxyFactory : public ProxyFactory {
72 public:
Paul Stewart7355ce12011-09-02 10:47:01 -070073 explicit TestProxyFactory(ModemTest *test) : test_(test) {}
Darin Petkove0a312e2011-07-20 13:45:28 -070074
75 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
Darin Petkov580c7af2011-10-24 12:32:50 +020076 DBusPropertiesProxyDelegate */*delegate*/,
mukesh agrawal1830fa12011-09-26 14:31:40 -070077 const string &/*path*/,
78 const string &/*service*/) {
Darin Petkov3b292332011-07-28 14:17:24 -070079 return test_->proxy_.release();
Darin Petkove0a312e2011-07-20 13:45:28 -070080 }
81
82 private:
Darin Petkov3b292332011-07-28 14:17:24 -070083 ModemTest *test_;
Darin Petkove0a312e2011-07-20 13:45:28 -070084 };
85
86 static const char kOwner[];
87 static const char kPath[];
88
Darin Petkov721ac932011-11-16 15:43:09 +010089 CellularCapabilityGSM *GetCapabilityGSM() {
90 return dynamic_cast<CellularCapabilityGSM *>(
91 modem_.device_->capability_.get());
92 }
93
Darin Petkove0a312e2011-07-20 13:45:28 -070094 MockGLib glib_;
95 MockControl control_interface_;
96 EventDispatcher dispatcher_;
Chris Masone626719f2011-08-18 16:58:48 -070097 MockManager manager_;
Darin Petkov3b292332011-07-28 14:17:24 -070098 scoped_ptr<MockDBusPropertiesProxy> proxy_;
Darin Petkove0a312e2011-07-20 13:45:28 -070099 TestProxyFactory proxy_factory_;
100 Modem modem_;
101 StrictMock<MockSockets> sockets_;
102};
103
104const char ModemTest::kOwner[] = ":1.18";
105const char ModemTest::kPath[] = "/org/chromium/ModemManager/Gobi/0";
106
107void ModemTest::SetUp() {
108 EXPECT_EQ(kOwner, modem_.owner_);
109 EXPECT_EQ(kPath, modem_.path_);
Darin Petkovab565bb2011-10-06 02:55:51 -0700110 modem_.proxy_factory_ = &proxy_factory_;
Darin Petkove0a312e2011-07-20 13:45:28 -0700111 SetSockets(&sockets_);
112}
113
114void ModemTest::TearDown() {
Darin Petkovab565bb2011-10-06 02:55:51 -0700115 modem_.proxy_factory_ = NULL;
Darin Petkove0a312e2011-07-20 13:45:28 -0700116 SetSockets(NULL);
117}
118
Darin Petkove0a312e2011-07-20 13:45:28 -0700119TEST_F(ModemTest, Init) {
Darin Petkove0a312e2011-07-20 13:45:28 -0700120 DBusPropertiesMap props;
121 props[Modem::kPropertyIPMethod].writer().append_uint32(
122 MM_MODEM_IP_METHOD_DHCP);
123 props[Modem::kPropertyLinkName].writer().append_string("usb1");
Darin Petkov3b292332011-07-28 14:17:24 -0700124 EXPECT_CALL(*proxy_, GetAll(MM_MODEM_INTERFACE)).WillOnce(Return(props));
Darin Petkov67d8ecf2011-07-26 16:03:30 -0700125 EXPECT_TRUE(modem_.task_factory_.empty());
Darin Petkove0a312e2011-07-20 13:45:28 -0700126 modem_.Init();
Darin Petkov67d8ecf2011-07-26 16:03:30 -0700127 EXPECT_FALSE(modem_.task_factory_.empty());
128
129 EXPECT_CALL(sockets_, Socket(PF_INET, SOCK_DGRAM, 0)).WillOnce(Return(-1));
130 dispatcher_.DispatchPendingEvents();
Darin Petkove0a312e2011-07-20 13:45:28 -0700131}
132
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100133TEST_F(ModemTest, CreateDeviceFromProperties) {
Darin Petkove0a312e2011-07-20 13:45:28 -0700134 DBusPropertiesMap props;
135
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100136 modem_.CreateDeviceFromProperties(props);
Darin Petkove0a312e2011-07-20 13:45:28 -0700137 EXPECT_FALSE(modem_.device_.get());
138
139 props[Modem::kPropertyIPMethod].writer().append_uint32(
140 MM_MODEM_IP_METHOD_PPP);
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100141 modem_.CreateDeviceFromProperties(props);
Darin Petkove0a312e2011-07-20 13:45:28 -0700142 EXPECT_FALSE(modem_.device_.get());
143
144 props.erase(Modem::kPropertyIPMethod);
145 props[Modem::kPropertyIPMethod].writer().append_uint32(
146 MM_MODEM_IP_METHOD_DHCP);
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100147 modem_.CreateDeviceFromProperties(props);
Darin Petkove0a312e2011-07-20 13:45:28 -0700148 EXPECT_FALSE(modem_.device_.get());
149
150 static const char kLinkName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700151 static const unsigned char kAddress[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05};
Darin Petkove0a312e2011-07-20 13:45:28 -0700152 const int kTestSocket = 10;
153 props[Modem::kPropertyLinkName].writer().append_string(kLinkName);
154 EXPECT_CALL(sockets_, Socket(PF_INET, SOCK_DGRAM, 0))
Darin Petkove9d12e02011-07-27 15:09:37 -0700155 .Times(2)
156 .WillRepeatedly(Return(kTestSocket));
Darin Petkove0a312e2011-07-20 13:45:28 -0700157 EXPECT_CALL(sockets_, Ioctl(kTestSocket, SIOCGIFINDEX, _))
Darin Petkove9d12e02011-07-27 15:09:37 -0700158 .WillRepeatedly(DoAll(SetInterfaceIndex(), Return(0)));
Darin Petkove0a312e2011-07-20 13:45:28 -0700159 EXPECT_CALL(sockets_, Close(kTestSocket))
Darin Petkove9d12e02011-07-27 15:09:37 -0700160 .WillRepeatedly(Return(0));
Chris Masone626719f2011-08-18 16:58:48 -0700161
162 ByteString expected_address(kAddress, arraysize(kAddress));
163 MockDeviceInfo info_(&control_interface_, &dispatcher_, &manager_);
Paul Stewart32852962011-08-30 14:06:53 -0700164 EXPECT_CALL(info_, GetMACAddress(kTestInterfaceIndex, _))
Chris Masone626719f2011-08-18 16:58:48 -0700165 .WillOnce(DoAll(SetArgumentPointee<1>(expected_address), Return(true)))
166 .WillOnce(DoAll(SetArgumentPointee<1>(expected_address), Return(true)));
Paul Stewartc8f4bef2011-12-13 09:45:51 -0800167 EXPECT_CALL(info_, GetDevice(kTestInterfaceIndex))
168 .WillRepeatedly(Return(modem_.device_));
Chris Masone626719f2011-08-18 16:58:48 -0700169 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&info_));
170
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100171 modem_.CreateDeviceFromProperties(props);
Darin Petkove9d12e02011-07-27 15:09:37 -0700172 EXPECT_FALSE(modem_.device_.get());
173
Darin Petkov721ac932011-11-16 15:43:09 +0100174 props[Modem::kPropertyType].writer().append_uint32(MM_MODEM_TYPE_GSM);
Darin Petkovbac96002011-08-09 13:22:00 -0700175 props[Modem::kPropertyState].writer().append_uint32(
176 Cellular::kModemStateDisabled);
Darin Petkov721ac932011-11-16 15:43:09 +0100177 static const char kLockType[] = "sim-pin";
178 const int kRetries = 2;
179 props[CellularCapabilityGSM::kPropertyUnlockRequired].writer().append_string(
180 kLockType);
181 props[CellularCapabilityGSM::kPropertyUnlockRetries].writer().append_uint32(
182 kRetries);
Darin Petkov41c0e0a2012-01-09 16:38:53 +0100183 modem_.CreateDeviceFromProperties(props);
Darin Petkove9d12e02011-07-27 15:09:37 -0700184 ASSERT_TRUE(modem_.device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700185 EXPECT_EQ(kLinkName, modem_.device_->link_name());
186 EXPECT_EQ(kTestInterfaceIndex, modem_.device_->interface_index());
Darin Petkovbac96002011-08-09 13:22:00 -0700187 EXPECT_EQ(Cellular::kModemStateDisabled, modem_.device_->modem_state());
Darin Petkov721ac932011-11-16 15:43:09 +0100188 EXPECT_EQ(kLockType, GetCapabilityGSM()->sim_lock_type());
189 EXPECT_EQ(kRetries, GetCapabilityGSM()->sim_lock_retries_left());
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700190
191 vector<DeviceRefPtr> devices;
Paul Stewartfdd16072011-09-16 12:41:35 -0700192 manager_.FilterByTechnology(Technology::kCellular, &devices);
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700193 EXPECT_EQ(1, devices.size());
194 EXPECT_TRUE(devices[0].get() == modem_.device_.get());
Darin Petkove0a312e2011-07-20 13:45:28 -0700195}
196
197} // namespace shill