blob: a2f2a686868a7040b034079120a6c57fdd5ddc3b [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>
8
Chris Masone3bd3c8c2011-06-13 08:20:26 -07009#include <map>
10#include <string>
11#include <vector>
12
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013#include <chromeos/dbus/service_constants.h>
Chris Masone34af2182011-08-22 11:59:36 -070014#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070015#include <gmock/gmock.h>
Chris Masone34af2182011-08-22 11:59:36 -070016#include <gtest/gtest.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070017
18#include "shill/dbus_adaptor.h"
19#include "shill/dhcp_provider.h"
20#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070021#include "shill/mock_adaptors.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070022#include "shill/mock_control.h"
23#include "shill/mock_device.h"
24#include "shill/mock_glib.h"
Chris Masone34af2182011-08-22 11:59:36 -070025#include "shill/mock_ipconfig.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070026#include "shill/mock_service.h"
Chris Masone5dec5f42011-07-22 14:07:55 -070027#include "shill/mock_store.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070028#include "shill/property_store_unittest.h"
29#include "shill/shill_event.h"
30
31using std::map;
32using std::string;
33using std::vector;
34using ::testing::_;
Chris Masone5dec5f42011-07-22 14:07:55 -070035using ::testing::AtLeast;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036using ::testing::NiceMock;
37using ::testing::Return;
Paul Stewart03dba0b2011-08-22 16:32:45 -070038using ::testing::StrictMock;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039using ::testing::Test;
Chris Masone34af2182011-08-22 11:59:36 -070040using ::testing::Values;
Darin Petkovafa6fc42011-06-21 16:21:08 -070041
42namespace shill {
43
Chris Masone3bd3c8c2011-06-13 08:20:26 -070044class DeviceTest : public PropertyStoreTest {
Darin Petkovafa6fc42011-06-21 16:21:08 -070045 public:
46 DeviceTest()
Chris Masone626719f2011-08-18 16:58:48 -070047 : device_(new Device(&control_interface_,
48 NULL,
49 NULL,
50 kDeviceName,
51 kDeviceAddress,
52 0)) {
Darin Petkovafa6fc42011-06-21 16:21:08 -070053 DHCPProvider::GetInstance()->glib_ = &glib_;
Chris Masone19e30402011-07-19 15:48:47 -070054 DHCPProvider::GetInstance()->control_interface_ = &control_interface_;
Darin Petkovafa6fc42011-06-21 16:21:08 -070055 }
Chris Masone3bd3c8c2011-06-13 08:20:26 -070056 virtual ~DeviceTest() {}
Darin Petkovafa6fc42011-06-21 16:21:08 -070057
58 protected:
Chris Masone626719f2011-08-18 16:58:48 -070059 static const char kDeviceName[];
60 static const char kDeviceAddress[];
61
Darin Petkovafa6fc42011-06-21 16:21:08 -070062 MockGLib glib_;
63 MockControl control_interface_;
64 DeviceRefPtr device_;
65};
66
Chris Masone626719f2011-08-18 16:58:48 -070067const char DeviceTest::kDeviceName[] = "testdevice";
68const char DeviceTest::kDeviceAddress[] = "address";
69
Chris Masone3bd3c8c2011-06-13 08:20:26 -070070TEST_F(DeviceTest, Contains) {
Chris Masone27c4aa52011-07-02 13:10:14 -070071 EXPECT_TRUE(device_->store()->Contains(flimflam::kNameProperty));
72 EXPECT_FALSE(device_->store()->Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -070073}
74
Chris Masonea8a2c252011-06-27 22:16:30 -070075TEST_F(DeviceTest, GetProperties) {
76 map<string, ::DBus::Variant> props;
77 Error error(Error::kInvalidProperty, "");
78 {
79 ::DBus::Error dbus_error;
80 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -070081 device_->store()->SetBoolProperty(flimflam::kPoweredProperty,
82 expected,
83 &error);
84 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070085 ASSERT_FALSE(props.find(flimflam::kPoweredProperty) == props.end());
86 EXPECT_EQ(props[flimflam::kPoweredProperty].reader().get_bool(),
87 expected);
88 }
89 {
90 ::DBus::Error dbus_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::kNameProperty) == props.end());
93 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
94 string(kDeviceName));
95 }
96}
97
Chris Masone3bd3c8c2011-06-13 08:20:26 -070098TEST_F(DeviceTest, Dispatch) {
99 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700100 EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_->store(),
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700101 flimflam::kPoweredProperty,
Chris Masoneb925cc82011-06-22 15:39:57 -0700102 PropertyStoreTest::kBoolV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700103 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700104
Chris Masoneb925cc82011-06-22 15:39:57 -0700105 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masone27c4aa52011-07-02 13:10:14 -0700106 EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_->store(),
Chris Masoneb925cc82011-06-22 15:39:57 -0700107 flimflam::kAddressProperty,
108 PropertyStoreTest::kStringV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700109 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700110 EXPECT_EQ(invalid_args_, error.name());
111}
112
Darin Petkovafa6fc42011-06-21 16:21:08 -0700113TEST_F(DeviceTest, TechnologyIs) {
114 EXPECT_FALSE(device_->TechnologyIs(Device::kEthernet));
115}
116
117TEST_F(DeviceTest, DestroyIPConfig) {
118 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone19e30402011-07-19 15:48:47 -0700119 device_->ipconfig_ = new IPConfig(&control_interface_, kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700120 device_->DestroyIPConfig();
121 ASSERT_FALSE(device_->ipconfig_.get());
122}
123
124TEST_F(DeviceTest, DestroyIPConfigNULL) {
125 ASSERT_FALSE(device_->ipconfig_.get());
126 device_->DestroyIPConfig();
127 ASSERT_FALSE(device_->ipconfig_.get());
128}
129
130TEST_F(DeviceTest, AcquireDHCPConfig) {
Chris Masone19e30402011-07-19 15:48:47 -0700131 device_->ipconfig_ = new IPConfig(&control_interface_, "randomname");
Darin Petkovafa6fc42011-06-21 16:21:08 -0700132 EXPECT_CALL(glib_, SpawnAsync(_, _, _, _, _, _, _, _))
133 .WillOnce(Return(false));
134 EXPECT_FALSE(device_->AcquireDHCPConfig());
135 ASSERT_TRUE(device_->ipconfig_.get());
136 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
137 EXPECT_TRUE(device_->ipconfig_->update_callback_.get());
138}
139
Chris Masone5dec5f42011-07-22 14:07:55 -0700140TEST_F(DeviceTest, Load) {
141 NiceMock<MockStore> storage;
142 const string id = device_->GetStorageIdentifier();
143 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
144 EXPECT_CALL(storage, GetBool(id, _, _))
145 .Times(AtLeast(1))
146 .WillRepeatedly(Return(true));
147 EXPECT_TRUE(device_->Load(&storage));
148}
149
150TEST_F(DeviceTest, Save) {
151 NiceMock<MockStore> storage;
152 const string id = device_->GetStorageIdentifier();
Chris Masone5dec5f42011-07-22 14:07:55 -0700153 EXPECT_CALL(storage, SetString(id, _, _))
154 .Times(AtLeast(1))
155 .WillRepeatedly(Return(true));
156 EXPECT_CALL(storage, SetBool(id, _, _))
157 .Times(AtLeast(1))
158 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700159 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(&control_interface_,
160 kDeviceName);
161 EXPECT_CALL(*ipconfig.get(), Save(_, _))
162 .WillOnce(Return(true));
163 device_->ipconfig_ = ipconfig;
Chris Masone5dec5f42011-07-22 14:07:55 -0700164 EXPECT_TRUE(device_->Save(&storage));
165}
166
Chris Masone34af2182011-08-22 11:59:36 -0700167TEST_F(DeviceTest, StorageIdGeneration) {
168 string to_process("/device/stuff/0");
169 ControlInterface::RpcIdToStorageId(&to_process);
170 EXPECT_TRUE(isalpha(to_process[0]));
171 EXPECT_EQ(string::npos, to_process.find('/'));
172}
173
Paul Stewart03dba0b2011-08-22 16:32:45 -0700174TEST_F(DeviceTest, SelectedService) {
175 EXPECT_FALSE(device_->selected_service_.get());
176 device_->SetServiceState(Service::kStateAssociating);
177 scoped_refptr<MockService> service(
178 new StrictMock<MockService>(&control_interface_,
179 &dispatcher_,
180 &manager_));
181 device_->SelectService(service);
182 EXPECT_TRUE(device_->selected_service_.get() == service.get());
183
184 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
185 device_->SetServiceState(Service::kStateConfiguring);
186 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
187 device_->SetServiceFailure(Service::kFailureOutOfRange);
188
189 // Service should be returned to "Idle" state
190 EXPECT_CALL(*service.get(), state())
191 .WillOnce(Return(Service::kStateUnknown));
192 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
193 device_->SelectService(NULL);
194
195 // A service in the "Failure" state should not be reset to "Idle"
196 device_->SelectService(service);
197 EXPECT_CALL(*service.get(), state())
198 .WillOnce(Return(Service::kStateFailure));
199 device_->SelectService(NULL);
200}
201
Darin Petkovafa6fc42011-06-21 16:21:08 -0700202} // namespace shill