blob: a92cfed63a77756c0fba0ce616b1d5844d462e12 [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 Masone2176a882011-09-14 22:29:15 -070047 : device_(new Device(control_interface(),
Chris Masone626719f2011-08-18 16:58:48 -070048 NULL,
49 NULL,
50 kDeviceName,
51 kDeviceAddress,
52 0)) {
Chris Masone2176a882011-09-14 22:29:15 -070053 DHCPProvider::GetInstance()->glib_ = glib();
54 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 MockControl control_interface_;
63 DeviceRefPtr device_;
64};
65
Chris Masone626719f2011-08-18 16:58:48 -070066const char DeviceTest::kDeviceName[] = "testdevice";
67const char DeviceTest::kDeviceAddress[] = "address";
68
Chris Masone3bd3c8c2011-06-13 08:20:26 -070069TEST_F(DeviceTest, Contains) {
Chris Masone27c4aa52011-07-02 13:10:14 -070070 EXPECT_TRUE(device_->store()->Contains(flimflam::kNameProperty));
71 EXPECT_FALSE(device_->store()->Contains(""));
Chris Masone3bd3c8c2011-06-13 08:20:26 -070072}
73
Chris Masonea8a2c252011-06-27 22:16:30 -070074TEST_F(DeviceTest, GetProperties) {
75 map<string, ::DBus::Variant> props;
76 Error error(Error::kInvalidProperty, "");
77 {
78 ::DBus::Error dbus_error;
79 bool expected = true;
Chris Masone27c4aa52011-07-02 13:10:14 -070080 device_->store()->SetBoolProperty(flimflam::kPoweredProperty,
81 expected,
82 &error);
83 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070084 ASSERT_FALSE(props.find(flimflam::kPoweredProperty) == props.end());
85 EXPECT_EQ(props[flimflam::kPoweredProperty].reader().get_bool(),
86 expected);
87 }
88 {
89 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -070090 DBusAdaptor::GetProperties(device_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -070091 ASSERT_FALSE(props.find(flimflam::kNameProperty) == props.end());
92 EXPECT_EQ(props[flimflam::kNameProperty].reader().get_string(),
93 string(kDeviceName));
94 }
95}
96
Chris Masone3bd3c8c2011-06-13 08:20:26 -070097TEST_F(DeviceTest, Dispatch) {
98 ::DBus::Error error;
Chris Masone27c4aa52011-07-02 13:10:14 -070099 EXPECT_TRUE(DBusAdaptor::DispatchOnType(device_->store(),
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700100 flimflam::kPoweredProperty,
Chris Masoneb925cc82011-06-22 15:39:57 -0700101 PropertyStoreTest::kBoolV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700102 &error));
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700103
Chris Masoneb925cc82011-06-22 15:39:57 -0700104 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masone27c4aa52011-07-02 13:10:14 -0700105 EXPECT_FALSE(DBusAdaptor::DispatchOnType(device_->store(),
Chris Masoneb925cc82011-06-22 15:39:57 -0700106 flimflam::kAddressProperty,
107 PropertyStoreTest::kStringV,
Chris Masonea8a2c252011-06-27 22:16:30 -0700108 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700109 EXPECT_EQ(invalid_args(), error.name());
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700110}
111
Darin Petkovafa6fc42011-06-21 16:21:08 -0700112TEST_F(DeviceTest, TechnologyIs) {
113 EXPECT_FALSE(device_->TechnologyIs(Device::kEthernet));
114}
115
116TEST_F(DeviceTest, DestroyIPConfig) {
117 ASSERT_FALSE(device_->ipconfig_.get());
Chris Masone2176a882011-09-14 22:29:15 -0700118 device_->ipconfig_ = new IPConfig(control_interface(), kDeviceName);
Darin Petkovafa6fc42011-06-21 16:21:08 -0700119 device_->DestroyIPConfig();
120 ASSERT_FALSE(device_->ipconfig_.get());
121}
122
123TEST_F(DeviceTest, DestroyIPConfigNULL) {
124 ASSERT_FALSE(device_->ipconfig_.get());
125 device_->DestroyIPConfig();
126 ASSERT_FALSE(device_->ipconfig_.get());
127}
128
129TEST_F(DeviceTest, AcquireDHCPConfig) {
Chris Masone2176a882011-09-14 22:29:15 -0700130 device_->ipconfig_ = new IPConfig(control_interface(), "randomname");
131 EXPECT_CALL(*glib(), SpawnAsync(_, _, _, _, _, _, _, _))
Darin Petkovafa6fc42011-06-21 16:21:08 -0700132 .WillOnce(Return(false));
133 EXPECT_FALSE(device_->AcquireDHCPConfig());
134 ASSERT_TRUE(device_->ipconfig_.get());
135 EXPECT_EQ(kDeviceName, device_->ipconfig_->device_name());
136 EXPECT_TRUE(device_->ipconfig_->update_callback_.get());
137}
138
Chris Masone5dec5f42011-07-22 14:07:55 -0700139TEST_F(DeviceTest, Load) {
140 NiceMock<MockStore> storage;
141 const string id = device_->GetStorageIdentifier();
142 EXPECT_CALL(storage, ContainsGroup(id)).WillOnce(Return(true));
143 EXPECT_CALL(storage, GetBool(id, _, _))
144 .Times(AtLeast(1))
145 .WillRepeatedly(Return(true));
146 EXPECT_TRUE(device_->Load(&storage));
147}
148
149TEST_F(DeviceTest, Save) {
150 NiceMock<MockStore> storage;
151 const string id = device_->GetStorageIdentifier();
Chris Masone5dec5f42011-07-22 14:07:55 -0700152 EXPECT_CALL(storage, SetString(id, _, _))
153 .Times(AtLeast(1))
154 .WillRepeatedly(Return(true));
155 EXPECT_CALL(storage, SetBool(id, _, _))
156 .Times(AtLeast(1))
157 .WillRepeatedly(Return(true));
Chris Masone2176a882011-09-14 22:29:15 -0700158 scoped_refptr<MockIPConfig> ipconfig = new MockIPConfig(control_interface(),
Chris Masone34af2182011-08-22 11:59:36 -0700159 kDeviceName);
160 EXPECT_CALL(*ipconfig.get(), Save(_, _))
161 .WillOnce(Return(true));
162 device_->ipconfig_ = ipconfig;
Chris Masone5dec5f42011-07-22 14:07:55 -0700163 EXPECT_TRUE(device_->Save(&storage));
164}
165
Chris Masone34af2182011-08-22 11:59:36 -0700166TEST_F(DeviceTest, StorageIdGeneration) {
167 string to_process("/device/stuff/0");
168 ControlInterface::RpcIdToStorageId(&to_process);
169 EXPECT_TRUE(isalpha(to_process[0]));
170 EXPECT_EQ(string::npos, to_process.find('/'));
171}
172
Paul Stewart03dba0b2011-08-22 16:32:45 -0700173TEST_F(DeviceTest, SelectedService) {
174 EXPECT_FALSE(device_->selected_service_.get());
175 device_->SetServiceState(Service::kStateAssociating);
176 scoped_refptr<MockService> service(
Chris Masone2176a882011-09-14 22:29:15 -0700177 new StrictMock<MockService>(control_interface(),
178 dispatcher(),
Chris Masone9d779932011-08-25 16:33:41 -0700179 manager()));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700180 device_->SelectService(service);
181 EXPECT_TRUE(device_->selected_service_.get() == service.get());
182
183 EXPECT_CALL(*service.get(), SetState(Service::kStateConfiguring));
184 device_->SetServiceState(Service::kStateConfiguring);
185 EXPECT_CALL(*service.get(), SetFailure(Service::kFailureOutOfRange));
186 device_->SetServiceFailure(Service::kFailureOutOfRange);
187
188 // Service should be returned to "Idle" state
189 EXPECT_CALL(*service.get(), state())
190 .WillOnce(Return(Service::kStateUnknown));
191 EXPECT_CALL(*service.get(), SetState(Service::kStateIdle));
192 device_->SelectService(NULL);
193
194 // A service in the "Failure" state should not be reset to "Idle"
195 device_->SelectService(service);
196 EXPECT_CALL(*service.get(), state())
197 .WillOnce(Return(Service::kStateFailure));
198 device_->SelectService(NULL);
199}
200
Darin Petkovafa6fc42011-06-21 16:21:08 -0700201} // namespace shill