1 //
2 // Copyright (C) 2013 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16
17 #include "shill/service.h"
18
19 #include <algorithm>
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24
25 #include <base/bind.h>
26 #if defined(__ANDROID__)
27 #include <dbus/service_constants.h>
28 #else
29 #include <chromeos/dbus/service_constants.h>
30 #endif // __ANDROID__
31 #include <gtest/gtest.h>
32 #include <gmock/gmock.h>
33
34 #include "shill/ethernet/ethernet_service.h"
35 #include "shill/event_dispatcher.h"
36 #include "shill/manager.h"
37 #include "shill/mock_adaptors.h"
38 #include "shill/mock_connection.h"
39 #include "shill/mock_control.h"
40 #include "shill/mock_device_info.h"
41 #include "shill/mock_dhcp_properties.h"
42 #include "shill/mock_event_dispatcher.h"
43 #include "shill/mock_log.h"
44 #include "shill/mock_manager.h"
45 #include "shill/mock_power_manager.h"
46 #include "shill/mock_profile.h"
47 #include "shill/mock_service.h"
48 #include "shill/mock_store.h"
49 #include "shill/net/mock_time.h"
50 #include "shill/property_store_unittest.h"
51 #include "shill/service_property_change_test.h"
52 #include "shill/service_sorter.h"
53 #include "shill/service_under_test.h"
54 #include "shill/testing.h"
55
56 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
57 #include "shill/mock_eap_credentials.h"
58 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
59
60 using base::Bind;
61 using base::Unretained;
62 using std::deque;
63 using std::map;
64 using std::string;
65 using std::vector;
66 using testing::_;
67 using testing::AnyNumber;
68 using testing::AtLeast;
69 using testing::DefaultValue;
70 using testing::DoAll;
71 using testing::HasSubstr;
72 using testing::Mock;
73 using testing::NiceMock;
74 using testing::Return;
75 using testing::ReturnNull;
76 using testing::ReturnRef;
77 using testing::StrictMock;
78 using testing::SetArgumentPointee;
79 using testing::Test;
80 using testing::Values;
81
82 namespace shill {
83
84 class ServiceTest : public PropertyStoreTest {
85 public:
ServiceTest()86 ServiceTest()
87 : mock_manager_(control_interface(), dispatcher(), metrics()),
88 service_(new ServiceUnderTest(control_interface(),
89 dispatcher(),
90 metrics(),
91 &mock_manager_)),
92 service2_(new ServiceUnderTest(control_interface(),
93 dispatcher(),
94 metrics(),
95 &mock_manager_)),
96 storage_id_(ServiceUnderTest::kStorageId),
97 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
98 eap_(new MockEapCredentials()),
99 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
100 power_manager_(new MockPowerManager(nullptr, &control_)) {
101 ON_CALL(control_, CreatePowerManagerProxy(_, _, _))
102 .WillByDefault(ReturnNull());
103
104 service_->time_ = &time_;
105 service_->disconnects_.time_ = &time_;
106 service_->misconnects_.time_ = &time_;
107 DefaultValue<Timestamp>::Set(Timestamp());
108 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
109 service_->eap_.reset(eap_); // Passes ownership.
110 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
111 mock_manager_.running_ = true;
112 mock_manager_.set_power_manager(power_manager_); // Passes ownership.
113 }
114
~ServiceTest()115 virtual ~ServiceTest() {}
116
117 MOCK_METHOD1(TestCallback, void(const Error& error));
118
119 protected:
120 typedef scoped_refptr<MockProfile> MockProfileRefPtr;
121
GetAdaptor()122 ServiceMockAdaptor* GetAdaptor() {
123 return static_cast<ServiceMockAdaptor*>(service_->adaptor());
124 }
125
GetFriendlyName()126 string GetFriendlyName() { return service_->friendly_name(); }
127
SetManagerRunning(bool running)128 void SetManagerRunning(bool running) { mock_manager_.running_ = running; }
129
SetSuspending(bool suspending)130 void SetSuspending(bool suspending) {
131 power_manager_->suspending_ = suspending;
132 }
133
GetExplicitlyDisconnected() const134 bool GetExplicitlyDisconnected() const {
135 return service_->explicitly_disconnected_;
136 }
137
SetExplicitlyDisconnected(bool explicitly)138 void SetExplicitlyDisconnected(bool explicitly) {
139 service_->explicitly_disconnected_ = explicitly;
140 }
141
SetStateField(Service::ConnectState state)142 void SetStateField(Service::ConnectState state) { service_->state_ = state; }
143
GetPreviousState() const144 Service::ConnectState GetPreviousState() const {
145 return service_->previous_state_;
146 }
147
NoteDisconnectEvent()148 void NoteDisconnectEvent() {
149 service_->NoteDisconnectEvent();
150 }
151
GetDisconnects()152 EventHistory* GetDisconnects() {
153 return &service_->disconnects_;
154 }
GetMisconnects()155 EventHistory* GetMisconnects() {
156 return &service_->misconnects_;
157 }
158
GetTimestamp(int monotonic_seconds,int boottime_seconds,const string & wall_clock)159 Timestamp GetTimestamp(int monotonic_seconds, int boottime_seconds,
160 const string& wall_clock) {
161 struct timeval monotonic = { .tv_sec = monotonic_seconds, .tv_usec = 0 };
162 struct timeval boottime = { .tv_sec = boottime_seconds, .tv_usec = 0 };
163 return Timestamp(monotonic, boottime, wall_clock);
164 }
165
PushTimestamp(EventHistory * events,int monotonic_seconds,int boottime_seconds,const string & wall_clock)166 void PushTimestamp(EventHistory* events,
167 int monotonic_seconds,
168 int boottime_seconds,
169 const string& wall_clock) {
170 events->RecordEventInternal(
171 GetTimestamp(monotonic_seconds, boottime_seconds, wall_clock));
172 }
173
GetDisconnectsMonitorSeconds()174 int GetDisconnectsMonitorSeconds() {
175 return Service::kDisconnectsMonitorSeconds;
176 }
177
GetMisconnectsMonitorSeconds()178 int GetMisconnectsMonitorSeconds() {
179 return Service::kMisconnectsMonitorSeconds;
180 }
181
GetMaxDisconnectEventHistory()182 int GetMaxDisconnectEventHistory() {
183 return Service::kMaxDisconnectEventHistory;
184 }
185
GetMaxMisconnectEventHistory()186 int GetMaxMisconnectEventHistory() {
187 return Service::kMaxMisconnectEventHistory;
188 }
189
GetAutoConnect(Error * error)190 bool GetAutoConnect(Error* error) {
191 return service_->GetAutoConnect(error);
192 }
193
ClearAutoConnect(Error * error)194 void ClearAutoConnect(Error* error) {
195 service_->ClearAutoConnect(error);
196 }
197
SetAutoConnectFull(bool connect,Error * error)198 bool SetAutoConnectFull(bool connect, Error* error) {
199 return service_->SetAutoConnectFull(connect, error);
200 }
201
SortingOrderIs(const ServiceRefPtr & service0,const ServiceRefPtr & service1,bool should_compare_connectivity_state)202 bool SortingOrderIs(const ServiceRefPtr& service0,
203 const ServiceRefPtr& service1,
204 bool should_compare_connectivity_state) {
205 vector<ServiceRefPtr> services;
206 services.push_back(service1);
207 services.push_back(service0);
208 std::sort(services.begin(), services.end(),
209 ServiceSorter(&mock_manager_, should_compare_connectivity_state,
210 technology_order_for_sorting_));
211 return (service0.get() == services[0].get() &&
212 service1.get() == services[1].get());
213 }
214
DefaultSortingOrderIs(const ServiceRefPtr & service0,const ServiceRefPtr & service1)215 bool DefaultSortingOrderIs(const ServiceRefPtr& service0,
216 const ServiceRefPtr& service1) {
217 const bool kShouldCompareConnectivityState = true;
218 return SortingOrderIs(
219 service0, service1, kShouldCompareConnectivityState);
220 }
221
222 MockManager mock_manager_;
223 MockTime time_;
224 scoped_refptr<ServiceUnderTest> service_;
225 scoped_refptr<ServiceUnderTest> service2_;
226 string storage_id_;
227 NiceMock<MockControl> control_;
228 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
229 MockEapCredentials* eap_; // Owned by |service_|.
230 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
231 MockPowerManager* power_manager_; // Owned by |mock_manager_|.
232 vector<Technology::Identifier> technology_order_for_sorting_;
233 };
234
235 class AllMockServiceTest : public testing::Test {
236 public:
AllMockServiceTest()237 AllMockServiceTest()
238 : metrics_(&dispatcher_),
239 manager_(&control_interface_, &dispatcher_, &metrics_),
240 service_(new ServiceUnderTest(&control_interface_,
241 &dispatcher_,
242 &metrics_,
243 &manager_)) { }
~AllMockServiceTest()244 virtual ~AllMockServiceTest() {}
245
246 protected:
247 MockControl control_interface_;
248 StrictMock<MockEventDispatcher> dispatcher_;
249 NiceMock<MockMetrics> metrics_;
250 MockManager manager_;
251 scoped_refptr<ServiceUnderTest> service_;
252 };
253
TEST_F(ServiceTest,Constructor)254 TEST_F(ServiceTest, Constructor) {
255 EXPECT_TRUE(service_->save_credentials_);
256 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
257 EXPECT_EQ(Service::kStateIdle, service_->state());
258 EXPECT_FALSE(service_->has_ever_connected());
259 EXPECT_EQ(0, service_->previous_error_serial_number_);
260 EXPECT_EQ("", service_->previous_error_);
261 }
262
TEST_F(ServiceTest,CalculateState)263 TEST_F(ServiceTest, CalculateState) {
264 service_->state_ = Service::kStateConnected;
265 Error error;
266 EXPECT_EQ(kStateReady, service_->CalculateState(&error));
267 EXPECT_TRUE(error.IsSuccess());
268 }
269
TEST_F(ServiceTest,CalculateTechnology)270 TEST_F(ServiceTest, CalculateTechnology) {
271 service_->technology_ = Technology::kWifi;
272 Error error;
273 EXPECT_EQ(kTypeWifi, service_->CalculateTechnology(&error));
274 EXPECT_TRUE(error.IsSuccess());
275 }
276
TEST_F(ServiceTest,GetProperties)277 TEST_F(ServiceTest, GetProperties) {
278 {
279 brillo::VariantDictionary props;
280 Error error;
281 string expected("true");
282 service_->mutable_store()->SetStringProperty(kCheckPortalProperty,
283 expected,
284 &error);
285 EXPECT_TRUE(service_->store().GetProperties(&props, &error));
286 ASSERT_FALSE(props.find(kCheckPortalProperty) == props.end());
287 EXPECT_TRUE(props[kCheckPortalProperty].IsTypeCompatible<string>());
288 EXPECT_EQ(props[kCheckPortalProperty].Get<string>(), expected);
289 }
290 {
291 brillo::VariantDictionary props;
292 Error error;
293 bool expected = true;
294 service_->mutable_store()->SetBoolProperty(kAutoConnectProperty,
295 expected,
296 &error);
297 EXPECT_TRUE(service_->store().GetProperties(&props, &error));
298 ASSERT_FALSE(props.find(kAutoConnectProperty) == props.end());
299 EXPECT_TRUE(props[kAutoConnectProperty].IsTypeCompatible<bool>());
300 EXPECT_EQ(props[kAutoConnectProperty].Get<bool>(), expected);
301 }
302 {
303 brillo::VariantDictionary props;
304 Error error;
305 EXPECT_TRUE(service_->store().GetProperties(&props, &error));
306 ASSERT_FALSE(props.find(kConnectableProperty) == props.end());
307 EXPECT_TRUE(props[kConnectableProperty].IsTypeCompatible<bool>());
308 EXPECT_EQ(props[kConnectableProperty].Get<bool>(), false);
309 }
310 {
311 brillo::VariantDictionary props;
312 Error error;
313 int32_t expected = 127;
314 service_->mutable_store()->SetInt32Property(kPriorityProperty,
315 expected,
316 &error);
317 EXPECT_TRUE(service_->store().GetProperties(&props, &error));
318 ASSERT_FALSE(props.find(kPriorityProperty) == props.end());
319 EXPECT_TRUE(props[kPriorityProperty].IsTypeCompatible<int32_t>());
320 EXPECT_EQ(props[kPriorityProperty].Get<int32_t>(), expected);
321 }
322 {
323 brillo::VariantDictionary props;
324 Error error;
325 service_->store().GetProperties(&props, &error);
326 ASSERT_FALSE(props.find(kDeviceProperty) == props.end());
327 EXPECT_TRUE(props[kDeviceProperty].IsTypeCompatible<dbus::ObjectPath>());
328 EXPECT_EQ(props[kDeviceProperty].Get<dbus::ObjectPath>().value(),
329 string(ServiceUnderTest::kRpcId));
330 }
331 }
332
TEST_F(ServiceTest,SetProperty)333 TEST_F(ServiceTest, SetProperty) {
334 {
335 Error error;
336 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
337 kSaveCredentialsProperty, PropertyStoreTest::kBoolV, &error));
338 }
339 {
340 Error error;
341 const int32_t priority = 1;
342 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
343 kPriorityProperty, brillo::Any(priority), &error));
344 }
345 {
346 Error error;
347 const string guid("not default");
348 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
349 kGuidProperty, brillo::Any(guid), &error));
350 }
351 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
352 // 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 Error error;
357 string eap("eap eep eip!");
358 EXPECT_FALSE(service2_->mutable_store()->SetAnyProperty(
359 kEapMethodProperty, brillo::Any(eap), &error));
360 ASSERT_TRUE(error.IsFailure());
361 EXPECT_EQ(Error::kInvalidProperty, error.type());
362 // Now plumb in eap credentials, and try again.
363 service2_->SetEapCredentials(new EapCredentials());
364 EXPECT_TRUE(service2_->mutable_store()->SetAnyProperty(
365 kEapMethodProperty, brillo::Any(eap), &error));
366 }
367 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
368 // Ensure that an attempt to write a R/O property returns InvalidArgs error.
369 {
370 Error error;
371 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
372 kConnectableProperty, PropertyStoreTest::kBoolV, &error));
373 ASSERT_TRUE(error.IsFailure());
374 EXPECT_EQ(Error::kInvalidArguments, error.type());
375 }
376 {
377 bool auto_connect = true;
378 Error error;
379 EXPECT_TRUE(service_->mutable_store()->SetAnyProperty(
380 kAutoConnectProperty, brillo::Any(auto_connect), &error));
381 }
382 // Ensure that we can perform a trivial set of the Name property (to its
383 // current value) but an attempt to set the property to a different value
384 // fails.
385 {
386 Error error;
387 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
388 kNameProperty, brillo::Any(GetFriendlyName()), &error));
389 EXPECT_FALSE(error.IsFailure());
390 }
391 {
392 Error error;
393 EXPECT_FALSE(service_->mutable_store()->SetAnyProperty(
394 kNameProperty, PropertyStoreTest::kStringV, &error));
395 ASSERT_TRUE(error.IsFailure());
396 EXPECT_EQ(Error::kInvalidArguments, error.type());
397 }
398 }
399
TEST_F(ServiceTest,GetLoadableStorageIdentifier)400 TEST_F(ServiceTest, GetLoadableStorageIdentifier) {
401 NiceMock<MockStore> storage;
402 EXPECT_CALL(storage, ContainsGroup(storage_id_))
403 .WillOnce(Return(false))
404 .WillOnce(Return(true));
405 EXPECT_EQ("", service_->GetLoadableStorageIdentifier(storage));
406 EXPECT_EQ(storage_id_, service_->GetLoadableStorageIdentifier(storage));
407 }
408
TEST_F(ServiceTest,IsLoadableFrom)409 TEST_F(ServiceTest, IsLoadableFrom) {
410 NiceMock<MockStore> storage;
411 EXPECT_CALL(storage, ContainsGroup(storage_id_))
412 .WillOnce(Return(false))
413 .WillOnce(Return(true));
414 EXPECT_FALSE(service_->IsLoadableFrom(storage));
415 EXPECT_TRUE(service_->IsLoadableFrom(storage));
416 }
417
418 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
419 class ServiceWithOnEapCredentialsChangedOverride : public ServiceUnderTest {
420 public:
ServiceWithOnEapCredentialsChangedOverride(ControlInterface * control_interface,EventDispatcher * dispatcher,Metrics * metrics,Manager * manager,EapCredentials * eap)421 ServiceWithOnEapCredentialsChangedOverride(
422 ControlInterface* control_interface,
423 EventDispatcher* dispatcher,
424 Metrics* metrics,
425 Manager* manager,
426 EapCredentials* eap)
427 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {
428 SetEapCredentials(eap);
429 }
OnEapCredentialsChanged(Service::UpdateCredentialsReason)430 void OnEapCredentialsChanged(Service::UpdateCredentialsReason) override {
431 SetHasEverConnected(false);
432 }
433 };
434 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
435
TEST_F(ServiceTest,Load)436 TEST_F(ServiceTest, Load) {
437 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
438 MockEapCredentials* eap = new MockEapCredentials(); // Owned by |service|.
439 scoped_refptr<ServiceWithOnEapCredentialsChangedOverride> service(
440 new ServiceWithOnEapCredentialsChangedOverride(control_interface(),
441 dispatcher(),
442 metrics(),
443 &mock_manager_,
444 eap));
445 #else
446 scoped_refptr<ServiceUnderTest> service(
447 new ServiceUnderTest(control_interface(),
448 dispatcher(),
449 metrics(),
450 &mock_manager_));
451 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
452
453 NiceMock<MockStore> storage;
454 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
455 const string kCheckPortal("check-portal");
456 const string kGUID("guid");
457 const bool kHasEverConnected = true;
458 const int kPriority = 20;
459 const string kProxyConfig("proxy-config");
460 const string kUIData("ui-data");
461 EXPECT_CALL(storage, GetString(storage_id_, _, _)).Times(AnyNumber());
462 EXPECT_CALL(storage, GetInt(storage_id_, _, _)).Times(AnyNumber());
463 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageCheckPortal, _))
464 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kCheckPortal), Return(true)));
465 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageGUID, _))
466 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kGUID), Return(true)));
467 EXPECT_CALL(storage, GetInt(storage_id_, Service::kStoragePriority, _))
468 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPriority), Return(true)));
469 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageProxyConfig, _))
470 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kProxyConfig), Return(true)));
471 EXPECT_CALL(storage, GetString(storage_id_, Service::kStorageUIData, _))
472 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kUIData), Return(true)));
473 EXPECT_CALL(storage, GetBool(storage_id_, _, _)).Times(AnyNumber());
474 EXPECT_CALL(storage,
475 GetBool(storage_id_, Service::kStorageSaveCredentials, _));
476 EXPECT_CALL(storage,
477 GetBool(storage_id_, Service::kStorageHasEverConnected, _))
478 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
479 Return(true)));
480 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
481 EXPECT_CALL(*eap, Load(&storage, storage_id_));
482 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
483 MockDhcpProperties* dhcp_props = new MockDhcpProperties();
484 service->dhcp_properties_.reset(dhcp_props);
485 EXPECT_CALL(*dhcp_props, Load(&storage, storage_id_));
486
487 EXPECT_TRUE(service->Load(&storage));
488 EXPECT_EQ(kCheckPortal, service->check_portal_);
489 EXPECT_EQ(kGUID, service->guid_);
490 EXPECT_TRUE(service->has_ever_connected_);
491 EXPECT_EQ(kProxyConfig, service->proxy_config_);
492 EXPECT_EQ(kUIData, service->ui_data_);
493
494 Mock::VerifyAndClearExpectations(&storage);
495 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
496 Mock::VerifyAndClearExpectations(eap_);
497 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
498 Mock::VerifyAndClearExpectations(dhcp_props);
499
500 // Assure that parameters are set to default if not available in the profile.
501 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
502 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
503 .WillRepeatedly(Return(false));
504 EXPECT_CALL(storage, GetString(storage_id_, _, _))
505 .WillRepeatedly(Return(false));
506 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
507 .WillRepeatedly(Return(false));
508 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
509 EXPECT_CALL(*eap, Load(&storage, storage_id_));
510 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
511 EXPECT_CALL(*dhcp_props, Load(&storage, storage_id_));
512
513 EXPECT_TRUE(service->Load(&storage));
514 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
515 EXPECT_EQ("", service->guid_);
516 EXPECT_EQ("", service->proxy_config_);
517 EXPECT_EQ("", service->ui_data_);
518
519 // has_ever_connected_ flag will reset when EAP credential changes.
520 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
521 EXPECT_FALSE(service->has_ever_connected_);
522 #else
523 EXPECT_TRUE(service->has_ever_connected_);
524 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
525 }
526
TEST_F(ServiceTest,LoadFail)527 TEST_F(ServiceTest, LoadFail) {
528 StrictMock<MockStore> storage;
529 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(false));
530 EXPECT_FALSE(service_->Load(&storage));
531 }
532
TEST_F(ServiceTest,LoadAutoConnect)533 TEST_F(ServiceTest, LoadAutoConnect) {
534 NiceMock<MockStore> storage;
535 EXPECT_CALL(storage, ContainsGroup(storage_id_))
536 .WillRepeatedly(Return(true));
537 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
538 .WillRepeatedly(Return(false));
539 EXPECT_CALL(storage, GetString(storage_id_, _, _))
540 .WillRepeatedly(Return(false));
541 EXPECT_CALL(storage, GetInt(storage_id_, _, _))
542 .WillRepeatedly(Return(false));
543 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
544 EXPECT_CALL(*eap_, Load(&storage, storage_id_)).Times(AnyNumber());
545 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
546
547 std::unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties());
548 EXPECT_CALL(*dhcp_props.get(), Load(&storage, storage_id_)).Times(AnyNumber());
549 service_->dhcp_properties_ = std::move(dhcp_props);
550
551 // Three of each expectation so we can test Favorite == unset, false, true.
552 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageAutoConnect, _))
553 .WillOnce(Return(false))
554 .WillOnce(Return(false))
555 .WillOnce(Return(false))
556 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
557 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
558 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
559 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
560 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
561 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
562 EXPECT_CALL(storage, GetBool(storage_id_, Service::kStorageFavorite, _))
563 .WillOnce(Return(false))
564 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
565 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
566 .WillOnce(Return(false))
567 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
568 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)))
569 .WillOnce(Return(false))
570 .WillOnce(DoAll(SetArgumentPointee<2>(false), Return(true)))
571 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
572
573 // AutoConnect is unset, Favorite is unset.
574 EXPECT_TRUE(service_->Load(&storage));
575 EXPECT_FALSE(service_->auto_connect());
576 EXPECT_FALSE(service_->retain_auto_connect());
577
578 // AutoConnect is unset, Favorite is false.
579 EXPECT_TRUE(service_->Load(&storage));
580 EXPECT_FALSE(service_->auto_connect());
581 EXPECT_FALSE(service_->retain_auto_connect());
582
583 // AutoConnect is unset, Favorite is true.
584 EXPECT_TRUE(service_->Load(&storage));
585 EXPECT_FALSE(service_->auto_connect());
586 EXPECT_TRUE(service_->retain_auto_connect());
587
588 // AutoConnect is false, Favorite is unset.
589 EXPECT_TRUE(service_->Load(&storage));
590 EXPECT_FALSE(service_->auto_connect());
591 EXPECT_TRUE(service_->retain_auto_connect());
592
593 // AutoConnect is false, Favorite is false.
594 EXPECT_TRUE(service_->Load(&storage));
595 EXPECT_FALSE(service_->auto_connect());
596 EXPECT_FALSE(service_->retain_auto_connect());
597
598 // AutoConnect is false, Favorite is true.
599 EXPECT_TRUE(service_->Load(&storage));
600 EXPECT_FALSE(service_->auto_connect());
601 EXPECT_TRUE(service_->retain_auto_connect());
602
603 // AutoConnect is true, Favorite is unset.
604 EXPECT_TRUE(service_->Load(&storage));
605 EXPECT_TRUE(service_->auto_connect());
606 EXPECT_TRUE(service_->retain_auto_connect());
607
608 // AutoConnect is true, Favorite is false (invalid case).
609 EXPECT_TRUE(service_->Load(&storage));
610 EXPECT_TRUE(service_->auto_connect());
611 EXPECT_FALSE(service_->retain_auto_connect());
612
613 // AutoConnect is true, Favorite is true.
614 EXPECT_TRUE(service_->Load(&storage));
615 EXPECT_TRUE(service_->auto_connect());
616 EXPECT_TRUE(service_->retain_auto_connect());
617 }
618
TEST_F(ServiceTest,SaveString)619 TEST_F(ServiceTest, SaveString) {
620 MockStore storage;
621 static const char kKey[] = "test-key";
622 static const char kData[] = "test-data";
623 EXPECT_CALL(storage, SetString(storage_id_, kKey, kData))
624 .WillOnce(Return(true));
625 service_->SaveString(&storage, storage_id_, kKey, kData, false, true);
626 }
627
TEST_F(ServiceTest,SaveStringCrypted)628 TEST_F(ServiceTest, SaveStringCrypted) {
629 MockStore storage;
630 static const char kKey[] = "test-key";
631 static const char kData[] = "test-data";
632 EXPECT_CALL(storage, SetCryptedString(storage_id_, kKey, kData))
633 .WillOnce(Return(true));
634 service_->SaveString(&storage, storage_id_, kKey, kData, true, true);
635 }
636
TEST_F(ServiceTest,SaveStringDontSave)637 TEST_F(ServiceTest, SaveStringDontSave) {
638 MockStore storage;
639 static const char kKey[] = "test-key";
640 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
641 .WillOnce(Return(true));
642 service_->SaveString(&storage, storage_id_, kKey, "data", false, false);
643 }
644
TEST_F(ServiceTest,SaveStringEmpty)645 TEST_F(ServiceTest, SaveStringEmpty) {
646 MockStore storage;
647 static const char kKey[] = "test-key";
648 EXPECT_CALL(storage, DeleteKey(storage_id_, kKey))
649 .WillOnce(Return(true));
650 service_->SaveString(&storage, storage_id_, kKey, "", true, true);
651 }
652
TEST_F(ServiceTest,Save)653 TEST_F(ServiceTest, Save) {
654 NiceMock<MockStore> storage;
655 EXPECT_CALL(storage, SetString(storage_id_, _, _))
656 .Times(AtLeast(1))
657 .WillRepeatedly(Return(true));
658 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
659 .Times(AtLeast(1))
660 .WillRepeatedly(Return(true));
661 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
662 .WillOnce(Return(true));
663 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
664 .WillOnce(Return(true));
665 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
666 EXPECT_CALL(storage,
667 SetBool(storage_id_,
668 Service::kStorageSaveCredentials,
669 service_->save_credentials()));
670 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
671 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true));
672 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
673 std::unique_ptr<MockDhcpProperties> dhcp_props(new MockDhcpProperties());
674 EXPECT_CALL(*dhcp_props.get(), Save(&storage, storage_id_));
675 service_->dhcp_properties_ = std::move(dhcp_props);
676 EXPECT_TRUE(service_->Save(&storage));
677 }
678
TEST_F(ServiceTest,RetainAutoConnect)679 TEST_F(ServiceTest, RetainAutoConnect) {
680 NiceMock<MockStore> storage;
681 EXPECT_CALL(storage, SetString(storage_id_, _, _))
682 .Times(AtLeast(1))
683 .WillRepeatedly(Return(true));
684 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
685 .Times(AtLeast(1))
686 .WillRepeatedly(Return(true));
687 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageFavorite))
688 .Times(2);
689 EXPECT_CALL(storage, DeleteKey(storage_id_, Service::kStorageAutoConnect))
690 .Times(0);
691 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
692 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
693 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
694 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
695
696 // AutoConnect flag set true.
697 service_->EnableAndRetainAutoConnect();
698 EXPECT_CALL(storage,
699 SetBool(storage_id_, Service::kStorageAutoConnect, true));
700 EXPECT_TRUE(service_->Save(&storage));
701
702 // AutoConnect flag set false.
703 EXPECT_CALL(storage,
704 SetBool(storage_id_, Service::kStorageAutoConnect, false));
705 service_->SetAutoConnect(false);
706 EXPECT_TRUE(service_->Save(&storage));
707 }
708
TEST_F(ServiceTest,HasEverConnectedSavedToProfile)709 TEST_F(ServiceTest, HasEverConnectedSavedToProfile) {
710 NiceMock<MockStore> storage;
711 EXPECT_CALL(storage, SetString(storage_id_, _, _))
712 .Times(AtLeast(1))
713 .WillRepeatedly(Return(true));
714 EXPECT_CALL(storage, DeleteKey(storage_id_, _))
715 .Times(AtLeast(1))
716 .WillRepeatedly(Return(true));
717 EXPECT_CALL(storage,
718 DeleteKey(storage_id_, Service::kStorageHasEverConnected))
719 .Times(0);
720 EXPECT_CALL(storage, SetBool(storage_id_, _, _)).Times(AnyNumber());
721 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
722 EXPECT_CALL(*eap_, Save(&storage, storage_id_, true)).Times(2);
723 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
724
725 // HasEverConnected flag set true.
726 service_->SetHasEverConnected(true);
727 EXPECT_CALL(storage,
728 SetBool(storage_id_, Service::kStorageHasEverConnected, true));
729 EXPECT_TRUE(service_->Save(&storage));
730
731 // HasEverConnected flag set false.
732 EXPECT_CALL(storage,
733 SetBool(storage_id_, Service::kStorageHasEverConnected, false));
734 service_->SetHasEverConnected(false);
735 EXPECT_TRUE(service_->Save(&storage));
736 }
737
TEST_F(ServiceTest,Unload)738 TEST_F(ServiceTest, Unload) {
739 NiceMock<MockStore> storage;
740 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
741 static const string string_value("value");
742 EXPECT_CALL(storage, GetString(storage_id_, _, _))
743 .Times(AtLeast(1))
744 .WillRepeatedly(DoAll(SetArgumentPointee<2>(string_value), Return(true)));
745 EXPECT_CALL(storage, GetBool(storage_id_, _, _))
746 .Times(AtLeast(1))
747 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
748 EXPECT_FALSE(service_->explicitly_disconnected_);
749 service_->explicitly_disconnected_ = true;
750 EXPECT_FALSE(service_->has_ever_connected_);
751 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
752 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
753 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
754 ASSERT_TRUE(service_->Load(&storage));
755 // TODO(pstew): Only two string properties in the service are tested as
756 // a sentinel that properties are being set and reset at the right times.
757 // However, since property load/store is essentially a manual process,
758 // it is error prone and should either be exhaustively unit-tested or
759 // a generic framework for registering loaded/stored properties should
760 // be created. crbug.com/207798
761 EXPECT_EQ(string_value, service_->ui_data_);
762 EXPECT_EQ(string_value, service_->guid_);
763 EXPECT_FALSE(service_->explicitly_disconnected_);
764 EXPECT_TRUE(service_->has_ever_connected_);
765 service_->explicitly_disconnected_ = true;
766 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
767 EXPECT_CALL(*eap_, Reset());
768 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
769 service_->Unload();
770 EXPECT_EQ(string(""), service_->ui_data_);
771 EXPECT_EQ(string(""), service_->guid_);
772 EXPECT_FALSE(service_->explicitly_disconnected_);
773 EXPECT_FALSE(service_->has_ever_connected_);
774 }
775
TEST_F(ServiceTest,State)776 TEST_F(ServiceTest, State) {
777 EXPECT_EQ(Service::kStateIdle, service_->state());
778 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
779 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
780 const string unknown_error(
781 Service::ConnectFailureToString(Service::kFailureUnknown));
782 EXPECT_EQ(unknown_error, service_->error());
783
784 EXPECT_CALL(*GetAdaptor(),
785 EmitStringChanged(kStateProperty, _)).Times(6);
786 EXPECT_CALL(*GetAdaptor(),
787 EmitStringChanged(kErrorProperty, _)).Times(4);
788 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
789 service_->SetState(Service::kStateConnected);
790 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
791 // A second state change shouldn't cause another update
792 service_->SetState(Service::kStateConnected);
793 EXPECT_EQ(Service::kStateConnected, service_->state());
794 EXPECT_EQ(Service::kStateIdle, GetPreviousState());
795 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
796 EXPECT_TRUE(service_->has_ever_connected_);
797
798 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
799 service_->SetFailure(Service::kFailureOutOfRange);
800 EXPECT_TRUE(service_->IsFailed());
801 EXPECT_GT(service_->failed_time_, 0);
802 EXPECT_GT(service_->previous_error_serial_number_, 0);
803 EXPECT_EQ(Service::kStateFailure, service_->state());
804 EXPECT_EQ(Service::kFailureOutOfRange, service_->failure());
805 const string out_of_range_error(
806 Service::ConnectFailureToString(Service::kFailureOutOfRange));
807 EXPECT_EQ(out_of_range_error, service_->error());
808 EXPECT_EQ(out_of_range_error, service_->previous_error_);
809
810 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
811 service_->SetState(Service::kStateConnected);
812 EXPECT_FALSE(service_->IsFailed());
813 EXPECT_EQ(service_->failed_time_, 0);
814 EXPECT_EQ(unknown_error, service_->error());
815 EXPECT_EQ(out_of_range_error, service_->previous_error_);
816 EXPECT_GT(service_->previous_error_serial_number_, 0);
817
818 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
819 service_->SetFailureSilent(Service::kFailurePinMissing);
820 EXPECT_TRUE(service_->IsFailed());
821 EXPECT_GT(service_->failed_time_, 0);
822 EXPECT_GT(service_->previous_error_serial_number_, 0);
823 EXPECT_EQ(Service::kStateIdle, service_->state());
824 EXPECT_EQ(Service::kFailurePinMissing, service_->failure());
825 const string pin_missing_error(
826 Service::ConnectFailureToString(Service::kFailurePinMissing));
827 EXPECT_EQ(pin_missing_error, service_->error());
828 EXPECT_EQ(pin_missing_error, service_->previous_error_);
829
830 // If the Service has a Profile, the profile should be saved when
831 // the service enters kStateConnected. (The case where the service
832 // doesn't have a profile is tested above.)
833 MockProfileRefPtr mock_profile(
834 new MockProfile(control_interface(), metrics(), &mock_manager_));
835 NiceMock<MockStore> storage;
836 service_->set_profile(mock_profile);
837 service_->has_ever_connected_ = false;
838 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
839 EXPECT_CALL(*mock_profile, GetConstStorage())
840 .WillOnce(Return(&storage));
841 EXPECT_CALL(*mock_profile, UpdateService(IsRefPtrTo(service_)));
842 service_->SetState(Service::kStateConnected);
843 EXPECT_TRUE(service_->has_ever_connected_);
844 service_->set_profile(nullptr); // Break reference cycle.
845
846 // Similar to the above, but emulate an emphemeral profile, which
847 // has no storage. We can't update the service in the profile, but
848 // we should not crash.
849 service_->state_ = Service::kStateIdle; // Skips state change logic.
850 service_->set_profile(mock_profile);
851 service_->has_ever_connected_ = false;
852 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
853 EXPECT_CALL(*mock_profile, GetConstStorage()).WillOnce(Return(nullptr));
854 service_->SetState(Service::kStateConnected);
855 EXPECT_TRUE(service_->has_ever_connected_);
856 service_->set_profile(nullptr); // Break reference cycle.
857 }
858
TEST_F(ServiceTest,PortalDetectionFailure)859 TEST_F(ServiceTest, PortalDetectionFailure) {
860 EXPECT_CALL(*GetAdaptor(),
861 EmitStringChanged(kPortalDetectionFailedPhaseProperty,
862 kPortalDetectionPhaseDns)).Times(1);
863 EXPECT_CALL(*GetAdaptor(),
864 EmitStringChanged(kPortalDetectionFailedStatusProperty,
865 kPortalDetectionStatusTimeout)).Times(1);
866 service_->SetPortalDetectionFailure(kPortalDetectionPhaseDns,
867 kPortalDetectionStatusTimeout);
868 EXPECT_EQ(kPortalDetectionPhaseDns,
869 service_->portal_detection_failure_phase_);
870 EXPECT_EQ(kPortalDetectionStatusTimeout,
871 service_->portal_detection_failure_status_);
872 }
873
TEST_F(ServiceTest,StateResetAfterFailure)874 TEST_F(ServiceTest, StateResetAfterFailure) {
875 service_->SetFailure(Service::kFailureOutOfRange);
876 EXPECT_EQ(Service::kStateFailure, service_->state());
877 Error error;
878 service_->Connect(&error, "in test");
879 EXPECT_EQ(Service::kStateIdle, service_->state());
880 EXPECT_EQ(Service::kFailureUnknown, service_->failure());
881
882 service_->SetState(Service::kStateConnected);
883 service_->Connect(&error, "in test");
884 EXPECT_EQ(Service::kStateConnected, service_->state());
885 }
886
TEST_F(ServiceTest,UserInitiatedConnectionResult)887 TEST_F(ServiceTest, UserInitiatedConnectionResult) {
888 service_->technology_ = Technology::kWifi;
889 Error error;
890 // User-initiated connection attempt succeed.
891 service_->SetState(Service::kStateIdle);
892 service_->UserInitiatedConnect(&error);
893 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
894 Metrics::kMetricWifiUserInitiatedConnectionResult,
895 Metrics::kUserInitiatedConnectionResultSuccess));
896 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
897 .Times(0);
898 service_->SetState(Service::kStateConnected);
899 Mock::VerifyAndClearExpectations(metrics());
900
901 // User-initiated connection attempt failed.
902 service_->SetState(Service::kStateIdle);
903 service_->UserInitiatedConnect(&error);
904 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
905 Metrics::kMetricWifiUserInitiatedConnectionResult,
906 Metrics::kUserInitiatedConnectionResultFailure));
907 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(
908 Metrics::kMetricWifiUserInitiatedConnectionFailureReason,
909 Service::kFailureDHCP));
910 service_->SetFailure(Service::kFailureDHCP);
911 Mock::VerifyAndClearExpectations(metrics());
912
913 // User-initiated connection attempt aborted.
914 service_->SetState(Service::kStateIdle);
915 service_->UserInitiatedConnect(&error);
916 service_->SetState(Service::kStateAssociating);
917 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(
918 Metrics::kMetricWifiUserInitiatedConnectionResult,
919 Metrics::kUserInitiatedConnectionResultAborted));
920 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
921 .Times(0);
922 service_->SetState(Service::kStateIdle);
923 Mock::VerifyAndClearExpectations(metrics());
924
925 // No metric reporting for other state transition.
926 service_->SetState(Service::kStateIdle);
927 service_->UserInitiatedConnect(&error);
928 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
929 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
930 .Times(0);
931 service_->SetState(Service::kStateAssociating);
932 service_->SetState(Service::kStateConfiguring);
933 Mock::VerifyAndClearExpectations(metrics());
934
935 // No metric reporting for non-user-initiated connection.
936 service_->SetState(Service::kStateIdle);
937 service_->Connect(&error, "in test");
938 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
939 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
940 .Times(0);
941 service_->SetState(Service::kStateConnected);
942 Mock::VerifyAndClearExpectations(metrics());
943
944 // No metric reporting for other technology.
945 service_->technology_ = Technology::kCellular;
946 service_->SetState(Service::kStateIdle);
947 service_->UserInitiatedConnect(&error);
948 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionResult(_, _)).Times(0);
949 EXPECT_CALL(*metrics(), NotifyUserInitiatedConnectionFailureReason(_, _))
950 .Times(0);
951 service_->SetFailure(Service::kFailureDHCP);
952 Mock::VerifyAndClearExpectations(metrics());
953 }
954
TEST_F(ServiceTest,ActivateCellularModem)955 TEST_F(ServiceTest, ActivateCellularModem) {
956 ResultCallback callback =
957 Bind(&ServiceTest::TestCallback, Unretained(this));
958 EXPECT_CALL(*this, TestCallback(_)).Times(0);
959 Error error;
960 service_->ActivateCellularModem("Carrier", &error, callback);
961 EXPECT_TRUE(error.IsFailure());
962 }
963
TEST_F(ServiceTest,CompleteCellularActivation)964 TEST_F(ServiceTest, CompleteCellularActivation) {
965 Error error;
966 service_->CompleteCellularActivation(&error);
967 EXPECT_EQ(Error::kNotSupported, error.type());
968 }
969
TEST_F(ServiceTest,EnableAndRetainAutoConnect)970 TEST_F(ServiceTest, EnableAndRetainAutoConnect) {
971 EXPECT_FALSE(service_->retain_auto_connect());
972 EXPECT_FALSE(service_->auto_connect());
973
974 service_->EnableAndRetainAutoConnect();
975 EXPECT_TRUE(service_->retain_auto_connect());
976 EXPECT_TRUE(service_->auto_connect());
977 }
978
TEST_F(ServiceTest,ReRetainAutoConnect)979 TEST_F(ServiceTest, ReRetainAutoConnect) {
980 service_->EnableAndRetainAutoConnect();
981 EXPECT_TRUE(service_->retain_auto_connect());
982 EXPECT_TRUE(service_->auto_connect());
983
984 service_->SetAutoConnect(false);
985 service_->EnableAndRetainAutoConnect();
986 EXPECT_TRUE(service_->retain_auto_connect());
987 EXPECT_FALSE(service_->auto_connect());
988 }
989
TEST_F(ServiceTest,IsAutoConnectable)990 TEST_F(ServiceTest, IsAutoConnectable) {
991 const char* reason = nullptr;
992 service_->SetConnectable(true);
993
994 // Services with non-primary connectivity technologies should not auto-connect
995 // when the system is offline.
996 EXPECT_EQ(Technology::kUnknown, service_->technology());
997 EXPECT_CALL(mock_manager_, IsConnected()).WillOnce(Return(false));
998 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
999 EXPECT_STREQ(Service::kAutoConnOffline, reason);
1000
1001 service_->technology_ = Technology::kEthernet;
1002 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1003
1004 // We should not auto-connect to a Service that a user has
1005 // deliberately disconnected.
1006 Error error;
1007 service_->UserInitiatedDisconnect(&error);
1008 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1009 EXPECT_STREQ(Service::kAutoConnExplicitDisconnect, reason);
1010
1011 // But if the Service is reloaded, it is eligible for auto-connect
1012 // again.
1013 NiceMock<MockStore> storage;
1014 EXPECT_CALL(storage, ContainsGroup(storage_id_)).WillOnce(Return(true));
1015 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
1016 EXPECT_CALL(*eap_, Load(&storage, storage_id_));
1017 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
1018 EXPECT_TRUE(service_->Load(&storage));
1019 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1020
1021 // A deliberate Connect should also re-enable auto-connect.
1022 service_->UserInitiatedDisconnect(&error);
1023 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1024 service_->Connect(&error, "in test");
1025 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1026
1027 // A non-user initiated Disconnect doesn't change anything.
1028 service_->Disconnect(&error, "in test");
1029 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1030
1031 // A resume also re-enables auto-connect.
1032 service_->UserInitiatedDisconnect(&error);
1033 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1034 service_->OnAfterResume();
1035 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1036
1037 service_->SetState(Service::kStateConnected);
1038 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1039 EXPECT_STREQ(Service::kAutoConnConnected, reason);
1040
1041 service_->SetState(Service::kStateAssociating);
1042 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1043 EXPECT_STREQ(Service::kAutoConnConnecting, reason);
1044
1045 service_->SetState(Service::kStateIdle);
1046 EXPECT_CALL(mock_manager_, IsTechnologyAutoConnectDisabled(
1047 service_->technology_)).WillOnce(Return(true));
1048 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1049 EXPECT_STREQ(Service::kAutoConnTechnologyNotConnectable, reason);
1050 }
1051
TEST_F(ServiceTest,AutoConnectLogging)1052 TEST_F(ServiceTest, AutoConnectLogging) {
1053 ScopedMockLog log;
1054 EXPECT_CALL(log, Log(_, _, _));
1055 service_->SetConnectable(true);
1056
1057 ScopeLogger::GetInstance()->EnableScopesByName("+service");
1058 ScopeLogger::GetInstance()->set_verbose_level(1);
1059 service_->SetState(Service::kStateConnected);
1060 EXPECT_CALL(log, Log(-1, _, HasSubstr(Service::kAutoConnConnected)));
1061 service_->AutoConnect();
1062
1063 ScopeLogger::GetInstance()->EnableScopesByName("-service");
1064 ScopeLogger::GetInstance()->set_verbose_level(0);
1065 EXPECT_CALL(log, Log(logging::LOG_INFO, _,
1066 HasSubstr(Service::kAutoConnNotConnectable)));
1067 service_->SetConnectable(false);
1068 service_->AutoConnect();
1069 }
1070
1071
TEST_F(AllMockServiceTest,AutoConnectWithFailures)1072 TEST_F(AllMockServiceTest, AutoConnectWithFailures) {
1073 const char* reason;
1074 service_->SetConnectable(true);
1075 service_->technology_ = Technology::kEthernet;
1076 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1077
1078 // The very first AutoConnect() doesn't trigger any throttling.
1079 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1080 service_->AutoConnect();
1081 Mock::VerifyAndClearExpectations(&dispatcher_);
1082 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1083
1084 // The second call does trigger some throttling.
1085 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1086 Service::kMinAutoConnectCooldownTimeMilliseconds));
1087 service_->AutoConnect();
1088 Mock::VerifyAndClearExpectations(&dispatcher_);
1089 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1090 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1091
1092 // Calling AutoConnect() again before the cooldown terminates does not change
1093 // the timeout.
1094 EXPECT_CALL(dispatcher_, PostDelayedTask(_, _)).Times(0);
1095 service_->AutoConnect();
1096 Mock::VerifyAndClearExpectations(&dispatcher_);
1097 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1098 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1099
1100 // Once the timeout expires, we can AutoConnect() again.
1101 service_->ReEnableAutoConnectTask();
1102 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1103
1104 // Timeouts increase exponentially.
1105 uint64_t next_cooldown_time = service_->auto_connect_cooldown_milliseconds_;
1106 EXPECT_EQ(next_cooldown_time,
1107 Service::kAutoConnectCooldownBackoffFactor *
1108 Service::kMinAutoConnectCooldownTimeMilliseconds);
1109 while (next_cooldown_time <=
1110 Service::kMaxAutoConnectCooldownTimeMilliseconds) {
1111 EXPECT_CALL(dispatcher_, PostDelayedTask(_, next_cooldown_time));
1112 service_->AutoConnect();
1113 Mock::VerifyAndClearExpectations(&dispatcher_);
1114 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1115 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1116 service_->ReEnableAutoConnectTask();
1117 next_cooldown_time *= Service::kAutoConnectCooldownBackoffFactor;
1118 }
1119
1120 // Once we hit our cap, future timeouts are the same.
1121 for (int32_t i = 0; i < 2; i++) {
1122 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1123 Service::kMaxAutoConnectCooldownTimeMilliseconds));
1124 service_->AutoConnect();
1125 Mock::VerifyAndClearExpectations(&dispatcher_);
1126 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1127 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1128 service_->ReEnableAutoConnectTask();
1129 }
1130
1131 // Connecting successfully resets our cooldown.
1132 service_->SetState(Service::kStateConnected);
1133 service_->SetState(Service::kStateIdle);
1134 reason = "";
1135 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1136 EXPECT_STREQ("", reason);
1137 EXPECT_EQ(service_->auto_connect_cooldown_milliseconds_, 0);
1138
1139 // But future AutoConnects behave as before
1140 EXPECT_CALL(dispatcher_, PostDelayedTask(_,
1141 Service::kMinAutoConnectCooldownTimeMilliseconds)).Times(1);
1142 service_->AutoConnect();
1143 service_->AutoConnect();
1144 Mock::VerifyAndClearExpectations(&dispatcher_);
1145 EXPECT_FALSE(service_->IsAutoConnectable(&reason));
1146 EXPECT_STREQ(Service::kAutoConnThrottled, reason);
1147
1148 // Cooldowns are forgotten if we go through a suspend/resume cycle.
1149 service_->OnAfterResume();
1150 reason = "";
1151 EXPECT_TRUE(service_->IsAutoConnectable(&reason));
1152 EXPECT_STREQ("", reason);
1153 }
1154
TEST_F(ServiceTest,ConfigureBadProperty)1155 TEST_F(ServiceTest, ConfigureBadProperty) {
1156 KeyValueStore args;
1157 args.SetString("XXXInvalid", "Value");
1158 Error error;
1159 service_->Configure(args, &error);
1160 EXPECT_FALSE(error.IsSuccess());
1161 }
1162
TEST_F(ServiceTest,ConfigureBoolProperty)1163 TEST_F(ServiceTest, ConfigureBoolProperty) {
1164 service_->EnableAndRetainAutoConnect();
1165 service_->SetAutoConnect(false);
1166 ASSERT_FALSE(service_->auto_connect());
1167 KeyValueStore args;
1168 args.SetBool(kAutoConnectProperty, true);
1169 Error error;
1170 service_->Configure(args, &error);
1171 EXPECT_TRUE(error.IsSuccess());
1172 EXPECT_TRUE(service_->auto_connect());
1173 }
1174
TEST_F(ServiceTest,ConfigureStringProperty)1175 TEST_F(ServiceTest, ConfigureStringProperty) {
1176 const string kGuid0 = "guid_zero";
1177 const string kGuid1 = "guid_one";
1178 service_->SetGuid(kGuid0, nullptr);
1179 ASSERT_EQ(kGuid0, service_->guid());
1180 KeyValueStore args;
1181 args.SetString(kGuidProperty, kGuid1);
1182 Error error;
1183 service_->Configure(args, &error);
1184 EXPECT_TRUE(error.IsSuccess());
1185 EXPECT_EQ(kGuid1, service_->guid());
1186 }
1187
TEST_F(ServiceTest,ConfigureStringsProperty)1188 TEST_F(ServiceTest, ConfigureStringsProperty) {
1189 const vector<string> kStrings0{ "string0", "string1" };
1190 const vector<string> kStrings1{ "string2", "string3" };
1191 service_->set_strings(kStrings0);
1192 ASSERT_EQ(kStrings0, service_->strings());
1193 KeyValueStore args;
1194 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
1195 Error error;
1196 service_->Configure(args, &error);
1197 EXPECT_TRUE(error.IsSuccess());
1198 EXPECT_EQ(kStrings1, service_->strings());
1199 }
1200
1201 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
TEST_F(ServiceTest,ConfigureEapStringProperty)1202 TEST_F(ServiceTest, ConfigureEapStringProperty) {
1203 MockEapCredentials* eap = new MockEapCredentials();
1204 service2_->SetEapCredentials(eap); // Passes ownership.
1205
1206 const string kEAPManagement0 = "management_zero";
1207 const string kEAPManagement1 = "management_one";
1208 service2_->SetEAPKeyManagement(kEAPManagement0);
1209
1210 EXPECT_CALL(*eap, key_management())
1211 .WillOnce(ReturnRef(kEAPManagement0));
1212 ASSERT_EQ(kEAPManagement0, service2_->GetEAPKeyManagement());
1213 KeyValueStore args;
1214 EXPECT_CALL(*eap, SetKeyManagement(kEAPManagement1, _));
1215 args.SetString(kEapKeyMgmtProperty, kEAPManagement1);
1216 Error error;
1217 service2_->Configure(args, &error);
1218 EXPECT_TRUE(error.IsSuccess());
1219 }
1220 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
1221
TEST_F(ServiceTest,ConfigureIntProperty)1222 TEST_F(ServiceTest, ConfigureIntProperty) {
1223 const int kPriority0 = 100;
1224 const int kPriority1 = 200;
1225 service_->SetPriority(kPriority0, nullptr);
1226 ASSERT_EQ(kPriority0, service_->priority());
1227 KeyValueStore args;
1228 args.SetInt(kPriorityProperty, kPriority1);
1229 Error error;
1230 service_->Configure(args, &error);
1231 EXPECT_TRUE(error.IsSuccess());
1232 EXPECT_EQ(kPriority1, service_->priority());
1233 }
1234
TEST_F(ServiceTest,ConfigureIgnoredProperty)1235 TEST_F(ServiceTest, ConfigureIgnoredProperty) {
1236 service_->EnableAndRetainAutoConnect();
1237 service_->SetAutoConnect(false);
1238 ASSERT_FALSE(service_->auto_connect());
1239 KeyValueStore args;
1240 args.SetBool(kAutoConnectProperty, true);
1241 Error error;
1242 service_->IgnoreParameterForConfigure(kAutoConnectProperty);
1243 service_->Configure(args, &error);
1244 EXPECT_TRUE(error.IsSuccess());
1245 EXPECT_FALSE(service_->auto_connect());
1246 }
1247
TEST_F(ServiceTest,ConfigureProfileProperty)1248 TEST_F(ServiceTest, ConfigureProfileProperty) {
1249 // Ensure that the Profile property is always ignored.
1250 KeyValueStore args;
1251 args.SetString(kProfileProperty, "profile");
1252 Error error;
1253 EXPECT_CALL(mock_manager_, SetProfileForService(_, _, _)).Times(0);
1254 service_->Configure(args, &error);
1255 EXPECT_TRUE(error.IsSuccess());
1256 }
1257
TEST_F(ServiceTest,ConfigureKeyValueStoreProperty)1258 TEST_F(ServiceTest, ConfigureKeyValueStoreProperty) {
1259 KeyValueStore key_value_store0;
1260 key_value_store0.SetBool("key0", true);
1261 KeyValueStore key_value_store1;
1262 key_value_store1.SetInt("key1", 1);
1263 service_->SetKeyValueStore(key_value_store0, NULL);
1264 ASSERT_EQ(key_value_store0, service_->GetKeyValueStore(NULL));
1265 KeyValueStore args;
1266 args.SetKeyValueStore(
1267 ServiceUnderTest::kKeyValueStoreProperty, key_value_store1);
1268 Error error;
1269 service_->Configure(args, &error);
1270 EXPECT_TRUE(error.IsSuccess());
1271 EXPECT_EQ(key_value_store1, service_->GetKeyValueStore(NULL));
1272 }
1273
TEST_F(ServiceTest,DoPropertiesMatch)1274 TEST_F(ServiceTest, DoPropertiesMatch) {
1275 service_->SetAutoConnect(false);
1276 const string kGUID0 = "guid_zero";
1277 const string kGUID1 = "guid_one";
1278 service_->SetGuid(kGUID0, nullptr);
1279 const uint32_t kPriority0 = 100;
1280 const uint32_t kPriority1 = 200;
1281 service_->SetPriority(kPriority0, nullptr);
1282 const vector<string> kStrings0{ "string0", "string1" };
1283 const vector<string> kStrings1{ "string2", "string3" };
1284 service_->set_strings(kStrings0);
1285 KeyValueStore key_value_store0;
1286 key_value_store0.SetBool("key0", true);
1287 KeyValueStore key_value_store1;
1288 key_value_store1.SetInt("key1", 1);
1289 service_->SetKeyValueStore(key_value_store0, NULL);
1290
1291 {
1292 KeyValueStore args;
1293 args.SetString(kGuidProperty, kGUID0);
1294 args.SetBool(kAutoConnectProperty, false);
1295 args.SetInt(kPriorityProperty, kPriority0);
1296 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1297 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1298 key_value_store0);
1299 EXPECT_TRUE(service_->DoPropertiesMatch(args));
1300 }
1301 {
1302 KeyValueStore args;
1303 args.SetString(kGuidProperty, kGUID1);
1304 args.SetBool(kAutoConnectProperty, false);
1305 args.SetInt(kPriorityProperty, kPriority0);
1306 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1307 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1308 key_value_store0);
1309 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1310 }
1311 {
1312 KeyValueStore args;
1313 args.SetString(kGuidProperty, kGUID0);
1314 args.SetBool(kAutoConnectProperty, true);
1315 args.SetInt(kPriorityProperty, kPriority0);
1316 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1317 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1318 key_value_store0);
1319 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1320 }
1321 {
1322 KeyValueStore args;
1323 args.SetString(kGuidProperty, kGUID0);
1324 args.SetBool(kAutoConnectProperty, false);
1325 args.SetInt(kPriorityProperty, kPriority1);
1326 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1327 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1328 key_value_store0);
1329 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1330 }
1331 {
1332 KeyValueStore args;
1333 args.SetString(kGuidProperty, kGUID0);
1334 args.SetBool(kAutoConnectProperty, false);
1335 args.SetInt(kPriorityProperty, kPriority0);
1336 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings1);
1337 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1338 key_value_store0);
1339 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1340 }
1341 {
1342 KeyValueStore args;
1343 args.SetString(kGuidProperty, kGUID0);
1344 args.SetBool(kAutoConnectProperty, false);
1345 args.SetInt(kPriorityProperty, kPriority0);
1346 args.SetStrings(ServiceUnderTest::kStringsProperty, kStrings0);
1347 args.SetKeyValueStore(ServiceUnderTest::kKeyValueStoreProperty,
1348 key_value_store1);
1349 EXPECT_FALSE(service_->DoPropertiesMatch(args));
1350 }
1351 }
1352
TEST_F(ServiceTest,IsRemembered)1353 TEST_F(ServiceTest, IsRemembered) {
1354 service_->set_profile(nullptr);
1355 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_)).Times(0);
1356 EXPECT_FALSE(service_->IsRemembered());
1357
1358 scoped_refptr<MockProfile> profile(
1359 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
1360 service_->set_profile(profile);
1361 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
1362 .WillOnce(Return(true))
1363 .WillOnce(Return(false));
1364 EXPECT_FALSE(service_->IsRemembered());
1365 EXPECT_TRUE(service_->IsRemembered());
1366 }
1367
TEST_F(ServiceTest,IsDependentOn)1368 TEST_F(ServiceTest, IsDependentOn) {
1369 EXPECT_FALSE(service_->IsDependentOn(nullptr));
1370
1371 std::unique_ptr<MockDeviceInfo> mock_device_info(
1372 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1373 &mock_manager_));
1374 scoped_refptr<MockConnection> mock_connection0(
1375 new NiceMock<MockConnection>(mock_device_info.get()));
1376 scoped_refptr<MockConnection> mock_connection1(
1377 new NiceMock<MockConnection>(mock_device_info.get()));
1378
1379 service_->connection_ = mock_connection0;
1380 EXPECT_CALL(*mock_connection0, GetLowerConnection())
1381 .WillRepeatedly(Return(mock_connection1));
1382 EXPECT_CALL(*mock_connection1, GetLowerConnection())
1383 .WillRepeatedly(Return(ConnectionRefPtr()));
1384 EXPECT_FALSE(service_->IsDependentOn(nullptr));
1385
1386 scoped_refptr<ServiceUnderTest> service1 =
1387 new ServiceUnderTest(control_interface(),
1388 dispatcher(),
1389 metrics(),
1390 &mock_manager_);
1391 EXPECT_FALSE(service_->IsDependentOn(service1));
1392
1393 service1->connection_ = mock_connection0;
1394 EXPECT_FALSE(service_->IsDependentOn(service1));
1395
1396 service1->connection_ = mock_connection1;
1397 EXPECT_TRUE(service_->IsDependentOn(service1));
1398
1399 service_->connection_ = mock_connection1;
1400 service1->connection_ = nullptr;
1401 EXPECT_FALSE(service_->IsDependentOn(service1));
1402
1403 service_->connection_ = nullptr;
1404 }
1405
TEST_F(ServiceTest,OnPropertyChanged)1406 TEST_F(ServiceTest, OnPropertyChanged) {
1407 scoped_refptr<MockProfile> profile(
1408 new StrictMock<MockProfile>(control_interface(), metrics(), manager()));
1409 service_->set_profile(nullptr);
1410 // Expect no crash.
1411 service_->OnPropertyChanged("");
1412
1413 // Expect no call to Update if the profile has no storage.
1414 service_->set_profile(profile);
1415 EXPECT_CALL(*profile, UpdateService(_)).Times(0);
1416 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(nullptr));
1417 service_->OnPropertyChanged("");
1418
1419 // Expect call to Update if the profile has storage.
1420 EXPECT_CALL(*profile, UpdateService(_)).Times(1);
1421 NiceMock<MockStore> storage;
1422 EXPECT_CALL(*profile, GetConstStorage()).WillOnce(Return(&storage));
1423 service_->OnPropertyChanged("");
1424 }
1425
1426
TEST_F(ServiceTest,RecheckPortal)1427 TEST_F(ServiceTest, RecheckPortal) {
1428 service_->state_ = Service::kStateIdle;
1429 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
1430 service_->OnPropertyChanged(kCheckPortalProperty);
1431
1432 service_->state_ = Service::kStatePortal;
1433 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1434 .Times(1);
1435 service_->OnPropertyChanged(kCheckPortalProperty);
1436
1437 service_->state_ = Service::kStateConnected;
1438 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1439 .Times(1);
1440 service_->OnPropertyChanged(kProxyConfigProperty);
1441
1442 service_->state_ = Service::kStateOnline;
1443 EXPECT_CALL(mock_manager_, RecheckPortalOnService(IsRefPtrTo(service_)))
1444 .Times(1);
1445 service_->OnPropertyChanged(kCheckPortalProperty);
1446
1447 service_->state_ = Service::kStatePortal;
1448 EXPECT_CALL(mock_manager_, RecheckPortalOnService(_)).Times(0);
1449 service_->OnPropertyChanged(kEapKeyIdProperty);
1450 }
1451
TEST_F(ServiceTest,SetCheckPortal)1452 TEST_F(ServiceTest, SetCheckPortal) {
1453 {
1454 Error error;
1455 service_->SetCheckPortal("false", &error);
1456 EXPECT_TRUE(error.IsSuccess());
1457 EXPECT_EQ(Service::kCheckPortalFalse, service_->check_portal_);
1458 }
1459 {
1460 Error error;
1461 service_->SetCheckPortal("true", &error);
1462 EXPECT_TRUE(error.IsSuccess());
1463 EXPECT_EQ(Service::kCheckPortalTrue, service_->check_portal_);
1464 }
1465 {
1466 Error error;
1467 service_->SetCheckPortal("auto", &error);
1468 EXPECT_TRUE(error.IsSuccess());
1469 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1470 }
1471 {
1472 Error error;
1473 service_->SetCheckPortal("xxx", &error);
1474 EXPECT_FALSE(error.IsSuccess());
1475 EXPECT_EQ(Error::kInvalidArguments, error.type());
1476 EXPECT_EQ(Service::kCheckPortalAuto, service_->check_portal_);
1477 }
1478 }
1479
TEST_F(ServiceTest,SetFriendlyName)1480 TEST_F(ServiceTest, SetFriendlyName) {
1481 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
1482 ServiceMockAdaptor* adaptor = GetAdaptor();
1483
1484 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1485 service_->SetFriendlyName(service_->unique_name_);
1486 EXPECT_EQ(service_->unique_name_, service_->friendly_name_);
1487
1488 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
1489 "Test Name 1"));
1490 service_->SetFriendlyName("Test Name 1");
1491 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1492
1493 EXPECT_CALL(*adaptor, EmitStringChanged(_, _)).Times(0);
1494 service_->SetFriendlyName("Test Name 1");
1495 EXPECT_EQ("Test Name 1", service_->friendly_name_);
1496
1497 EXPECT_CALL(*adaptor, EmitStringChanged(kNameProperty,
1498 "Test Name 2"));
1499 service_->SetFriendlyName("Test Name 2");
1500 EXPECT_EQ("Test Name 2", service_->friendly_name_);
1501 }
1502
TEST_F(ServiceTest,SetConnectableFull)1503 TEST_F(ServiceTest, SetConnectableFull) {
1504 EXPECT_FALSE(service_->connectable());
1505
1506 ServiceMockAdaptor* adaptor = GetAdaptor();
1507
1508 EXPECT_CALL(*adaptor, EmitBoolChanged(_, _)).Times(0);
1509 EXPECT_CALL(mock_manager_, HasService(_)).Times(0);
1510 service_->SetConnectableFull(false);
1511 EXPECT_FALSE(service_->connectable());
1512
1513 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
1514 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(false));
1515 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
1516 service_->SetConnectableFull(true);
1517 EXPECT_TRUE(service_->connectable());
1518
1519 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, false));
1520 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1521 EXPECT_CALL(mock_manager_, UpdateService(_));
1522 service_->SetConnectableFull(false);
1523 EXPECT_FALSE(service_->connectable());
1524
1525 EXPECT_CALL(*adaptor, EmitBoolChanged(kConnectableProperty, true));
1526 EXPECT_CALL(mock_manager_, HasService(_)).WillOnce(Return(true));
1527 EXPECT_CALL(mock_manager_, UpdateService(_));
1528 service_->SetConnectableFull(true);
1529 EXPECT_TRUE(service_->connectable());
1530 }
1531
1532 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
1533 class WriteOnlyServicePropertyTest : public ServiceTest {};
TEST_P(WriteOnlyServicePropertyTest,PropertyWriteOnly)1534 TEST_P(WriteOnlyServicePropertyTest, PropertyWriteOnly) {
1535 // Use a real EapCredentials instance since the base Service class
1536 // contains no write-only properties.
1537 EapCredentials eap;
1538 eap.InitPropertyStore(service_->mutable_store());
1539
1540 string property(GetParam().Get<string>());
1541 Error error;
1542 EXPECT_FALSE(service_->store().GetStringProperty(property, nullptr, &error));
1543 EXPECT_EQ(Error::kPermissionDenied, error.type());
1544 }
1545
1546 INSTANTIATE_TEST_CASE_P(
1547 WriteOnlyServicePropertyTestInstance,
1548 WriteOnlyServicePropertyTest,
1549 Values(
1550 brillo::Any(string(kEapPrivateKeyPasswordProperty)),
1551 brillo::Any(string(kEapPasswordProperty))));
1552 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
1553
TEST_F(ServiceTest,GetIPConfigRpcIdentifier)1554 TEST_F(ServiceTest, GetIPConfigRpcIdentifier) {
1555 {
1556 Error error;
1557 EXPECT_EQ(control_interface()->NullRPCIdentifier(),
1558 service_->GetIPConfigRpcIdentifier(&error));
1559 EXPECT_EQ(Error::kNotFound, error.type());
1560 }
1561
1562 std::unique_ptr<MockDeviceInfo> mock_device_info(
1563 new NiceMock<MockDeviceInfo>(control_interface(), dispatcher(), metrics(),
1564 &mock_manager_));
1565 scoped_refptr<MockConnection> mock_connection(
1566 new NiceMock<MockConnection>(mock_device_info.get()));
1567
1568 service_->connection_ = mock_connection;
1569
1570 {
1571 Error error;
1572 const string empty_string;
1573 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1574 .WillOnce(ReturnRef(empty_string));
1575 EXPECT_EQ(control_interface()->NullRPCIdentifier(),
1576 service_->GetIPConfigRpcIdentifier(&error));
1577 EXPECT_EQ(Error::kNotFound, error.type());
1578 }
1579
1580 {
1581 Error error;
1582 const string nonempty_string("/ipconfig/path");
1583 EXPECT_CALL(*mock_connection, ipconfig_rpc_identifier())
1584 .WillOnce(ReturnRef(nonempty_string));
1585 EXPECT_EQ(nonempty_string, service_->GetIPConfigRpcIdentifier(&error));
1586 EXPECT_EQ(Error::kSuccess, error.type());
1587 }
1588
1589 // Assure orderly destruction of the Connection before DeviceInfo.
1590 service_->connection_ = nullptr;
1591 mock_connection = nullptr;
1592 mock_device_info.reset();
1593 }
1594
1595 #if !defined(DISABLE_WIFI) || !defined(DISABLE_WIRED_8021X)
1596 class ServiceWithMockOnEapCredentialsChanged : public ServiceUnderTest {
1597 public:
ServiceWithMockOnEapCredentialsChanged(ControlInterface * control_interface,EventDispatcher * dispatcher,Metrics * metrics,Manager * manager)1598 ServiceWithMockOnEapCredentialsChanged(ControlInterface* control_interface,
1599 EventDispatcher* dispatcher,
1600 Metrics* metrics,
1601 Manager* manager)
1602 : ServiceUnderTest(control_interface, dispatcher, metrics, manager),
1603 is_8021x_(false) {}
1604 MOCK_METHOD1(OnEapCredentialsChanged, void(Service::UpdateCredentialsReason));
Is8021x() const1605 virtual bool Is8021x() const { return is_8021x_; }
set_is_8021x(bool is_8021x)1606 void set_is_8021x(bool is_8021x) { is_8021x_ = is_8021x; }
1607
1608 private:
1609 bool is_8021x_;
1610 };
1611
TEST_F(ServiceTest,SetEAPCredentialsOverRPC)1612 TEST_F(ServiceTest, SetEAPCredentialsOverRPC) {
1613 scoped_refptr<ServiceWithMockOnEapCredentialsChanged> service(
1614 new ServiceWithMockOnEapCredentialsChanged(control_interface(),
1615 dispatcher(),
1616 metrics(),
1617 &mock_manager_));
1618 string eap_credential_properties[] = {
1619 kEapAnonymousIdentityProperty,
1620 kEapCertIdProperty,
1621 kEapClientCertProperty,
1622 kEapIdentityProperty,
1623 kEapKeyIdProperty,
1624 kEapPasswordProperty,
1625 kEapPinProperty,
1626 kEapPrivateKeyProperty,
1627 kEapPrivateKeyPasswordProperty
1628 };
1629 string eap_non_credential_properties[] = {
1630 kEapCaCertIdProperty,
1631 kEapCaCertNssProperty,
1632 kEapMethodProperty,
1633 kEapPhase2AuthProperty,
1634 kEapUseSystemCasProperty
1635 };
1636 // While this is not an 802.1x-based service, none of these property
1637 // changes should cause a call to set_eap().
1638 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
1639 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i)
1640 service->OnPropertyChanged(eap_credential_properties[i]);
1641 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1642 service->OnPropertyChanged(eap_non_credential_properties[i]);
1643 service->OnPropertyChanged(kEapKeyMgmtProperty);
1644
1645 service->set_is_8021x(true);
1646
1647 // When this is an 802.1x-based service, set_eap should be called for
1648 // all credential-carrying properties.
1649 for (size_t i = 0; i < arraysize(eap_credential_properties); ++i) {
1650 EXPECT_CALL(*service,
1651 OnEapCredentialsChanged(
1652 Service::kReasonPropertyUpdate)).Times(1);
1653 service->OnPropertyChanged(eap_credential_properties[i]);
1654 Mock::VerifyAndClearExpectations(service.get());
1655 }
1656
1657 // The key management property is a special case. While not strictly
1658 // a credential, it can change which credentials are used. Therefore it
1659 // should also trigger a call to set_eap();
1660 EXPECT_CALL(*service,
1661 OnEapCredentialsChanged(Service::kReasonPropertyUpdate)).Times(1);
1662 service->OnPropertyChanged(kEapKeyMgmtProperty);
1663 Mock::VerifyAndClearExpectations(service.get());
1664
1665 EXPECT_CALL(*service, OnEapCredentialsChanged(_)).Times(0);
1666 for (size_t i = 0; i < arraysize(eap_non_credential_properties); ++i)
1667 service->OnPropertyChanged(eap_non_credential_properties[i]);
1668 }
1669
TEST_F(ServiceTest,Certification)1670 TEST_F(ServiceTest, Certification) {
1671 EXPECT_FALSE(service_->remote_certification_.size());
1672
1673 ScopedMockLog log;
1674 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1675 HasSubstr("exceeds our maximum"))).Times(2);
1676 string kSubject("foo");
1677 EXPECT_FALSE(service_->AddEAPCertification(
1678 kSubject, Service::kEAPMaxCertificationElements));
1679 EXPECT_FALSE(service_->AddEAPCertification(
1680 kSubject, Service::kEAPMaxCertificationElements + 1));
1681 EXPECT_FALSE(service_->remote_certification_.size());
1682 Mock::VerifyAndClearExpectations(&log);
1683
1684 EXPECT_CALL(log,
1685 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1686 .Times(1);
1687 EXPECT_TRUE(service_->AddEAPCertification(
1688 kSubject, Service::kEAPMaxCertificationElements - 1));
1689 Mock::VerifyAndClearExpectations(&log);
1690 EXPECT_EQ(Service::kEAPMaxCertificationElements,
1691 service_->remote_certification_.size());
1692 for (size_t i = 0; i < Service::kEAPMaxCertificationElements - 1; ++i) {
1693 EXPECT_TRUE(service_->remote_certification_[i].empty());
1694 }
1695 EXPECT_EQ(kSubject, service_->remote_certification_[
1696 Service::kEAPMaxCertificationElements - 1]);
1697
1698 // Re-adding the same name in the same position should not generate a log.
1699 EXPECT_CALL(log, Log(_, _, _)).Times(0);
1700 EXPECT_TRUE(service_->AddEAPCertification(
1701 kSubject, Service::kEAPMaxCertificationElements - 1));
1702
1703 // Replacing the item should generate a log message.
1704 EXPECT_CALL(log,
1705 Log(logging::LOG_INFO, _, HasSubstr("Received certification")))
1706 .Times(1);
1707 EXPECT_TRUE(service_->AddEAPCertification(
1708 kSubject + "x", Service::kEAPMaxCertificationElements - 1));
1709
1710 service_->ClearEAPCertification();
1711 EXPECT_TRUE(service_->remote_certification_.empty());
1712 }
1713 #endif // DISABLE_WIFI || DISABLE_WIRED_8021X
1714
TEST_F(ServiceTest,NoteDisconnectEventIdle)1715 TEST_F(ServiceTest, NoteDisconnectEventIdle) {
1716 Timestamp timestamp;
1717 EXPECT_CALL(time_, GetNow()).Times(7).WillRepeatedly((Return(timestamp)));
1718 SetStateField(Service::kStateOnline);
1719 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1720 service_->SetState(Service::kStateIdle);
1721 // The transition Online->Idle is not an event.
1722 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1723 service_->SetState(Service::kStateFailure);
1724 // The transition Online->Idle->Failure is a connection drop.
1725 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1726 }
1727
TEST_F(ServiceTest,NoteDisconnectEventOnSetStateFailure)1728 TEST_F(ServiceTest, NoteDisconnectEventOnSetStateFailure) {
1729 Timestamp timestamp;
1730 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
1731 SetStateField(Service::kStateOnline);
1732 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1733 service_->SetState(Service::kStateFailure);
1734 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1735 }
1736
TEST_F(ServiceTest,NoteDisconnectEventOnSetFailureSilent)1737 TEST_F(ServiceTest, NoteDisconnectEventOnSetFailureSilent) {
1738 Timestamp timestamp;
1739 EXPECT_CALL(time_, GetNow()).Times(5).WillRepeatedly((Return(timestamp)));
1740 SetStateField(Service::kStateConfiguring);
1741 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1742 service_->SetFailureSilent(Service::kFailureEAPAuthentication);
1743 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1744 }
1745
TEST_F(ServiceTest,NoteDisconnectEventNonEvent)1746 TEST_F(ServiceTest, NoteDisconnectEventNonEvent) {
1747 EXPECT_CALL(time_, GetNow()).Times(0);
1748
1749 // Explicit disconnect is a non-event.
1750 SetStateField(Service::kStateOnline);
1751 SetExplicitlyDisconnected(true);
1752 NoteDisconnectEvent();
1753 EXPECT_TRUE(GetDisconnects()->Empty());
1754 EXPECT_TRUE(GetMisconnects()->Empty());
1755
1756 // Failure to idle transition is a non-event.
1757 SetStateField(Service::kStateFailure);
1758 SetExplicitlyDisconnected(false);
1759 NoteDisconnectEvent();
1760 EXPECT_TRUE(GetDisconnects()->Empty());
1761 EXPECT_TRUE(GetMisconnects()->Empty());
1762
1763 // Disconnect while manager is stopped is a non-event.
1764 SetStateField(Service::kStateOnline);
1765 SetManagerRunning(false);
1766 NoteDisconnectEvent();
1767 EXPECT_TRUE(GetDisconnects()->Empty());
1768 EXPECT_TRUE(GetMisconnects()->Empty());
1769
1770 // Disconnect while suspending is a non-event.
1771 SetManagerRunning(true);
1772 SetSuspending(true);
1773 NoteDisconnectEvent();
1774 EXPECT_TRUE(GetDisconnects()->Empty());
1775 EXPECT_TRUE(GetMisconnects()->Empty());
1776 }
1777
TEST_F(ServiceTest,NoteDisconnectEventDisconnectOnce)1778 TEST_F(ServiceTest, NoteDisconnectEventDisconnectOnce) {
1779 const int kNow = 5;
1780 EXPECT_FALSE(service_->explicitly_disconnected());
1781 SetStateField(Service::kStateOnline);
1782 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
1783 NoteDisconnectEvent();
1784 ASSERT_EQ(1, GetDisconnects()->Size());
1785 EXPECT_EQ(kNow, GetDisconnects()->Front().monotonic.tv_sec);
1786 EXPECT_TRUE(GetMisconnects()->Empty());
1787
1788 Mock::VerifyAndClearExpectations(&time_);
1789 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
1790 kNow + GetDisconnectsMonitorSeconds() - 1,
1791 kNow + GetDisconnectsMonitorSeconds() - 1,
1792 "")));
1793 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1794 ASSERT_EQ(1, GetDisconnects()->Size());
1795
1796 Mock::VerifyAndClearExpectations(&time_);
1797 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
1798 kNow + GetDisconnectsMonitorSeconds(),
1799 kNow + GetDisconnectsMonitorSeconds(),
1800 "")));
1801 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1802 ASSERT_TRUE(GetDisconnects()->Empty());
1803 }
1804
TEST_F(ServiceTest,NoteDisconnectEventMisconnectOnce)1805 TEST_F(ServiceTest, NoteDisconnectEventMisconnectOnce) {
1806 const int kNow = 7;
1807 EXPECT_FALSE(service_->explicitly_disconnected());
1808 SetStateField(Service::kStateConfiguring);
1809 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(kNow, kNow, "")));
1810 NoteDisconnectEvent();
1811 EXPECT_TRUE(GetDisconnects()->Empty());
1812 ASSERT_EQ(1, GetMisconnects()->Size());
1813 EXPECT_EQ(kNow, GetMisconnects()->Front().monotonic.tv_sec);
1814
1815 Mock::VerifyAndClearExpectations(&time_);
1816 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
1817 kNow + GetMisconnectsMonitorSeconds() - 1,
1818 kNow + GetMisconnectsMonitorSeconds() - 1,
1819 "")));
1820 EXPECT_TRUE(service_->HasRecentConnectionIssues());
1821 ASSERT_EQ(1, GetMisconnects()->Size());
1822
1823 Mock::VerifyAndClearExpectations(&time_);
1824 EXPECT_CALL(time_, GetNow()).Times(2).WillRepeatedly(Return(GetTimestamp(
1825 kNow + GetMisconnectsMonitorSeconds(),
1826 kNow + GetMisconnectsMonitorSeconds(),
1827 "")));
1828 EXPECT_FALSE(service_->HasRecentConnectionIssues());
1829 ASSERT_TRUE(GetMisconnects()->Empty());
1830 }
1831
TEST_F(ServiceTest,NoteDisconnectEventDiscardOld)1832 TEST_F(ServiceTest, NoteDisconnectEventDiscardOld) {
1833 EXPECT_FALSE(service_->explicitly_disconnected());
1834 for (int i = 0; i < 2; i++) {
1835 int now = 0;
1836 EventHistory* events = nullptr;
1837 if (i == 0) {
1838 SetStateField(Service::kStateConnected);
1839 now = GetDisconnectsMonitorSeconds() + 1;
1840 events = GetDisconnects();
1841 } else {
1842 SetStateField(Service::kStateAssociating);
1843 now = GetMisconnectsMonitorSeconds() + 1;
1844 events = GetMisconnects();
1845 }
1846 PushTimestamp(events, 0, 0, "");
1847 PushTimestamp(events, 0, 0, "");
1848 EXPECT_CALL(time_, GetNow()).WillOnce(Return(GetTimestamp(now, now, "")));
1849 NoteDisconnectEvent();
1850 ASSERT_EQ(1, events->Size());
1851 EXPECT_EQ(now, events->Front().monotonic.tv_sec);
1852 }
1853 }
1854
TEST_F(ServiceTest,NoteDisconnectEventDiscardExcessive)1855 TEST_F(ServiceTest, NoteDisconnectEventDiscardExcessive) {
1856 EXPECT_FALSE(service_->explicitly_disconnected());
1857 SetStateField(Service::kStateOnline);
1858 for (int i = 0; i < 2 * GetMaxDisconnectEventHistory(); i++) {
1859 PushTimestamp(GetDisconnects(), 0, 0, "");
1860 }
1861 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
1862 NoteDisconnectEvent();
1863 EXPECT_EQ(GetMaxDisconnectEventHistory(), GetDisconnects()->Size());
1864 }
1865
TEST_F(ServiceTest,NoteMisconnectEventDiscardExcessive)1866 TEST_F(ServiceTest, NoteMisconnectEventDiscardExcessive) {
1867 EXPECT_FALSE(service_->explicitly_disconnected());
1868 SetStateField(Service::kStateAssociating);
1869 for (int i = 0; i < 2 * GetMaxMisconnectEventHistory(); i++) {
1870 PushTimestamp(GetMisconnects(), 0, 0, "");
1871 }
1872 EXPECT_CALL(time_, GetNow()).WillOnce(Return(Timestamp()));
1873 NoteDisconnectEvent();
1874 EXPECT_EQ(GetMaxMisconnectEventHistory(), GetMisconnects()->Size());
1875 }
1876
TEST_F(ServiceTest,DiagnosticsProperties)1877 TEST_F(ServiceTest, DiagnosticsProperties) {
1878 const string kWallClock0 = "2012-12-09T12:41:22.234567-0800";
1879 const string kWallClock1 = "2012-12-31T23:59:59.345678-0800";
1880 Strings values;
1881
1882 PushTimestamp(GetDisconnects(), 0, 0, kWallClock0);
1883 Error unused_error;
1884 ASSERT_TRUE(service_->store().GetStringsProperty(
1885 kDiagnosticsDisconnectsProperty, &values, &unused_error));
1886 ASSERT_EQ(1, values.size());
1887 EXPECT_EQ(kWallClock0, values[0]);
1888
1889 PushTimestamp(GetMisconnects(), 0, 0, kWallClock1);
1890 ASSERT_TRUE(service_->store().GetStringsProperty(
1891 kDiagnosticsMisconnectsProperty, &values, &unused_error));
1892 ASSERT_EQ(1, values.size());
1893 EXPECT_EQ(kWallClock1, values[0]);
1894 }
1895
TEST_F(ServiceTest,SecurityLevel)1896 TEST_F(ServiceTest, SecurityLevel) {
1897 // Encrypted is better than not.
1898 service_->SetSecurity(Service::kCryptoNone, false, false);
1899 service2_->SetSecurity(Service::kCryptoRc4, false, false);
1900 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1901
1902 // AES encryption is better than RC4 encryption.
1903 service_->SetSecurity(Service::kCryptoRc4, false, false);
1904 service2_->SetSecurity(Service::kCryptoAes, false, false);
1905 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1906
1907 // Crypto algorithm is more important than key rotation.
1908 service_->SetSecurity(Service::kCryptoNone, true, false);
1909 service2_->SetSecurity(Service::kCryptoAes, false, false);
1910 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1911
1912 // Encrypted-but-unauthenticated is better than clear-but-authenticated.
1913 service_->SetSecurity(Service::kCryptoNone, false, true);
1914 service2_->SetSecurity(Service::kCryptoAes, false, false);
1915 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1916
1917 // For same encryption, prefer key rotation.
1918 service_->SetSecurity(Service::kCryptoRc4, false, false);
1919 service2_->SetSecurity(Service::kCryptoRc4, true, false);
1920 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1921
1922 // For same encryption, prefer authenticated AP.
1923 service_->SetSecurity(Service::kCryptoRc4, false, false);
1924 service2_->SetSecurity(Service::kCryptoRc4, false, true);
1925 EXPECT_GT(service2_->SecurityLevel(), service_->SecurityLevel());
1926 }
1927
TEST_F(ServiceTest,SetErrorDetails)1928 TEST_F(ServiceTest, SetErrorDetails) {
1929 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1930 static const char kDetails[] = "Certificate revoked.";
1931 ServiceMockAdaptor* adaptor = GetAdaptor();
1932 EXPECT_CALL(*adaptor, EmitStringChanged(kErrorDetailsProperty, kDetails));
1933 service_->SetErrorDetails(Service::kErrorDetailsNone);
1934 EXPECT_EQ(Service::kErrorDetailsNone, service_->error_details());
1935 service_->SetErrorDetails(kDetails);
1936 EXPECT_EQ(kDetails, service_->error_details());
1937 service_->SetErrorDetails(kDetails);
1938 }
1939
TEST_F(ServiceTest,SetAutoConnectFull)1940 TEST_F(ServiceTest, SetAutoConnectFull) {
1941 EXPECT_FALSE(service_->auto_connect());
1942 Error error;
1943 EXPECT_FALSE(GetAutoConnect(&error));
1944 EXPECT_TRUE(error.IsSuccess());
1945
1946 // false -> false
1947 EXPECT_FALSE(service_->retain_auto_connect());
1948 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
1949 SetAutoConnectFull(false, &error);
1950 EXPECT_TRUE(error.IsSuccess());
1951 EXPECT_FALSE(service_->auto_connect());
1952 EXPECT_TRUE(service_->retain_auto_connect());
1953 EXPECT_FALSE(GetAutoConnect(nullptr));
1954 Mock::VerifyAndClearExpectations(&mock_manager_);
1955
1956 // Clear the |retain_auto_connect_| flag for the next test.
1957 service_->Unload();
1958 ASSERT_FALSE(service_->retain_auto_connect());
1959
1960 // false -> true
1961 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
1962 SetAutoConnectFull(true, &error);
1963 EXPECT_TRUE(error.IsSuccess());
1964 EXPECT_TRUE(service_->auto_connect());
1965 EXPECT_TRUE(GetAutoConnect(nullptr));
1966 EXPECT_TRUE(service_->retain_auto_connect());
1967 Mock::VerifyAndClearExpectations(&mock_manager_);
1968
1969 // Clear the |retain_auto_connect_| flag for the next test.
1970 service_->Unload();
1971 ASSERT_FALSE(service_->retain_auto_connect());
1972
1973 // true -> true
1974 service_->SetAutoConnect(true);
1975 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
1976 SetAutoConnectFull(true, &error);
1977 EXPECT_TRUE(error.IsSuccess());
1978 EXPECT_TRUE(service_->auto_connect());
1979 EXPECT_TRUE(GetAutoConnect(nullptr));
1980 EXPECT_TRUE(service_->retain_auto_connect());
1981 Mock::VerifyAndClearExpectations(&mock_manager_);
1982
1983 // Clear the |retain_auto_connect_| flag for the next test.
1984 service_->Unload();
1985 ASSERT_FALSE(service_->retain_auto_connect());
1986
1987 // true -> false
1988 service_->SetAutoConnect(true);
1989 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
1990 SetAutoConnectFull(false, &error);
1991 EXPECT_TRUE(error.IsSuccess());
1992 EXPECT_FALSE(service_->auto_connect());
1993 EXPECT_FALSE(GetAutoConnect(nullptr));
1994 EXPECT_TRUE(service_->retain_auto_connect());
1995 Mock::VerifyAndClearExpectations(&mock_manager_);
1996 }
1997
TEST_F(ServiceTest,SetAutoConnectFullUserUpdatePersists)1998 TEST_F(ServiceTest, SetAutoConnectFullUserUpdatePersists) {
1999 // If the user sets the kAutoConnectProperty explicitly, the preference must
2000 // be persisted, even if the property was not changed.
2001 Error error;
2002 MockProfileRefPtr mock_profile(
2003 new MockProfile(control_interface(), metrics(), &mock_manager_));
2004 NiceMock<MockStore> storage;
2005 service_->set_profile(mock_profile);
2006 service_->SetAutoConnect(true);
2007
2008 EXPECT_CALL(*mock_profile, UpdateService(_));
2009 EXPECT_CALL(*mock_profile, GetConstStorage())
2010 .WillOnce(Return(&storage));
2011 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service_)))
2012 .WillOnce(Return(false));
2013 EXPECT_FALSE(service_->retain_auto_connect());
2014 SetAutoConnectFull(true, &error);
2015 EXPECT_TRUE(error.IsSuccess());
2016 EXPECT_TRUE(service_->auto_connect());
2017 EXPECT_TRUE(service_->retain_auto_connect());
2018 }
2019
TEST_F(ServiceTest,ClearAutoConnect)2020 TEST_F(ServiceTest, ClearAutoConnect) {
2021 EXPECT_FALSE(service_->auto_connect());
2022 Error error;
2023 EXPECT_FALSE(GetAutoConnect(&error));
2024 EXPECT_TRUE(error.IsSuccess());
2025
2026 // unset -> false
2027 EXPECT_FALSE(service_->retain_auto_connect());
2028 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2029 ClearAutoConnect(&error);
2030 EXPECT_TRUE(error.IsSuccess());
2031 EXPECT_FALSE(service_->retain_auto_connect());
2032 EXPECT_FALSE(GetAutoConnect(nullptr));
2033 Mock::VerifyAndClearExpectations(&mock_manager_);
2034
2035 // false -> false
2036 SetAutoConnectFull(false, &error);
2037 EXPECT_FALSE(GetAutoConnect(nullptr));
2038 EXPECT_TRUE(service_->retain_auto_connect());
2039 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2040 ClearAutoConnect(&error);
2041 EXPECT_TRUE(error.IsSuccess());
2042 EXPECT_FALSE(service_->retain_auto_connect());
2043 EXPECT_FALSE(GetAutoConnect(nullptr));
2044 Mock::VerifyAndClearExpectations(&mock_manager_);
2045
2046 // true -> false
2047 SetAutoConnectFull(true, &error);
2048 EXPECT_TRUE(error.IsSuccess());
2049 EXPECT_TRUE(GetAutoConnect(nullptr));
2050 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(1);
2051 ClearAutoConnect(&error);
2052 EXPECT_FALSE(service_->retain_auto_connect());
2053 EXPECT_FALSE(GetAutoConnect(nullptr));
2054 Mock::VerifyAndClearExpectations(&mock_manager_);
2055 }
2056
TEST_F(ServiceTest,UniqueAttributes)2057 TEST_F(ServiceTest, UniqueAttributes) {
2058 EXPECT_NE(service_->serial_number_, service2_->serial_number_);
2059 EXPECT_NE(service_->unique_name(), service2_->unique_name());
2060 }
2061
TEST_F(ServiceTest,PropertyChanges)2062 TEST_F(ServiceTest, PropertyChanges) {
2063 TestCommonPropertyChanges(service_, GetAdaptor());
2064 TestAutoConnectPropertyChange(service_, GetAdaptor());
2065 }
2066
2067 // Custom property setters should return false, and make no changes, if
2068 // the new value is the same as the old value.
TEST_F(ServiceTest,CustomSetterNoopChange)2069 TEST_F(ServiceTest, CustomSetterNoopChange) {
2070 TestCustomSetterNoopChange(service_, &mock_manager_);
2071 }
2072
TEST_F(ServiceTest,GetTethering)2073 TEST_F(ServiceTest, GetTethering) {
2074 Error error;
2075 EXPECT_EQ("", service_->GetTethering(&error));
2076 EXPECT_EQ(Error::kNotSupported, error.type());
2077 }
2078
2079 class ServiceWithMockOnPropertyChanged : public ServiceUnderTest {
2080 public:
ServiceWithMockOnPropertyChanged(ControlInterface * control_interface,EventDispatcher * dispatcher,Metrics * metrics,Manager * manager)2081 ServiceWithMockOnPropertyChanged(ControlInterface* control_interface,
2082 EventDispatcher* dispatcher,
2083 Metrics* metrics,
2084 Manager* manager)
2085 : ServiceUnderTest(control_interface, dispatcher, metrics, manager) {}
2086 MOCK_METHOD1(OnPropertyChanged, void(const string& property));
2087 };
2088
TEST_F(ServiceTest,ConfigureServiceTriggersOnPropertyChanged)2089 TEST_F(ServiceTest, ConfigureServiceTriggersOnPropertyChanged) {
2090 auto service(make_scoped_refptr(
2091 new ServiceWithMockOnPropertyChanged(control_interface(),
2092 dispatcher(),
2093 metrics(),
2094 &mock_manager_)));
2095 KeyValueStore args;
2096 args.SetString(kUIDataProperty, "terpsichorean ejectamenta");
2097 args.SetBool(kSaveCredentialsProperty, false);
2098
2099 // Calling Configure with different values from before triggers a single
2100 // OnPropertyChanged call per property.
2101 EXPECT_CALL(*service, OnPropertyChanged(kUIDataProperty)).Times(1);
2102 EXPECT_CALL(*service, OnPropertyChanged(kSaveCredentialsProperty)).Times(1);
2103 {
2104 Error error;
2105 service->Configure(args, &error);
2106 EXPECT_TRUE(error.IsSuccess());
2107 }
2108 Mock::VerifyAndClearExpectations(service.get());
2109
2110 // Calling Configure with the same values as before should not trigger
2111 // OnPropertyChanged().
2112 EXPECT_CALL(*service, OnPropertyChanged(_)).Times(0);
2113 {
2114 Error error;
2115 service->Configure(args, &error);
2116 EXPECT_TRUE(error.IsSuccess());
2117 }
2118 }
2119
TEST_F(ServiceTest,ClearExplicitlyDisconnected)2120 TEST_F(ServiceTest, ClearExplicitlyDisconnected) {
2121 EXPECT_FALSE(GetExplicitlyDisconnected());
2122 EXPECT_CALL(mock_manager_, UpdateService(_)).Times(0);
2123 service_->ClearExplicitlyDisconnected();
2124 Mock::VerifyAndClearExpectations(&mock_manager_);
2125
2126 SetExplicitlyDisconnected(true);
2127 EXPECT_CALL(mock_manager_, UpdateService(IsRefPtrTo(service_)));
2128 service_->ClearExplicitlyDisconnected();
2129 Mock::VerifyAndClearExpectations(&mock_manager_);
2130 EXPECT_FALSE(GetExplicitlyDisconnected());
2131 }
2132
TEST_F(ServiceTest,Compare)2133 TEST_F(ServiceTest, Compare) {
2134 // Construct our Services so that the string comparison of
2135 // unique_name_ differs from the numerical comparison of
2136 // serial_number_.
2137 vector<scoped_refptr<MockService>> mock_services;
2138 for (size_t i = 0; i < 11; ++i) {
2139 mock_services.push_back(
2140 new NiceMock<MockService>(control_interface(),
2141 dispatcher(),
2142 metrics(),
2143 manager()));
2144 }
2145 scoped_refptr<MockService> service2 = mock_services[2];
2146 scoped_refptr<MockService> service10 = mock_services[10];
2147 mock_services.clear();
2148
2149 // Services should already be sorted by |serial_number_|.
2150 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2151
2152 // Two otherwise equal services should be reordered by strength
2153 service10->SetStrength(1);
2154 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2155
2156 scoped_refptr<MockProfile> profile2(
2157 new MockProfile(control_interface(), metrics(), manager(), ""));
2158 scoped_refptr<MockProfile> profile10(
2159 new MockProfile(control_interface(), metrics(), manager(), ""));
2160
2161 service2->set_profile(profile2);
2162 service10->set_profile(profile10);
2163
2164 // When comparing two services with different profiles, prefer the one
2165 // that is not ephemeral.
2166 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service2)))
2167 .WillRepeatedly(Return(false));
2168 EXPECT_CALL(mock_manager_, IsServiceEphemeral(IsRefPtrTo(service10)))
2169 .WillRepeatedly(Return(true));
2170 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2171 Mock::VerifyAndClearExpectations(&mock_manager_);
2172
2173 // Prefer the service with the more recently applied profile if neither
2174 // service is ephemeral.
2175 EXPECT_CALL(mock_manager_, IsServiceEphemeral(_))
2176 .WillRepeatedly(Return(false));
2177 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile2),
2178 IsRefPtrTo(profile10)))
2179 .WillRepeatedly(Return(true));
2180 EXPECT_CALL(mock_manager_, IsProfileBefore(IsRefPtrTo(profile10),
2181 IsRefPtrTo(profile2)))
2182 .WillRepeatedly(Return(false));
2183 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2184
2185 // Security.
2186 service2->SetSecurity(Service::kCryptoAes, true, true);
2187 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2188
2189 // PriorityWithinTechnology.
2190 service10->SetPriorityWithinTechnology(1, nullptr);
2191 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2192 service2->SetPriorityWithinTechnology(2, nullptr);
2193 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2194
2195 // Technology.
2196 EXPECT_CALL(*service2.get(), technology())
2197 .WillRepeatedly(Return((Technology::kWifi)));
2198 EXPECT_CALL(*service10.get(), technology())
2199 .WillRepeatedly(Return(Technology::kEthernet));
2200
2201 technology_order_for_sorting_ = {Technology::kEthernet, Technology::kWifi};
2202 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2203
2204 technology_order_for_sorting_ = {Technology::kWifi, Technology::kEthernet};
2205 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2206
2207 // Priority.
2208 service2->SetPriority(1, nullptr);
2209 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2210 service10->SetPriority(2, nullptr);
2211 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2212
2213 // A service that has been connected before should be considered
2214 // above a service that neither been connected to before nor has
2215 // has managed credentials.
2216 service2->has_ever_connected_ = true;
2217 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2218
2219 // If one service has been connected to before, and the other is managed
2220 // by Chrome they should rank same, so the priority will be considered
2221 // instead.
2222 service10->managed_credentials_ = true;
2223 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2224 service2->SetPriority(3, nullptr);
2225 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2226
2227 // A service with managed credentials should be considered above one that
2228 // has neither been connected to before nor has managed credentials.
2229 service2->has_ever_connected_ = false;
2230 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2231
2232 // Auto-connect.
2233 service2->SetAutoConnect(true);
2234 service10->SetAutoConnect(false);
2235 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2236
2237 // Test is-dependent-on.
2238 EXPECT_CALL(*service10.get(),
2239 IsDependentOn(IsRefPtrTo(service2.get())))
2240 .WillOnce(Return(true))
2241 .WillOnce(Return(false));
2242 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2243 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2244
2245 // It doesn't make sense to have is-dependent-on ranking comparison in any of
2246 // the remaining subtests below. Reset to the default.
2247 EXPECT_CALL(*service10.get(), IsDependentOn(_)).WillRepeatedly(Return(false));
2248 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2249
2250 // Connectable.
2251 service10->SetConnectable(true);
2252 service2->SetConnectable(false);
2253 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2254
2255 // IsFailed.
2256 EXPECT_CALL(*service2.get(), state())
2257 .WillRepeatedly(Return(Service::kStateIdle));
2258 EXPECT_CALL(*service2.get(), IsFailed())
2259 .WillRepeatedly(Return(false));
2260 EXPECT_CALL(*service10.get(), state())
2261 .WillRepeatedly(Return(Service::kStateFailure));
2262 EXPECT_CALL(*service10.get(), IsFailed())
2263 .WillRepeatedly(Return(true));
2264 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2265
2266 // Connecting.
2267 EXPECT_CALL(*service10.get(), state())
2268 .WillRepeatedly(Return(Service::kStateAssociating));
2269 EXPECT_CALL(*service10.get(), IsConnecting())
2270 .WillRepeatedly(Return(true));
2271 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2272
2273 // Connected-but-portalled preferred over unconnected.
2274 EXPECT_CALL(*service2.get(), state())
2275 .WillRepeatedly(Return(Service::kStatePortal));
2276 EXPECT_CALL(*service2.get(), IsConnected())
2277 .WillRepeatedly(Return(true));
2278 EXPECT_TRUE(DefaultSortingOrderIs(service2, service10));
2279
2280 // Connected preferred over connected-but-portalled.
2281 service10->SetConnectable(false);
2282 service2->SetConnectable(true);
2283 EXPECT_CALL(*service10.get(), state())
2284 .WillRepeatedly(Return(Service::kStateConnected));
2285 EXPECT_CALL(*service10.get(), IsConnected())
2286 .WillRepeatedly(Return(true));
2287 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2288
2289 // Online preferred over just connected.
2290 EXPECT_CALL(*service2.get(), state())
2291 .WillRepeatedly(Return(Service::kStateOnline));
2292 EXPECT_TRUE(DefaultSortingOrderIs(service10, service2));
2293
2294 // Connectivity state ignored if this is specified.
2295 const bool kDoNotCompareConnectivityState = false;
2296 EXPECT_TRUE(SortingOrderIs(service2, service10,
2297 kDoNotCompareConnectivityState));
2298 }
2299
2300 } // namespace shill
2301