blob: 83b1755f15735d957773762b65b626b9c93b5485 [file] [log] [blame]
Arman Uguray2717a102013-01-29 23:36:06 -08001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/service.h"
6
7#include <map>
8#include <string>
9#include <vector>
10
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include <base/bind.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070012#include <chromeos/dbus/service_constants.h>
mukesh agrawal1830fa12011-09-26 14:31:40 -070013#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070014#include <gtest/gtest.h>
15#include <gmock/gmock.h>
16
17#include "shill/dbus_adaptor.h"
18#include "shill/ethernet_service.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070020#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"
Paul Stewart10241e32012-04-23 18:15:06 -070023#include "shill/mock_connection.h"
24#include "shill/mock_device_info.h"
Darin Petkov385b9bc2012-12-03 15:25:05 +010025#include "shill/mock_diagnostics_reporter.h"
Paul Stewartc43cbbe2013-04-11 06:29:30 -070026#include "shill/mock_eap_credentials.h"
Christopher Wiley0801d192012-09-24 11:57:15 -070027#include "shill/mock_event_dispatcher.h"
Paul Stewartbc6e7392012-05-24 07:07:48 -070028#include "shill/mock_log.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070029#include "shill/mock_manager.h"
Darin Petkovcb0b5662012-12-13 09:59:44 +010030#include "shill/mock_power_manager.h"
Paul Stewartff14b022012-04-24 20:06:23 -070031#include "shill/mock_profile.h"
Darin Petkovcb0b5662012-12-13 09:59:44 +010032#include "shill/mock_proxy_factory.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070033#include "shill/mock_store.h"
Darin Petkov385b9bc2012-12-03 15:25:05 +010034#include "shill/mock_time.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035#include "shill/property_store_unittest.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070036#include "shill/service_property_change_test.h"
Chris Masone6515aab2011-10-12 16:19:09 -070037#include "shill/service_under_test.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070038
Eric Shienbrood9a245532012-03-07 14:20:39 -050039using base::Bind;
40using base::Unretained;
Darin Petkov385b9bc2012-12-03 15:25:05 +010041using std::deque;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042using std::map;
43using std::string;
44using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070045using testing::_;
mukesh agrawalcf24a242012-05-21 16:46:11 -070046using testing::AnyNumber;
Darin Petkovba40dd32011-07-11 20:06:39 -070047using testing::AtLeast;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010048using testing::DefaultValue;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080049using testing::DoAll;
Paul Stewartbc6e7392012-05-24 07:07:48 -070050using testing::HasSubstr;
Paul Stewart81426132012-05-16 10:05:10 -070051using testing::Mock;
Darin Petkovba40dd32011-07-11 20:06:39 -070052using testing::NiceMock;
53using testing::Return;
Paul Stewart10241e32012-04-23 18:15:06 -070054using testing::ReturnRef;
Darin Petkovba40dd32011-07-11 20:06:39 -070055using testing::StrictMock;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080056using testing::SetArgumentPointee;
Darin Petkovba40dd32011-07-11 20:06:39 -070057using testing::Test;
Paul Stewart9f32d192012-01-30 20:37:50 -080058using testing::Values;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070059
60namespace shill {
61
62class ServiceTest : public PropertyStoreTest {
63 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070064 ServiceTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080065 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
Chris Masone2176a882011-09-14 22:29:15 -070066 service_(new ServiceUnderTest(control_interface(),
67 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080068 metrics(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070069 &mock_manager_)),
mukesh agrawal43970a22013-02-15 16:00:07 -080070 service2_(new ServiceUnderTest(control_interface(),
71 dispatcher(),
72 metrics(),
73 &mock_manager_)),
Darin Petkovcb0b5662012-12-13 09:59:44 +010074 storage_id_(ServiceUnderTest::kStorageId),
Paul Stewartc43cbbe2013-04-11 06:29:30 -070075 power_manager_(new MockPowerManager(NULL, &proxy_factory_)),
76 eap_(new MockEapCredentials()) {
Darin Petkov385b9bc2012-12-03 15:25:05 +010077 service_->time_ = &time_;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010078 DefaultValue<Timestamp>::Set(Timestamp());
Darin Petkov385b9bc2012-12-03 15:25:05 +010079 service_->diagnostics_reporter_ = &diagnostics_reporter_;
Paul Stewartc43cbbe2013-04-11 06:29:30 -070080 service_->eap_.reset(eap_); // Passes ownership.
Darin Petkovcb0b5662012-12-13 09:59:44 +010081 mock_manager_.running_ = true;
82 mock_manager_.set_power_manager(power_manager_); // Passes ownership.
Chris Masone9d779932011-08-25 16:33:41 -070083 }
Chris Masoneb925cc82011-06-22 15:39:57 -070084
Chris Masone3bd3c8c2011-06-13 08:20:26 -070085 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -070086
Eric Shienbrood9a245532012-03-07 14:20:39 -050087 MOCK_METHOD1(TestCallback, void(const Error &error));
88
Chris Masoneb925cc82011-06-22 15:39:57 -070089 protected:
mukesh agrawalcf24a242012-05-21 16:46:11 -070090 typedef scoped_refptr<MockProfile> MockProfileRefPtr;
Eric Shienbrood9a245532012-03-07 14:20:39 -050091
Darin Petkovcb0b5662012-12-13 09:59:44 +010092 class TestProxyFactory : public ProxyFactory {
93 public:
94 TestProxyFactory() {}
95
96 virtual PowerManagerProxyInterface *CreatePowerManagerProxy(
97 PowerManagerProxyDelegate *delegate) {
98 return NULL;
99 }
100
101 private:
102 DISALLOW_COPY_AND_ASSIGN(TestProxyFactory);
103 };
104
Darin Petkovaba89322013-03-11 14:48:22 +0100105 ServiceMockAdaptor *GetAdaptor() {
106 return dynamic_cast<ServiceMockAdaptor *>(service_->adaptor());
107 }
108
Darin Petkov457728b2013-01-09 09:49:08 +0100109 string GetFriendlyName() { return service_->friendly_name(); }
110
Darin Petkovcb0b5662012-12-13 09:59:44 +0100111 void SetManagerRunning(bool running) { mock_manager_.running_ = running; }
112
113 void SetPowerState(PowerManager::SuspendState state) {
114 power_manager_->power_state_ = state;
115 }
116
Darin Petkov385b9bc2012-12-03 15:25:05 +0100117 void SetExplicitlyDisconnected(bool explicitly) {
118 service_->explicitly_disconnected_ = explicitly;
119 }
120
121 void SetStateField(Service::ConnectState state) { service_->state_ = state; }
122
Darin Petkovc8d91e52013-01-21 11:43:47 +0100123 Service::ConnectState GetPreviousState() const {
124 return service_->previous_state_;
125 }
126
Darin Petkov385b9bc2012-12-03 15:25:05 +0100127 void NoteDisconnectEvent() {
128 service_->NoteDisconnectEvent();
129 }
130
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100131 deque<Timestamp> *GetDisconnects() {
132 return &service_->disconnects_;
133 }
134 deque<Timestamp> *GetMisconnects() {
135 return &service_->misconnects_;
136 }
137
138 Timestamp GetTimestamp(int monotonic_seconds, const string &wall_clock) {
139 struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 };
140 return Timestamp(monotonic, wall_clock);
141 }
142
143 void PushTimestamp(deque<Timestamp> *timestamps,
144 int monotonic_seconds,
145 const string &wall_clock) {
146 timestamps->push_back(GetTimestamp(monotonic_seconds, wall_clock));
147 }
Darin Petkov385b9bc2012-12-03 15:25:05 +0100148
149 int GetDisconnectsMonitorSeconds() {
150 return Service::kDisconnectsMonitorSeconds;
151 }
152
153 int GetMisconnectsMonitorSeconds() {
154 return Service::kMisconnectsMonitorSeconds;
155 }
156
157 int GetReportDisconnectsThreshold() {
158 return Service::kReportDisconnectsThreshold;
159 }
160
161 int GetReportMisconnectsThreshold() {
162 return Service::kReportMisconnectsThreshold;
163 }
164
165 int GetMaxDisconnectEventHistory() {
166 return Service::kMaxDisconnectEventHistory;
167 }
168
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100169 static Strings ExtractWallClockToStrings(const deque<Timestamp> &timestamps) {
170 return Service::ExtractWallClockToStrings(timestamps);
171 }
172
Darin Petkov36d962d2013-03-25 13:03:14 +0100173 bool GetAutoConnect(Error *error) {
174 return service_->GetAutoConnect(error);
175 }
176
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700177 bool SetAutoConnectFull(bool connect, Error *error) {
178 return service_->SetAutoConnectFull(connect, error);
Darin Petkov36d962d2013-03-25 13:03:14 +0100179 }
180
Paul Stewart03dba0b2011-08-22 16:32:45 -0700181 MockManager mock_manager_;
Darin Petkov385b9bc2012-12-03 15:25:05 +0100182 MockDiagnosticsReporter diagnostics_reporter_;
183 MockTime time_;
Paul Stewart03dba0b2011-08-22 16:32:45 -0700184 scoped_refptr<ServiceUnderTest> service_;
mukesh agrawal43970a22013-02-15 16:00:07 -0800185 scoped_refptr<ServiceUnderTest> service2_;
Chris Masone34af2182011-08-22 11:59:36 -0700186 string storage_id_;
Darin Petkovcb0b5662012-12-13 09:59:44 +0100187 TestProxyFactory proxy_factory_;
188 MockPowerManager *power_manager_; // Owned by |mock_manager_|.
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700189 MockEapCredentials *eap_; // Owned by |service_|.
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700190};
191
Christopher Wiley0801d192012-09-24 11:57:15 -0700192class AllMockServiceTest : public testing::Test {
193 public:
194 AllMockServiceTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800195 : metrics_(&dispatcher_),
196 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Christopher Wiley0801d192012-09-24 11:57:15 -0700197 service_(new ServiceUnderTest(&control_interface_,
198 &dispatcher_,
199 &metrics_,
200 &manager_)) { }
201 virtual ~AllMockServiceTest() {}
202
203 protected:
204 MockControl control_interface_;
205 StrictMock<MockEventDispatcher> dispatcher_;
206 MockGLib glib_;
207 NiceMock<MockMetrics> metrics_;
208 MockManager manager_;
209 scoped_refptr<ServiceUnderTest> service_;
210};
211
Darin Petkovba40dd32011-07-11 20:06:39 -0700212TEST_F(ServiceTest, Constructor) {
213 EXPECT_TRUE(service_->save_credentials_);
214 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400215 EXPECT_EQ(Service::kStateIdle, service_->state());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700216 EXPECT_FALSE(service_->has_ever_connected());
Darin Petkovba40dd32011-07-11 20:06:39 -0700217}
218
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200219TEST_F(ServiceTest, CalculateState) {
220 service_->state_ = Service::kStateConnected;
221 Error error;
222 EXPECT_EQ(flimflam::kStateReady, service_->CalculateState(&error));
223 EXPECT_TRUE(error.IsSuccess());
224}
225
226TEST_F(ServiceTest, CalculateTechnology) {
227 service_->technology_ = Technology::kWifi;
228 Error error;
229 EXPECT_EQ(flimflam::kTypeWifi, service_->CalculateTechnology(&error));
230 EXPECT_TRUE(error.IsSuccess());
231}
232
Chris Masonea8a2c252011-06-27 22:16:30 -0700233TEST_F(ServiceTest, GetProperties) {
234 map<string, ::DBus::Variant> props;
235 Error error(Error::kInvalidProperty, "");
236 {
237 ::DBus::Error dbus_error;
Paul Stewartd215af62012-04-24 23:25:50 -0700238 string expected("true");
mukesh agrawalde29fa82011-09-16 16:16:36 -0700239 service_->mutable_store()->SetStringProperty(flimflam::kCheckPortalProperty,
240 expected,
241 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700242 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700243 ASSERT_FALSE(props.find(flimflam::kCheckPortalProperty) == props.end());
244 EXPECT_EQ(props[flimflam::kCheckPortalProperty].reader().get_string(),
245 expected);
246 }
247 {
248 ::DBus::Error dbus_error;
249 bool expected = true;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700250 service_->mutable_store()->SetBoolProperty(flimflam::kAutoConnectProperty,
251 expected,
252 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700253 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700254 ASSERT_FALSE(props.find(flimflam::kAutoConnectProperty) == props.end());
255 EXPECT_EQ(props[flimflam::kAutoConnectProperty].reader().get_bool(),
256 expected);
257 }
258 {
259 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700260 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700261 ASSERT_FALSE(props.find(flimflam::kConnectableProperty) == props.end());
262 EXPECT_EQ(props[flimflam::kConnectableProperty].reader().get_bool(), false);
263 }
264 {
265 ::DBus::Error dbus_error;
266 int32 expected = 127;
mukesh agrawalde29fa82011-09-16 16:16:36 -0700267 service_->mutable_store()->SetInt32Property(flimflam::kPriorityProperty,
268 expected,
269 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700270 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masonea8a2c252011-06-27 22:16:30 -0700271 ASSERT_FALSE(props.find(flimflam::kPriorityProperty) == props.end());
272 EXPECT_EQ(props[flimflam::kPriorityProperty].reader().get_int32(),
273 expected);
274 }
Chris Masone95207da2011-06-29 16:50:49 -0700275 {
276 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700277 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Chris Masone95207da2011-06-29 16:50:49 -0700278 ASSERT_FALSE(props.find(flimflam::kDeviceProperty) == props.end());
Jason Glasgowacdc11f2012-03-30 14:12:22 -0400279 EXPECT_EQ(props[flimflam::kDeviceProperty].reader().get_path(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700280 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700281 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700282}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700283
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800284TEST_F(ServiceTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700285 {
286 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800287 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
288 flimflam::kSaveCredentialsProperty,
289 PropertyStoreTest::kBoolV,
290 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700291 }
292 {
293 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700294 ::DBus::Variant priority;
295 priority.writer().append_int32(1);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800296 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
297 flimflam::kPriorityProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700298 priority,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800299 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700300 }
301 {
302 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700303 ::DBus::Variant guid;
304 guid.writer().append_string("not default");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800305 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700306 flimflam::kGuidProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700307 guid,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700308 &error));
309 }
310 // Ensure that EAP properties cannot be set on services with no EAP
311 // credentials. Use service2_ here since we're have some code in
312 // ServiceTest::SetUp() that fiddles with service_->eap_.
313 {
314 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700315 ::DBus::Variant eap;
316 eap.writer().append_string("eap eep eip!");
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700317 EXPECT_FALSE(DBusAdaptor::SetProperty(service2_->mutable_store(),
318 flimflam::kEAPEAPProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700319 eap,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700320 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700321 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700322 EXPECT_EQ(invalid_prop(), error.name());
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700323 // Now plumb in eap credentials, and try again.
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700324 service2_->SetEapCredentials(new EapCredentials());
325 EXPECT_TRUE(DBusAdaptor::SetProperty(service2_->mutable_store(),
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800326 flimflam::kEAPEAPProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700327 eap,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800328 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700329 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700330 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700331 {
332 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800333 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
334 flimflam::kFavoriteProperty,
335 PropertyStoreTest::kBoolV,
336 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700337 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700338 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700339 }
Thieu Le284fe792012-01-31 17:53:19 -0800340 {
341 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700342 ::DBus::Variant auto_connect;
343 auto_connect.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800344 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
345 flimflam::kAutoConnectProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700346 auto_connect,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800347 &error));
Thieu Le284fe792012-01-31 17:53:19 -0800348 }
Paul Stewart0c438332012-04-11 07:55:27 -0700349 // Ensure that we can perform a trivial set of the Name property (to its
350 // current value) but an attempt to set the property to a different value
351 // fails.
352 {
353 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700354 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
355 flimflam::kNameProperty,
356 DBusAdaptor::StringToVariant(
357 GetFriendlyName()),
358 &error));
359 EXPECT_FALSE(error.is_set());
Paul Stewart0c438332012-04-11 07:55:27 -0700360 }
361 {
362 ::DBus::Error error;
363 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
364 flimflam::kNameProperty,
365 PropertyStoreTest::kStringV,
366 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700367 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewart0c438332012-04-11 07:55:27 -0700368 EXPECT_EQ(invalid_args(), error.name());
369 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700370}
371
Paul Stewarte7de2942013-04-25 17:07:31 -0700372TEST_F(ServiceTest, GetLoadableStorageIdentifier) {
373 NiceMock<MockStore> storage;
374 EXPECT_CALL(storage, ContainsGroup(storage_id_))
375 .WillOnce(Return(false))
376 .WillOnce(Return(true));
377 EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage));
378 EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage));
379}
380
381TEST_F(ServiceTest, IsLoadableFrom) {
382 NiceMock<MockStore> storage;
383 EXPECT_CALL(storage, ContainsGroup(storage_id_))
384 .WillOnce(Return(false))
385 .WillOnce(Return(true));
386 EXPECT_FALSE(service_->IsLoadableFrom(storage));
387 EXPECT_TRUE(service_->IsLoadableFrom(storage));
388}
389
Darin Petkovba40dd32011-07-11 20:06:39 -0700390TEST_F(ServiceTest, Load) {
391 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700392 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700393 const string kCheckPortal("check-portal");
394 const string kGUID("guid");
395 const int kPriority = 20;
396 const string kProxyConfig("proxy-config");
397 const string kUIData("ui-data");
398 EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber());
399 EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber());
400 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _))
401 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true)));
402 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _))
403 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true)));
404 EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _))
405 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true)));
406 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _))
407 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true)));
408 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _))
409 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true)));
Darin Petkov0debec02013-01-22 10:40:05 +0100410 EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber());
411 EXPECT_CALL(storage,
412 GetBool(storage_id_, Service::kStorageSaveCredentials, _));
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700413 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Chris Masone9d779932011-08-25 16:33:41 -0700414 EXPECT_TRUE(service_->Load(&storage));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700415
416 EXPECT_EQ(kCheckPortal, service_->check_portal_);
417 EXPECT_EQ(kGUID, service_->guid_);
418 EXPECT_EQ(kProxyConfig, service_->proxy_config_);
419 EXPECT_EQ(kUIData, service_->ui_data_);
420
421 Mock::VerifyAndClearExpectations(&storage);
422 Mock::VerifyAndClearExpectations(eap_);
423
424 // Assure that parameters are set to default if not available in the profile.
425 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
426 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
427 .WillRepeatedly(Return(false));
428 EXPECT_CALL(storage, GetString(storage_id_, _, _))
429 .WillRepeatedly(Return(false));
430 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
431 .WillRepeatedly(Return(false));
432 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
433 EXPECT_TRUE(service_->Load(&storage));
434
435 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
436 EXPECT_EQ("", service_->guid_);
437 EXPECT_EQ("", service_->proxy_config_);
438 EXPECT_EQ("", service_->ui_data_);
Darin Petkovba40dd32011-07-11 20:06:39 -0700439}
440
441TEST_F(ServiceTest, LoadFail) {
442 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700443 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700444 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700445}
446
447TEST_F(ServiceTest, SaveString) {
448 MockStore storage;
449 static const char kKey[] = "test-key";
450 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700451 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700452 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700453 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700454}
455
456TEST_F(ServiceTest, SaveStringCrypted) {
457 MockStore storage;
458 static const char kKey[] = "test-key";
459 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700460 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700461 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700462 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700463}
464
465TEST_F(ServiceTest, SaveStringDontSave) {
466 MockStore storage;
467 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700468 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700469 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700470 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700471}
472
473TEST_F(ServiceTest, SaveStringEmpty) {
474 MockStore storage;
475 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700476 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700477 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700478 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700479}
480
481TEST_F(ServiceTest, Save) {
482 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700483 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700484 .Times(AtLeast(1))
485 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700486 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700487 .Times(AtLeast(1))
488 .WillRepeatedly(Return(true));
Darin Petkov0debec02013-01-22 10:40:05 +0100489 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
490 EXPECT_CALL(storage,
491 SetBool(storage_id_,
492 Service::kStorageSaveCredentials,
493 service_->save_credentials()));
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700494 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true));
Chris Masone9d779932011-08-25 16:33:41 -0700495 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700496}
497
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800498TEST_F(ServiceTest, Unload) {
499 NiceMock<MockStore> storage;
500 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
501 static const string string_value("value");
502 EXPECT_CALL(storage, GetString(storage_id_, _, _))
503 .Times(AtLeast(1))
504 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
Paul Stewart88769de2012-09-21 13:14:36 -0700505 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
506 .Times(AtLeast(1))
507 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
508 EXPECT_FALSE(service_->explicitly_disconnected_);
509 service_->explicitly_disconnected_ = true;
510 EXPECT_FALSE(service_->has_ever_connected_);
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700511 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800512 ASSERT_TRUE(service_->Load(&storage));
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700513 // TODO(pstew): Only two string properties in the service are tested as
mukesh agrawalcf24a242012-05-21 16:46:11 -0700514 // a sentinel that properties are being set and reset at the right times.
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800515 // However, since property load/store is essentially a manual process,
516 // it is error prone and should either be exhaustively unit-tested or
517 // a generic framework for registering loaded/stored properties should
Paul Stewartee6b3d72013-07-12 16:07:51 -0700518 // be created. crbug.com/207798
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800519 EXPECT_EQ(string_value, service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700520 EXPECT_EQ(string_value, service_->guid_);
Paul Stewart88769de2012-09-21 13:14:36 -0700521 EXPECT_FALSE(service_->explicitly_disconnected_);
522 EXPECT_TRUE(service_->has_ever_connected_);
523 service_->explicitly_disconnected_ = true;
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700524 EXPECT_CALL(*eap_, Reset());
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800525 service_->Unload();
526 EXPECT_EQ(string(""), service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700527 EXPECT_EQ(string(""), service_->guid_);
Philipp Neubeckf883a7b2012-09-14 19:52:44 +0200528 EXPECT_FALSE(service_->explicitly_disconnected_);
Paul Stewart88769de2012-09-21 13:14:36 -0700529 EXPECT_FALSE(service_->has_ever_connected_);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800530}
531
Paul Stewart03dba0b2011-08-22 16:32:45 -0700532TEST_F(ServiceTest, State) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400533 EXPECT_EQ(Service::kStateIdle, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100534 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700535 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700536 const string unknown_error(
537 Service::ConnectFailureToString(Service::kFailureUnknown));
538 EXPECT_EQ(unknown_error, service_->error());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700539
mukesh agrawal00917ce2011-11-22 23:56:55 +0000540 ServiceRefPtr service_ref(service_);
mukesh agrawalf2f68a52011-09-01 12:15:48 -0700541
Darin Petkovaba89322013-03-11 14:48:22 +0100542 EXPECT_CALL(*GetAdaptor(),
Wade Guthriecb094352013-05-08 15:24:59 -0700543 EmitStringChanged(flimflam::kStateProperty, _)).Times(6);
Darin Petkovaba89322013-03-11 14:48:22 +0100544 EXPECT_CALL(*GetAdaptor(),
Paul Stewartf2d60912012-07-15 08:37:30 -0700545 EmitStringChanged(flimflam::kErrorProperty, _)).Times(4);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700546 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
547 service_->SetState(Service::kStateConnected);
Darin Petkovc8d91e52013-01-21 11:43:47 +0100548 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700549 // A second state change shouldn't cause another update
550 service_->SetState(Service::kStateConnected);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700551 EXPECT_EQ(Service::kStateConnected, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100552 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700553 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700554 EXPECT_TRUE(service_->has_ever_connected_);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800555
Paul Stewart03dba0b2011-08-22 16:32:45 -0700556 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700557 service_->SetFailure(Service::kFailureOutOfRange);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800558 EXPECT_TRUE(service_->IsFailed());
559 EXPECT_GT(service_->failed_time_, 0);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700560 EXPECT_EQ(Service::kStateFailure, service_->state());
561 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700562 const string out_of_range_error(
563 Service::ConnectFailureToString(Service::kFailureOutOfRange));
564 EXPECT_EQ(out_of_range_error, service_->error());
mukesh agrawal568b5c62012-02-28 14:44:47 -0800565
566 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
567 service_->SetState(Service::kStateConnected);
568 EXPECT_FALSE(service_->IsFailed());
569 EXPECT_EQ(service_->failed_time_, 0);
Paul Stewartf2d60912012-07-15 08:37:30 -0700570 EXPECT_EQ(unknown_error, service_->error());
mukesh agrawal568b5c62012-02-28 14:44:47 -0800571
572 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
573 service_->SetFailureSilent(Service::kFailurePinMissing);
574 EXPECT_TRUE(service_->IsFailed());
575 EXPECT_GT(service_->failed_time_, 0);
576 EXPECT_EQ(Service::kStateIdle, service_->state());
577 EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700578 const string pin_missing_error(
579 Service::ConnectFailureToString(Service::kFailurePinMissing));
580 EXPECT_EQ(pin_missing_error, service_->error());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700581
582 // If the Service has a Profile, the profile should be saved when
583 // the service enters kStateConnected. (The case where the service
584 // doesn't have a profile is tested above.)
585 MockProfileRefPtr mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800586 new MockProfile(control_interface(), metrics(), &mock_manager_));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700587 NiceMock<MockStore> storage;
588 service_->set_profile(mock_profile);
589 service_->has_ever_connected_ = false;
590 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
591 EXPECT_CALL(*mock_profile, GetConstStorage())
592 .WillOnce(Return(&storage));
593 EXPECT_CALL(*mock_profile, UpdateService(service_ref));
594 service_->SetState(Service::kStateConnected);
595 EXPECT_TRUE(service_->has_ever_connected_);
596 service_->set_profile(NULL); // Break reference cycle.
597
598 // Similar to the above, but emulate an emphemeral profile, which
599 // has no storage. We can't update the service in the profile, but
600 // we should not crash.
601 service_->state_ = Service::kStateIdle; // Skips state change logic.
602 service_->set_profile(mock_profile);
603 service_->has_ever_connected_ = false;
604 EXPECT_CALL(mock_manager_, UpdateService(service_ref));
605 EXPECT_CALL(*mock_profile, GetConstStorage()).
606 WillOnce(Return(static_cast<StoreInterface *>(NULL)));
607 service_->SetState(Service::kStateConnected);
608 EXPECT_TRUE(service_->has_ever_connected_);
609 service_->set_profile(NULL); // Break reference cycle.
Paul Stewart03dba0b2011-08-22 16:32:45 -0700610}
611
Thieu Leaf471412013-06-27 14:12:37 -0700612TEST_F(ServiceTest, StateResetAfterFailure) {
613 service_->SetFailure(Service::kFailureOutOfRange);
614 EXPECT_EQ(Service::kStateFailure, service_->state());
615 Error error;
616 service_->Connect(&error, "in test");
617 EXPECT_EQ(Service::kStateIdle, service_->state());
618 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
619
620 service_->SetState(Service::kStateConnected);
621 service_->Connect(&error, "in test");
622 EXPECT_EQ(Service::kStateConnected, service_->state());
623}
624
Darin Petkovb100ae72011-08-24 16:19:45 -0700625TEST_F(ServiceTest, ActivateCellularModem) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500626 ResultCallback callback =
627 Bind(&ServiceTest::TestCallback, Unretained(this));
628 EXPECT_CALL(*this, TestCallback(_)).Times(0);
Darin Petkovb100ae72011-08-24 16:19:45 -0700629 Error error;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500630 service_->ActivateCellularModem("Carrier", &error, callback);
631 EXPECT_TRUE(error.IsFailure());
Darin Petkovb100ae72011-08-24 16:19:45 -0700632}
633
Ben Chan5d924542013-02-14 17:49:08 -0800634TEST_F(ServiceTest, CompleteCellularActivation) {
635 Error error;
636 service_->CompleteCellularActivation(&error);
637 EXPECT_EQ(Error::kNotSupported, error.type());
638}
639
mukesh agrawal00917ce2011-11-22 23:56:55 +0000640TEST_F(ServiceTest, MakeFavorite) {
641 EXPECT_FALSE(service_->favorite());
642 EXPECT_FALSE(service_->auto_connect());
643
644 service_->MakeFavorite();
645 EXPECT_TRUE(service_->favorite());
646 EXPECT_TRUE(service_->auto_connect());
647}
648
649TEST_F(ServiceTest, ReMakeFavorite) {
650 service_->MakeFavorite();
651 EXPECT_TRUE(service_->favorite());
652 EXPECT_TRUE(service_->auto_connect());
653
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700654 service_->SetAutoConnect(false);
mukesh agrawal00917ce2011-11-22 23:56:55 +0000655 service_->MakeFavorite();
656 EXPECT_TRUE(service_->favorite());
657 EXPECT_FALSE(service_->auto_connect());
658}
659
mukesh agrawal76d13882012-01-12 15:23:11 -0800660TEST_F(ServiceTest, IsAutoConnectable) {
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100661 const char *reason = NULL;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700662 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100663
664 // Services with non-primary connectivity technologies should not auto-connect
665 // when the system is offline.
666 EXPECT_EQ(Technology::kUnknown, service_->technology());
667 EXPECT_CALL(mock_manager_, IsOnline()).WillOnce(Return(false));
668 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
669 EXPECT_STREQ(Service::kAutoConnOffline, reason);
670
671 service_->technology_ = Technology::kEthernet;
mukesh agrawalbf14e942012-03-02 14:36:34 -0800672 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawal76d13882012-01-12 15:23:11 -0800673
mukesh agrawaladb68482012-01-17 16:31:51 -0800674 // We should not auto-connect to a Service that a user has
675 // deliberately disconnected.
676 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -0700677 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800678 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
679 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
mukesh agrawaladb68482012-01-17 16:31:51 -0800680
681 // But if the Service is reloaded, it is eligible for auto-connect
682 // again.
683 NiceMock<MockStore> storage;
684 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700685 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
mukesh agrawaladb68482012-01-17 16:31:51 -0800686 EXPECT_TRUE(service_->Load(&storage));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800687 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800688
689 // A deliberate Connect should also re-enable auto-connect.
Christopher Wileyabd3b502012-09-26 13:08:52 -0700690 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800691 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700692 service_->Connect(&error, "in test");
mukesh agrawalbf14e942012-03-02 14:36:34 -0800693 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800694
Christopher Wileyabd3b502012-09-26 13:08:52 -0700695 // A non-user initiated Disconnect doesn't change anything.
696 service_->Disconnect(&error);
697 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
698
Christopher Wileya4c61ae2012-10-01 11:04:30 -0700699 // A resume also re-enables auto-connect.
700 service_->UserInitiatedDisconnect(&error);
701 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
702 service_->OnAfterResume();
703 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -0800704
mukesh agrawal76d13882012-01-12 15:23:11 -0800705 service_->SetState(Service::kStateConnected);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800706 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
707 EXPECT_STREQ(Service::kAutoConnConnected, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -0800708
709 service_->SetState(Service::kStateAssociating);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800710 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
711 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -0800712}
713
mukesh agrawal03c15ce2012-11-29 17:36:21 -0800714TEST_F(ServiceTest, AutoConnectLogging) {
715 ScopedMockLog log;
716 EXPECT_CALL(log, Log(_, _, _));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700717 service_->SetConnectable(true);
mukesh agrawal03c15ce2012-11-29 17:36:21 -0800718
719 ScopeLogger::GetInstance()->EnableScopesByName("+service");
720 ScopeLogger::GetInstance()->set_verbose_level(1);
721 service_->SetState(Service::kStateConnected);
722 EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected)));
723 service_->AutoConnect();
724
725 ScopeLogger::GetInstance()->EnableScopesByName("-service");
726 ScopeLogger::GetInstance()->set_verbose_level(0);
727 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
728 HasSubstr(Service::kAutoConnNotConnectable)));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700729 service_->SetConnectable(false);
mukesh agrawal03c15ce2012-11-29 17:36:21 -0800730 service_->AutoConnect();
731}
732
733
Christopher Wiley0801d192012-09-24 11:57:15 -0700734TEST_F(AllMockServiceTest, AutoConnectWithFailures) {
735 const char *reason;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700736 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100737 service_->technology_ = Technology::kEthernet;
Christopher Wiley0801d192012-09-24 11:57:15 -0700738 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
739
740 // The very first AutoConnect() doesn't trigger any throttling.
741 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
742 service_->AutoConnect();
743 Mock::VerifyAndClearExpectations(&dispatcher_);
744 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
745
746 // The second call does trigger some throttling.
747 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
748 Service::kMinAutoConnectCooldownTimeMilliseconds));
749 service_->AutoConnect();
750 Mock::VerifyAndClearExpectations(&dispatcher_);
751 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
752 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
753
754 // Calling AutoConnect() again before the cooldown terminates does not change
755 // the timeout.
756 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
757 service_->AutoConnect();
758 Mock::VerifyAndClearExpectations(&dispatcher_);
759 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
760 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
761
762 // Once the timeout expires, we can AutoConnect() again.
763 service_->ReEnableAutoConnectTask();
764 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
765
766 // Timeouts increase exponentially.
767 uint64 next_cooldown_time = service_->auto_connect_cooldown_milliseconds_;
768 EXPECT_EQ(next_cooldown_time,
769 Service::kAutoConnectCooldownBackoffFactor *
770 Service::kMinAutoConnectCooldownTimeMilliseconds);
771 while (next_cooldown_time <=
772 Service::kMaxAutoConnectCooldownTimeMilliseconds) {
773 EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time));
774 service_->AutoConnect();
775 Mock::VerifyAndClearExpectations(&dispatcher_);
776 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
777 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
778 service_->ReEnableAutoConnectTask();
779 next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor;
780 }
781
782 // Once we hit our cap, future timeouts are the same.
783 for (int32 i = 0; i < 2; i++) {
784 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
785 Service::kMaxAutoConnectCooldownTimeMilliseconds));
786 service_->AutoConnect();
787 Mock::VerifyAndClearExpectations(&dispatcher_);
788 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
789 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
790 service_->ReEnableAutoConnectTask();
791 }
792
793 // Connecting successfully resets our cooldown.
794 service_->SetState(Service::kStateConnected);
795 service_->SetState(Service::kStateIdle);
796 reason = "";
797 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
798 EXPECT_STREQ("", reason);
799 EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0);
800
801 // But future AutoConnects behave as before
802 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
803 Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1);
804 service_->AutoConnect();
805 service_->AutoConnect();
806 Mock::VerifyAndClearExpectations(&dispatcher_);
807 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
808 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
809
810 // Cooldowns are forgotten if we go through a suspend/resume cycle.
811 service_->OnAfterResume();
812 reason = "";
813 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
814 EXPECT_STREQ("", reason);
815}
816
Paul Stewartcb59fed2012-03-21 21:14:46 -0700817TEST_F(ServiceTest, ConfigureBadProperty) {
818 KeyValueStore args;
819 args.SetString("XXXInvalid", "Value");
820 Error error;
821 service_->Configure(args, &error);
822 EXPECT_FALSE(error.IsSuccess());
823}
824
825TEST_F(ServiceTest, ConfigureBoolProperty) {
826 service_->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700827 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -0700828 ASSERT_FALSE(service_->auto_connect());
829 KeyValueStore args;
830 args.SetBool(flimflam::kAutoConnectProperty, true);
831 Error error;
832 service_->Configure(args, &error);
833 EXPECT_TRUE(error.IsSuccess());
834 EXPECT_TRUE(service_->auto_connect());
835}
836
837TEST_F(ServiceTest, ConfigureStringProperty) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700838 const string kGuid0 = "guid_zero";
839 const string kGuid1 = "guid_one";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700840 service_->SetGuid(kGuid0, NULL);
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700841 ASSERT_EQ(kGuid0, service_->guid());
Paul Stewartcb59fed2012-03-21 21:14:46 -0700842 KeyValueStore args;
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700843 args.SetString(flimflam::kGuidProperty, kGuid1);
Paul Stewartcb59fed2012-03-21 21:14:46 -0700844 Error error;
845 service_->Configure(args, &error);
846 EXPECT_TRUE(error.IsSuccess());
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700847 EXPECT_EQ(kGuid1, service_->guid());
848}
849
Paul Stewart99dc9f32013-06-27 07:39:25 -0700850TEST_F(ServiceTest, ConfigureStringsProperty) {
851 const vector<string> kStrings0{ "string0", "string1" };
852 const vector<string> kStrings1{ "string2", "string3" };
853 service_->set_strings(kStrings0);
854 ASSERT_EQ(kStrings0, service_->strings());
855 KeyValueStore args;
856 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
857 Error error;
858 service_->Configure(args, &error);
859 EXPECT_TRUE(error.IsSuccess());
860 EXPECT_EQ(kStrings1, service_->strings());
861}
862
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700863TEST_F(ServiceTest, ConfigureEapStringProperty) {
864 MockEapCredentials *eap = new MockEapCredentials();
865 service2_->SetEapCredentials(eap); // Passes ownership.
866
867 const string kEAPManagement0 = "management_zero";
868 const string kEAPManagement1 = "management_one";
869 service2_->SetEAPKeyManagement(kEAPManagement0);
870
871 EXPECT_CALL(*eap, key_management())
872 .WillOnce(ReturnRef(kEAPManagement0));
873 ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement());
874 KeyValueStore args;
875 EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _));
876 args.SetString(flimflam::kEapKeyMgmtProperty, kEAPManagement1);
877 Error error;
878 service2_->Configure(args, &error);
879 EXPECT_TRUE(error.IsSuccess());
Paul Stewartcb59fed2012-03-21 21:14:46 -0700880}
881
Paul Stewart7a20aa42013-01-17 12:21:41 -0800882TEST_F(ServiceTest, ConfigureIntProperty) {
883 const int kPriority0 = 100;
884 const int kPriority1 = 200;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700885 service_->SetPriority(kPriority0, NULL);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800886 ASSERT_EQ(kPriority0, service_->priority());
887 KeyValueStore args;
888 args.SetInt(flimflam::kPriorityProperty, kPriority1);
889 Error error;
890 service_->Configure(args, &error);
891 EXPECT_TRUE(error.IsSuccess());
892 EXPECT_EQ(kPriority1, service_->priority());
893}
894
Paul Stewartcb59fed2012-03-21 21:14:46 -0700895TEST_F(ServiceTest, ConfigureIgnoredProperty) {
896 service_->MakeFavorite();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700897 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -0700898 ASSERT_FALSE(service_->auto_connect());
899 KeyValueStore args;
900 args.SetBool(flimflam::kAutoConnectProperty, true);
901 Error error;
902 service_->IgnoreParameterForConfigure(flimflam::kAutoConnectProperty);
903 service_->Configure(args, &error);
904 EXPECT_TRUE(error.IsSuccess());
905 EXPECT_FALSE(service_->auto_connect());
906}
907
Paul Stewartad0e5982013-07-02 08:47:47 -0700908TEST_F(ServiceTest, ConfigureProfileProperty) {
909 // Ensure that the Profile property is always ignored.
910 KeyValueStore args;
911 args.SetString(flimflam::kProfileProperty, "profile");
912 Error error;
913 EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
914 service_->Configure(args, &error);
915 EXPECT_TRUE(error.IsSuccess());
916}
917
Paul Stewart7a20aa42013-01-17 12:21:41 -0800918TEST_F(ServiceTest, DoPropertiesMatch) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700919 service_->SetAutoConnect(false);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800920 const string kGUID0 = "guid_zero";
921 const string kGUID1 = "guid_one";
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700922 service_->SetGuid(kGUID0, NULL);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800923 const uint32 kPriority0 = 100;
924 const uint32 kPriority1 = 200;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700925 service_->SetPriority(kPriority0, NULL);
Paul Stewart99dc9f32013-06-27 07:39:25 -0700926 const vector<string> kStrings0{ "string0", "string1" };
927 const vector<string> kStrings1{ "string2", "string3" };
928 service_->set_strings(kStrings0);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800929
930 {
931 KeyValueStore args;
932 args.SetString(flimflam::kGuidProperty, kGUID0);
933 args.SetBool(flimflam::kAutoConnectProperty, false);
934 args.SetInt(flimflam::kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -0700935 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800936 EXPECT_TRUE(service_->DoPropertiesMatch(args));
937 }
938 {
939 KeyValueStore args;
940 args.SetString(flimflam::kGuidProperty, kGUID1);
941 args.SetBool(flimflam::kAutoConnectProperty, false);
942 args.SetInt(flimflam::kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -0700943 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800944 EXPECT_FALSE(service_->DoPropertiesMatch(args));
945 }
946 {
947 KeyValueStore args;
948 args.SetString(flimflam::kGuidProperty, kGUID0);
949 args.SetBool(flimflam::kAutoConnectProperty, true);
950 args.SetInt(flimflam::kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -0700951 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800952 EXPECT_FALSE(service_->DoPropertiesMatch(args));
953 }
954 {
955 KeyValueStore args;
956 args.SetString(flimflam::kGuidProperty, kGUID0);
957 args.SetBool(flimflam::kAutoConnectProperty, false);
958 args.SetInt(flimflam::kPriorityProperty, kPriority1);
Paul Stewart99dc9f32013-06-27 07:39:25 -0700959 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
960 EXPECT_FALSE(service_->DoPropertiesMatch(args));
961 }
962 {
963 KeyValueStore args;
964 args.SetString(flimflam::kGuidProperty, kGUID0);
965 args.SetBool(flimflam::kAutoConnectProperty, false);
966 args.SetInt(flimflam::kPriorityProperty, kPriority0);
967 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
Paul Stewart7a20aa42013-01-17 12:21:41 -0800968 EXPECT_FALSE(service_->DoPropertiesMatch(args));
969 }
970}
971
Paul Stewart10ccbb32012-04-26 15:59:30 -0700972TEST_F(ServiceTest, IsRemembered) {
973 ServiceConstRefPtr service_ref(service_);
974 service_->set_profile(NULL);
975 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
976 EXPECT_FALSE(service_->IsRemembered());
977
978 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -0800979 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Paul Stewart10ccbb32012-04-26 15:59:30 -0700980 service_->set_profile(profile);
981 EXPECT_CALL(mock_manager_, IsServiceEphemeral(service_ref))
982 .WillOnce(Return(true))
983 .WillOnce(Return(false));
984 EXPECT_FALSE(service_->IsRemembered());
985 EXPECT_TRUE(service_->IsRemembered());
986}
987
Paul Stewartdf3c0a82012-11-09 15:54:33 -0800988TEST_F(ServiceTest, IsDependentOn) {
989 EXPECT_FALSE(service_->IsDependentOn(NULL));
990
991 scoped_ptr<MockDeviceInfo> mock_device_info(
992 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
993 &mock_manager_));
994 scoped_refptr<MockConnection> mock_connection0(
995 new NiceMock<MockConnection>(mock_device_info.get()));
996 scoped_refptr<MockConnection> mock_connection1(
997 new NiceMock<MockConnection>(mock_device_info.get()));
998
999 service_->connection_ = mock_connection0;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001000 EXPECT_CALL(*mock_connection0, GetLowerConnection())
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001001 .WillRepeatedly(Return(mock_connection1));
Paul Stewartcd7f5852013-03-27 13:54:23 -07001002 EXPECT_CALL(*mock_connection1, GetLowerConnection())
1003 .WillRepeatedly(Return(ConnectionRefPtr()));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001004 EXPECT_FALSE(service_->IsDependentOn(NULL));
1005
1006 scoped_refptr<ServiceUnderTest> service1 =
1007 new ServiceUnderTest(control_interface(),
1008 dispatcher(),
1009 metrics(),
1010 &mock_manager_);
1011 EXPECT_FALSE(service_->IsDependentOn(service1));
1012
1013 service1->connection_ = mock_connection0;
1014 EXPECT_FALSE(service_->IsDependentOn(service1));
1015
1016 service1->connection_ = mock_connection1;
1017 EXPECT_TRUE(service_->IsDependentOn(service1));
1018
Paul Stewartcd7f5852013-03-27 13:54:23 -07001019 service_->connection_ = mock_connection1;
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001020 service1->connection_ = NULL;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001021 EXPECT_FALSE(service_->IsDependentOn(service1));
1022
1023 service_->connection_ = NULL;
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001024}
1025
Paul Stewartff14b022012-04-24 20:06:23 -07001026TEST_F(ServiceTest, OnPropertyChanged) {
1027 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001028 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Paul Stewartff14b022012-04-24 20:06:23 -07001029 service_->set_profile(NULL);
1030 // Expect no crash.
1031 service_->OnPropertyChanged("");
1032
1033 // Expect no call to Update if the profile has no storage.
1034 service_->set_profile(profile);
1035 EXPECT_CALL(*profile, UpdateService(_)).Times(0);
1036 EXPECT_CALL(*profile, GetConstStorage())
1037 .WillOnce(Return(reinterpret_cast<StoreInterface *>(NULL)));
1038 service_->OnPropertyChanged("");
1039
1040 // Expect call to Update if the profile has storage.
1041 EXPECT_CALL(*profile, UpdateService(_)).Times(1);
1042 NiceMock<MockStore> storage;
1043 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
1044 service_->OnPropertyChanged("");
1045}
1046
Paul Stewartd215af62012-04-24 23:25:50 -07001047
1048TEST_F(ServiceTest, RecheckPortal) {
1049 ServiceRefPtr service_ref(service_);
1050 service_->state_ = Service::kStateIdle;
1051 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
1052 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
1053
1054 service_->state_ = Service::kStatePortal;
1055 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
1056 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
1057
1058 service_->state_ = Service::kStateConnected;
1059 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
1060 service_->OnPropertyChanged(flimflam::kProxyConfigProperty);
1061
1062 service_->state_ = Service::kStateOnline;
1063 EXPECT_CALL(mock_manager_, RecheckPortalOnService(service_ref)).Times(1);
1064 service_->OnPropertyChanged(flimflam::kCheckPortalProperty);
1065
1066 service_->state_ = Service::kStatePortal;
1067 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
1068 service_->OnPropertyChanged(flimflam::kEAPKeyIDProperty);
1069}
1070
1071TEST_F(ServiceTest, SetCheckPortal) {
1072 ServiceRefPtr service_ref(service_);
1073 {
1074 Error error;
1075 service_->SetCheckPortal("false", &error);
1076 EXPECT_TRUE(error.IsSuccess());
1077 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
1078 }
1079 {
1080 Error error;
1081 service_->SetCheckPortal("true", &error);
1082 EXPECT_TRUE(error.IsSuccess());
1083 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
1084 }
1085 {
1086 Error error;
1087 service_->SetCheckPortal("auto", &error);
1088 EXPECT_TRUE(error.IsSuccess());
1089 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1090 }
1091 {
1092 Error error;
1093 service_->SetCheckPortal("xxx", &error);
1094 EXPECT_FALSE(error.IsSuccess());
1095 EXPECT_EQ(Error::kInvalidArguments, error.type());
1096 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1097 }
1098}
1099
Arman Uguray2717a102013-01-29 23:36:06 -08001100TEST_F(ServiceTest, SetFriendlyName) {
1101 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
Darin Petkovaba89322013-03-11 14:48:22 +01001102 ServiceMockAdaptor *adaptor = GetAdaptor();
Arman Uguray2717a102013-01-29 23:36:06 -08001103
1104 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1105 service_->SetFriendlyName(service_->unique_name_);
1106 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
1107
1108 EXPECT_CALL(*adaptor, EmitStringChanged(flimflam::kNameProperty,
1109 "Test Name 1"));
1110 service_->SetFriendlyName("Test Name 1");
1111 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1112
1113 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1114 service_->SetFriendlyName("Test Name 1");
1115 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1116
1117 EXPECT_CALL(*adaptor, EmitStringChanged(flimflam::kNameProperty,
1118 "Test Name 2"));
1119 service_->SetFriendlyName("Test Name 2");
1120 EXPECT_EQ("Test Name 2", service_->friendly_name_);
1121}
1122
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001123TEST_F(ServiceTest, SetConnectableFull) {
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001124 EXPECT_FALSE(service_->connectable());
1125
Darin Petkovaba89322013-03-11 14:48:22 +01001126 ServiceMockAdaptor *adaptor = GetAdaptor();
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001127
1128 EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0);
1129 EXPECT_CALL(mock_manager_, HasService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001130 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001131 EXPECT_FALSE(service_->connectable());
1132
1133 EXPECT_CALL(*adaptor, EmitBoolChanged(flimflam::kConnectableProperty, true));
1134 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false));
1135 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001136 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001137 EXPECT_TRUE(service_->connectable());
1138
1139 EXPECT_CALL(*adaptor, EmitBoolChanged(flimflam::kConnectableProperty, false));
1140 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1141 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001142 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001143 EXPECT_FALSE(service_->connectable());
1144
1145 EXPECT_CALL(*adaptor, EmitBoolChanged(flimflam::kConnectableProperty, true));
1146 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1147 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001148 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001149 EXPECT_TRUE(service_->connectable());
1150}
1151
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001152class WriteOnlyServicePropertyTest : public ServiceTest {};
1153TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) {
1154 // Use a real EapCredentials instance since the base Service class
1155 // contains no write-only properties.
1156 EapCredentials eap;
1157 eap.InitPropertyStore(service_->mutable_store());
1158
Paul Stewart9f32d192012-01-30 20:37:50 -08001159 string property(GetParam().reader().get_string());
Paul Stewarte6e8e492013-01-17 11:00:50 -08001160 Error error;
1161 EXPECT_FALSE(service_->store().GetStringProperty(property, NULL, &error));
1162 EXPECT_EQ(Error::kPermissionDenied, error.type());
Paul Stewart9f32d192012-01-30 20:37:50 -08001163}
1164
1165INSTANTIATE_TEST_CASE_P(
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001166 WriteOnlyServicePropertyTestInstance,
1167 WriteOnlyServicePropertyTest,
Paul Stewart9f32d192012-01-30 20:37:50 -08001168 Values(
1169 DBusAdaptor::StringToVariant(flimflam::kEapPrivateKeyPasswordProperty),
1170 DBusAdaptor::StringToVariant(flimflam::kEapPasswordProperty)));
1171
Paul Stewart10241e32012-04-23 18:15:06 -07001172
1173TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
1174 {
1175 Error error;
1176 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1177 EXPECT_EQ(Error::kNotFound, error.type());
1178 }
1179
1180 scoped_ptr<MockDeviceInfo> mock_device_info(
1181 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1182 &mock_manager_));
1183 scoped_refptr<MockConnection> mock_connection(
1184 new NiceMock<MockConnection>(mock_device_info.get()));
1185
1186 service_->connection_ = mock_connection;
1187
1188 {
1189 Error error;
1190 const string empty_string;
1191 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1192 .WillOnce(ReturnRef(empty_string));
1193 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1194 EXPECT_EQ(Error::kNotFound, error.type());
1195 }
1196
1197 {
1198 Error error;
1199 const string nonempty_string("/ipconfig/path");
1200 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1201 .WillOnce(ReturnRef(nonempty_string));
1202 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
1203 EXPECT_EQ(Error::kSuccess, error.type());
1204 }
1205
1206 // Assure orderly destruction of the Connection before DeviceInfo.
1207 service_->connection_ = NULL;
1208 mock_connection = NULL;
1209 mock_device_info.reset();
1210}
1211
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001212class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest {
Paul Stewart81426132012-05-16 10:05:10 -07001213 public:
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001214 ServiceWithMockOnEapCredentialsChanged(ControlInterface *control_interface,
1215 EventDispatcher *dispatcher,
1216 Metrics *metrics,
1217 Manager *manager)
Paul Stewart81426132012-05-16 10:05:10 -07001218 : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
1219 is_8021x_(false) {}
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001220 MOCK_METHOD0(OnEapCredentialsChanged, void());
Paul Stewart81426132012-05-16 10:05:10 -07001221 virtual bool Is8021x() const { return is_8021x_; }
1222 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }
1223
1224 private:
1225 bool is_8021x_;
1226};
1227
1228TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001229 scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service(
1230 new ServiceWithMockOnEapCredentialsChanged(control_interface(),
1231 dispatcher(),
1232 metrics(),
1233 &mock_manager_));
Paul Stewart81426132012-05-16 10:05:10 -07001234 string eap_credential_properties[] = {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001235 flimflam::kEapAnonymousIdentityProperty,
Paul Stewart81426132012-05-16 10:05:10 -07001236 flimflam::kEAPCertIDProperty,
1237 flimflam::kEAPClientCertProperty,
Paul Stewart81426132012-05-16 10:05:10 -07001238 flimflam::kEapIdentityProperty,
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001239 flimflam::kEAPKeyIDProperty,
Paul Stewart81426132012-05-16 10:05:10 -07001240 flimflam::kEapPasswordProperty,
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001241 flimflam::kEAPPINProperty,
1242 flimflam::kEapPrivateKeyProperty,
1243 flimflam::kEapPrivateKeyPasswordProperty
Paul Stewart81426132012-05-16 10:05:10 -07001244 };
1245 string eap_non_credential_properties[] = {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001246 flimflam::kEapCaCertIDProperty,
1247 flimflam::kEapCaCertNssProperty,
Paul Stewart81426132012-05-16 10:05:10 -07001248 flimflam::kEAPEAPProperty,
1249 flimflam::kEapPhase2AuthProperty,
Paul Stewart81426132012-05-16 10:05:10 -07001250 flimflam::kEapUseSystemCAsProperty
1251 };
1252 // While this is not an 802.1x-based service, none of these property
1253 // changes should cause a call to set_eap().
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001254 EXPECT_CALL(*service, OnEapCredentialsChanged()).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001255 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
1256 service->OnPropertyChanged(eap_credential_properties[i]);
1257 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1258 service->OnPropertyChanged(eap_non_credential_properties[i]);
Paul Stewartadf79d82012-07-18 16:09:56 -07001259 service->OnPropertyChanged(flimflam::kEapKeyMgmtProperty);
Paul Stewart81426132012-05-16 10:05:10 -07001260
1261 service->set_is_8021x(true);
1262
1263 // When this is an 802.1x-based service, set_eap should be called for
1264 // all credential-carrying properties.
1265 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001266 EXPECT_CALL(*service, OnEapCredentialsChanged()).Times(1);
Paul Stewart81426132012-05-16 10:05:10 -07001267 service->OnPropertyChanged(eap_credential_properties[i]);
1268 Mock::VerifyAndClearExpectations(service.get());
1269 }
Paul Stewartadf79d82012-07-18 16:09:56 -07001270
1271 // The key management property is a special case. While not strictly
1272 // a credential, it can change which credentials are used. Therefore it
1273 // should also trigger a call to set_eap();
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001274 EXPECT_CALL(*service, OnEapCredentialsChanged()).Times(1);
Paul Stewartadf79d82012-07-18 16:09:56 -07001275 service->OnPropertyChanged(flimflam::kEapKeyMgmtProperty);
1276 Mock::VerifyAndClearExpectations(service.get());
1277
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001278 EXPECT_CALL(*service, OnEapCredentialsChanged()).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001279 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1280 service->OnPropertyChanged(eap_non_credential_properties[i]);
1281}
1282
Paul Stewartbc6e7392012-05-24 07:07:48 -07001283TEST_F(ServiceTest, Certification) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001284 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001285
1286 ScopedMockLog log;
1287 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1288 HasSubstr("exceeds our maximum"))).Times(2);
1289 string kSubject("foo");
1290 EXPECT_FALSE(service_->AddEAPCertification(
1291 kSubject, Service::kEAPMaxCertificationElements));
1292 EXPECT_FALSE(service_->AddEAPCertification(
1293 kSubject, Service::kEAPMaxCertificationElements + 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001294 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001295 Mock::VerifyAndClearExpectations(&log);
1296
1297 EXPECT_CALL(log,
1298 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1299 .Times(1);
1300 EXPECT_TRUE(service_->AddEAPCertification(
1301 kSubject, Service::kEAPMaxCertificationElements - 1));
1302 Mock::VerifyAndClearExpectations(&log);
1303 EXPECT_EQ(Service::kEAPMaxCertificationElements,
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001304 service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001305 for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001306 EXPECT_TRUE(service_->remote_certification_[i].empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001307 }
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001308 EXPECT_EQ(kSubject, service_->remote_certification_[
Paul Stewartbc6e7392012-05-24 07:07:48 -07001309 Service::kEAPMaxCertificationElements - 1]);
1310
1311 // Re-adding the same name in the same position should not generate a log.
1312 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1313 EXPECT_TRUE(service_->AddEAPCertification(
1314 kSubject, Service::kEAPMaxCertificationElements - 1));
1315
1316 // Replacing the item should generate a log message.
1317 EXPECT_CALL(log,
1318 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1319 .Times(1);
1320 EXPECT_TRUE(service_->AddEAPCertification(
1321 kSubject + "x", Service::kEAPMaxCertificationElements - 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001322
1323 service_->ClearEAPCertification();
1324 EXPECT_TRUE(service_->remote_certification_.empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001325}
1326
Darin Petkovc8d91e52013-01-21 11:43:47 +01001327TEST_F(ServiceTest, NoteDisconnectEventIdle) {
Paul Stewart483e4722012-12-18 10:23:17 -08001328 Timestamp timestamp;
Darin Petkovc8d91e52013-01-21 11:43:47 +01001329 EXPECT_CALL(time_, GetNow()).Times(4).WillRepeatedly((Return(timestamp)));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001330 SetStateField(Service::kStateOnline);
Darin Petkov0857f8e2012-12-21 10:49:17 +01001331 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001332 service_->SetState(Service::kStateIdle);
Darin Petkovc8d91e52013-01-21 11:43:47 +01001333 // The transition Online->Idle is not an event.
Darin Petkov0857f8e2012-12-21 10:49:17 +01001334 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkovc8d91e52013-01-21 11:43:47 +01001335 service_->SetState(Service::kStateFailure);
1336 // The transition Online->Idle->Failure is a connection drop.
1337 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov0857f8e2012-12-21 10:49:17 +01001338}
1339
1340TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) {
1341 Timestamp timestamp;
1342 EXPECT_CALL(time_, GetNow()).Times(3).WillRepeatedly((Return(timestamp)));
1343 SetStateField(Service::kStateOnline);
1344 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1345 service_->SetState(Service::kStateFailure);
1346 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1347}
1348
1349TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) {
1350 Timestamp timestamp;
1351 EXPECT_CALL(time_, GetNow()).Times(3).WillRepeatedly((Return(timestamp)));
1352 SetStateField(Service::kStateConfiguring);
1353 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1354 service_->SetFailureSilent(Service::kFailureEAPAuthentication);
Paul Stewart483e4722012-12-18 10:23:17 -08001355 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001356}
1357
1358TEST_F(ServiceTest, NoteDisconnectEventNonEvent) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001359 EXPECT_CALL(time_, GetNow()).Times(0);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001360 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1361
1362 // Explicit disconnect is a non-event.
1363 SetStateField(Service::kStateOnline);
1364 SetExplicitlyDisconnected(true);
1365 NoteDisconnectEvent();
1366 EXPECT_TRUE(GetDisconnects()->empty());
1367 EXPECT_TRUE(GetMisconnects()->empty());
1368
1369 // Failure to idle transition is a non-event.
1370 SetStateField(Service::kStateFailure);
1371 SetExplicitlyDisconnected(false);
1372 NoteDisconnectEvent();
1373 EXPECT_TRUE(GetDisconnects()->empty());
1374 EXPECT_TRUE(GetMisconnects()->empty());
Darin Petkovcb0b5662012-12-13 09:59:44 +01001375
1376 // Disconnect while manager is stopped is a non-event.
1377 SetStateField(Service::kStateOnline);
1378 SetManagerRunning(false);
1379 NoteDisconnectEvent();
1380 EXPECT_TRUE(GetDisconnects()->empty());
1381 EXPECT_TRUE(GetMisconnects()->empty());
1382
1383 // Disconnect while suspending is a non-event.
1384 SetManagerRunning(true);
1385 SetPowerState(PowerManager::kSuspending);
1386 NoteDisconnectEvent();
1387 EXPECT_TRUE(GetDisconnects()->empty());
1388 EXPECT_TRUE(GetMisconnects()->empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001389}
1390
1391TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001392 const int kNow = 5;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001393 EXPECT_FALSE(service_->explicitly_disconnected());
1394 SetStateField(Service::kStateOnline);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001395 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001396 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1397 NoteDisconnectEvent();
1398 ASSERT_EQ(1, GetDisconnects()->size());
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001399 EXPECT_EQ(kNow, GetDisconnects()->front().monotonic.tv_sec);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001400 EXPECT_TRUE(GetMisconnects()->empty());
Paul Stewart483e4722012-12-18 10:23:17 -08001401
1402 Mock::VerifyAndClearExpectations(&time_);
1403 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
1404 kNow + GetDisconnectsMonitorSeconds() - 1, "")));
1405 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1406 ASSERT_EQ(1, GetDisconnects()->size());
1407
1408 Mock::VerifyAndClearExpectations(&time_);
1409 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
1410 kNow + GetDisconnectsMonitorSeconds(), "")));
1411 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1412 ASSERT_TRUE(GetDisconnects()->empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001413}
1414
1415TEST_F(ServiceTest, NoteDisconnectEventDisconnectThreshold) {
1416 EXPECT_FALSE(service_->explicitly_disconnected());
1417 SetStateField(Service::kStateOnline);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001418 const int kNow = 6;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001419 for (int i = 0; i < GetReportDisconnectsThreshold() - 1; i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001420 PushTimestamp(GetDisconnects(), kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001421 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001422 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001423 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1424 NoteDisconnectEvent();
1425 EXPECT_EQ(GetReportDisconnectsThreshold(), GetDisconnects()->size());
1426}
1427
1428TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001429 const int kNow = 7;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001430 EXPECT_FALSE(service_->explicitly_disconnected());
1431 SetStateField(Service::kStateConfiguring);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001432 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001433 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1434 NoteDisconnectEvent();
1435 EXPECT_TRUE(GetDisconnects()->empty());
1436 ASSERT_EQ(1, GetMisconnects()->size());
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001437 EXPECT_EQ(kNow, GetMisconnects()->front().monotonic.tv_sec);
Paul Stewart483e4722012-12-18 10:23:17 -08001438
1439 Mock::VerifyAndClearExpectations(&time_);
1440 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
1441 kNow + GetMisconnectsMonitorSeconds() - 1, "")));
1442 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1443 ASSERT_EQ(1, GetMisconnects()->size());
1444
1445 Mock::VerifyAndClearExpectations(&time_);
1446 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(
1447 kNow + GetMisconnectsMonitorSeconds(), "")));
1448 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1449 ASSERT_TRUE(GetMisconnects()->empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001450}
1451
1452TEST_F(ServiceTest, NoteDisconnectEventMisconnectThreshold) {
1453 EXPECT_FALSE(service_->explicitly_disconnected());
1454 SetStateField(Service::kStateConfiguring);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001455 const int kNow = 8;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001456 for (int i = 0; i < GetReportMisconnectsThreshold() - 1; i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001457 PushTimestamp(GetMisconnects(), kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001458 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001459 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001460 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1461 NoteDisconnectEvent();
1462 EXPECT_EQ(GetReportMisconnectsThreshold(), GetMisconnects()->size());
1463}
1464
1465TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) {
1466 EXPECT_FALSE(service_->explicitly_disconnected());
1467 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1468 for (int i = 0; i < 2; i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001469 int now = 0;
1470 deque<Timestamp> *events = NULL;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001471 if (i == 0) {
1472 SetStateField(Service::kStateConnected);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001473 now = GetDisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001474 events = GetDisconnects();
1475 } else {
1476 SetStateField(Service::kStateAssociating);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001477 now = GetMisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001478 events = GetMisconnects();
1479 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001480 PushTimestamp(events, 0, "");
1481 PushTimestamp(events, 0, "");
1482 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001483 NoteDisconnectEvent();
1484 ASSERT_EQ(1, events->size());
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001485 EXPECT_EQ(now, events->front().monotonic.tv_sec);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001486 }
1487}
1488
1489TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) {
1490 EXPECT_FALSE(service_->explicitly_disconnected());
1491 SetStateField(Service::kStateOnline);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001492 for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001493 PushTimestamp(GetDisconnects(), 0, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001494 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001495 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001496 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1497 NoteDisconnectEvent();
1498 EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->size());
1499}
1500
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001501TEST_F(ServiceTest, ConvertTimestampsToStrings) {
1502 EXPECT_TRUE(ExtractWallClockToStrings(deque<Timestamp>()).empty());
1503
1504 const Timestamp kValues[] = {
Darin Petkov0857f8e2012-12-21 10:49:17 +01001505 GetTimestamp(123, "2012-12-09T12:41:22.123456+0100"),
1506 GetTimestamp(234, "2012-12-31T23:59:59.012345+0100")
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001507 };
1508 Strings strings =
1509 ExtractWallClockToStrings(
1510 deque<Timestamp>(kValues, kValues + arraysize(kValues)));
1511 EXPECT_GT(arraysize(kValues), 0);
1512 ASSERT_EQ(arraysize(kValues), strings.size());
1513 for (size_t i = 0; i < arraysize(kValues); i++) {
1514 EXPECT_EQ(kValues[i].wall_clock, strings[i]);
1515 }
1516}
1517
1518TEST_F(ServiceTest, DiagnosticsProperties) {
Darin Petkov0857f8e2012-12-21 10:49:17 +01001519 const string kWallClock0 = "2012-12-09T12:41:22.234567-0800";
1520 const string kWallClock1 = "2012-12-31T23:59:59.345678-0800";
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001521 Strings values;
1522
1523 PushTimestamp(GetDisconnects(), 0, kWallClock0);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001524 Error unused_error;
1525 ASSERT_TRUE(service_->store().GetStringsProperty(
1526 kDiagnosticsDisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001527 ASSERT_EQ(1, values.size());
1528 EXPECT_EQ(kWallClock0, values[0]);
1529
1530 PushTimestamp(GetMisconnects(), 0, kWallClock1);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001531 ASSERT_TRUE(service_->store().GetStringsProperty(
1532 kDiagnosticsMisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001533 ASSERT_EQ(1, values.size());
1534 EXPECT_EQ(kWallClock1, values[0]);
1535}
1536
mukesh agrawal43970a22013-02-15 16:00:07 -08001537TEST_F(ServiceTest, SecurityLevel) {
1538 // Encrypted is better than not.
1539 service_->SetSecurity(Service::kCryptoNone, false, false);
1540 service2_->SetSecurity(Service::kCryptoRc4, false, false);
1541 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1542
1543 // AES encryption is better than RC4 encryption.
1544 service_->SetSecurity(Service::kCryptoRc4, false, false);
1545 service2_->SetSecurity(Service::kCryptoAes, false, false);
1546 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1547
1548 // Crypto algorithm is more important than key rotation.
1549 service_->SetSecurity(Service::kCryptoNone, true, false);
1550 service2_->SetSecurity(Service::kCryptoAes, false, false);
1551 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1552
1553 // Encrypted-but-unauthenticated is better than clear-but-authenticated.
1554 service_->SetSecurity(Service::kCryptoNone, false, true);
1555 service2_->SetSecurity(Service::kCryptoAes, false, false);
1556 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1557
1558 // For same encryption, prefer key rotation.
1559 service_->SetSecurity(Service::kCryptoRc4, false, false);
1560 service2_->SetSecurity(Service::kCryptoRc4, true, false);
1561 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1562
1563 // For same encryption, prefer authenticated AP.
1564 service_->SetSecurity(Service::kCryptoRc4, false, false);
1565 service2_->SetSecurity(Service::kCryptoRc4, false, true);
1566 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1567}
1568
Darin Petkovaba89322013-03-11 14:48:22 +01001569TEST_F(ServiceTest, SetErrorDetails) {
1570 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1571 static const char kDetails[] = "Certificate revoked.";
1572 ServiceMockAdaptor *adaptor = GetAdaptor();
1573 EXPECT_CALL(*adaptor, EmitStringChanged(shill::kErrorDetailsProperty,
1574 kDetails));
1575 service_->SetErrorDetails(Service::kErrorDetailsNone);
1576 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1577 service_->SetErrorDetails(kDetails);
1578 EXPECT_EQ(kDetails, service_->error_details());
1579 service_->SetErrorDetails(kDetails);
1580}
1581
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001582TEST_F(ServiceTest, SetAutoConnectFull) {
Darin Petkov36d962d2013-03-25 13:03:14 +01001583 EXPECT_FALSE(service_->auto_connect());
1584 Error error;
1585 EXPECT_FALSE(GetAutoConnect(&error));
1586 EXPECT_TRUE(error.IsSuccess());
1587
1588 // false -> false
1589 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001590 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001591 EXPECT_TRUE(error.IsSuccess());
1592 EXPECT_FALSE(service_->auto_connect());
1593 EXPECT_FALSE(GetAutoConnect(NULL));
1594 Mock::VerifyAndClearExpectations(&mock_manager_);
1595
1596 // false -> true
1597 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001598 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001599 EXPECT_TRUE(error.IsSuccess());
1600 EXPECT_TRUE(service_->auto_connect());
1601 EXPECT_TRUE(GetAutoConnect(NULL));
1602 Mock::VerifyAndClearExpectations(&mock_manager_);
1603
1604 // true -> true
1605 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001606 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001607 EXPECT_TRUE(error.IsSuccess());
1608 EXPECT_TRUE(service_->auto_connect());
1609 EXPECT_TRUE(GetAutoConnect(NULL));
1610 Mock::VerifyAndClearExpectations(&mock_manager_);
1611
1612 // true -> false
1613 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001614 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001615 EXPECT_TRUE(error.IsSuccess());
1616 EXPECT_FALSE(service_->auto_connect());
1617 EXPECT_FALSE(GetAutoConnect(NULL));
1618 Mock::VerifyAndClearExpectations(&mock_manager_);
1619}
1620
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001621TEST_F(ServiceTest, PropertyChanges) {
1622 TestCommonPropertyChanges(service_, GetAdaptor());
1623 TestAutoConnectPropertyChange(service_, GetAdaptor());
1624}
1625
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001626// Custom property setters should return false, and make no changes, if
1627// the new value is the same as the old value.
1628TEST_F(ServiceTest, CustomSetterNoopChange) {
1629 TestCustomSetterNoopChange(service_, &mock_manager_);
1630}
1631
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001632} // namespace shill