blob: 1895db041fe73d70b045e6d9132e4a291a3ba26e [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
Paul Stewart22ce7652014-10-15 21:26:44 -07007#include <algorithm>
Chris Masone3bd3c8c2011-06-13 08:20:26 -07008#include <map>
Ben Chancd477322014-10-17 14:19:30 -07009#include <memory>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070010#include <string>
11#include <vector>
12
Eric Shienbrood9a245532012-03-07 14:20:39 -050013#include <base/bind.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070014#include <chromeos/dbus/service_constants.h>
mukesh agrawal1830fa12011-09-26 14:31:40 -070015#include <dbus-c++/dbus.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016#include <gtest/gtest.h>
17#include <gmock/gmock.h>
18
19#include "shill/dbus_adaptor.h"
Ben Chan87602512014-11-07 20:50:05 -080020#include "shill/ethernet/ethernet_service.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070021#include "shill/event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070022#include "shill/manager.h"
Chris Masone95207da2011-06-29 16:50:49 -070023#include "shill/mock_adaptors.h"
Paul Stewart10241e32012-04-23 18:15:06 -070024#include "shill/mock_connection.h"
Alex Vakulenkoa41ab512014-07-23 14:24:23 -070025#include "shill/mock_control.h"
Paul Stewart10241e32012-04-23 18:15:06 -070026#include "shill/mock_device_info.h"
Darin Petkov385b9bc2012-12-03 15:25:05 +010027#include "shill/mock_diagnostics_reporter.h"
Christopher Wiley0801d192012-09-24 11:57:15 -070028#include "shill/mock_event_dispatcher.h"
Paul Stewartbc6e7392012-05-24 07:07:48 -070029#include "shill/mock_log.h"
Paul Stewart03dba0b2011-08-22 16:32:45 -070030#include "shill/mock_manager.h"
Darin Petkovcb0b5662012-12-13 09:59:44 +010031#include "shill/mock_power_manager.h"
Paul Stewartff14b022012-04-24 20:06:23 -070032#include "shill/mock_profile.h"
Darin Petkovcb0b5662012-12-13 09:59:44 +010033#include "shill/mock_proxy_factory.h"
Paul Stewart22ce7652014-10-15 21:26:44 -070034#include "shill/mock_service.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070035#include "shill/mock_store.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070036#include "shill/net/mock_time.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070037#include "shill/property_store_unittest.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070038#include "shill/service_property_change_test.h"
Paul Stewart22ce7652014-10-15 21:26:44 -070039#include "shill/service_sorter.h"
Chris Masone6515aab2011-10-12 16:19:09 -070040#include "shill/service_under_test.h"
Paul Stewartf2860342014-05-09 14:29:16 -070041#include "shill/testing.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070042
Peter Qiu1a72f542015-04-14 16:31:36 -070043#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
44#include "shill/mock_eap_credentials.h"
45#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
46
Eric Shienbrood9a245532012-03-07 14:20:39 -050047using base::Bind;
48using base::Unretained;
Darin Petkov385b9bc2012-12-03 15:25:05 +010049using std::deque;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070050using std::map;
51using std::string;
52using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070053using testing::_;
mukesh agrawalcf24a242012-05-21 16:46:11 -070054using testing::AnyNumber;
Darin Petkovba40dd32011-07-11 20:06:39 -070055using testing::AtLeast;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010056using testing::DefaultValue;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080057using testing::DoAll;
Paul Stewartbc6e7392012-05-24 07:07:48 -070058using testing::HasSubstr;
Paul Stewart81426132012-05-16 10:05:10 -070059using testing::Mock;
Darin Petkovba40dd32011-07-11 20:06:39 -070060using testing::NiceMock;
61using testing::Return;
Ben Chana55469d2014-01-27 16:35:29 -080062using testing::ReturnNull;
Paul Stewart10241e32012-04-23 18:15:06 -070063using testing::ReturnRef;
Darin Petkovba40dd32011-07-11 20:06:39 -070064using testing::StrictMock;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080065using testing::SetArgumentPointee;
Darin Petkovba40dd32011-07-11 20:06:39 -070066using testing::Test;
Paul Stewart9f32d192012-01-30 20:37:50 -080067using testing::Values;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070068
69namespace shill {
70
71class ServiceTest : public PropertyStoreTest {
72 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070073 ServiceTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080074 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
Chris Masone2176a882011-09-14 22:29:15 -070075 service_(new ServiceUnderTest(control_interface(),
76 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080077 metrics(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070078 &mock_manager_)),
mukesh agrawal43970a22013-02-15 16:00:07 -080079 service2_(new ServiceUnderTest(control_interface(),
80 dispatcher(),
81 metrics(),
82 &mock_manager_)),
Darin Petkovcb0b5662012-12-13 09:59:44 +010083 storage_id_(ServiceUnderTest::kStorageId),
Peter Qiu1a72f542015-04-14 16:31:36 -070084#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
85 eap_(new MockEapCredentials()),
86#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
87 power_manager_(new MockPowerManager(nullptr, &proxy_factory_)) {
Ben Chana55469d2014-01-27 16:35:29 -080088 ON_CALL(proxy_factory_, CreatePowerManagerProxy(_))
89 .WillByDefault(ReturnNull());
90
Darin Petkov385b9bc2012-12-03 15:25:05 +010091 service_->time_ = &time_;
Samuel Tan07dfabc2015-01-20 15:10:39 -080092 service_->disconnects_.time_ = &time_;
93 service_->misconnects_.time_ = &time_;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010094 DefaultValue<Timestamp>::Set(Timestamp());
Darin Petkov385b9bc2012-12-03 15:25:05 +010095 service_->diagnostics_reporter_ = &diagnostics_reporter_;
Peter Qiu1a72f542015-04-14 16:31:36 -070096#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -070097 service_->eap_.reset(eap_); // Passes ownership.
Peter Qiu1a72f542015-04-14 16:31:36 -070098#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Darin Petkovcb0b5662012-12-13 09:59:44 +010099 mock_manager_.running_ = true;
100 mock_manager_.set_power_manager(power_manager_); // Passes ownership.
Chris Masone9d779932011-08-25 16:33:41 -0700101 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700102
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700103 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -0700104
Paul Stewart3b30ca52015-06-16 13:13:10 -0700105 MOCK_METHOD1(TestCallback, void(const Error& error));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500106
Chris Masoneb925cc82011-06-22 15:39:57 -0700107 protected:
mukesh agrawalcf24a242012-05-21 16:46:11 -0700108 typedef scoped_refptr<MockProfile> MockProfileRefPtr;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500109
Paul Stewart3b30ca52015-06-16 13:13:10 -0700110 ServiceMockAdaptor* GetAdaptor() {
111 return dynamic_cast<ServiceMockAdaptor*>(service_->adaptor());
Darin Petkovaba89322013-03-11 14:48:22 +0100112 }
113
Darin Petkov457728b2013-01-09 09:49:08 +0100114 string GetFriendlyName() { return service_->friendly_name(); }
115
Darin Petkovcb0b5662012-12-13 09:59:44 +0100116 void SetManagerRunning(bool running) { mock_manager_.running_ = running; }
117
Daniel Eratfac09532014-04-17 20:25:59 -0700118 void SetSuspending(bool suspending) {
119 power_manager_->suspending_ = suspending;
Darin Petkovcb0b5662012-12-13 09:59:44 +0100120 }
121
Paul Stewart2eee6132014-05-09 13:33:26 -0700122 bool GetExplicitlyDisconnected() const {
123 return service_->explicitly_disconnected_;
124 }
125
Darin Petkov385b9bc2012-12-03 15:25:05 +0100126 void SetExplicitlyDisconnected(bool explicitly) {
127 service_->explicitly_disconnected_ = explicitly;
128 }
129
130 void SetStateField(Service::ConnectState state) { service_->state_ = state; }
131
Darin Petkovc8d91e52013-01-21 11:43:47 +0100132 Service::ConnectState GetPreviousState() const {
133 return service_->previous_state_;
134 }
135
Darin Petkov385b9bc2012-12-03 15:25:05 +0100136 void NoteDisconnectEvent() {
137 service_->NoteDisconnectEvent();
138 }
139
Paul Stewart3b30ca52015-06-16 13:13:10 -0700140 EventHistory* GetDisconnects() {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100141 return &service_->disconnects_;
142 }
Paul Stewart3b30ca52015-06-16 13:13:10 -0700143 EventHistory* GetMisconnects() {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100144 return &service_->misconnects_;
145 }
146
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700147 Timestamp GetTimestamp(int monotonic_seconds, int boottime_seconds,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700148 const string& wall_clock) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100149 struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 };
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700150 struct timeval boottime = { .tv_sec = boottime_seconds, .tv_usec = 0 };
151 return Timestamp(monotonic, boottime, wall_clock);
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100152 }
153
Paul Stewart3b30ca52015-06-16 13:13:10 -0700154 void PushTimestamp(EventHistory* events,
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100155 int monotonic_seconds,
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700156 int boottime_seconds,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700157 const string& wall_clock) {
Samuel Tan07dfabc2015-01-20 15:10:39 -0800158 events->RecordEventInternal(
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700159 GetTimestamp(monotonic_seconds, boottime_seconds, wall_clock));
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100160 }
Darin Petkov385b9bc2012-12-03 15:25:05 +0100161
162 int GetDisconnectsMonitorSeconds() {
163 return Service::kDisconnectsMonitorSeconds;
164 }
165
166 int GetMisconnectsMonitorSeconds() {
167 return Service::kMisconnectsMonitorSeconds;
168 }
169
170 int GetReportDisconnectsThreshold() {
171 return Service::kReportDisconnectsThreshold;
172 }
173
174 int GetReportMisconnectsThreshold() {
175 return Service::kReportMisconnectsThreshold;
176 }
177
178 int GetMaxDisconnectEventHistory() {
179 return Service::kMaxDisconnectEventHistory;
180 }
181
Samuel Tan07dfabc2015-01-20 15:10:39 -0800182 int GetMaxMisconnectEventHistory() {
183 return Service::kMaxMisconnectEventHistory;
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100184 }
185
Paul Stewart3b30ca52015-06-16 13:13:10 -0700186 bool GetAutoConnect(Error* error) {
Darin Petkov36d962d2013-03-25 13:03:14 +0100187 return service_->GetAutoConnect(error);
188 }
189
Paul Stewart3b30ca52015-06-16 13:13:10 -0700190 void ClearAutoConnect(Error* error) {
Paul Stewart43d8dc02013-10-17 10:32:53 -0700191 service_->ClearAutoConnect(error);
192 }
193
Paul Stewart3b30ca52015-06-16 13:13:10 -0700194 bool SetAutoConnectFull(bool connect, Error* error) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700195 return service_->SetAutoConnectFull(connect, error);
Darin Petkov36d962d2013-03-25 13:03:14 +0100196 }
197
Paul Stewart3b30ca52015-06-16 13:13:10 -0700198 bool SortingOrderIs(const ServiceRefPtr& service0,
199 const ServiceRefPtr& service1,
Paul Stewart22ce7652014-10-15 21:26:44 -0700200 bool should_compare_connectivity_state) {
201 vector<ServiceRefPtr> services;
202 services.push_back(service1);
203 services.push_back(service0);
204 std::sort(services.begin(), services.end(),
205 ServiceSorter(&mock_manager_, should_compare_connectivity_state,
206 technology_order_for_sorting_));
207 return (service0.get() == services[0].get() &&
208 service1.get() == services[1].get());
209 }
210
Paul Stewart3b30ca52015-06-16 13:13:10 -0700211 bool DefaultSortingOrderIs(const ServiceRefPtr& service0,
212 const ServiceRefPtr& service1) {
Paul Stewart22ce7652014-10-15 21:26:44 -0700213 const bool kShouldCompareConnectivityState = true;
214 return SortingOrderIs(
215 service0, service1, kShouldCompareConnectivityState);
216 }
217
Paul Stewart03dba0b2011-08-22 16:32:45 -0700218 MockManager mock_manager_;
Darin Petkov385b9bc2012-12-03 15:25:05 +0100219 MockDiagnosticsReporter diagnostics_reporter_;
220 MockTime time_;
Paul Stewart03dba0b2011-08-22 16:32:45 -0700221 scoped_refptr<ServiceUnderTest> service_;
mukesh agrawal43970a22013-02-15 16:00:07 -0800222 scoped_refptr<ServiceUnderTest> service2_;
Chris Masone34af2182011-08-22 11:59:36 -0700223 string storage_id_;
Ben Chana55469d2014-01-27 16:35:29 -0800224 NiceMock<MockProxyFactory> proxy_factory_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700225#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart3b30ca52015-06-16 13:13:10 -0700226 MockEapCredentials* eap_; // Owned by |service_|.
Peter Qiu1a72f542015-04-14 16:31:36 -0700227#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart3b30ca52015-06-16 13:13:10 -0700228 MockPowerManager* power_manager_; // Owned by |mock_manager_|.
Paul Stewart22ce7652014-10-15 21:26:44 -0700229 vector<Technology::Identifier> technology_order_for_sorting_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700230};
231
Christopher Wiley0801d192012-09-24 11:57:15 -0700232class AllMockServiceTest : public testing::Test {
233 public:
234 AllMockServiceTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800235 : metrics_(&dispatcher_),
236 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Christopher Wiley0801d192012-09-24 11:57:15 -0700237 service_(new ServiceUnderTest(&control_interface_,
238 &dispatcher_,
239 &metrics_,
240 &manager_)) { }
241 virtual ~AllMockServiceTest() {}
242
243 protected:
244 MockControl control_interface_;
245 StrictMock<MockEventDispatcher> dispatcher_;
246 MockGLib glib_;
247 NiceMock<MockMetrics> metrics_;
248 MockManager manager_;
249 scoped_refptr<ServiceUnderTest> service_;
250};
251
Darin Petkovba40dd32011-07-11 20:06:39 -0700252TEST_F(ServiceTest, Constructor) {
253 EXPECT_TRUE(service_->save_credentials_);
254 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400255 EXPECT_EQ(Service::kStateIdle, service_->state());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700256 EXPECT_FALSE(service_->has_ever_connected());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800257 EXPECT_EQ(0, service_->previous_error_serial_number_);
258 EXPECT_EQ("", service_->previous_error_);
Darin Petkovba40dd32011-07-11 20:06:39 -0700259}
260
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200261TEST_F(ServiceTest, CalculateState) {
262 service_->state_ = Service::kStateConnected;
263 Error error;
Ben Chan923a5022013-09-20 11:23:23 -0700264 EXPECT_EQ(kStateReady, service_->CalculateState(&error));
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200265 EXPECT_TRUE(error.IsSuccess());
266}
267
268TEST_F(ServiceTest, CalculateTechnology) {
269 service_->technology_ = Technology::kWifi;
270 Error error;
Ben Chan923a5022013-09-20 11:23:23 -0700271 EXPECT_EQ(kTypeWifi, service_->CalculateTechnology(&error));
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200272 EXPECT_TRUE(error.IsSuccess());
273}
274
Chris Masonea8a2c252011-06-27 22:16:30 -0700275TEST_F(ServiceTest, GetProperties) {
276 map<string, ::DBus::Variant> props;
277 Error error(Error::kInvalidProperty, "");
278 {
279 ::DBus::Error dbus_error;
Paul Stewartd215af62012-04-24 23:25:50 -0700280 string expected("true");
Ben Chan923a5022013-09-20 11:23:23 -0700281 service_->mutable_store()->SetStringProperty(kCheckPortalProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700282 expected,
283 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700284 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700285 ASSERT_FALSE(props.find(kCheckPortalProperty) == props.end());
286 EXPECT_EQ(props[kCheckPortalProperty].reader().get_string(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700287 expected);
288 }
289 {
290 ::DBus::Error dbus_error;
291 bool expected = true;
Ben Chan923a5022013-09-20 11:23:23 -0700292 service_->mutable_store()->SetBoolProperty(kAutoConnectProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700293 expected,
294 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700295 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700296 ASSERT_FALSE(props.find(kAutoConnectProperty) == props.end());
297 EXPECT_EQ(props[kAutoConnectProperty].reader().get_bool(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700298 expected);
299 }
300 {
301 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700302 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700303 ASSERT_FALSE(props.find(kConnectableProperty) == props.end());
304 EXPECT_EQ(props[kConnectableProperty].reader().get_bool(), false);
Chris Masonea8a2c252011-06-27 22:16:30 -0700305 }
306 {
307 ::DBus::Error dbus_error;
Ben Chan7fab8972014-08-10 17:14:46 -0700308 int32_t expected = 127;
Ben Chan923a5022013-09-20 11:23:23 -0700309 service_->mutable_store()->SetInt32Property(kPriorityProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700310 expected,
311 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700312 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700313 ASSERT_FALSE(props.find(kPriorityProperty) == props.end());
314 EXPECT_EQ(props[kPriorityProperty].reader().get_int32(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700315 expected);
316 }
Chris Masone95207da2011-06-29 16:50:49 -0700317 {
318 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700319 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700320 ASSERT_FALSE(props.find(kDeviceProperty) == props.end());
321 EXPECT_EQ(props[kDeviceProperty].reader().get_path(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700322 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700323 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700324}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700325
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800326TEST_F(ServiceTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700327 {
328 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800329 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700330 kSaveCredentialsProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800331 PropertyStoreTest::kBoolV,
332 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700333 }
334 {
335 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700336 ::DBus::Variant priority;
337 priority.writer().append_int32(1);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800338 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700339 kPriorityProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700340 priority,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800341 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700342 }
343 {
344 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700345 ::DBus::Variant guid;
346 guid.writer().append_string("not default");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800347 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700348 kGuidProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700349 guid,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700350 &error));
351 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700352#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700353 // Ensure that EAP properties cannot be set on services with no EAP
354 // credentials. Use service2_ here since we're have some code in
355 // ServiceTest::SetUp() that fiddles with service_->eap_.
356 {
357 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700358 ::DBus::Variant eap;
359 eap.writer().append_string("eap eep eip!");
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700360 EXPECT_FALSE(DBusAdaptor::SetProperty(service2_->mutable_store(),
Ben Chan011e6662014-05-07 11:03:25 -0700361 kEapMethodProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700362 eap,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700363 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700364 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700365 EXPECT_EQ(invalid_prop(), error.name());
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700366 // Now plumb in eap credentials, and try again.
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700367 service2_->SetEapCredentials(new EapCredentials());
368 EXPECT_TRUE(DBusAdaptor::SetProperty(service2_->mutable_store(),
Ben Chan011e6662014-05-07 11:03:25 -0700369 kEapMethodProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700370 eap,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800371 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700372 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700373#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Chris Masoneb925cc82011-06-22 15:39:57 -0700374 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700375 {
376 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800377 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Paul Stewart2da34c02013-10-17 15:28:56 -0700378 kConnectableProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800379 PropertyStoreTest::kBoolV,
380 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700381 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700382 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700383 }
Thieu Le284fe792012-01-31 17:53:19 -0800384 {
385 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700386 ::DBus::Variant auto_connect;
387 auto_connect.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800388 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700389 kAutoConnectProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700390 auto_connect,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800391 &error));
Thieu Le284fe792012-01-31 17:53:19 -0800392 }
Paul Stewart0c438332012-04-11 07:55:27 -0700393 // Ensure that we can perform a trivial set of the Name property (to its
394 // current value) but an attempt to set the property to a different value
395 // fails.
396 {
397 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700398 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700399 kNameProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700400 DBusAdaptor::StringToVariant(
401 GetFriendlyName()),
402 &error));
403 EXPECT_FALSE(error.is_set());
Paul Stewart0c438332012-04-11 07:55:27 -0700404 }
405 {
406 ::DBus::Error error;
407 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700408 kNameProperty,
Paul Stewart0c438332012-04-11 07:55:27 -0700409 PropertyStoreTest::kStringV,
410 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700411 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewart0c438332012-04-11 07:55:27 -0700412 EXPECT_EQ(invalid_args(), error.name());
413 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700414}
415
Paul Stewarte7de2942013-04-25 17:07:31 -0700416TEST_F(ServiceTest, GetLoadableStorageIdentifier) {
417 NiceMock<MockStore> storage;
418 EXPECT_CALL(storage, ContainsGroup(storage_id_))
419 .WillOnce(Return(false))
420 .WillOnce(Return(true));
421 EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage));
422 EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage));
423}
424
425TEST_F(ServiceTest, IsLoadableFrom) {
426 NiceMock<MockStore> storage;
427 EXPECT_CALL(storage, ContainsGroup(storage_id_))
428 .WillOnce(Return(false))
429 .WillOnce(Return(true));
430 EXPECT_FALSE(service_->IsLoadableFrom(storage));
431 EXPECT_TRUE(service_->IsLoadableFrom(storage));
432}
433
Peter Qiu1a72f542015-04-14 16:31:36 -0700434#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700435class ServiceWithOnEapCredentialsChangedOverride : public ServiceUnderTest {
436 public:
437 ServiceWithOnEapCredentialsChangedOverride(
Paul Stewart3b30ca52015-06-16 13:13:10 -0700438 ControlInterface* control_interface,
439 EventDispatcher* dispatcher,
440 Metrics* metrics,
441 Manager* manager,
442 EapCredentials* eap)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700443 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {
444 SetEapCredentials(eap);
445 }
Rebecca Silberstein57776902014-09-15 21:43:02 -0700446 void OnEapCredentialsChanged(Service::UpdateCredentialsReason) override {
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700447 SetHasEverConnected(false);
448 }
449};
Peter Qiu1a72f542015-04-14 16:31:36 -0700450#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700451
Darin Petkovba40dd32011-07-11 20:06:39 -0700452TEST_F(ServiceTest, Load) {
Peter Qiu1a72f542015-04-14 16:31:36 -0700453#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart3b30ca52015-06-16 13:13:10 -0700454 MockEapCredentials* eap = new MockEapCredentials(); // Owned by |service|.
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700455 scoped_refptr<ServiceWithOnEapCredentialsChangedOverride> service(
456 new ServiceWithOnEapCredentialsChangedOverride(control_interface(),
457 dispatcher(),
458 metrics(),
459 &mock_manager_,
460 eap));
Peter Qiu1a72f542015-04-14 16:31:36 -0700461#else
462 scoped_refptr<ServiceUnderTest> service(
463 new ServiceUnderTest(control_interface(),
464 dispatcher(),
465 metrics(),
466 &mock_manager_));
467#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700468
Darin Petkovba40dd32011-07-11 20:06:39 -0700469 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700470 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700471 const string kCheckPortal("check-portal");
472 const string kGUID("guid");
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700473 const bool kHasEverConnected = true;
Paul Stewartc3dbff12013-07-17 10:32:48 -0700474 const int kPriority = 20;
475 const string kProxyConfig("proxy-config");
476 const string kUIData("ui-data");
477 EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber());
478 EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber());
479 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _))
480 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true)));
481 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _))
482 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true)));
483 EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _))
484 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true)));
485 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _))
486 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true)));
487 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _))
488 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true)));
Darin Petkov0debec02013-01-22 10:40:05 +0100489 EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber());
490 EXPECT_CALL(storage,
491 GetBool(storage_id_, Service::kStorageSaveCredentials, _));
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700492 EXPECT_CALL(storage,
493 GetBool(storage_id_, Service::kStorageHasEverConnected, _))
494 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
495 Return(true)));
Peter Qiu1a72f542015-04-14 16:31:36 -0700496#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700497 EXPECT_CALL(*eap, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700498#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700499 EXPECT_TRUE(service->Load(&storage));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700500
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700501 EXPECT_EQ(kCheckPortal, service->check_portal_);
502 EXPECT_EQ(kGUID, service->guid_);
503 EXPECT_TRUE(service->has_ever_connected_);
504 EXPECT_EQ(kProxyConfig, service->proxy_config_);
505 EXPECT_EQ(kUIData, service->ui_data_);
Paul Stewartc3dbff12013-07-17 10:32:48 -0700506
507 Mock::VerifyAndClearExpectations(&storage);
Peter Qiu1a72f542015-04-14 16:31:36 -0700508#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc3dbff12013-07-17 10:32:48 -0700509 Mock::VerifyAndClearExpectations(eap_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700510#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartc3dbff12013-07-17 10:32:48 -0700511
512 // Assure that parameters are set to default if not available in the profile.
513 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
514 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
515 .WillRepeatedly(Return(false));
516 EXPECT_CALL(storage, GetString(storage_id_, _, _))
517 .WillRepeatedly(Return(false));
518 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
519 .WillRepeatedly(Return(false));
Peter Qiu1a72f542015-04-14 16:31:36 -0700520#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700521 EXPECT_CALL(*eap, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700522#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700523 EXPECT_TRUE(service->Load(&storage));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700524
525 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700526 EXPECT_EQ("", service->guid_);
527 EXPECT_EQ("", service->proxy_config_);
528 EXPECT_EQ("", service->ui_data_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700529
530 // has_ever_connected_ flag will reset when EAP credential changes.
531#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700532 EXPECT_FALSE(service->has_ever_connected_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700533#else
534 EXPECT_TRUE(service->has_ever_connected_);
535#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Darin Petkovba40dd32011-07-11 20:06:39 -0700536}
537
538TEST_F(ServiceTest, LoadFail) {
539 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700540 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700541 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700542}
543
Paul Stewart2da34c02013-10-17 15:28:56 -0700544TEST_F(ServiceTest, LoadAutoConnect) {
545 NiceMock<MockStore> storage;
546 EXPECT_CALL(storage, ContainsGroup(storage_id_))
547 .WillRepeatedly(Return(true));
548 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
549 .WillRepeatedly(Return(false));
550 EXPECT_CALL(storage, GetString(storage_id_, _, _))
551 .WillRepeatedly(Return(false));
552 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
553 .WillRepeatedly(Return(false));
Peter Qiu1a72f542015-04-14 16:31:36 -0700554#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart2da34c02013-10-17 15:28:56 -0700555 EXPECT_CALL(*eap_, Load(&storage, storage_id_)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700556#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart2da34c02013-10-17 15:28:56 -0700557
558 // Three of each expectation so we can test Favorite == unset, false, true.
559 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageAutoConnect, _))
560 .WillOnce(Return(false))
561 .WillOnce(Return(false))
562 .WillOnce(Return(false))
563 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
564 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
565 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
566 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
567 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
568 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
569 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageFavorite, _))
570 .WillOnce(Return(false))
571 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
572 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
573 .WillOnce(Return(false))
574 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
575 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
576 .WillOnce(Return(false))
577 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
578 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
579
580 // AutoConnect is unset, Favorite is unset.
581 EXPECT_TRUE(service_->Load(&storage));
582 EXPECT_FALSE(service_->auto_connect());
583 EXPECT_FALSE(service_->retain_auto_connect());
584
585 // AutoConnect is unset, Favorite is false.
586 EXPECT_TRUE(service_->Load(&storage));
587 EXPECT_FALSE(service_->auto_connect());
588 EXPECT_FALSE(service_->retain_auto_connect());
589
590 // AutoConnect is unset, Favorite is true.
591 EXPECT_TRUE(service_->Load(&storage));
592 EXPECT_FALSE(service_->auto_connect());
593 EXPECT_TRUE(service_->retain_auto_connect());
594
595 // AutoConnect is false, Favorite is unset.
596 EXPECT_TRUE(service_->Load(&storage));
597 EXPECT_FALSE(service_->auto_connect());
598 EXPECT_TRUE(service_->retain_auto_connect());
599
600 // AutoConnect is false, Favorite is false.
601 EXPECT_TRUE(service_->Load(&storage));
602 EXPECT_FALSE(service_->auto_connect());
603 EXPECT_FALSE(service_->retain_auto_connect());
604
605 // AutoConnect is false, Favorite is true.
606 EXPECT_TRUE(service_->Load(&storage));
607 EXPECT_FALSE(service_->auto_connect());
608 EXPECT_TRUE(service_->retain_auto_connect());
609
610 // AutoConnect is true, Favorite is unset.
611 EXPECT_TRUE(service_->Load(&storage));
612 EXPECT_TRUE(service_->auto_connect());
613 EXPECT_TRUE(service_->retain_auto_connect());
614
615 // AutoConnect is true, Favorite is false (invalid case).
616 EXPECT_TRUE(service_->Load(&storage));
617 EXPECT_TRUE(service_->auto_connect());
618 EXPECT_FALSE(service_->retain_auto_connect());
619
620 // AutoConnect is true, Favorite is true.
621 EXPECT_TRUE(service_->Load(&storage));
622 EXPECT_TRUE(service_->auto_connect());
623 EXPECT_TRUE(service_->retain_auto_connect());
624}
625
Darin Petkovba40dd32011-07-11 20:06:39 -0700626TEST_F(ServiceTest, SaveString) {
627 MockStore storage;
628 static const char kKey[] = "test-key";
629 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700630 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700631 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700632 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700633}
634
635TEST_F(ServiceTest, SaveStringCrypted) {
636 MockStore storage;
637 static const char kKey[] = "test-key";
638 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700639 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700640 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700641 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700642}
643
644TEST_F(ServiceTest, SaveStringDontSave) {
645 MockStore storage;
646 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700647 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700648 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700649 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700650}
651
652TEST_F(ServiceTest, SaveStringEmpty) {
653 MockStore storage;
654 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700655 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700656 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700657 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700658}
659
660TEST_F(ServiceTest, Save) {
661 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700662 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700663 .Times(AtLeast(1))
664 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700665 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700666 .Times(AtLeast(1))
667 .WillRepeatedly(Return(true));
Paul Stewart2da34c02013-10-17 15:28:56 -0700668 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
669 .WillOnce(Return(true));
670 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
671 .WillOnce(Return(true));
Darin Petkov0debec02013-01-22 10:40:05 +0100672 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
673 EXPECT_CALL(storage,
674 SetBool(storage_id_,
675 Service::kStorageSaveCredentials,
676 service_->save_credentials()));
Peter Qiu1a72f542015-04-14 16:31:36 -0700677#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700678 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true));
Peter Qiu1a72f542015-04-14 16:31:36 -0700679#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Chris Masone9d779932011-08-25 16:33:41 -0700680 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700681}
682
Paul Stewart2da34c02013-10-17 15:28:56 -0700683TEST_F(ServiceTest, RetainAutoConnect) {
684 NiceMock<MockStore> storage;
685 EXPECT_CALL(storage, SetString(storage_id_, _, _))
686 .Times(AtLeast(1))
687 .WillRepeatedly(Return(true));
688 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
689 .Times(AtLeast(1))
690 .WillRepeatedly(Return(true));
691 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
692 .Times(2);
693 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
694 .Times(0);
695 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700696#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart2da34c02013-10-17 15:28:56 -0700697 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
Peter Qiu1a72f542015-04-14 16:31:36 -0700698#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart2da34c02013-10-17 15:28:56 -0700699
700 // AutoConnect flag set true.
701 service_->EnableAndRetainAutoConnect();
702 EXPECT_CALL(storage,
703 SetBool(storage_id_, Service::kStorageAutoConnect, true));
704 EXPECT_TRUE(service_->Save(&storage));
705
706 // AutoConnect flag set false.
707 EXPECT_CALL(storage,
708 SetBool(storage_id_, Service::kStorageAutoConnect, false));
709 service_->SetAutoConnect(false);
710 EXPECT_TRUE(service_->Save(&storage));
711}
712
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700713TEST_F(ServiceTest, HasEverConnectedSavedToProfile) {
714 NiceMock<MockStore> storage;
715 EXPECT_CALL(storage, SetString(storage_id_, _, _))
716 .Times(AtLeast(1))
717 .WillRepeatedly(Return(true));
718 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
719 .Times(AtLeast(1))
720 .WillRepeatedly(Return(true));
721 EXPECT_CALL(storage,
722 DeleteKey(storage_id_, Service::kStorageHasEverConnected))
723 .Times(0);
724 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700725#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700726 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
Peter Qiu1a72f542015-04-14 16:31:36 -0700727#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700728
729 // HasEverConnected flag set true.
730 service_->SetHasEverConnected(true);
731 EXPECT_CALL(storage,
732 SetBool(storage_id_, Service::kStorageHasEverConnected, true));
733 EXPECT_TRUE(service_->Save(&storage));
734
735 // HasEverConnected flag set false.
736 EXPECT_CALL(storage,
737 SetBool(storage_id_, Service::kStorageHasEverConnected, false));
738 service_->SetHasEverConnected(false);
739 EXPECT_TRUE(service_->Save(&storage));
740}
741
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800742TEST_F(ServiceTest, Unload) {
743 NiceMock<MockStore> storage;
744 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
745 static const string string_value("value");
746 EXPECT_CALL(storage, GetString(storage_id_, _, _))
747 .Times(AtLeast(1))
748 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
Paul Stewart88769de2012-09-21 13:14:36 -0700749 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
750 .Times(AtLeast(1))
751 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
752 EXPECT_FALSE(service_->explicitly_disconnected_);
753 service_->explicitly_disconnected_ = true;
754 EXPECT_FALSE(service_->has_ever_connected_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700755#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700756 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700757#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800758 ASSERT_TRUE(service_->Load(&storage));
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700759 // TODO(pstew): Only two string properties in the service are tested as
mukesh agrawalcf24a242012-05-21 16:46:11 -0700760 // a sentinel that properties are being set and reset at the right times.
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800761 // However, since property load/store is essentially a manual process,
762 // it is error prone and should either be exhaustively unit-tested or
763 // a generic framework for registering loaded/stored properties should
Paul Stewartee6b3d72013-07-12 16:07:51 -0700764 // be created. crbug.com/207798
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800765 EXPECT_EQ(string_value, service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700766 EXPECT_EQ(string_value, service_->guid_);
Paul Stewart88769de2012-09-21 13:14:36 -0700767 EXPECT_FALSE(service_->explicitly_disconnected_);
768 EXPECT_TRUE(service_->has_ever_connected_);
769 service_->explicitly_disconnected_ = true;
Peter Qiu1a72f542015-04-14 16:31:36 -0700770#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700771 EXPECT_CALL(*eap_, Reset());
Peter Qiu1a72f542015-04-14 16:31:36 -0700772#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800773 service_->Unload();
774 EXPECT_EQ(string(""), service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700775 EXPECT_EQ(string(""), service_->guid_);
Philipp Neubeckf883a7b2012-09-14 19:52:44 +0200776 EXPECT_FALSE(service_->explicitly_disconnected_);
Paul Stewart88769de2012-09-21 13:14:36 -0700777 EXPECT_FALSE(service_->has_ever_connected_);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800778}
779
Paul Stewart03dba0b2011-08-22 16:32:45 -0700780TEST_F(ServiceTest, State) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400781 EXPECT_EQ(Service::kStateIdle, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100782 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700783 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700784 const string unknown_error(
785 Service::ConnectFailureToString(Service::kFailureUnknown));
786 EXPECT_EQ(unknown_error, service_->error());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700787
Darin Petkovaba89322013-03-11 14:48:22 +0100788 EXPECT_CALL(*GetAdaptor(),
Ben Chan923a5022013-09-20 11:23:23 -0700789 EmitStringChanged(kStateProperty, _)).Times(6);
Darin Petkovaba89322013-03-11 14:48:22 +0100790 EXPECT_CALL(*GetAdaptor(),
Ben Chan923a5022013-09-20 11:23:23 -0700791 EmitStringChanged(kErrorProperty, _)).Times(4);
Paul Stewartf2860342014-05-09 14:29:16 -0700792 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700793 service_->SetState(Service::kStateConnected);
Darin Petkovc8d91e52013-01-21 11:43:47 +0100794 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700795 // A second state change shouldn't cause another update
796 service_->SetState(Service::kStateConnected);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700797 EXPECT_EQ(Service::kStateConnected, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100798 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700799 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700800 EXPECT_TRUE(service_->has_ever_connected_);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800801
Paul Stewartf2860342014-05-09 14:29:16 -0700802 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700803 service_->SetFailure(Service::kFailureOutOfRange);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800804 EXPECT_TRUE(service_->IsFailed());
805 EXPECT_GT(service_->failed_time_, 0);
Paul Stewartd7c09a52014-02-19 12:50:29 -0800806 EXPECT_GT(service_->previous_error_serial_number_, 0);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700807 EXPECT_EQ(Service::kStateFailure, service_->state());
808 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700809 const string out_of_range_error(
810 Service::ConnectFailureToString(Service::kFailureOutOfRange));
811 EXPECT_EQ(out_of_range_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800812 EXPECT_EQ(out_of_range_error, service_->previous_error_);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800813
Paul Stewartf2860342014-05-09 14:29:16 -0700814 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawal568b5c62012-02-28 14:44:47 -0800815 service_->SetState(Service::kStateConnected);
816 EXPECT_FALSE(service_->IsFailed());
817 EXPECT_EQ(service_->failed_time_, 0);
Paul Stewartf2d60912012-07-15 08:37:30 -0700818 EXPECT_EQ(unknown_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800819 EXPECT_EQ(out_of_range_error, service_->previous_error_);
820 EXPECT_GT(service_->previous_error_serial_number_, 0);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800821
Paul Stewartf2860342014-05-09 14:29:16 -0700822 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawal568b5c62012-02-28 14:44:47 -0800823 service_->SetFailureSilent(Service::kFailurePinMissing);
824 EXPECT_TRUE(service_->IsFailed());
825 EXPECT_GT(service_->failed_time_, 0);
Paul Stewartd7c09a52014-02-19 12:50:29 -0800826 EXPECT_GT(service_->previous_error_serial_number_, 0);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800827 EXPECT_EQ(Service::kStateIdle, service_->state());
828 EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700829 const string pin_missing_error(
830 Service::ConnectFailureToString(Service::kFailurePinMissing));
831 EXPECT_EQ(pin_missing_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800832 EXPECT_EQ(pin_missing_error, service_->previous_error_);
mukesh agrawalcf24a242012-05-21 16:46:11 -0700833
834 // If the Service has a Profile, the profile should be saved when
835 // the service enters kStateConnected. (The case where the service
836 // doesn't have a profile is tested above.)
837 MockProfileRefPtr mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800838 new MockProfile(control_interface(), metrics(), &mock_manager_));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700839 NiceMock<MockStore> storage;
840 service_->set_profile(mock_profile);
841 service_->has_ever_connected_ = false;
Paul Stewartf2860342014-05-09 14:29:16 -0700842 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700843 EXPECT_CALL(*mock_profile, GetConstStorage())
844 .WillOnce(Return(&storage));
Paul Stewartf2860342014-05-09 14:29:16 -0700845 EXPECT_CALL(*mock_profile, UpdateService(IsRefPtrTo(service_)));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700846 service_->SetState(Service::kStateConnected);
847 EXPECT_TRUE(service_->has_ever_connected_);
Ben Chancc225ef2014-09-30 13:26:51 -0700848 service_->set_profile(nullptr); // Break reference cycle.
mukesh agrawalcf24a242012-05-21 16:46:11 -0700849
850 // Similar to the above, but emulate an emphemeral profile, which
851 // has no storage. We can't update the service in the profile, but
852 // we should not crash.
853 service_->state_ = Service::kStateIdle; // Skips state change logic.
854 service_->set_profile(mock_profile);
855 service_->has_ever_connected_ = false;
Paul Stewartf2860342014-05-09 14:29:16 -0700856 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Ben Chancc225ef2014-09-30 13:26:51 -0700857 EXPECT_CALL(*mock_profile, GetConstStorage()).WillOnce(Return(nullptr));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700858 service_->SetState(Service::kStateConnected);
859 EXPECT_TRUE(service_->has_ever_connected_);
Ben Chancc225ef2014-09-30 13:26:51 -0700860 service_->set_profile(nullptr); // Break reference cycle.
Paul Stewart03dba0b2011-08-22 16:32:45 -0700861}
862
Peter Qiu9b83c892014-08-09 23:06:02 -0700863TEST_F(ServiceTest, PortalDetectionFailure) {
864 EXPECT_CALL(*GetAdaptor(),
865 EmitStringChanged(kPortalDetectionFailedPhaseProperty,
866 kPortalDetectionPhaseDns)).Times(1);
867 EXPECT_CALL(*GetAdaptor(),
868 EmitStringChanged(kPortalDetectionFailedStatusProperty,
869 kPortalDetectionStatusTimeout)).Times(1);
870 service_->SetPortalDetectionFailure(kPortalDetectionPhaseDns,
871 kPortalDetectionStatusTimeout);
872 EXPECT_EQ(kPortalDetectionPhaseDns,
873 service_->portal_detection_failure_phase_);
874 EXPECT_EQ(kPortalDetectionStatusTimeout,
875 service_->portal_detection_failure_status_);
876}
877
Thieu Leaf471412013-06-27 14:12:37 -0700878TEST_F(ServiceTest, StateResetAfterFailure) {
879 service_->SetFailure(Service::kFailureOutOfRange);
880 EXPECT_EQ(Service::kStateFailure, service_->state());
881 Error error;
882 service_->Connect(&error, "in test");
883 EXPECT_EQ(Service::kStateIdle, service_->state());
884 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
885
886 service_->SetState(Service::kStateConnected);
887 service_->Connect(&error, "in test");
888 EXPECT_EQ(Service::kStateConnected, service_->state());
889}
890
Peter Qiudc4e0992014-05-01 10:02:52 -0700891TEST_F(ServiceTest, UserInitiatedConnectionResult) {
892 service_->technology_ = Technology::kWifi;
893 Error error;
894 // User-initiated connection attempt succeed.
895 service_->SetState(Service::kStateIdle);
896 service_->UserInitiatedConnect(&error);
897 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
898 Metrics::kMetricWifiUserInitiatedConnectionResult,
899 Metrics::kUserInitiatedConnectionResultSuccess));
Peter Qiud87179e2014-07-10 18:29:22 -0700900 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
901 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700902 service_->SetState(Service::kStateConnected);
903 Mock::VerifyAndClearExpectations(metrics());
904
905 // User-initiated connection attempt failed.
906 service_->SetState(Service::kStateIdle);
907 service_->UserInitiatedConnect(&error);
908 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
909 Metrics::kMetricWifiUserInitiatedConnectionResult,
910 Metrics::kUserInitiatedConnectionResultFailure));
Peter Qiud87179e2014-07-10 18:29:22 -0700911 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(
912 Metrics::kMetricWifiUserInitiatedConnectionFailureReason,
913 Service::kFailureDHCP));
914 service_->SetFailure(Service::kFailureDHCP);
Peter Qiudc4e0992014-05-01 10:02:52 -0700915 Mock::VerifyAndClearExpectations(metrics());
916
917 // User-initiated connection attempt aborted.
918 service_->SetState(Service::kStateIdle);
919 service_->UserInitiatedConnect(&error);
920 service_->SetState(Service::kStateAssociating);
921 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
922 Metrics::kMetricWifiUserInitiatedConnectionResult,
923 Metrics::kUserInitiatedConnectionResultAborted));
Peter Qiud87179e2014-07-10 18:29:22 -0700924 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
925 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700926 service_->SetState(Service::kStateIdle);
927 Mock::VerifyAndClearExpectations(metrics());
928
929 // No metric reporting for other state transition.
930 service_->SetState(Service::kStateIdle);
931 service_->UserInitiatedConnect(&error);
932 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700933 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
934 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700935 service_->SetState(Service::kStateAssociating);
936 service_->SetState(Service::kStateConfiguring);
937 Mock::VerifyAndClearExpectations(metrics());
938
939 // No metric reporting for non-user-initiated connection.
940 service_->SetState(Service::kStateIdle);
941 service_->Connect(&error, "in test");
942 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700943 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
944 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700945 service_->SetState(Service::kStateConnected);
946 Mock::VerifyAndClearExpectations(metrics());
947
948 // No metric reporting for other technology.
949 service_->technology_ = Technology::kCellular;
950 service_->SetState(Service::kStateIdle);
951 service_->UserInitiatedConnect(&error);
952 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700953 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
954 .Times(0);
955 service_->SetFailure(Service::kFailureDHCP);
Peter Qiudc4e0992014-05-01 10:02:52 -0700956 Mock::VerifyAndClearExpectations(metrics());
957}
958
Darin Petkovb100ae72011-08-24 16:19:45 -0700959TEST_F(ServiceTest, ActivateCellularModem) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500960 ResultCallback callback =
961 Bind(&ServiceTest::TestCallback, Unretained(this));
962 EXPECT_CALL(*this, TestCallback(_)).Times(0);
Darin Petkovb100ae72011-08-24 16:19:45 -0700963 Error error;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500964 service_->ActivateCellularModem("Carrier", &error, callback);
965 EXPECT_TRUE(error.IsFailure());
Darin Petkovb100ae72011-08-24 16:19:45 -0700966}
967
Ben Chan5d924542013-02-14 17:49:08 -0800968TEST_F(ServiceTest, CompleteCellularActivation) {
969 Error error;
970 service_->CompleteCellularActivation(&error);
971 EXPECT_EQ(Error::kNotSupported, error.type());
972}
973
Paul Stewart2da34c02013-10-17 15:28:56 -0700974TEST_F(ServiceTest, EnableAndRetainAutoConnect) {
975 EXPECT_FALSE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000976 EXPECT_FALSE(service_->auto_connect());
977
Paul Stewart2da34c02013-10-17 15:28:56 -0700978 service_->EnableAndRetainAutoConnect();
979 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000980 EXPECT_TRUE(service_->auto_connect());
981}
982
Paul Stewart2da34c02013-10-17 15:28:56 -0700983TEST_F(ServiceTest, ReRetainAutoConnect) {
984 service_->EnableAndRetainAutoConnect();
985 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000986 EXPECT_TRUE(service_->auto_connect());
987
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700988 service_->SetAutoConnect(false);
Paul Stewart2da34c02013-10-17 15:28:56 -0700989 service_->EnableAndRetainAutoConnect();
990 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000991 EXPECT_FALSE(service_->auto_connect());
992}
993
mukesh agrawal76d13882012-01-12 15:23:11 -0800994TEST_F(ServiceTest, IsAutoConnectable) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700995 const char* reason = nullptr;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700996 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100997
998 // Services with non-primary connectivity technologies should not auto-connect
999 // when the system is offline.
1000 EXPECT_EQ(Technology::kUnknown, service_->technology());
Peter Qiu700de642014-07-14 16:31:30 -07001001 EXPECT_CALL(mock_manager_, IsConnected()).WillOnce(Return(false));
Darin Petkov4cbff5b2013-01-29 16:29:05 +01001002 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1003 EXPECT_STREQ(Service::kAutoConnOffline, reason);
1004
1005 service_->technology_ = Technology::kEthernet;
mukesh agrawalbf14e942012-03-02 14:36:34 -08001006 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawal76d13882012-01-12 15:23:11 -08001007
mukesh agrawaladb68482012-01-17 16:31:51 -08001008 // We should not auto-connect to a Service that a user has
1009 // deliberately disconnected.
1010 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001011 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001012 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1013 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
mukesh agrawaladb68482012-01-17 16:31:51 -08001014
1015 // But if the Service is reloaded, it is eligible for auto-connect
1016 // again.
1017 NiceMock<MockStore> storage;
1018 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Peter Qiu1a72f542015-04-14 16:31:36 -07001019#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001020 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -07001021#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
mukesh agrawaladb68482012-01-17 16:31:51 -08001022 EXPECT_TRUE(service_->Load(&storage));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001023 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001024
1025 // A deliberate Connect should also re-enable auto-connect.
Christopher Wileyabd3b502012-09-26 13:08:52 -07001026 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001027 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07001028 service_->Connect(&error, "in test");
mukesh agrawalbf14e942012-03-02 14:36:34 -08001029 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001030
Christopher Wileyabd3b502012-09-26 13:08:52 -07001031 // A non-user initiated Disconnect doesn't change anything.
Samuel Tan0d061192014-07-07 15:45:15 -07001032 service_->Disconnect(&error, "in test");
Christopher Wileyabd3b502012-09-26 13:08:52 -07001033 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1034
Christopher Wileya4c61ae2012-10-01 11:04:30 -07001035 // A resume also re-enables auto-connect.
1036 service_->UserInitiatedDisconnect(&error);
1037 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1038 service_->OnAfterResume();
1039 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001040
mukesh agrawal76d13882012-01-12 15:23:11 -08001041 service_->SetState(Service::kStateConnected);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001042 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1043 EXPECT_STREQ(Service::kAutoConnConnected, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -08001044
1045 service_->SetState(Service::kStateAssociating);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001046 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1047 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
Ben Chan8e6b8ef2014-07-14 21:50:18 -07001048
1049 service_->SetState(Service::kStateIdle);
1050 EXPECT_CALL(mock_manager_, IsTechnologyAutoConnectDisabled(
1051 service_->technology_)).WillOnce(Return(true));
1052 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1053 EXPECT_STREQ(Service::kAutoConnTechnologyNotConnectable, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -08001054}
1055
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001056TEST_F(ServiceTest, AutoConnectLogging) {
1057 ScopedMockLog log;
1058 EXPECT_CALL(log, Log(_, _, _));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001059 service_->SetConnectable(true);
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001060
1061 ScopeLogger::GetInstance()->EnableScopesByName("+service");
1062 ScopeLogger::GetInstance()->set_verbose_level(1);
1063 service_->SetState(Service::kStateConnected);
1064 EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected)));
1065 service_->AutoConnect();
1066
1067 ScopeLogger::GetInstance()->EnableScopesByName("-service");
1068 ScopeLogger::GetInstance()->set_verbose_level(0);
1069 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1070 HasSubstr(Service::kAutoConnNotConnectable)));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001071 service_->SetConnectable(false);
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001072 service_->AutoConnect();
1073}
1074
1075
Christopher Wiley0801d192012-09-24 11:57:15 -07001076TEST_F(AllMockServiceTest, AutoConnectWithFailures) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001077 const char* reason;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001078 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +01001079 service_->technology_ = Technology::kEthernet;
Christopher Wiley0801d192012-09-24 11:57:15 -07001080 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1081
1082 // The very first AutoConnect() doesn't trigger any throttling.
1083 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1084 service_->AutoConnect();
1085 Mock::VerifyAndClearExpectations(&dispatcher_);
1086 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1087
1088 // The second call does trigger some throttling.
1089 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1090 Service::kMinAutoConnectCooldownTimeMilliseconds));
1091 service_->AutoConnect();
1092 Mock::VerifyAndClearExpectations(&dispatcher_);
1093 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1094 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1095
1096 // Calling AutoConnect() again before the cooldown terminates does not change
1097 // the timeout.
1098 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1099 service_->AutoConnect();
1100 Mock::VerifyAndClearExpectations(&dispatcher_);
1101 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1102 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1103
1104 // Once the timeout expires, we can AutoConnect() again.
1105 service_->ReEnableAutoConnectTask();
1106 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1107
1108 // Timeouts increase exponentially.
Ben Chan7fab8972014-08-10 17:14:46 -07001109 uint64_t next_cooldown_time = service_->auto_connect_cooldown_milliseconds_;
Christopher Wiley0801d192012-09-24 11:57:15 -07001110 EXPECT_EQ(next_cooldown_time,
1111 Service::kAutoConnectCooldownBackoffFactor *
1112 Service::kMinAutoConnectCooldownTimeMilliseconds);
1113 while (next_cooldown_time <=
1114 Service::kMaxAutoConnectCooldownTimeMilliseconds) {
1115 EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time));
1116 service_->AutoConnect();
1117 Mock::VerifyAndClearExpectations(&dispatcher_);
1118 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1119 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1120 service_->ReEnableAutoConnectTask();
1121 next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor;
1122 }
1123
1124 // Once we hit our cap, future timeouts are the same.
Ben Chan7fab8972014-08-10 17:14:46 -07001125 for (int32_t i = 0; i < 2; i++) {
Christopher Wiley0801d192012-09-24 11:57:15 -07001126 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1127 Service::kMaxAutoConnectCooldownTimeMilliseconds));
1128 service_->AutoConnect();
1129 Mock::VerifyAndClearExpectations(&dispatcher_);
1130 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1131 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1132 service_->ReEnableAutoConnectTask();
1133 }
1134
1135 // Connecting successfully resets our cooldown.
1136 service_->SetState(Service::kStateConnected);
1137 service_->SetState(Service::kStateIdle);
1138 reason = "";
1139 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1140 EXPECT_STREQ("", reason);
1141 EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0);
1142
1143 // But future AutoConnects behave as before
1144 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1145 Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1);
1146 service_->AutoConnect();
1147 service_->AutoConnect();
1148 Mock::VerifyAndClearExpectations(&dispatcher_);
1149 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1150 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1151
1152 // Cooldowns are forgotten if we go through a suspend/resume cycle.
1153 service_->OnAfterResume();
1154 reason = "";
1155 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1156 EXPECT_STREQ("", reason);
1157}
1158
Paul Stewartcb59fed2012-03-21 21:14:46 -07001159TEST_F(ServiceTest, ConfigureBadProperty) {
1160 KeyValueStore args;
1161 args.SetString("XXXInvalid", "Value");
1162 Error error;
1163 service_->Configure(args, &error);
1164 EXPECT_FALSE(error.IsSuccess());
1165}
1166
1167TEST_F(ServiceTest, ConfigureBoolProperty) {
Paul Stewart2da34c02013-10-17 15:28:56 -07001168 service_->EnableAndRetainAutoConnect();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001169 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001170 ASSERT_FALSE(service_->auto_connect());
1171 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001172 args.SetBool(kAutoConnectProperty, true);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001173 Error error;
1174 service_->Configure(args, &error);
1175 EXPECT_TRUE(error.IsSuccess());
1176 EXPECT_TRUE(service_->auto_connect());
1177}
1178
1179TEST_F(ServiceTest, ConfigureStringProperty) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001180 const string kGuid0 = "guid_zero";
1181 const string kGuid1 = "guid_one";
Ben Chancc225ef2014-09-30 13:26:51 -07001182 service_->SetGuid(kGuid0, nullptr);
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001183 ASSERT_EQ(kGuid0, service_->guid());
Paul Stewartcb59fed2012-03-21 21:14:46 -07001184 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001185 args.SetString(kGuidProperty, kGuid1);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001186 Error error;
1187 service_->Configure(args, &error);
1188 EXPECT_TRUE(error.IsSuccess());
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001189 EXPECT_EQ(kGuid1, service_->guid());
1190}
1191
Paul Stewart99dc9f32013-06-27 07:39:25 -07001192TEST_F(ServiceTest, ConfigureStringsProperty) {
1193 const vector<string> kStrings0{ "string0", "string1" };
1194 const vector<string> kStrings1{ "string2", "string3" };
1195 service_->set_strings(kStrings0);
1196 ASSERT_EQ(kStrings0, service_->strings());
1197 KeyValueStore args;
1198 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
1199 Error error;
1200 service_->Configure(args, &error);
1201 EXPECT_TRUE(error.IsSuccess());
1202 EXPECT_EQ(kStrings1, service_->strings());
1203}
1204
Peter Qiu1a72f542015-04-14 16:31:36 -07001205#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001206TEST_F(ServiceTest, ConfigureEapStringProperty) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001207 MockEapCredentials* eap = new MockEapCredentials();
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001208 service2_->SetEapCredentials(eap); // Passes ownership.
1209
1210 const string kEAPManagement0 = "management_zero";
1211 const string kEAPManagement1 = "management_one";
1212 service2_->SetEAPKeyManagement(kEAPManagement0);
1213
1214 EXPECT_CALL(*eap, key_management())
1215 .WillOnce(ReturnRef(kEAPManagement0));
1216 ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement());
1217 KeyValueStore args;
1218 EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _));
Ben Chan923a5022013-09-20 11:23:23 -07001219 args.SetString(kEapKeyMgmtProperty, kEAPManagement1);
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001220 Error error;
1221 service2_->Configure(args, &error);
1222 EXPECT_TRUE(error.IsSuccess());
Paul Stewartcb59fed2012-03-21 21:14:46 -07001223}
Peter Qiu1a72f542015-04-14 16:31:36 -07001224#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartcb59fed2012-03-21 21:14:46 -07001225
Paul Stewart7a20aa42013-01-17 12:21:41 -08001226TEST_F(ServiceTest, ConfigureIntProperty) {
1227 const int kPriority0 = 100;
1228 const int kPriority1 = 200;
Ben Chancc225ef2014-09-30 13:26:51 -07001229 service_->SetPriority(kPriority0, nullptr);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001230 ASSERT_EQ(kPriority0, service_->priority());
1231 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001232 args.SetInt(kPriorityProperty, kPriority1);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001233 Error error;
1234 service_->Configure(args, &error);
1235 EXPECT_TRUE(error.IsSuccess());
1236 EXPECT_EQ(kPriority1, service_->priority());
1237}
1238
Paul Stewartcb59fed2012-03-21 21:14:46 -07001239TEST_F(ServiceTest, ConfigureIgnoredProperty) {
Paul Stewart2da34c02013-10-17 15:28:56 -07001240 service_->EnableAndRetainAutoConnect();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001241 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001242 ASSERT_FALSE(service_->auto_connect());
1243 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001244 args.SetBool(kAutoConnectProperty, true);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001245 Error error;
Ben Chan923a5022013-09-20 11:23:23 -07001246 service_->IgnoreParameterForConfigure(kAutoConnectProperty);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001247 service_->Configure(args, &error);
1248 EXPECT_TRUE(error.IsSuccess());
1249 EXPECT_FALSE(service_->auto_connect());
1250}
1251
Paul Stewartad0e5982013-07-02 08:47:47 -07001252TEST_F(ServiceTest, ConfigureProfileProperty) {
1253 // Ensure that the Profile property is always ignored.
1254 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001255 args.SetString(kProfileProperty, "profile");
Paul Stewartad0e5982013-07-02 08:47:47 -07001256 Error error;
1257 EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
1258 service_->Configure(args, &error);
1259 EXPECT_TRUE(error.IsSuccess());
1260}
1261
Paul Stewartbb833562015-01-21 23:30:46 -08001262TEST_F(ServiceTest, ConfigureKeyValueStoreProperty) {
1263 KeyValueStore key_value_store0;
1264 key_value_store0.SetBool("key0", true);
1265 KeyValueStore key_value_store1;
1266 key_value_store1.SetInt("key1", 1);
1267 service_->SetKeyValueStore(key_value_store0, NULL);
1268 ASSERT_TRUE(key_value_store0.Equals(service_->GetKeyValueStore(NULL)));
1269 KeyValueStore args;
1270 args.SetKeyValueStore(
1271 ServiceUnderTest::kKeyValueStoreProperty, key_value_store1);
1272 Error error;
1273 service_->Configure(args, &error);
1274 EXPECT_TRUE(error.IsSuccess());
1275 EXPECT_TRUE(key_value_store1.Equals(service_->GetKeyValueStore(NULL)));
1276}
1277
Paul Stewart7a20aa42013-01-17 12:21:41 -08001278TEST_F(ServiceTest, DoPropertiesMatch) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001279 service_->SetAutoConnect(false);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001280 const string kGUID0 = "guid_zero";
1281 const string kGUID1 = "guid_one";
Ben Chancc225ef2014-09-30 13:26:51 -07001282 service_->SetGuid(kGUID0, nullptr);
Ben Chan7fab8972014-08-10 17:14:46 -07001283 const uint32_t kPriority0 = 100;
1284 const uint32_t kPriority1 = 200;
Ben Chancc225ef2014-09-30 13:26:51 -07001285 service_->SetPriority(kPriority0, nullptr);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001286 const vector<string> kStrings0{ "string0", "string1" };
1287 const vector<string> kStrings1{ "string2", "string3" };
1288 service_->set_strings(kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001289 KeyValueStore key_value_store0;
1290 key_value_store0.SetBool("key0", true);
1291 KeyValueStore key_value_store1;
1292 key_value_store1.SetInt("key1", 1);
1293 service_->SetKeyValueStore(key_value_store0, NULL);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001294
1295 {
1296 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001297 args.SetString(kGuidProperty, kGUID0);
1298 args.SetBool(kAutoConnectProperty, false);
1299 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001300 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001301 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1302 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001303 EXPECT_TRUE(service_->DoPropertiesMatch(args));
1304 }
1305 {
1306 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001307 args.SetString(kGuidProperty, kGUID1);
1308 args.SetBool(kAutoConnectProperty, false);
1309 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001310 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001311 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1312 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001313 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1314 }
1315 {
1316 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001317 args.SetString(kGuidProperty, kGUID0);
1318 args.SetBool(kAutoConnectProperty, true);
1319 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001320 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001321 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1322 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001323 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1324 }
1325 {
1326 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001327 args.SetString(kGuidProperty, kGUID0);
1328 args.SetBool(kAutoConnectProperty, false);
1329 args.SetInt(kPriorityProperty, kPriority1);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001330 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001331 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1332 key_value_store0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001333 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1334 }
1335 {
1336 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001337 args.SetString(kGuidProperty, kGUID0);
1338 args.SetBool(kAutoConnectProperty, false);
1339 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001340 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
Paul Stewartbb833562015-01-21 23:30:46 -08001341 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1342 key_value_store0);
1343 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1344 }
1345 {
1346 KeyValueStore args;
1347 args.SetString(kGuidProperty, kGUID0);
1348 args.SetBool(kAutoConnectProperty, false);
1349 args.SetInt(kPriorityProperty, kPriority0);
1350 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1351 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1352 key_value_store1);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001353 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1354 }
1355}
1356
Paul Stewart10ccbb32012-04-26 15:59:30 -07001357TEST_F(ServiceTest, IsRemembered) {
Ben Chancc225ef2014-09-30 13:26:51 -07001358 service_->set_profile(nullptr);
Paul Stewart10ccbb32012-04-26 15:59:30 -07001359 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
1360 EXPECT_FALSE(service_->IsRemembered());
1361
1362 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001363 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Paul Stewart10ccbb32012-04-26 15:59:30 -07001364 service_->set_profile(profile);
Paul Stewartf2860342014-05-09 14:29:16 -07001365 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
Paul Stewart10ccbb32012-04-26 15:59:30 -07001366 .WillOnce(Return(true))
1367 .WillOnce(Return(false));
1368 EXPECT_FALSE(service_->IsRemembered());
1369 EXPECT_TRUE(service_->IsRemembered());
1370}
1371
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001372TEST_F(ServiceTest, IsDependentOn) {
Ben Chancc225ef2014-09-30 13:26:51 -07001373 EXPECT_FALSE(service_->IsDependentOn(nullptr));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001374
Ben Chancd477322014-10-17 14:19:30 -07001375 std::unique_ptr<MockDeviceInfo> mock_device_info(
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001376 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1377 &mock_manager_));
1378 scoped_refptr<MockConnection> mock_connection0(
1379 new NiceMock<MockConnection>(mock_device_info.get()));
1380 scoped_refptr<MockConnection> mock_connection1(
1381 new NiceMock<MockConnection>(mock_device_info.get()));
1382
1383 service_->connection_ = mock_connection0;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001384 EXPECT_CALL(*mock_connection0, GetLowerConnection())
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001385 .WillRepeatedly(Return(mock_connection1));
Paul Stewartcd7f5852013-03-27 13:54:23 -07001386 EXPECT_CALL(*mock_connection1, GetLowerConnection())
1387 .WillRepeatedly(Return(ConnectionRefPtr()));
Ben Chancc225ef2014-09-30 13:26:51 -07001388 EXPECT_FALSE(service_->IsDependentOn(nullptr));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001389
1390 scoped_refptr<ServiceUnderTest> service1 =
1391 new ServiceUnderTest(control_interface(),
1392 dispatcher(),
1393 metrics(),
1394 &mock_manager_);
1395 EXPECT_FALSE(service_->IsDependentOn(service1));
1396
1397 service1->connection_ = mock_connection0;
1398 EXPECT_FALSE(service_->IsDependentOn(service1));
1399
1400 service1->connection_ = mock_connection1;
1401 EXPECT_TRUE(service_->IsDependentOn(service1));
1402
Paul Stewartcd7f5852013-03-27 13:54:23 -07001403 service_->connection_ = mock_connection1;
Ben Chancc225ef2014-09-30 13:26:51 -07001404 service1->connection_ = nullptr;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001405 EXPECT_FALSE(service_->IsDependentOn(service1));
1406
Ben Chancc225ef2014-09-30 13:26:51 -07001407 service_->connection_ = nullptr;
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001408}
1409
Paul Stewartff14b022012-04-24 20:06:23 -07001410TEST_F(ServiceTest, OnPropertyChanged) {
1411 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001412 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Ben Chancc225ef2014-09-30 13:26:51 -07001413 service_->set_profile(nullptr);
Paul Stewartff14b022012-04-24 20:06:23 -07001414 // Expect no crash.
1415 service_->OnPropertyChanged("");
1416
1417 // Expect no call to Update if the profile has no storage.
1418 service_->set_profile(profile);
1419 EXPECT_CALL(*profile, UpdateService(_)).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -07001420 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(nullptr));
Paul Stewartff14b022012-04-24 20:06:23 -07001421 service_->OnPropertyChanged("");
1422
1423 // Expect call to Update if the profile has storage.
1424 EXPECT_CALL(*profile, UpdateService(_)).Times(1);
1425 NiceMock<MockStore> storage;
1426 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
1427 service_->OnPropertyChanged("");
1428}
1429
Paul Stewartd215af62012-04-24 23:25:50 -07001430
1431TEST_F(ServiceTest, RecheckPortal) {
Paul Stewartd215af62012-04-24 23:25:50 -07001432 service_->state_ = Service::kStateIdle;
1433 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
Ben Chan923a5022013-09-20 11:23:23 -07001434 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001435
1436 service_->state_ = Service::kStatePortal;
Paul Stewartf2860342014-05-09 14:29:16 -07001437 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1438 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001439 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001440
1441 service_->state_ = Service::kStateConnected;
Paul Stewartf2860342014-05-09 14:29:16 -07001442 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1443 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001444 service_->OnPropertyChanged(kProxyConfigProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001445
1446 service_->state_ = Service::kStateOnline;
Paul Stewartf2860342014-05-09 14:29:16 -07001447 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1448 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001449 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001450
1451 service_->state_ = Service::kStatePortal;
1452 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
Ben Chan011e6662014-05-07 11:03:25 -07001453 service_->OnPropertyChanged(kEapKeyIdProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001454}
1455
1456TEST_F(ServiceTest, SetCheckPortal) {
Paul Stewartd215af62012-04-24 23:25:50 -07001457 {
1458 Error error;
1459 service_->SetCheckPortal("false", &error);
1460 EXPECT_TRUE(error.IsSuccess());
1461 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
1462 }
1463 {
1464 Error error;
1465 service_->SetCheckPortal("true", &error);
1466 EXPECT_TRUE(error.IsSuccess());
1467 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
1468 }
1469 {
1470 Error error;
1471 service_->SetCheckPortal("auto", &error);
1472 EXPECT_TRUE(error.IsSuccess());
1473 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1474 }
1475 {
1476 Error error;
1477 service_->SetCheckPortal("xxx", &error);
1478 EXPECT_FALSE(error.IsSuccess());
1479 EXPECT_EQ(Error::kInvalidArguments, error.type());
1480 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1481 }
1482}
1483
Arman Uguray2717a102013-01-29 23:36:06 -08001484TEST_F(ServiceTest, SetFriendlyName) {
1485 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
Paul Stewart3b30ca52015-06-16 13:13:10 -07001486 ServiceMockAdaptor* adaptor = GetAdaptor();
Arman Uguray2717a102013-01-29 23:36:06 -08001487
1488 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1489 service_->SetFriendlyName(service_->unique_name_);
1490 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
1491
Ben Chan923a5022013-09-20 11:23:23 -07001492 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
Arman Uguray2717a102013-01-29 23:36:06 -08001493 "Test Name 1"));
1494 service_->SetFriendlyName("Test Name 1");
1495 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1496
1497 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1498 service_->SetFriendlyName("Test Name 1");
1499 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1500
Ben Chan923a5022013-09-20 11:23:23 -07001501 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
Arman Uguray2717a102013-01-29 23:36:06 -08001502 "Test Name 2"));
1503 service_->SetFriendlyName("Test Name 2");
1504 EXPECT_EQ("Test Name 2", service_->friendly_name_);
1505}
1506
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001507TEST_F(ServiceTest, SetConnectableFull) {
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001508 EXPECT_FALSE(service_->connectable());
1509
Paul Stewart3b30ca52015-06-16 13:13:10 -07001510 ServiceMockAdaptor* adaptor = GetAdaptor();
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001511
1512 EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0);
1513 EXPECT_CALL(mock_manager_, HasService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001514 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001515 EXPECT_FALSE(service_->connectable());
1516
Ben Chan923a5022013-09-20 11:23:23 -07001517 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001518 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false));
1519 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001520 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001521 EXPECT_TRUE(service_->connectable());
1522
Ben Chan923a5022013-09-20 11:23:23 -07001523 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, false));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001524 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1525 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001526 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001527 EXPECT_FALSE(service_->connectable());
1528
Ben Chan923a5022013-09-20 11:23:23 -07001529 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001530 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1531 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001532 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001533 EXPECT_TRUE(service_->connectable());
1534}
1535
Peter Qiu1a72f542015-04-14 16:31:36 -07001536#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001537class WriteOnlyServicePropertyTest : public ServiceTest {};
1538TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) {
1539 // Use a real EapCredentials instance since the base Service class
1540 // contains no write-only properties.
1541 EapCredentials eap;
1542 eap.InitPropertyStore(service_->mutable_store());
1543
Paul Stewart9f32d192012-01-30 20:37:50 -08001544 string property(GetParam().reader().get_string());
Paul Stewarte6e8e492013-01-17 11:00:50 -08001545 Error error;
Ben Chancc225ef2014-09-30 13:26:51 -07001546 EXPECT_FALSE(service_->store().GetStringProperty(property, nullptr, &error));
Paul Stewarte6e8e492013-01-17 11:00:50 -08001547 EXPECT_EQ(Error::kPermissionDenied, error.type());
Paul Stewart9f32d192012-01-30 20:37:50 -08001548}
1549
1550INSTANTIATE_TEST_CASE_P(
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001551 WriteOnlyServicePropertyTestInstance,
1552 WriteOnlyServicePropertyTest,
Paul Stewart9f32d192012-01-30 20:37:50 -08001553 Values(
Ben Chan923a5022013-09-20 11:23:23 -07001554 DBusAdaptor::StringToVariant(kEapPrivateKeyPasswordProperty),
1555 DBusAdaptor::StringToVariant(kEapPasswordProperty)));
Peter Qiu1a72f542015-04-14 16:31:36 -07001556#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart10241e32012-04-23 18:15:06 -07001557
1558TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
1559 {
1560 Error error;
1561 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1562 EXPECT_EQ(Error::kNotFound, error.type());
1563 }
1564
Ben Chancd477322014-10-17 14:19:30 -07001565 std::unique_ptr<MockDeviceInfo> mock_device_info(
Paul Stewart10241e32012-04-23 18:15:06 -07001566 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1567 &mock_manager_));
1568 scoped_refptr<MockConnection> mock_connection(
1569 new NiceMock<MockConnection>(mock_device_info.get()));
1570
1571 service_->connection_ = mock_connection;
1572
1573 {
1574 Error error;
1575 const string empty_string;
1576 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1577 .WillOnce(ReturnRef(empty_string));
1578 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1579 EXPECT_EQ(Error::kNotFound, error.type());
1580 }
1581
1582 {
1583 Error error;
1584 const string nonempty_string("/ipconfig/path");
1585 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1586 .WillOnce(ReturnRef(nonempty_string));
1587 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
1588 EXPECT_EQ(Error::kSuccess, error.type());
1589 }
1590
1591 // Assure orderly destruction of the Connection before DeviceInfo.
Ben Chancc225ef2014-09-30 13:26:51 -07001592 service_->connection_ = nullptr;
1593 mock_connection = nullptr;
Paul Stewart10241e32012-04-23 18:15:06 -07001594 mock_device_info.reset();
1595}
1596
Peter Qiu1a72f542015-04-14 16:31:36 -07001597#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001598class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest {
Paul Stewart81426132012-05-16 10:05:10 -07001599 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -07001600 ServiceWithMockOnEapCredentialsChanged(ControlInterface* control_interface,
1601 EventDispatcher* dispatcher,
1602 Metrics* metrics,
1603 Manager* manager)
Paul Stewart81426132012-05-16 10:05:10 -07001604 : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
1605 is_8021x_(false) {}
Rebecca Silberstein57776902014-09-15 21:43:02 -07001606 MOCK_METHOD1(OnEapCredentialsChanged, void(Service::UpdateCredentialsReason));
Paul Stewart81426132012-05-16 10:05:10 -07001607 virtual bool Is8021x() const { return is_8021x_; }
1608 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }
1609
1610 private:
1611 bool is_8021x_;
1612};
1613
1614TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001615 scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service(
1616 new ServiceWithMockOnEapCredentialsChanged(control_interface(),
1617 dispatcher(),
1618 metrics(),
1619 &mock_manager_));
Paul Stewart81426132012-05-16 10:05:10 -07001620 string eap_credential_properties[] = {
Ben Chan923a5022013-09-20 11:23:23 -07001621 kEapAnonymousIdentityProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001622 kEapCertIdProperty,
1623 kEapClientCertProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001624 kEapIdentityProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001625 kEapKeyIdProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001626 kEapPasswordProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001627 kEapPinProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001628 kEapPrivateKeyProperty,
1629 kEapPrivateKeyPasswordProperty
Paul Stewart81426132012-05-16 10:05:10 -07001630 };
1631 string eap_non_credential_properties[] = {
Ben Chan011e6662014-05-07 11:03:25 -07001632 kEapCaCertIdProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001633 kEapCaCertNssProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001634 kEapMethodProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001635 kEapPhase2AuthProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001636 kEapUseSystemCasProperty
Paul Stewart81426132012-05-16 10:05:10 -07001637 };
1638 // While this is not an 802.1x-based service, none of these property
1639 // changes should cause a call to set_eap().
Rebecca Silberstein57776902014-09-15 21:43:02 -07001640 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001641 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
1642 service->OnPropertyChanged(eap_credential_properties[i]);
1643 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1644 service->OnPropertyChanged(eap_non_credential_properties[i]);
Ben Chan923a5022013-09-20 11:23:23 -07001645 service->OnPropertyChanged(kEapKeyMgmtProperty);
Paul Stewart81426132012-05-16 10:05:10 -07001646
1647 service->set_is_8021x(true);
1648
1649 // When this is an 802.1x-based service, set_eap should be called for
1650 // all credential-carrying properties.
1651 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
Rebecca Silberstein57776902014-09-15 21:43:02 -07001652 EXPECT_CALL(*service,
1653 OnEapCredentialsChanged(
1654 Service::kReasonPropertyUpdate)).Times(1);
Paul Stewart81426132012-05-16 10:05:10 -07001655 service->OnPropertyChanged(eap_credential_properties[i]);
1656 Mock::VerifyAndClearExpectations(service.get());
1657 }
Paul Stewartadf79d82012-07-18 16:09:56 -07001658
1659 // The key management property is a special case. While not strictly
1660 // a credential, it can change which credentials are used. Therefore it
1661 // should also trigger a call to set_eap();
Rebecca Silberstein57776902014-09-15 21:43:02 -07001662 EXPECT_CALL(*service,
1663 OnEapCredentialsChanged(Service::kReasonPropertyUpdate)).Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001664 service->OnPropertyChanged(kEapKeyMgmtProperty);
Paul Stewartadf79d82012-07-18 16:09:56 -07001665 Mock::VerifyAndClearExpectations(service.get());
1666
Rebecca Silberstein57776902014-09-15 21:43:02 -07001667 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001668 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1669 service->OnPropertyChanged(eap_non_credential_properties[i]);
1670}
1671
Paul Stewartbc6e7392012-05-24 07:07:48 -07001672TEST_F(ServiceTest, Certification) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001673 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001674
1675 ScopedMockLog log;
1676 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1677 HasSubstr("exceeds our maximum"))).Times(2);
1678 string kSubject("foo");
1679 EXPECT_FALSE(service_->AddEAPCertification(
1680 kSubject, Service::kEAPMaxCertificationElements));
1681 EXPECT_FALSE(service_->AddEAPCertification(
1682 kSubject, Service::kEAPMaxCertificationElements + 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001683 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001684 Mock::VerifyAndClearExpectations(&log);
1685
1686 EXPECT_CALL(log,
1687 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1688 .Times(1);
1689 EXPECT_TRUE(service_->AddEAPCertification(
1690 kSubject, Service::kEAPMaxCertificationElements - 1));
1691 Mock::VerifyAndClearExpectations(&log);
1692 EXPECT_EQ(Service::kEAPMaxCertificationElements,
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001693 service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001694 for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001695 EXPECT_TRUE(service_->remote_certification_[i].empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001696 }
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001697 EXPECT_EQ(kSubject, service_->remote_certification_[
Paul Stewartbc6e7392012-05-24 07:07:48 -07001698 Service::kEAPMaxCertificationElements - 1]);
1699
1700 // Re-adding the same name in the same position should not generate a log.
1701 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1702 EXPECT_TRUE(service_->AddEAPCertification(
1703 kSubject, Service::kEAPMaxCertificationElements - 1));
1704
1705 // Replacing the item should generate a log message.
1706 EXPECT_CALL(log,
1707 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1708 .Times(1);
1709 EXPECT_TRUE(service_->AddEAPCertification(
1710 kSubject + "x", Service::kEAPMaxCertificationElements - 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001711
1712 service_->ClearEAPCertification();
1713 EXPECT_TRUE(service_->remote_certification_.empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001714}
Peter Qiu1a72f542015-04-14 16:31:36 -07001715#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartbc6e7392012-05-24 07:07:48 -07001716
Darin Petkovc8d91e52013-01-21 11:43:47 +01001717TEST_F(ServiceTest, NoteDisconnectEventIdle) {
Paul Stewart483e4722012-12-18 10:23:17 -08001718 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001719 EXPECT_CALL(time_, GetNow()).Times(7).WillRepeatedly((Return(timestamp)));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001720 SetStateField(Service::kStateOnline);
Darin Petkov0857f8e2012-12-21 10:49:17 +01001721 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001722 service_->SetState(Service::kStateIdle);
Darin Petkovc8d91e52013-01-21 11:43:47 +01001723 // The transition Online->Idle is not an event.
Darin Petkov0857f8e2012-12-21 10:49:17 +01001724 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkovc8d91e52013-01-21 11:43:47 +01001725 service_->SetState(Service::kStateFailure);
1726 // The transition Online->Idle->Failure is a connection drop.
1727 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov0857f8e2012-12-21 10:49:17 +01001728}
1729
1730TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) {
1731 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001732 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
Darin Petkov0857f8e2012-12-21 10:49:17 +01001733 SetStateField(Service::kStateOnline);
1734 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1735 service_->SetState(Service::kStateFailure);
1736 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1737}
1738
1739TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) {
1740 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001741 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
Darin Petkov0857f8e2012-12-21 10:49:17 +01001742 SetStateField(Service::kStateConfiguring);
1743 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1744 service_->SetFailureSilent(Service::kFailureEAPAuthentication);
Paul Stewart483e4722012-12-18 10:23:17 -08001745 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001746}
1747
1748TEST_F(ServiceTest, NoteDisconnectEventNonEvent) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001749 EXPECT_CALL(time_, GetNow()).Times(0);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001750 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1751
1752 // Explicit disconnect is a non-event.
1753 SetStateField(Service::kStateOnline);
1754 SetExplicitlyDisconnected(true);
1755 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001756 EXPECT_TRUE(GetDisconnects()->Empty());
1757 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001758
1759 // Failure to idle transition is a non-event.
1760 SetStateField(Service::kStateFailure);
1761 SetExplicitlyDisconnected(false);
1762 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001763 EXPECT_TRUE(GetDisconnects()->Empty());
1764 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkovcb0b5662012-12-13 09:59:44 +01001765
1766 // Disconnect while manager is stopped is a non-event.
1767 SetStateField(Service::kStateOnline);
1768 SetManagerRunning(false);
1769 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001770 EXPECT_TRUE(GetDisconnects()->Empty());
1771 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkovcb0b5662012-12-13 09:59:44 +01001772
1773 // Disconnect while suspending is a non-event.
1774 SetManagerRunning(true);
Daniel Eratfac09532014-04-17 20:25:59 -07001775 SetSuspending(true);
Darin Petkovcb0b5662012-12-13 09:59:44 +01001776 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001777 EXPECT_TRUE(GetDisconnects()->Empty());
1778 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001779}
1780
1781TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001782 const int kNow = 5;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001783 EXPECT_FALSE(service_->explicitly_disconnected());
1784 SetStateField(Service::kStateOnline);
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001785 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001786 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1787 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001788 ASSERT_EQ(1, GetDisconnects()->Size());
1789 EXPECT_EQ(kNow, GetDisconnects()->Front().monotonic.tv_sec);
1790 EXPECT_TRUE(GetMisconnects()->Empty());
Paul Stewart483e4722012-12-18 10:23:17 -08001791
1792 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001793 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001794 kNow + GetDisconnectsMonitorSeconds() - 1,
1795 kNow + GetDisconnectsMonitorSeconds() - 1,
1796 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001797 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001798 ASSERT_EQ(1, GetDisconnects()->Size());
Paul Stewart483e4722012-12-18 10:23:17 -08001799
1800 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001801 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001802 kNow + GetDisconnectsMonitorSeconds(),
1803 kNow + GetDisconnectsMonitorSeconds(),
1804 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001805 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001806 ASSERT_TRUE(GetDisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001807}
1808
1809TEST_F(ServiceTest, NoteDisconnectEventDisconnectThreshold) {
1810 EXPECT_FALSE(service_->explicitly_disconnected());
1811 SetStateField(Service::kStateOnline);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001812 const int kNow = 6;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001813 for (int i = 0; i < GetReportDisconnectsThreshold() - 1; i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001814 PushTimestamp(GetDisconnects(), kNow, kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001815 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001816 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001817 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1818 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001819 EXPECT_EQ(GetReportDisconnectsThreshold(), GetDisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001820}
1821
1822TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001823 const int kNow = 7;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001824 EXPECT_FALSE(service_->explicitly_disconnected());
1825 SetStateField(Service::kStateConfiguring);
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001826 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001827 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1828 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001829 EXPECT_TRUE(GetDisconnects()->Empty());
1830 ASSERT_EQ(1, GetMisconnects()->Size());
1831 EXPECT_EQ(kNow, GetMisconnects()->Front().monotonic.tv_sec);
Paul Stewart483e4722012-12-18 10:23:17 -08001832
1833 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001834 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001835 kNow + GetMisconnectsMonitorSeconds() - 1,
1836 kNow + GetMisconnectsMonitorSeconds() - 1,
1837 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001838 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001839 ASSERT_EQ(1, GetMisconnects()->Size());
Paul Stewart483e4722012-12-18 10:23:17 -08001840
1841 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001842 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001843 kNow + GetMisconnectsMonitorSeconds(),
1844 kNow + GetMisconnectsMonitorSeconds(),
1845 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001846 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001847 ASSERT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001848}
1849
1850TEST_F(ServiceTest, NoteDisconnectEventMisconnectThreshold) {
1851 EXPECT_FALSE(service_->explicitly_disconnected());
1852 SetStateField(Service::kStateConfiguring);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001853 const int kNow = 8;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001854 for (int i = 0; i < GetReportMisconnectsThreshold() - 1; i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001855 PushTimestamp(GetMisconnects(), kNow, kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001856 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001857 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001858 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1859 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001860 EXPECT_EQ(GetReportMisconnectsThreshold(), GetMisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001861}
1862
1863TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) {
1864 EXPECT_FALSE(service_->explicitly_disconnected());
1865 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1866 for (int i = 0; i < 2; i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001867 int now = 0;
Paul Stewart3b30ca52015-06-16 13:13:10 -07001868 EventHistory* events = nullptr;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001869 if (i == 0) {
1870 SetStateField(Service::kStateConnected);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001871 now = GetDisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001872 events = GetDisconnects();
1873 } else {
1874 SetStateField(Service::kStateAssociating);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001875 now = GetMisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001876 events = GetMisconnects();
1877 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001878 PushTimestamp(events, 0, 0, "");
1879 PushTimestamp(events, 0, 0, "");
1880 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, now, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001881 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001882 ASSERT_EQ(1, events->Size());
1883 EXPECT_EQ(now, events->Front().monotonic.tv_sec);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001884 }
1885}
1886
1887TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) {
1888 EXPECT_FALSE(service_->explicitly_disconnected());
1889 SetStateField(Service::kStateOnline);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001890 for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001891 PushTimestamp(GetDisconnects(), 0, 0, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001892 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001893 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001894 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1895 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001896 EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001897}
1898
Samuel Tan07dfabc2015-01-20 15:10:39 -08001899TEST_F(ServiceTest, NoteMisconnectEventDiscardExcessive) {
1900 EXPECT_FALSE(service_->explicitly_disconnected());
1901 SetStateField(Service::kStateAssociating);
1902 for (int i = 0; i < 2 * GetMaxMisconnectEventHistory(); i++) {
1903 PushTimestamp(GetMisconnects(), 0, 0, "");
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001904 }
Samuel Tan07dfabc2015-01-20 15:10:39 -08001905 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
1906 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1907 NoteDisconnectEvent();
1908 EXPECT_EQ(GetMaxMisconnectEventHistory(), GetMisconnects()->Size());
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001909}
1910
1911TEST_F(ServiceTest, DiagnosticsProperties) {
Darin Petkov0857f8e2012-12-21 10:49:17 +01001912 const string kWallClock0 = "2012-12-09T12:41:22.234567-0800";
1913 const string kWallClock1 = "2012-12-31T23:59:59.345678-0800";
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001914 Strings values;
1915
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001916 PushTimestamp(GetDisconnects(), 0, 0, kWallClock0);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001917 Error unused_error;
1918 ASSERT_TRUE(service_->store().GetStringsProperty(
1919 kDiagnosticsDisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001920 ASSERT_EQ(1, values.size());
1921 EXPECT_EQ(kWallClock0, values[0]);
1922
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001923 PushTimestamp(GetMisconnects(), 0, 0, kWallClock1);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001924 ASSERT_TRUE(service_->store().GetStringsProperty(
1925 kDiagnosticsMisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001926 ASSERT_EQ(1, values.size());
1927 EXPECT_EQ(kWallClock1, values[0]);
1928}
1929
mukesh agrawal43970a22013-02-15 16:00:07 -08001930TEST_F(ServiceTest, SecurityLevel) {
1931 // Encrypted is better than not.
1932 service_->SetSecurity(Service::kCryptoNone, false, false);
1933 service2_->SetSecurity(Service::kCryptoRc4, false, false);
1934 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1935
1936 // AES encryption is better than RC4 encryption.
1937 service_->SetSecurity(Service::kCryptoRc4, false, false);
1938 service2_->SetSecurity(Service::kCryptoAes, false, false);
1939 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1940
1941 // Crypto algorithm is more important than key rotation.
1942 service_->SetSecurity(Service::kCryptoNone, true, false);
1943 service2_->SetSecurity(Service::kCryptoAes, false, false);
1944 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1945
1946 // Encrypted-but-unauthenticated is better than clear-but-authenticated.
1947 service_->SetSecurity(Service::kCryptoNone, false, true);
1948 service2_->SetSecurity(Service::kCryptoAes, false, false);
1949 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1950
1951 // For same encryption, prefer key rotation.
1952 service_->SetSecurity(Service::kCryptoRc4, false, false);
1953 service2_->SetSecurity(Service::kCryptoRc4, true, false);
1954 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1955
1956 // For same encryption, prefer authenticated AP.
1957 service_->SetSecurity(Service::kCryptoRc4, false, false);
1958 service2_->SetSecurity(Service::kCryptoRc4, false, true);
1959 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1960}
1961
Darin Petkovaba89322013-03-11 14:48:22 +01001962TEST_F(ServiceTest, SetErrorDetails) {
1963 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1964 static const char kDetails[] = "Certificate revoked.";
Paul Stewart3b30ca52015-06-16 13:13:10 -07001965 ServiceMockAdaptor* adaptor = GetAdaptor();
Ben Chan39a7beb2013-09-21 11:28:00 -07001966 EXPECT_CALL(*adaptor, EmitStringChanged(kErrorDetailsProperty, kDetails));
Darin Petkovaba89322013-03-11 14:48:22 +01001967 service_->SetErrorDetails(Service::kErrorDetailsNone);
1968 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1969 service_->SetErrorDetails(kDetails);
1970 EXPECT_EQ(kDetails, service_->error_details());
1971 service_->SetErrorDetails(kDetails);
1972}
1973
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001974TEST_F(ServiceTest, SetAutoConnectFull) {
Darin Petkov36d962d2013-03-25 13:03:14 +01001975 EXPECT_FALSE(service_->auto_connect());
1976 Error error;
1977 EXPECT_FALSE(GetAutoConnect(&error));
1978 EXPECT_TRUE(error.IsSuccess());
1979
1980 // false -> false
Paul Stewart2da34c02013-10-17 15:28:56 -07001981 EXPECT_FALSE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01001982 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001983 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001984 EXPECT_TRUE(error.IsSuccess());
1985 EXPECT_FALSE(service_->auto_connect());
Paul Stewart2da34c02013-10-17 15:28:56 -07001986 EXPECT_TRUE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07001987 EXPECT_FALSE(GetAutoConnect(nullptr));
Darin Petkov36d962d2013-03-25 13:03:14 +01001988 Mock::VerifyAndClearExpectations(&mock_manager_);
1989
Paul Stewart2da34c02013-10-17 15:28:56 -07001990 // Clear the |retain_auto_connect_| flag for the next test.
Paul Stewart96a6d092013-08-26 09:32:49 -07001991 service_->Unload();
Paul Stewart2da34c02013-10-17 15:28:56 -07001992 ASSERT_FALSE(service_->retain_auto_connect());
Paul Stewart96a6d092013-08-26 09:32:49 -07001993
Darin Petkov36d962d2013-03-25 13:03:14 +01001994 // false -> true
1995 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001996 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001997 EXPECT_TRUE(error.IsSuccess());
1998 EXPECT_TRUE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07001999 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart36e67be2013-12-12 14:36:10 -08002000 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002001 Mock::VerifyAndClearExpectations(&mock_manager_);
2002
Paul Stewart36e67be2013-12-12 14:36:10 -08002003 // Clear the |retain_auto_connect_| flag for the next test.
2004 service_->Unload();
2005 ASSERT_FALSE(service_->retain_auto_connect());
2006
Darin Petkov36d962d2013-03-25 13:03:14 +01002007 // true -> true
Paul Stewart36e67be2013-12-12 14:36:10 -08002008 service_->SetAutoConnect(true);
Darin Petkov36d962d2013-03-25 13:03:14 +01002009 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002010 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01002011 EXPECT_TRUE(error.IsSuccess());
2012 EXPECT_TRUE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002013 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart36e67be2013-12-12 14:36:10 -08002014 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002015 Mock::VerifyAndClearExpectations(&mock_manager_);
2016
Paul Stewart36e67be2013-12-12 14:36:10 -08002017 // Clear the |retain_auto_connect_| flag for the next test.
2018 service_->Unload();
2019 ASSERT_FALSE(service_->retain_auto_connect());
2020
Darin Petkov36d962d2013-03-25 13:03:14 +01002021 // true -> false
Paul Stewart36e67be2013-12-12 14:36:10 -08002022 service_->SetAutoConnect(true);
Darin Petkov36d962d2013-03-25 13:03:14 +01002023 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002024 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01002025 EXPECT_TRUE(error.IsSuccess());
2026 EXPECT_FALSE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002027 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart2da34c02013-10-17 15:28:56 -07002028 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002029 Mock::VerifyAndClearExpectations(&mock_manager_);
2030}
2031
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002032TEST_F(ServiceTest, SetAutoConnectFullUserUpdatePersists) {
2033 // If the user sets the kAutoConnectProperty explicitly, the preference must
2034 // be persisted, even if the property was not changed.
2035 Error error;
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002036 MockProfileRefPtr mock_profile(
2037 new MockProfile(control_interface(), metrics(), &mock_manager_));
2038 NiceMock<MockStore> storage;
2039 service_->set_profile(mock_profile);
2040 service_->SetAutoConnect(true);
2041
2042 EXPECT_CALL(*mock_profile, UpdateService(_));
2043 EXPECT_CALL(*mock_profile, GetConstStorage())
2044 .WillOnce(Return(&storage));
Paul Stewartf2860342014-05-09 14:29:16 -07002045 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002046 .WillOnce(Return(false));
2047 EXPECT_FALSE(service_->retain_auto_connect());
2048 SetAutoConnectFull(true, &error);
2049 EXPECT_TRUE(error.IsSuccess());
2050 EXPECT_TRUE(service_->auto_connect());
2051 EXPECT_TRUE(service_->retain_auto_connect());
2052}
2053
Paul Stewart43d8dc02013-10-17 10:32:53 -07002054TEST_F(ServiceTest, ClearAutoConnect) {
2055 EXPECT_FALSE(service_->auto_connect());
2056 Error error;
2057 EXPECT_FALSE(GetAutoConnect(&error));
2058 EXPECT_TRUE(error.IsSuccess());
2059
2060 // unset -> false
Paul Stewart2da34c02013-10-17 15:28:56 -07002061 EXPECT_FALSE(service_->retain_auto_connect());
Paul Stewart43d8dc02013-10-17 10:32:53 -07002062 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2063 ClearAutoConnect(&error);
2064 EXPECT_TRUE(error.IsSuccess());
Paul Stewart2da34c02013-10-17 15:28:56 -07002065 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002066 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002067 Mock::VerifyAndClearExpectations(&mock_manager_);
2068
2069 // false -> false
2070 SetAutoConnectFull(false, &error);
Ben Chancc225ef2014-09-30 13:26:51 -07002071 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart2da34c02013-10-17 15:28:56 -07002072 EXPECT_TRUE(service_->retain_auto_connect());
2073 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
Paul Stewart43d8dc02013-10-17 10:32:53 -07002074 ClearAutoConnect(&error);
2075 EXPECT_TRUE(error.IsSuccess());
Paul Stewart2da34c02013-10-17 15:28:56 -07002076 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002077 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002078 Mock::VerifyAndClearExpectations(&mock_manager_);
2079
2080 // true -> false
2081 SetAutoConnectFull(true, &error);
2082 EXPECT_TRUE(error.IsSuccess());
Ben Chancc225ef2014-09-30 13:26:51 -07002083 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002084 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
2085 ClearAutoConnect(&error);
Paul Stewart2da34c02013-10-17 15:28:56 -07002086 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002087 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002088 Mock::VerifyAndClearExpectations(&mock_manager_);
2089}
2090
mukesh agrawale37ad322013-10-08 16:33:56 -07002091TEST_F(ServiceTest, UniqueAttributes) {
2092 EXPECT_NE(service_->serial_number_, service2_->serial_number_);
2093 EXPECT_NE(service_->unique_name(), service2_->unique_name());
2094}
2095
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002096TEST_F(ServiceTest, PropertyChanges) {
2097 TestCommonPropertyChanges(service_, GetAdaptor());
2098 TestAutoConnectPropertyChange(service_, GetAdaptor());
2099}
2100
mukesh agrawalbebf1b82013-04-23 15:06:33 -07002101// Custom property setters should return false, and make no changes, if
2102// the new value is the same as the old value.
2103TEST_F(ServiceTest, CustomSetterNoopChange) {
2104 TestCustomSetterNoopChange(service_, &mock_manager_);
2105}
2106
Paul Stewartfa11e282013-12-02 22:04:25 -08002107TEST_F(ServiceTest, GetTethering) {
2108 Error error;
2109 EXPECT_EQ("", service_->GetTethering(&error));
2110 EXPECT_EQ(Error::kNotSupported, error.type());
2111}
2112
Paul Stewart836a9372014-04-23 19:57:15 -07002113class ServiceWithMockOnPropertyChanged : public ServiceUnderTest {
2114 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -07002115 ServiceWithMockOnPropertyChanged(ControlInterface* control_interface,
2116 EventDispatcher* dispatcher,
2117 Metrics* metrics,
2118 Manager* manager)
Paul Stewart836a9372014-04-23 19:57:15 -07002119 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {}
Paul Stewart3b30ca52015-06-16 13:13:10 -07002120 MOCK_METHOD1(OnPropertyChanged, void(const string& property));
Paul Stewart836a9372014-04-23 19:57:15 -07002121};
2122
2123TEST_F(ServiceTest, ConfigureServiceTriggersOnPropertyChanged) {
2124 auto service(make_scoped_refptr(
2125 new ServiceWithMockOnPropertyChanged(control_interface(),
2126 dispatcher(),
2127 metrics(),
2128 &mock_manager_)));
2129 KeyValueStore args;
2130 args.SetString(kUIDataProperty, "terpsichorean ejectamenta");
2131 args.SetBool(kSaveCredentialsProperty, false);
2132
2133 // Calling Configure with different values from before triggers a single
2134 // OnPropertyChanged call per property.
2135 EXPECT_CALL(*service, OnPropertyChanged(kUIDataProperty)).Times(1);
2136 EXPECT_CALL(*service, OnPropertyChanged(kSaveCredentialsProperty)).Times(1);
2137 {
2138 Error error;
2139 service->Configure(args, &error);
2140 EXPECT_TRUE(error.IsSuccess());
2141 }
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002142 Mock::VerifyAndClearExpectations(service.get());
Paul Stewart836a9372014-04-23 19:57:15 -07002143
2144 // Calling Configure with the same values as before should not trigger
2145 // OnPropertyChanged().
2146 EXPECT_CALL(*service, OnPropertyChanged(_)).Times(0);
2147 {
2148 Error error;
2149 service->Configure(args, &error);
2150 EXPECT_TRUE(error.IsSuccess());
2151 }
2152}
2153
Paul Stewart2eee6132014-05-09 13:33:26 -07002154TEST_F(ServiceTest, ClearExplicitlyDisconnected) {
2155 EXPECT_FALSE(GetExplicitlyDisconnected());
2156 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2157 service_->ClearExplicitlyDisconnected();
2158 Mock::VerifyAndClearExpectations(&mock_manager_);
2159
2160 SetExplicitlyDisconnected(true);
2161 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
2162 service_->ClearExplicitlyDisconnected();
2163 Mock::VerifyAndClearExpectations(&mock_manager_);
2164 EXPECT_FALSE(GetExplicitlyDisconnected());
2165}
2166
Paul Stewart22ce7652014-10-15 21:26:44 -07002167TEST_F(ServiceTest, Compare) {
2168 // Construct our Services so that the string comparison of
2169 // unique_name_ differs from the numerical comparison of
2170 // serial_number_.
2171 vector<scoped_refptr<MockService>> mock_services;
2172 for (size_t i = 0; i < 11; ++i) {
2173 mock_services.push_back(
2174 new NiceMock<MockService>(control_interface(),
2175 dispatcher(),
2176 metrics(),
2177 manager()));
2178 }
2179 scoped_refptr<MockService> service2 = mock_services[2];
2180 scoped_refptr<MockService> service10 = mock_services[10];
2181 mock_services.clear();
2182
2183 // Services should already be sorted by |serial_number_|.
2184 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2185
2186 // Two otherwise equal services should be reordered by strength
2187 service10->SetStrength(1);
2188 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2189
2190 scoped_refptr<MockProfile> profile2(
2191 new MockProfile(control_interface(), metrics(), manager(), ""));
2192 scoped_refptr<MockProfile> profile10(
2193 new MockProfile(control_interface(), metrics(), manager(), ""));
2194
2195 service2->set_profile(profile2);
2196 service10->set_profile(profile10);
2197
2198 // When comparing two services with different profiles, prefer the one
2199 // that is not ephemeral.
2200 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service2)))
2201 .WillRepeatedly(Return(false));
2202 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service10)))
2203 .WillRepeatedly(Return(true));
2204 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2205 Mock::VerifyAndClearExpectations(&mock_manager_);
2206
2207 // Prefer the service with the more recently applied profile if neither
2208 // service is ephemeral.
2209 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_))
2210 .WillRepeatedly(Return(false));
2211 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile2),
2212 IsRefPtrTo(profile10)))
2213 .WillRepeatedly(Return(true));
2214 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile10),
2215 IsRefPtrTo(profile2)))
2216 .WillRepeatedly(Return(false));
2217 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2218
Paul Stewartd9c7cfc2015-01-06 14:26:22 -08002219 // Security.
Paul Stewart22ce7652014-10-15 21:26:44 -07002220 service2->SetSecurity(Service::kCryptoAes, true, true);
2221 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2222
Paul Stewartd9c7cfc2015-01-06 14:26:22 -08002223 // PriorityWithinTechnology.
2224 service10->SetPriorityWithinTechnology(1, nullptr);
2225 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2226 service2->SetPriorityWithinTechnology(2, nullptr);
2227 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2228
2229 // Technology.
Paul Stewart22ce7652014-10-15 21:26:44 -07002230 EXPECT_CALL(*service2.get(), technology())
2231 .WillRepeatedly(Return((Technology::kWifi)));
2232 EXPECT_CALL(*service10.get(), technology())
2233 .WillRepeatedly(Return(Technology::kEthernet));
2234
2235 technology_order_for_sorting_ = {Technology::kEthernet, Technology::kWifi};
2236 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2237
2238 technology_order_for_sorting_ = {Technology::kWifi, Technology::kEthernet};
2239 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2240
2241 // Priority.
2242 service2->SetPriority(1, nullptr);
2243 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
Paul Stewart3fee7e32014-10-15 21:39:29 -07002244 service10->SetPriority(2, nullptr);
2245 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
Paul Stewart22ce7652014-10-15 21:26:44 -07002246
Paul Stewart3fee7e32014-10-15 21:39:29 -07002247 // A service that has been connected before should be considered
2248 // above a service that neither been connected to before nor has
2249 // has managed credentials.
2250 service2->has_ever_connected_ = true;
2251 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2252
2253 // If one service has been connected to before, and the other is managed
2254 // by Chrome they should rank same, so the priority will be considered
2255 // instead.
2256 service10->managed_credentials_ = true;
2257 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2258 service2->SetPriority(3, nullptr);
2259 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2260
2261 // A service with managed credentials should be considered above one that
2262 // has neither been connected to before nor has managed credentials.
2263 service2->has_ever_connected_ = false;
Paul Stewart22ce7652014-10-15 21:26:44 -07002264 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2265
2266 // Auto-connect.
2267 service2->SetAutoConnect(true);
2268 service10->SetAutoConnect(false);
2269 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2270
2271 // Test is-dependent-on.
2272 EXPECT_CALL(*service10.get(),
2273 IsDependentOn(IsRefPtrTo(service2.get())))
2274 .WillOnce(Return(true))
2275 .WillOnce(Return(false));
2276 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2277 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2278
2279 // It doesn't make sense to have is-dependent-on ranking comparison in any of
2280 // the remaining subtests below. Reset to the default.
2281 EXPECT_CALL(*service10.get(), IsDependentOn(_)).WillRepeatedly(Return(false));
2282 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2283
2284 // Connectable.
2285 service10->SetConnectable(true);
2286 service2->SetConnectable(false);
2287 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2288
2289 // IsFailed.
2290 EXPECT_CALL(*service2.get(), state())
2291 .WillRepeatedly(Return(Service::kStateIdle));
2292 EXPECT_CALL(*service2.get(), IsFailed())
2293 .WillRepeatedly(Return(false));
2294 EXPECT_CALL(*service10.get(), state())
2295 .WillRepeatedly(Return(Service::kStateFailure));
2296 EXPECT_CALL(*service10.get(), IsFailed())
2297 .WillRepeatedly(Return(true));
2298 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2299
2300 // Connecting.
2301 EXPECT_CALL(*service10.get(), state())
2302 .WillRepeatedly(Return(Service::kStateAssociating));
2303 EXPECT_CALL(*service10.get(), IsConnecting())
2304 .WillRepeatedly(Return(true));
2305 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2306
2307 // Connected-but-portalled preferred over unconnected.
2308 EXPECT_CALL(*service2.get(), state())
2309 .WillRepeatedly(Return(Service::kStatePortal));
2310 EXPECT_CALL(*service2.get(), IsConnected())
2311 .WillRepeatedly(Return(true));
2312 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2313
2314 // Connected preferred over connected-but-portalled.
2315 service10->SetConnectable(false);
2316 service2->SetConnectable(true);
2317 EXPECT_CALL(*service10.get(), state())
2318 .WillRepeatedly(Return(Service::kStateConnected));
2319 EXPECT_CALL(*service10.get(), IsConnected())
2320 .WillRepeatedly(Return(true));
2321 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2322
2323 // Connectivity state ignored if this is specified.
2324 const bool kDoNotCompareConnectivityState = false;
2325 EXPECT_TRUE(SortingOrderIs(service2, service10,
2326 kDoNotCompareConnectivityState));
2327}
2328
Chris Masone3bd3c8c2011-06-13 08:20:26 -07002329} // namespace shill