blob: af17603f9981e8cb19d0aea6e78ace6106b9b353 [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"
Paul Stewart22ce7652014-10-15 21:26:44 -070033#include "shill/mock_service.h"
Darin Petkovba40dd32011-07-11 20:06:39 -070034#include "shill/mock_store.h"
Peter Qiu8d6b5972014-10-28 15:33:34 -070035#include "shill/net/mock_time.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070036#include "shill/property_store_unittest.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070037#include "shill/service_property_change_test.h"
Paul Stewart22ce7652014-10-15 21:26:44 -070038#include "shill/service_sorter.h"
Chris Masone6515aab2011-10-12 16:19:09 -070039#include "shill/service_under_test.h"
Paul Stewartf2860342014-05-09 14:29:16 -070040#include "shill/testing.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070041
Peter Qiu1a72f542015-04-14 16:31:36 -070042#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
43#include "shill/mock_eap_credentials.h"
44#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
45
Eric Shienbrood9a245532012-03-07 14:20:39 -050046using base::Bind;
47using base::Unretained;
Darin Petkov385b9bc2012-12-03 15:25:05 +010048using std::deque;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070049using std::map;
50using std::string;
51using std::vector;
Darin Petkovba40dd32011-07-11 20:06:39 -070052using testing::_;
mukesh agrawalcf24a242012-05-21 16:46:11 -070053using testing::AnyNumber;
Darin Petkovba40dd32011-07-11 20:06:39 -070054using testing::AtLeast;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010055using testing::DefaultValue;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080056using testing::DoAll;
Paul Stewartbc6e7392012-05-24 07:07:48 -070057using testing::HasSubstr;
Paul Stewart81426132012-05-16 10:05:10 -070058using testing::Mock;
Darin Petkovba40dd32011-07-11 20:06:39 -070059using testing::NiceMock;
60using testing::Return;
Ben Chana55469d2014-01-27 16:35:29 -080061using testing::ReturnNull;
Paul Stewart10241e32012-04-23 18:15:06 -070062using testing::ReturnRef;
Darin Petkovba40dd32011-07-11 20:06:39 -070063using testing::StrictMock;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080064using testing::SetArgumentPointee;
Darin Petkovba40dd32011-07-11 20:06:39 -070065using testing::Test;
Paul Stewart9f32d192012-01-30 20:37:50 -080066using testing::Values;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070067
68namespace shill {
69
70class ServiceTest : public PropertyStoreTest {
71 public:
Chris Masoneb925cc82011-06-22 15:39:57 -070072 ServiceTest()
Thieu Le3426c8f2012-01-11 17:35:11 -080073 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
Chris Masone2176a882011-09-14 22:29:15 -070074 service_(new ServiceUnderTest(control_interface(),
75 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080076 metrics(),
Paul Stewart03dba0b2011-08-22 16:32:45 -070077 &mock_manager_)),
mukesh agrawal43970a22013-02-15 16:00:07 -080078 service2_(new ServiceUnderTest(control_interface(),
79 dispatcher(),
80 metrics(),
81 &mock_manager_)),
Darin Petkovcb0b5662012-12-13 09:59:44 +010082 storage_id_(ServiceUnderTest::kStorageId),
Peter Qiu1a72f542015-04-14 16:31:36 -070083#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
84 eap_(new MockEapCredentials()),
85#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Peter Qiu608ec292015-07-30 15:46:16 -070086 power_manager_(new MockPowerManager(nullptr, &control_)) {
87 ON_CALL(control_, CreatePowerManagerProxy(_))
Ben Chana55469d2014-01-27 16:35:29 -080088 .WillByDefault(ReturnNull());
89
Darin Petkov385b9bc2012-12-03 15:25:05 +010090 service_->time_ = &time_;
Samuel Tan07dfabc2015-01-20 15:10:39 -080091 service_->disconnects_.time_ = &time_;
92 service_->misconnects_.time_ = &time_;
Darin Petkov0c65bdd2012-12-05 13:42:41 +010093 DefaultValue<Timestamp>::Set(Timestamp());
Darin Petkov385b9bc2012-12-03 15:25:05 +010094 service_->diagnostics_reporter_ = &diagnostics_reporter_;
Peter Qiu1a72f542015-04-14 16:31:36 -070095#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -070096 service_->eap_.reset(eap_); // Passes ownership.
Peter Qiu1a72f542015-04-14 16:31:36 -070097#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Darin Petkovcb0b5662012-12-13 09:59:44 +010098 mock_manager_.running_ = true;
99 mock_manager_.set_power_manager(power_manager_); // Passes ownership.
Chris Masone9d779932011-08-25 16:33:41 -0700100 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700101
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700102 virtual ~ServiceTest() {}
Chris Masoneb925cc82011-06-22 15:39:57 -0700103
Paul Stewart3b30ca52015-06-16 13:13:10 -0700104 MOCK_METHOD1(TestCallback, void(const Error& error));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500105
Chris Masoneb925cc82011-06-22 15:39:57 -0700106 protected:
mukesh agrawalcf24a242012-05-21 16:46:11 -0700107 typedef scoped_refptr<MockProfile> MockProfileRefPtr;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500108
Paul Stewart3b30ca52015-06-16 13:13:10 -0700109 ServiceMockAdaptor* GetAdaptor() {
110 return dynamic_cast<ServiceMockAdaptor*>(service_->adaptor());
Darin Petkovaba89322013-03-11 14:48:22 +0100111 }
112
Darin Petkov457728b2013-01-09 09:49:08 +0100113 string GetFriendlyName() { return service_->friendly_name(); }
114
Darin Petkovcb0b5662012-12-13 09:59:44 +0100115 void SetManagerRunning(bool running) { mock_manager_.running_ = running; }
116
Daniel Eratfac09532014-04-17 20:25:59 -0700117 void SetSuspending(bool suspending) {
118 power_manager_->suspending_ = suspending;
Darin Petkovcb0b5662012-12-13 09:59:44 +0100119 }
120
Paul Stewart2eee6132014-05-09 13:33:26 -0700121 bool GetExplicitlyDisconnected() const {
122 return service_->explicitly_disconnected_;
123 }
124
Darin Petkov385b9bc2012-12-03 15:25:05 +0100125 void SetExplicitlyDisconnected(bool explicitly) {
126 service_->explicitly_disconnected_ = explicitly;
127 }
128
129 void SetStateField(Service::ConnectState state) { service_->state_ = state; }
130
Darin Petkovc8d91e52013-01-21 11:43:47 +0100131 Service::ConnectState GetPreviousState() const {
132 return service_->previous_state_;
133 }
134
Darin Petkov385b9bc2012-12-03 15:25:05 +0100135 void NoteDisconnectEvent() {
136 service_->NoteDisconnectEvent();
137 }
138
Paul Stewart3b30ca52015-06-16 13:13:10 -0700139 EventHistory* GetDisconnects() {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100140 return &service_->disconnects_;
141 }
Paul Stewart3b30ca52015-06-16 13:13:10 -0700142 EventHistory* GetMisconnects() {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100143 return &service_->misconnects_;
144 }
145
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700146 Timestamp GetTimestamp(int monotonic_seconds, int boottime_seconds,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700147 const string& wall_clock) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100148 struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 };
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700149 struct timeval boottime = { .tv_sec = boottime_seconds, .tv_usec = 0 };
150 return Timestamp(monotonic, boottime, wall_clock);
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100151 }
152
Paul Stewart3b30ca52015-06-16 13:13:10 -0700153 void PushTimestamp(EventHistory* events,
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100154 int monotonic_seconds,
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700155 int boottime_seconds,
Paul Stewart3b30ca52015-06-16 13:13:10 -0700156 const string& wall_clock) {
Samuel Tan07dfabc2015-01-20 15:10:39 -0800157 events->RecordEventInternal(
Peter Qiu3b4ebd52014-07-29 11:16:55 -0700158 GetTimestamp(monotonic_seconds, boottime_seconds, wall_clock));
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100159 }
Darin Petkov385b9bc2012-12-03 15:25:05 +0100160
161 int GetDisconnectsMonitorSeconds() {
162 return Service::kDisconnectsMonitorSeconds;
163 }
164
165 int GetMisconnectsMonitorSeconds() {
166 return Service::kMisconnectsMonitorSeconds;
167 }
168
169 int GetReportDisconnectsThreshold() {
170 return Service::kReportDisconnectsThreshold;
171 }
172
173 int GetReportMisconnectsThreshold() {
174 return Service::kReportMisconnectsThreshold;
175 }
176
177 int GetMaxDisconnectEventHistory() {
178 return Service::kMaxDisconnectEventHistory;
179 }
180
Samuel Tan07dfabc2015-01-20 15:10:39 -0800181 int GetMaxMisconnectEventHistory() {
182 return Service::kMaxMisconnectEventHistory;
Darin Petkov0c65bdd2012-12-05 13:42:41 +0100183 }
184
Paul Stewart3b30ca52015-06-16 13:13:10 -0700185 bool GetAutoConnect(Error* error) {
Darin Petkov36d962d2013-03-25 13:03:14 +0100186 return service_->GetAutoConnect(error);
187 }
188
Paul Stewart3b30ca52015-06-16 13:13:10 -0700189 void ClearAutoConnect(Error* error) {
Paul Stewart43d8dc02013-10-17 10:32:53 -0700190 service_->ClearAutoConnect(error);
191 }
192
Paul Stewart3b30ca52015-06-16 13:13:10 -0700193 bool SetAutoConnectFull(bool connect, Error* error) {
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700194 return service_->SetAutoConnectFull(connect, error);
Darin Petkov36d962d2013-03-25 13:03:14 +0100195 }
196
Paul Stewart3b30ca52015-06-16 13:13:10 -0700197 bool SortingOrderIs(const ServiceRefPtr& service0,
198 const ServiceRefPtr& service1,
Paul Stewart22ce7652014-10-15 21:26:44 -0700199 bool should_compare_connectivity_state) {
200 vector<ServiceRefPtr> services;
201 services.push_back(service1);
202 services.push_back(service0);
203 std::sort(services.begin(), services.end(),
204 ServiceSorter(&mock_manager_, should_compare_connectivity_state,
205 technology_order_for_sorting_));
206 return (service0.get() == services[0].get() &&
207 service1.get() == services[1].get());
208 }
209
Paul Stewart3b30ca52015-06-16 13:13:10 -0700210 bool DefaultSortingOrderIs(const ServiceRefPtr& service0,
211 const ServiceRefPtr& service1) {
Paul Stewart22ce7652014-10-15 21:26:44 -0700212 const bool kShouldCompareConnectivityState = true;
213 return SortingOrderIs(
214 service0, service1, kShouldCompareConnectivityState);
215 }
216
Paul Stewart03dba0b2011-08-22 16:32:45 -0700217 MockManager mock_manager_;
Darin Petkov385b9bc2012-12-03 15:25:05 +0100218 MockDiagnosticsReporter diagnostics_reporter_;
219 MockTime time_;
Paul Stewart03dba0b2011-08-22 16:32:45 -0700220 scoped_refptr<ServiceUnderTest> service_;
mukesh agrawal43970a22013-02-15 16:00:07 -0800221 scoped_refptr<ServiceUnderTest> service2_;
Chris Masone34af2182011-08-22 11:59:36 -0700222 string storage_id_;
Peter Qiu608ec292015-07-30 15:46:16 -0700223 NiceMock<MockControl> control_;
Peter Qiu1a72f542015-04-14 16:31:36 -0700224#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart3b30ca52015-06-16 13:13:10 -0700225 MockEapCredentials* eap_; // Owned by |service_|.
Peter Qiu1a72f542015-04-14 16:31:36 -0700226#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart3b30ca52015-06-16 13:13:10 -0700227 MockPowerManager* power_manager_; // Owned by |mock_manager_|.
Paul Stewart22ce7652014-10-15 21:26:44 -0700228 vector<Technology::Identifier> technology_order_for_sorting_;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700229};
230
Christopher Wiley0801d192012-09-24 11:57:15 -0700231class AllMockServiceTest : public testing::Test {
232 public:
233 AllMockServiceTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -0800234 : metrics_(&dispatcher_),
235 manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
Christopher Wiley0801d192012-09-24 11:57:15 -0700236 service_(new ServiceUnderTest(&control_interface_,
237 &dispatcher_,
238 &metrics_,
239 &manager_)) { }
240 virtual ~AllMockServiceTest() {}
241
242 protected:
243 MockControl control_interface_;
244 StrictMock<MockEventDispatcher> dispatcher_;
245 MockGLib glib_;
246 NiceMock<MockMetrics> metrics_;
247 MockManager manager_;
248 scoped_refptr<ServiceUnderTest> service_;
249};
250
Darin Petkovba40dd32011-07-11 20:06:39 -0700251TEST_F(ServiceTest, Constructor) {
252 EXPECT_TRUE(service_->save_credentials_);
253 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400254 EXPECT_EQ(Service::kStateIdle, service_->state());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700255 EXPECT_FALSE(service_->has_ever_connected());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800256 EXPECT_EQ(0, service_->previous_error_serial_number_);
257 EXPECT_EQ("", service_->previous_error_);
Darin Petkovba40dd32011-07-11 20:06:39 -0700258}
259
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200260TEST_F(ServiceTest, CalculateState) {
261 service_->state_ = Service::kStateConnected;
262 Error error;
Ben Chan923a5022013-09-20 11:23:23 -0700263 EXPECT_EQ(kStateReady, service_->CalculateState(&error));
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200264 EXPECT_TRUE(error.IsSuccess());
265}
266
267TEST_F(ServiceTest, CalculateTechnology) {
268 service_->technology_ = Technology::kWifi;
269 Error error;
Ben Chan923a5022013-09-20 11:23:23 -0700270 EXPECT_EQ(kTypeWifi, service_->CalculateTechnology(&error));
Darin Petkov58f0b6d2012-06-12 12:52:30 +0200271 EXPECT_TRUE(error.IsSuccess());
272}
273
Chris Masonea8a2c252011-06-27 22:16:30 -0700274TEST_F(ServiceTest, GetProperties) {
275 map<string, ::DBus::Variant> props;
276 Error error(Error::kInvalidProperty, "");
277 {
278 ::DBus::Error dbus_error;
Paul Stewartd215af62012-04-24 23:25:50 -0700279 string expected("true");
Ben Chan923a5022013-09-20 11:23:23 -0700280 service_->mutable_store()->SetStringProperty(kCheckPortalProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700281 expected,
282 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700283 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700284 ASSERT_FALSE(props.find(kCheckPortalProperty) == props.end());
285 EXPECT_EQ(props[kCheckPortalProperty].reader().get_string(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700286 expected);
287 }
288 {
289 ::DBus::Error dbus_error;
290 bool expected = true;
Ben Chan923a5022013-09-20 11:23:23 -0700291 service_->mutable_store()->SetBoolProperty(kAutoConnectProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700292 expected,
293 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700294 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700295 ASSERT_FALSE(props.find(kAutoConnectProperty) == props.end());
296 EXPECT_EQ(props[kAutoConnectProperty].reader().get_bool(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700297 expected);
298 }
299 {
300 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700301 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700302 ASSERT_FALSE(props.find(kConnectableProperty) == props.end());
303 EXPECT_EQ(props[kConnectableProperty].reader().get_bool(), false);
Chris Masonea8a2c252011-06-27 22:16:30 -0700304 }
305 {
306 ::DBus::Error dbus_error;
Ben Chan7fab8972014-08-10 17:14:46 -0700307 int32_t expected = 127;
Ben Chan923a5022013-09-20 11:23:23 -0700308 service_->mutable_store()->SetInt32Property(kPriorityProperty,
mukesh agrawalde29fa82011-09-16 16:16:36 -0700309 expected,
310 &error);
Chris Masone27c4aa52011-07-02 13:10:14 -0700311 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700312 ASSERT_FALSE(props.find(kPriorityProperty) == props.end());
313 EXPECT_EQ(props[kPriorityProperty].reader().get_int32(),
Chris Masonea8a2c252011-06-27 22:16:30 -0700314 expected);
315 }
Chris Masone95207da2011-06-29 16:50:49 -0700316 {
317 ::DBus::Error dbus_error;
Chris Masone27c4aa52011-07-02 13:10:14 -0700318 DBusAdaptor::GetProperties(service_->store(), &props, &dbus_error);
Ben Chan923a5022013-09-20 11:23:23 -0700319 ASSERT_FALSE(props.find(kDeviceProperty) == props.end());
320 EXPECT_EQ(props[kDeviceProperty].reader().get_path(),
Paul Stewart03dba0b2011-08-22 16:32:45 -0700321 string(ServiceUnderTest::kRpcId));
Chris Masone95207da2011-06-29 16:50:49 -0700322 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700323}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700324
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800325TEST_F(ServiceTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -0700326 {
327 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800328 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700329 kSaveCredentialsProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800330 PropertyStoreTest::kBoolV,
331 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700332 }
333 {
334 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700335 ::DBus::Variant priority;
336 priority.writer().append_int32(1);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800337 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700338 kPriorityProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700339 priority,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800340 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700341 }
342 {
343 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700344 ::DBus::Variant guid;
345 guid.writer().append_string("not default");
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800346 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700347 kGuidProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700348 guid,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700349 &error));
350 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700351#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700352 // Ensure that EAP properties cannot be set on services with no EAP
353 // credentials. Use service2_ here since we're have some code in
354 // ServiceTest::SetUp() that fiddles with service_->eap_.
355 {
356 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700357 ::DBus::Variant eap;
358 eap.writer().append_string("eap eep eip!");
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700359 EXPECT_FALSE(DBusAdaptor::SetProperty(service2_->mutable_store(),
Ben Chan011e6662014-05-07 11:03:25 -0700360 kEapMethodProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700361 eap,
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700362 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700363 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700364 EXPECT_EQ(invalid_prop(), error.name());
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700365 // Now plumb in eap credentials, and try again.
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700366 service2_->SetEapCredentials(new EapCredentials());
367 EXPECT_TRUE(DBusAdaptor::SetProperty(service2_->mutable_store(),
Ben Chan011e6662014-05-07 11:03:25 -0700368 kEapMethodProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700369 eap,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800370 &error));
Chris Masonea8a2c252011-06-27 22:16:30 -0700371 }
Peter Qiu1a72f542015-04-14 16:31:36 -0700372#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Chris Masoneb925cc82011-06-22 15:39:57 -0700373 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
Chris Masonea8a2c252011-06-27 22:16:30 -0700374 {
375 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800376 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Paul Stewart2da34c02013-10-17 15:28:56 -0700377 kConnectableProperty,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800378 PropertyStoreTest::kBoolV,
379 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700380 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Chris Masone9d779932011-08-25 16:33:41 -0700381 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700382 }
Thieu Le284fe792012-01-31 17:53:19 -0800383 {
384 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700385 ::DBus::Variant auto_connect;
386 auto_connect.writer().append_bool(true);
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800387 EXPECT_TRUE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700388 kAutoConnectProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700389 auto_connect,
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800390 &error));
Thieu Le284fe792012-01-31 17:53:19 -0800391 }
Paul Stewart0c438332012-04-11 07:55:27 -0700392 // Ensure that we can perform a trivial set of the Name property (to its
393 // current value) but an attempt to set the property to a different value
394 // fails.
395 {
396 ::DBus::Error error;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700397 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700398 kNameProperty,
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700399 DBusAdaptor::StringToVariant(
400 GetFriendlyName()),
401 &error));
402 EXPECT_FALSE(error.is_set());
Paul Stewart0c438332012-04-11 07:55:27 -0700403 }
404 {
405 ::DBus::Error error;
406 EXPECT_FALSE(DBusAdaptor::SetProperty(service_->mutable_store(),
Ben Chan923a5022013-09-20 11:23:23 -0700407 kNameProperty,
Paul Stewart0c438332012-04-11 07:55:27 -0700408 PropertyStoreTest::kStringV,
409 &error));
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700410 ASSERT_TRUE(error.is_set()); // name() may be invalid otherwise
Paul Stewart0c438332012-04-11 07:55:27 -0700411 EXPECT_EQ(invalid_args(), error.name());
412 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700413}
414
Paul Stewarte7de2942013-04-25 17:07:31 -0700415TEST_F(ServiceTest, GetLoadableStorageIdentifier) {
416 NiceMock<MockStore> storage;
417 EXPECT_CALL(storage, ContainsGroup(storage_id_))
418 .WillOnce(Return(false))
419 .WillOnce(Return(true));
420 EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage));
421 EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage));
422}
423
424TEST_F(ServiceTest, IsLoadableFrom) {
425 NiceMock<MockStore> storage;
426 EXPECT_CALL(storage, ContainsGroup(storage_id_))
427 .WillOnce(Return(false))
428 .WillOnce(Return(true));
429 EXPECT_FALSE(service_->IsLoadableFrom(storage));
430 EXPECT_TRUE(service_->IsLoadableFrom(storage));
431}
432
Peter Qiu1a72f542015-04-14 16:31:36 -0700433#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700434class ServiceWithOnEapCredentialsChangedOverride : public ServiceUnderTest {
435 public:
436 ServiceWithOnEapCredentialsChangedOverride(
Paul Stewart3b30ca52015-06-16 13:13:10 -0700437 ControlInterface* control_interface,
438 EventDispatcher* dispatcher,
439 Metrics* metrics,
440 Manager* manager,
441 EapCredentials* eap)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700442 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {
443 SetEapCredentials(eap);
444 }
Rebecca Silberstein57776902014-09-15 21:43:02 -0700445 void OnEapCredentialsChanged(Service::UpdateCredentialsReason) override {
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700446 SetHasEverConnected(false);
447 }
448};
Peter Qiu1a72f542015-04-14 16:31:36 -0700449#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700450
Darin Petkovba40dd32011-07-11 20:06:39 -0700451TEST_F(ServiceTest, Load) {
Peter Qiu1a72f542015-04-14 16:31:36 -0700452#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart3b30ca52015-06-16 13:13:10 -0700453 MockEapCredentials* eap = new MockEapCredentials(); // Owned by |service|.
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700454 scoped_refptr<ServiceWithOnEapCredentialsChangedOverride> service(
455 new ServiceWithOnEapCredentialsChangedOverride(control_interface(),
456 dispatcher(),
457 metrics(),
458 &mock_manager_,
459 eap));
Peter Qiu1a72f542015-04-14 16:31:36 -0700460#else
461 scoped_refptr<ServiceUnderTest> service(
462 new ServiceUnderTest(control_interface(),
463 dispatcher(),
464 metrics(),
465 &mock_manager_));
466#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700467
Darin Petkovba40dd32011-07-11 20:06:39 -0700468 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700469 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700470 const string kCheckPortal("check-portal");
471 const string kGUID("guid");
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700472 const bool kHasEverConnected = true;
Paul Stewartc3dbff12013-07-17 10:32:48 -0700473 const int kPriority = 20;
474 const string kProxyConfig("proxy-config");
475 const string kUIData("ui-data");
476 EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber());
477 EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber());
478 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _))
479 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true)));
480 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _))
481 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true)));
482 EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _))
483 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true)));
484 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _))
485 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true)));
486 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _))
487 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true)));
Darin Petkov0debec02013-01-22 10:40:05 +0100488 EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber());
489 EXPECT_CALL(storage,
490 GetBool(storage_id_, Service::kStorageSaveCredentials, _));
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700491 EXPECT_CALL(storage,
492 GetBool(storage_id_, Service::kStorageHasEverConnected, _))
493 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
494 Return(true)));
Peter Qiu1a72f542015-04-14 16:31:36 -0700495#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700496 EXPECT_CALL(*eap, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700497#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700498 EXPECT_TRUE(service->Load(&storage));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700499
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700500 EXPECT_EQ(kCheckPortal, service->check_portal_);
501 EXPECT_EQ(kGUID, service->guid_);
502 EXPECT_TRUE(service->has_ever_connected_);
503 EXPECT_EQ(kProxyConfig, service->proxy_config_);
504 EXPECT_EQ(kUIData, service->ui_data_);
Paul Stewartc3dbff12013-07-17 10:32:48 -0700505
506 Mock::VerifyAndClearExpectations(&storage);
Peter Qiu1a72f542015-04-14 16:31:36 -0700507#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc3dbff12013-07-17 10:32:48 -0700508 Mock::VerifyAndClearExpectations(eap_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700509#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartc3dbff12013-07-17 10:32:48 -0700510
511 // Assure that parameters are set to default if not available in the profile.
512 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
513 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
514 .WillRepeatedly(Return(false));
515 EXPECT_CALL(storage, GetString(storage_id_, _, _))
516 .WillRepeatedly(Return(false));
517 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
518 .WillRepeatedly(Return(false));
Peter Qiu1a72f542015-04-14 16:31:36 -0700519#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700520 EXPECT_CALL(*eap, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700521#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700522 EXPECT_TRUE(service->Load(&storage));
Paul Stewartc3dbff12013-07-17 10:32:48 -0700523
524 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700525 EXPECT_EQ("", service->guid_);
526 EXPECT_EQ("", service->proxy_config_);
527 EXPECT_EQ("", service->ui_data_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700528
529 // has_ever_connected_ flag will reset when EAP credential changes.
530#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700531 EXPECT_FALSE(service->has_ever_connected_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700532#else
533 EXPECT_TRUE(service->has_ever_connected_);
534#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Darin Petkovba40dd32011-07-11 20:06:39 -0700535}
536
537TEST_F(ServiceTest, LoadFail) {
538 StrictMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700539 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
Chris Masone9d779932011-08-25 16:33:41 -0700540 EXPECT_FALSE(service_->Load(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700541}
542
Paul Stewart2da34c02013-10-17 15:28:56 -0700543TEST_F(ServiceTest, LoadAutoConnect) {
544 NiceMock<MockStore> storage;
545 EXPECT_CALL(storage, ContainsGroup(storage_id_))
546 .WillRepeatedly(Return(true));
547 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
548 .WillRepeatedly(Return(false));
549 EXPECT_CALL(storage, GetString(storage_id_, _, _))
550 .WillRepeatedly(Return(false));
551 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
552 .WillRepeatedly(Return(false));
Peter Qiu1a72f542015-04-14 16:31:36 -0700553#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart2da34c02013-10-17 15:28:56 -0700554 EXPECT_CALL(*eap_, Load(&storage, storage_id_)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700555#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart2da34c02013-10-17 15:28:56 -0700556
557 // Three of each expectation so we can test Favorite == unset, false, true.
558 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageAutoConnect, _))
559 .WillOnce(Return(false))
560 .WillOnce(Return(false))
561 .WillOnce(Return(false))
562 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
563 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
564 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
565 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
566 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
567 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
568 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageFavorite, _))
569 .WillOnce(Return(false))
570 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
571 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
572 .WillOnce(Return(false))
573 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
574 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
575 .WillOnce(Return(false))
576 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
577 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
578
579 // AutoConnect is unset, Favorite is unset.
580 EXPECT_TRUE(service_->Load(&storage));
581 EXPECT_FALSE(service_->auto_connect());
582 EXPECT_FALSE(service_->retain_auto_connect());
583
584 // AutoConnect is unset, Favorite is false.
585 EXPECT_TRUE(service_->Load(&storage));
586 EXPECT_FALSE(service_->auto_connect());
587 EXPECT_FALSE(service_->retain_auto_connect());
588
589 // AutoConnect is unset, Favorite is true.
590 EXPECT_TRUE(service_->Load(&storage));
591 EXPECT_FALSE(service_->auto_connect());
592 EXPECT_TRUE(service_->retain_auto_connect());
593
594 // AutoConnect is false, Favorite is unset.
595 EXPECT_TRUE(service_->Load(&storage));
596 EXPECT_FALSE(service_->auto_connect());
597 EXPECT_TRUE(service_->retain_auto_connect());
598
599 // AutoConnect is false, Favorite is false.
600 EXPECT_TRUE(service_->Load(&storage));
601 EXPECT_FALSE(service_->auto_connect());
602 EXPECT_FALSE(service_->retain_auto_connect());
603
604 // AutoConnect is false, Favorite is true.
605 EXPECT_TRUE(service_->Load(&storage));
606 EXPECT_FALSE(service_->auto_connect());
607 EXPECT_TRUE(service_->retain_auto_connect());
608
609 // AutoConnect is true, Favorite is unset.
610 EXPECT_TRUE(service_->Load(&storage));
611 EXPECT_TRUE(service_->auto_connect());
612 EXPECT_TRUE(service_->retain_auto_connect());
613
614 // AutoConnect is true, Favorite is false (invalid case).
615 EXPECT_TRUE(service_->Load(&storage));
616 EXPECT_TRUE(service_->auto_connect());
617 EXPECT_FALSE(service_->retain_auto_connect());
618
619 // AutoConnect is true, Favorite is true.
620 EXPECT_TRUE(service_->Load(&storage));
621 EXPECT_TRUE(service_->auto_connect());
622 EXPECT_TRUE(service_->retain_auto_connect());
623}
624
Darin Petkovba40dd32011-07-11 20:06:39 -0700625TEST_F(ServiceTest, SaveString) {
626 MockStore storage;
627 static const char kKey[] = "test-key";
628 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700629 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700630 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700631 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700632}
633
634TEST_F(ServiceTest, SaveStringCrypted) {
635 MockStore storage;
636 static const char kKey[] = "test-key";
637 static const char kData[] = "test-data";
Chris Masone34af2182011-08-22 11:59:36 -0700638 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
Darin Petkovba40dd32011-07-11 20:06:39 -0700639 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700640 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700641}
642
643TEST_F(ServiceTest, SaveStringDontSave) {
644 MockStore storage;
645 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700646 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700647 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700648 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
Darin Petkovba40dd32011-07-11 20:06:39 -0700649}
650
651TEST_F(ServiceTest, SaveStringEmpty) {
652 MockStore storage;
653 static const char kKey[] = "test-key";
Chris Masone34af2182011-08-22 11:59:36 -0700654 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
Darin Petkovba40dd32011-07-11 20:06:39 -0700655 .WillOnce(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700656 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
Darin Petkovba40dd32011-07-11 20:06:39 -0700657}
658
659TEST_F(ServiceTest, Save) {
660 NiceMock<MockStore> storage;
Chris Masone34af2182011-08-22 11:59:36 -0700661 EXPECT_CALL(storage, SetString(storage_id_, _, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700662 .Times(AtLeast(1))
663 .WillRepeatedly(Return(true));
Chris Masone34af2182011-08-22 11:59:36 -0700664 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
Darin Petkovba40dd32011-07-11 20:06:39 -0700665 .Times(AtLeast(1))
666 .WillRepeatedly(Return(true));
Paul Stewart2da34c02013-10-17 15:28:56 -0700667 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
668 .WillOnce(Return(true));
669 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
670 .WillOnce(Return(true));
Darin Petkov0debec02013-01-22 10:40:05 +0100671 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
672 EXPECT_CALL(storage,
673 SetBool(storage_id_,
674 Service::kStorageSaveCredentials,
675 service_->save_credentials()));
Peter Qiu1a72f542015-04-14 16:31:36 -0700676#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700677 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true));
Peter Qiu1a72f542015-04-14 16:31:36 -0700678#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Chris Masone9d779932011-08-25 16:33:41 -0700679 EXPECT_TRUE(service_->Save(&storage));
Darin Petkovba40dd32011-07-11 20:06:39 -0700680}
681
Paul Stewart2da34c02013-10-17 15:28:56 -0700682TEST_F(ServiceTest, RetainAutoConnect) {
683 NiceMock<MockStore> storage;
684 EXPECT_CALL(storage, SetString(storage_id_, _, _))
685 .Times(AtLeast(1))
686 .WillRepeatedly(Return(true));
687 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
688 .Times(AtLeast(1))
689 .WillRepeatedly(Return(true));
690 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
691 .Times(2);
692 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
693 .Times(0);
694 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700695#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewart2da34c02013-10-17 15:28:56 -0700696 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
Peter Qiu1a72f542015-04-14 16:31:36 -0700697#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart2da34c02013-10-17 15:28:56 -0700698
699 // AutoConnect flag set true.
700 service_->EnableAndRetainAutoConnect();
701 EXPECT_CALL(storage,
702 SetBool(storage_id_, Service::kStorageAutoConnect, true));
703 EXPECT_TRUE(service_->Save(&storage));
704
705 // AutoConnect flag set false.
706 EXPECT_CALL(storage,
707 SetBool(storage_id_, Service::kStorageAutoConnect, false));
708 service_->SetAutoConnect(false);
709 EXPECT_TRUE(service_->Save(&storage));
710}
711
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700712TEST_F(ServiceTest, HasEverConnectedSavedToProfile) {
713 NiceMock<MockStore> storage;
714 EXPECT_CALL(storage, SetString(storage_id_, _, _))
715 .Times(AtLeast(1))
716 .WillRepeatedly(Return(true));
717 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
718 .Times(AtLeast(1))
719 .WillRepeatedly(Return(true));
720 EXPECT_CALL(storage,
721 DeleteKey(storage_id_, Service::kStorageHasEverConnected))
722 .Times(0);
723 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
Peter Qiu1a72f542015-04-14 16:31:36 -0700724#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700725 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
Peter Qiu1a72f542015-04-14 16:31:36 -0700726#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Rebecca Silberstein73dd0dc2014-08-07 16:44:23 -0700727
728 // HasEverConnected flag set true.
729 service_->SetHasEverConnected(true);
730 EXPECT_CALL(storage,
731 SetBool(storage_id_, Service::kStorageHasEverConnected, true));
732 EXPECT_TRUE(service_->Save(&storage));
733
734 // HasEverConnected flag set false.
735 EXPECT_CALL(storage,
736 SetBool(storage_id_, Service::kStorageHasEverConnected, false));
737 service_->SetHasEverConnected(false);
738 EXPECT_TRUE(service_->Save(&storage));
739}
740
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800741TEST_F(ServiceTest, Unload) {
742 NiceMock<MockStore> storage;
743 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
744 static const string string_value("value");
745 EXPECT_CALL(storage, GetString(storage_id_, _, _))
746 .Times(AtLeast(1))
747 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
Paul Stewart88769de2012-09-21 13:14:36 -0700748 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
749 .Times(AtLeast(1))
750 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
751 EXPECT_FALSE(service_->explicitly_disconnected_);
752 service_->explicitly_disconnected_ = true;
753 EXPECT_FALSE(service_->has_ever_connected_);
Peter Qiu1a72f542015-04-14 16:31:36 -0700754#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700755 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -0700756#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800757 ASSERT_TRUE(service_->Load(&storage));
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700758 // TODO(pstew): Only two string properties in the service are tested as
mukesh agrawalcf24a242012-05-21 16:46:11 -0700759 // a sentinel that properties are being set and reset at the right times.
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800760 // However, since property load/store is essentially a manual process,
761 // it is error prone and should either be exhaustively unit-tested or
762 // a generic framework for registering loaded/stored properties should
Paul Stewartee6b3d72013-07-12 16:07:51 -0700763 // be created. crbug.com/207798
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800764 EXPECT_EQ(string_value, service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700765 EXPECT_EQ(string_value, service_->guid_);
Paul Stewart88769de2012-09-21 13:14:36 -0700766 EXPECT_FALSE(service_->explicitly_disconnected_);
767 EXPECT_TRUE(service_->has_ever_connected_);
768 service_->explicitly_disconnected_ = true;
Peter Qiu1a72f542015-04-14 16:31:36 -0700769#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700770 EXPECT_CALL(*eap_, Reset());
Peter Qiu1a72f542015-04-14 16:31:36 -0700771#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800772 service_->Unload();
773 EXPECT_EQ(string(""), service_->ui_data_);
Paul Stewarte7cce8f2012-09-11 10:56:38 -0700774 EXPECT_EQ(string(""), service_->guid_);
Philipp Neubeckf883a7b2012-09-14 19:52:44 +0200775 EXPECT_FALSE(service_->explicitly_disconnected_);
Paul Stewart88769de2012-09-21 13:14:36 -0700776 EXPECT_FALSE(service_->has_ever_connected_);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800777}
778
Paul Stewart03dba0b2011-08-22 16:32:45 -0700779TEST_F(ServiceTest, State) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400780 EXPECT_EQ(Service::kStateIdle, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100781 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700782 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700783 const string unknown_error(
784 Service::ConnectFailureToString(Service::kFailureUnknown));
785 EXPECT_EQ(unknown_error, service_->error());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700786
Darin Petkovaba89322013-03-11 14:48:22 +0100787 EXPECT_CALL(*GetAdaptor(),
Ben Chan923a5022013-09-20 11:23:23 -0700788 EmitStringChanged(kStateProperty, _)).Times(6);
Darin Petkovaba89322013-03-11 14:48:22 +0100789 EXPECT_CALL(*GetAdaptor(),
Ben Chan923a5022013-09-20 11:23:23 -0700790 EmitStringChanged(kErrorProperty, _)).Times(4);
Paul Stewartf2860342014-05-09 14:29:16 -0700791 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700792 service_->SetState(Service::kStateConnected);
Darin Petkovc8d91e52013-01-21 11:43:47 +0100793 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700794 // A second state change shouldn't cause another update
795 service_->SetState(Service::kStateConnected);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700796 EXPECT_EQ(Service::kStateConnected, service_->state());
Darin Petkovc8d91e52013-01-21 11:43:47 +0100797 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
Paul Stewart03dba0b2011-08-22 16:32:45 -0700798 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
mukesh agrawalcf24a242012-05-21 16:46:11 -0700799 EXPECT_TRUE(service_->has_ever_connected_);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800800
Paul Stewartf2860342014-05-09 14:29:16 -0700801 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Paul Stewart03dba0b2011-08-22 16:32:45 -0700802 service_->SetFailure(Service::kFailureOutOfRange);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800803 EXPECT_TRUE(service_->IsFailed());
804 EXPECT_GT(service_->failed_time_, 0);
Paul Stewartd7c09a52014-02-19 12:50:29 -0800805 EXPECT_GT(service_->previous_error_serial_number_, 0);
Paul Stewart03dba0b2011-08-22 16:32:45 -0700806 EXPECT_EQ(Service::kStateFailure, service_->state());
807 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700808 const string out_of_range_error(
809 Service::ConnectFailureToString(Service::kFailureOutOfRange));
810 EXPECT_EQ(out_of_range_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800811 EXPECT_EQ(out_of_range_error, service_->previous_error_);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800812
Paul Stewartf2860342014-05-09 14:29:16 -0700813 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawal568b5c62012-02-28 14:44:47 -0800814 service_->SetState(Service::kStateConnected);
815 EXPECT_FALSE(service_->IsFailed());
816 EXPECT_EQ(service_->failed_time_, 0);
Paul Stewartf2d60912012-07-15 08:37:30 -0700817 EXPECT_EQ(unknown_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800818 EXPECT_EQ(out_of_range_error, service_->previous_error_);
819 EXPECT_GT(service_->previous_error_serial_number_, 0);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800820
Paul Stewartf2860342014-05-09 14:29:16 -0700821 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawal568b5c62012-02-28 14:44:47 -0800822 service_->SetFailureSilent(Service::kFailurePinMissing);
823 EXPECT_TRUE(service_->IsFailed());
824 EXPECT_GT(service_->failed_time_, 0);
Paul Stewartd7c09a52014-02-19 12:50:29 -0800825 EXPECT_GT(service_->previous_error_serial_number_, 0);
mukesh agrawal568b5c62012-02-28 14:44:47 -0800826 EXPECT_EQ(Service::kStateIdle, service_->state());
827 EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
Paul Stewartf2d60912012-07-15 08:37:30 -0700828 const string pin_missing_error(
829 Service::ConnectFailureToString(Service::kFailurePinMissing));
830 EXPECT_EQ(pin_missing_error, service_->error());
Paul Stewartd7c09a52014-02-19 12:50:29 -0800831 EXPECT_EQ(pin_missing_error, service_->previous_error_);
mukesh agrawalcf24a242012-05-21 16:46:11 -0700832
833 // If the Service has a Profile, the profile should be saved when
834 // the service enters kStateConnected. (The case where the service
835 // doesn't have a profile is tested above.)
836 MockProfileRefPtr mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800837 new MockProfile(control_interface(), metrics(), &mock_manager_));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700838 NiceMock<MockStore> storage;
839 service_->set_profile(mock_profile);
840 service_->has_ever_connected_ = false;
Paul Stewartf2860342014-05-09 14:29:16 -0700841 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700842 EXPECT_CALL(*mock_profile, GetConstStorage())
843 .WillOnce(Return(&storage));
Paul Stewartf2860342014-05-09 14:29:16 -0700844 EXPECT_CALL(*mock_profile, UpdateService(IsRefPtrTo(service_)));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700845 service_->SetState(Service::kStateConnected);
846 EXPECT_TRUE(service_->has_ever_connected_);
Ben Chancc225ef2014-09-30 13:26:51 -0700847 service_->set_profile(nullptr); // Break reference cycle.
mukesh agrawalcf24a242012-05-21 16:46:11 -0700848
849 // Similar to the above, but emulate an emphemeral profile, which
850 // has no storage. We can't update the service in the profile, but
851 // we should not crash.
852 service_->state_ = Service::kStateIdle; // Skips state change logic.
853 service_->set_profile(mock_profile);
854 service_->has_ever_connected_ = false;
Paul Stewartf2860342014-05-09 14:29:16 -0700855 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
Ben Chancc225ef2014-09-30 13:26:51 -0700856 EXPECT_CALL(*mock_profile, GetConstStorage()).WillOnce(Return(nullptr));
mukesh agrawalcf24a242012-05-21 16:46:11 -0700857 service_->SetState(Service::kStateConnected);
858 EXPECT_TRUE(service_->has_ever_connected_);
Ben Chancc225ef2014-09-30 13:26:51 -0700859 service_->set_profile(nullptr); // Break reference cycle.
Paul Stewart03dba0b2011-08-22 16:32:45 -0700860}
861
Peter Qiu9b83c892014-08-09 23:06:02 -0700862TEST_F(ServiceTest, PortalDetectionFailure) {
863 EXPECT_CALL(*GetAdaptor(),
864 EmitStringChanged(kPortalDetectionFailedPhaseProperty,
865 kPortalDetectionPhaseDns)).Times(1);
866 EXPECT_CALL(*GetAdaptor(),
867 EmitStringChanged(kPortalDetectionFailedStatusProperty,
868 kPortalDetectionStatusTimeout)).Times(1);
869 service_->SetPortalDetectionFailure(kPortalDetectionPhaseDns,
870 kPortalDetectionStatusTimeout);
871 EXPECT_EQ(kPortalDetectionPhaseDns,
872 service_->portal_detection_failure_phase_);
873 EXPECT_EQ(kPortalDetectionStatusTimeout,
874 service_->portal_detection_failure_status_);
875}
876
Thieu Leaf471412013-06-27 14:12:37 -0700877TEST_F(ServiceTest, StateResetAfterFailure) {
878 service_->SetFailure(Service::kFailureOutOfRange);
879 EXPECT_EQ(Service::kStateFailure, service_->state());
880 Error error;
881 service_->Connect(&error, "in test");
882 EXPECT_EQ(Service::kStateIdle, service_->state());
883 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
884
885 service_->SetState(Service::kStateConnected);
886 service_->Connect(&error, "in test");
887 EXPECT_EQ(Service::kStateConnected, service_->state());
888}
889
Peter Qiudc4e0992014-05-01 10:02:52 -0700890TEST_F(ServiceTest, UserInitiatedConnectionResult) {
891 service_->technology_ = Technology::kWifi;
892 Error error;
893 // User-initiated connection attempt succeed.
894 service_->SetState(Service::kStateIdle);
895 service_->UserInitiatedConnect(&error);
896 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
897 Metrics::kMetricWifiUserInitiatedConnectionResult,
898 Metrics::kUserInitiatedConnectionResultSuccess));
Peter Qiud87179e2014-07-10 18:29:22 -0700899 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
900 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700901 service_->SetState(Service::kStateConnected);
902 Mock::VerifyAndClearExpectations(metrics());
903
904 // User-initiated connection attempt failed.
905 service_->SetState(Service::kStateIdle);
906 service_->UserInitiatedConnect(&error);
907 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
908 Metrics::kMetricWifiUserInitiatedConnectionResult,
909 Metrics::kUserInitiatedConnectionResultFailure));
Peter Qiud87179e2014-07-10 18:29:22 -0700910 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(
911 Metrics::kMetricWifiUserInitiatedConnectionFailureReason,
912 Service::kFailureDHCP));
913 service_->SetFailure(Service::kFailureDHCP);
Peter Qiudc4e0992014-05-01 10:02:52 -0700914 Mock::VerifyAndClearExpectations(metrics());
915
916 // User-initiated connection attempt aborted.
917 service_->SetState(Service::kStateIdle);
918 service_->UserInitiatedConnect(&error);
919 service_->SetState(Service::kStateAssociating);
920 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
921 Metrics::kMetricWifiUserInitiatedConnectionResult,
922 Metrics::kUserInitiatedConnectionResultAborted));
Peter Qiud87179e2014-07-10 18:29:22 -0700923 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
924 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700925 service_->SetState(Service::kStateIdle);
926 Mock::VerifyAndClearExpectations(metrics());
927
928 // No metric reporting for other state transition.
929 service_->SetState(Service::kStateIdle);
930 service_->UserInitiatedConnect(&error);
931 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700932 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
933 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700934 service_->SetState(Service::kStateAssociating);
935 service_->SetState(Service::kStateConfiguring);
936 Mock::VerifyAndClearExpectations(metrics());
937
938 // No metric reporting for non-user-initiated connection.
939 service_->SetState(Service::kStateIdle);
940 service_->Connect(&error, "in test");
941 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700942 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
943 .Times(0);
Peter Qiudc4e0992014-05-01 10:02:52 -0700944 service_->SetState(Service::kStateConnected);
945 Mock::VerifyAndClearExpectations(metrics());
946
947 // No metric reporting for other technology.
948 service_->technology_ = Technology::kCellular;
949 service_->SetState(Service::kStateIdle);
950 service_->UserInitiatedConnect(&error);
951 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
Peter Qiud87179e2014-07-10 18:29:22 -0700952 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
953 .Times(0);
954 service_->SetFailure(Service::kFailureDHCP);
Peter Qiudc4e0992014-05-01 10:02:52 -0700955 Mock::VerifyAndClearExpectations(metrics());
956}
957
Darin Petkovb100ae72011-08-24 16:19:45 -0700958TEST_F(ServiceTest, ActivateCellularModem) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500959 ResultCallback callback =
960 Bind(&ServiceTest::TestCallback, Unretained(this));
961 EXPECT_CALL(*this, TestCallback(_)).Times(0);
Darin Petkovb100ae72011-08-24 16:19:45 -0700962 Error error;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500963 service_->ActivateCellularModem("Carrier", &error, callback);
964 EXPECT_TRUE(error.IsFailure());
Darin Petkovb100ae72011-08-24 16:19:45 -0700965}
966
Ben Chan5d924542013-02-14 17:49:08 -0800967TEST_F(ServiceTest, CompleteCellularActivation) {
968 Error error;
969 service_->CompleteCellularActivation(&error);
970 EXPECT_EQ(Error::kNotSupported, error.type());
971}
972
Paul Stewart2da34c02013-10-17 15:28:56 -0700973TEST_F(ServiceTest, EnableAndRetainAutoConnect) {
974 EXPECT_FALSE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000975 EXPECT_FALSE(service_->auto_connect());
976
Paul Stewart2da34c02013-10-17 15:28:56 -0700977 service_->EnableAndRetainAutoConnect();
978 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000979 EXPECT_TRUE(service_->auto_connect());
980}
981
Paul Stewart2da34c02013-10-17 15:28:56 -0700982TEST_F(ServiceTest, ReRetainAutoConnect) {
983 service_->EnableAndRetainAutoConnect();
984 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000985 EXPECT_TRUE(service_->auto_connect());
986
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700987 service_->SetAutoConnect(false);
Paul Stewart2da34c02013-10-17 15:28:56 -0700988 service_->EnableAndRetainAutoConnect();
989 EXPECT_TRUE(service_->retain_auto_connect());
mukesh agrawal00917ce2011-11-22 23:56:55 +0000990 EXPECT_FALSE(service_->auto_connect());
991}
992
mukesh agrawal76d13882012-01-12 15:23:11 -0800993TEST_F(ServiceTest, IsAutoConnectable) {
Paul Stewart3b30ca52015-06-16 13:13:10 -0700994 const char* reason = nullptr;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700995 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +0100996
997 // Services with non-primary connectivity technologies should not auto-connect
998 // when the system is offline.
999 EXPECT_EQ(Technology::kUnknown, service_->technology());
Peter Qiu700de642014-07-14 16:31:30 -07001000 EXPECT_CALL(mock_manager_, IsConnected()).WillOnce(Return(false));
Darin Petkov4cbff5b2013-01-29 16:29:05 +01001001 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1002 EXPECT_STREQ(Service::kAutoConnOffline, reason);
1003
1004 service_->technology_ = Technology::kEthernet;
mukesh agrawalbf14e942012-03-02 14:36:34 -08001005 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawal76d13882012-01-12 15:23:11 -08001006
mukesh agrawaladb68482012-01-17 16:31:51 -08001007 // We should not auto-connect to a Service that a user has
1008 // deliberately disconnected.
1009 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001010 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001011 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1012 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
mukesh agrawaladb68482012-01-17 16:31:51 -08001013
1014 // But if the Service is reloaded, it is eligible for auto-connect
1015 // again.
1016 NiceMock<MockStore> storage;
1017 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
Peter Qiu1a72f542015-04-14 16:31:36 -07001018#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001019 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
Peter Qiu1a72f542015-04-14 16:31:36 -07001020#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
mukesh agrawaladb68482012-01-17 16:31:51 -08001021 EXPECT_TRUE(service_->Load(&storage));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001022 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001023
1024 // A deliberate Connect should also re-enable auto-connect.
Christopher Wileyabd3b502012-09-26 13:08:52 -07001025 service_->UserInitiatedDisconnect(&error);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001026 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
mukesh agrawaldc7b8442012-09-27 13:48:14 -07001027 service_->Connect(&error, "in test");
mukesh agrawalbf14e942012-03-02 14:36:34 -08001028 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001029
Christopher Wileyabd3b502012-09-26 13:08:52 -07001030 // A non-user initiated Disconnect doesn't change anything.
Samuel Tan0d061192014-07-07 15:45:15 -07001031 service_->Disconnect(&error, "in test");
Christopher Wileyabd3b502012-09-26 13:08:52 -07001032 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1033
Christopher Wileya4c61ae2012-10-01 11:04:30 -07001034 // A resume also re-enables auto-connect.
1035 service_->UserInitiatedDisconnect(&error);
1036 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1037 service_->OnAfterResume();
1038 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
mukesh agrawaladb68482012-01-17 16:31:51 -08001039
mukesh agrawal76d13882012-01-12 15:23:11 -08001040 service_->SetState(Service::kStateConnected);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001041 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1042 EXPECT_STREQ(Service::kAutoConnConnected, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -08001043
1044 service_->SetState(Service::kStateAssociating);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001045 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1046 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
Ben Chan8e6b8ef2014-07-14 21:50:18 -07001047
1048 service_->SetState(Service::kStateIdle);
1049 EXPECT_CALL(mock_manager_, IsTechnologyAutoConnectDisabled(
1050 service_->technology_)).WillOnce(Return(true));
1051 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1052 EXPECT_STREQ(Service::kAutoConnTechnologyNotConnectable, reason);
mukesh agrawal76d13882012-01-12 15:23:11 -08001053}
1054
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001055TEST_F(ServiceTest, AutoConnectLogging) {
1056 ScopedMockLog log;
1057 EXPECT_CALL(log, Log(_, _, _));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001058 service_->SetConnectable(true);
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001059
1060 ScopeLogger::GetInstance()->EnableScopesByName("+service");
1061 ScopeLogger::GetInstance()->set_verbose_level(1);
1062 service_->SetState(Service::kStateConnected);
1063 EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected)));
1064 service_->AutoConnect();
1065
1066 ScopeLogger::GetInstance()->EnableScopesByName("-service");
1067 ScopeLogger::GetInstance()->set_verbose_level(0);
1068 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1069 HasSubstr(Service::kAutoConnNotConnectable)));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001070 service_->SetConnectable(false);
mukesh agrawal03c15ce2012-11-29 17:36:21 -08001071 service_->AutoConnect();
1072}
1073
1074
Christopher Wiley0801d192012-09-24 11:57:15 -07001075TEST_F(AllMockServiceTest, AutoConnectWithFailures) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001076 const char* reason;
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001077 service_->SetConnectable(true);
Darin Petkov4cbff5b2013-01-29 16:29:05 +01001078 service_->technology_ = Technology::kEthernet;
Christopher Wiley0801d192012-09-24 11:57:15 -07001079 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1080
1081 // The very first AutoConnect() doesn't trigger any throttling.
1082 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1083 service_->AutoConnect();
1084 Mock::VerifyAndClearExpectations(&dispatcher_);
1085 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1086
1087 // The second call does trigger some throttling.
1088 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1089 Service::kMinAutoConnectCooldownTimeMilliseconds));
1090 service_->AutoConnect();
1091 Mock::VerifyAndClearExpectations(&dispatcher_);
1092 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1093 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1094
1095 // Calling AutoConnect() again before the cooldown terminates does not change
1096 // the timeout.
1097 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1098 service_->AutoConnect();
1099 Mock::VerifyAndClearExpectations(&dispatcher_);
1100 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1101 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1102
1103 // Once the timeout expires, we can AutoConnect() again.
1104 service_->ReEnableAutoConnectTask();
1105 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1106
1107 // Timeouts increase exponentially.
Ben Chan7fab8972014-08-10 17:14:46 -07001108 uint64_t next_cooldown_time = service_->auto_connect_cooldown_milliseconds_;
Christopher Wiley0801d192012-09-24 11:57:15 -07001109 EXPECT_EQ(next_cooldown_time,
1110 Service::kAutoConnectCooldownBackoffFactor *
1111 Service::kMinAutoConnectCooldownTimeMilliseconds);
1112 while (next_cooldown_time <=
1113 Service::kMaxAutoConnectCooldownTimeMilliseconds) {
1114 EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time));
1115 service_->AutoConnect();
1116 Mock::VerifyAndClearExpectations(&dispatcher_);
1117 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1118 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1119 service_->ReEnableAutoConnectTask();
1120 next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor;
1121 }
1122
1123 // Once we hit our cap, future timeouts are the same.
Ben Chan7fab8972014-08-10 17:14:46 -07001124 for (int32_t i = 0; i < 2; i++) {
Christopher Wiley0801d192012-09-24 11:57:15 -07001125 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1126 Service::kMaxAutoConnectCooldownTimeMilliseconds));
1127 service_->AutoConnect();
1128 Mock::VerifyAndClearExpectations(&dispatcher_);
1129 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1130 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1131 service_->ReEnableAutoConnectTask();
1132 }
1133
1134 // Connecting successfully resets our cooldown.
1135 service_->SetState(Service::kStateConnected);
1136 service_->SetState(Service::kStateIdle);
1137 reason = "";
1138 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1139 EXPECT_STREQ("", reason);
1140 EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0);
1141
1142 // But future AutoConnects behave as before
1143 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1144 Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1);
1145 service_->AutoConnect();
1146 service_->AutoConnect();
1147 Mock::VerifyAndClearExpectations(&dispatcher_);
1148 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1149 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1150
1151 // Cooldowns are forgotten if we go through a suspend/resume cycle.
1152 service_->OnAfterResume();
1153 reason = "";
1154 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1155 EXPECT_STREQ("", reason);
1156}
1157
Paul Stewartcb59fed2012-03-21 21:14:46 -07001158TEST_F(ServiceTest, ConfigureBadProperty) {
1159 KeyValueStore args;
1160 args.SetString("XXXInvalid", "Value");
1161 Error error;
1162 service_->Configure(args, &error);
1163 EXPECT_FALSE(error.IsSuccess());
1164}
1165
1166TEST_F(ServiceTest, ConfigureBoolProperty) {
Paul Stewart2da34c02013-10-17 15:28:56 -07001167 service_->EnableAndRetainAutoConnect();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001168 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001169 ASSERT_FALSE(service_->auto_connect());
1170 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001171 args.SetBool(kAutoConnectProperty, true);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001172 Error error;
1173 service_->Configure(args, &error);
1174 EXPECT_TRUE(error.IsSuccess());
1175 EXPECT_TRUE(service_->auto_connect());
1176}
1177
1178TEST_F(ServiceTest, ConfigureStringProperty) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001179 const string kGuid0 = "guid_zero";
1180 const string kGuid1 = "guid_one";
Ben Chancc225ef2014-09-30 13:26:51 -07001181 service_->SetGuid(kGuid0, nullptr);
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001182 ASSERT_EQ(kGuid0, service_->guid());
Paul Stewartcb59fed2012-03-21 21:14:46 -07001183 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001184 args.SetString(kGuidProperty, kGuid1);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001185 Error error;
1186 service_->Configure(args, &error);
1187 EXPECT_TRUE(error.IsSuccess());
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001188 EXPECT_EQ(kGuid1, service_->guid());
1189}
1190
Paul Stewart99dc9f32013-06-27 07:39:25 -07001191TEST_F(ServiceTest, ConfigureStringsProperty) {
1192 const vector<string> kStrings0{ "string0", "string1" };
1193 const vector<string> kStrings1{ "string2", "string3" };
1194 service_->set_strings(kStrings0);
1195 ASSERT_EQ(kStrings0, service_->strings());
1196 KeyValueStore args;
1197 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
1198 Error error;
1199 service_->Configure(args, &error);
1200 EXPECT_TRUE(error.IsSuccess());
1201 EXPECT_EQ(kStrings1, service_->strings());
1202}
1203
Peter Qiu1a72f542015-04-14 16:31:36 -07001204#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001205TEST_F(ServiceTest, ConfigureEapStringProperty) {
Paul Stewart3b30ca52015-06-16 13:13:10 -07001206 MockEapCredentials* eap = new MockEapCredentials();
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001207 service2_->SetEapCredentials(eap); // Passes ownership.
1208
1209 const string kEAPManagement0 = "management_zero";
1210 const string kEAPManagement1 = "management_one";
1211 service2_->SetEAPKeyManagement(kEAPManagement0);
1212
1213 EXPECT_CALL(*eap, key_management())
1214 .WillOnce(ReturnRef(kEAPManagement0));
1215 ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement());
1216 KeyValueStore args;
1217 EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _));
Ben Chan923a5022013-09-20 11:23:23 -07001218 args.SetString(kEapKeyMgmtProperty, kEAPManagement1);
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001219 Error error;
1220 service2_->Configure(args, &error);
1221 EXPECT_TRUE(error.IsSuccess());
Paul Stewartcb59fed2012-03-21 21:14:46 -07001222}
Peter Qiu1a72f542015-04-14 16:31:36 -07001223#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartcb59fed2012-03-21 21:14:46 -07001224
Paul Stewart7a20aa42013-01-17 12:21:41 -08001225TEST_F(ServiceTest, ConfigureIntProperty) {
1226 const int kPriority0 = 100;
1227 const int kPriority1 = 200;
Ben Chancc225ef2014-09-30 13:26:51 -07001228 service_->SetPriority(kPriority0, nullptr);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001229 ASSERT_EQ(kPriority0, service_->priority());
1230 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001231 args.SetInt(kPriorityProperty, kPriority1);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001232 Error error;
1233 service_->Configure(args, &error);
1234 EXPECT_TRUE(error.IsSuccess());
1235 EXPECT_EQ(kPriority1, service_->priority());
1236}
1237
Paul Stewartcb59fed2012-03-21 21:14:46 -07001238TEST_F(ServiceTest, ConfigureIgnoredProperty) {
Paul Stewart2da34c02013-10-17 15:28:56 -07001239 service_->EnableAndRetainAutoConnect();
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001240 service_->SetAutoConnect(false);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001241 ASSERT_FALSE(service_->auto_connect());
1242 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001243 args.SetBool(kAutoConnectProperty, true);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001244 Error error;
Ben Chan923a5022013-09-20 11:23:23 -07001245 service_->IgnoreParameterForConfigure(kAutoConnectProperty);
Paul Stewartcb59fed2012-03-21 21:14:46 -07001246 service_->Configure(args, &error);
1247 EXPECT_TRUE(error.IsSuccess());
1248 EXPECT_FALSE(service_->auto_connect());
1249}
1250
Paul Stewartad0e5982013-07-02 08:47:47 -07001251TEST_F(ServiceTest, ConfigureProfileProperty) {
1252 // Ensure that the Profile property is always ignored.
1253 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001254 args.SetString(kProfileProperty, "profile");
Paul Stewartad0e5982013-07-02 08:47:47 -07001255 Error error;
1256 EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
1257 service_->Configure(args, &error);
1258 EXPECT_TRUE(error.IsSuccess());
1259}
1260
Paul Stewartbb833562015-01-21 23:30:46 -08001261TEST_F(ServiceTest, ConfigureKeyValueStoreProperty) {
1262 KeyValueStore key_value_store0;
1263 key_value_store0.SetBool("key0", true);
1264 KeyValueStore key_value_store1;
1265 key_value_store1.SetInt("key1", 1);
1266 service_->SetKeyValueStore(key_value_store0, NULL);
Peter Qiud31fb582015-07-15 14:33:32 -07001267 ASSERT_EQ(key_value_store0, service_->GetKeyValueStore(NULL));
Paul Stewartbb833562015-01-21 23:30:46 -08001268 KeyValueStore args;
1269 args.SetKeyValueStore(
1270 ServiceUnderTest::kKeyValueStoreProperty, key_value_store1);
1271 Error error;
1272 service_->Configure(args, &error);
1273 EXPECT_TRUE(error.IsSuccess());
Peter Qiud31fb582015-07-15 14:33:32 -07001274 EXPECT_EQ(key_value_store1, service_->GetKeyValueStore(NULL));
Paul Stewartbb833562015-01-21 23:30:46 -08001275}
1276
Paul Stewart7a20aa42013-01-17 12:21:41 -08001277TEST_F(ServiceTest, DoPropertiesMatch) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001278 service_->SetAutoConnect(false);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001279 const string kGUID0 = "guid_zero";
1280 const string kGUID1 = "guid_one";
Ben Chancc225ef2014-09-30 13:26:51 -07001281 service_->SetGuid(kGUID0, nullptr);
Ben Chan7fab8972014-08-10 17:14:46 -07001282 const uint32_t kPriority0 = 100;
1283 const uint32_t kPriority1 = 200;
Ben Chancc225ef2014-09-30 13:26:51 -07001284 service_->SetPriority(kPriority0, nullptr);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001285 const vector<string> kStrings0{ "string0", "string1" };
1286 const vector<string> kStrings1{ "string2", "string3" };
1287 service_->set_strings(kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001288 KeyValueStore key_value_store0;
1289 key_value_store0.SetBool("key0", true);
1290 KeyValueStore key_value_store1;
1291 key_value_store1.SetInt("key1", 1);
1292 service_->SetKeyValueStore(key_value_store0, NULL);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001293
1294 {
1295 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001296 args.SetString(kGuidProperty, kGUID0);
1297 args.SetBool(kAutoConnectProperty, false);
1298 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001299 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001300 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1301 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001302 EXPECT_TRUE(service_->DoPropertiesMatch(args));
1303 }
1304 {
1305 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001306 args.SetString(kGuidProperty, kGUID1);
1307 args.SetBool(kAutoConnectProperty, false);
1308 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001309 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001310 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1311 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001312 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1313 }
1314 {
1315 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001316 args.SetString(kGuidProperty, kGUID0);
1317 args.SetBool(kAutoConnectProperty, true);
1318 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001319 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001320 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1321 key_value_store0);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001322 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1323 }
1324 {
1325 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001326 args.SetString(kGuidProperty, kGUID0);
1327 args.SetBool(kAutoConnectProperty, false);
1328 args.SetInt(kPriorityProperty, kPriority1);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001329 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
Paul Stewartbb833562015-01-21 23:30:46 -08001330 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1331 key_value_store0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001332 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1333 }
1334 {
1335 KeyValueStore args;
Ben Chan923a5022013-09-20 11:23:23 -07001336 args.SetString(kGuidProperty, kGUID0);
1337 args.SetBool(kAutoConnectProperty, false);
1338 args.SetInt(kPriorityProperty, kPriority0);
Paul Stewart99dc9f32013-06-27 07:39:25 -07001339 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
Paul Stewartbb833562015-01-21 23:30:46 -08001340 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1341 key_value_store0);
1342 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1343 }
1344 {
1345 KeyValueStore args;
1346 args.SetString(kGuidProperty, kGUID0);
1347 args.SetBool(kAutoConnectProperty, false);
1348 args.SetInt(kPriorityProperty, kPriority0);
1349 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1350 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1351 key_value_store1);
Paul Stewart7a20aa42013-01-17 12:21:41 -08001352 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1353 }
1354}
1355
Paul Stewart10ccbb32012-04-26 15:59:30 -07001356TEST_F(ServiceTest, IsRemembered) {
Ben Chancc225ef2014-09-30 13:26:51 -07001357 service_->set_profile(nullptr);
Paul Stewart10ccbb32012-04-26 15:59:30 -07001358 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
1359 EXPECT_FALSE(service_->IsRemembered());
1360
1361 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001362 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Paul Stewart10ccbb32012-04-26 15:59:30 -07001363 service_->set_profile(profile);
Paul Stewartf2860342014-05-09 14:29:16 -07001364 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
Paul Stewart10ccbb32012-04-26 15:59:30 -07001365 .WillOnce(Return(true))
1366 .WillOnce(Return(false));
1367 EXPECT_FALSE(service_->IsRemembered());
1368 EXPECT_TRUE(service_->IsRemembered());
1369}
1370
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001371TEST_F(ServiceTest, IsDependentOn) {
Ben Chancc225ef2014-09-30 13:26:51 -07001372 EXPECT_FALSE(service_->IsDependentOn(nullptr));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001373
Ben Chancd477322014-10-17 14:19:30 -07001374 std::unique_ptr<MockDeviceInfo> mock_device_info(
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001375 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1376 &mock_manager_));
1377 scoped_refptr<MockConnection> mock_connection0(
1378 new NiceMock<MockConnection>(mock_device_info.get()));
1379 scoped_refptr<MockConnection> mock_connection1(
1380 new NiceMock<MockConnection>(mock_device_info.get()));
1381
1382 service_->connection_ = mock_connection0;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001383 EXPECT_CALL(*mock_connection0, GetLowerConnection())
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001384 .WillRepeatedly(Return(mock_connection1));
Paul Stewartcd7f5852013-03-27 13:54:23 -07001385 EXPECT_CALL(*mock_connection1, GetLowerConnection())
1386 .WillRepeatedly(Return(ConnectionRefPtr()));
Ben Chancc225ef2014-09-30 13:26:51 -07001387 EXPECT_FALSE(service_->IsDependentOn(nullptr));
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001388
1389 scoped_refptr<ServiceUnderTest> service1 =
1390 new ServiceUnderTest(control_interface(),
1391 dispatcher(),
1392 metrics(),
1393 &mock_manager_);
1394 EXPECT_FALSE(service_->IsDependentOn(service1));
1395
1396 service1->connection_ = mock_connection0;
1397 EXPECT_FALSE(service_->IsDependentOn(service1));
1398
1399 service1->connection_ = mock_connection1;
1400 EXPECT_TRUE(service_->IsDependentOn(service1));
1401
Paul Stewartcd7f5852013-03-27 13:54:23 -07001402 service_->connection_ = mock_connection1;
Ben Chancc225ef2014-09-30 13:26:51 -07001403 service1->connection_ = nullptr;
Paul Stewartcd7f5852013-03-27 13:54:23 -07001404 EXPECT_FALSE(service_->IsDependentOn(service1));
1405
Ben Chancc225ef2014-09-30 13:26:51 -07001406 service_->connection_ = nullptr;
Paul Stewartdf3c0a82012-11-09 15:54:33 -08001407}
1408
Paul Stewartff14b022012-04-24 20:06:23 -07001409TEST_F(ServiceTest, OnPropertyChanged) {
1410 scoped_refptr<MockProfile> profile(
Thieu Le5133b712013-02-19 14:47:21 -08001411 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
Ben Chancc225ef2014-09-30 13:26:51 -07001412 service_->set_profile(nullptr);
Paul Stewartff14b022012-04-24 20:06:23 -07001413 // Expect no crash.
1414 service_->OnPropertyChanged("");
1415
1416 // Expect no call to Update if the profile has no storage.
1417 service_->set_profile(profile);
1418 EXPECT_CALL(*profile, UpdateService(_)).Times(0);
Ben Chancc225ef2014-09-30 13:26:51 -07001419 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(nullptr));
Paul Stewartff14b022012-04-24 20:06:23 -07001420 service_->OnPropertyChanged("");
1421
1422 // Expect call to Update if the profile has storage.
1423 EXPECT_CALL(*profile, UpdateService(_)).Times(1);
1424 NiceMock<MockStore> storage;
1425 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
1426 service_->OnPropertyChanged("");
1427}
1428
Paul Stewartd215af62012-04-24 23:25:50 -07001429
1430TEST_F(ServiceTest, RecheckPortal) {
Paul Stewartd215af62012-04-24 23:25:50 -07001431 service_->state_ = Service::kStateIdle;
1432 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
Ben Chan923a5022013-09-20 11:23:23 -07001433 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001434
1435 service_->state_ = Service::kStatePortal;
Paul Stewartf2860342014-05-09 14:29:16 -07001436 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1437 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001438 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001439
1440 service_->state_ = Service::kStateConnected;
Paul Stewartf2860342014-05-09 14:29:16 -07001441 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1442 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001443 service_->OnPropertyChanged(kProxyConfigProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001444
1445 service_->state_ = Service::kStateOnline;
Paul Stewartf2860342014-05-09 14:29:16 -07001446 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1447 .Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001448 service_->OnPropertyChanged(kCheckPortalProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001449
1450 service_->state_ = Service::kStatePortal;
1451 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
Ben Chan011e6662014-05-07 11:03:25 -07001452 service_->OnPropertyChanged(kEapKeyIdProperty);
Paul Stewartd215af62012-04-24 23:25:50 -07001453}
1454
1455TEST_F(ServiceTest, SetCheckPortal) {
Paul Stewartd215af62012-04-24 23:25:50 -07001456 {
1457 Error error;
1458 service_->SetCheckPortal("false", &error);
1459 EXPECT_TRUE(error.IsSuccess());
1460 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
1461 }
1462 {
1463 Error error;
1464 service_->SetCheckPortal("true", &error);
1465 EXPECT_TRUE(error.IsSuccess());
1466 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
1467 }
1468 {
1469 Error error;
1470 service_->SetCheckPortal("auto", &error);
1471 EXPECT_TRUE(error.IsSuccess());
1472 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1473 }
1474 {
1475 Error error;
1476 service_->SetCheckPortal("xxx", &error);
1477 EXPECT_FALSE(error.IsSuccess());
1478 EXPECT_EQ(Error::kInvalidArguments, error.type());
1479 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1480 }
1481}
1482
Arman Uguray2717a102013-01-29 23:36:06 -08001483TEST_F(ServiceTest, SetFriendlyName) {
1484 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
Paul Stewart3b30ca52015-06-16 13:13:10 -07001485 ServiceMockAdaptor* adaptor = GetAdaptor();
Arman Uguray2717a102013-01-29 23:36:06 -08001486
1487 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1488 service_->SetFriendlyName(service_->unique_name_);
1489 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
1490
Ben Chan923a5022013-09-20 11:23:23 -07001491 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
Arman Uguray2717a102013-01-29 23:36:06 -08001492 "Test Name 1"));
1493 service_->SetFriendlyName("Test Name 1");
1494 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1495
1496 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1497 service_->SetFriendlyName("Test Name 1");
1498 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1499
Ben Chan923a5022013-09-20 11:23:23 -07001500 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
Arman Uguray2717a102013-01-29 23:36:06 -08001501 "Test Name 2"));
1502 service_->SetFriendlyName("Test Name 2");
1503 EXPECT_EQ("Test Name 2", service_->friendly_name_);
1504}
1505
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001506TEST_F(ServiceTest, SetConnectableFull) {
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001507 EXPECT_FALSE(service_->connectable());
1508
Paul Stewart3b30ca52015-06-16 13:13:10 -07001509 ServiceMockAdaptor* adaptor = GetAdaptor();
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001510
1511 EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0);
1512 EXPECT_CALL(mock_manager_, HasService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001513 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001514 EXPECT_FALSE(service_->connectable());
1515
Ben Chan923a5022013-09-20 11:23:23 -07001516 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001517 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false));
1518 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001519 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001520 EXPECT_TRUE(service_->connectable());
1521
Ben Chan923a5022013-09-20 11:23:23 -07001522 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, false));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001523 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1524 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001525 service_->SetConnectableFull(false);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001526 EXPECT_FALSE(service_->connectable());
1527
Ben Chan923a5022013-09-20 11:23:23 -07001528 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001529 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1530 EXPECT_CALL(mock_manager_, UpdateService(_));
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001531 service_->SetConnectableFull(true);
Darin Petkovb2ba39f2012-06-06 10:33:43 +02001532 EXPECT_TRUE(service_->connectable());
1533}
1534
Peter Qiu1a72f542015-04-14 16:31:36 -07001535#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001536class WriteOnlyServicePropertyTest : public ServiceTest {};
1537TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) {
1538 // Use a real EapCredentials instance since the base Service class
1539 // contains no write-only properties.
1540 EapCredentials eap;
1541 eap.InitPropertyStore(service_->mutable_store());
1542
Paul Stewart9f32d192012-01-30 20:37:50 -08001543 string property(GetParam().reader().get_string());
Paul Stewarte6e8e492013-01-17 11:00:50 -08001544 Error error;
Ben Chancc225ef2014-09-30 13:26:51 -07001545 EXPECT_FALSE(service_->store().GetStringProperty(property, nullptr, &error));
Paul Stewarte6e8e492013-01-17 11:00:50 -08001546 EXPECT_EQ(Error::kPermissionDenied, error.type());
Paul Stewart9f32d192012-01-30 20:37:50 -08001547}
1548
1549INSTANTIATE_TEST_CASE_P(
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001550 WriteOnlyServicePropertyTestInstance,
1551 WriteOnlyServicePropertyTest,
Paul Stewart9f32d192012-01-30 20:37:50 -08001552 Values(
Ben Chan923a5022013-09-20 11:23:23 -07001553 DBusAdaptor::StringToVariant(kEapPrivateKeyPasswordProperty),
1554 DBusAdaptor::StringToVariant(kEapPasswordProperty)));
Peter Qiu1a72f542015-04-14 16:31:36 -07001555#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewart10241e32012-04-23 18:15:06 -07001556
1557TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
1558 {
1559 Error error;
1560 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1561 EXPECT_EQ(Error::kNotFound, error.type());
1562 }
1563
Ben Chancd477322014-10-17 14:19:30 -07001564 std::unique_ptr<MockDeviceInfo> mock_device_info(
Paul Stewart10241e32012-04-23 18:15:06 -07001565 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1566 &mock_manager_));
1567 scoped_refptr<MockConnection> mock_connection(
1568 new NiceMock<MockConnection>(mock_device_info.get()));
1569
1570 service_->connection_ = mock_connection;
1571
1572 {
1573 Error error;
1574 const string empty_string;
1575 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1576 .WillOnce(ReturnRef(empty_string));
1577 EXPECT_EQ("/", service_->GetIPConfigRpcIdentifier(&error));
1578 EXPECT_EQ(Error::kNotFound, error.type());
1579 }
1580
1581 {
1582 Error error;
1583 const string nonempty_string("/ipconfig/path");
1584 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1585 .WillOnce(ReturnRef(nonempty_string));
1586 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
1587 EXPECT_EQ(Error::kSuccess, error.type());
1588 }
1589
1590 // Assure orderly destruction of the Connection before DeviceInfo.
Ben Chancc225ef2014-09-30 13:26:51 -07001591 service_->connection_ = nullptr;
1592 mock_connection = nullptr;
Paul Stewart10241e32012-04-23 18:15:06 -07001593 mock_device_info.reset();
1594}
1595
Peter Qiu1a72f542015-04-14 16:31:36 -07001596#if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001597class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest {
Paul Stewart81426132012-05-16 10:05:10 -07001598 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -07001599 ServiceWithMockOnEapCredentialsChanged(ControlInterface* control_interface,
1600 EventDispatcher* dispatcher,
1601 Metrics* metrics,
1602 Manager* manager)
Paul Stewart81426132012-05-16 10:05:10 -07001603 : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
1604 is_8021x_(false) {}
Rebecca Silberstein57776902014-09-15 21:43:02 -07001605 MOCK_METHOD1(OnEapCredentialsChanged, void(Service::UpdateCredentialsReason));
Paul Stewart81426132012-05-16 10:05:10 -07001606 virtual bool Is8021x() const { return is_8021x_; }
1607 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }
1608
1609 private:
1610 bool is_8021x_;
1611};
1612
1613TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001614 scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service(
1615 new ServiceWithMockOnEapCredentialsChanged(control_interface(),
1616 dispatcher(),
1617 metrics(),
1618 &mock_manager_));
Paul Stewart81426132012-05-16 10:05:10 -07001619 string eap_credential_properties[] = {
Ben Chan923a5022013-09-20 11:23:23 -07001620 kEapAnonymousIdentityProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001621 kEapCertIdProperty,
1622 kEapClientCertProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001623 kEapIdentityProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001624 kEapKeyIdProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001625 kEapPasswordProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001626 kEapPinProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001627 kEapPrivateKeyProperty,
1628 kEapPrivateKeyPasswordProperty
Paul Stewart81426132012-05-16 10:05:10 -07001629 };
1630 string eap_non_credential_properties[] = {
Ben Chan011e6662014-05-07 11:03:25 -07001631 kEapCaCertIdProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001632 kEapCaCertNssProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001633 kEapMethodProperty,
Ben Chan923a5022013-09-20 11:23:23 -07001634 kEapPhase2AuthProperty,
Ben Chan011e6662014-05-07 11:03:25 -07001635 kEapUseSystemCasProperty
Paul Stewart81426132012-05-16 10:05:10 -07001636 };
1637 // While this is not an 802.1x-based service, none of these property
1638 // changes should cause a call to set_eap().
Rebecca Silberstein57776902014-09-15 21:43:02 -07001639 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001640 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
1641 service->OnPropertyChanged(eap_credential_properties[i]);
1642 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1643 service->OnPropertyChanged(eap_non_credential_properties[i]);
Ben Chan923a5022013-09-20 11:23:23 -07001644 service->OnPropertyChanged(kEapKeyMgmtProperty);
Paul Stewart81426132012-05-16 10:05:10 -07001645
1646 service->set_is_8021x(true);
1647
1648 // When this is an 802.1x-based service, set_eap should be called for
1649 // all credential-carrying properties.
1650 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
Rebecca Silberstein57776902014-09-15 21:43:02 -07001651 EXPECT_CALL(*service,
1652 OnEapCredentialsChanged(
1653 Service::kReasonPropertyUpdate)).Times(1);
Paul Stewart81426132012-05-16 10:05:10 -07001654 service->OnPropertyChanged(eap_credential_properties[i]);
1655 Mock::VerifyAndClearExpectations(service.get());
1656 }
Paul Stewartadf79d82012-07-18 16:09:56 -07001657
1658 // The key management property is a special case. While not strictly
1659 // a credential, it can change which credentials are used. Therefore it
1660 // should also trigger a call to set_eap();
Rebecca Silberstein57776902014-09-15 21:43:02 -07001661 EXPECT_CALL(*service,
1662 OnEapCredentialsChanged(Service::kReasonPropertyUpdate)).Times(1);
Ben Chan923a5022013-09-20 11:23:23 -07001663 service->OnPropertyChanged(kEapKeyMgmtProperty);
Paul Stewartadf79d82012-07-18 16:09:56 -07001664 Mock::VerifyAndClearExpectations(service.get());
1665
Rebecca Silberstein57776902014-09-15 21:43:02 -07001666 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
Paul Stewart81426132012-05-16 10:05:10 -07001667 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1668 service->OnPropertyChanged(eap_non_credential_properties[i]);
1669}
1670
Paul Stewartbc6e7392012-05-24 07:07:48 -07001671TEST_F(ServiceTest, Certification) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001672 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001673
1674 ScopedMockLog log;
1675 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1676 HasSubstr("exceeds our maximum"))).Times(2);
1677 string kSubject("foo");
1678 EXPECT_FALSE(service_->AddEAPCertification(
1679 kSubject, Service::kEAPMaxCertificationElements));
1680 EXPECT_FALSE(service_->AddEAPCertification(
1681 kSubject, Service::kEAPMaxCertificationElements + 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001682 EXPECT_FALSE(service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001683 Mock::VerifyAndClearExpectations(&log);
1684
1685 EXPECT_CALL(log,
1686 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1687 .Times(1);
1688 EXPECT_TRUE(service_->AddEAPCertification(
1689 kSubject, Service::kEAPMaxCertificationElements - 1));
1690 Mock::VerifyAndClearExpectations(&log);
1691 EXPECT_EQ(Service::kEAPMaxCertificationElements,
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001692 service_->remote_certification_.size());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001693 for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) {
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001694 EXPECT_TRUE(service_->remote_certification_[i].empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001695 }
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001696 EXPECT_EQ(kSubject, service_->remote_certification_[
Paul Stewartbc6e7392012-05-24 07:07:48 -07001697 Service::kEAPMaxCertificationElements - 1]);
1698
1699 // Re-adding the same name in the same position should not generate a log.
1700 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1701 EXPECT_TRUE(service_->AddEAPCertification(
1702 kSubject, Service::kEAPMaxCertificationElements - 1));
1703
1704 // Replacing the item should generate a log message.
1705 EXPECT_CALL(log,
1706 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1707 .Times(1);
1708 EXPECT_TRUE(service_->AddEAPCertification(
1709 kSubject + "x", Service::kEAPMaxCertificationElements - 1));
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001710
1711 service_->ClearEAPCertification();
1712 EXPECT_TRUE(service_->remote_certification_.empty());
Paul Stewartbc6e7392012-05-24 07:07:48 -07001713}
Peter Qiu1a72f542015-04-14 16:31:36 -07001714#endif // DISABLE_WIFI || DISABLE_WIRED_8021X
Paul Stewartbc6e7392012-05-24 07:07:48 -07001715
Darin Petkovc8d91e52013-01-21 11:43:47 +01001716TEST_F(ServiceTest, NoteDisconnectEventIdle) {
Paul Stewart483e4722012-12-18 10:23:17 -08001717 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001718 EXPECT_CALL(time_, GetNow()).Times(7).WillRepeatedly((Return(timestamp)));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001719 SetStateField(Service::kStateOnline);
Darin Petkov0857f8e2012-12-21 10:49:17 +01001720 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001721 service_->SetState(Service::kStateIdle);
Darin Petkovc8d91e52013-01-21 11:43:47 +01001722 // The transition Online->Idle is not an event.
Darin Petkov0857f8e2012-12-21 10:49:17 +01001723 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Darin Petkovc8d91e52013-01-21 11:43:47 +01001724 service_->SetState(Service::kStateFailure);
1725 // The transition Online->Idle->Failure is a connection drop.
1726 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov0857f8e2012-12-21 10:49:17 +01001727}
1728
1729TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) {
1730 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001731 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
Darin Petkov0857f8e2012-12-21 10:49:17 +01001732 SetStateField(Service::kStateOnline);
1733 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1734 service_->SetState(Service::kStateFailure);
1735 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1736}
1737
1738TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) {
1739 Timestamp timestamp;
Samuel Tan07dfabc2015-01-20 15:10:39 -08001740 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
Darin Petkov0857f8e2012-12-21 10:49:17 +01001741 SetStateField(Service::kStateConfiguring);
1742 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1743 service_->SetFailureSilent(Service::kFailureEAPAuthentication);
Paul Stewart483e4722012-12-18 10:23:17 -08001744 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001745}
1746
1747TEST_F(ServiceTest, NoteDisconnectEventNonEvent) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001748 EXPECT_CALL(time_, GetNow()).Times(0);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001749 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1750
1751 // Explicit disconnect is a non-event.
1752 SetStateField(Service::kStateOnline);
1753 SetExplicitlyDisconnected(true);
1754 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001755 EXPECT_TRUE(GetDisconnects()->Empty());
1756 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001757
1758 // Failure to idle transition is a non-event.
1759 SetStateField(Service::kStateFailure);
1760 SetExplicitlyDisconnected(false);
1761 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001762 EXPECT_TRUE(GetDisconnects()->Empty());
1763 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkovcb0b5662012-12-13 09:59:44 +01001764
1765 // Disconnect while manager is stopped is a non-event.
1766 SetStateField(Service::kStateOnline);
1767 SetManagerRunning(false);
1768 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001769 EXPECT_TRUE(GetDisconnects()->Empty());
1770 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkovcb0b5662012-12-13 09:59:44 +01001771
1772 // Disconnect while suspending is a non-event.
1773 SetManagerRunning(true);
Daniel Eratfac09532014-04-17 20:25:59 -07001774 SetSuspending(true);
Darin Petkovcb0b5662012-12-13 09:59:44 +01001775 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001776 EXPECT_TRUE(GetDisconnects()->Empty());
1777 EXPECT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001778}
1779
1780TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001781 const int kNow = 5;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001782 EXPECT_FALSE(service_->explicitly_disconnected());
1783 SetStateField(Service::kStateOnline);
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001784 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001785 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1786 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001787 ASSERT_EQ(1, GetDisconnects()->Size());
1788 EXPECT_EQ(kNow, GetDisconnects()->Front().monotonic.tv_sec);
1789 EXPECT_TRUE(GetMisconnects()->Empty());
Paul Stewart483e4722012-12-18 10:23:17 -08001790
1791 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001792 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001793 kNow + GetDisconnectsMonitorSeconds() - 1,
1794 kNow + GetDisconnectsMonitorSeconds() - 1,
1795 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001796 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001797 ASSERT_EQ(1, GetDisconnects()->Size());
Paul Stewart483e4722012-12-18 10:23:17 -08001798
1799 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001800 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001801 kNow + GetDisconnectsMonitorSeconds(),
1802 kNow + GetDisconnectsMonitorSeconds(),
1803 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001804 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001805 ASSERT_TRUE(GetDisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001806}
1807
1808TEST_F(ServiceTest, NoteDisconnectEventDisconnectThreshold) {
1809 EXPECT_FALSE(service_->explicitly_disconnected());
1810 SetStateField(Service::kStateOnline);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001811 const int kNow = 6;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001812 for (int i = 0; i < GetReportDisconnectsThreshold() - 1; i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001813 PushTimestamp(GetDisconnects(), kNow, kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001814 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001815 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001816 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1817 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001818 EXPECT_EQ(GetReportDisconnectsThreshold(), GetDisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001819}
1820
1821TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001822 const int kNow = 7;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001823 EXPECT_FALSE(service_->explicitly_disconnected());
1824 SetStateField(Service::kStateConfiguring);
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001825 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001826 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1827 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001828 EXPECT_TRUE(GetDisconnects()->Empty());
1829 ASSERT_EQ(1, GetMisconnects()->Size());
1830 EXPECT_EQ(kNow, GetMisconnects()->Front().monotonic.tv_sec);
Paul Stewart483e4722012-12-18 10:23:17 -08001831
1832 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001833 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001834 kNow + GetMisconnectsMonitorSeconds() - 1,
1835 kNow + GetMisconnectsMonitorSeconds() - 1,
1836 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001837 EXPECT_TRUE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001838 ASSERT_EQ(1, GetMisconnects()->Size());
Paul Stewart483e4722012-12-18 10:23:17 -08001839
1840 Mock::VerifyAndClearExpectations(&time_);
Samuel Tan07dfabc2015-01-20 15:10:39 -08001841 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001842 kNow + GetMisconnectsMonitorSeconds(),
1843 kNow + GetMisconnectsMonitorSeconds(),
1844 "")));
Paul Stewart483e4722012-12-18 10:23:17 -08001845 EXPECT_FALSE(service_->HasRecentConnectionIssues());
Samuel Tan07dfabc2015-01-20 15:10:39 -08001846 ASSERT_TRUE(GetMisconnects()->Empty());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001847}
1848
1849TEST_F(ServiceTest, NoteDisconnectEventMisconnectThreshold) {
1850 EXPECT_FALSE(service_->explicitly_disconnected());
1851 SetStateField(Service::kStateConfiguring);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001852 const int kNow = 8;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001853 for (int i = 0; i < GetReportMisconnectsThreshold() - 1; i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001854 PushTimestamp(GetMisconnects(), kNow, kNow, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001855 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001856 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001857 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1858 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001859 EXPECT_EQ(GetReportMisconnectsThreshold(), GetMisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001860}
1861
1862TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) {
1863 EXPECT_FALSE(service_->explicitly_disconnected());
1864 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(0);
1865 for (int i = 0; i < 2; i++) {
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001866 int now = 0;
Paul Stewart3b30ca52015-06-16 13:13:10 -07001867 EventHistory* events = nullptr;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001868 if (i == 0) {
1869 SetStateField(Service::kStateConnected);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001870 now = GetDisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001871 events = GetDisconnects();
1872 } else {
1873 SetStateField(Service::kStateAssociating);
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001874 now = GetMisconnectsMonitorSeconds() + 1;
Darin Petkov385b9bc2012-12-03 15:25:05 +01001875 events = GetMisconnects();
1876 }
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001877 PushTimestamp(events, 0, 0, "");
1878 PushTimestamp(events, 0, 0, "");
1879 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, now, "")));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001880 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001881 ASSERT_EQ(1, events->Size());
1882 EXPECT_EQ(now, events->Front().monotonic.tv_sec);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001883 }
1884}
1885
1886TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) {
1887 EXPECT_FALSE(service_->explicitly_disconnected());
1888 SetStateField(Service::kStateOnline);
Darin Petkov385b9bc2012-12-03 15:25:05 +01001889 for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) {
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001890 PushTimestamp(GetDisconnects(), 0, 0, "");
Darin Petkov385b9bc2012-12-03 15:25:05 +01001891 }
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001892 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
Darin Petkov385b9bc2012-12-03 15:25:05 +01001893 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1894 NoteDisconnectEvent();
Samuel Tan07dfabc2015-01-20 15:10:39 -08001895 EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->Size());
Darin Petkov385b9bc2012-12-03 15:25:05 +01001896}
1897
Samuel Tan07dfabc2015-01-20 15:10:39 -08001898TEST_F(ServiceTest, NoteMisconnectEventDiscardExcessive) {
1899 EXPECT_FALSE(service_->explicitly_disconnected());
1900 SetStateField(Service::kStateAssociating);
1901 for (int i = 0; i < 2 * GetMaxMisconnectEventHistory(); i++) {
1902 PushTimestamp(GetMisconnects(), 0, 0, "");
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001903 }
Samuel Tan07dfabc2015-01-20 15:10:39 -08001904 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
1905 EXPECT_CALL(diagnostics_reporter_, OnConnectivityEvent()).Times(1);
1906 NoteDisconnectEvent();
1907 EXPECT_EQ(GetMaxMisconnectEventHistory(), GetMisconnects()->Size());
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001908}
1909
1910TEST_F(ServiceTest, DiagnosticsProperties) {
Darin Petkov0857f8e2012-12-21 10:49:17 +01001911 const string kWallClock0 = "2012-12-09T12:41:22.234567-0800";
1912 const string kWallClock1 = "2012-12-31T23:59:59.345678-0800";
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001913 Strings values;
1914
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001915 PushTimestamp(GetDisconnects(), 0, 0, kWallClock0);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001916 Error unused_error;
1917 ASSERT_TRUE(service_->store().GetStringsProperty(
1918 kDiagnosticsDisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001919 ASSERT_EQ(1, values.size());
1920 EXPECT_EQ(kWallClock0, values[0]);
1921
Peter Qiu3b4ebd52014-07-29 11:16:55 -07001922 PushTimestamp(GetMisconnects(), 0, 0, kWallClock1);
Paul Stewarte6e8e492013-01-17 11:00:50 -08001923 ASSERT_TRUE(service_->store().GetStringsProperty(
1924 kDiagnosticsMisconnectsProperty, &values, &unused_error));
Darin Petkov0c65bdd2012-12-05 13:42:41 +01001925 ASSERT_EQ(1, values.size());
1926 EXPECT_EQ(kWallClock1, values[0]);
1927}
1928
mukesh agrawal43970a22013-02-15 16:00:07 -08001929TEST_F(ServiceTest, SecurityLevel) {
1930 // Encrypted is better than not.
1931 service_->SetSecurity(Service::kCryptoNone, false, false);
1932 service2_->SetSecurity(Service::kCryptoRc4, false, false);
1933 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1934
1935 // AES encryption is better than RC4 encryption.
1936 service_->SetSecurity(Service::kCryptoRc4, false, false);
1937 service2_->SetSecurity(Service::kCryptoAes, false, false);
1938 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1939
1940 // Crypto algorithm is more important than key rotation.
1941 service_->SetSecurity(Service::kCryptoNone, true, false);
1942 service2_->SetSecurity(Service::kCryptoAes, false, false);
1943 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1944
1945 // Encrypted-but-unauthenticated is better than clear-but-authenticated.
1946 service_->SetSecurity(Service::kCryptoNone, false, true);
1947 service2_->SetSecurity(Service::kCryptoAes, false, false);
1948 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1949
1950 // For same encryption, prefer key rotation.
1951 service_->SetSecurity(Service::kCryptoRc4, false, false);
1952 service2_->SetSecurity(Service::kCryptoRc4, true, false);
1953 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1954
1955 // For same encryption, prefer authenticated AP.
1956 service_->SetSecurity(Service::kCryptoRc4, false, false);
1957 service2_->SetSecurity(Service::kCryptoRc4, false, true);
1958 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1959}
1960
Darin Petkovaba89322013-03-11 14:48:22 +01001961TEST_F(ServiceTest, SetErrorDetails) {
1962 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1963 static const char kDetails[] = "Certificate revoked.";
Paul Stewart3b30ca52015-06-16 13:13:10 -07001964 ServiceMockAdaptor* adaptor = GetAdaptor();
Ben Chan39a7beb2013-09-21 11:28:00 -07001965 EXPECT_CALL(*adaptor, EmitStringChanged(kErrorDetailsProperty, kDetails));
Darin Petkovaba89322013-03-11 14:48:22 +01001966 service_->SetErrorDetails(Service::kErrorDetailsNone);
1967 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1968 service_->SetErrorDetails(kDetails);
1969 EXPECT_EQ(kDetails, service_->error_details());
1970 service_->SetErrorDetails(kDetails);
1971}
1972
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001973TEST_F(ServiceTest, SetAutoConnectFull) {
Darin Petkov36d962d2013-03-25 13:03:14 +01001974 EXPECT_FALSE(service_->auto_connect());
1975 Error error;
1976 EXPECT_FALSE(GetAutoConnect(&error));
1977 EXPECT_TRUE(error.IsSuccess());
1978
1979 // false -> false
Paul Stewart2da34c02013-10-17 15:28:56 -07001980 EXPECT_FALSE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01001981 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001982 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001983 EXPECT_TRUE(error.IsSuccess());
1984 EXPECT_FALSE(service_->auto_connect());
Paul Stewart2da34c02013-10-17 15:28:56 -07001985 EXPECT_TRUE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07001986 EXPECT_FALSE(GetAutoConnect(nullptr));
Darin Petkov36d962d2013-03-25 13:03:14 +01001987 Mock::VerifyAndClearExpectations(&mock_manager_);
1988
Paul Stewart2da34c02013-10-17 15:28:56 -07001989 // Clear the |retain_auto_connect_| flag for the next test.
Paul Stewart96a6d092013-08-26 09:32:49 -07001990 service_->Unload();
Paul Stewart2da34c02013-10-17 15:28:56 -07001991 ASSERT_FALSE(service_->retain_auto_connect());
Paul Stewart96a6d092013-08-26 09:32:49 -07001992
Darin Petkov36d962d2013-03-25 13:03:14 +01001993 // false -> true
1994 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001995 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01001996 EXPECT_TRUE(error.IsSuccess());
1997 EXPECT_TRUE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07001998 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart36e67be2013-12-12 14:36:10 -08001999 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002000 Mock::VerifyAndClearExpectations(&mock_manager_);
2001
Paul Stewart36e67be2013-12-12 14:36:10 -08002002 // Clear the |retain_auto_connect_| flag for the next test.
2003 service_->Unload();
2004 ASSERT_FALSE(service_->retain_auto_connect());
2005
Darin Petkov36d962d2013-03-25 13:03:14 +01002006 // true -> true
Paul Stewart36e67be2013-12-12 14:36:10 -08002007 service_->SetAutoConnect(true);
Darin Petkov36d962d2013-03-25 13:03:14 +01002008 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002009 SetAutoConnectFull(true, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01002010 EXPECT_TRUE(error.IsSuccess());
2011 EXPECT_TRUE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002012 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart36e67be2013-12-12 14:36:10 -08002013 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002014 Mock::VerifyAndClearExpectations(&mock_manager_);
2015
Paul Stewart36e67be2013-12-12 14:36:10 -08002016 // Clear the |retain_auto_connect_| flag for the next test.
2017 service_->Unload();
2018 ASSERT_FALSE(service_->retain_auto_connect());
2019
Darin Petkov36d962d2013-03-25 13:03:14 +01002020 // true -> false
Paul Stewart36e67be2013-12-12 14:36:10 -08002021 service_->SetAutoConnect(true);
Darin Petkov36d962d2013-03-25 13:03:14 +01002022 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002023 SetAutoConnectFull(false, &error);
Darin Petkov36d962d2013-03-25 13:03:14 +01002024 EXPECT_TRUE(error.IsSuccess());
2025 EXPECT_FALSE(service_->auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002026 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart2da34c02013-10-17 15:28:56 -07002027 EXPECT_TRUE(service_->retain_auto_connect());
Darin Petkov36d962d2013-03-25 13:03:14 +01002028 Mock::VerifyAndClearExpectations(&mock_manager_);
2029}
2030
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002031TEST_F(ServiceTest, SetAutoConnectFullUserUpdatePersists) {
2032 // If the user sets the kAutoConnectProperty explicitly, the preference must
2033 // be persisted, even if the property was not changed.
2034 Error error;
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002035 MockProfileRefPtr mock_profile(
2036 new MockProfile(control_interface(), metrics(), &mock_manager_));
2037 NiceMock<MockStore> storage;
2038 service_->set_profile(mock_profile);
2039 service_->SetAutoConnect(true);
2040
2041 EXPECT_CALL(*mock_profile, UpdateService(_));
2042 EXPECT_CALL(*mock_profile, GetConstStorage())
2043 .WillOnce(Return(&storage));
Paul Stewartf2860342014-05-09 14:29:16 -07002044 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
Prathmesh Prabhu765d5df2014-04-22 16:43:15 -07002045 .WillOnce(Return(false));
2046 EXPECT_FALSE(service_->retain_auto_connect());
2047 SetAutoConnectFull(true, &error);
2048 EXPECT_TRUE(error.IsSuccess());
2049 EXPECT_TRUE(service_->auto_connect());
2050 EXPECT_TRUE(service_->retain_auto_connect());
2051}
2052
Paul Stewart43d8dc02013-10-17 10:32:53 -07002053TEST_F(ServiceTest, ClearAutoConnect) {
2054 EXPECT_FALSE(service_->auto_connect());
2055 Error error;
2056 EXPECT_FALSE(GetAutoConnect(&error));
2057 EXPECT_TRUE(error.IsSuccess());
2058
2059 // unset -> false
Paul Stewart2da34c02013-10-17 15:28:56 -07002060 EXPECT_FALSE(service_->retain_auto_connect());
Paul Stewart43d8dc02013-10-17 10:32:53 -07002061 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2062 ClearAutoConnect(&error);
2063 EXPECT_TRUE(error.IsSuccess());
Paul Stewart2da34c02013-10-17 15:28:56 -07002064 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002065 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002066 Mock::VerifyAndClearExpectations(&mock_manager_);
2067
2068 // false -> false
2069 SetAutoConnectFull(false, &error);
Ben Chancc225ef2014-09-30 13:26:51 -07002070 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart2da34c02013-10-17 15:28:56 -07002071 EXPECT_TRUE(service_->retain_auto_connect());
2072 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
Paul Stewart43d8dc02013-10-17 10:32:53 -07002073 ClearAutoConnect(&error);
2074 EXPECT_TRUE(error.IsSuccess());
Paul Stewart2da34c02013-10-17 15:28:56 -07002075 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002076 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002077 Mock::VerifyAndClearExpectations(&mock_manager_);
2078
2079 // true -> false
2080 SetAutoConnectFull(true, &error);
2081 EXPECT_TRUE(error.IsSuccess());
Ben Chancc225ef2014-09-30 13:26:51 -07002082 EXPECT_TRUE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002083 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
2084 ClearAutoConnect(&error);
Paul Stewart2da34c02013-10-17 15:28:56 -07002085 EXPECT_FALSE(service_->retain_auto_connect());
Ben Chancc225ef2014-09-30 13:26:51 -07002086 EXPECT_FALSE(GetAutoConnect(nullptr));
Paul Stewart43d8dc02013-10-17 10:32:53 -07002087 Mock::VerifyAndClearExpectations(&mock_manager_);
2088}
2089
mukesh agrawale37ad322013-10-08 16:33:56 -07002090TEST_F(ServiceTest, UniqueAttributes) {
2091 EXPECT_NE(service_->serial_number_, service2_->serial_number_);
2092 EXPECT_NE(service_->unique_name(), service2_->unique_name());
2093}
2094
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07002095TEST_F(ServiceTest, PropertyChanges) {
2096 TestCommonPropertyChanges(service_, GetAdaptor());
2097 TestAutoConnectPropertyChange(service_, GetAdaptor());
2098}
2099
mukesh agrawalbebf1b82013-04-23 15:06:33 -07002100// Custom property setters should return false, and make no changes, if
2101// the new value is the same as the old value.
2102TEST_F(ServiceTest, CustomSetterNoopChange) {
2103 TestCustomSetterNoopChange(service_, &mock_manager_);
2104}
2105
Paul Stewartfa11e282013-12-02 22:04:25 -08002106TEST_F(ServiceTest, GetTethering) {
2107 Error error;
2108 EXPECT_EQ("", service_->GetTethering(&error));
2109 EXPECT_EQ(Error::kNotSupported, error.type());
2110}
2111
Paul Stewart836a9372014-04-23 19:57:15 -07002112class ServiceWithMockOnPropertyChanged : public ServiceUnderTest {
2113 public:
Paul Stewart3b30ca52015-06-16 13:13:10 -07002114 ServiceWithMockOnPropertyChanged(ControlInterface* control_interface,
2115 EventDispatcher* dispatcher,
2116 Metrics* metrics,
2117 Manager* manager)
Paul Stewart836a9372014-04-23 19:57:15 -07002118 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {}
Paul Stewart3b30ca52015-06-16 13:13:10 -07002119 MOCK_METHOD1(OnPropertyChanged, void(const string& property));
Paul Stewart836a9372014-04-23 19:57:15 -07002120};
2121
2122TEST_F(ServiceTest, ConfigureServiceTriggersOnPropertyChanged) {
2123 auto service(make_scoped_refptr(
2124 new ServiceWithMockOnPropertyChanged(control_interface(),
2125 dispatcher(),
2126 metrics(),
2127 &mock_manager_)));
2128 KeyValueStore args;
2129 args.SetString(kUIDataProperty, "terpsichorean ejectamenta");
2130 args.SetBool(kSaveCredentialsProperty, false);
2131
2132 // Calling Configure with different values from before triggers a single
2133 // OnPropertyChanged call per property.
2134 EXPECT_CALL(*service, OnPropertyChanged(kUIDataProperty)).Times(1);
2135 EXPECT_CALL(*service, OnPropertyChanged(kSaveCredentialsProperty)).Times(1);
2136 {
2137 Error error;
2138 service->Configure(args, &error);
2139 EXPECT_TRUE(error.IsSuccess());
2140 }
Alex Vakulenko0951ccb2014-12-10 12:52:31 -08002141 Mock::VerifyAndClearExpectations(service.get());
Paul Stewart836a9372014-04-23 19:57:15 -07002142
2143 // Calling Configure with the same values as before should not trigger
2144 // OnPropertyChanged().
2145 EXPECT_CALL(*service, OnPropertyChanged(_)).Times(0);
2146 {
2147 Error error;
2148 service->Configure(args, &error);
2149 EXPECT_TRUE(error.IsSuccess());
2150 }
2151}
2152
Paul Stewart2eee6132014-05-09 13:33:26 -07002153TEST_F(ServiceTest, ClearExplicitlyDisconnected) {
2154 EXPECT_FALSE(GetExplicitlyDisconnected());
2155 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2156 service_->ClearExplicitlyDisconnected();
2157 Mock::VerifyAndClearExpectations(&mock_manager_);
2158
2159 SetExplicitlyDisconnected(true);
2160 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
2161 service_->ClearExplicitlyDisconnected();
2162 Mock::VerifyAndClearExpectations(&mock_manager_);
2163 EXPECT_FALSE(GetExplicitlyDisconnected());
2164}
2165
Paul Stewart22ce7652014-10-15 21:26:44 -07002166TEST_F(ServiceTest, Compare) {
2167 // Construct our Services so that the string comparison of
2168 // unique_name_ differs from the numerical comparison of
2169 // serial_number_.
2170 vector<scoped_refptr<MockService>> mock_services;
2171 for (size_t i = 0; i < 11; ++i) {
2172 mock_services.push_back(
2173 new NiceMock<MockService>(control_interface(),
2174 dispatcher(),
2175 metrics(),
2176 manager()));
2177 }
2178 scoped_refptr<MockService> service2 = mock_services[2];
2179 scoped_refptr<MockService> service10 = mock_services[10];
2180 mock_services.clear();
2181
2182 // Services should already be sorted by |serial_number_|.
2183 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2184
2185 // Two otherwise equal services should be reordered by strength
2186 service10->SetStrength(1);
2187 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2188
2189 scoped_refptr<MockProfile> profile2(
2190 new MockProfile(control_interface(), metrics(), manager(), ""));
2191 scoped_refptr<MockProfile> profile10(
2192 new MockProfile(control_interface(), metrics(), manager(), ""));
2193
2194 service2->set_profile(profile2);
2195 service10->set_profile(profile10);
2196
2197 // When comparing two services with different profiles, prefer the one
2198 // that is not ephemeral.
2199 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service2)))
2200 .WillRepeatedly(Return(false));
2201 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service10)))
2202 .WillRepeatedly(Return(true));
2203 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2204 Mock::VerifyAndClearExpectations(&mock_manager_);
2205
2206 // Prefer the service with the more recently applied profile if neither
2207 // service is ephemeral.
2208 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_))
2209 .WillRepeatedly(Return(false));
2210 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile2),
2211 IsRefPtrTo(profile10)))
2212 .WillRepeatedly(Return(true));
2213 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile10),
2214 IsRefPtrTo(profile2)))
2215 .WillRepeatedly(Return(false));
2216 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2217
Paul Stewartd9c7cfc2015-01-06 14:26:22 -08002218 // Security.
Paul Stewart22ce7652014-10-15 21:26:44 -07002219 service2->SetSecurity(Service::kCryptoAes, true, true);
2220 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2221
Paul Stewartd9c7cfc2015-01-06 14:26:22 -08002222 // PriorityWithinTechnology.
2223 service10->SetPriorityWithinTechnology(1, nullptr);
2224 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2225 service2->SetPriorityWithinTechnology(2, nullptr);
2226 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2227
2228 // Technology.
Paul Stewart22ce7652014-10-15 21:26:44 -07002229 EXPECT_CALL(*service2.get(), technology())
2230 .WillRepeatedly(Return((Technology::kWifi)));
2231 EXPECT_CALL(*service10.get(), technology())
2232 .WillRepeatedly(Return(Technology::kEthernet));
2233
2234 technology_order_for_sorting_ = {Technology::kEthernet, Technology::kWifi};
2235 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2236
2237 technology_order_for_sorting_ = {Technology::kWifi, Technology::kEthernet};
2238 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2239
2240 // Priority.
2241 service2->SetPriority(1, nullptr);
2242 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
Paul Stewart3fee7e32014-10-15 21:39:29 -07002243 service10->SetPriority(2, nullptr);
2244 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
Paul Stewart22ce7652014-10-15 21:26:44 -07002245
Paul Stewart3fee7e32014-10-15 21:39:29 -07002246 // A service that has been connected before should be considered
2247 // above a service that neither been connected to before nor has
2248 // has managed credentials.
2249 service2->has_ever_connected_ = true;
2250 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2251
2252 // If one service has been connected to before, and the other is managed
2253 // by Chrome they should rank same, so the priority will be considered
2254 // instead.
2255 service10->managed_credentials_ = true;
2256 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2257 service2->SetPriority(3, nullptr);
2258 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2259
2260 // A service with managed credentials should be considered above one that
2261 // has neither been connected to before nor has managed credentials.
2262 service2->has_ever_connected_ = false;
Paul Stewart22ce7652014-10-15 21:26:44 -07002263 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2264
2265 // Auto-connect.
2266 service2->SetAutoConnect(true);
2267 service10->SetAutoConnect(false);
2268 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2269
2270 // Test is-dependent-on.
2271 EXPECT_CALL(*service10.get(),
2272 IsDependentOn(IsRefPtrTo(service2.get())))
2273 .WillOnce(Return(true))
2274 .WillOnce(Return(false));
2275 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2276 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2277
2278 // It doesn't make sense to have is-dependent-on ranking comparison in any of
2279 // the remaining subtests below. Reset to the default.
2280 EXPECT_CALL(*service10.get(), IsDependentOn(_)).WillRepeatedly(Return(false));
2281 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2282
2283 // Connectable.
2284 service10->SetConnectable(true);
2285 service2->SetConnectable(false);
2286 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2287
2288 // IsFailed.
2289 EXPECT_CALL(*service2.get(), state())
2290 .WillRepeatedly(Return(Service::kStateIdle));
2291 EXPECT_CALL(*service2.get(), IsFailed())
2292 .WillRepeatedly(Return(false));
2293 EXPECT_CALL(*service10.get(), state())
2294 .WillRepeatedly(Return(Service::kStateFailure));
2295 EXPECT_CALL(*service10.get(), IsFailed())
2296 .WillRepeatedly(Return(true));
2297 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2298
2299 // Connecting.
2300 EXPECT_CALL(*service10.get(), state())
2301 .WillRepeatedly(Return(Service::kStateAssociating));
2302 EXPECT_CALL(*service10.get(), IsConnecting())
2303 .WillRepeatedly(Return(true));
2304 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2305
2306 // Connected-but-portalled preferred over unconnected.
2307 EXPECT_CALL(*service2.get(), state())
2308 .WillRepeatedly(Return(Service::kStatePortal));
2309 EXPECT_CALL(*service2.get(), IsConnected())
2310 .WillRepeatedly(Return(true));
2311 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2312
2313 // Connected preferred over connected-but-portalled.
2314 service10->SetConnectable(false);
2315 service2->SetConnectable(true);
2316 EXPECT_CALL(*service10.get(), state())
2317 .WillRepeatedly(Return(Service::kStateConnected));
2318 EXPECT_CALL(*service10.get(), IsConnected())
2319 .WillRepeatedly(Return(true));
2320 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2321
Paul Stewart778c9862015-07-30 10:17:42 -07002322 // Online preferred over just connected.
2323 EXPECT_CALL(*service2.get(), state())
2324 .WillRepeatedly(Return(Service::kStateOnline));
2325 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2326
Paul Stewart22ce7652014-10-15 21:26:44 -07002327 // Connectivity state ignored if this is specified.
2328 const bool kDoNotCompareConnectivityState = false;
2329 EXPECT_TRUE(SortingOrderIs(service2, service10,
2330 kDoNotCompareConnectivityState));
2331}
2332
Chris Masone3bd3c8c2011-06-13 08:20:26 -07002333} // namespace shill