blob: 1fbd0647f3ffaf0e3f3bb3a09123ea16721b7a05 [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>
Chris Masone34af2182011-08-22 11:59:36 -07008#include <string>
9#include <vector>
10
11#include <base/string_util.h>
12#include <chromeos/dbus/service_constants.h>
13#include <gmock/gmock.h>
14#include <gtest/gtest.h>
15
Paul Stewart26b327e2011-10-19 11:38:09 -070016#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070017#include "shill/manager.h"
18#include "shill/mock_adaptors.h"
19#include "shill/mock_control.h"
20#include "shill/mock_service.h"
21#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070022#include "shill/mock_wifi.h"
Chris Masone34af2182011-08-22 11:59:36 -070023#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000024#include "shill/refptr_types.h"
25#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070026#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070027
mukesh agrawald835b202011-10-07 15:26:47 -070028using std::map;
Chris Masone34af2182011-08-22 11:59:36 -070029using std::string;
30using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070031using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080032using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070033using ::testing::DoAll;
mukesh agrawale1d90e92012-02-15 17:36:08 -080034using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070035using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070036using ::testing::Return;
37using ::testing::SetArgumentPointee;
38using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080039using ::testing::StrNe;
Chris Masone34af2182011-08-22 11:59:36 -070040
mukesh agrawalb20776f2012-02-10 16:00:36 -080041namespace shill {
42
Chris Masone34af2182011-08-22 11:59:36 -070043class WiFiServiceTest : public PropertyStoreTest {
44 public:
mukesh agrawal6e277772011-09-29 15:04:23 -070045 WiFiServiceTest() : wifi_(
46 new NiceMock<MockWiFi>(
47 control_interface(),
48 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080049 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -070050 manager(),
51 "wifi",
52 fake_mac,
53 0)) {}
Chris Masone34af2182011-08-22 11:59:36 -070054 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070055
56 protected:
57 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080058
Gaurav Shah10109f22011-11-11 20:16:22 -080059 bool CheckConnectable(const std::string &security, const char *passphrase,
60 Service::EapCredentials *eap) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000061 Error error;
62 vector<uint8_t> ssid(1, 'a');
63 WiFiServiceRefPtr service = new WiFiService(control_interface(),
64 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -080065 metrics(),
mukesh agrawal29c13a12011-11-24 00:09:19 +000066 manager(),
67 wifi(),
68 ssid,
69 flimflam::kModeManaged,
70 security,
71 false);
72 if (passphrase)
73 service->SetPassphrase(passphrase, &error);
Gaurav Shah10109f22011-11-11 20:16:22 -080074 if (eap) {
75 service->set_eap(*eap);
76 }
mukesh agrawal29c13a12011-11-24 00:09:19 +000077 return service->connectable();
78 }
mukesh agrawale1d90e92012-02-15 17:36:08 -080079 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
80 uint16 frequency, int16 signal_dbm) {
81 return WiFiEndpoint::MakeOpenEndpoint(
82 NULL, NULL, ssid, bssid, frequency, signal_dbm);
83 }
84 WiFiService *MakeGenericService() {
85 return new WiFiService(control_interface(),
86 dispatcher(),
87 metrics(),
88 manager(),
89 wifi(),
90 vector<uint8_t>(),
91 flimflam::kModeManaged,
92 flimflam::kSecurityWep,
93 false);
94 }
95 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
96 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +000097 }
mukesh agrawal6e277772011-09-29 15:04:23 -070098 scoped_refptr<MockWiFi> wifi() { return wifi_; }
99
100 private:
101 scoped_refptr<MockWiFi> wifi_;
Chris Masone34af2182011-08-22 11:59:36 -0700102};
103
mukesh agrawal6e277772011-09-29 15:04:23 -0700104// static
105const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
106
Paul Stewartd08f4432011-11-04 07:48:20 -0700107class WiFiServiceSecurityTest : public WiFiServiceTest {
108 public:
109 WiFiServiceRefPtr CreateServiceWithSecurity(const string &security) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800110 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700111 ssid.push_back(0xff);
112
113 return new WiFiService(control_interface(),
114 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800115 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700116 manager(),
117 wifi(),
118 ssid,
119 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800120 security,
121 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700122 }
123
124 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
125 const string &security) {
126 string id = wifi_service->GetStorageIdentifier();
127 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
128 EXPECT_NE(mac_pos, string::npos);
129 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
130 EXPECT_NE(mode_pos, string::npos);
131 return id.find(string(security), mode_pos) != string::npos;
132 }
133
134 // Test that a service that is created with security |from_security|
135 // gets by default a storage identifier with |to_security| as its
136 // security component.
137 bool TestStorageMapping(const string &from_security,
138 const string &to_security) {
139 WiFiServiceRefPtr wifi_service = CreateServiceWithSecurity(from_security);
140 return TestStorageSecurityIs(wifi_service, to_security);
141 }
142
143 // Test whether a service of type |service_security| can load from a
144 // storage interface containing an entry for |storage_security|.
145 // Make sure the result meets |expectation|. If |expectation| is
146 // true, also make sure the service storage identifier changes to
147 // match |storage_security|.
148 bool TestLoadMapping(const string &service_security,
149 const string &storage_security,
150 bool expectation) {
151 WiFiServiceRefPtr wifi_service =
152 CreateServiceWithSecurity(service_security);
153 NiceMock<MockStore> mock_store;
154 const string storage_id =
155 wifi_service->GetStorageIdentifierForSecurity(storage_security);
156 EXPECT_CALL(mock_store, ContainsGroup(_))
157 .WillRepeatedly(Return(false));
158 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
159 .WillRepeatedly(Return(true));
160 bool is_loadable = wifi_service->IsLoadableFrom(&mock_store);
161 EXPECT_EQ(expectation, is_loadable);
162 bool is_loaded = wifi_service->Load(&mock_store);
163 EXPECT_EQ(expectation, is_loaded);
164
165 if (expectation != is_loadable || expectation != is_loaded) {
166 return false;
167 } else if (!expectation) {
168 return true;
169 } else {
170 return TestStorageSecurityIs(wifi_service, storage_security);
171 }
172 }
173};
174
mukesh agrawale1d90e92012-02-15 17:36:08 -0800175class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
176 public:
177 WiFiServiceUpdateFromEndpointsTest()
178 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
179 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
180 kGoodEndpointStrength(
181 WiFiService::SignalToStrength(kGoodEndpointSignal)),
182 service(MakeGenericService()),
183 adaptor(*GetAdaptor(service)) {
184 ok_endpoint = MakeEndpoint(
185 "", "00:00:00:00:01", kOkEndpointFrequency, kOkEndpointSignal);
186 good_endpoint = MakeEndpoint(
187 "", "00:00:00:00:02", kGoodEndpointFrequency, kGoodEndpointSignal);
188 bad_endpoint = MakeEndpoint(
189 "", "00:00:00:00:03", kBadEndpointFrequency, kBadEndpointSignal);
190 }
191
192 protected:
193 static const uint16 kOkEndpointFrequency = 2422;
194 static const uint16 kBadEndpointFrequency = 2417;
195 static const uint16 kGoodEndpointFrequency = 2412;
196 static const int16 kOkEndpointSignal = -50;
197 static const int16 kBadEndpointSignal = -75;
198 static const int16 kGoodEndpointSignal = -25;
199 // Can't be both static and const (because initialization requires a
200 // function call). So choose to be just const.
201 const uint8 kOkEndpointStrength;
202 const uint8 kBadEndpointStrength;
203 const uint8 kGoodEndpointStrength;
204 WiFiEndpointRefPtr ok_endpoint;
205 WiFiEndpointRefPtr bad_endpoint;
206 WiFiEndpointRefPtr good_endpoint;
207 WiFiServiceRefPtr service;
208 ServiceMockAdaptor &adaptor;
209};
210
211
Chris Masone34af2182011-08-22 11:59:36 -0700212TEST_F(WiFiServiceTest, StorageId) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800213 vector<uint8_t> ssid(5);
Chris Masone34af2182011-08-22 11:59:36 -0700214 ssid.push_back(0xff);
Chris Masone9d779932011-08-25 16:33:41 -0700215
Chris Masone2176a882011-09-14 22:29:15 -0700216 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
217 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800218 metrics(),
Chris Masone9d779932011-08-25 16:33:41 -0700219 manager(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700220 wifi(),
Chris Masone9d779932011-08-25 16:33:41 -0700221 ssid,
222 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800223 flimflam::kSecurityNone,
224 false);
Chris Masone9d779932011-08-25 16:33:41 -0700225 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700226 for (uint i = 0; i < id.length(); ++i) {
227 EXPECT_TRUE(id[i] == '_' ||
228 isxdigit(id[i]) ||
229 (isalpha(id[i]) && islower(id[i])));
230 }
Paul Stewart22aa71b2011-09-16 12:15:11 -0700231 EXPECT_TRUE(wifi_service->TechnologyIs(Technology::kWifi));
Chris Masone34af2182011-08-22 11:59:36 -0700232 size_t mac_pos = id.find(StringToLowerASCII(string(fake_mac)));
233 EXPECT_NE(mac_pos, string::npos);
234 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
235}
236
Gaurav Shahda6218a2011-11-11 12:09:33 -0800237// Make sure the passphrase is registered as a write only property
238// by reading and comparing all string properties returned on the store.
239TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
240 vector<uint8_t> ssid(5);
241 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
242 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800243 metrics(),
Gaurav Shahda6218a2011-11-11 12:09:33 -0800244 manager(),
245 wifi(),
246 ssid,
247 flimflam::kModeManaged,
248 flimflam::kSecurityWpa,
249 false);
250 ReadablePropertyConstIterator<string> it =
251 (wifi_service->store()).GetStringPropertiesIter();
252 for( ; !it.AtEnd(); it.Advance())
253 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
254}
255
Thieu Lef7709452011-11-15 01:13:19 +0000256// Make sure setting the passphrase via D-Bus Service.SetProperty validates
257// the passphrase.
258TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
259 // We only spot check two password cases here to make sure the
260 // SetProperty code path does validation. We're not going to exhaustively
261 // test for all types of passwords.
262 vector<uint8_t> ssid(5);
263 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
264 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800265 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000266 manager(),
267 wifi(),
268 ssid,
269 flimflam::kModeManaged,
270 flimflam::kSecurityWep,
271 false);
272 Error error;
273 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
274 flimflam::kPassphraseProperty, "0:abcde", &error));
275 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
276 flimflam::kPassphraseProperty, "invalid", &error));
277 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
278}
279
280TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
281 vector<uint8_t> ssid(5);
282 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
283 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800284 metrics(),
Thieu Lef7709452011-11-15 01:13:19 +0000285 manager(),
286 wifi(),
287 ssid,
288 flimflam::kModeManaged,
289 flimflam::kSecurityNone,
290 false);
291 Error error;
292 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
293 flimflam::kPassphraseProperty, "invalid", &error));
294 EXPECT_EQ(Error::kNotSupported, error.type());
295}
296
mukesh agrawald835b202011-10-07 15:26:47 -0700297TEST_F(WiFiServiceTest, NonUTF8SSID) {
298 vector<uint8_t> ssid;
299
300 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
301 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
302 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800303 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700304 manager(),
305 wifi(),
306 ssid,
307 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800308 flimflam::kSecurityNone,
309 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700310 map<string, ::DBus::Variant> properties;
311 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
312 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
313}
314
Gaurav Shahda6218a2011-11-11 12:09:33 -0800315MATCHER(WPASecurityArgs, "") {
316 return ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol) &&
317 ContainsKey(arg, wpa_supplicant::kPropertyPreSharedKey);
318}
319
Gaurav Shah10109f22011-11-11 20:16:22 -0800320MATCHER(EAPSecurityArgs, "") {
321 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
322 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath);
323}
324
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700325TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800326 vector<uint8_t> ssid(5);
mukesh agrawal6e277772011-09-29 15:04:23 -0700327 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
328 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800329 metrics(),
mukesh agrawal6e277772011-09-29 15:04:23 -0700330 manager(),
331 wifi(),
332 ssid,
333 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800334 flimflam::kSecurityWpa,
335 false);
mukesh agrawal6e277772011-09-29 15:04:23 -0700336 EXPECT_CALL(*wifi(),
337 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500338 wifi_service->Connect(NULL);
mukesh agrawal6e277772011-09-29 15:04:23 -0700339}
340
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700341TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800342 vector<uint8_t> ssid(5);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700343 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
344 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800345 metrics(),
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700346 manager(),
347 wifi(),
348 ssid,
349 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800350 flimflam::kSecurityRsn,
351 false);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700352 EXPECT_CALL(*wifi(),
353 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500354 wifi_service->Connect(NULL);
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700355}
356
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800357TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800358 vector<uint8_t> ssid(5);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800359 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
360 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800361 metrics(),
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800362 manager(),
363 wifi(),
364 ssid,
365 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800366 flimflam::kSecurityPsk,
367 false);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800368 EXPECT_CALL(*wifi(),
369 ConnectTo(wifi_service.get(), WPASecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500370 wifi_service->Connect(NULL);
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800371}
372
Gaurav Shah10109f22011-11-11 20:16:22 -0800373TEST_F(WiFiServiceTest, ConnectTask8021x) {
374 vector<uint8_t> ssid(5);
375 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
376 dispatcher(),
377 metrics(),
378 manager(),
379 wifi(),
380 ssid,
381 flimflam::kModeManaged,
382 flimflam::kSecurity8021x,
383 false);
384 Service::EapCredentials eap;
385 eap.identity = "identity";
386 wifi_service->set_eap(eap);
387 EXPECT_CALL(*wifi(),
388 ConnectTo(wifi_service.get(), EAPSecurityArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500389 wifi_service->Connect(NULL);
Gaurav Shah10109f22011-11-11 20:16:22 -0800390}
391
Thieu Lef4cbda92011-11-10 23:41:24 +0000392MATCHER(WEPSecurityArgsKeyIndex0, "") {
393 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
394 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("0")) &&
395 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
396 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
397 reader().get_uint32() == 0);
398}
399
400MATCHER(WEPSecurityArgsKeyIndex1, "") {
401 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
402 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("1")) &&
403 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
404 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
405 reader().get_uint32() == 1);
406}
407
408MATCHER(WEPSecurityArgsKeyIndex2, "") {
409 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
410 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("2")) &&
411 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
412 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
413 reader().get_uint32() == 2);
414}
415
416MATCHER(WEPSecurityArgsKeyIndex3, "") {
417 return ContainsKey(arg, wpa_supplicant::kPropertyAuthAlg) &&
418 ContainsKey(arg, wpa_supplicant::kPropertyWEPKey + std::string("3")) &&
419 ContainsKey(arg, wpa_supplicant::kPropertyWEPTxKeyIndex) &&
420 (arg.find(wpa_supplicant::kPropertyWEPTxKeyIndex)->second.
421 reader().get_uint32() == 3);
422}
423
424TEST_F(WiFiServiceTest, ConnectTaskWEP) {
425 vector<uint8_t> ssid(5);
426 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
427 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800428 metrics(),
Thieu Lef4cbda92011-11-10 23:41:24 +0000429 manager(),
430 wifi(),
431 ssid,
432 flimflam::kModeManaged,
433 flimflam::kSecurityWep,
434 false);
435 Error error;
436 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
437 EXPECT_CALL(*wifi(),
438 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500439 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000440
441 wifi_service->SetPassphrase("abcdefghijklm", &error);
442 EXPECT_CALL(*wifi(),
443 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500444 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000445
446 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
447 EXPECT_CALL(*wifi(),
448 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500449 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000450
451 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
452 EXPECT_CALL(*wifi(),
453 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500454 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000455
456 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
457 EXPECT_CALL(*wifi(),
458 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500459 wifi_service->Connect(NULL);
Thieu Lef4cbda92011-11-10 23:41:24 +0000460}
461
Gaurav Shah29d68882012-01-30 19:06:42 -0800462
463MATCHER(DynamicWEPArgs, "") {
464 return ContainsKey(arg, wpa_supplicant::kNetworkPropertyEapIdentity) &&
465 ContainsKey(arg, wpa_supplicant::kNetworkPropertyCaPath) &&
466 !ContainsKey(arg, wpa_supplicant::kPropertySecurityProtocol);
467}
468
469// Dynamic WEP + 802.1x.
470TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
471 vector<uint8_t> ssid(5);
472 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
473 dispatcher(),
474 metrics(),
475 manager(),
476 wifi(),
477 ssid,
478 flimflam::kModeManaged,
479 flimflam::kSecurityWep,
480 false);
481
482 Service::EapCredentials eap;
483 eap.key_management = "IEEE8021X";
484 eap.identity = "something";
485 wifi_service->set_eap(eap);
486 EXPECT_CALL(*wifi(),
487 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500488 wifi_service->Connect(NULL);
Gaurav Shah29d68882012-01-30 19:06:42 -0800489}
490
Paul Stewartd08f4432011-11-04 07:48:20 -0700491TEST_F(WiFiServiceTest, LoadHidden) {
Gaurav Shahda6218a2011-11-11 12:09:33 -0800492 vector<uint8_t> ssid(5);
Paul Stewartd08f4432011-11-04 07:48:20 -0700493 ssid.push_back(0xff);
494
495 WiFiServiceRefPtr service = new WiFiService(control_interface(),
496 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800497 metrics(),
Paul Stewartd08f4432011-11-04 07:48:20 -0700498 manager(),
499 wifi(),
500 ssid,
501 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800502 flimflam::kSecurityNone,
503 false);
Paul Stewartd08f4432011-11-04 07:48:20 -0700504 ASSERT_FALSE(service->hidden_ssid_);
505 NiceMock<MockStore> mock_store;
506 const string storage_id = service->GetStorageIdentifier();
507 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
508 .WillRepeatedly(Return(true));
509 EXPECT_CALL(mock_store, GetBool(_, _, _))
510 .WillRepeatedly(Return(false));
511 EXPECT_CALL(mock_store,
512 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
513 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
514 EXPECT_TRUE(service->Load(&mock_store));
515 EXPECT_TRUE(service->hidden_ssid_);
516}
517
518TEST_F(WiFiServiceSecurityTest, WPAMapping) {
519 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
520 flimflam::kSecurityPsk));
521 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
522 flimflam::kSecurityPsk));
523 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
524 flimflam::kSecurityPsk));
525 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
526 flimflam::kSecurityWep));
527 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
528 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800529 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
530 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700531}
532
533TEST_F(WiFiServiceSecurityTest, LoadMapping) {
534 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
535 flimflam::kSecurityPsk,
536 true));
537 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
538 flimflam::kSecurityRsn,
539 true));
540 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
541 flimflam::kSecurityWpa,
542 false));
543 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
544 flimflam::kSecurityPsk,
545 true));
546 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
547 flimflam::kSecurityWpa,
548 true));
549 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
550 flimflam::kSecurityRsn,
551 false));
552 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
553 flimflam::kSecurityWep,
554 true));
555 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
556 flimflam::kSecurityPsk,
557 false));
558}
559
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800560TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
561 vector<uint8_t> ssid(5);
562 ssid.push_back(0xff);
563
564 WiFiServiceRefPtr service = new WiFiService(control_interface(),
565 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800566 metrics(),
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800567 manager(),
568 wifi(),
569 ssid,
570 flimflam::kModeManaged,
571 flimflam::kSecurityPsk,
572 false);
573 NiceMock<MockStore> mock_store;
574 const string storage_id = service->GetStorageIdentifier();
575 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
576 .WillRepeatedly(Return(true));
577 EXPECT_CALL(mock_store, GetBool(_, _, _))
578 .WillRepeatedly(Return(false));
579 const string passphrase = "passphrase";
580 EXPECT_CALL(mock_store,
581 GetCryptedString(StrEq(storage_id),
582 WiFiService::kStoragePassphrase, _))
583 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
584 EXPECT_CALL(mock_store,
585 GetCryptedString(StrEq(storage_id),
586 StrNe(WiFiService::kStoragePassphrase), _))
587 .WillRepeatedly(Return(false));
588 EXPECT_TRUE(service->need_passphrase_);
589 EXPECT_TRUE(service->Load(&mock_store));
590 EXPECT_EQ(passphrase, service->passphrase_);
591 EXPECT_TRUE(service->connectable());
592 EXPECT_FALSE(service->need_passphrase_);
593 service->Unload();
594 EXPECT_EQ(string(""), service->passphrase_);
595 EXPECT_FALSE(service->connectable());
596 EXPECT_TRUE(service->need_passphrase_);
597}
598
Paul Stewart66c86002012-01-30 18:00:52 -0800599TEST_F(WiFiServiceTest, UnloadAndClearCacheWep) {
600 vector<uint8_t> ssid(1, 'a');
601 WiFiServiceRefPtr service = new WiFiService(control_interface(),
602 dispatcher(),
603 metrics(),
604 manager(),
605 wifi(),
606 ssid,
607 flimflam::kModeManaged,
608 flimflam::kSecurityWep,
609 false);
610 // A WEP network does not incur cached credentials.
611 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(0);
612 service->Unload();
613}
614
615TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
616 vector<uint8_t> ssid(1, 'a');
617 WiFiServiceRefPtr service = new WiFiService(control_interface(),
618 dispatcher(),
619 metrics(),
620 manager(),
621 wifi(),
622 ssid,
623 flimflam::kModeManaged,
624 flimflam::kSecurity8021x,
625 false);
626 // An 802.1x network should clear its cached credentials.
627 EXPECT_CALL(*wifi(), ClearCachedCredentials()).Times(1);
628 service->Unload();
629}
630
Paul Stewart0756db92012-01-27 08:34:47 -0800631TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewarta41e38d2011-11-11 07:47:29 -0800632 vector<uint8_t> ssid(5);
633 ssid.push_back(0xff);
634
635 WiFiServiceRefPtr service = new WiFiService(control_interface(),
636 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800637 metrics(),
Paul Stewarta41e38d2011-11-11 07:47:29 -0800638 manager(),
639 wifi(),
640 ssid,
641 flimflam::kModeManaged,
642 flimflam::kSecurityNone,
643 false);
644 const string storage_id = service->GetStorageIdentifier();
645 string address;
646 string mode;
647 string security;
648 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
649 &security));
650 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
651 EXPECT_EQ(flimflam::kModeManaged, mode);
652 EXPECT_EQ(flimflam::kSecurityNone, security);
653}
654
Paul Stewart0756db92012-01-27 08:34:47 -0800655TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
656 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
657 // which needs to be dealt with specially in the parser.
658 vector<uint8_t> ssid(5);
659 ssid.push_back(0xff);
660
661 WiFiServiceRefPtr service = new WiFiService(control_interface(),
662 dispatcher(),
663 metrics(),
664 manager(),
665 wifi(),
666 ssid,
667 flimflam::kModeManaged,
668 flimflam::kSecurity8021x,
669 false);
670 const string storage_id = service->GetStorageIdentifier();
671 string address;
672 string mode;
673 string security;
674 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
675 &security));
676 EXPECT_EQ(StringToLowerASCII(string(fake_mac)), address);
677 EXPECT_EQ(flimflam::kModeManaged, mode);
678 EXPECT_EQ(flimflam::kSecurity8021x, security);
679}
680
mukesh agrawal29c13a12011-11-24 00:09:19 +0000681TEST_F(WiFiServiceTest, Connectable) {
682 // Open network should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800683 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000684
685 // Open network should remain connectable if we try to set a password on it.
Gaurav Shah10109f22011-11-11 20:16:22 -0800686 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000687
688 // WEP network with passphrase set should be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800689 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000690
691 // WEP network without passphrase set should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800692 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000693
694 // A bad passphrase should not make a WEP network connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800695 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000696
697 // Similar to WEP, for WPA.
Gaurav Shah10109f22011-11-11 20:16:22 -0800698 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", NULL));
699 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, NULL));
700 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", NULL));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000701
702 // Unconfigured 802.1x should NOT be connectable.
Gaurav Shah10109f22011-11-11 20:16:22 -0800703 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, NULL));
704
705 Service::EapCredentials eap;
706 // Empty EAP credentials should not make a 802.1x network connectable.
707 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
708
709 eap.identity = "something";
710 // If client certificate is being used, a private key must exist.
711 eap.client_cert = "some client cert";
712 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
713 eap.private_key = "some private key";
714 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
715
716 // Identity is always required.
717 eap.identity.clear();
718 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
719
720 eap.identity = "something";
721 // For non EAP-TLS types, a password is required.
722 eap.eap = "Non-TLS";
723 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
724 eap.password = "some password";
725 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, &eap));
Gaurav Shah29d68882012-01-30 19:06:42 -0800726 // Dynamic WEP + 802.1X should be connectable under the same conditions.
727 eap.key_management = "IEEE8021X";
728 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, &eap));
mukesh agrawal29c13a12011-11-24 00:09:19 +0000729}
730
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000731TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800732 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000733 vector<uint8_t> ssid(1, 'a');
734 WiFiServiceRefPtr service = new WiFiService(control_interface(),
735 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800736 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000737 manager(),
738 wifi(),
739 ssid,
740 flimflam::kModeManaged,
741 flimflam::kSecurityNone,
742 false);
743 EXPECT_CALL(*wifi(), IsIdle())
744 .WillRepeatedly(Return(true));
745 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800746 EXPECT_FALSE(service->IsAutoConnectable(&reason));
747 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000748
mukesh agrawalbf14e942012-03-02 14:36:34 -0800749 reason = "";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800750 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000751 service->AddEndpoint(endpoint);
752 EXPECT_CALL(*wifi(), IsIdle())
753 .WillRepeatedly(Return(true));
754 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800755 EXPECT_TRUE(service->IsAutoConnectable(&reason));
756 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000757
758 // WiFi only supports connecting to one Service at a time. So, to
759 // avoid disrupting connectivity, we only allow auto-connection to
760 // a WiFiService when the corresponding WiFi is idle.
761 EXPECT_CALL(*wifi(), IsIdle())
762 .WillRepeatedly(Return(false));
763 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -0800764 EXPECT_FALSE(service->IsAutoConnectable(&reason));
765 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000766}
767
768TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -0800769 const char *reason;
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000770 vector<uint8_t> ssid(1, 'a');
771 WiFiServiceRefPtr service = new WiFiService(control_interface(),
772 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800773 metrics(),
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000774 manager(),
775 wifi(),
776 ssid,
777 flimflam::kModeManaged,
778 flimflam::kSecurityNone,
779 false);
mukesh agrawalbf14e942012-03-02 14:36:34 -0800780 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000781 EXPECT_CALL(*wifi(), ConnectTo(_, _))
782 .Times(0);
783 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500784 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000785
mukesh agrawale1d90e92012-02-15 17:36:08 -0800786 WiFiEndpointRefPtr endpoint = MakeEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000787 service->AddEndpoint(endpoint);
788 EXPECT_CALL(*wifi(), IsIdle())
789 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -0800790 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000791 EXPECT_CALL(*wifi(), ConnectTo(_, _));
792 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500793 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -0800794
795 Error error;
796 service->Disconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -0500797 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -0800798 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000799}
800
Gaurav Shah10109f22011-11-11 20:16:22 -0800801TEST_F(WiFiServiceTest, Populate8021x) {
802 vector<uint8_t> ssid(1, 'a');
803 WiFiServiceRefPtr service = new WiFiService(control_interface(),
804 dispatcher(),
805 metrics(),
806 manager(),
807 wifi(),
808 ssid,
809 flimflam::kModeManaged,
810 flimflam::kSecurityNone,
811 false);
812 Service::EapCredentials eap;
813 eap.identity = "testidentity";
814 service->set_eap(eap);
815 map<string, ::DBus::Variant> params;
816 service->Populate8021xProperties(&params);
817 // Test that only non-empty 802.1x properties are populated.
818 EXPECT_TRUE(ContainsKey(params,
819 wpa_supplicant::kNetworkPropertyEapIdentity));
820 EXPECT_FALSE(ContainsKey(params,
821 wpa_supplicant::kNetworkPropertyEapKeyId));
822}
823
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800824TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
825 vector<uint8_t> ssid(1, 'a');
826 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
827 dispatcher(),
828 metrics(),
829 manager(),
830 wifi(),
831 ssid,
832 flimflam::kModeManaged,
833 flimflam::kSecurityWep,
834 false);
835
836 EXPECT_EQ("", wifi_service->passphrase_);
837
838 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800839 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -0800840 wifi_service->mutable_store(),
841 flimflam::kPassphraseProperty,
842 DBusAdaptor::StringToVariant("0:abcde"),
843 &error));
844 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
845
846 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
847 flimflam::kPassphraseProperty,
848 &error));
849 EXPECT_EQ("", wifi_service->passphrase_);
850}
851
mukesh agrawale1d90e92012-02-15 17:36:08 -0800852TEST_F(WiFiServiceTest, SignalToStrength) {
853 // Verify that our mapping is sane, in the sense that it preserves ordering.
854 // We break the test into two domains, because we assume that positive
855 // values aren't actually in dBm.
856 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
857 int16 current_mapped = WiFiService::SignalToStrength(i);
858 int16 next_mapped = WiFiService::SignalToStrength(i+1);
859 EXPECT_LE(current_mapped, next_mapped)
860 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800861 EXPECT_GE(current_mapped, Service::kStrengthMin);
862 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800863 }
864 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
865 int16 current_mapped = WiFiService::SignalToStrength(i);
866 int16 next_mapped = WiFiService::SignalToStrength(i+1);
867 EXPECT_LE(current_mapped, next_mapped)
868 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -0800869 EXPECT_GE(current_mapped, Service::kStrengthMin);
870 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800871 }
872}
873
874TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
875 // If the chosen signal values don't map to distinct strength
876 // values, then we can't expect our other tests to pass. So verify
877 // their distinctness.
878 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
879 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
880 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
881}
882
883TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
884 // Initial endpoint updates values.
885 EXPECT_CALL(adaptor, EmitUint16Changed(
886 flimflam::kWifiFrequency, kOkEndpointFrequency));
887 EXPECT_CALL(adaptor,EmitUint8Changed(
888 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
889 service->AddEndpoint(ok_endpoint);
890 Mock::VerifyAndClearExpectations(&adaptor);
891
892 // Endpoint with stronger signal updates values.
893 EXPECT_CALL(adaptor, EmitUint16Changed(
894 flimflam::kWifiFrequency, kGoodEndpointFrequency));
895 EXPECT_CALL(adaptor, EmitUint8Changed(
896 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
897 service->AddEndpoint(good_endpoint);
898 Mock::VerifyAndClearExpectations(&adaptor);
899
900 // Endpoint with lower signal does not change values.
901 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
902 EXPECT_CALL(adaptor,
903 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
904 service->AddEndpoint(bad_endpoint);
905 Mock::VerifyAndClearExpectations(&adaptor);
906
907 // Removing non-optimal endpoint does not change values.
908 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
909 EXPECT_CALL(adaptor,
910 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
911 service->RemoveEndpoint(bad_endpoint);
912 Mock::VerifyAndClearExpectations(&adaptor);
913
914 // Removing optimal endpoint updates values.
915 EXPECT_CALL(adaptor, EmitUint16Changed(
916 flimflam::kWifiFrequency, kOkEndpointFrequency));
917 EXPECT_CALL(adaptor, EmitUint8Changed(
918 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
919 service->RemoveEndpoint(good_endpoint);
920 Mock::VerifyAndClearExpectations(&adaptor);
921
922 // Removing last endpoint updates values (and doesn't crash).
923 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
924 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
925 service->RemoveEndpoint(ok_endpoint);
926 Mock::VerifyAndClearExpectations(&adaptor);
927}
928
929TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
930 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
931 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
932 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
933 service->AddEndpoint(bad_endpoint);
934 service->AddEndpoint(ok_endpoint);
935 Mock::VerifyAndClearExpectations(&adaptor);
936
937 // Setting current endpoint forces adoption of its values, even if it
938 // doesn't have the highest signal.
939 EXPECT_CALL(adaptor, EmitUint16Changed(
940 flimflam::kWifiFrequency, kBadEndpointFrequency));
941 EXPECT_CALL(adaptor, EmitUint8Changed(
942 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
943 service->NotifyCurrentEndpoint(bad_endpoint);
944 Mock::VerifyAndClearExpectations(&adaptor);
945
946 // Adding a better endpoint doesn't matter, when current endpoint is set.
947 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
948 EXPECT_CALL(adaptor,
949 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
950 service->AddEndpoint(good_endpoint);
951 Mock::VerifyAndClearExpectations(&adaptor);
952
953 // Removing a better endpoint doesn't matter, when current endpoint is set.
954 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
955 EXPECT_CALL(adaptor,
956 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
957 service->RemoveEndpoint(good_endpoint);
958 Mock::VerifyAndClearExpectations(&adaptor);
959
960 // Removing the current endpoint is safe and sane.
961 EXPECT_CALL(adaptor, EmitUint16Changed(
962 flimflam::kWifiFrequency, kOkEndpointFrequency));
963 EXPECT_CALL(adaptor, EmitUint8Changed(
964 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
965 service->RemoveEndpoint(bad_endpoint);
966 Mock::VerifyAndClearExpectations(&adaptor);
967
968 // Clearing the current endpoint (without removing it) is also safe and sane.
969 service->NotifyCurrentEndpoint(ok_endpoint);
970 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
971 EXPECT_CALL(adaptor,
972 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
973 service->NotifyCurrentEndpoint(NULL);
974 Mock::VerifyAndClearExpectations(&adaptor);
975}
976
977TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
978 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
979 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
980 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
981 service->AddEndpoint(ok_endpoint);
982 service->AddEndpoint(good_endpoint);
983 Mock::VerifyAndClearExpectations(&adaptor);
984
985 // Updating sub-optimal Endpoint doesn't update Service.
986 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
987 EXPECT_CALL(adaptor,
988 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
989 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
990 service->NotifyEndpointUpdated(*ok_endpoint);
991 Mock::VerifyAndClearExpectations(&adaptor);
992
993 // Updating optimal Endpoint updates appropriate Service property.
994 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
995 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
996 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
997 service->NotifyEndpointUpdated(*good_endpoint);
998 Mock::VerifyAndClearExpectations(&adaptor);
999
1000 // Change in optimal Endpoint updates Service properties.
1001 EXPECT_CALL(adaptor, EmitUint16Changed(
1002 flimflam::kWifiFrequency, kOkEndpointFrequency));
1003 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1004 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
1005 service->NotifyEndpointUpdated(*ok_endpoint);
1006 Mock::VerifyAndClearExpectations(&adaptor);
1007}
1008
Chris Masone34af2182011-08-22 11:59:36 -07001009} // namespace shill