blob: dfa02142163d0b95421292f4b19389f02f56483a [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone34af2182011-08-22 11:59:36 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/wifi_service.h"
6
mukesh agrawald835b202011-10-07 15:26:47 -07007#include <map>
Paul Stewart85aea152013-01-22 09:31:56 -08008#include <set>
Chris Masone34af2182011-08-22 11:59:36 -07009#include <string>
10#include <vector>
11
Paul Stewart85aea152013-01-22 09:31:56 -080012#include <base/stringprintf.h>
Chris Masone34af2182011-08-22 11:59:36 -070013#include <base/string_util.h>
14#include <chromeos/dbus/service_constants.h>
15#include <gmock/gmock.h>
16#include <gtest/gtest.h>
17
Paul Stewart26b327e2011-10-19 11:38:09 -070018#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070019#include "shill/manager.h"
20#include "shill/mock_adaptors.h"
21#include "shill/mock_control.h"
Paul Stewartecf4cd12012-04-17 11:08:39 -070022#include "shill/mock_nss.h"
Christopher Wiley1ce658d2012-10-10 10:02:03 -070023#include "shill/mock_profile.h"
Chris Masone34af2182011-08-22 11:59:36 -070024#include "shill/mock_service.h"
25#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070026#include "shill/mock_wifi.h"
Chris Masone34af2182011-08-22 11:59:36 -070027#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000028#include "shill/refptr_types.h"
29#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070030#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070031
mukesh agrawald835b202011-10-07 15:26:47 -070032using std::map;
Paul Stewart85aea152013-01-22 09:31:56 -080033using std::set;
Chris Masone34af2182011-08-22 11:59:36 -070034using std::string;
35using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070036using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080037using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070038using ::testing::DoAll;
mukesh agrawale1d90e92012-02-15 17:36:08 -080039using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070040using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070041using ::testing::Return;
42using ::testing::SetArgumentPointee;
43using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080044using ::testing::StrNe;
Paul Stewart85aea152013-01-22 09:31:56 -080045using ::testing::StrictMock;
Chris Masone34af2182011-08-22 11:59:36 -070046
mukesh agrawalb20776f2012-02-10 16:00:36 -080047namespace shill {
48
Chris Masone34af2182011-08-22 11:59:36 -070049class WiFiServiceTest : public PropertyStoreTest {
50 public:
mukesh agrawal6e277772011-09-29 15:04:23 -070051 WiFiServiceTest() : wifi_(
52 new NiceMock<MockWiFi>(
53 control_interface(),
54 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080055 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -070056 manager(),
57 "wifi",
58 fake_mac,
59 0)) {}
Chris Masone34af2182011-08-22 11:59:36 -070060 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070061
62 protected:
63 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080064
Gaurav Shah10109f22011-11-11 20:16:22 -080065 bool CheckConnectable(const std::string &security, const char *passphrase,
66 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000067 Error error;
68 vector<uint8_t> ssid(1, 'a');
69 WiFiServiceRefPtr service = new WiFiService(control_interface(),
70 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080071 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000072 manager(),
73 wifi(),
74 ssid,
75 flimflam::kModeManaged,
76 security,
77 false);
78 if (passphrase)
79 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080080 if (eap) {
81 service->set_eap(*eap);
82 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000083 return service->connectable();
84 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080085 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
86 uint16 frequency, int16 signal_dbm) {
87 return WiFiEndpoint::MakeOpenEndpoint(
88 NULL, NULL, ssid, bssid, frequency, signal_dbm);
89 }
90 WiFiService *MakeGenericService() {
91 return new WiFiService(control_interface(),
92 dispatcher(),
93 metrics(),
94 manager(),
95 wifi(),
96 vector<uint8_t>(),
97 flimflam::kModeManaged,
98 flimflam::kSecurityWep,
99 false);
100 }
101 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
102 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000103 }
mukesh agrawal6e277772011-09-29 15:04:23 -0700104 scoped_refptr<MockWiFi> wifi() { return wifi_; }
105
106 private:
107 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -0700108};
109
mukesh agrawal6e277772011-09-29 15:04:23 -0700110// static
111const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
112
Paul Stewartd08f4432011-11-04 07:48:20 -0700113class WiFiServiceSecurityTest : public WiFiServiceTest {
114 public:
115 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800116 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700117 ssid.push_back(0xff);
118
119 return new WiFiService(control_interface(),
120 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800121 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700122 manager(),
123 wifi(),
124 ssid,
125 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800126 security,
127 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700128 }
129
130 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
131 const string &security) {
132 string id = wifi_service->GetStorageIdentifier();
133 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
134 EXPECT_NE(mac_pos, string::npos);
135 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
136 EXPECT_NE(mode_pos, string::npos);
137 return id.find(string(security), mode_pos) != string::npos;
138 }
139
140 // Test that a service that is created with security |from_security|
141 // gets by default a storage identifier with |to_security| as its
142 // security component.
143 bool TestStorageMapping(const string &from_security,
144 const string &to_security) {
145 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
146 return TestStorageSecurityIs(wifi_service, to_security);
147 }
148
149 // Test whether a service of type |service_security| can load from a
150 // storage interface containing an entry for |storage_security|.
151 // Make sure the result meets |expectation|. If |expectation| is
152 // true, also make sure the service storage identifier changes to
153 // match |storage_security|.
154 bool TestLoadMapping(const string &service_security,
155 const string &storage_security,
156 bool expectation) {
157 WiFiServiceRefPtr wifi_service =
158 CreateServiceWithSecurity(service_security);
159 NiceMock<MockStore> mock_store;
160 const string storage_id =
161 wifi_service->GetStorageIdentifierForSecurity(storage_security);
162 EXPECT_CALL(mock_store, ContainsGroup(_))
163 .WillRepeatedly(Return(false));
164 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
165 .WillRepeatedly(Return(true));
166 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
167 EXPECT_EQ(expectation, is_loadable);
168 bool is_loaded = wifi_service->Load(&mock_store);
169 EXPECT_EQ(expectation, is_loaded);
170
171 if (expectation != is_loadable || expectation != is_loaded) {
172 return false;
173 } else if (!expectation) {
174 return true;
175 } else {
176 return TestStorageSecurityIs(wifi_service, storage_security);
177 }
178 }
179};
180
mukesh agrawale1d90e92012-02-15 17:36:08 -0800181class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
182 public:
183 WiFiServiceUpdateFromEndpointsTest()
184 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
185 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
186 kGoodEndpointStrength(
187 WiFiService::SignalToStrength(kGoodEndpointSignal)),
188 service(MakeGenericService()),
189 adaptor(*GetAdaptor(service)) {
190 ok_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700191 "", kOkEndpointBssId, kOkEndpointFrequency, kOkEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800192 good_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700193 "", kGoodEndpointBssId, kGoodEndpointFrequency, kGoodEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800194 bad_endpoint = MakeEndpoint(
mukesh agrawal923f14f2012-06-04 16:46:08 -0700195 "", kBadEndpointBssId, kBadEndpointFrequency, kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800196 }
197
198 protected:
199 static const uint16 kOkEndpointFrequency = 2422;
200 static const uint16 kBadEndpointFrequency = 2417;
201 static const uint16 kGoodEndpointFrequency = 2412;
202 static const int16 kOkEndpointSignal = -50;
203 static const int16 kBadEndpointSignal = -75;
204 static const int16 kGoodEndpointSignal = -25;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700205 static const char *kOkEndpointBssId;
206 static const char *kGoodEndpointBssId;
207 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800208 // Can't be both static and const (because initialization requires a
209 // function call). So choose to be just const.
210 const uint8 kOkEndpointStrength;
211 const uint8 kBadEndpointStrength;
212 const uint8 kGoodEndpointStrength;
213 WiFiEndpointRefPtr ok_endpoint;
214 WiFiEndpointRefPtr bad_endpoint;
215 WiFiEndpointRefPtr good_endpoint;
216 WiFiServiceRefPtr service;
217 ServiceMockAdaptor &adaptor;
218};
219
mukesh agrawal923f14f2012-06-04 16:46:08 -0700220const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
221 "00:00:00:00:00:01";
222const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
223 "00:00:00:00:00:02";
224const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
225 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800226
Paul Stewart85aea152013-01-22 09:31:56 -0800227class WiFiServiceFixupStorageTest : public WiFiServiceTest {
228 protected:
229 void AddGroup(string group_name) {
230 groups_.insert(group_name);
231 }
232
233 void AddServiceEntry(bool has_type, bool has_mode, bool has_security) {
234 int index = groups_.size();
235 string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
236 index, index, flimflam::kModeManaged,
237 flimflam::kSecurityNone);
238 AddGroup(id);
239 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
240 .WillOnce(Return(has_type));
241 if (!has_type) {
242 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
243 flimflam::kTypeWifi));
244 }
245 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
246 .WillOnce(Return(has_mode));
247 if (!has_mode) {
248 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
249 flimflam::kModeManaged));
250 }
251 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
252 .WillOnce(Return(has_security));
253 if (!has_security) {
254 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
255 flimflam::kSecurityNone));
256 }
257 }
258
259 bool FixupServiceEntries() {
260 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
261 return WiFiService::FixupServiceEntries(&store_);
262 }
263
264 private:
265 StrictMock<MockStore> store_;
266 set<string> groups_;
267};
268
Chris Masone34af2182011-08-22 11:59:36 -0700269TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800270 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700271 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700272
Chris Masone2176a882011-09-14 22:29:15 -0700273 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
274 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800275 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700276 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700277 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700278 ssid,
279 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800280 flimflam::kSecurityNone,
281 false);
Chris Masone9d779932011-08-25 16:33:41 -0700282 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700283 for (uint i = 0; i < id.length(); ++i) {
284 EXPECT_TRUE(id[i] == '_' ||
285 isxdigit(id[i]) ||
286 (isalpha(id[i]) && islower(id[i])));
287 }
Chris Masone34af2182011-08-22 11:59:36 -0700288 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
289 EXPECT_NE(mac_pos, string::npos);
290 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
291}
292
Gaurav Shahda6218a2011-11-11 12:09:33 -0800293// Make sure the passphrase is registered as a write only property
294// by reading and comparing all string properties returned on the store.
295TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
296 vector<uint8_t> ssid(5);
297 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
298 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800299 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800300 manager(),
301 wifi(),
302 ssid,
303 flimflam::kModeManaged,
304 flimflam::kSecurityWpa,
305 false);
306 ReadablePropertyConstIterator<string> it =
307 (wifi_service->store()).GetStringPropertiesIter();
308 for( ; !it.AtEnd(); it.Advance())
309 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
310}
311
Thieu Lef7709452011-11-15 01:13:19 +0000312// Make sure setting the passphrase via D-Bus Service.SetProperty validates
313// the passphrase.
314TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
315 // We only spot check two password cases here to make sure the
316 // SetProperty code path does validation. We're not going to exhaustively
317 // test for all types of passwords.
318 vector<uint8_t> ssid(5);
319 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
320 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800321 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000322 manager(),
323 wifi(),
324 ssid,
325 flimflam::kModeManaged,
326 flimflam::kSecurityWep,
327 false);
328 Error error;
329 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
330 flimflam::kPassphraseProperty, "0:abcde", &error));
331 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
332 flimflam::kPassphraseProperty, "invalid", &error));
333 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
334}
335
336TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
337 vector<uint8_t> ssid(5);
338 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
339 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800340 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000341 manager(),
342 wifi(),
343 ssid,
344 flimflam::kModeManaged,
345 flimflam::kSecurityNone,
346 false);
347 Error error;
348 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
349 flimflam::kPassphraseProperty, "invalid", &error));
350 EXPECT_EQ(Error::kNotSupported, error.type());
351}
352
mukesh agrawald835b202011-10-07 15:26:47 -0700353TEST_F(WiFiServiceTest, NonUTF8SSID) {
354 vector<uint8_t> ssid;
355
356 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
357 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
358 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800359 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700360 manager(),
361 wifi(),
362 ssid,
363 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800364 flimflam::kSecurityNone,
365 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700366 map<string, ::DBus::Variant> properties;
367 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
368 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
369}
370
Gaurav Shahda6218a2011-11-11 12:09:33 -0800371MATCHER(WPASecurityArgs, "") {
372 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
373 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
374}
375
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800376MATCHER(WPA80211wSecurityArgs, "") {
377 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
378 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey) &&
379 ContainsKey(arg, wpa_supplicant::kNetworkPropertyIeee80211w);
380}
381
Gaurav Shah10109f22011-11-11 20:16:22 -0800382MATCHER(EAPSecurityArgs, "") {
383 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
384 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
385}
386
Paul Stewarte2d7c502012-07-16 16:35:10 -0700387MATCHER_P(FrequencyArg, has_arg, "") {
388 return has_arg ==
389 ContainsKey(arg, wpa_supplicant::kNetworkPropertyFrequency);
390}
391
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700392TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800393 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700394 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
395 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800396 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700397 manager(),
398 wifi(),
399 ssid,
400 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800401 flimflam::kSecurityWpa,
402 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700403 EXPECT_CALL(*wifi(),
404 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700405 Error error;
406 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500407 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700408}
409
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700410TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800411 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700412 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
413 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800414 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700415 manager(),
416 wifi(),
417 ssid,
418 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800419 flimflam::kSecurityRsn,
420 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700421 EXPECT_CALL(*wifi(),
422 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700423 Error error;
424 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500425 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700426}
427
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700428TEST_F(WiFiServiceTest, ConnectConditions) {
429 Error error;
430 vector<uint8_t> ssid(5);
431 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
432 dispatcher(),
433 metrics(),
434 manager(),
435 wifi(),
436 ssid,
437 flimflam::kModeManaged,
438 flimflam::kSecurityNone,
439 false);
440 scoped_refptr<MockProfile> mock_profile(
441 new NiceMock<MockProfile>(control_interface(), manager()));
442 wifi_service->set_profile(mock_profile);
443 // With nothing else going on, the service should attempt to connect.
444 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
445 wifi_service->Connect(&error);
446 Mock::VerifyAndClearExpectations(wifi());
447
448 // But if we're already "connecting" or "connected" then we shouldn't attempt
449 // again.
450 EXPECT_CALL(*wifi(),
451 ConnectTo(wifi_service.get(), _)).Times(0);
452 wifi_service->SetState(Service::kStateAssociating);
453 wifi_service->Connect(&error);
454 wifi_service->SetState(Service::kStateConfiguring);
455 wifi_service->Connect(&error);
456 wifi_service->SetState(Service::kStateConnected);
457 wifi_service->Connect(&error);
458 wifi_service->SetState(Service::kStatePortal);
459 wifi_service->Connect(&error);
460 wifi_service->SetState(Service::kStateOnline);
461 wifi_service->Connect(&error);
462 Mock::VerifyAndClearExpectations(wifi());
463}
464
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800465TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800466 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800467 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
468 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800469 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800470 manager(),
471 wifi(),
472 ssid,
473 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800474 flimflam::kSecurityPsk,
475 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800476 EXPECT_CALL(*wifi(),
477 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700478 Error error;
479 wifi_service->SetPassphrase("0:mumblemumblem", &error);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500480 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800481}
482
Gaurav Shah10109f22011-11-11 20:16:22 -0800483TEST_F(WiFiServiceTest, ConnectTask8021x) {
484 vector<uint8_t> ssid(5);
485 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
486 dispatcher(),
487 metrics(),
488 manager(),
489 wifi(),
490 ssid,
491 flimflam::kModeManaged,
492 flimflam::kSecurity8021x,
493 false);
494 Service::EapCredentials eap;
495 eap.identity = "identity";
Wade Guthrie005bd342012-05-02 09:37:07 -0700496 eap.password = "mumble";
Gaurav Shah10109f22011-11-11 20:16:22 -0800497 wifi_service->set_eap(eap);
498 EXPECT_CALL(*wifi(),
499 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500500 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800501}
502
Paul Stewarte2d7c502012-07-16 16:35:10 -0700503TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
504 vector<uint8_t> ssid(1, 'a');
505 WiFiEndpointRefPtr endpoint_nofreq =
506 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
507 WiFiEndpointRefPtr endpoint_freq =
508 MakeEndpoint("a", "00:00:00:00:00:02", 2412, 0);
509
510 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
511 dispatcher(),
512 metrics(),
513 manager(),
514 wifi(),
515 ssid,
516 flimflam::kModeManaged,
517 flimflam::kSecurityNone,
518 false);
519 wifi_service->AddEndpoint(endpoint_freq);
520 EXPECT_CALL(*wifi(),
521 ConnectTo(wifi_service.get(), FrequencyArg(false)));
522 wifi_service->Connect(NULL);
523
524 wifi_service = new WiFiService(control_interface(),
525 dispatcher(),
526 metrics(),
527 manager(),
528 wifi(),
529 ssid,
530 flimflam::kModeAdhoc,
531 flimflam::kSecurityNone,
532 false);
533 EXPECT_CALL(*wifi(),
534 ConnectTo(wifi_service.get(), FrequencyArg(false)));
535 wifi_service->Connect(NULL);
536
537 wifi_service = new WiFiService(control_interface(),
538 dispatcher(),
539 metrics(),
540 manager(),
541 wifi(),
542 ssid,
543 flimflam::kModeAdhoc,
544 flimflam::kSecurityNone,
545 false);
546 wifi_service->AddEndpoint(endpoint_nofreq);
547 EXPECT_CALL(*wifi(),
548 ConnectTo(wifi_service.get(), FrequencyArg(false)));
549 wifi_service->Connect(NULL);
550
551 wifi_service = new WiFiService(control_interface(),
552 dispatcher(),
553 metrics(),
554 manager(),
555 wifi(),
556 ssid,
557 flimflam::kModeAdhoc,
558 flimflam::kSecurityNone,
559 false);
560 wifi_service->AddEndpoint(endpoint_freq);
561 EXPECT_CALL(*wifi(),
562 ConnectTo(wifi_service.get(), FrequencyArg(true)));
563 wifi_service->Connect(NULL);
564}
565
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800566TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
567 vector<uint8_t> ssid(1, 'a');
568 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
569 dispatcher(),
570 metrics(),
571 manager(),
572 wifi(),
573 ssid,
574 flimflam::kModeManaged,
575 flimflam::kSecurityPsk,
576 false);
577 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
578 endpoint->ieee80211w_required_ = true;
579 wifi_service->AddEndpoint(endpoint);
580 Error error;
581 wifi_service->SetPassphrase("0:mumblemumblem", &error);
582 EXPECT_CALL(*wifi(),
583 ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
584 wifi_service->Connect(NULL);
585}
586
Thieu Lef4cbda92011-11-10 23:41:24 +0000587MATCHER(WEPSecurityArgsKeyIndex0, "") {
588 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
589 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
590 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
591 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
592 reader().get_uint32() == 0);
593}
594
595MATCHER(WEPSecurityArgsKeyIndex1, "") {
596 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
597 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
598 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
599 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
600 reader().get_uint32() == 1);
601}
602
603MATCHER(WEPSecurityArgsKeyIndex2, "") {
604 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
605 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
606 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
607 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
608 reader().get_uint32() == 2);
609}
610
611MATCHER(WEPSecurityArgsKeyIndex3, "") {
612 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
613 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
614 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
615 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
616 reader().get_uint32() == 3);
617}
618
619TEST_F(WiFiServiceTest, ConnectTaskWEP) {
620 vector<uint8_t> ssid(5);
621 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
622 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800623 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000624 manager(),
625 wifi(),
626 ssid,
627 flimflam::kModeManaged,
628 flimflam::kSecurityWep,
629 false);
630 Error error;
631 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
632 EXPECT_CALL(*wifi(),
633 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500634 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000635
636 wifi_service->SetPassphrase("abcdefghijklm", &error);
637 EXPECT_CALL(*wifi(),
638 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500639 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000640
641 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
642 EXPECT_CALL(*wifi(),
643 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500644 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000645
646 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
647 EXPECT_CALL(*wifi(),
648 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500649 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000650
651 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
652 EXPECT_CALL(*wifi(),
653 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500654 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000655}
656
Gaurav Shah29d68882012-01-30 19:06:42 -0800657
658MATCHER(DynamicWEPArgs, "") {
659 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
660 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
661 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
662}
663
664// Dynamic WEP + 802.1x.
665TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
666 vector<uint8_t> ssid(5);
667 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
668 dispatcher(),
669 metrics(),
670 manager(),
671 wifi(),
672 ssid,
673 flimflam::kModeManaged,
674 flimflam::kSecurityWep,
675 false);
676
677 Service::EapCredentials eap;
678 eap.key_management = "IEEE8021X";
679 eap.identity = "something";
Wade Guthrie005bd342012-05-02 09:37:07 -0700680 eap.password = "mumble";
Gaurav Shah29d68882012-01-30 19:06:42 -0800681 wifi_service->set_eap(eap);
682 EXPECT_CALL(*wifi(),
683 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500684 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800685}
686
Paul Stewart835934a2012-12-06 19:27:09 -0800687TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
688 vector<uint8_t> ssid(5);
689 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
690 dispatcher(),
691 metrics(),
692 manager(),
693 wifi(),
694 ssid,
695 flimflam::kModeManaged,
696 flimflam::kSecurityRsn,
697 false);
698
699 const string kPassphrase = "abcdefgh";
700
701 {
702 Error error;
703 // A changed passphrase should trigger cache removal.
704 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
705 wifi_service->SetPassphrase(kPassphrase, &error);
706 Mock::VerifyAndClearExpectations(wifi());
707 EXPECT_TRUE(error.IsSuccess());
708 }
709
710 {
711 Error error;
712 // An unchanged passphrase should not trigger cache removal.
713 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
714 wifi_service->SetPassphrase(kPassphrase, &error);
715 Mock::VerifyAndClearExpectations(wifi());
716 EXPECT_TRUE(error.IsSuccess());
717 }
718
719 {
720 Error error;
721 // A modified passphrase should trigger cache removal.
722 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
723 wifi_service->SetPassphrase(kPassphrase + "X", &error);
724 Mock::VerifyAndClearExpectations(wifi());
725 EXPECT_TRUE(error.IsSuccess());
726 }
727
728 {
729 Error error;
730 // A cleared passphrase should also trigger cache removal.
731 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
732 wifi_service->ClearPassphrase(&error);
733 Mock::VerifyAndClearExpectations(wifi());
734 EXPECT_TRUE(error.IsSuccess());
735 }
736
737 {
738 Error error;
739 // An invalid passphrase should not trigger cache removal.
740 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
741 wifi_service->SetPassphrase("", &error);
742 Mock::VerifyAndClearExpectations(wifi());
743 EXPECT_FALSE(error.IsSuccess());
744 }
745
746 {
747 // Any change to EAP parameters (including a null one) will trigger cache
748 // removal. This is a lot less granular than the passphrase checks above.
749 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
750 wifi_service->set_eap(Service::EapCredentials());
751 Mock::VerifyAndClearExpectations(wifi());
752 }
753}
754
Paul Stewartd08f4432011-11-04 07:48:20 -0700755TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800756 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700757 ssid.push_back(0xff);
758
759 WiFiServiceRefPtr service = new WiFiService(control_interface(),
760 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800761 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700762 manager(),
763 wifi(),
764 ssid,
765 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800766 flimflam::kSecurityNone,
767 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700768 ASSERT_FALSE(service->hidden_ssid_);
769 NiceMock<MockStore> mock_store;
770 const string storage_id = service->GetStorageIdentifier();
771 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
772 .WillRepeatedly(Return(true));
773 EXPECT_CALL(mock_store, GetBool(_, _, _))
774 .WillRepeatedly(Return(false));
775 EXPECT_CALL(mock_store,
776 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
777 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
778 EXPECT_TRUE(service->Load(&mock_store));
779 EXPECT_TRUE(service->hidden_ssid_);
780}
781
782TEST_F(WiFiServiceSecurityTest, WPAMapping) {
783 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
784 flimflam::kSecurityPsk));
785 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
786 flimflam::kSecurityPsk));
787 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
788 flimflam::kSecurityPsk));
789 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
790 flimflam::kSecurityWep));
791 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
792 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800793 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
794 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700795}
796
797TEST_F(WiFiServiceSecurityTest, LoadMapping) {
798 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
799 flimflam::kSecurityPsk,
800 true));
801 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
802 flimflam::kSecurityRsn,
803 true));
804 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
805 flimflam::kSecurityWpa,
806 false));
807 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
808 flimflam::kSecurityPsk,
809 true));
810 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
811 flimflam::kSecurityWpa,
812 true));
813 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
814 flimflam::kSecurityRsn,
815 false));
816 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
817 flimflam::kSecurityWep,
818 true));
819 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
820 flimflam::kSecurityPsk,
821 false));
822}
823
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800824TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
825 vector<uint8_t> ssid(5);
826 ssid.push_back(0xff);
827
828 WiFiServiceRefPtr service = new WiFiService(control_interface(),
829 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800830 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800831 manager(),
832 wifi(),
833 ssid,
834 flimflam::kModeManaged,
835 flimflam::kSecurityPsk,
836 false);
837 NiceMock<MockStore> mock_store;
838 const string storage_id = service->GetStorageIdentifier();
839 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
840 .WillRepeatedly(Return(true));
841 EXPECT_CALL(mock_store, GetBool(_, _, _))
842 .WillRepeatedly(Return(false));
843 const string passphrase = "passphrase";
844 EXPECT_CALL(mock_store,
845 GetCryptedString(StrEq(storage_id),
846 WiFiService::kStoragePassphrase, _))
847 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
848 EXPECT_CALL(mock_store,
849 GetCryptedString(StrEq(storage_id),
850 StrNe(WiFiService::kStoragePassphrase), _))
851 .WillRepeatedly(Return(false));
852 EXPECT_TRUE(service->need_passphrase_);
853 EXPECT_TRUE(service->Load(&mock_store));
854 EXPECT_EQ(passphrase, service->passphrase_);
855 EXPECT_TRUE(service->connectable());
856 EXPECT_FALSE(service->need_passphrase_);
857 service->Unload();
858 EXPECT_EQ(string(""), service->passphrase_);
859 EXPECT_FALSE(service->connectable());
860 EXPECT_TRUE(service->need_passphrase_);
861}
862
Christopher Wiley27b47232012-11-02 13:13:00 -0700863TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
864 string guid("legit_guid");
865 KeyValueStore args;
866 args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
867 args.SetString(flimflam::kEapPasswordProperty, "legit_password");
868 args.SetString(flimflam::kEAPEAPProperty, "PEAP");
869 args.SetString(flimflam::kGuidProperty, guid);
870 Error error;
871 vector<uint8_t> ssid(5);
872 ssid.push_back(0xff);
873
874 WiFiServiceRefPtr service = new WiFiService(control_interface(),
875 dispatcher(),
876 metrics(),
877 manager(),
878 wifi(),
879 ssid,
880 flimflam::kModeManaged,
881 flimflam::kSecurity8021x,
882 false);
883 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
884 // our service. This way, Manager will handle the lookup itself.
885 service->set_guid(guid);
886 manager()->RegisterService(service);
887 EXPECT_FALSE(service->connectable());
888 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
889 EXPECT_TRUE(error.IsSuccess());
890 EXPECT_TRUE(service->connectable());
891}
892
Paul Stewart835934a2012-12-06 19:27:09 -0800893TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
Paul Stewart66c86002012-01-30 18:00:52 -0800894 vector<uint8_t> ssid(1, 'a');
895 WiFiServiceRefPtr service = new WiFiService(control_interface(),
896 dispatcher(),
897 metrics(),
898 manager(),
899 wifi(),
900 ssid,
901 flimflam::kModeManaged,
902 flimflam::kSecurityWep,
903 false);
Paul Stewart835934a2012-12-06 19:27:09 -0800904 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
905 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800906 service->Unload();
907}
908
909TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
910 vector<uint8_t> ssid(1, 'a');
911 WiFiServiceRefPtr service = new WiFiService(control_interface(),
912 dispatcher(),
913 metrics(),
914 manager(),
915 wifi(),
916 ssid,
917 flimflam::kModeManaged,
918 flimflam::kSecurity8021x,
919 false);
Paul Stewart835934a2012-12-06 19:27:09 -0800920 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
921 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -0800922 service->Unload();
923}
924
Paul Stewart0756db92012-01-27 08:34:47 -0800925TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800926 vector<uint8_t> ssid(5);
927 ssid.push_back(0xff);
928
929 WiFiServiceRefPtr service = new WiFiService(control_interface(),
930 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800931 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800932 manager(),
933 wifi(),
934 ssid,
935 flimflam::kModeManaged,
936 flimflam::kSecurityNone,
937 false);
938 const string storage_id = service->GetStorageIdentifier();
939 string address;
940 string mode;
941 string security;
942 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
943 &security));
944 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
945 EXPECT_EQ(flimflam::kModeManaged, mode);
946 EXPECT_EQ(flimflam::kSecurityNone, security);
947}
948
Paul Stewart0756db92012-01-27 08:34:47 -0800949TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
950 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
951 // which needs to be dealt with specially in the parser.
952 vector<uint8_t> ssid(5);
953 ssid.push_back(0xff);
954
955 WiFiServiceRefPtr service = new WiFiService(control_interface(),
956 dispatcher(),
957 metrics(),
958 manager(),
959 wifi(),
960 ssid,
961 flimflam::kModeManaged,
962 flimflam::kSecurity8021x,
963 false);
964 const string storage_id = service->GetStorageIdentifier();
965 string address;
966 string mode;
967 string security;
968 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
969 &security));
970 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
971 EXPECT_EQ(flimflam::kModeManaged, mode);
972 EXPECT_EQ(flimflam::kSecurity8021x, security);
973}
974
Paul Stewart85aea152013-01-22 09:31:56 -0800975TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
976 const string kNonWiFiId = "vpn_foo";
977 const string kUnparsableWiFiId = "wifi_foo";
978
979 AddGroup(kNonWiFiId);
980 AddGroup(kUnparsableWiFiId);
981 AddServiceEntry(true, true, true);
982 AddServiceEntry(false, false, false);
983 AddServiceEntry(true, true, true);
984 AddServiceEntry(false, false, false);
985 EXPECT_TRUE(FixupServiceEntries());
986}
987
988TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
989 const string kNonWiFiId = "vpn_foo";
990 const string kUnparsableWiFiId = "wifi_foo";
991
992 AddGroup(kNonWiFiId);
993 AddGroup(kUnparsableWiFiId);
994 AddServiceEntry(true, true, true);
995 EXPECT_FALSE(FixupServiceEntries());
996}
997
998TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
999 AddServiceEntry(false, true, true);
1000 EXPECT_TRUE(FixupServiceEntries());
1001}
1002
1003TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
1004 AddServiceEntry(true, false, true);
1005 EXPECT_TRUE(FixupServiceEntries());
1006}
1007
1008TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
1009 AddServiceEntry(true, true, false);
1010 EXPECT_TRUE(FixupServiceEntries());
1011}
1012
1013
mukesh agrawal29c13a12011-11-24 00:09:19 +00001014TEST_F(WiFiServiceTest, Connectable) {
1015 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001016 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001017
1018 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -08001019 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001020
1021 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001022 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001023
1024 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001025 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001026
1027 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001028 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001029
1030 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -08001031 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
1032 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
1033 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001034
1035 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -08001036 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
1037
1038 Service::EapCredentials eap;
1039 // Empty EAP credentials should not make a 802.1x network connectable.
1040 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1041
1042 eap.identity = "something";
1043 // If client certificate is being used, a private key must exist.
1044 eap.client_cert = "some client cert";
1045 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1046 eap.private_key = "some private key";
1047 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1048
1049 // Identity is always required.
1050 eap.identity.clear();
1051 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1052
1053 eap.identity = "something";
1054 // For non EAP-TLS types, a password is required.
1055 eap.eap = "Non-TLS";
1056 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
1057 eap.password = "some password";
1058 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -08001059 // Dynamic WEP + 802.1X should be connectable under the same conditions.
1060 eap.key_management = "IEEE8021X";
1061 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001062}
1063
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001064TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001065 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001066 vector<uint8_t> ssid(1, 'a');
1067 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1068 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001069 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001070 manager(),
1071 wifi(),
1072 ssid,
1073 flimflam::kModeManaged,
1074 flimflam::kSecurityNone,
1075 false);
1076 EXPECT_CALL(*wifi(), IsIdle())
1077 .WillRepeatedly(Return(true));
1078 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001079 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1080 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001081
mukesh agrawalbf14e942012-03-02 14:36:34 -08001082 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -08001083 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001084 service->AddEndpoint(endpoint);
1085 EXPECT_CALL(*wifi(), IsIdle())
1086 .WillRepeatedly(Return(true));
1087 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001088 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1089 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001090
1091 // WiFi only supports connecting to one Service at a time. So, to
1092 // avoid disrupting connectivity, we only allow auto-connection to
1093 // a WiFiService when the corresponding WiFi is idle.
1094 EXPECT_CALL(*wifi(), IsIdle())
1095 .WillRepeatedly(Return(false));
1096 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001097 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1098 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001099}
1100
1101TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001102 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001103 vector<uint8_t> ssid(1, 'a');
1104 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1105 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -08001106 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001107 manager(),
1108 wifi(),
1109 ssid,
1110 flimflam::kModeManaged,
1111 flimflam::kSecurityNone,
1112 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001113 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001114 EXPECT_CALL(*wifi(), ConnectTo(_, _))
1115 .Times(0);
1116 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001117 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001118
mukesh agrawale1d90e92012-02-15 17:36:08 -08001119 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001120 service->AddEndpoint(endpoint);
1121 EXPECT_CALL(*wifi(), IsIdle())
1122 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001123 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001124 EXPECT_CALL(*wifi(), ConnectTo(_, _));
1125 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001126 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -08001127
1128 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001129 service->UserInitiatedDisconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001130 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -08001131 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001132}
1133
Gaurav Shah10109f22011-11-11 20:16:22 -08001134TEST_F(WiFiServiceTest, Populate8021x) {
1135 vector<uint8_t> ssid(1, 'a');
1136 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1137 dispatcher(),
1138 metrics(),
1139 manager(),
1140 wifi(),
1141 ssid,
1142 flimflam::kModeManaged,
1143 flimflam::kSecurityNone,
1144 false);
1145 Service::EapCredentials eap;
1146 eap.identity = "testidentity";
Paul Stewart20550982012-04-16 12:16:11 -07001147 eap.pin = "xxxx";
Gaurav Shah10109f22011-11-11 20:16:22 -08001148 service->set_eap(eap);
1149 map<string, ::DBus::Variant> params;
1150 service->Populate8021xProperties(&params);
1151 // Test that only non-empty 802.1x properties are populated.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001152 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapIdentity));
1153 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1154 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1155
Paul Stewart20550982012-04-16 12:16:11 -07001156 // Test that CA path is set by default.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001157 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
1158
Paul Stewart20550982012-04-16 12:16:11 -07001159 // Test that hardware-backed security arguments are not set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001160 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1161 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1162 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
Paul Stewart20550982012-04-16 12:16:11 -07001163}
1164
1165TEST_F(WiFiServiceTest, Populate8021xNoSystemCAs) {
1166 vector<uint8_t> ssid(1, 'a');
1167 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1168 dispatcher(),
1169 metrics(),
1170 manager(),
1171 wifi(),
1172 ssid,
1173 flimflam::kModeManaged,
1174 flimflam::kSecurityNone,
1175 false);
1176 Service::EapCredentials eap;
1177 eap.identity = "testidentity";
1178 eap.use_system_cas = false;
1179 service->set_eap(eap);
1180 map<string, ::DBus::Variant> params;
1181 service->Populate8021xProperties(&params);
1182 // Test that CA path is not set if use_system_cas is explicitly false.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001183 EXPECT_FALSE(ContainsKey(params, wpa_supplicant::kNetworkPropertyCaPath));
Paul Stewart20550982012-04-16 12:16:11 -07001184}
1185
1186TEST_F(WiFiServiceTest, Populate8021xUsingHardwareAuth) {
1187 vector<uint8_t> ssid(1, 'a');
1188 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1189 dispatcher(),
1190 metrics(),
1191 manager(),
1192 wifi(),
1193 ssid,
1194 flimflam::kModeManaged,
1195 flimflam::kSecurityNone,
1196 false);
1197 Service::EapCredentials eap;
1198 eap.identity = "testidentity";
1199 eap.key_id = "key_id";
1200 eap.pin = "xxxx";
1201 service->set_eap(eap);
1202 map<string, ::DBus::Variant> params;
1203 service->Populate8021xProperties(&params);
1204 // Test that EAP engine parameters set if key_id is set.
Paul Stewartecf4cd12012-04-17 11:08:39 -07001205 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapPin));
1206 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapKeyId));
1207 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngine));
1208 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEngineId));
1209}
1210
1211TEST_F(WiFiServiceTest, Populate8021xNSS) {
1212 vector<uint8_t> ssid(1, 'a');
1213 WiFiServiceRefPtr service = new WiFiService(control_interface(),
1214 dispatcher(),
1215 metrics(),
1216 manager(),
1217 wifi(),
1218 ssid,
1219 flimflam::kModeManaged,
1220 flimflam::kSecurityNone,
1221 false);
1222 Service::EapCredentials eap;
1223 eap.ca_cert_nss = "nss_nickname";
1224 service->set_eap(eap);
1225 MockNSS nss;
1226 service->nss_ = &nss;
1227
1228 const string kNSSCertfile("/tmp/nss-cert");
1229 FilePath nss_cert(kNSSCertfile);
1230 vector<char> ssid_in_chars(ssid.begin(), ssid.end());
1231 EXPECT_CALL(nss, GetDERCertfile(eap.ca_cert_nss, ssid_in_chars))
1232 .WillOnce(Return(nss_cert));
1233
1234 map<string, ::DBus::Variant> params;
1235 service->Populate8021xProperties(&params);
1236 EXPECT_TRUE(ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert));
1237 if (ContainsKey(params, wpa_supplicant::kNetworkPropertyEapCaCert)) {
1238 EXPECT_EQ(kNSSCertfile, params[wpa_supplicant::kNetworkPropertyEapCaCert]
1239 .reader().get_string());
1240 }
Gaurav Shah10109f22011-11-11 20:16:22 -08001241}
1242
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001243TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
1244 vector<uint8_t> ssid(1, 'a');
1245 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
1246 dispatcher(),
1247 metrics(),
1248 manager(),
1249 wifi(),
1250 ssid,
1251 flimflam::kModeManaged,
1252 flimflam::kSecurityWep,
1253 false);
1254
1255 EXPECT_EQ("", wifi_service->passphrase_);
1256
1257 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001258 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001259 wifi_service->mutable_store(),
1260 flimflam::kPassphraseProperty,
1261 DBusAdaptor::StringToVariant("0:abcde"),
1262 &error));
1263 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1264
1265 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1266 flimflam::kPassphraseProperty,
1267 &error));
1268 EXPECT_EQ("", wifi_service->passphrase_);
1269}
1270
mukesh agrawale1d90e92012-02-15 17:36:08 -08001271TEST_F(WiFiServiceTest, SignalToStrength) {
1272 // Verify that our mapping is sane, in the sense that it preserves ordering.
1273 // We break the test into two domains, because we assume that positive
1274 // values aren't actually in dBm.
1275 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1276 int16 current_mapped = WiFiService::SignalToStrength(i);
1277 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1278 EXPECT_LE(current_mapped, next_mapped)
1279 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001280 EXPECT_GE(current_mapped, Service::kStrengthMin);
1281 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001282 }
1283 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1284 int16 current_mapped = WiFiService::SignalToStrength(i);
1285 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1286 EXPECT_LE(current_mapped, next_mapped)
1287 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001288 EXPECT_GE(current_mapped, Service::kStrengthMin);
1289 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001290 }
1291}
1292
1293TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1294 // If the chosen signal values don't map to distinct strength
1295 // values, then we can't expect our other tests to pass. So verify
1296 // their distinctness.
1297 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1298 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1299 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1300}
1301
1302TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1303 // Initial endpoint updates values.
1304 EXPECT_CALL(adaptor, EmitUint16Changed(
1305 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001306 EXPECT_CALL(adaptor, EmitStringChanged(
1307 flimflam::kWifiBSsid, kOkEndpointBssId));
1308 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001309 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1310 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001311 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001312 Mock::VerifyAndClearExpectations(&adaptor);
1313
1314 // Endpoint with stronger signal updates values.
1315 EXPECT_CALL(adaptor, EmitUint16Changed(
1316 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001317 EXPECT_CALL(adaptor, EmitStringChanged(
1318 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001319 EXPECT_CALL(adaptor, EmitUint8Changed(
1320 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
1321 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001322 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001323 Mock::VerifyAndClearExpectations(&adaptor);
1324
1325 // Endpoint with lower signal does not change values.
1326 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001327 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001328 EXPECT_CALL(adaptor,
1329 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1330 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001331 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001332 Mock::VerifyAndClearExpectations(&adaptor);
1333
1334 // Removing non-optimal endpoint does not change values.
1335 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001336 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001337 EXPECT_CALL(adaptor,
1338 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1339 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001340 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001341 Mock::VerifyAndClearExpectations(&adaptor);
1342
1343 // Removing optimal endpoint updates values.
1344 EXPECT_CALL(adaptor, EmitUint16Changed(
1345 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001346 EXPECT_CALL(adaptor, EmitStringChanged(
1347 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001348 EXPECT_CALL(adaptor, EmitUint8Changed(
1349 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1350 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001351 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001352 Mock::VerifyAndClearExpectations(&adaptor);
1353
1354 // Removing last endpoint updates values (and doesn't crash).
1355 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001356 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001357 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1358 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001359 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001360 Mock::VerifyAndClearExpectations(&adaptor);
1361}
1362
1363TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1364 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001365 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001366 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1367 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1368 service->AddEndpoint(bad_endpoint);
1369 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001370 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001371 Mock::VerifyAndClearExpectations(&adaptor);
1372
1373 // Setting current endpoint forces adoption of its values, even if it
1374 // doesn't have the highest signal.
1375 EXPECT_CALL(adaptor, EmitUint16Changed(
1376 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001377 EXPECT_CALL(adaptor, EmitStringChanged(
1378 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001379 EXPECT_CALL(adaptor, EmitUint8Changed(
1380 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1381 service->NotifyCurrentEndpoint(bad_endpoint);
1382 Mock::VerifyAndClearExpectations(&adaptor);
1383
1384 // Adding a better endpoint doesn't matter, when current endpoint is set.
1385 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001386 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001387 EXPECT_CALL(adaptor,
1388 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1389 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001390 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001391 Mock::VerifyAndClearExpectations(&adaptor);
1392
1393 // Removing a better endpoint doesn't matter, when current endpoint is set.
1394 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001395 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001396 EXPECT_CALL(adaptor,
1397 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1398 service->RemoveEndpoint(good_endpoint);
1399 Mock::VerifyAndClearExpectations(&adaptor);
1400
1401 // Removing the current endpoint is safe and sane.
1402 EXPECT_CALL(adaptor, EmitUint16Changed(
1403 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001404 EXPECT_CALL(adaptor, EmitStringChanged(
1405 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001406 EXPECT_CALL(adaptor, EmitUint8Changed(
1407 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1408 service->RemoveEndpoint(bad_endpoint);
1409 Mock::VerifyAndClearExpectations(&adaptor);
1410
1411 // Clearing the current endpoint (without removing it) is also safe and sane.
1412 service->NotifyCurrentEndpoint(ok_endpoint);
1413 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001414 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001415 EXPECT_CALL(adaptor,
1416 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1417 service->NotifyCurrentEndpoint(NULL);
1418 Mock::VerifyAndClearExpectations(&adaptor);
1419}
1420
1421TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1422 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001423 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001424 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1425 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1426 service->AddEndpoint(ok_endpoint);
1427 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001428 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001429 Mock::VerifyAndClearExpectations(&adaptor);
1430
1431 // Updating sub-optimal Endpoint doesn't update Service.
1432 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001433 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001434 EXPECT_CALL(adaptor,
1435 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1436 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
1437 service->NotifyEndpointUpdated(*ok_endpoint);
1438 Mock::VerifyAndClearExpectations(&adaptor);
1439
1440 // Updating optimal Endpoint updates appropriate Service property.
1441 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001442 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001443 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1444 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
1445 service->NotifyEndpointUpdated(*good_endpoint);
1446 Mock::VerifyAndClearExpectations(&adaptor);
1447
1448 // Change in optimal Endpoint updates Service properties.
1449 EXPECT_CALL(adaptor, EmitUint16Changed(
1450 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001451 EXPECT_CALL(adaptor, EmitStringChanged(
1452 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001453 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1454 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1455 service->NotifyEndpointUpdated(*ok_endpoint);
1456 Mock::VerifyAndClearExpectations(&adaptor);
1457}
1458
Paul Stewarta5e7d5f2013-01-09 18:06:15 -08001459TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1460 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1461 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1462 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1463 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1464 service->AddEndpoint(ok_endpoint);
1465 EXPECT_FALSE(service->ieee80211w_required());
1466 good_endpoint->ieee80211w_required_ = true;
1467 service->AddEndpoint(good_endpoint);
1468 EXPECT_TRUE(service->ieee80211w_required());
1469 service->RemoveEndpoint(good_endpoint);
1470 EXPECT_TRUE(service->ieee80211w_required());
1471}
1472
Chris Masone34af2182011-08-22 11:59:36 -07001473} // namespace shill