1 //
2 // Copyright (C) 2012 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/wifi/wifi_service.h"
18
19 #include <limits>
20 #include <map>
21 #include <set>
22 #include <string>
23 #include <vector>
24
25 #include <base/strings/stringprintf.h>
26 #include <base/strings/string_number_conversions.h>
27 #include <base/strings/string_util.h>
28 #if defined(__ANDROID__)
29 #include <dbus/service_constants.h>
30 #else
31 #include <chromeos/dbus/service_constants.h>
32 #endif // __ANDROID__
33 #include <gmock/gmock.h>
34 #include <gtest/gtest.h>
35
36 #include "shill/event_dispatcher.h"
37 #include "shill/manager.h"
38 #include "shill/metrics.h"
39 #include "shill/mock_adaptors.h"
40 #include "shill/mock_certificate_file.h"
41 #include "shill/mock_control.h"
42 #include "shill/mock_eap_credentials.h"
43 #include "shill/mock_log.h"
44 #include "shill/mock_manager.h"
45 #include "shill/mock_profile.h"
46 #include "shill/mock_service.h"
47 #include "shill/mock_store.h"
48 #include "shill/property_store_unittest.h"
49 #include "shill/refptr_types.h"
50 #include "shill/service_property_change_test.h"
51 #include "shill/supplicant/wpa_supplicant.h"
52 #include "shill/technology.h"
53 #include "shill/tethering.h"
54 #include "shill/wifi/mock_wifi.h"
55 #include "shill/wifi/mock_wifi_provider.h"
56 #include "shill/wifi/wifi_endpoint.h"
57
58 using base::FilePath;
59 using std::map;
60 using std::set;
61 using std::string;
62 using std::vector;
63 using ::testing::_;
64 using ::testing::AnyNumber;
65 using ::testing::DoAll;
66 using ::testing::EndsWith;
67 using ::testing::HasSubstr;
68 using ::testing::Mock;
69 using ::testing::NiceMock;
70 using ::testing::Return;
71 using ::testing::ReturnRef;
72 using ::testing::SetArgumentPointee;
73 using ::testing::StrEq;
74 using ::testing::StrNe;
75 using ::testing::StrictMock;
76
77 namespace shill {
78
79 class WiFiServiceTest : public PropertyStoreTest {
80 public:
WiFiServiceTest()81 WiFiServiceTest()
82 : mock_manager_(control_interface(), dispatcher(), metrics()),
83 wifi_(
84 new NiceMock<MockWiFi>(control_interface(),
85 dispatcher(),
86 metrics(),
87 manager(),
88 "wifi",
89 fake_mac,
90 0)),
91 simple_ssid_(1, 'a'),
92 simple_ssid_string_("a") {}
~WiFiServiceTest()93 virtual ~WiFiServiceTest() {}
94
95 protected:
96 static const char fake_mac[];
97
SetMockEap(const WiFiServiceRefPtr & service)98 MockEapCredentials* SetMockEap(
99 const WiFiServiceRefPtr& service) {
100 MockEapCredentials* eap = new MockEapCredentials();
101 service->eap_.reset(eap); // Passes ownership.
102 return eap;
103 }
CheckConnectable(const string & security,const char * passphrase,bool is_1x_connectable)104 bool CheckConnectable(const string& security, const char* passphrase,
105 bool is_1x_connectable) {
106 Error error;
107 WiFiServiceRefPtr service = MakeSimpleService(security);
108 if (passphrase)
109 service->SetPassphrase(passphrase, &error);
110 MockEapCredentials* eap = SetMockEap(service);
111 EXPECT_CALL(*eap, IsConnectable())
112 .WillRepeatedly(Return(is_1x_connectable));
113 const string kKeyManagement8021x(WPASupplicant::kKeyManagementIeee8021X);
114 if (security == kSecurityWep && is_1x_connectable) {
115 EXPECT_CALL(*eap, key_management())
116 .WillRepeatedly(ReturnRef(kKeyManagement8021x));
117 }
118 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
119 return service->connectable();
120 }
MakeEndpoint(const string & ssid,const string & bssid,uint16_t frequency,int16_t signal_dbm,bool has_wpa_property,bool has_rsn_property)121 WiFiEndpoint* MakeEndpoint(const string& ssid, const string& bssid,
122 uint16_t frequency, int16_t signal_dbm,
123 bool has_wpa_property, bool has_rsn_property) {
124 return WiFiEndpoint::MakeEndpoint(
125 nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
126 frequency, signal_dbm, has_wpa_property, has_rsn_property);
127 }
MakeOpenEndpoint(const string & ssid,const string & bssid,uint16_t frequency,int16_t signal_dbm)128 WiFiEndpoint* MakeOpenEndpoint(const string& ssid, const string& bssid,
129 uint16_t frequency, int16_t signal_dbm) {
130 return WiFiEndpoint::MakeOpenEndpoint(
131 nullptr, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
132 frequency, signal_dbm);
133 }
MakeOpenEndpointWithWiFi(WiFiRefPtr wifi,const string & ssid,const string & bssid,uint16_t frequency,int16_t signal_dbm)134 WiFiEndpoint* MakeOpenEndpointWithWiFi(WiFiRefPtr wifi,
135 const string& ssid,
136 const string& bssid,
137 uint16_t frequency,
138 int16_t signal_dbm) {
139 return WiFiEndpoint::MakeOpenEndpoint(
140 nullptr, wifi, ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
141 frequency, signal_dbm);
142 }
MakeSimpleService(const string & security)143 WiFiServiceRefPtr MakeSimpleService(const string& security) {
144 return new WiFiService(control_interface(),
145 dispatcher(),
146 metrics(),
147 manager(),
148 &provider_,
149 simple_ssid_,
150 kModeManaged,
151 security,
152 false);
153 }
MakeGenericService()154 WiFiServiceRefPtr MakeGenericService() {
155 return MakeSimpleService(kSecurityWep);
156 }
SetWiFi(WiFiServiceRefPtr service,WiFiRefPtr wifi)157 void SetWiFi(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
158 service->SetWiFi(wifi); // Has side-effects.
159 }
SetWiFiForService(WiFiServiceRefPtr service,WiFiRefPtr wifi)160 void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
161 service->wifi_ = wifi;
162 }
MakeServiceWithWiFi(const string & security)163 WiFiServiceRefPtr MakeServiceWithWiFi(const string& security) {
164 WiFiServiceRefPtr service = MakeSimpleService(security);
165 SetWiFiForService(service, wifi_);
166 return service;
167 }
MakeServiceWithMockManager()168 WiFiServiceRefPtr MakeServiceWithMockManager() {
169 return new WiFiService(control_interface(),
170 dispatcher(),
171 metrics(),
172 &mock_manager_,
173 &provider_,
174 simple_ssid_,
175 kModeManaged,
176 kSecurityNone,
177 false);
178 }
MakeSimpleWiFi(const string & link_name)179 scoped_refptr<MockWiFi> MakeSimpleWiFi(const string& link_name) {
180 return new NiceMock<MockWiFi>(control_interface(),
181 dispatcher(),
182 metrics(),
183 manager(),
184 link_name,
185 fake_mac,
186 0);
187 }
GetAdaptor(WiFiService * service)188 ServiceMockAdaptor* GetAdaptor(WiFiService* service) {
189 return static_cast<ServiceMockAdaptor*>(service->adaptor());
190 }
TestConfigurePassphrase(const string & security,const char * passphrase)191 Error::Type TestConfigurePassphrase(const string& security,
192 const char* passphrase) {
193 WiFiServiceRefPtr service = MakeSimpleService(security);
194 KeyValueStore args;
195 if (passphrase) {
196 args.SetString(kPassphraseProperty, passphrase);
197 }
198 Error error;
199 service->Configure(args, &error);
200 return error.type();
201 }
SetRoamThreshold(WiFiServiceRefPtr service,uint16_t threshold)202 bool SetRoamThreshold(WiFiServiceRefPtr service, uint16_t threshold) {
203 return service->SetRoamThreshold(threshold, nullptr);
204 }
GetRoamThreshold(WiFiServiceRefPtr service) const205 uint16_t GetRoamThreshold(WiFiServiceRefPtr service) const {
206 return service->GetRoamThreshold(nullptr);
207 }
wifi()208 scoped_refptr<MockWiFi> wifi() { return wifi_; }
mock_manager()209 MockManager* mock_manager() { return &mock_manager_; }
provider()210 MockWiFiProvider* provider() { return &provider_; }
GetAnyDeviceAddress()211 string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
simple_ssid()212 const vector<uint8_t>& simple_ssid() { return simple_ssid_; }
simple_ssid_string()213 const string& simple_ssid_string() { return simple_ssid_string_; }
214
215 private:
216 MockManager mock_manager_;
217 scoped_refptr<MockWiFi> wifi_;
218 MockWiFiProvider provider_;
219 const vector<uint8_t> simple_ssid_;
220 const string simple_ssid_string_;
221 };
222
223 // static
224 const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
225
226 MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
227 string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
228 return
229 arg.ContainsString(WiFiService::kStorageType) &&
230 arg.GetString(WiFiService::kStorageType) == kTypeWifi &&
231 arg.ContainsString(WiFiService::kStorageSSID) &&
232 arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
233 arg.ContainsString(WiFiService::kStorageMode) &&
234 arg.GetString(WiFiService::kStorageMode) == mode &&
235 arg.ContainsString(WiFiService::kStorageSecurityClass) &&
236 arg.GetString(WiFiService::kStorageSecurityClass) == security;
237 }
238
239 class WiFiServiceSecurityTest : public WiFiServiceTest {
240 public:
TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,const string & security)241 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
242 const string& security) {
243 string id = wifi_service->GetStorageIdentifier();
244 size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress()));
245 EXPECT_NE(mac_pos, string::npos);
246 size_t mode_pos = id.find(string(kModeManaged), mac_pos);
247 EXPECT_NE(mode_pos, string::npos);
248 return id.find(string(security), mode_pos) != string::npos;
249 }
250
251 // Test that a service that is created with security |from_security|
252 // gets by default a storage identifier with |to_security| as its
253 // security component, and that when saved, it sets the Security
254 // property in to |to_security| as well.
TestStorageMapping(const string & from_security,const string & to_security)255 bool TestStorageMapping(const string& from_security,
256 const string& to_security) {
257 WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
258 NiceMock<MockStore> mock_store;
259 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
260 EXPECT_CALL(mock_store,
261 SetString(_, WiFiService::kStorageSecurity, from_security))
262 .Times(1);
263 EXPECT_CALL(mock_store,
264 SetString(_, WiFiService::kStorageSecurityClass, to_security))
265 .Times(1);
266 wifi_service->Save(&mock_store);
267 return TestStorageSecurityIs(wifi_service, to_security);
268 }
269
270 // Test whether a service of type |service_security| can load from a
271 // storage interface containing an entry for |storage_security|.
272 // Make sure the result meets |expectation|. If |expectation| is
273 // true, also make sure the service storage identifier changes to
274 // match |storage_security|.
TestLoadMapping(const string & service_security,const string & storage_security,bool expectation)275 bool TestLoadMapping(const string& service_security,
276 const string& storage_security,
277 bool expectation) {
278 WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
279 NiceMock<MockStore> mock_store;
280 EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
281 .WillRepeatedly(Return(set<string>()));
282 const string kStorageId = "storage_id";
283 EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
284 .WillRepeatedly(Return(true));
285 set<string> groups;
286 groups.insert(kStorageId);
287 EXPECT_CALL(mock_store, GetGroupsWithProperties(
288 ContainsWiFiProperties(wifi_service->ssid(),
289 kModeManaged,
290 storage_security)))
291 .WillRepeatedly(Return(groups));
292 bool is_loadable = wifi_service->IsLoadableFrom(mock_store);
293 EXPECT_EQ(expectation, is_loadable);
294 bool is_loaded = wifi_service->Load(&mock_store);
295 EXPECT_EQ(expectation, is_loaded);
296 const string expected_identifier(expectation ? kStorageId : "");
297 EXPECT_EQ(expected_identifier,
298 wifi_service->GetLoadableStorageIdentifier(mock_store));
299
300 if (expectation != is_loadable || expectation != is_loaded) {
301 return false;
302 } else if (!expectation) {
303 return true;
304 } else {
305 return wifi_service->GetStorageIdentifier() == kStorageId;
306 }
307 }
308 };
309
310 class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
311 public:
WiFiServiceUpdateFromEndpointsTest()312 WiFiServiceUpdateFromEndpointsTest()
313 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
314 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
315 kGoodEndpointStrength(
316 WiFiService::SignalToStrength(kGoodEndpointSignal)),
317 service(MakeGenericService()),
318 adaptor(*GetAdaptor(service.get())) {
319 ok_endpoint = MakeOpenEndpoint(
320 simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
321 kOkEndpointSignal);
322 good_endpoint = MakeOpenEndpoint(
323 simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
324 kGoodEndpointSignal);
325 bad_endpoint = MakeOpenEndpoint(
326 simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
327 kBadEndpointSignal);
328 }
329
330 protected:
331 static const uint16_t kOkEndpointFrequency = 2422;
332 static const uint16_t kBadEndpointFrequency = 2417;
333 static const uint16_t kGoodEndpointFrequency = 2412;
334 static const int16_t kOkEndpointSignal = -50;
335 static const int16_t kBadEndpointSignal = -75;
336 static const int16_t kGoodEndpointSignal = -25;
337 static const char* kOkEndpointBssId;
338 static const char* kGoodEndpointBssId;
339 static const char* kBadEndpointBssId;
340 // Can't be both static and const (because initialization requires a
341 // function call). So choose to be just const.
342 const uint8_t kOkEndpointStrength;
343 const uint8_t kBadEndpointStrength;
344 const uint8_t kGoodEndpointStrength;
345 WiFiEndpointRefPtr ok_endpoint;
346 WiFiEndpointRefPtr bad_endpoint;
347 WiFiEndpointRefPtr good_endpoint;
348 WiFiServiceRefPtr service;
349 ServiceMockAdaptor& adaptor;
350 };
351
352 const char* WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
353 "00:00:00:00:00:01";
354 const char* WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
355 "00:00:00:00:00:02";
356 const char* WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
357 "00:00:00:00:00:03";
358
359 class WiFiServiceFixupStorageTest : public WiFiServiceTest {
360 protected:
AddGroup(string group_name)361 void AddGroup(string group_name) {
362 groups_.insert(group_name);
363 }
364
AddServiceEntry(bool has_type,bool has_mode,bool has_security,bool has_security_class)365 void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
366 bool has_security_class) {
367 int index = groups_.size();
368 string id = base::StringPrintf("%s_%d_%d_%s_%s", kTypeWifi,
369 index, index, kModeManaged,
370 kSecurityWpa);
371 AddGroup(id);
372 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
373 .WillOnce(Return(has_type));
374 if (!has_type) {
375 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
376 kTypeWifi));
377 }
378 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
379 .WillOnce(Return(has_mode));
380 if (!has_mode) {
381 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
382 kModeManaged));
383 }
384 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
385 .WillOnce(Return(has_security));
386 if (!has_security) {
387 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
388 kSecurityWpa));
389 }
390 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
391 .WillOnce(Return(has_security_class));
392 if (!has_security_class) {
393 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
394 kSecurityPsk));
395 }
396 }
397
FixupServiceEntries()398 bool FixupServiceEntries() {
399 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
400 return WiFiService::FixupServiceEntries(&store_);
401 }
402
403 private:
404 StrictMock<MockStore> store_;
405 set<string> groups_;
406 };
407
TEST_F(WiFiServiceTest,Constructor)408 TEST_F(WiFiServiceTest, Constructor) {
409 string histogram = metrics()->GetFullMetricName(
410 Metrics::kMetricTimeToJoinMillisecondsSuffix, Technology::kWifi);
411 EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer(_, _, _, _))
412 .Times(AnyNumber());
413 EXPECT_CALL(*metrics(), AddServiceStateTransitionTimer(
414 _, histogram, Service::kStateAssociating, Service::kStateConfiguring));
415 MakeSimpleService(kSecurityNone);
416 }
417
TEST_F(WiFiServiceTest,StorageId)418 TEST_F(WiFiServiceTest, StorageId) {
419 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone);
420 string id = wifi_service->GetStorageIdentifier();
421 for (uint i = 0; i < id.length(); ++i) {
422 EXPECT_TRUE(id[i] == '_' ||
423 isxdigit(id[i]) ||
424 (isalpha(id[i]) && islower(id[i])));
425 }
426 size_t mac_pos = id.find(base::ToLowerASCII(GetAnyDeviceAddress()));
427 EXPECT_NE(mac_pos, string::npos);
428 EXPECT_NE(id.find(string(kModeManaged), mac_pos), string::npos);
429 }
430
431 // Make sure the passphrase is registered as a write only property
432 // by reading and comparing all string properties returned on the store.
TEST_F(WiFiServiceTest,PassphraseWriteOnly)433 TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
434 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWpa);
435 ReadablePropertyConstIterator<string> it =
436 (wifi_service->store()).GetStringPropertiesIter();
437 for ( ; !it.AtEnd(); it.Advance())
438 EXPECT_NE(it.Key(), kPassphraseProperty);
439 }
440
441 // Make sure setting the passphrase via D-Bus Service.SetProperty validates
442 // the passphrase.
TEST_F(WiFiServiceTest,PassphraseSetPropertyValidation)443 TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
444 // We only spot check two password cases here to make sure the
445 // SetProperty code path does validation. We're not going to exhaustively
446 // test for all types of passwords.
447 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep);
448 Error error;
449 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
450 kPassphraseProperty, "0:abcde", &error));
451 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
452 kPassphraseProperty, "invalid", &error));
453 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
454 }
455
TEST_F(WiFiServiceTest,PassphraseSetPropertyOpenNetwork)456 TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
457 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityNone);
458 Error error;
459 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
460 kPassphraseProperty, "invalid", &error));
461 EXPECT_EQ(Error::kNotSupported, error.type());
462 }
463
TEST_F(WiFiServiceTest,NonUTF8SSID)464 TEST_F(WiFiServiceTest, NonUTF8SSID) {
465 vector<uint8_t> ssid;
466
467 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
468 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
469 dispatcher(),
470 metrics(),
471 manager(),
472 provider(),
473 ssid,
474 kModeManaged,
475 kSecurityNone,
476 false);
477 brillo::VariantDictionary properties;
478 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
479 EXPECT_TRUE(wifi_service->store().GetProperties(&properties, nullptr));
480 }
481
482 MATCHER(PSKSecurityArgs, "") {
483 return arg.ContainsString(WPASupplicant::kPropertySecurityProtocol) &&
484 arg.GetString(WPASupplicant::kPropertySecurityProtocol) ==
485 string("WPA RSN") &&
486 arg.ContainsString(WPASupplicant::kPropertyPreSharedKey);
487 }
488
489 MATCHER_P(FrequencyArg, has_arg, "") {
490 return has_arg ==
491 arg.ContainsInt(WPASupplicant::kNetworkPropertyFrequency);
492 }
493
TEST_F(WiFiServiceTest,ConnectReportBSSes)494 TEST_F(WiFiServiceTest, ConnectReportBSSes) {
495 WiFiEndpointRefPtr endpoint1 =
496 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
497 WiFiEndpointRefPtr endpoint2 =
498 MakeOpenEndpoint("a", "00:00:00:00:00:02", 0, 0);
499 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
500 wifi_service->AddEndpoint(endpoint1);
501 wifi_service->AddEndpoint(endpoint2);
502 EXPECT_CALL(*metrics(), NotifyWifiAvailableBSSes(2));
503 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
504 wifi_service->Connect(nullptr, "in test");
505 }
506
TEST_F(WiFiServiceTest,ConnectWithPreferredDevice)507 TEST_F(WiFiServiceTest, ConnectWithPreferredDevice) {
508 // Setup service, device, and endpoints.
509 WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager();
510 const string kDeviceName1 = "test_device1";
511 const string kDeviceName2 = "test_device2";
512 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
513 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
514 WiFiEndpointRefPtr endpoint1 =
515 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0, 0);
516 WiFiEndpointRefPtr endpoint2 =
517 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0, 0);
518
519 wifi_service->SetPreferredDevice(kDeviceName1, nullptr);
520 wifi_service->AddEndpoint(endpoint1);
521 wifi_service->AddEndpoint(endpoint2);
522 EXPECT_EQ(wifi1, wifi_service->wifi_);
523
524 EXPECT_CALL(*wifi1, ConnectTo(wifi_service.get()));
525 EXPECT_CALL(*wifi2, ConnectTo(_)).Times(0);
526 wifi_service->Connect(nullptr, "in test");
527 }
528
TEST_F(WiFiServiceTest,ConnectTaskWPA)529 TEST_F(WiFiServiceTest, ConnectTaskWPA) {
530 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWpa);
531 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
532 Error error;
533 wifi_service->SetPassphrase("0:mumblemumblem", &error);
534 wifi_service->Connect(nullptr, "in test");
535 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
536 PSKSecurityArgs());
537 }
538
TEST_F(WiFiServiceTest,ConnectTaskRSN)539 TEST_F(WiFiServiceTest, ConnectTaskRSN) {
540 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
541 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
542 Error error;
543 wifi_service->SetPassphrase("0:mumblemumblem", &error);
544 wifi_service->Connect(nullptr, "in test");
545 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
546 PSKSecurityArgs());
547 }
548
TEST_F(WiFiServiceTest,ConnectConditions)549 TEST_F(WiFiServiceTest, ConnectConditions) {
550 Error error;
551 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
552 scoped_refptr<MockProfile> mock_profile(
553 new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
554 wifi_service->set_profile(mock_profile);
555 // With nothing else going on, the service should attempt to connect.
556 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
557 wifi_service->Connect(&error, "in test");
558 Mock::VerifyAndClearExpectations(wifi().get());
559
560 // But if we're already "connecting" or "connected" then we shouldn't attempt
561 // again.
562 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get())).Times(0);
563 wifi_service->SetState(Service::kStateAssociating);
564 wifi_service->Connect(&error, "in test");
565 wifi_service->SetState(Service::kStateConfiguring);
566 wifi_service->Connect(&error, "in test");
567 wifi_service->SetState(Service::kStateConnected);
568 wifi_service->Connect(&error, "in test");
569 wifi_service->SetState(Service::kStatePortal);
570 wifi_service->Connect(&error, "in test");
571 wifi_service->SetState(Service::kStateOnline);
572 wifi_service->Connect(&error, "in test");
573 Mock::VerifyAndClearExpectations(wifi().get());
574 }
575
TEST_F(WiFiServiceTest,ConnectTaskPSK)576 TEST_F(WiFiServiceTest, ConnectTaskPSK) {
577 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk);
578 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
579 Error error;
580 wifi_service->SetPassphrase("0:mumblemumblem", &error);
581 wifi_service->Connect(nullptr, "in test");
582 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
583 PSKSecurityArgs());
584 }
585
TEST_F(WiFiServiceTest,ConnectTask8021x)586 TEST_F(WiFiServiceTest, ConnectTask8021x) {
587 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
588 service->mutable_eap()->set_identity("identity");
589 service->mutable_eap()->set_password("mumble");
590 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
591 EXPECT_CALL(*wifi(), ConnectTo(service.get()));
592 service->Connect(nullptr, "in test");
593 KeyValueStore params = service->GetSupplicantConfigurationParameters();
594 EXPECT_TRUE(
595 params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity));
596 EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath));
597 }
598
TEST_F(WiFiServiceTest,ConnectTask8021xWithMockEap)599 TEST_F(WiFiServiceTest, ConnectTask8021xWithMockEap) {
600 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
601 MockEapCredentials* eap = SetMockEap(service);
602 EXPECT_CALL(*eap, IsConnectable()).WillOnce(Return(true));
603 EXPECT_CALL(*wifi(), ConnectTo(service.get()));
604 service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
605 service->Connect(nullptr, "in test");
606
607 EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _));
608 // The mocked function does not actually set EAP parameters so we cannot
609 // expect them to be set.
610 service->GetSupplicantConfigurationParameters();
611 }
612
TEST_F(WiFiServiceTest,ConnectTaskAdHocFrequency)613 TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
614 vector<uint8_t> ssid(1, 'a');
615 WiFiEndpointRefPtr endpoint_nofreq =
616 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
617 WiFiEndpointRefPtr endpoint_freq =
618 MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0);
619
620 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
621 wifi_service->AddEndpoint(endpoint_freq);
622 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
623 wifi_service->Connect(nullptr, "in test");
624
625 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
626 FrequencyArg(false));
627
628 wifi_service = new WiFiService(control_interface(),
629 dispatcher(),
630 metrics(),
631 manager(),
632 provider(),
633 ssid,
634 kModeAdhoc,
635 kSecurityNone,
636 false);
637 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
638 SetWiFiForService(wifi_service, wifi());
639 wifi_service->Connect(nullptr, "in test");
640
641 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
642 FrequencyArg(false));
643
644 wifi_service = new WiFiService(control_interface(),
645 dispatcher(),
646 metrics(),
647 manager(),
648 provider(),
649 ssid,
650 kModeAdhoc,
651 kSecurityNone,
652 false);
653 wifi_service->AddEndpoint(endpoint_nofreq);
654 SetWiFiForService(wifi_service, wifi());
655 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
656 wifi_service->Connect(nullptr, "in test");
657
658 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
659 FrequencyArg(false));
660
661 wifi_service = new WiFiService(control_interface(),
662 dispatcher(),
663 metrics(),
664 manager(),
665 provider(),
666 ssid,
667 kModeAdhoc,
668 kSecurityNone,
669 false);
670 wifi_service->AddEndpoint(endpoint_freq);
671 SetWiFiForService(wifi_service, wifi());
672 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
673 wifi_service->Connect(nullptr, "in test");
674 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
675 FrequencyArg(true));
676 }
677
TEST_F(WiFiServiceTest,ConnectTaskWPA80211w)678 TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
679 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityPsk);
680 WiFiEndpointRefPtr endpoint =
681 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
682 endpoint->ieee80211w_required_ = true;
683 wifi_service->AddEndpoint(endpoint);
684 Error error;
685 wifi_service->SetPassphrase("0:mumblemumblem", &error);
686 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
687 wifi_service->Connect(nullptr, "in test");
688
689 KeyValueStore params =
690 wifi_service->GetSupplicantConfigurationParameters();
691 EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertySecurityProtocol));
692 EXPECT_TRUE(params.ContainsString(WPASupplicant::kPropertyPreSharedKey));
693 EXPECT_TRUE(params.ContainsUint(WPASupplicant::kNetworkPropertyIeee80211w));
694 }
695
696 MATCHER_P(WEPSecurityArgsKeyIndex, index, "") {
697 uint32_t index_u32 = index;
698 return arg.ContainsString(WPASupplicant::kPropertyAuthAlg) &&
699 arg.ContainsUint8s(
700 WPASupplicant::kPropertyWEPKey + base::IntToString(index)) &&
701 arg.ContainsUint(WPASupplicant::kPropertyWEPTxKeyIndex) &&
702 (arg.GetUint(WPASupplicant::kPropertyWEPTxKeyIndex) == index_u32);
703 }
704
TEST_F(WiFiServiceTest,ConnectTaskWEP)705 TEST_F(WiFiServiceTest, ConnectTaskWEP) {
706 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep);
707 Error error;
708 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
709 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
710 wifi_service->Connect(nullptr, "in test");
711 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
712 WEPSecurityArgsKeyIndex(0));
713
714 wifi_service->SetPassphrase("abcdefghijklm", &error);
715 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
716 wifi_service->Connect(nullptr, "in test");
717 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
718 WEPSecurityArgsKeyIndex(0));
719
720 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
721 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
722 wifi_service->Connect(nullptr, "in test");
723 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
724 WEPSecurityArgsKeyIndex(1));
725
726 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
727 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
728 wifi_service->Connect(nullptr, "in test");
729 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
730 WEPSecurityArgsKeyIndex(2));
731
732 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
733 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
734 wifi_service->Connect(nullptr, "in test");
735 EXPECT_THAT(wifi_service->GetSupplicantConfigurationParameters(),
736 WEPSecurityArgsKeyIndex(3));
737 }
738
739 // Dynamic WEP + 802.1x.
TEST_F(WiFiServiceTest,ConnectTaskDynamicWEP)740 TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
741 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityWep);
742
743 wifi_service->mutable_eap()->SetKeyManagement("IEEE8021X", nullptr);
744 wifi_service->mutable_eap()->set_identity("something");
745 wifi_service->mutable_eap()->set_password("mumble");
746 wifi_service->OnEapCredentialsChanged(Service::kReasonCredentialsLoaded);
747 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get()));
748 wifi_service->Connect(nullptr, "in test");
749 KeyValueStore params =
750 wifi_service->GetSupplicantConfigurationParameters();
751 EXPECT_TRUE(
752 params.ContainsString(WPASupplicant::kNetworkPropertyEapIdentity));
753 EXPECT_TRUE(params.ContainsString(WPASupplicant::kNetworkPropertyCaPath));
754 EXPECT_FALSE(
755 params.ContainsString(WPASupplicant::kPropertySecurityProtocol));
756 }
757
TEST_F(WiFiServiceTest,SetPassphraseResetHasEverConnected)758 TEST_F(WiFiServiceTest, SetPassphraseResetHasEverConnected) {
759 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
760 const string kPassphrase = "abcdefgh";
761
762 Error error;
763 // A changed passphrase should reset has_ever_connected_ field.
764 wifi_service->has_ever_connected_ = true;
765 EXPECT_TRUE(wifi_service->has_ever_connected());
766 wifi_service->SetPassphrase(kPassphrase, &error);
767 EXPECT_FALSE(wifi_service->has_ever_connected());
768 }
769
TEST_F(WiFiServiceTest,SetPassphraseRemovesCachedCredentials)770 TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
771 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityRsn);
772
773 const string kPassphrase = "abcdefgh";
774
775 {
776 Error error;
777 // A changed passphrase should trigger cache removal.
778 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
779 wifi_service->SetPassphrase(kPassphrase, &error);
780 Mock::VerifyAndClearExpectations(wifi().get());
781 EXPECT_TRUE(error.IsSuccess());
782 }
783
784 {
785 Error error;
786 // An unchanged passphrase should not trigger cache removal.
787 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
788 wifi_service->SetPassphrase(kPassphrase, &error);
789 Mock::VerifyAndClearExpectations(wifi().get());
790 EXPECT_TRUE(error.IsSuccess());
791 }
792
793 {
794 Error error;
795 // A modified passphrase should trigger cache removal.
796 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
797 wifi_service->SetPassphrase(kPassphrase + "X", &error);
798 Mock::VerifyAndClearExpectations(wifi().get());
799 EXPECT_TRUE(error.IsSuccess());
800 }
801
802 {
803 Error error;
804 // A cleared passphrase should also trigger cache removal.
805 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
806 wifi_service->ClearPassphrase(&error);
807 Mock::VerifyAndClearExpectations(wifi().get());
808 EXPECT_TRUE(error.IsSuccess());
809 }
810
811 {
812 Error error;
813 // An invalid passphrase should not trigger cache removal.
814 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
815 wifi_service->SetPassphrase("", &error);
816 Mock::VerifyAndClearExpectations(wifi().get());
817 EXPECT_FALSE(error.IsSuccess());
818 }
819
820 {
821 // A change to EAP parameters in a PSK (non 802.1x) service will not
822 // trigger cache removal.
823 wifi_service->has_ever_connected_ = true;
824 EXPECT_TRUE(wifi_service->has_ever_connected());
825 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get())).Times(0);
826 wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate);
827 EXPECT_TRUE(wifi_service->has_ever_connected());
828 Mock::VerifyAndClearExpectations(wifi().get());
829 }
830
831 WiFiServiceRefPtr eap_wifi_service = MakeServiceWithWiFi(kSecurity8021x);
832
833 {
834 // Any change to EAP parameters (including a null one) will trigger cache
835 // removal in an 802.1x service. This is a lot less granular than the
836 // passphrase checks above.
837 // Changes in EAP parameters should also clear has_ever_connected_.
838 eap_wifi_service->has_ever_connected_ = true;
839 EXPECT_TRUE(eap_wifi_service->has_ever_connected());
840 EXPECT_CALL(*wifi(), ClearCachedCredentials(eap_wifi_service.get()));
841 eap_wifi_service->OnEapCredentialsChanged(Service::kReasonPropertyUpdate);
842 EXPECT_FALSE(eap_wifi_service->has_ever_connected());
843 Mock::VerifyAndClearExpectations(wifi().get());
844 }
845 }
846
847 // This test is somewhat redundant, since:
848 //
849 // a) we test that generic property setters return false on a null
850 // change (e.g. in PropertyAccessorTest.SignedIntCorrectness)
851 // b) we test that custom EAP property setters return false on a null
852 // change in EapCredentialsTest.CustomSetterNoopChange
853 // c) we test that the various custom accessors pass through the
854 // return value of custom setters
855 // (e.g. PropertyAccessorTest.CustomAccessorCorrectness)
856 // d) we test that PropertyStore skips the change callback when a
857 // property setter return false (PropertyStoreTypedTest.SetProperty)
858 //
859 // Nonetheless, I think it's worth testing the WiFi+EAP case directly.
TEST_F(WiFiServiceTest,EapAuthPropertyChangeClearsCachedCredentials)860 TEST_F(WiFiServiceTest, EapAuthPropertyChangeClearsCachedCredentials) {
861 WiFiServiceRefPtr wifi_service =
862 MakeServiceWithWiFi(kSecurity8021x);
863 PropertyStore& property_store(*wifi_service->mutable_store());
864
865 // Property with custom accessor.
866 const string kPassword = "abcdefgh";
867 {
868 Error error;
869 // A changed passphrase should trigger cache removal.
870 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
871 EXPECT_TRUE(property_store.SetStringProperty(
872 kEapPasswordProperty, kPassword, &error));
873 Mock::VerifyAndClearExpectations(wifi().get());
874 EXPECT_TRUE(error.IsSuccess());
875 }
876 {
877 Error error;
878 // An unchanged passphrase should not trigger cache removal.
879 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
880 EXPECT_FALSE(property_store.SetStringProperty(
881 kEapPasswordProperty, kPassword, &error));
882 Mock::VerifyAndClearExpectations(wifi().get());
883 EXPECT_TRUE(error.IsSuccess());
884 }
885 {
886 Error error;
887 // A modified passphrase should trigger cache removal.
888 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
889 EXPECT_TRUE(property_store.SetStringProperty(
890 kEapPasswordProperty, kPassword + "X", &error));
891 Mock::VerifyAndClearExpectations(wifi().get());
892 EXPECT_TRUE(error.IsSuccess());
893 }
894
895 // Property with generic accessor.
896 const string kCertId = "abcdefgh";
897 {
898 Error error;
899 // A changed cert id should trigger cache removal.
900 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
901 EXPECT_TRUE(property_store.SetStringProperty(
902 kEapCertIdProperty, kCertId, &error));
903 Mock::VerifyAndClearExpectations(wifi().get());
904 EXPECT_TRUE(error.IsSuccess());
905 }
906 {
907 Error error;
908 // An unchanged cert id should not trigger cache removal.
909 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
910 EXPECT_FALSE(property_store.SetStringProperty(
911 kEapCertIdProperty, kCertId, &error));
912 Mock::VerifyAndClearExpectations(wifi().get());
913 EXPECT_TRUE(error.IsSuccess());
914 }
915 {
916 Error error;
917 // A modified cert id should trigger cache removal.
918 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
919 EXPECT_TRUE(property_store.SetStringProperty(
920 kEapCertIdProperty, kCertId + "X", &error));
921 Mock::VerifyAndClearExpectations(wifi().get());
922 EXPECT_TRUE(error.IsSuccess());
923 }
924 }
925
TEST_F(WiFiServiceTest,LoadHidden)926 TEST_F(WiFiServiceTest, LoadHidden) {
927 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
928 ASSERT_FALSE(service->hidden_ssid_);
929 NiceMock<MockStore> mock_store;
930 const string storage_id = service->GetStorageIdentifier();
931 set<string> groups;
932 groups.insert(storage_id);
933 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
934 .WillRepeatedly(Return(true));
935 EXPECT_CALL(mock_store, GetGroupsWithProperties(
936 ContainsWiFiProperties(
937 simple_ssid(), kModeManaged, kSecurityNone)))
938 .WillRepeatedly(Return(groups));
939 EXPECT_CALL(mock_store, GetBool(_, _, _))
940 .WillRepeatedly(Return(false));
941 EXPECT_CALL(mock_store,
942 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
943 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
944 EXPECT_TRUE(service->Load(&mock_store));
945 EXPECT_TRUE(service->hidden_ssid_);
946 }
947
TEST_F(WiFiServiceTest,SetPassphraseForNonPassphraseService)948 TEST_F(WiFiServiceTest, SetPassphraseForNonPassphraseService) {
949 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
950 NiceMock<MockStore> mock_store;
951 const string storage_id = service->GetStorageIdentifier();
952 set<string> groups;
953 groups.insert(storage_id);
954 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
955 .WillRepeatedly(Return(true));
956 EXPECT_CALL(mock_store, GetGroupsWithProperties(
957 ContainsWiFiProperties(
958 simple_ssid(), kModeManaged, kSecurityNone)))
959 .WillRepeatedly(Return(groups));
960
961 EXPECT_TRUE(service->Load(&mock_store));
962 Error error;
963 EXPECT_FALSE(service->SetPassphrase("password", &error));
964 EXPECT_TRUE(error.type() == Error::kNotSupported);
965 }
966
TEST_F(WiFiServiceTest,LoadMultipleMatchingGroups)967 TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
968 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone);
969 set<string> groups;
970 groups.insert("id0");
971 groups.insert("id1");
972 // Make sure we retain the first matched group in the same way that
973 // WiFiService::Load() will.
974 string first_group = *groups.begin();
975
976 NiceMock<MockStore> mock_store;
977 EXPECT_CALL(mock_store, GetGroupsWithProperties(
978 ContainsWiFiProperties(
979 simple_ssid(), kModeManaged, kSecurityNone)))
980 .WillRepeatedly(Return(groups));
981 EXPECT_CALL(mock_store, ContainsGroup(first_group))
982 .WillRepeatedly(Return(true));
983 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
984 EXPECT_CALL(mock_store, GetBool(first_group, _, _))
985 .WillRepeatedly(Return(false));
986 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
987 ScopedMockLog log;
988 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
989 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
990 EndsWith("choosing the first.")));
991 EXPECT_TRUE(service->Load(&mock_store));
992 }
993
TEST_F(WiFiServiceSecurityTest,WPAMapping)994 TEST_F(WiFiServiceSecurityTest, WPAMapping) {
995 EXPECT_TRUE(TestStorageMapping(kSecurityRsn, kSecurityPsk));
996 EXPECT_TRUE(TestStorageMapping(kSecurityWpa, kSecurityPsk));
997 EXPECT_TRUE(TestStorageMapping(kSecurityPsk, kSecurityPsk));
998 EXPECT_TRUE(TestStorageMapping(kSecurityWep, kSecurityWep));
999 EXPECT_TRUE(TestStorageMapping(kSecurityNone, kSecurityNone));
1000 EXPECT_TRUE(TestStorageMapping(kSecurity8021x, kSecurity8021x));
1001 }
1002
TEST_F(WiFiServiceSecurityTest,LoadMapping)1003 TEST_F(WiFiServiceSecurityTest, LoadMapping) {
1004 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityPsk, true));
1005 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityRsn, false));
1006 EXPECT_TRUE(TestLoadMapping(kSecurityRsn, kSecurityWpa, false));
1007 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityPsk, true));
1008 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityWpa, false));
1009 EXPECT_TRUE(TestLoadMapping(kSecurityWpa, kSecurityRsn, false));
1010 EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityWep, true));
1011 EXPECT_TRUE(TestLoadMapping(kSecurityWep, kSecurityPsk, false));
1012 }
1013
TEST_F(WiFiServiceTest,LoadAndUnloadPassphrase)1014 TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
1015 WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk);
1016 NiceMock<MockStore> mock_store;
1017 const string kStorageId = service->GetStorageIdentifier();
1018 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
1019 .WillRepeatedly(Return(true));
1020 set<string> groups;
1021 groups.insert(kStorageId);
1022 EXPECT_CALL(mock_store, GetGroupsWithProperties(
1023 ContainsWiFiProperties(
1024 simple_ssid(), kModeManaged, kSecurityPsk)))
1025 .WillRepeatedly(Return(groups));
1026 EXPECT_CALL(mock_store, GetBool(_, _, _))
1027 .WillRepeatedly(Return(false));
1028 const string kPassphrase = "passphrase";
1029 EXPECT_CALL(mock_store,
1030 GetCryptedString(StrEq(kStorageId),
1031 WiFiService::kStoragePassphrase, _))
1032 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true)));
1033 EXPECT_CALL(mock_store,
1034 GetCryptedString(StrEq(kStorageId),
1035 StrNe(WiFiService::kStoragePassphrase), _))
1036 .WillRepeatedly(Return(false));
1037 EXPECT_TRUE(service->need_passphrase_);
1038 EXPECT_TRUE(service->Load(&mock_store));
1039 EXPECT_EQ(kPassphrase, service->passphrase_);
1040 EXPECT_TRUE(service->connectable());
1041 EXPECT_FALSE(service->need_passphrase_);
1042 service->Unload();
1043 EXPECT_EQ(string(""), service->passphrase_);
1044 EXPECT_FALSE(service->connectable());
1045 EXPECT_TRUE(service->need_passphrase_);
1046 }
1047
TEST_F(WiFiServiceTest,LoadPassphraseClearCredentials)1048 TEST_F(WiFiServiceTest, LoadPassphraseClearCredentials) {
1049 const string kOldPassphrase = "oldpassphrase";
1050 const string kPassphrase = "passphrase";
1051
1052 const bool kHasEverConnected = true;
1053 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityPsk);
1054 NiceMock<MockStore> mock_store;
1055 const string kStorageId = service->GetStorageIdentifier();
1056 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
1057 .WillRepeatedly(Return(true));
1058 set<string> groups;
1059 groups.insert(kStorageId);
1060 EXPECT_CALL(mock_store, GetGroupsWithProperties(
1061 ContainsWiFiProperties(
1062 simple_ssid(), kModeManaged, kSecurityPsk)))
1063 .WillRepeatedly(Return(groups));
1064 EXPECT_CALL(mock_store, GetBool(_, _, _))
1065 .WillRepeatedly(Return(false));
1066 EXPECT_CALL(mock_store,
1067 GetCryptedString(StrEq(kStorageId),
1068 WiFiService::kStoragePassphrase, _))
1069 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kPassphrase), Return(true)));
1070 EXPECT_CALL(mock_store,
1071 GetCryptedString(StrEq(kStorageId),
1072 StrNe(WiFiService::kStoragePassphrase), _))
1073 .WillRepeatedly(Return(false));
1074 EXPECT_CALL(mock_store,
1075 GetBool(kStorageId, Service::kStorageHasEverConnected, _))
1076 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kHasEverConnected),
1077 Return(true)));
1078 // Set old passphrase for service
1079 EXPECT_TRUE(service->need_passphrase_);
1080 service->passphrase_ = kOldPassphrase;
1081 service->has_ever_connected_ = true;
1082
1083 scoped_refptr<MockProfile> mock_profile(
1084 new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
1085 service->set_profile(mock_profile);
1086 // Detect if the service is going to attempt to update the stored profile.
1087 EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0);
1088
1089 // The kOldPassphrase is different than the newly loaded passhprase,
1090 // so the credentials should be cleared.
1091 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(1);
1092 EXPECT_CALL(*mock_profile, UpdateService(_)).Times(0);
1093 EXPECT_TRUE(service->Load(&mock_store));
1094 EXPECT_EQ(kPassphrase, service->passphrase_);
1095 EXPECT_TRUE(service->has_ever_connected_);
1096
1097 Mock::VerifyAndClearExpectations(wifi().get());
1098 Mock::VerifyAndClearExpectations(mock_profile.get());
1099
1100
1101 // Repeat Service::Load with same old and new passphrase. Since the old
1102 // and new passphrase match, verify the cache is not cleared during
1103 // profile load.
1104 service->set_profile(mock_profile);
1105 EXPECT_CALL(*mock_profile, GetConstStorage()).Times(0);
1106 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
1107 EXPECT_TRUE(service->Load(&mock_store));
1108 EXPECT_EQ(kPassphrase, service->passphrase_);
1109 EXPECT_TRUE(service->has_ever_connected_);
1110 }
1111
TEST_F(WiFiServiceTest,ConfigureMakesConnectable)1112 TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
1113 string guid("legit_guid");
1114 KeyValueStore args;
1115 args.SetString(kEapIdentityProperty, "legit_identity");
1116 args.SetString(kEapPasswordProperty, "legit_password");
1117 args.SetString(kEapMethodProperty, "PEAP");
1118 args.SetString(kGuidProperty, guid);
1119 Error error;
1120
1121 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
1122 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
1123 // our service. This way, Manager will handle the lookup itself.
1124 service->SetGuid(guid, nullptr);
1125 manager()->RegisterService(service);
1126 EXPECT_FALSE(service->connectable());
1127 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
1128 EXPECT_TRUE(error.IsSuccess());
1129 EXPECT_TRUE(service->connectable());
1130 }
1131
TEST_F(WiFiServiceTest,ConfigurePassphrase)1132 TEST_F(WiFiServiceTest, ConfigurePassphrase) {
1133 EXPECT_EQ(Error::kNotSupported,
1134 TestConfigurePassphrase(kSecurityNone, ""));
1135 EXPECT_EQ(Error::kNotSupported,
1136 TestConfigurePassphrase(kSecurityNone, "foo"));
1137 EXPECT_EQ(Error::kSuccess,
1138 TestConfigurePassphrase(kSecurityWep, nullptr));
1139 EXPECT_EQ(Error::kInvalidPassphrase,
1140 TestConfigurePassphrase(kSecurityWep, ""));
1141 EXPECT_EQ(Error::kInvalidPassphrase,
1142 TestConfigurePassphrase(kSecurityWep, "abcd"));
1143 EXPECT_EQ(Error::kSuccess,
1144 TestConfigurePassphrase(kSecurityWep, "abcde"));
1145 EXPECT_EQ(Error::kSuccess,
1146 TestConfigurePassphrase(kSecurityWep, "abcdefghijklm"));
1147 EXPECT_EQ(Error::kSuccess,
1148 TestConfigurePassphrase(kSecurityWep, "0:abcdefghijklm"));
1149 EXPECT_EQ(Error::kSuccess,
1150 TestConfigurePassphrase(kSecurityWep, "0102030405"));
1151 EXPECT_EQ(Error::kInvalidPassphrase,
1152 TestConfigurePassphrase(kSecurityWep, "0x0102030405"));
1153 EXPECT_EQ(Error::kInvalidPassphrase,
1154 TestConfigurePassphrase(kSecurityWep, "O102030405"));
1155 EXPECT_EQ(Error::kInvalidPassphrase,
1156 TestConfigurePassphrase(kSecurityWep, "1:O102030405"));
1157 EXPECT_EQ(Error::kInvalidPassphrase,
1158 TestConfigurePassphrase(kSecurityWep, "1:0xO102030405"));
1159 EXPECT_EQ(Error::kInvalidPassphrase,
1160 TestConfigurePassphrase(kSecurityWep, "0xO102030405"));
1161 EXPECT_EQ(Error::kSuccess,
1162 TestConfigurePassphrase(kSecurityWep,
1163 "0102030405060708090a0b0c0d"));
1164 EXPECT_EQ(Error::kSuccess,
1165 TestConfigurePassphrase(kSecurityWep,
1166 "0102030405060708090A0B0C0D"));
1167 EXPECT_EQ(Error::kSuccess,
1168 TestConfigurePassphrase(kSecurityWep,
1169 "0:0102030405060708090a0b0c0d"));
1170 EXPECT_EQ(Error::kSuccess,
1171 TestConfigurePassphrase(kSecurityWep,
1172 "0:0x0102030405060708090a0b0c0d"));
1173 EXPECT_EQ(Error::kSuccess,
1174 TestConfigurePassphrase(kSecurityWpa, nullptr));
1175 EXPECT_EQ(Error::kSuccess,
1176 TestConfigurePassphrase(kSecurityWpa, "secure password"));
1177 EXPECT_EQ(Error::kInvalidPassphrase,
1178 TestConfigurePassphrase(kSecurityWpa, ""));
1179 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1180 kSecurityWpa,
1181 string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
1182 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1183 kSecurityWpa,
1184 string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
1185 // subtle: invalid length for hex key, but valid as ascii passphrase
1186 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1187 kSecurityWpa,
1188 string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
1189 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1190 kSecurityWpa,
1191 string(IEEE_80211::kWPAHexLen, '1').c_str()));
1192 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1193 kSecurityWpa,
1194 string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
1195 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1196 kSecurityWpa,
1197 string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
1198 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1199 kSecurityWpa,
1200 string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
1201 }
1202
TEST_F(WiFiServiceTest,ConfigureRedundantProperties)1203 TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
1204 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
1205 KeyValueStore args;
1206 args.SetString(kTypeProperty, kTypeWifi);
1207 args.SetString(kSSIDProperty, simple_ssid_string());
1208 args.SetString(kSecurityProperty, kSecurityNone);
1209 args.SetString(kWifiHexSsid, "This is ignored even if it is invalid hex.");
1210 const string kGUID = "aguid";
1211 args.SetString(kGuidProperty, kGUID);
1212
1213 EXPECT_EQ("", service->guid());
1214 Error error;
1215 service->Configure(args, &error);
1216 EXPECT_TRUE(error.IsSuccess());
1217 EXPECT_EQ(kGUID, service->guid());
1218 }
1219
TEST_F(WiFiServiceTest,DisconnectWithWiFi)1220 TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
1221 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep);
1222 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
1223 Error error;
1224 service->Disconnect(&error, "in test");
1225 }
1226
TEST_F(WiFiServiceTest,DisconnectWithoutWiFi)1227 TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
1228 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
1229 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
1230 Error error;
1231 service->Disconnect(&error, "in test");
1232 EXPECT_EQ(Error::kOperationFailed, error.type());
1233 }
1234
TEST_F(WiFiServiceTest,DisconnectWithoutWiFiWhileAssociating)1235 TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
1236 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
1237 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
1238 service->SetState(Service::kStateAssociating);
1239 ScopedMockLog log;
1240 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1241 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1242 HasSubstr("WiFi endpoints do not (yet) exist.")));
1243 Error error;
1244 service->Disconnect(&error, "in test");
1245 EXPECT_EQ(Error::kOperationFailed, error.type());
1246 }
1247
TEST_F(WiFiServiceTest,UnloadAndClearCacheWEP)1248 TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
1249 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityWep);
1250 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
1251 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
1252 service->Unload();
1253 }
1254
TEST_F(WiFiServiceTest,UnloadAndClearCache8021x)1255 TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
1256 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurity8021x);
1257 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
1258 EXPECT_CALL(*wifi(), DisconnectFromIfActive(service.get())).Times(1);
1259 service->Unload();
1260 }
1261
TEST_F(WiFiServiceTest,ParseStorageIdentifierNone)1262 TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
1263 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
1264 const string storage_id = service->GetStorageIdentifier();
1265 string address;
1266 string mode;
1267 string security;
1268 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1269 &security));
1270 EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address);
1271 EXPECT_EQ(kModeManaged, mode);
1272 EXPECT_EQ(kSecurityNone, security);
1273 }
1274
TEST_F(WiFiServiceTest,ParseStorageIdentifier8021x)1275 TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
1276 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
1277 // which needs to be dealt with specially in the parser.
1278 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
1279 const string storage_id = service->GetStorageIdentifier();
1280 string address;
1281 string mode;
1282 string security;
1283 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1284 &security));
1285 EXPECT_EQ(base::ToLowerASCII(GetAnyDeviceAddress()), address);
1286 EXPECT_EQ(kModeManaged, mode);
1287 EXPECT_EQ(kSecurity8021x, security);
1288 }
1289
TEST_F(WiFiServiceFixupStorageTest,FixedEntries)1290 TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
1291 const string kNonWiFiId = "vpn_foo";
1292 const string kUnparsableWiFiId = "wifi_foo";
1293
1294 AddGroup(kNonWiFiId);
1295 AddGroup(kUnparsableWiFiId);
1296 AddServiceEntry(true, true, true, true);
1297 AddServiceEntry(false, false, false, false);
1298 AddServiceEntry(true, true, true, true);
1299 AddServiceEntry(false, false, false, false);
1300 EXPECT_TRUE(FixupServiceEntries());
1301 }
1302
TEST_F(WiFiServiceFixupStorageTest,NoFixedEntries)1303 TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
1304 const string kNonWiFiId = "vpn_foo";
1305 const string kUnparsableWiFiId = "wifi_foo";
1306
1307 AddGroup(kNonWiFiId);
1308 AddGroup(kUnparsableWiFiId);
1309 AddServiceEntry(true, true, true, true);
1310 EXPECT_FALSE(FixupServiceEntries());
1311 }
1312
TEST_F(WiFiServiceFixupStorageTest,MissingTypeProperty)1313 TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
1314 AddServiceEntry(false, true, true, true);
1315 EXPECT_TRUE(FixupServiceEntries());
1316 }
1317
TEST_F(WiFiServiceFixupStorageTest,MissingModeProperty)1318 TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
1319 AddServiceEntry(true, false, true, true);
1320 EXPECT_TRUE(FixupServiceEntries());
1321 }
1322
TEST_F(WiFiServiceFixupStorageTest,MissingSecurityProperty)1323 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
1324 AddServiceEntry(true, true, false, true);
1325 EXPECT_TRUE(FixupServiceEntries());
1326 }
1327
TEST_F(WiFiServiceFixupStorageTest,MissingSecurityClassProperty)1328 TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
1329 AddServiceEntry(true, true, true, false);
1330 EXPECT_TRUE(FixupServiceEntries());
1331 }
1332
TEST_F(WiFiServiceTest,Connectable)1333 TEST_F(WiFiServiceTest, Connectable) {
1334 // Open network should be connectable.
1335 EXPECT_TRUE(CheckConnectable(kSecurityNone, nullptr, false));
1336
1337 // Open network should remain connectable if we try to set a password on it.
1338 EXPECT_TRUE(CheckConnectable(kSecurityNone, "abcde", false));
1339
1340 // WEP network with passphrase set should be connectable.
1341 EXPECT_TRUE(CheckConnectable(kSecurityWep, "abcde", false));
1342
1343 // WEP network without passphrase set should NOT be connectable.
1344 EXPECT_FALSE(CheckConnectable(kSecurityWep, nullptr, false));
1345
1346 // A bad passphrase should not make a WEP network connectable.
1347 EXPECT_FALSE(CheckConnectable(kSecurityWep, "a", false));
1348
1349 // Similar to WEP, for WPA.
1350 EXPECT_TRUE(CheckConnectable(kSecurityWpa, "abcdefgh", false));
1351 EXPECT_FALSE(CheckConnectable(kSecurityWpa, nullptr, false));
1352 EXPECT_FALSE(CheckConnectable(kSecurityWpa, "a", false));
1353
1354 // 802.1x without connectable EAP credentials should NOT be connectable.
1355 EXPECT_FALSE(CheckConnectable(kSecurity8021x, nullptr, false));
1356
1357 // 802.1x with connectable EAP credentials should be connectable.
1358 EXPECT_TRUE(CheckConnectable(kSecurity8021x, nullptr, true));
1359
1360 // Dynamic WEP + 802.1X should be connectable under the same conditions.
1361 EXPECT_TRUE(CheckConnectable(kSecurityWep, nullptr, true));
1362 }
1363
TEST_F(WiFiServiceTest,IsAutoConnectable)1364 TEST_F(WiFiServiceTest, IsAutoConnectable) {
1365 const char* reason;
1366 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
1367 EXPECT_CALL(*wifi(), IsIdle())
1368 .WillRepeatedly(Return(true));
1369 EXPECT_FALSE(service->HasEndpoints());
1370 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1371 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
1372
1373 reason = "";
1374 WiFiEndpointRefPtr endpoint =
1375 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
1376 service->AddEndpoint(endpoint);
1377 EXPECT_CALL(*wifi(), IsIdle())
1378 .WillRepeatedly(Return(true));
1379 EXPECT_TRUE(service->HasEndpoints());
1380 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1381 EXPECT_STREQ("", reason);
1382
1383 // WiFi only supports connecting to one Service at a time. So, to
1384 // avoid disrupting connectivity, we only allow auto-connection to
1385 // a WiFiService when the corresponding WiFi is idle.
1386 EXPECT_CALL(*wifi(), IsIdle())
1387 .WillRepeatedly(Return(false));
1388 EXPECT_TRUE(service->HasEndpoints());
1389 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1390 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
1391 }
1392
TEST_F(WiFiServiceTest,AutoConnect)1393 TEST_F(WiFiServiceTest, AutoConnect) {
1394 const char* reason;
1395 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
1396 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1397 EXPECT_CALL(*wifi(), ConnectTo(_)).Times(0);
1398 service->AutoConnect();
1399 dispatcher()->DispatchPendingEvents();
1400
1401 WiFiEndpointRefPtr endpoint =
1402 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
1403 service->AddEndpoint(endpoint);
1404 EXPECT_CALL(*wifi(), IsIdle())
1405 .WillRepeatedly(Return(true));
1406 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1407 EXPECT_CALL(*wifi(), ConnectTo(_));
1408 service->AutoConnect();
1409 dispatcher()->DispatchPendingEvents();
1410
1411 Error error;
1412 service->UserInitiatedDisconnect(&error);
1413 dispatcher()->DispatchPendingEvents();
1414 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1415 }
1416
TEST_F(WiFiServiceTest,ClearWriteOnlyDerivedProperty)1417 TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
1418 WiFiServiceRefPtr wifi_service = MakeSimpleService(kSecurityWep);
1419
1420 EXPECT_EQ("", wifi_service->passphrase_);
1421
1422 Error error;
1423 const string kPassphrase = "0:abcde";
1424 EXPECT_TRUE(
1425 wifi_service->mutable_store()->SetAnyProperty(kPassphraseProperty,
1426 brillo::Any(kPassphrase),
1427 &error));
1428 EXPECT_EQ(kPassphrase, wifi_service->passphrase_);
1429
1430 EXPECT_TRUE(wifi_service->mutable_store()->ClearProperty(kPassphraseProperty,
1431 &error));
1432 EXPECT_EQ("", wifi_service->passphrase_);
1433 }
1434
TEST_F(WiFiServiceTest,SignalToStrength)1435 TEST_F(WiFiServiceTest, SignalToStrength) {
1436 // Verify that our mapping is sane, in the sense that it preserves ordering.
1437 // We break the test into two domains, because we assume that positive
1438 // values aren't actually in dBm.
1439 for (int16_t i = std::numeric_limits<int16_t>::min(); i < 0; ++i) {
1440 int16_t current_mapped = WiFiService::SignalToStrength(i);
1441 int16_t next_mapped = WiFiService::SignalToStrength(i+1);
1442 EXPECT_LE(current_mapped, next_mapped)
1443 << "(original values " << i << " " << i+1 << ")";
1444 EXPECT_GE(current_mapped, Service::kStrengthMin);
1445 EXPECT_LE(current_mapped, Service::kStrengthMax);
1446 }
1447 for (int16_t i = 1; i < std::numeric_limits<int16_t>::max(); ++i) {
1448 int16_t current_mapped = WiFiService::SignalToStrength(i);
1449 int16_t next_mapped = WiFiService::SignalToStrength(i+1);
1450 EXPECT_LE(current_mapped, next_mapped)
1451 << "(original values " << i << " " << i+1 << ")";
1452 EXPECT_GE(current_mapped, Service::kStrengthMin);
1453 EXPECT_LE(current_mapped, Service::kStrengthMax);
1454 }
1455 }
1456
TEST_F(WiFiServiceUpdateFromEndpointsTest,Strengths)1457 TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1458 // If the chosen signal values don't map to distinct strength
1459 // values, then we can't expect our other tests to pass. So verify
1460 // their distinctness.
1461 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1462 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1463 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1464 }
1465
TEST_F(WiFiServiceUpdateFromEndpointsTest,Floating)1466 TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1467 // Initial endpoint updates values.
1468 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
1469 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
1470 EXPECT_CALL(adaptor,
1471 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
1472 EXPECT_CALL(adaptor,
1473 EmitUint16Changed(kWifiPhyMode, Metrics::kWiFiNetworkPhyMode11b));
1474 service->AddEndpoint(ok_endpoint);
1475 EXPECT_EQ(1, service->GetEndpointCount());
1476 Mock::VerifyAndClearExpectations(&adaptor);
1477
1478 // Endpoint with stronger signal updates values.
1479 EXPECT_CALL(adaptor,
1480 EmitUint16Changed(kWifiFrequency, kGoodEndpointFrequency));
1481 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kGoodEndpointBssId));
1482 EXPECT_CALL(adaptor,
1483 EmitUint8Changed(kSignalStrengthProperty, kGoodEndpointStrength));
1484 // However, both endpoints are 11b.
1485 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
1486 service->AddEndpoint(good_endpoint);
1487 EXPECT_EQ(2, service->GetEndpointCount());
1488 Mock::VerifyAndClearExpectations(&adaptor);
1489
1490 // Endpoint with lower signal does not change values.
1491 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1492 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1493 EXPECT_CALL(adaptor,
1494 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1495 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
1496 service->AddEndpoint(bad_endpoint);
1497 EXPECT_EQ(3, service->GetEndpointCount());
1498 Mock::VerifyAndClearExpectations(&adaptor);
1499
1500 // Removing non-optimal endpoint does not change values.
1501 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1502 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1503 EXPECT_CALL(adaptor,
1504 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1505 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
1506 service->RemoveEndpoint(bad_endpoint);
1507 EXPECT_EQ(2, service->GetEndpointCount());
1508 Mock::VerifyAndClearExpectations(&adaptor);
1509
1510 // Removing optimal endpoint updates values.
1511 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
1512 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
1513 EXPECT_CALL(adaptor,
1514 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
1515 // However, both endpoints are 11b.
1516 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiPhyMode, _)).Times(0);
1517 service->RemoveEndpoint(good_endpoint);
1518 EXPECT_EQ(1, service->GetEndpointCount());
1519 Mock::VerifyAndClearExpectations(&adaptor);
1520
1521 // Removing last endpoint updates values (and doesn't crash).
1522 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _));
1523 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _));
1524 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
1525 EXPECT_CALL(adaptor, EmitUint16Changed(
1526 kWifiPhyMode, Metrics::kWiFiNetworkPhyModeUndef));
1527 service->RemoveEndpoint(ok_endpoint);
1528 EXPECT_EQ(0, service->GetEndpointCount());
1529 Mock::VerifyAndClearExpectations(&adaptor);
1530 }
1531
TEST_F(WiFiServiceUpdateFromEndpointsTest,Connected)1532 TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1533 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1534 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1535 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1536 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1537 service->AddEndpoint(bad_endpoint);
1538 service->AddEndpoint(ok_endpoint);
1539 EXPECT_EQ(2, service->GetEndpointCount());
1540 Mock::VerifyAndClearExpectations(&adaptor);
1541
1542 // Setting current endpoint forces adoption of its values, even if it
1543 // doesn't have the highest signal.
1544 EXPECT_CALL(adaptor,
1545 EmitUint16Changed(kWifiFrequency, kBadEndpointFrequency));
1546 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kBadEndpointBssId));
1547 EXPECT_CALL(adaptor,
1548 EmitUint8Changed(kSignalStrengthProperty, kBadEndpointStrength));
1549 service->NotifyCurrentEndpoint(bad_endpoint);
1550 Mock::VerifyAndClearExpectations(&adaptor);
1551
1552 // Adding a better endpoint doesn't matter, when current endpoint is set.
1553 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1554 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1555 EXPECT_CALL(adaptor,
1556 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1557 service->AddEndpoint(good_endpoint);
1558 EXPECT_EQ(3, service->GetEndpointCount());
1559 Mock::VerifyAndClearExpectations(&adaptor);
1560
1561 // Removing a better endpoint doesn't matter, when current endpoint is set.
1562 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1563 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1564 EXPECT_CALL(adaptor,
1565 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1566 service->RemoveEndpoint(good_endpoint);
1567 Mock::VerifyAndClearExpectations(&adaptor);
1568
1569 // Removing the current endpoint is safe and sane.
1570 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
1571 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
1572 EXPECT_CALL(adaptor,
1573 EmitUint8Changed(kSignalStrengthProperty, kOkEndpointStrength));
1574 service->RemoveEndpoint(bad_endpoint);
1575 Mock::VerifyAndClearExpectations(&adaptor);
1576
1577 // Clearing the current endpoint (without removing it) is also safe and sane.
1578 service->NotifyCurrentEndpoint(ok_endpoint);
1579 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1580 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1581 EXPECT_CALL(adaptor,
1582 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1583 service->NotifyCurrentEndpoint(nullptr);
1584 Mock::VerifyAndClearExpectations(&adaptor);
1585 }
1586
TEST_F(WiFiServiceUpdateFromEndpointsTest,EndpointModified)1587 TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1588 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1589 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1590 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1591 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1592 service->AddEndpoint(ok_endpoint);
1593 service->AddEndpoint(good_endpoint);
1594 EXPECT_EQ(2, service->GetEndpointCount());
1595 Mock::VerifyAndClearExpectations(&adaptor);
1596
1597 // Updating sub-optimal Endpoint doesn't update Service.
1598 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1599 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1600 EXPECT_CALL(adaptor,
1601 EmitUint8Changed(kSignalStrengthProperty, _)).Times(0);
1602 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1603 service->NotifyEndpointUpdated(ok_endpoint);
1604 Mock::VerifyAndClearExpectations(&adaptor);
1605
1606 // Updating optimal Endpoint updates appropriate Service property.
1607 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, _)).Times(0);
1608 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, _)).Times(0);
1609 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
1610 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1611 service->NotifyEndpointUpdated(good_endpoint);
1612 Mock::VerifyAndClearExpectations(&adaptor);
1613
1614 // Change in optimal Endpoint updates Service properties.
1615 EXPECT_CALL(adaptor, EmitUint16Changed(kWifiFrequency, kOkEndpointFrequency));
1616 EXPECT_CALL(adaptor, EmitStringChanged(kWifiBSsid, kOkEndpointBssId));
1617 EXPECT_CALL(adaptor, EmitUint8Changed(kSignalStrengthProperty, _));
1618 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1619 service->NotifyEndpointUpdated(ok_endpoint);
1620 Mock::VerifyAndClearExpectations(&adaptor);
1621 }
1622
TEST_F(WiFiServiceUpdateFromEndpointsTest,Ieee80211w)1623 TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1624 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1625 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1626 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1627 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1628 service->AddEndpoint(ok_endpoint);
1629 EXPECT_FALSE(service->ieee80211w_required());
1630 good_endpoint->ieee80211w_required_ = true;
1631 service->AddEndpoint(good_endpoint);
1632 EXPECT_TRUE(service->ieee80211w_required());
1633 service->RemoveEndpoint(good_endpoint);
1634 EXPECT_TRUE(service->ieee80211w_required());
1635 }
1636
TEST_F(WiFiServiceUpdateFromEndpointsTest,PhysicalMode)1637 TEST_F(WiFiServiceUpdateFromEndpointsTest, PhysicalMode) {
1638 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1639 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1640 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1641 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1642
1643 // No endpoints -> undef.
1644 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1645
1646 // Endpoint has unknown physical mode -> undef.
1647 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyModeUndef;
1648 service->AddEndpoint(ok_endpoint);
1649 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1650
1651 // New endpoint with 802.11a -> 802.11a.
1652 good_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
1653 service->AddEndpoint(good_endpoint);
1654 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, service->physical_mode());
1655
1656 // Remove 802.11a endpoint -> undef.
1657 service->RemoveEndpoint(good_endpoint);
1658 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1659
1660 // Change endpoint -> take endpoint's new value.
1661 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11n;
1662 service->NotifyEndpointUpdated(ok_endpoint);
1663 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, service->physical_mode());
1664
1665 // No endpoints -> undef.
1666 service->RemoveEndpoint(ok_endpoint);
1667 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1668 }
1669
TEST_F(WiFiServiceUpdateFromEndpointsTest,WarningOnDisconnect)1670 TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) {
1671 service->AddEndpoint(ok_endpoint);
1672 service->SetState(Service::kStateAssociating);
1673 ScopedMockLog log;
1674 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1675 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1676 EndsWith("disconnect due to no remaining endpoints.")));
1677 service->RemoveEndpoint(ok_endpoint);
1678 }
1679
TEST_F(WiFiServiceUpdateFromEndpointsTest,AddEndpointWithPreferredDevice)1680 TEST_F(WiFiServiceUpdateFromEndpointsTest, AddEndpointWithPreferredDevice) {
1681 // Setup service, device, and endpoints.
1682 WiFiServiceRefPtr wifi_service = MakeServiceWithMockManager();
1683 const string kDeviceName1 = "test_device1";
1684 const string kDeviceName2 = "test_device2";
1685 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
1686 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
1687 // Best signal for endpoint associated with the preferred device.
1688 const int16_t kPreferredDeviceBestSignal = -40;
1689 WiFiEndpointRefPtr endpoint0 =
1690 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0,
1691 kPreferredDeviceBestSignal + 10);
1692 WiFiEndpointRefPtr endpoint1 =
1693 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0,
1694 kPreferredDeviceBestSignal - 10);
1695 WiFiEndpointRefPtr endpoint2 =
1696 MakeOpenEndpointWithWiFi(wifi1, "a", "00:00:00:00:00:01", 0,
1697 kPreferredDeviceBestSignal);
1698 WiFiEndpointRefPtr endpoint3 =
1699 MakeOpenEndpointWithWiFi(wifi2, "a", "00:00:00:00:00:01", 0,
1700 kPreferredDeviceBestSignal + 10);
1701
1702 wifi_service->SetPreferredDevice(kDeviceName1, nullptr);
1703
1704 wifi_service->AddEndpoint(endpoint0);
1705 wifi_service->AddEndpoint(endpoint1);
1706 wifi_service->AddEndpoint(endpoint2);
1707 wifi_service->AddEndpoint(endpoint3);
1708 EXPECT_EQ(wifi1, wifi_service->wifi_);
1709 // Service should display the signal strength of the best signal endpoint
1710 // that's associated with the preferred device.
1711 EXPECT_EQ(WiFiService::SignalToStrength(kPreferredDeviceBestSignal),
1712 wifi_service->strength());
1713 }
1714
1715 MATCHER_P(IsSetwiseEqual, expected_set, "") {
1716 set<uint16_t> arg_set(arg.begin(), arg.end());
1717 return arg_set == expected_set;
1718 }
1719
TEST_F(WiFiServiceUpdateFromEndpointsTest,FrequencyList)1720 TEST_F(WiFiServiceUpdateFromEndpointsTest, FrequencyList) {
1721 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1722 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1723 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1724 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1725
1726 // No endpoints -> empty list.
1727 EXPECT_EQ(vector<uint16_t>(), service->frequency_list());
1728
1729 // Add endpoint -> endpoint's frequency in list.
1730 EXPECT_CALL(adaptor, EmitUint16sChanged(
1731 kWifiFrequencyListProperty, vector<uint16_t>{kGoodEndpointFrequency}));
1732 service->AddEndpoint(good_endpoint);
1733 Mock::VerifyAndClearExpectations(&adaptor);
1734
1735 // Add another endpoint -> both frequencies in list.
1736 // Order doesn't matter.
1737 set<uint16_t> expected_frequencies{kGoodEndpointFrequency,
1738 kOkEndpointFrequency};
1739 EXPECT_CALL(adaptor, EmitUint16sChanged(
1740 kWifiFrequencyListProperty, IsSetwiseEqual(expected_frequencies)));
1741 service->AddEndpoint(ok_endpoint);
1742 Mock::VerifyAndClearExpectations(&adaptor);
1743
1744 // Remove endpoint -> other endpoint's frequency remains.
1745 EXPECT_CALL(adaptor, EmitUint16sChanged(
1746 kWifiFrequencyListProperty, vector<uint16_t>{kOkEndpointFrequency}));
1747 service->RemoveEndpoint(good_endpoint);
1748 Mock::VerifyAndClearExpectations(&adaptor);
1749
1750 // Endpoint with same frequency -> frequency remains.
1751 // Notification may or may not occur -- don't care.
1752 // Frequency may or may not be repeated in list -- don't care.
1753 WiFiEndpointRefPtr same_freq_as_ok_endpoint = MakeOpenEndpoint(
1754 simple_ssid_string(), "aa:bb:cc:dd:ee:ff", ok_endpoint->frequency(), 0);
1755 service->AddEndpoint(same_freq_as_ok_endpoint);
1756 EXPECT_THAT(service->frequency_list(),
1757 IsSetwiseEqual(set<uint16_t>{kOkEndpointFrequency}));
1758 Mock::VerifyAndClearExpectations(&adaptor);
1759
1760 // Remove endpoint with same frequency -> frequency remains.
1761 // Notification may or may not occur -- don't care.
1762 service->RemoveEndpoint(ok_endpoint);
1763 EXPECT_EQ(vector<uint16_t>{same_freq_as_ok_endpoint->frequency()},
1764 service->frequency_list());
1765 Mock::VerifyAndClearExpectations(&adaptor);
1766
1767 // Remove last endpoint. Frequency list goes empty.
1768 EXPECT_CALL(adaptor, EmitUint16sChanged(
1769 kWifiFrequencyListProperty, vector<uint16_t>{}));
1770 service->RemoveEndpoint(same_freq_as_ok_endpoint);
1771 Mock::VerifyAndClearExpectations(&adaptor);
1772 }
1773
TEST_F(WiFiServiceTest,SecurityFromCurrentEndpoint)1774 TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) {
1775 WiFiServiceRefPtr service(MakeSimpleService(kSecurityPsk));
1776 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
1777 WiFiEndpoint* endpoint = MakeOpenEndpoint(
1778 simple_ssid_string(), "00:00:00:00:00:00", 0, 0);
1779 service->AddEndpoint(endpoint);
1780 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
1781 service->NotifyCurrentEndpoint(endpoint);
1782 EXPECT_EQ(kSecurityNone, service->GetSecurity(nullptr));
1783 service->NotifyCurrentEndpoint(nullptr);
1784 EXPECT_EQ(kSecurityPsk, service->GetSecurity(nullptr));
1785 }
1786
TEST_F(WiFiServiceTest,UpdateSecurity)1787 TEST_F(WiFiServiceTest, UpdateSecurity) {
1788 // Cleartext and pre-shared-key crypto.
1789 {
1790 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
1791 EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm());
1792 EXPECT_FALSE(service->key_rotation());
1793 EXPECT_FALSE(service->endpoint_auth());
1794 }
1795 {
1796 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
1797 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1798 EXPECT_FALSE(service->key_rotation());
1799 EXPECT_FALSE(service->endpoint_auth());
1800 }
1801 {
1802 WiFiServiceRefPtr service = MakeSimpleService(kSecurityPsk);
1803 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1804 EXPECT_TRUE(service->key_rotation());
1805 EXPECT_FALSE(service->endpoint_auth());
1806 }
1807 {
1808 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa);
1809 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1810 EXPECT_TRUE(service->key_rotation());
1811 EXPECT_FALSE(service->endpoint_auth());
1812 }
1813 {
1814 WiFiServiceRefPtr service = MakeSimpleService(kSecurityRsn);
1815 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1816 EXPECT_TRUE(service->key_rotation());
1817 EXPECT_FALSE(service->endpoint_auth());
1818 }
1819
1820 // Crypto with 802.1X key management.
1821 {
1822 // WEP
1823 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWep);
1824 service->SetEAPKeyManagement("IEEE8021X");
1825 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1826 EXPECT_TRUE(service->key_rotation());
1827 EXPECT_TRUE(service->endpoint_auth());
1828 }
1829 {
1830 // WPA
1831 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
1832 WiFiEndpointRefPtr endpoint =
1833 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false);
1834 service->AddEndpoint(endpoint);
1835 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1836 EXPECT_TRUE(service->key_rotation());
1837 EXPECT_TRUE(service->endpoint_auth());
1838 }
1839 {
1840 // RSN
1841 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
1842 WiFiEndpointRefPtr endpoint =
1843 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true);
1844 service->AddEndpoint(endpoint);
1845 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1846 EXPECT_TRUE(service->key_rotation());
1847 EXPECT_TRUE(service->endpoint_auth());
1848 }
1849 {
1850 // AP supports both WPA and RSN.
1851 WiFiServiceRefPtr service = MakeSimpleService(kSecurity8021x);
1852 WiFiEndpointRefPtr endpoint =
1853 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true);
1854 service->AddEndpoint(endpoint);
1855 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1856 EXPECT_TRUE(service->key_rotation());
1857 EXPECT_TRUE(service->endpoint_auth());
1858 }
1859 }
1860
TEST_F(WiFiServiceTest,ComputeCipher8021x)1861 TEST_F(WiFiServiceTest, ComputeCipher8021x) {
1862 // No endpoints.
1863 {
1864 const set<WiFiEndpointConstRefPtr> endpoints;
1865 EXPECT_EQ(Service::kCryptoNone,
1866 WiFiService::ComputeCipher8021x(endpoints));
1867 }
1868
1869 // Single endpoint, various configs.
1870 {
1871 set<WiFiEndpointConstRefPtr> endpoints;
1872 endpoints.insert(
1873 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1874 EXPECT_EQ(Service::kCryptoNone,
1875 WiFiService::ComputeCipher8021x(endpoints));
1876 }
1877 {
1878 set<WiFiEndpointConstRefPtr> endpoints;
1879 endpoints.insert(
1880 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1881 EXPECT_EQ(Service::kCryptoRc4,
1882 WiFiService::ComputeCipher8021x(endpoints));
1883 }
1884 {
1885 set<WiFiEndpointConstRefPtr> endpoints;
1886 endpoints.insert(
1887 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1888 EXPECT_EQ(Service::kCryptoAes,
1889 WiFiService::ComputeCipher8021x(endpoints));
1890 }
1891 {
1892 set<WiFiEndpointConstRefPtr> endpoints;
1893 endpoints.insert(
1894 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1895 EXPECT_EQ(Service::kCryptoAes,
1896 WiFiService::ComputeCipher8021x(endpoints));
1897 }
1898
1899 // Multiple endpoints.
1900 {
1901 set<WiFiEndpointConstRefPtr> endpoints;
1902 endpoints.insert(
1903 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1904 endpoints.insert(
1905 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false));
1906 EXPECT_EQ(Service::kCryptoNone,
1907 WiFiService::ComputeCipher8021x(endpoints));
1908 }
1909 {
1910 set<WiFiEndpointConstRefPtr> endpoints;
1911 endpoints.insert(
1912 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1913 endpoints.insert(
1914 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1915 EXPECT_EQ(Service::kCryptoNone,
1916 WiFiService::ComputeCipher8021x(endpoints));
1917 }
1918 {
1919 set<WiFiEndpointConstRefPtr> endpoints;
1920 endpoints.insert(
1921 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1922 endpoints.insert(
1923 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1924 EXPECT_EQ(Service::kCryptoRc4,
1925 WiFiService::ComputeCipher8021x(endpoints));
1926 }
1927 {
1928 set<WiFiEndpointConstRefPtr> endpoints;
1929 endpoints.insert(
1930 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1931 endpoints.insert(
1932 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1933 EXPECT_EQ(Service::kCryptoRc4,
1934 WiFiService::ComputeCipher8021x(endpoints));
1935 }
1936 {
1937 set<WiFiEndpointConstRefPtr> endpoints;
1938 endpoints.insert(
1939 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1940 endpoints.insert(
1941 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1942 EXPECT_EQ(Service::kCryptoAes,
1943 WiFiService::ComputeCipher8021x(endpoints));
1944 }
1945 {
1946 set<WiFiEndpointConstRefPtr> endpoints;
1947 endpoints.insert(
1948 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1949 endpoints.insert(
1950 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true));
1951 EXPECT_EQ(Service::kCryptoAes,
1952 WiFiService::ComputeCipher8021x(endpoints));
1953 }
1954 }
1955
TEST_F(WiFiServiceTest,Unload)1956 TEST_F(WiFiServiceTest, Unload) {
1957 WiFiServiceRefPtr service = MakeServiceWithWiFi(kSecurityNone);
1958 EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())).
1959 Times(1);
1960 service->Unload();
1961 }
1962
TEST_F(WiFiServiceTest,PropertyChanges)1963 TEST_F(WiFiServiceTest, PropertyChanges) {
1964 WiFiServiceRefPtr service = MakeServiceWithMockManager();
1965 ServiceMockAdaptor* adaptor = GetAdaptor(service.get());
1966 TestCommonPropertyChanges(service, adaptor);
1967 TestAutoConnectPropertyChange(service, adaptor);
1968
1969 EXPECT_CALL(*adaptor,
1970 EmitRpcIdentifierChanged(kDeviceProperty, _));
1971 SetWiFi(service, wifi());
1972 Mock::VerifyAndClearExpectations(adaptor);
1973
1974 EXPECT_CALL(*adaptor,
1975 EmitRpcIdentifierChanged(kDeviceProperty, _));
1976 service->ResetWiFi();
1977 Mock::VerifyAndClearExpectations(adaptor);
1978 }
1979
1980 // Custom property setters should return false, and make no changes, if
1981 // the new value is the same as the old value.
TEST_F(WiFiServiceTest,CustomSetterNoopChange)1982 TEST_F(WiFiServiceTest, CustomSetterNoopChange) {
1983 WiFiServiceRefPtr service = MakeServiceWithMockManager();
1984 TestCustomSetterNoopChange(service, mock_manager());
1985 }
1986
TEST_F(WiFiServiceTest,SuspectedCredentialFailure)1987 TEST_F(WiFiServiceTest, SuspectedCredentialFailure) {
1988 WiFiServiceRefPtr service = MakeSimpleService(kSecurityWpa);
1989 EXPECT_FALSE(service->has_ever_connected());
1990 EXPECT_EQ(0, service->suspected_credential_failures_);
1991
1992 EXPECT_TRUE(service->AddSuspectedCredentialFailure());
1993 EXPECT_EQ(0, service->suspected_credential_failures_);
1994
1995 service->has_ever_connected_ = true;
1996 for (int i = 0; i < WiFiService::kSuspectedCredentialFailureThreshold - 1;
1997 ++i) {
1998 EXPECT_FALSE(service->AddSuspectedCredentialFailure());
1999 EXPECT_EQ(i + 1, service->suspected_credential_failures_);
2000 }
2001
2002 EXPECT_TRUE(service->AddSuspectedCredentialFailure());
2003 // Make sure the failure state does not reset just because we ask again.
2004 EXPECT_TRUE(service->AddSuspectedCredentialFailure());
2005 // Make sure the failure state resets because of a credential change.
2006 // A credential change changes the has_ever_connected to false and
2007 // immediately returns true when attempting to add the failure.
2008 Error error;
2009 service->SetPassphrase("Panchromatic Resonance", &error);
2010 EXPECT_TRUE(error.IsSuccess());
2011 EXPECT_TRUE(service->AddSuspectedCredentialFailure());
2012 EXPECT_EQ(0, service->suspected_credential_failures_);
2013
2014 // Make sure that we still return true after resetting the failure
2015 // count.
2016 service->suspected_credential_failures_ = 3;
2017 EXPECT_EQ(3, service->suspected_credential_failures_);
2018 service->ResetSuspectedCredentialFailures();
2019 EXPECT_EQ(0, service->suspected_credential_failures_);
2020 EXPECT_TRUE(service->AddSuspectedCredentialFailure());
2021 }
2022
TEST_F(WiFiServiceTest,GetTethering)2023 TEST_F(WiFiServiceTest, GetTethering) {
2024 WiFiServiceRefPtr service = MakeSimpleService(kSecurityNone);
2025 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
2026
2027 // Since the device isn't connected, we shouldn't even query the WiFi device.
2028 EXPECT_CALL(*wifi(), IsConnectedViaTether()).Times(0);
2029 SetWiFiForService(service, wifi());
2030 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
2031 Mock::VerifyAndClearExpectations(wifi().get());
2032
2033 scoped_refptr<MockProfile> mock_profile(
2034 new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
2035 service->set_profile(mock_profile);
2036 service->SetState(Service::kStateConnected);
2037
2038 // A connected service should return "confirmed" iff the underlying device
2039 // reports it is tethered.
2040 EXPECT_CALL(*wifi(), IsConnectedViaTether())
2041 .WillOnce(Return(true))
2042 .WillOnce(Return(false));
2043 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
2044 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
2045 Mock::VerifyAndClearExpectations(wifi().get());
2046
2047 // Add two endpoints that have a BSSID associated with some Android devices
2048 // in tethering mode.
2049 WiFiEndpointRefPtr endpoint_android1 =
2050 MakeOpenEndpoint("a", "02:1a:11:00:00:01", 2412, 0);
2051 service->AddEndpoint(endpoint_android1);
2052 WiFiEndpointRefPtr endpoint_android2 =
2053 MakeOpenEndpoint("a", "02:1a:11:00:00:02", 2412, 0);
2054 service->AddEndpoint(endpoint_android2);
2055
2056 // Since there are two endpoints, we should not detect tethering mode.
2057 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(false));
2058 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
2059
2060 // If the device reports that it is tethered, this should override any
2061 // findings gained from examining the endpoints.
2062 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true));
2063 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
2064
2065 // Continue in the un-tethered device case for a few more tests below.
2066 Mock::VerifyAndClearExpectations(wifi().get());
2067 EXPECT_CALL(*wifi(), IsConnectedViaTether())
2068 .WillRepeatedly(Return(false));
2069
2070 // Removing an endpoint so we only have one should put us in the "Suspected"
2071 // state.
2072 service->RemoveEndpoint(endpoint_android1);
2073 EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr));
2074
2075 // Add a different endpoint which has a locally administered MAC address
2076 // but not one used by Android.
2077 service->RemoveEndpoint(endpoint_android2);
2078 WiFiEndpointRefPtr endpoint_ios =
2079 MakeOpenEndpoint("a", "02:00:00:00:00:01", 2412, 0);
2080 service->AddEndpoint(endpoint_ios);
2081 EXPECT_EQ(kTetheringNotDetectedState, service->GetTethering(nullptr));
2082
2083 // If this endpoint reports the right vendor OUI, we should suspect
2084 // it to be tethered. However since this evaluation normally only
2085 // happens in the endpoint constructor, we must force it to recalculate.
2086 endpoint_ios->vendor_information_.oui_set.insert(Tethering::kIosOui);
2087 endpoint_ios->CheckForTetheringSignature();
2088 EXPECT_EQ(kTetheringSuspectedState, service->GetTethering(nullptr));
2089
2090 // If the device reports that it is tethered, this should override any
2091 // findings gained from examining the endpoints.
2092 Mock::VerifyAndClearExpectations(wifi().get());
2093 EXPECT_CALL(*wifi(), IsConnectedViaTether()).WillOnce(Return(true));
2094 EXPECT_EQ(kTetheringConfirmedState, service->GetTethering(nullptr));
2095 }
2096
TEST_F(WiFiServiceTest,IsVisible)2097 TEST_F(WiFiServiceTest, IsVisible) {
2098 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(kSecurityNone);
2099 ServiceMockAdaptor* adaptor = GetAdaptor(wifi_service.get());
2100
2101 // Adding the first endpoint emits a change: Visible = true.
2102 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true));
2103 WiFiEndpointRefPtr endpoint =
2104 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
2105 wifi_service->AddEndpoint(endpoint);
2106 EXPECT_TRUE(wifi_service->IsVisible());
2107 Mock::VerifyAndClearExpectations(adaptor);
2108
2109 // Removing the last endpoint emits a change: Visible = false.
2110 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false));
2111 wifi_service->RemoveEndpoint(endpoint);
2112 EXPECT_FALSE(wifi_service->IsVisible());
2113 Mock::VerifyAndClearExpectations(adaptor);
2114
2115 // Entering the a connecting state emits a change: Visible = true
2116 // although the service has no endpoints.
2117 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, true));
2118 wifi_service->SetState(Service::kStateAssociating);
2119 EXPECT_TRUE(wifi_service->IsVisible());
2120 Mock::VerifyAndClearExpectations(adaptor);
2121
2122 // Moving between connecting / connected states does not trigger an Emit.
2123 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, _)).Times(0);
2124 wifi_service->SetState(Service::kStateConfiguring);
2125 EXPECT_TRUE(wifi_service->IsVisible());
2126 Mock::VerifyAndClearExpectations(adaptor);
2127
2128 // Entering the Idle state emits a change: Visible = false.
2129 EXPECT_CALL(*adaptor, EmitBoolChanged(kVisibleProperty, false));
2130 wifi_service->SetState(Service::kStateIdle);
2131 EXPECT_FALSE(wifi_service->IsVisible());
2132 Mock::VerifyAndClearExpectations(adaptor);
2133 }
2134
TEST_F(WiFiServiceTest,ConfigurePreferredDevice)2135 TEST_F(WiFiServiceTest, ConfigurePreferredDevice) {
2136 const string kDeviceName = "test_device";
2137
2138 WiFiServiceRefPtr service = MakeGenericService();
2139 KeyValueStore args;
2140 args.SetString(kWifiPreferredDeviceProperty, kDeviceName);
2141
2142 // With no wifi device.
2143 Error error;
2144 service->Configure(args, &error);
2145 EXPECT_EQ(Error::kSuccess, error.type());
2146 EXPECT_EQ(kDeviceName, service->preferred_device_);
2147
2148 // With non-preferred wifi device.
2149 SetWiFiForService(service, wifi());
2150 service->Configure(args, &error);
2151 EXPECT_EQ(Error::kSuccess, error.type());
2152 EXPECT_EQ(nullptr, service->wifi_);
2153 EXPECT_EQ(kDeviceName, service->preferred_device_);
2154
2155 // With preferred wifi device.
2156 scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName);
2157 SetWiFiForService(service, preferred_wifi);
2158 service->Configure(args, &error);
2159 EXPECT_EQ(Error::kSuccess, error.type());
2160 EXPECT_EQ(preferred_wifi, service->wifi_);
2161 EXPECT_EQ(kDeviceName, service->preferred_device_);
2162 }
2163
TEST_F(WiFiServiceTest,LoadAndUnloadPreferredDevice)2164 TEST_F(WiFiServiceTest, LoadAndUnloadPreferredDevice) {
2165 WiFiServiceRefPtr service = MakeGenericService();
2166 NiceMock<MockStore> mock_store;
2167 const string kStorageId = service->GetStorageIdentifier();
2168 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
2169 .WillRepeatedly(Return(true));
2170 set<string> groups;
2171 groups.insert(kStorageId);
2172 EXPECT_CALL(mock_store, GetGroupsWithProperties(
2173 ContainsWiFiProperties(
2174 simple_ssid(), kModeManaged, kSecurityWep)))
2175 .WillRepeatedly(Return(groups));
2176 EXPECT_CALL(mock_store, GetBool(_, _, _))
2177 .WillRepeatedly(Return(false));
2178 const string kDeviceName = "test_device";
2179 EXPECT_CALL(mock_store,
2180 GetString(StrEq(kStorageId),
2181 WiFiService::kStoragePreferredDevice, _))
2182 .WillRepeatedly(DoAll(SetArgumentPointee<2>(kDeviceName), Return(true)));
2183 EXPECT_CALL(mock_store,
2184 GetString(StrEq(kStorageId),
2185 StrNe(WiFiService::kStoragePreferredDevice), _))
2186 .WillRepeatedly(Return(false));
2187
2188 // With no wifi device.
2189 EXPECT_TRUE(service->Load(&mock_store));
2190 EXPECT_EQ(kDeviceName, service->preferred_device_);
2191 service->Unload();
2192 EXPECT_EQ("", service->preferred_device_);
2193
2194 // With non-preferred wifi device.
2195 SetWiFiForService(service, wifi());
2196 EXPECT_TRUE(service->Load(&mock_store));
2197 EXPECT_EQ(nullptr, service->wifi_);
2198 EXPECT_EQ(kDeviceName, service->preferred_device_);
2199 service->Unload();
2200 EXPECT_EQ("", service->preferred_device_);
2201
2202 // With preferred wifi device.
2203 scoped_refptr<MockWiFi> preferred_wifi = MakeSimpleWiFi(kDeviceName);
2204 SetWiFiForService(service, preferred_wifi);
2205 EXPECT_TRUE(service->Load(&mock_store));
2206 EXPECT_EQ(preferred_wifi, service->wifi_);
2207 EXPECT_EQ(kDeviceName, service->preferred_device_);
2208 service->Unload();
2209 EXPECT_EQ("", service->preferred_device_);
2210 }
2211
TEST_F(WiFiServiceTest,ChooseDevice)2212 TEST_F(WiFiServiceTest, ChooseDevice) {
2213 const string kDeviceName1 = "test_device1";
2214 const string kDeviceName2 = "test_device2";
2215 scoped_refptr<MockWiFi> wifi1 = MakeSimpleWiFi(kDeviceName1);
2216 scoped_refptr<MockWiFi> wifi2 = MakeSimpleWiFi(kDeviceName2);
2217 WiFiServiceRefPtr service = MakeServiceWithMockManager();
2218
2219 // No preferred device.
2220 EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(_)).Times(0);
2221 EXPECT_CALL(*mock_manager(),
2222 GetEnabledDeviceWithTechnology(Technology::kWifi))
2223 .WillOnce(Return(wifi1));
2224 EXPECT_EQ(wifi1, service->ChooseDevice());
2225 Mock::VerifyAndClearExpectations(mock_manager());
2226
2227 // With preferred device.
2228 service->SetPreferredDevice(kDeviceName2, nullptr);
2229 EXPECT_CALL(*mock_manager(), GetEnabledDeviceByLinkName(kDeviceName2))
2230 .WillOnce(Return(wifi2));
2231 EXPECT_CALL(*mock_manager(), GetEnabledDeviceWithTechnology(_)).Times(0);
2232 EXPECT_EQ(wifi2, service->ChooseDevice());
2233 Mock::VerifyAndClearExpectations(mock_manager());
2234 }
2235
TEST_F(WiFiServiceTest,RoamThresholdProperty)2236 TEST_F(WiFiServiceTest, RoamThresholdProperty) {
2237 WiFiServiceRefPtr service = MakeGenericService();
2238 static const uint16_t kRoamThreshold16 = 16;
2239 static const uint16_t kRoamThreshold32 = 32;
2240
2241 EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold16));
2242 EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold16);
2243
2244 // Try a different number
2245 EXPECT_TRUE(SetRoamThreshold(service, kRoamThreshold32));
2246 EXPECT_EQ(GetRoamThreshold(service), kRoamThreshold32);
2247 }
2248
TEST_F(WiFiServiceTest,SaveLoadRoamThreshold)2249 TEST_F(WiFiServiceTest, SaveLoadRoamThreshold) {
2250 WiFiServiceRefPtr service = MakeGenericService();
2251 NiceMock<MockStore> mock_store;
2252 const uint16_t kRoamThreshold = 10;
2253 const string kStorageId = service->GetStorageIdentifier();
2254 EXPECT_CALL(mock_store, ContainsGroup(StrEq(kStorageId)))
2255 .WillRepeatedly(Return(true));
2256 set<string> groups;
2257 groups.insert(kStorageId);
2258 EXPECT_CALL(mock_store, GetGroupsWithProperties(ContainsWiFiProperties(
2259 simple_ssid(), kModeManaged, kSecurityWep)))
2260 .WillRepeatedly(Return(groups));
2261 EXPECT_CALL(mock_store, GetBool(_, _, _)).Times(AnyNumber());
2262 EXPECT_CALL(mock_store, SetBool(_, _, _)).Times(AnyNumber());
2263
2264 // First, save these values.
2265 service->roam_threshold_db_ = kRoamThreshold;
2266 service->roam_threshold_db_set_ = true;
2267 EXPECT_CALL(mock_store,
2268 SetUint64(StrEq(kStorageId), WiFiService::kStorageRoamThreshold,
2269 kRoamThreshold));
2270 EXPECT_CALL(mock_store, SetBool(StrEq(kStorageId),
2271 WiFiService::kStorageRoamThresholdSet, true));
2272 EXPECT_TRUE(service->Save(&mock_store));
2273
2274 // Then, load these values into the WiFiService members.
2275 service->roam_threshold_db_ = 0;
2276 service->roam_threshold_db_set_ = false;
2277 EXPECT_CALL(mock_store, GetUint64(StrEq(kStorageId),
2278 WiFiService::kStorageRoamThreshold, _))
2279 .WillOnce(DoAll(SetArgumentPointee<2>(kRoamThreshold), Return(true)));
2280 EXPECT_CALL(mock_store, GetBool(StrEq(kStorageId),
2281 WiFiService::kStorageRoamThresholdSet, _))
2282 .WillOnce(DoAll(SetArgumentPointee<2>(true), Return(true)));
2283 EXPECT_TRUE(service->Load(&mock_store));
2284 EXPECT_EQ(kRoamThreshold, service->roam_threshold_db_);
2285 EXPECT_TRUE(service->roam_threshold_db_set_);
2286 }
2287
2288 } // namespace shill
2289