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