blob: 1270a49914e0c865ee28e19d9f06ca6c8ba7b77e [file] [log] [blame]
Darin Petkovafa6fc42011-06-21 16:21:08 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Darin Petkovafa6fc42011-06-21 16:21:08 -07005#include "shill/device.h"
Darin Petkovafa6fc42011-06-21 16:21:08 -07006
Chris Masone34af2182011-08-22 11:59:36 -07007#include <ctype.h>
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -07008#include <sys/socket.h>
9#include <linux/if.h> // Needs typedefs from sys/socket.h.
Chris Masone34af2182011-08-22 11:59:36 -070010
Chris Masone3bd3c8c2011-06-13 08:20:26 -070011#include <map>
12#include <string>
13#include <vector>
14
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <chromeos/dbus/service_constants.h>
Chris Masone34af2182011-08-22 11:59:36 -070016#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017#include <gmock/gmock.h>
Chris Masone34af2182011-08-22 11:59:36 -070018#include <gtest/gtest.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070019
20#include "shill/dbus_adaptor.h"
21#include "shill/dhcp_provider.h"
22#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070023#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070024#include "shill/mock_control.h"
25#include "shill/mock_device.h"
26#include "shill/mock_glib.h"
Chris Masone34af2182011-08-22 11:59:36 -070027#include "shill/mock_ipconfig.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070028#include "shill/mock_rtnl_handler.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070029#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070030#include "shill/mock_store.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070031#include "shill/property_store_unittest.h"
32#include "shill/shill_event.h"
33
34using std::map;
35using std::string;
36using std::vector;
37using ::testing::_;
Chris Masone5dec5f42011-07-22 14:07:55 -070038using ::testing::AtLeast;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039using ::testing::NiceMock;
40using ::testing::Return;
Paul Stewart03dba0b2011-08-22 16:32:45 -070041using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070043using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070044
45namespace shill {
46
Chris Masone3bd3c8c2011-06-13 08:20:26 -070047class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070048 public:
49 DeviceTest()
Chris Masone2176a882011-09-14 22:29:15 -070050 : device_(new Device(control_interface(),
Chris Masone626719f2011-08-18 16:58:48 -070051 NULL,
52 NULL,
53 kDeviceName,
54 kDeviceAddress,
55 0)) {
Chris Masone2176a882011-09-14 22:29:15 -070056 DHCPProvider::GetInstance()->glib_ = glib();
57 DHCPProvider::GetInstance()->control_interface_ = control_interface();
Darin Petkovafa6fc42011-06-21 16:21:08 -070058 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070059 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -070060
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070061 virtual void SetUp() {
62 device_->rtnl_handler_ = &rtnl_handler_;
63 }
64
Darin Petkovafa6fc42011-06-21 16:21:08 -070065 protected:
Chris Masone626719f2011-08-18 16:58:48 -070066 static const char kDeviceName[];
67 static const char kDeviceAddress[];
68
Darin Petkovafa6fc42011-06-21 16:21:08 -070069 MockControl control_interface_;
70 DeviceRefPtr device_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070071 StrictMock<MockRTNLHandler> rtnl_handler_;
Darin Petkovafa6fc42011-06-21 16:21:08 -070072};
73
Chris Masone626719f2011-08-18 16:58:48 -070074const char DeviceTest::kDeviceName[] = "testdevice";
75const char DeviceTest::kDeviceAddress[] = "address";
76
Chris Masone3bd3c8c2011-06-13 08:20:26 -070077TEST_F(DeviceTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -070078 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
79 EXPECT_FALSE(device_->store().Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -070080}
81
Chris Masonea8a2c252011-06-27 22:16:30 -070082TEST_F(DeviceTest, GetProperties) {
83 map<string, ::DBus::Variant> props;
84 Error error(Error::kInvalidProperty, "");
85 {
86 ::DBus::Error dbus_error;
87 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -070088 device_->mutable_store()->SetBoolProperty(flimflam::kPoweredProperty,
89 expected,
90 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -070091 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070092 ASSERT_FALSE(props.find(flimflam::kPoweredProperty) == props.end());
93 EXPECT_EQ(props[flimflam::kPoweredProperty].reader().get_bool(),
94 expected);
95 }
96 {
97 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -070098 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070099 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
100 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
101 string(kDeviceName));
102 }
103}
104
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700105TEST_F(DeviceTest, Dispatch) {
106 ::DBus::Error error;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700107 EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_->mutable_store(),
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700108 flimflam::kPoweredProperty,
Chris Masoneb925cc82011-06-22 15:39:57 -0700109 PropertyStoreTest::kBoolV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700110 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700111
Chris Masoneb925cc82011-06-22 15:39:57 -0700112 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
mukesh agrawalde29fa82011-09-16 16:16:36 -0700113 EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_->mutable_store(),
Chris Masoneb925cc82011-06-22 15:39:57 -0700114 flimflam::kAddressProperty,
115 PropertyStoreTest::kStringV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700116 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700117 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700118}
119
Darin Petkovafa6fc42011-06-21 16:21:08 -0700120TEST_F(DeviceTest, TechnologyIs) {
121 EXPECT_FALSE(device_->TechnologyIs(Device::kEthernet));
122}
123
124TEST_F(DeviceTest, DestroyIPConfig) {
125 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700126 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700127 device_->DestroyIPConfig();
128 ASSERT_FALSE(device_->ipconfig_.get());
129}
130
131TEST_F(DeviceTest, DestroyIPConfigNULL) {
132 ASSERT_FALSE(device_->ipconfig_.get());
133 device_->DestroyIPConfig();
134 ASSERT_FALSE(device_->ipconfig_.get());
135}
136
137TEST_F(DeviceTest, AcquireDHCPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700138 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
139 EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
Darin Petkovafa6fc42011-06-21 16:21:08 -0700140 .WillOnce(Return(false));
141 EXPECT_FALSE(device_->AcquireDHCPConfig());
142 ASSERT_TRUE(device_->ipconfig_.get());
143 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
144 EXPECT_TRUE(device_->ipconfig_->update_callback_.get());
145}
146
Chris Masone5dec5f42011-07-22 14:07:55 -0700147TEST_F(DeviceTest, Load) {
148 NiceMock<MockStore> storage;
149 const string id = device_->GetStorageIdentifier();
150 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
151 EXPECT_CALL(storage, GetBool(id, _, _))
152 .Times(AtLeast(1))
153 .WillRepeatedly(Return(true));
154 EXPECT_TRUE(device_->Load(&storage));
155}
156
157TEST_F(DeviceTest, Save) {
158 NiceMock<MockStore> storage;
159 const string id = device_->GetStorageIdentifier();
Chris Masone5dec5f42011-07-22 14:07:55 -0700160 EXPECT_CALL(storage, SetString(id, _, _))
161 .Times(AtLeast(1))
162 .WillRepeatedly(Return(true));
163 EXPECT_CALL(storage, SetBool(id, _, _))
164 .Times(AtLeast(1))
165 .WillRepeatedly(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700166 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700167 kDeviceName);
168 EXPECT_CALL(*ipconfig.get(), Save(_, _))
169 .WillOnce(Return(true));
170 device_->ipconfig_ = ipconfig;
Chris Masone5dec5f42011-07-22 14:07:55 -0700171 EXPECT_TRUE(device_->Save(&storage));
172}
173
Chris Masone34af2182011-08-22 11:59:36 -0700174TEST_F(DeviceTest, StorageIdGeneration) {
175 string to_process("/device/stuff/0");
176 ControlInterface::RpcIdToStorageId(&to_process);
177 EXPECT_TRUE(isalpha(to_process[0]));
178 EXPECT_EQ(string::npos, to_process.find('/'));
179}
180
Paul Stewart03dba0b2011-08-22 16:32:45 -0700181TEST_F(DeviceTest, SelectedService) {
182 EXPECT_FALSE(device_->selected_service_.get());
183 device_->SetServiceState(Service::kStateAssociating);
184 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700185 new StrictMock<MockService>(control_interface(),
186 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700187 manager()));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700188 device_->SelectService(service);
189 EXPECT_TRUE(device_->selected_service_.get() == service.get());
190
191 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
192 device_->SetServiceState(Service::kStateConfiguring);
193 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
194 device_->SetServiceFailure(Service::kFailureOutOfRange);
195
196 // Service should be returned to "Idle" state
197 EXPECT_CALL(*service.get(), state())
198 .WillOnce(Return(Service::kStateUnknown));
199 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
200 device_->SelectService(NULL);
201
202 // A service in the "Failure" state should not be reset to "Idle"
203 device_->SelectService(service);
204 EXPECT_CALL(*service.get(), state())
205 .WillOnce(Return(Service::kStateFailure));
206 device_->SelectService(NULL);
207}
208
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700209TEST_F(DeviceTest, Stop) {
210 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
211 scoped_refptr<MockService> service(
212 new NiceMock<MockService>(&control_interface_,
213 dispatcher(),
214 manager()));
215 device_->SelectService(service);
216
217 EXPECT_CALL(*service.get(), state()).
218 WillRepeatedly(Return(Service::kStateConnected));
219 EXPECT_CALL(*dynamic_cast<DeviceMockAdaptor *>(device_->adaptor_.get()),
220 UpdateEnabled());
221 EXPECT_CALL(rtnl_handler_, SetInterfaceFlags(_, 0, IFF_UP));
222 device_->Stop();
223
224 EXPECT_FALSE(device_->ipconfig_.get());
225 EXPECT_FALSE(device_->selected_service_.get());
226}
227
Darin Petkovafa6fc42011-06-21 16:21:08 -0700228} // namespace shill