blob: 0d62e8ec12526fb48ba84d51e5a118fa0778d5c4 [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>
Paul Stewart71a4d3b2013-01-18 18:12:56 -080013#include <base/string_number_conversions.h>
Chris Masone34af2182011-08-22 11:59:36 -070014#include <base/string_util.h>
15#include <chromeos/dbus/service_constants.h>
16#include <gmock/gmock.h>
17#include <gtest/gtest.h>
18
Paul Stewart26b327e2011-10-19 11:38:09 -070019#include "shill/event_dispatcher.h"
Chris Masone34af2182011-08-22 11:59:36 -070020#include "shill/manager.h"
mukesh agrawalf6b32092013-04-10 15:49:55 -070021#include "shill/metrics.h"
Chris Masone34af2182011-08-22 11:59:36 -070022#include "shill/mock_adaptors.h"
Paul Stewart5baebb72013-03-14 11:43:29 -070023#include "shill/mock_certificate_file.h"
Chris Masone34af2182011-08-22 11:59:36 -070024#include "shill/mock_control.h"
Paul Stewartc43cbbe2013-04-11 06:29:30 -070025#include "shill/mock_eap_credentials.h"
Paul Stewart71a4d3b2013-01-18 18:12:56 -080026#include "shill/mock_log.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070027#include "shill/mock_manager.h"
Paul Stewartecf4cd12012-04-17 11:08:39 -070028#include "shill/mock_nss.h"
Christopher Wiley1ce658d2012-10-10 10:02:03 -070029#include "shill/mock_profile.h"
Chris Masone34af2182011-08-22 11:59:36 -070030#include "shill/mock_service.h"
31#include "shill/mock_store.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070032#include "shill/mock_wifi.h"
Paul Stewart3c504012013-01-17 17:49:58 -080033#include "shill/mock_wifi_provider.h"
Chris Masone34af2182011-08-22 11:59:36 -070034#include "shill/property_store_unittest.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000035#include "shill/refptr_types.h"
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070036#include "shill/service_property_change_test.h"
mukesh agrawal8a3188d2011-12-01 20:56:44 +000037#include "shill/wifi_endpoint.h"
mukesh agrawal6e277772011-09-29 15:04:23 -070038#include "shill/wpa_supplicant.h"
Chris Masone34af2182011-08-22 11:59:36 -070039
Albert Chaulk0e1cdea2013-02-27 15:32:55 -080040using base::FilePath;
mukesh agrawald835b202011-10-07 15:26:47 -070041using std::map;
Paul Stewart85aea152013-01-22 09:31:56 -080042using std::set;
Chris Masone34af2182011-08-22 11:59:36 -070043using std::string;
44using std::vector;
Paul Stewartd08f4432011-11-04 07:48:20 -070045using ::testing::_;
mukesh agrawale1d90e92012-02-15 17:36:08 -080046using ::testing::AnyNumber;
Paul Stewartd08f4432011-11-04 07:48:20 -070047using ::testing::DoAll;
Paul Stewart71a4d3b2013-01-18 18:12:56 -080048using ::testing::EndsWith;
Paul Stewart3c504012013-01-17 17:49:58 -080049using ::testing::HasSubstr;
mukesh agrawale1d90e92012-02-15 17:36:08 -080050using ::testing::Mock;
mukesh agrawal6e277772011-09-29 15:04:23 -070051using ::testing::NiceMock;
Paul Stewartd08f4432011-11-04 07:48:20 -070052using ::testing::Return;
Paul Stewartc43cbbe2013-04-11 06:29:30 -070053using ::testing::ReturnRef;
Paul Stewartd08f4432011-11-04 07:48:20 -070054using ::testing::SetArgumentPointee;
55using ::testing::StrEq;
Paul Stewartd8ad3c42012-01-09 12:39:38 -080056using ::testing::StrNe;
Paul Stewart85aea152013-01-22 09:31:56 -080057using ::testing::StrictMock;
Chris Masone34af2182011-08-22 11:59:36 -070058
mukesh agrawalb20776f2012-02-10 16:00:36 -080059namespace shill {
60
Chris Masone34af2182011-08-22 11:59:36 -070061class WiFiServiceTest : public PropertyStoreTest {
62 public:
Paul Stewart3c504012013-01-17 17:49:58 -080063 WiFiServiceTest()
mukesh agrawalcbfb34e2013-04-17 19:33:25 -070064 : mock_manager_(control_interface(), dispatcher(), metrics(), glib()),
65 wifi_(
66 new NiceMock<MockWiFi>(control_interface(),
67 dispatcher(),
68 metrics(),
69 manager(),
70 "wifi",
71 fake_mac,
72 0)),
73 simple_ssid_(1, 'a'),
74 simple_ssid_string_("a") {}
Chris Masone34af2182011-08-22 11:59:36 -070075 virtual ~WiFiServiceTest() {}
mukesh agrawal6e277772011-09-29 15:04:23 -070076
77 protected:
78 static const char fake_mac[];
mukesh agrawale1d90e92012-02-15 17:36:08 -080079
Paul Stewartc43cbbe2013-04-11 06:29:30 -070080 MockEapCredentials *SetMockEap(
81 const WiFiServiceRefPtr &service) {
82 MockEapCredentials *eap = new MockEapCredentials();
83 service->eap_.reset(eap); // Passes ownership.
84 return eap;
85 }
Gaurav Shah10109f22011-11-11 20:16:22 -080086 bool CheckConnectable(const std::string &security, const char *passphrase,
Paul Stewartc43cbbe2013-04-11 06:29:30 -070087 bool is_1x_connectable) {
mukesh agrawal29c13a12011-11-24 00:09:19 +000088 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -080089 WiFiServiceRefPtr service = MakeSimpleService(security);
mukesh agrawal29c13a12011-11-24 00:09:19 +000090 if (passphrase)
91 service->SetPassphrase(passphrase, &error);
Paul Stewartc43cbbe2013-04-11 06:29:30 -070092 MockEapCredentials *eap = SetMockEap(service);
93 EXPECT_CALL(*eap, IsConnectable())
94 .WillRepeatedly(Return(is_1x_connectable));
95 const string kKeyManagement8021x(WPASupplicant::kKeyManagementIeee8021X);
96 if (security == flimflam::kSecurityWep && is_1x_connectable) {
97 EXPECT_CALL(*eap, key_management())
98 .WillRepeatedly(ReturnRef(kKeyManagement8021x));
Gaurav Shah10109f22011-11-11 20:16:22 -080099 }
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700100 service->OnEapCredentialsChanged();
mukesh agrawal29c13a12011-11-24 00:09:19 +0000101 return service->connectable();
102 }
mukesh agrawale1d90e92012-02-15 17:36:08 -0800103 WiFiEndpoint *MakeEndpoint(const string &ssid, const string &bssid,
mukesh agrawal43970a22013-02-15 16:00:07 -0800104 uint16 frequency, int16 signal_dbm,
105 bool has_wpa_property, bool has_rsn_property) {
106 return WiFiEndpoint::MakeEndpoint(
Paul Stewart0654ece2013-03-26 15:21:26 -0700107 NULL, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
mukesh agrawal43970a22013-02-15 16:00:07 -0800108 frequency, signal_dbm, has_wpa_property, has_rsn_property);
109 }
110 WiFiEndpoint *MakeOpenEndpoint(const string &ssid, const string &bssid,
111 uint16 frequency, int16 signal_dbm) {
mukesh agrawale1d90e92012-02-15 17:36:08 -0800112 return WiFiEndpoint::MakeOpenEndpoint(
Paul Stewart0654ece2013-03-26 15:21:26 -0700113 NULL, wifi(), ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
Paul Stewart3c504012013-01-17 17:49:58 -0800114 frequency, signal_dbm);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800115 }
Paul Stewart3c504012013-01-17 17:49:58 -0800116 WiFiServiceRefPtr MakeSimpleService(const string &security) {
mukesh agrawale1d90e92012-02-15 17:36:08 -0800117 return new WiFiService(control_interface(),
118 dispatcher(),
119 metrics(),
120 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800121 &provider_,
122 simple_ssid_,
mukesh agrawale1d90e92012-02-15 17:36:08 -0800123 flimflam::kModeManaged,
Paul Stewart3c504012013-01-17 17:49:58 -0800124 security,
mukesh agrawale1d90e92012-02-15 17:36:08 -0800125 false);
126 }
Paul Stewart3c504012013-01-17 17:49:58 -0800127 WiFiServiceRefPtr MakeGenericService() {
128 return MakeSimpleService(flimflam::kSecurityWep);
129 }
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700130 void SetWiFi(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
131 service->SetWiFi(wifi); // Has side-effects.
132 }
Paul Stewart3c504012013-01-17 17:49:58 -0800133 void SetWiFiForService(WiFiServiceRefPtr service, WiFiRefPtr wifi) {
134 service->wifi_ = wifi;
135 }
136 WiFiServiceRefPtr MakeServiceWithWiFi(const string &security) {
137 WiFiServiceRefPtr service = MakeSimpleService(security);
138 SetWiFiForService(service, wifi_);
139 return service;
140 }
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700141 WiFiServiceRefPtr MakeServiceWithMockManager() {
142 return new WiFiService(control_interface(),
143 dispatcher(),
144 metrics(),
145 &mock_manager_,
146 &provider_,
147 simple_ssid_,
148 flimflam::kModeManaged,
149 flimflam::kSecurityWep,
150 false);
151 }
mukesh agrawale1d90e92012-02-15 17:36:08 -0800152 ServiceMockAdaptor *GetAdaptor(WiFiService *service) {
153 return dynamic_cast<ServiceMockAdaptor *>(service->adaptor());
mukesh agrawal8a3188d2011-12-01 20:56:44 +0000154 }
Paul Stewart3c504012013-01-17 17:49:58 -0800155 Error::Type TestConfigurePassphrase(const string &security,
156 const char *passphrase) {
157 WiFiServiceRefPtr service = MakeSimpleService(security);
158 KeyValueStore args;
159 if (passphrase) {
160 args.SetString(flimflam::kPassphraseProperty, passphrase);
161 }
162 Error error;
163 service->Configure(args, &error);
164 return error.type();
165 }
mukesh agrawal6e277772011-09-29 15:04:23 -0700166 scoped_refptr<MockWiFi> wifi() { return wifi_; }
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700167 MockManager *mock_manager() { return &mock_manager_; }
Paul Stewart3c504012013-01-17 17:49:58 -0800168 MockWiFiProvider *provider() { return &provider_; }
169 string GetAnyDeviceAddress() { return WiFiService::kAnyDeviceAddress; }
170 const vector<uint8_t> &simple_ssid() { return simple_ssid_; }
171 const string &simple_ssid_string() { return simple_ssid_string_; }
mukesh agrawal6e277772011-09-29 15:04:23 -0700172
173 private:
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700174 MockManager mock_manager_;
mukesh agrawal6e277772011-09-29 15:04:23 -0700175 scoped_refptr<MockWiFi> wifi_;
Paul Stewart3c504012013-01-17 17:49:58 -0800176 MockWiFiProvider provider_;
177 const vector<uint8_t> simple_ssid_;
178 const string simple_ssid_string_;
Chris Masone34af2182011-08-22 11:59:36 -0700179};
180
mukesh agrawal6e277772011-09-29 15:04:23 -0700181// static
182const char WiFiServiceTest::fake_mac[] = "AaBBcCDDeeFF";
183
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800184MATCHER_P3(ContainsWiFiProperties, ssid, mode, security, "") {
185 string hex_ssid = base::HexEncode(ssid.data(), ssid.size());
186 return
187 arg.ContainsString(WiFiService::kStorageType) &&
188 arg.GetString(WiFiService::kStorageType) == flimflam::kTypeWifi &&
189 arg.ContainsString(WiFiService::kStorageSSID) &&
190 arg.GetString(WiFiService::kStorageSSID) == hex_ssid &&
191 arg.ContainsString(WiFiService::kStorageMode) &&
192 arg.GetString(WiFiService::kStorageMode) == mode &&
193 arg.ContainsString(WiFiService::kStorageSecurityClass) &&
194 arg.GetString(WiFiService::kStorageSecurityClass) == security;
195}
196
Paul Stewartd08f4432011-11-04 07:48:20 -0700197class WiFiServiceSecurityTest : public WiFiServiceTest {
198 public:
Paul Stewartd08f4432011-11-04 07:48:20 -0700199 bool TestStorageSecurityIs(WiFiServiceRefPtr wifi_service,
200 const string &security) {
201 string id = wifi_service->GetStorageIdentifier();
Paul Stewart3c504012013-01-17 17:49:58 -0800202 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Paul Stewartd08f4432011-11-04 07:48:20 -0700203 EXPECT_NE(mac_pos, string::npos);
204 size_t mode_pos = id.find(string(flimflam::kModeManaged), mac_pos);
205 EXPECT_NE(mode_pos, string::npos);
206 return id.find(string(security), mode_pos) != string::npos;
207 }
208
209 // Test that a service that is created with security |from_security|
210 // gets by default a storage identifier with |to_security| as its
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800211 // security component, and that when saved, it sets the Security
212 // property in to |to_security| as well.
Paul Stewartd08f4432011-11-04 07:48:20 -0700213 bool TestStorageMapping(const string &from_security,
214 const string &to_security) {
Paul Stewart3c504012013-01-17 17:49:58 -0800215 WiFiServiceRefPtr wifi_service = MakeSimpleService(from_security);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800216 NiceMock<MockStore> mock_store;
217 EXPECT_CALL(mock_store, SetString(_, _, _)).WillRepeatedly(Return(true));
218 EXPECT_CALL(mock_store,
219 SetString(_, WiFiService::kStorageSecurity, from_security))
220 .Times(1);
221 EXPECT_CALL(mock_store,
222 SetString(_, WiFiService::kStorageSecurityClass, to_security))
223 .Times(1);
224 wifi_service->Save(&mock_store);
Paul Stewartd08f4432011-11-04 07:48:20 -0700225 return TestStorageSecurityIs(wifi_service, to_security);
226 }
227
228 // Test whether a service of type |service_security| can load from a
229 // storage interface containing an entry for |storage_security|.
230 // Make sure the result meets |expectation|. If |expectation| is
231 // true, also make sure the service storage identifier changes to
232 // match |storage_security|.
233 bool TestLoadMapping(const string &service_security,
234 const string &storage_security,
235 bool expectation) {
Paul Stewart3c504012013-01-17 17:49:58 -0800236 WiFiServiceRefPtr wifi_service = MakeSimpleService(service_security);
Paul Stewartd08f4432011-11-04 07:48:20 -0700237 NiceMock<MockStore> mock_store;
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800238 EXPECT_CALL(mock_store, GetGroupsWithProperties(_))
239 .WillRepeatedly(Return(set<string>()));
240 const string kStorageId = "storage_id";
241 EXPECT_CALL(mock_store, ContainsGroup(kStorageId))
Paul Stewartd08f4432011-11-04 07:48:20 -0700242 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800243 set<string> groups;
244 groups.insert(kStorageId);
245 EXPECT_CALL(mock_store, GetGroupsWithProperties(
246 ContainsWiFiProperties(wifi_service->ssid(),
247 flimflam::kModeManaged,
248 storage_security)))
249 .WillRepeatedly(Return(groups));
Paul Stewarte7de2942013-04-25 17:07:31 -0700250 bool is_loadable = wifi_service->IsLoadableFrom(mock_store);
Paul Stewartd08f4432011-11-04 07:48:20 -0700251 EXPECT_EQ(expectation, is_loadable);
252 bool is_loaded = wifi_service->Load(&mock_store);
253 EXPECT_EQ(expectation, is_loaded);
Paul Stewarte7de2942013-04-25 17:07:31 -0700254 const string expected_identifier(expectation ? kStorageId : "");
255 EXPECT_EQ(expected_identifier,
256 wifi_service->GetLoadableStorageIdentifier(mock_store));
Paul Stewartd08f4432011-11-04 07:48:20 -0700257
258 if (expectation != is_loadable || expectation != is_loaded) {
259 return false;
260 } else if (!expectation) {
261 return true;
262 } else {
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800263 return wifi_service->GetStorageIdentifier() == kStorageId;
Paul Stewartd08f4432011-11-04 07:48:20 -0700264 }
265 }
266};
267
mukesh agrawale1d90e92012-02-15 17:36:08 -0800268class WiFiServiceUpdateFromEndpointsTest : public WiFiServiceTest {
269 public:
270 WiFiServiceUpdateFromEndpointsTest()
271 : kOkEndpointStrength(WiFiService::SignalToStrength(kOkEndpointSignal)),
272 kBadEndpointStrength(WiFiService::SignalToStrength(kBadEndpointSignal)),
273 kGoodEndpointStrength(
274 WiFiService::SignalToStrength(kGoodEndpointSignal)),
275 service(MakeGenericService()),
276 adaptor(*GetAdaptor(service)) {
mukesh agrawal43970a22013-02-15 16:00:07 -0800277 ok_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800278 simple_ssid_string(), kOkEndpointBssId, kOkEndpointFrequency,
279 kOkEndpointSignal);
mukesh agrawal43970a22013-02-15 16:00:07 -0800280 good_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800281 simple_ssid_string(), kGoodEndpointBssId, kGoodEndpointFrequency,
282 kGoodEndpointSignal);
mukesh agrawal43970a22013-02-15 16:00:07 -0800283 bad_endpoint = MakeOpenEndpoint(
Paul Stewart3c504012013-01-17 17:49:58 -0800284 simple_ssid_string(), kBadEndpointBssId, kBadEndpointFrequency,
285 kBadEndpointSignal);
mukesh agrawale1d90e92012-02-15 17:36:08 -0800286 }
287
288 protected:
289 static const uint16 kOkEndpointFrequency = 2422;
290 static const uint16 kBadEndpointFrequency = 2417;
291 static const uint16 kGoodEndpointFrequency = 2412;
292 static const int16 kOkEndpointSignal = -50;
293 static const int16 kBadEndpointSignal = -75;
294 static const int16 kGoodEndpointSignal = -25;
mukesh agrawal923f14f2012-06-04 16:46:08 -0700295 static const char *kOkEndpointBssId;
296 static const char *kGoodEndpointBssId;
297 static const char *kBadEndpointBssId;
mukesh agrawale1d90e92012-02-15 17:36:08 -0800298 // Can't be both static and const (because initialization requires a
299 // function call). So choose to be just const.
300 const uint8 kOkEndpointStrength;
301 const uint8 kBadEndpointStrength;
302 const uint8 kGoodEndpointStrength;
303 WiFiEndpointRefPtr ok_endpoint;
304 WiFiEndpointRefPtr bad_endpoint;
305 WiFiEndpointRefPtr good_endpoint;
306 WiFiServiceRefPtr service;
307 ServiceMockAdaptor &adaptor;
308};
309
mukesh agrawal923f14f2012-06-04 16:46:08 -0700310const char *WiFiServiceUpdateFromEndpointsTest::kOkEndpointBssId =
311 "00:00:00:00:00:01";
312const char *WiFiServiceUpdateFromEndpointsTest::kGoodEndpointBssId =
313 "00:00:00:00:00:02";
314const char *WiFiServiceUpdateFromEndpointsTest::kBadEndpointBssId =
315 "00:00:00:00:00:03";
mukesh agrawale1d90e92012-02-15 17:36:08 -0800316
Paul Stewart85aea152013-01-22 09:31:56 -0800317class WiFiServiceFixupStorageTest : public WiFiServiceTest {
318 protected:
319 void AddGroup(string group_name) {
320 groups_.insert(group_name);
321 }
322
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800323 void AddServiceEntry(bool has_type, bool has_mode, bool has_security,
324 bool has_security_class) {
Paul Stewart85aea152013-01-22 09:31:56 -0800325 int index = groups_.size();
326 string id = base::StringPrintf("%s_%d_%d_%s_%s", flimflam::kTypeWifi,
327 index, index, flimflam::kModeManaged,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800328 flimflam::kSecurityWpa);
Paul Stewart85aea152013-01-22 09:31:56 -0800329 AddGroup(id);
330 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageType, _))
331 .WillOnce(Return(has_type));
332 if (!has_type) {
333 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageType,
334 flimflam::kTypeWifi));
335 }
336 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageMode, _))
337 .WillOnce(Return(has_mode));
338 if (!has_mode) {
339 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageMode,
340 flimflam::kModeManaged));
341 }
342 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurity, _))
343 .WillOnce(Return(has_security));
344 if (!has_security) {
345 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurity,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800346 flimflam::kSecurityWpa));
347 }
348 EXPECT_CALL(store_, GetString(id, WiFiService::kStorageSecurityClass, _))
349 .WillOnce(Return(has_security_class));
350 if (!has_security_class) {
351 EXPECT_CALL(store_, SetString(id, WiFiService::kStorageSecurityClass,
352 flimflam::kSecurityPsk));
Paul Stewart85aea152013-01-22 09:31:56 -0800353 }
354 }
355
356 bool FixupServiceEntries() {
357 EXPECT_CALL(store_, GetGroups()).WillOnce(Return(groups_));
358 return WiFiService::FixupServiceEntries(&store_);
359 }
360
361 private:
362 StrictMock<MockStore> store_;
363 set<string> groups_;
364};
365
Chris Masone34af2182011-08-22 11:59:36 -0700366TEST_F(WiFiServiceTest, StorageId) {
Paul Stewart3c504012013-01-17 17:49:58 -0800367 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Chris Masone9d779932011-08-25 16:33:41 -0700368 string id = wifi_service->GetStorageIdentifier();
Chris Masone34af2182011-08-22 11:59:36 -0700369 for (uint i = 0; i < id.length(); ++i) {
370 EXPECT_TRUE(id[i] == '_' ||
371 isxdigit(id[i]) ||
372 (isalpha(id[i]) && islower(id[i])));
373 }
Paul Stewart3c504012013-01-17 17:49:58 -0800374 size_t mac_pos = id.find(StringToLowerASCII(GetAnyDeviceAddress()));
Chris Masone34af2182011-08-22 11:59:36 -0700375 EXPECT_NE(mac_pos, string::npos);
376 EXPECT_NE(id.find(string(flimflam::kModeManaged), mac_pos), string::npos);
377}
378
Gaurav Shahda6218a2011-11-11 12:09:33 -0800379// Make sure the passphrase is registered as a write only property
380// by reading and comparing all string properties returned on the store.
381TEST_F(WiFiServiceTest, PassphraseWriteOnly) {
Paul Stewart3c504012013-01-17 17:49:58 -0800382 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWpa);
Gaurav Shahda6218a2011-11-11 12:09:33 -0800383 ReadablePropertyConstIterator<string> it =
384 (wifi_service->store()).GetStringPropertiesIter();
Wade Guthrief54872f2013-04-11 15:11:50 -0700385 for ( ; !it.AtEnd(); it.Advance())
Gaurav Shahda6218a2011-11-11 12:09:33 -0800386 EXPECT_NE(it.Key(), flimflam::kPassphraseProperty);
387}
388
Thieu Lef7709452011-11-15 01:13:19 +0000389// Make sure setting the passphrase via D-Bus Service.SetProperty validates
390// the passphrase.
391TEST_F(WiFiServiceTest, PassphraseSetPropertyValidation) {
392 // We only spot check two password cases here to make sure the
393 // SetProperty code path does validation. We're not going to exhaustively
394 // test for all types of passwords.
Paul Stewart3c504012013-01-17 17:49:58 -0800395 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
Thieu Lef7709452011-11-15 01:13:19 +0000396 Error error;
397 EXPECT_TRUE(wifi_service->mutable_store()->SetStringProperty(
398 flimflam::kPassphraseProperty, "0:abcde", &error));
399 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
400 flimflam::kPassphraseProperty, "invalid", &error));
401 EXPECT_EQ(Error::kInvalidPassphrase, error.type());
402}
403
404TEST_F(WiFiServiceTest, PassphraseSetPropertyOpenNetwork) {
Paul Stewart3c504012013-01-17 17:49:58 -0800405 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityNone);
Thieu Lef7709452011-11-15 01:13:19 +0000406 Error error;
407 EXPECT_FALSE(wifi_service->mutable_store()->SetStringProperty(
408 flimflam::kPassphraseProperty, "invalid", &error));
409 EXPECT_EQ(Error::kNotSupported, error.type());
410}
411
mukesh agrawald835b202011-10-07 15:26:47 -0700412TEST_F(WiFiServiceTest, NonUTF8SSID) {
413 vector<uint8_t> ssid;
414
415 ssid.push_back(0xff); // not a valid UTF-8 byte-sequence
416 WiFiServiceRefPtr wifi_service = new WiFiService(control_interface(),
417 dispatcher(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800418 metrics(),
mukesh agrawald835b202011-10-07 15:26:47 -0700419 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800420 provider(),
mukesh agrawald835b202011-10-07 15:26:47 -0700421 ssid,
422 flimflam::kModeManaged,
Paul Stewartced6a0b2011-11-08 15:32:04 -0800423 flimflam::kSecurityNone,
424 false);
mukesh agrawald835b202011-10-07 15:26:47 -0700425 map<string, ::DBus::Variant> properties;
426 // if service doesn't propertly sanitize SSID, this will generate SIGABRT.
427 DBusAdaptor::GetProperties(wifi_service->store(), &properties, NULL);
428}
429
Paul Stewart4108db92013-03-11 12:13:24 -0700430MATCHER(PSKSecurityArgs, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700431 return ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol) &&
432 arg.find(WPASupplicant::kPropertySecurityProtocol)->second.
Paul Stewart4108db92013-03-11 12:13:24 -0700433 reader().get_string() == string("WPA RSN") &&
Paul Stewart0654ece2013-03-26 15:21:26 -0700434 ContainsKey(arg, WPASupplicant::kPropertyPreSharedKey);
Gaurav Shahda6218a2011-11-11 12:09:33 -0800435}
436
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800437MATCHER(WPA80211wSecurityArgs, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700438 return ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol) &&
439 ContainsKey(arg, WPASupplicant::kPropertyPreSharedKey) &&
440 ContainsKey(arg, WPASupplicant::kNetworkPropertyIeee80211w);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800441}
442
Gaurav Shah10109f22011-11-11 20:16:22 -0800443MATCHER(EAPSecurityArgs, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700444 return ContainsKey(arg, WPASupplicant::kNetworkPropertyEapIdentity) &&
445 ContainsKey(arg, WPASupplicant::kNetworkPropertyCaPath);
Gaurav Shah10109f22011-11-11 20:16:22 -0800446}
447
Paul Stewarte2d7c502012-07-16 16:35:10 -0700448MATCHER_P(FrequencyArg, has_arg, "") {
449 return has_arg ==
Paul Stewart0654ece2013-03-26 15:21:26 -0700450 ContainsKey(arg, WPASupplicant::kNetworkPropertyFrequency);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700451}
452
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700453TEST_F(WiFiServiceTest, ConnectTaskWPA) {
Paul Stewart3c504012013-01-17 17:49:58 -0800454 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWpa);
Paul Stewart4108db92013-03-11 12:13:24 -0700455 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700456 Error error;
457 wifi_service->SetPassphrase("0:mumblemumblem", &error);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700458 wifi_service->Connect(NULL, "in test");
mukesh agrawal6e277772011-09-29 15:04:23 -0700459}
460
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700461TEST_F(WiFiServiceTest, ConnectTaskRSN) {
Paul Stewart3c504012013-01-17 17:49:58 -0800462 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
Paul Stewart4108db92013-03-11 12:13:24 -0700463 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700464 Error error;
465 wifi_service->SetPassphrase("0:mumblemumblem", &error);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700466 wifi_service->Connect(NULL, "in test");
mukesh agrawalf2fd7452011-10-03 16:38:47 -0700467}
468
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700469TEST_F(WiFiServiceTest, ConnectConditions) {
470 Error error;
Paul Stewart3c504012013-01-17 17:49:58 -0800471 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700472 scoped_refptr<MockProfile> mock_profile(
Thieu Le5133b712013-02-19 14:47:21 -0800473 new NiceMock<MockProfile>(control_interface(), metrics(), manager()));
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700474 wifi_service->set_profile(mock_profile);
475 // With nothing else going on, the service should attempt to connect.
476 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), _));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700477 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700478 Mock::VerifyAndClearExpectations(wifi());
479
480 // But if we're already "connecting" or "connected" then we shouldn't attempt
481 // again.
482 EXPECT_CALL(*wifi(),
483 ConnectTo(wifi_service.get(), _)).Times(0);
484 wifi_service->SetState(Service::kStateAssociating);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700485 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700486 wifi_service->SetState(Service::kStateConfiguring);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700487 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700488 wifi_service->SetState(Service::kStateConnected);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700489 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700490 wifi_service->SetState(Service::kStatePortal);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700491 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700492 wifi_service->SetState(Service::kStateOnline);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700493 wifi_service->Connect(&error, "in test");
Christopher Wiley1ce658d2012-10-10 10:02:03 -0700494 Mock::VerifyAndClearExpectations(wifi());
495}
496
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800497TEST_F(WiFiServiceTest, ConnectTaskPSK) {
Paul Stewart3c504012013-01-17 17:49:58 -0800498 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
Paul Stewart4108db92013-03-11 12:13:24 -0700499 EXPECT_CALL(*wifi(), ConnectTo(wifi_service.get(), PSKSecurityArgs()));
Wade Guthrie005bd342012-05-02 09:37:07 -0700500 Error error;
501 wifi_service->SetPassphrase("0:mumblemumblem", &error);
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700502 wifi_service->Connect(NULL, "in test");
Gaurav Shahf8721ee2011-11-07 09:12:46 -0800503}
504
Gaurav Shah10109f22011-11-11 20:16:22 -0800505TEST_F(WiFiServiceTest, ConnectTask8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -0800506 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700507 service->mutable_eap()->set_identity("identity");
508 service->mutable_eap()->set_password("mumble");
509 service->OnEapCredentialsChanged();
Paul Stewart3c504012013-01-17 17:49:58 -0800510 EXPECT_CALL(*wifi(), ConnectTo(service.get(), EAPSecurityArgs()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700511 service->Connect(NULL, "in test");
Gaurav Shah10109f22011-11-11 20:16:22 -0800512}
513
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700514TEST_F(WiFiServiceTest, ConnectTask8021xWithMockEap) {
515 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
516 MockEapCredentials *eap = SetMockEap(service);
517 EXPECT_CALL(*eap, IsConnectable()).WillOnce(Return(true));
518 service->OnEapCredentialsChanged();
519 EXPECT_CALL(*eap, PopulateSupplicantProperties(_, _, _, _));
520 // The mocked function does not actually set EAP parameters so we cannot
521 // expect them to be set.
522 EXPECT_CALL(*wifi(), ConnectTo(service.get(), _));
523 service->Connect(NULL, "in test");
524}
525
Paul Stewarte2d7c502012-07-16 16:35:10 -0700526TEST_F(WiFiServiceTest, ConnectTaskAdHocFrequency) {
527 vector<uint8_t> ssid(1, 'a');
528 WiFiEndpointRefPtr endpoint_nofreq =
mukesh agrawal43970a22013-02-15 16:00:07 -0800529 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700530 WiFiEndpointRefPtr endpoint_freq =
mukesh agrawal43970a22013-02-15 16:00:07 -0800531 MakeOpenEndpoint("a", "00:00:00:00:00:02", 2412, 0);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700532
Paul Stewart3c504012013-01-17 17:49:58 -0800533 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewarte2d7c502012-07-16 16:35:10 -0700534 wifi_service->AddEndpoint(endpoint_freq);
535 EXPECT_CALL(*wifi(),
536 ConnectTo(wifi_service.get(), FrequencyArg(false)));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700537 wifi_service->Connect(NULL, "in test");
Paul Stewarte2d7c502012-07-16 16:35:10 -0700538
539 wifi_service = new WiFiService(control_interface(),
540 dispatcher(),
541 metrics(),
542 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800543 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700544 ssid,
545 flimflam::kModeAdhoc,
546 flimflam::kSecurityNone,
547 false);
548 EXPECT_CALL(*wifi(),
549 ConnectTo(wifi_service.get(), FrequencyArg(false)));
Paul Stewart3c504012013-01-17 17:49:58 -0800550 SetWiFiForService(wifi_service, wifi());
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700551 wifi_service->Connect(NULL, "in test");
Paul Stewarte2d7c502012-07-16 16:35:10 -0700552
553 wifi_service = new WiFiService(control_interface(),
554 dispatcher(),
555 metrics(),
556 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800557 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700558 ssid,
559 flimflam::kModeAdhoc,
560 flimflam::kSecurityNone,
561 false);
562 wifi_service->AddEndpoint(endpoint_nofreq);
Paul Stewart3c504012013-01-17 17:49:58 -0800563 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700564 EXPECT_CALL(*wifi(),
565 ConnectTo(wifi_service.get(), FrequencyArg(false)));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700566 wifi_service->Connect(NULL, "in test");
Paul Stewarte2d7c502012-07-16 16:35:10 -0700567
568 wifi_service = new WiFiService(control_interface(),
569 dispatcher(),
570 metrics(),
571 manager(),
Paul Stewart3c504012013-01-17 17:49:58 -0800572 provider(),
Paul Stewarte2d7c502012-07-16 16:35:10 -0700573 ssid,
574 flimflam::kModeAdhoc,
575 flimflam::kSecurityNone,
576 false);
577 wifi_service->AddEndpoint(endpoint_freq);
Paul Stewart3c504012013-01-17 17:49:58 -0800578 SetWiFiForService(wifi_service, wifi());
Paul Stewarte2d7c502012-07-16 16:35:10 -0700579 EXPECT_CALL(*wifi(),
580 ConnectTo(wifi_service.get(), FrequencyArg(true)));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700581 wifi_service->Connect(NULL, "in test");
Paul Stewarte2d7c502012-07-16 16:35:10 -0700582}
583
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800584TEST_F(WiFiServiceTest, ConnectTaskWPA80211w) {
Paul Stewart3c504012013-01-17 17:49:58 -0800585 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityPsk);
mukesh agrawal43970a22013-02-15 16:00:07 -0800586 WiFiEndpointRefPtr endpoint =
587 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800588 endpoint->ieee80211w_required_ = true;
589 wifi_service->AddEndpoint(endpoint);
590 Error error;
591 wifi_service->SetPassphrase("0:mumblemumblem", &error);
592 EXPECT_CALL(*wifi(),
593 ConnectTo(wifi_service.get(), WPA80211wSecurityArgs()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700594 wifi_service->Connect(NULL, "in test");
Paul Stewarta5e7d5f2013-01-09 18:06:15 -0800595}
596
Thieu Lef4cbda92011-11-10 23:41:24 +0000597MATCHER(WEPSecurityArgsKeyIndex0, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700598 return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
599 ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("0")) &&
600 ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
601 (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
Thieu Lef4cbda92011-11-10 23:41:24 +0000602 reader().get_uint32() == 0);
603}
604
605MATCHER(WEPSecurityArgsKeyIndex1, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700606 return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
607 ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("1")) &&
608 ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
609 (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
Thieu Lef4cbda92011-11-10 23:41:24 +0000610 reader().get_uint32() == 1);
611}
612
613MATCHER(WEPSecurityArgsKeyIndex2, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700614 return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
615 ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("2")) &&
616 ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
617 (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
Thieu Lef4cbda92011-11-10 23:41:24 +0000618 reader().get_uint32() == 2);
619}
620
621MATCHER(WEPSecurityArgsKeyIndex3, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700622 return ContainsKey(arg, WPASupplicant::kPropertyAuthAlg) &&
623 ContainsKey(arg, WPASupplicant::kPropertyWEPKey + std::string("3")) &&
624 ContainsKey(arg, WPASupplicant::kPropertyWEPTxKeyIndex) &&
625 (arg.find(WPASupplicant::kPropertyWEPTxKeyIndex)->second.
Thieu Lef4cbda92011-11-10 23:41:24 +0000626 reader().get_uint32() == 3);
627}
628
629TEST_F(WiFiServiceTest, ConnectTaskWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800630 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Thieu Lef4cbda92011-11-10 23:41:24 +0000631 Error error;
632 wifi_service->SetPassphrase("0:abcdefghijklm", &error);
633 EXPECT_CALL(*wifi(),
634 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700635 wifi_service->Connect(NULL, "in test");
Thieu Lef4cbda92011-11-10 23:41:24 +0000636
637 wifi_service->SetPassphrase("abcdefghijklm", &error);
638 EXPECT_CALL(*wifi(),
639 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex0()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700640 wifi_service->Connect(NULL, "in test");
Thieu Lef4cbda92011-11-10 23:41:24 +0000641
642 wifi_service->SetPassphrase("1:abcdefghijklm", &error);
643 EXPECT_CALL(*wifi(),
644 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex1()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700645 wifi_service->Connect(NULL, "in test");
Thieu Lef4cbda92011-11-10 23:41:24 +0000646
647 wifi_service->SetPassphrase("2:abcdefghijklm", &error);
648 EXPECT_CALL(*wifi(),
649 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex2()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700650 wifi_service->Connect(NULL, "in test");
Thieu Lef4cbda92011-11-10 23:41:24 +0000651
652 wifi_service->SetPassphrase("3:abcdefghijklm", &error);
653 EXPECT_CALL(*wifi(),
654 ConnectTo(wifi_service.get(), WEPSecurityArgsKeyIndex3()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700655 wifi_service->Connect(NULL, "in test");
Thieu Lef4cbda92011-11-10 23:41:24 +0000656}
657
Gaurav Shah29d68882012-01-30 19:06:42 -0800658
659MATCHER(DynamicWEPArgs, "") {
Paul Stewart0654ece2013-03-26 15:21:26 -0700660 return ContainsKey(arg, WPASupplicant::kNetworkPropertyEapIdentity) &&
661 ContainsKey(arg, WPASupplicant::kNetworkPropertyCaPath) &&
662 !ContainsKey(arg, WPASupplicant::kPropertySecurityProtocol);
Gaurav Shah29d68882012-01-30 19:06:42 -0800663}
664
665// Dynamic WEP + 802.1x.
666TEST_F(WiFiServiceTest, ConnectTaskDynamicWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -0800667 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Gaurav Shah29d68882012-01-30 19:06:42 -0800668
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700669 wifi_service->mutable_eap()->SetKeyManagement("IEEE8021X", NULL);
670 wifi_service->mutable_eap()->set_identity("something");
671 wifi_service->mutable_eap()->set_password("mumble");
672 wifi_service->OnEapCredentialsChanged();
Gaurav Shah29d68882012-01-30 19:06:42 -0800673 EXPECT_CALL(*wifi(),
674 ConnectTo(wifi_service.get(), DynamicWEPArgs()));
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700675 wifi_service->Connect(NULL, "in test");
Gaurav Shah29d68882012-01-30 19:06:42 -0800676}
677
Paul Stewart835934a2012-12-06 19:27:09 -0800678TEST_F(WiFiServiceTest, SetPassphraseRemovesCachedCredentials) {
Paul Stewart3c504012013-01-17 17:49:58 -0800679 WiFiServiceRefPtr wifi_service = MakeServiceWithWiFi(flimflam::kSecurityRsn);
Paul Stewart835934a2012-12-06 19:27:09 -0800680
681 const string kPassphrase = "abcdefgh";
682
683 {
684 Error error;
685 // A changed passphrase should trigger cache removal.
686 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
687 wifi_service->SetPassphrase(kPassphrase, &error);
688 Mock::VerifyAndClearExpectations(wifi());
689 EXPECT_TRUE(error.IsSuccess());
690 }
691
692 {
693 Error error;
694 // An unchanged passphrase should not trigger cache removal.
695 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
696 wifi_service->SetPassphrase(kPassphrase, &error);
697 Mock::VerifyAndClearExpectations(wifi());
698 EXPECT_TRUE(error.IsSuccess());
699 }
700
701 {
702 Error error;
703 // A modified passphrase should trigger cache removal.
704 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
705 wifi_service->SetPassphrase(kPassphrase + "X", &error);
706 Mock::VerifyAndClearExpectations(wifi());
707 EXPECT_TRUE(error.IsSuccess());
708 }
709
710 {
711 Error error;
712 // A cleared passphrase should also trigger cache removal.
713 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
714 wifi_service->ClearPassphrase(&error);
715 Mock::VerifyAndClearExpectations(wifi());
716 EXPECT_TRUE(error.IsSuccess());
717 }
718
719 {
720 Error error;
721 // An invalid passphrase should not trigger cache removal.
722 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
723 wifi_service->SetPassphrase("", &error);
724 Mock::VerifyAndClearExpectations(wifi());
725 EXPECT_FALSE(error.IsSuccess());
726 }
727
728 {
729 // Any change to EAP parameters (including a null one) will trigger cache
730 // removal. This is a lot less granular than the passphrase checks above.
731 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
Paul Stewartc43cbbe2013-04-11 06:29:30 -0700732 wifi_service->OnEapCredentialsChanged();
Paul Stewart835934a2012-12-06 19:27:09 -0800733 Mock::VerifyAndClearExpectations(wifi());
734 }
735}
736
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700737// This test is somewhat redundant, since:
738//
739// a) we test that generic property setters return false on a null
740// change (e.g. in PropertyAccessorTest.SignedIntCorrectness)
741// b) we test that custom EAP property setters return false on a null
742// change in EapCredentialsTest.CustomSetterNoopChange
743// c) we test that the various custom accessors pass through the
744// return value of custom setters
745// (e.g. PropertyAccessorTest.CustomAccessorCorrectness)
746// d) we test that PropertyStore skips the change callback when a
747// property setter return false (PropertyStoreTypedTest.SetProperty)
748//
749// Nonetheless, I think it's worth testing the WiFi+EAP case directly.
750TEST_F(WiFiServiceTest, EapAuthPropertyChangeClearsCachedCredentials) {
751 WiFiServiceRefPtr wifi_service =
752 MakeServiceWithWiFi(flimflam::kSecurity8021x);
753 PropertyStore &property_store(*wifi_service->mutable_store());
754
755 // Property with custom accessor.
756 const string kPassword = "abcdefgh";
757 {
758 Error error;
759 // A changed passphrase should trigger cache removal.
760 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
761 EXPECT_TRUE(property_store.SetStringProperty(
762 flimflam::kEapPasswordProperty, kPassword, &error));
763 Mock::VerifyAndClearExpectations(wifi());
764 EXPECT_TRUE(error.IsSuccess());
765 }
766 {
767 Error error;
768 // An unchanged passphrase should not trigger cache removal.
769 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
770 EXPECT_FALSE(property_store.SetStringProperty(
771 flimflam::kEapPasswordProperty, kPassword, &error));
772 Mock::VerifyAndClearExpectations(wifi());
773 EXPECT_TRUE(error.IsSuccess());
774 }
775 {
776 Error error;
777 // A modified passphrase should trigger cache removal.
778 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
779 EXPECT_TRUE(property_store.SetStringProperty(
780 flimflam::kEapPasswordProperty, kPassword + "X", &error));
781 Mock::VerifyAndClearExpectations(wifi());
782 EXPECT_TRUE(error.IsSuccess());
783 }
784
785 // Property with generic accessor.
786 const string kCertId = "abcdefgh";
787 {
788 Error error;
789 // A changed cert id should trigger cache removal.
790 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
791 EXPECT_TRUE(property_store.SetStringProperty(
792 flimflam::kEapCertIdProperty, kCertId, &error));
793 Mock::VerifyAndClearExpectations(wifi());
794 EXPECT_TRUE(error.IsSuccess());
795 }
796 {
797 Error error;
798 // An unchanged cert id should not trigger cache removal.
799 EXPECT_CALL(*wifi(), ClearCachedCredentials(_)).Times(0);
800 EXPECT_FALSE(property_store.SetStringProperty(
801 flimflam::kEapCertIdProperty, kCertId, &error));
802 Mock::VerifyAndClearExpectations(wifi());
803 EXPECT_TRUE(error.IsSuccess());
804 }
805 {
806 Error error;
807 // A modified cert id should trigger cache removal.
808 EXPECT_CALL(*wifi(), ClearCachedCredentials(wifi_service.get()));
809 EXPECT_TRUE(property_store.SetStringProperty(
810 flimflam::kEapCertIdProperty, kCertId + "X", &error));
811 Mock::VerifyAndClearExpectations(wifi());
812 EXPECT_TRUE(error.IsSuccess());
813 }
814}
815
Paul Stewartd08f4432011-11-04 07:48:20 -0700816TEST_F(WiFiServiceTest, LoadHidden) {
Paul Stewart3c504012013-01-17 17:49:58 -0800817 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewartd08f4432011-11-04 07:48:20 -0700818 ASSERT_FALSE(service->hidden_ssid_);
819 NiceMock<MockStore> mock_store;
820 const string storage_id = service->GetStorageIdentifier();
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800821 set<string> groups;
822 groups.insert(storage_id);
Paul Stewartd08f4432011-11-04 07:48:20 -0700823 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
824 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800825 EXPECT_CALL(mock_store, GetGroupsWithProperties(
826 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800827 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800828 .WillRepeatedly(Return(groups));
Paul Stewartd08f4432011-11-04 07:48:20 -0700829 EXPECT_CALL(mock_store, GetBool(_, _, _))
830 .WillRepeatedly(Return(false));
831 EXPECT_CALL(mock_store,
832 GetBool(StrEq(storage_id), WiFiService::kStorageHiddenSSID, _))
833 .WillRepeatedly(DoAll(SetArgumentPointee<2>(true), Return(true)));
834 EXPECT_TRUE(service->Load(&mock_store));
835 EXPECT_TRUE(service->hidden_ssid_);
836}
837
Paul Stewartfa013ab2013-04-11 07:12:03 -0700838TEST_F(WiFiServiceTest, LoadPassphraseForNonPassphraseService) {
839 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
840 NiceMock<MockStore> mock_store;
841 const string storage_id = service->GetStorageIdentifier();
842 set<string> groups;
843 groups.insert(storage_id);
844 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
845 .WillRepeatedly(Return(true));
846 EXPECT_CALL(mock_store, GetGroupsWithProperties(
847 ContainsWiFiProperties(
848 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
849 .WillRepeatedly(Return(groups));
850 EXPECT_CALL(mock_store,
851 GetCryptedString(StrEq(storage_id),
852 StrNe(WiFiService::kStoragePassphrase), _))
853 .WillRepeatedly(Return(false));
854 EXPECT_CALL(mock_store,
855 GetCryptedString(StrEq(storage_id),
856 WiFiService::kStoragePassphrase, _))
857 .WillOnce(DoAll(SetArgumentPointee<2>(string("password")), Return(true)))
858 .WillOnce(DoAll(SetArgumentPointee<2>(string()), Return(true)));
859 ScopedMockLog log;
860 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
861 EndsWith("Passphrase could not be set: "
862 "org.chromium.flimflam.Error.NotSupported")))
863 .Times(1);
864 EXPECT_TRUE(service->Load(&mock_store));
865 Mock::VerifyAndClearExpectations(&log);
866 EXPECT_CALL(log, Log(logging::LOG_ERROR, _, _)).Times(0);
867 EXPECT_TRUE(service->Load(&mock_store));
868}
869
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800870TEST_F(WiFiServiceTest, LoadMultipleMatchingGroups) {
Paul Stewart3c504012013-01-17 17:49:58 -0800871 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800872 set<string> groups;
873 groups.insert("id0");
874 groups.insert("id1");
875 // Make sure we retain the first matched group in the same way that
876 // WiFiService::Load() will.
877 string first_group = *groups.begin();
878
879 NiceMock<MockStore> mock_store;
880 EXPECT_CALL(mock_store, GetGroupsWithProperties(
881 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800882 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityNone)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800883 .WillRepeatedly(Return(groups));
884 EXPECT_CALL(mock_store, ContainsGroup(first_group))
885 .WillRepeatedly(Return(true));
886 EXPECT_CALL(mock_store, ContainsGroup(StrNe(first_group))).Times(0);
887 EXPECT_CALL(mock_store, GetBool(first_group, _, _))
888 .WillRepeatedly(Return(false));
889 EXPECT_CALL(mock_store, GetBool(StrNe(first_group), _, _)).Times(0);
890 ScopedMockLog log;
891 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
892 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
893 EndsWith("choosing the first.")));
894 EXPECT_TRUE(service->Load(&mock_store));
895}
896
Paul Stewartd08f4432011-11-04 07:48:20 -0700897TEST_F(WiFiServiceSecurityTest, WPAMapping) {
898 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityRsn,
899 flimflam::kSecurityPsk));
900 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWpa,
901 flimflam::kSecurityPsk));
902 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityPsk,
903 flimflam::kSecurityPsk));
904 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityWep,
905 flimflam::kSecurityWep));
906 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurityNone,
907 flimflam::kSecurityNone));
Gaurav Shah10109f22011-11-11 20:16:22 -0800908 EXPECT_TRUE(TestStorageMapping(flimflam::kSecurity8021x,
909 flimflam::kSecurity8021x));
Paul Stewartd08f4432011-11-04 07:48:20 -0700910}
911
912TEST_F(WiFiServiceSecurityTest, LoadMapping) {
913 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
914 flimflam::kSecurityPsk,
915 true));
916 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
917 flimflam::kSecurityRsn,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800918 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700919 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityRsn,
920 flimflam::kSecurityWpa,
921 false));
922 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
923 flimflam::kSecurityPsk,
924 true));
925 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
926 flimflam::kSecurityWpa,
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800927 false));
Paul Stewartd08f4432011-11-04 07:48:20 -0700928 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWpa,
929 flimflam::kSecurityRsn,
930 false));
931 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
932 flimflam::kSecurityWep,
933 true));
934 EXPECT_TRUE(TestLoadMapping(flimflam::kSecurityWep,
935 flimflam::kSecurityPsk,
936 false));
937}
938
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800939TEST_F(WiFiServiceTest, LoadAndUnloadPassphrase) {
Paul Stewart3c504012013-01-17 17:49:58 -0800940 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800941 NiceMock<MockStore> mock_store;
942 const string storage_id = service->GetStorageIdentifier();
943 EXPECT_CALL(mock_store, ContainsGroup(StrEq(storage_id)))
944 .WillRepeatedly(Return(true));
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800945 set<string> groups;
946 groups.insert(storage_id);
947 EXPECT_CALL(mock_store, GetGroupsWithProperties(
948 ContainsWiFiProperties(
Paul Stewart3c504012013-01-17 17:49:58 -0800949 simple_ssid(), flimflam::kModeManaged, flimflam::kSecurityPsk)))
Paul Stewart71a4d3b2013-01-18 18:12:56 -0800950 .WillRepeatedly(Return(groups));
Paul Stewartd8ad3c42012-01-09 12:39:38 -0800951 EXPECT_CALL(mock_store, GetBool(_, _, _))
952 .WillRepeatedly(Return(false));
953 const string passphrase = "passphrase";
954 EXPECT_CALL(mock_store,
955 GetCryptedString(StrEq(storage_id),
956 WiFiService::kStoragePassphrase, _))
957 .WillRepeatedly(DoAll(SetArgumentPointee<2>(passphrase), Return(true)));
958 EXPECT_CALL(mock_store,
959 GetCryptedString(StrEq(storage_id),
960 StrNe(WiFiService::kStoragePassphrase), _))
961 .WillRepeatedly(Return(false));
962 EXPECT_TRUE(service->need_passphrase_);
963 EXPECT_TRUE(service->Load(&mock_store));
964 EXPECT_EQ(passphrase, service->passphrase_);
965 EXPECT_TRUE(service->connectable());
966 EXPECT_FALSE(service->need_passphrase_);
967 service->Unload();
968 EXPECT_EQ(string(""), service->passphrase_);
969 EXPECT_FALSE(service->connectable());
970 EXPECT_TRUE(service->need_passphrase_);
971}
972
Christopher Wiley27b47232012-11-02 13:13:00 -0700973TEST_F(WiFiServiceTest, ConfigureMakesConnectable) {
974 string guid("legit_guid");
975 KeyValueStore args;
976 args.SetString(flimflam::kEapIdentityProperty, "legit_identity");
977 args.SetString(flimflam::kEapPasswordProperty, "legit_password");
978 args.SetString(flimflam::kEAPEAPProperty, "PEAP");
979 args.SetString(flimflam::kGuidProperty, guid);
980 Error error;
Christopher Wiley27b47232012-11-02 13:13:00 -0700981
Paul Stewart3c504012013-01-17 17:49:58 -0800982 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Christopher Wiley27b47232012-11-02 13:13:00 -0700983 // Hack the GUID in so that we don't have to mess about with WiFi to regsiter
984 // our service. This way, Manager will handle the lookup itself.
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700985 service->SetGuid(guid, NULL);
Christopher Wiley27b47232012-11-02 13:13:00 -0700986 manager()->RegisterService(service);
987 EXPECT_FALSE(service->connectable());
988 EXPECT_EQ(service.get(), manager()->GetService(args, &error).get());
989 EXPECT_TRUE(error.IsSuccess());
990 EXPECT_TRUE(service->connectable());
991}
992
Paul Stewart3c504012013-01-17 17:49:58 -0800993TEST_F(WiFiServiceTest, ConfigurePassphrase) {
994 EXPECT_EQ(Error::kNotSupported,
995 TestConfigurePassphrase(flimflam::kSecurityNone, ""));
996 EXPECT_EQ(Error::kNotSupported,
997 TestConfigurePassphrase(flimflam::kSecurityNone, "foo"));
998 EXPECT_EQ(Error::kSuccess,
999 TestConfigurePassphrase(flimflam::kSecurityWep, NULL));
1000 EXPECT_EQ(Error::kInvalidPassphrase,
1001 TestConfigurePassphrase(flimflam::kSecurityWep, ""));
1002 EXPECT_EQ(Error::kInvalidPassphrase,
1003 TestConfigurePassphrase(flimflam::kSecurityWep, "abcd"));
1004 EXPECT_EQ(Error::kSuccess,
1005 TestConfigurePassphrase(flimflam::kSecurityWep, "abcde"));
1006 EXPECT_EQ(Error::kSuccess,
1007 TestConfigurePassphrase(flimflam::kSecurityWep, "abcdefghijklm"));
1008 EXPECT_EQ(Error::kSuccess,
1009 TestConfigurePassphrase(flimflam::kSecurityWep, "0:abcdefghijklm"));
1010 EXPECT_EQ(Error::kSuccess,
1011 TestConfigurePassphrase(flimflam::kSecurityWep, "0102030405"));
1012 EXPECT_EQ(Error::kInvalidPassphrase,
1013 TestConfigurePassphrase(flimflam::kSecurityWep, "0x0102030405"));
1014 EXPECT_EQ(Error::kInvalidPassphrase,
1015 TestConfigurePassphrase(flimflam::kSecurityWep, "O102030405"));
1016 EXPECT_EQ(Error::kInvalidPassphrase,
1017 TestConfigurePassphrase(flimflam::kSecurityWep, "1:O102030405"));
1018 EXPECT_EQ(Error::kInvalidPassphrase,
1019 TestConfigurePassphrase(flimflam::kSecurityWep, "1:0xO102030405"));
1020 EXPECT_EQ(Error::kInvalidPassphrase,
1021 TestConfigurePassphrase(flimflam::kSecurityWep, "0xO102030405"));
1022 EXPECT_EQ(Error::kSuccess,
1023 TestConfigurePassphrase(flimflam::kSecurityWep,
1024 "0102030405060708090a0b0c0d"));
1025 EXPECT_EQ(Error::kSuccess,
1026 TestConfigurePassphrase(flimflam::kSecurityWep,
1027 "0102030405060708090A0B0C0D"));
1028 EXPECT_EQ(Error::kSuccess,
1029 TestConfigurePassphrase(flimflam::kSecurityWep,
1030 "0:0102030405060708090a0b0c0d"));
1031 EXPECT_EQ(Error::kSuccess,
1032 TestConfigurePassphrase(flimflam::kSecurityWep,
1033 "0:0x0102030405060708090a0b0c0d"));
1034 EXPECT_EQ(Error::kSuccess,
1035 TestConfigurePassphrase(flimflam::kSecurityWpa, NULL));
1036 EXPECT_EQ(Error::kSuccess,
1037 TestConfigurePassphrase(flimflam::kSecurityWpa, "secure password"));
1038 EXPECT_EQ(Error::kInvalidPassphrase,
1039 TestConfigurePassphrase(flimflam::kSecurityWpa, ""));
1040 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1041 flimflam::kSecurityWpa,
1042 string(IEEE_80211::kWPAAsciiMinLen, 'Z').c_str()));
1043 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1044 flimflam::kSecurityWpa,
1045 string(IEEE_80211::kWPAAsciiMaxLen, 'Z').c_str()));
1046 // subtle: invalid length for hex key, but valid as ascii passphrase
1047 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1048 flimflam::kSecurityWpa,
1049 string(IEEE_80211::kWPAHexLen-1, '1').c_str()));
1050 EXPECT_EQ(Error::kSuccess, TestConfigurePassphrase(
1051 flimflam::kSecurityWpa,
1052 string(IEEE_80211::kWPAHexLen, '1').c_str()));
1053 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1054 flimflam::kSecurityWpa,
1055 string(IEEE_80211::kWPAAsciiMinLen-1, 'Z').c_str()));
1056 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1057 flimflam::kSecurityWpa,
1058 string(IEEE_80211::kWPAAsciiMaxLen+1, 'Z').c_str()));
1059 EXPECT_EQ(Error::kInvalidPassphrase, TestConfigurePassphrase(
1060 flimflam::kSecurityWpa,
1061 string(IEEE_80211::kWPAHexLen+1, '1').c_str()));
1062}
1063
1064TEST_F(WiFiServiceTest, ConfigureRedundantProperties) {
1065 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
1066 KeyValueStore args;
1067 args.SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
1068 args.SetString(flimflam::kSSIDProperty, simple_ssid_string());
1069 args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityNone);
1070 const string kGUID = "aguid";
1071 args.SetString(flimflam::kGuidProperty, kGUID);
1072
1073 EXPECT_EQ("", service->guid());
1074 Error error;
1075 service->Configure(args, &error);
1076 EXPECT_TRUE(error.IsSuccess());
1077 EXPECT_EQ(kGUID, service->guid());
1078}
1079
1080TEST_F(WiFiServiceTest, DisconnectWithWiFi) {
1081 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
1082 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
1083 Error error;
1084 service->Disconnect(&error);
1085}
1086
1087TEST_F(WiFiServiceTest, DisconnectWithoutWiFi) {
1088 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1089 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
1090 Error error;
1091 service->Disconnect(&error);
1092 EXPECT_EQ(Error::kOperationFailed, error.type());
1093}
1094
1095TEST_F(WiFiServiceTest, DisconnectWithoutWiFiWhileAssociating) {
1096 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1097 EXPECT_CALL(*wifi(), DisconnectFrom(_)).Times(0);
1098 service->SetState(Service::kStateAssociating);
1099 ScopedMockLog log;
1100 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1101 EXPECT_CALL(log, Log(logging::LOG_ERROR, _,
1102 HasSubstr("WiFi endpoints do not (yet) exist.")));
1103 Error error;
1104 service->Disconnect(&error);
1105 EXPECT_EQ(Error::kOperationFailed, error.type());
1106}
1107
Paul Stewart835934a2012-12-06 19:27:09 -08001108TEST_F(WiFiServiceTest, UnloadAndClearCacheWEP) {
Paul Stewart3c504012013-01-17 17:49:58 -08001109 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityWep);
Paul Stewart835934a2012-12-06 19:27:09 -08001110 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
1111 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -08001112 service->Unload();
1113}
1114
1115TEST_F(WiFiServiceTest, UnloadAndClearCache8021x) {
Paul Stewart3c504012013-01-17 17:49:58 -08001116 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurity8021x);
Paul Stewart835934a2012-12-06 19:27:09 -08001117 EXPECT_CALL(*wifi(), ClearCachedCredentials(service.get())).Times(1);
1118 EXPECT_CALL(*wifi(), DisconnectFrom(service.get())).Times(1);
Paul Stewart66c86002012-01-30 18:00:52 -08001119 service->Unload();
1120}
1121
Paul Stewart0756db92012-01-27 08:34:47 -08001122TEST_F(WiFiServiceTest, ParseStorageIdentifierNone) {
Paul Stewart3c504012013-01-17 17:49:58 -08001123 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
Paul Stewarta41e38d2011-11-11 07:47:29 -08001124 const string storage_id = service->GetStorageIdentifier();
1125 string address;
1126 string mode;
1127 string security;
1128 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1129 &security));
Paul Stewart3c504012013-01-17 17:49:58 -08001130 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewarta41e38d2011-11-11 07:47:29 -08001131 EXPECT_EQ(flimflam::kModeManaged, mode);
1132 EXPECT_EQ(flimflam::kSecurityNone, security);
1133}
1134
Paul Stewart0756db92012-01-27 08:34:47 -08001135TEST_F(WiFiServiceTest, ParseStorageIdentifier8021x) {
1136 // Do a separate test for 802.1x, since kSecurity8021x contains a "_",
1137 // which needs to be dealt with specially in the parser.
Paul Stewart3c504012013-01-17 17:49:58 -08001138 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
Paul Stewart0756db92012-01-27 08:34:47 -08001139 const string storage_id = service->GetStorageIdentifier();
1140 string address;
1141 string mode;
1142 string security;
1143 EXPECT_TRUE(service->ParseStorageIdentifier(storage_id, &address, &mode,
1144 &security));
Paul Stewart3c504012013-01-17 17:49:58 -08001145 EXPECT_EQ(StringToLowerASCII(GetAnyDeviceAddress()), address);
Paul Stewart0756db92012-01-27 08:34:47 -08001146 EXPECT_EQ(flimflam::kModeManaged, mode);
1147 EXPECT_EQ(flimflam::kSecurity8021x, security);
1148}
1149
Paul Stewart85aea152013-01-22 09:31:56 -08001150TEST_F(WiFiServiceFixupStorageTest, FixedEntries) {
1151 const string kNonWiFiId = "vpn_foo";
1152 const string kUnparsableWiFiId = "wifi_foo";
1153
1154 AddGroup(kNonWiFiId);
1155 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001156 AddServiceEntry(true, true, true, true);
1157 AddServiceEntry(false, false, false, false);
1158 AddServiceEntry(true, true, true, true);
1159 AddServiceEntry(false, false, false, false);
Paul Stewart85aea152013-01-22 09:31:56 -08001160 EXPECT_TRUE(FixupServiceEntries());
1161}
1162
1163TEST_F(WiFiServiceFixupStorageTest, NoFixedEntries) {
1164 const string kNonWiFiId = "vpn_foo";
1165 const string kUnparsableWiFiId = "wifi_foo";
1166
1167 AddGroup(kNonWiFiId);
1168 AddGroup(kUnparsableWiFiId);
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001169 AddServiceEntry(true, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001170 EXPECT_FALSE(FixupServiceEntries());
1171}
1172
1173TEST_F(WiFiServiceFixupStorageTest, MissingTypeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001174 AddServiceEntry(false, true, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001175 EXPECT_TRUE(FixupServiceEntries());
1176}
1177
1178TEST_F(WiFiServiceFixupStorageTest, MissingModeProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001179 AddServiceEntry(true, false, true, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001180 EXPECT_TRUE(FixupServiceEntries());
1181}
1182
1183TEST_F(WiFiServiceFixupStorageTest, MissingSecurityProperty) {
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001184 AddServiceEntry(true, true, false, true);
Paul Stewart85aea152013-01-22 09:31:56 -08001185 EXPECT_TRUE(FixupServiceEntries());
1186}
1187
Paul Stewart71a4d3b2013-01-18 18:12:56 -08001188TEST_F(WiFiServiceFixupStorageTest, MissingSecurityClassProperty) {
1189 AddServiceEntry(true, true, true, false);
1190 EXPECT_TRUE(FixupServiceEntries());
1191}
Paul Stewart85aea152013-01-22 09:31:56 -08001192
mukesh agrawal29c13a12011-11-24 00:09:19 +00001193TEST_F(WiFiServiceTest, Connectable) {
1194 // Open network should be connectable.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001195 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, NULL, false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001196
1197 // Open network should remain connectable if we try to set a password on it.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001198 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityNone, "abcde", false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001199
1200 // WEP network with passphrase set should be connectable.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001201 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, "abcde", false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001202
1203 // WEP network without passphrase set should NOT be connectable.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001204 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, NULL, false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001205
1206 // A bad passphrase should not make a WEP network connectable.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001207 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWep, "a", false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001208
1209 // Similar to WEP, for WPA.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001210 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWpa, "abcdefgh", false));
1211 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, NULL, false));
1212 EXPECT_FALSE(CheckConnectable(flimflam::kSecurityWpa, "a", false));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001213
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001214 // 802.1x without connectable EAP credentials should NOT be connectable.
1215 EXPECT_FALSE(CheckConnectable(flimflam::kSecurity8021x, NULL, false));
Gaurav Shah10109f22011-11-11 20:16:22 -08001216
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001217 // 802.1x with connectable EAP credentials should be connectable.
1218 EXPECT_TRUE(CheckConnectable(flimflam::kSecurity8021x, NULL, true));
Gaurav Shah10109f22011-11-11 20:16:22 -08001219
Gaurav Shah29d68882012-01-30 19:06:42 -08001220 // Dynamic WEP + 802.1X should be connectable under the same conditions.
Paul Stewartc43cbbe2013-04-11 06:29:30 -07001221 EXPECT_TRUE(CheckConnectable(flimflam::kSecurityWep, NULL, true));
mukesh agrawal29c13a12011-11-24 00:09:19 +00001222}
1223
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001224TEST_F(WiFiServiceTest, IsAutoConnectable) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001225 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001226 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001227 EXPECT_CALL(*wifi(), IsIdle())
1228 .WillRepeatedly(Return(true));
1229 EXPECT_FALSE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001230 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1231 EXPECT_STREQ(WiFiService::kAutoConnNoEndpoint, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001232
mukesh agrawalbf14e942012-03-02 14:36:34 -08001233 reason = "";
mukesh agrawal43970a22013-02-15 16:00:07 -08001234 WiFiEndpointRefPtr endpoint =
1235 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001236 service->AddEndpoint(endpoint);
1237 EXPECT_CALL(*wifi(), IsIdle())
1238 .WillRepeatedly(Return(true));
1239 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001240 EXPECT_TRUE(service->IsAutoConnectable(&reason));
1241 EXPECT_STREQ("", reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001242
1243 // WiFi only supports connecting to one Service at a time. So, to
1244 // avoid disrupting connectivity, we only allow auto-connection to
1245 // a WiFiService when the corresponding WiFi is idle.
1246 EXPECT_CALL(*wifi(), IsIdle())
1247 .WillRepeatedly(Return(false));
1248 EXPECT_TRUE(service->HasEndpoints());
mukesh agrawalbf14e942012-03-02 14:36:34 -08001249 EXPECT_FALSE(service->IsAutoConnectable(&reason));
1250 EXPECT_STREQ(WiFiService::kAutoConnBusy, reason);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001251}
1252
1253TEST_F(WiFiServiceTest, AutoConnect) {
mukesh agrawalbf14e942012-03-02 14:36:34 -08001254 const char *reason;
Paul Stewart3c504012013-01-17 17:49:58 -08001255 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
mukesh agrawalbf14e942012-03-02 14:36:34 -08001256 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001257 EXPECT_CALL(*wifi(), ConnectTo(_, _))
1258 .Times(0);
1259 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001260 dispatcher()->DispatchPendingEvents();
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001261
mukesh agrawal43970a22013-02-15 16:00:07 -08001262 WiFiEndpointRefPtr endpoint =
1263 MakeOpenEndpoint("a", "00:00:00:00:00:01", 0, 0);
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001264 service->AddEndpoint(endpoint);
1265 EXPECT_CALL(*wifi(), IsIdle())
1266 .WillRepeatedly(Return(true));
mukesh agrawalbf14e942012-03-02 14:36:34 -08001267 EXPECT_TRUE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001268 EXPECT_CALL(*wifi(), ConnectTo(_, _));
1269 service->AutoConnect();
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001270 dispatcher()->DispatchPendingEvents();
mukesh agrawaladb68482012-01-17 16:31:51 -08001271
1272 Error error;
Christopher Wileyabd3b502012-09-26 13:08:52 -07001273 service->UserInitiatedDisconnect(&error);
Eric Shienbrood3e20a232012-02-16 11:35:56 -05001274 dispatcher()->DispatchPendingEvents();
mukesh agrawalbf14e942012-03-02 14:36:34 -08001275 EXPECT_FALSE(service->IsAutoConnectable(&reason));
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001276}
1277
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001278TEST_F(WiFiServiceTest, ClearWriteOnlyDerivedProperty) {
Paul Stewart3c504012013-01-17 17:49:58 -08001279 WiFiServiceRefPtr wifi_service = MakeSimpleService(flimflam::kSecurityWep);
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001280
1281 EXPECT_EQ("", wifi_service->passphrase_);
1282
1283 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -08001284 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawal8abd2f62012-01-30 14:56:14 -08001285 wifi_service->mutable_store(),
1286 flimflam::kPassphraseProperty,
1287 DBusAdaptor::StringToVariant("0:abcde"),
1288 &error));
1289 EXPECT_EQ("0:abcde", wifi_service->passphrase_);
1290
1291 EXPECT_TRUE(DBusAdaptor::ClearProperty(wifi_service->mutable_store(),
1292 flimflam::kPassphraseProperty,
1293 &error));
1294 EXPECT_EQ("", wifi_service->passphrase_);
1295}
1296
mukesh agrawale1d90e92012-02-15 17:36:08 -08001297TEST_F(WiFiServiceTest, SignalToStrength) {
1298 // Verify that our mapping is sane, in the sense that it preserves ordering.
1299 // We break the test into two domains, because we assume that positive
1300 // values aren't actually in dBm.
1301 for (int16 i = std::numeric_limits<int16>::min(); i < 0; ++i) {
1302 int16 current_mapped = WiFiService::SignalToStrength(i);
1303 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1304 EXPECT_LE(current_mapped, next_mapped)
1305 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001306 EXPECT_GE(current_mapped, Service::kStrengthMin);
1307 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001308 }
1309 for (int16 i = 1; i < std::numeric_limits<int16>::max(); ++i) {
1310 int16 current_mapped = WiFiService::SignalToStrength(i);
1311 int16 next_mapped = WiFiService::SignalToStrength(i+1);
1312 EXPECT_LE(current_mapped, next_mapped)
1313 << "(original values " << i << " " << i+1 << ")";
mukesh agrawal8f3f7752012-02-17 19:42:09 -08001314 EXPECT_GE(current_mapped, Service::kStrengthMin);
1315 EXPECT_LE(current_mapped, Service::kStrengthMax);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001316 }
1317}
1318
1319TEST_F(WiFiServiceUpdateFromEndpointsTest, Strengths) {
1320 // If the chosen signal values don't map to distinct strength
1321 // values, then we can't expect our other tests to pass. So verify
1322 // their distinctness.
1323 EXPECT_TRUE(kOkEndpointStrength != kBadEndpointStrength);
1324 EXPECT_TRUE(kOkEndpointStrength != kGoodEndpointStrength);
1325 EXPECT_TRUE(kGoodEndpointStrength != kBadEndpointStrength);
1326}
1327
1328TEST_F(WiFiServiceUpdateFromEndpointsTest, Floating) {
1329 // Initial endpoint updates values.
1330 EXPECT_CALL(adaptor, EmitUint16Changed(
1331 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001332 EXPECT_CALL(adaptor, EmitStringChanged(
1333 flimflam::kWifiBSsid, kOkEndpointBssId));
1334 EXPECT_CALL(adaptor, EmitUint8Changed(
mukesh agrawale1d90e92012-02-15 17:36:08 -08001335 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
mukesh agrawalf6b32092013-04-10 15:49:55 -07001336 EXPECT_CALL(adaptor, EmitUint16Changed(
1337 flimflam::kWifiPhyMode, Metrics::kWiFiNetworkPhyMode11b));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001338 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001339 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001340 Mock::VerifyAndClearExpectations(&adaptor);
1341
1342 // Endpoint with stronger signal updates values.
1343 EXPECT_CALL(adaptor, EmitUint16Changed(
1344 flimflam::kWifiFrequency, kGoodEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001345 EXPECT_CALL(adaptor, EmitStringChanged(
1346 flimflam::kWifiBSsid, kGoodEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001347 EXPECT_CALL(adaptor, EmitUint8Changed(
1348 flimflam::kSignalStrengthProperty, kGoodEndpointStrength));
mukesh agrawalf6b32092013-04-10 15:49:55 -07001349 // However, both endpoints are 11b.
1350 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001351 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001352 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001353 Mock::VerifyAndClearExpectations(&adaptor);
1354
1355 // Endpoint with lower signal does not change values.
1356 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001357 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001358 EXPECT_CALL(adaptor,
1359 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
mukesh agrawalf6b32092013-04-10 15:49:55 -07001360 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001361 service->AddEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001362 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001363 Mock::VerifyAndClearExpectations(&adaptor);
1364
1365 // Removing non-optimal endpoint does not change values.
1366 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001367 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001368 EXPECT_CALL(adaptor,
1369 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
mukesh agrawalf6b32092013-04-10 15:49:55 -07001370 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001371 service->RemoveEndpoint(bad_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001372 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001373 Mock::VerifyAndClearExpectations(&adaptor);
1374
1375 // Removing optimal endpoint updates values.
1376 EXPECT_CALL(adaptor, EmitUint16Changed(
1377 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001378 EXPECT_CALL(adaptor, EmitStringChanged(
1379 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001380 EXPECT_CALL(adaptor, EmitUint8Changed(
1381 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
mukesh agrawalf6b32092013-04-10 15:49:55 -07001382 // However, both endpoints are 11b.
1383 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiPhyMode, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001384 service->RemoveEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001385 EXPECT_EQ(1, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001386 Mock::VerifyAndClearExpectations(&adaptor);
1387
1388 // Removing last endpoint updates values (and doesn't crash).
1389 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001390 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001391 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
mukesh agrawalf6b32092013-04-10 15:49:55 -07001392 EXPECT_CALL(adaptor, EmitUint16Changed(
1393 flimflam::kWifiPhyMode, Metrics::kWiFiNetworkPhyModeUndef));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001394 service->RemoveEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001395 EXPECT_EQ(0, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001396 Mock::VerifyAndClearExpectations(&adaptor);
1397}
1398
1399TEST_F(WiFiServiceUpdateFromEndpointsTest, Connected) {
1400 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001401 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001402 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1403 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1404 service->AddEndpoint(bad_endpoint);
1405 service->AddEndpoint(ok_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001406 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001407 Mock::VerifyAndClearExpectations(&adaptor);
1408
1409 // Setting current endpoint forces adoption of its values, even if it
1410 // doesn't have the highest signal.
1411 EXPECT_CALL(adaptor, EmitUint16Changed(
1412 flimflam::kWifiFrequency, kBadEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001413 EXPECT_CALL(adaptor, EmitStringChanged(
1414 flimflam::kWifiBSsid, kBadEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001415 EXPECT_CALL(adaptor, EmitUint8Changed(
1416 flimflam::kSignalStrengthProperty, kBadEndpointStrength));
1417 service->NotifyCurrentEndpoint(bad_endpoint);
1418 Mock::VerifyAndClearExpectations(&adaptor);
1419
1420 // Adding a better endpoint doesn't matter, when current endpoint is set.
1421 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001422 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001423 EXPECT_CALL(adaptor,
1424 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1425 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001426 EXPECT_EQ(3, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001427 Mock::VerifyAndClearExpectations(&adaptor);
1428
1429 // Removing a better endpoint doesn't matter, when current endpoint is set.
1430 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001431 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001432 EXPECT_CALL(adaptor,
1433 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1434 service->RemoveEndpoint(good_endpoint);
1435 Mock::VerifyAndClearExpectations(&adaptor);
1436
1437 // Removing the current endpoint is safe and sane.
1438 EXPECT_CALL(adaptor, EmitUint16Changed(
1439 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001440 EXPECT_CALL(adaptor, EmitStringChanged(
1441 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001442 EXPECT_CALL(adaptor, EmitUint8Changed(
1443 flimflam::kSignalStrengthProperty, kOkEndpointStrength));
1444 service->RemoveEndpoint(bad_endpoint);
1445 Mock::VerifyAndClearExpectations(&adaptor);
1446
1447 // Clearing the current endpoint (without removing it) is also safe and sane.
1448 service->NotifyCurrentEndpoint(ok_endpoint);
1449 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001450 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001451 EXPECT_CALL(adaptor,
1452 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1453 service->NotifyCurrentEndpoint(NULL);
1454 Mock::VerifyAndClearExpectations(&adaptor);
1455}
1456
1457TEST_F(WiFiServiceUpdateFromEndpointsTest, EndpointModified) {
1458 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
mukesh agrawal923f14f2012-06-04 16:46:08 -07001459 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001460 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1461 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1462 service->AddEndpoint(ok_endpoint);
1463 service->AddEndpoint(good_endpoint);
Darin Petkov4a66cc52012-06-15 10:08:29 +02001464 EXPECT_EQ(2, service->GetEndpointCount());
mukesh agrawale1d90e92012-02-15 17:36:08 -08001465 Mock::VerifyAndClearExpectations(&adaptor);
1466
1467 // Updating sub-optimal Endpoint doesn't update Service.
1468 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001469 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001470 EXPECT_CALL(adaptor,
1471 EmitUint8Changed(flimflam::kSignalStrengthProperty, _)).Times(0);
1472 ok_endpoint->signal_strength_ = (kOkEndpointSignal + kGoodEndpointSignal) / 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001473 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001474 Mock::VerifyAndClearExpectations(&adaptor);
1475
1476 // Updating optimal Endpoint updates appropriate Service property.
1477 EXPECT_CALL(adaptor, EmitUint16Changed(flimflam::kWifiFrequency, _)).Times(0);
mukesh agrawal923f14f2012-06-04 16:46:08 -07001478 EXPECT_CALL(adaptor, EmitStringChanged(flimflam::kWifiBSsid, _)).Times(0);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001479 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1480 good_endpoint->signal_strength_ = kGoodEndpointSignal + 1;
Paul Stewart3c504012013-01-17 17:49:58 -08001481 service->NotifyEndpointUpdated(good_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001482 Mock::VerifyAndClearExpectations(&adaptor);
1483
1484 // Change in optimal Endpoint updates Service properties.
1485 EXPECT_CALL(adaptor, EmitUint16Changed(
1486 flimflam::kWifiFrequency, kOkEndpointFrequency));
mukesh agrawal923f14f2012-06-04 16:46:08 -07001487 EXPECT_CALL(adaptor, EmitStringChanged(
1488 flimflam::kWifiBSsid, kOkEndpointBssId));
mukesh agrawale1d90e92012-02-15 17:36:08 -08001489 EXPECT_CALL(adaptor, EmitUint8Changed(flimflam::kSignalStrengthProperty, _));
1490 ok_endpoint->signal_strength_ = kGoodEndpointSignal + 2;
Paul Stewart3c504012013-01-17 17:49:58 -08001491 service->NotifyEndpointUpdated(ok_endpoint);
mukesh agrawale1d90e92012-02-15 17:36:08 -08001492 Mock::VerifyAndClearExpectations(&adaptor);
1493}
1494
Paul Stewarta5e7d5f2013-01-09 18:06:15 -08001495TEST_F(WiFiServiceUpdateFromEndpointsTest, Ieee80211w) {
1496 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1497 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1498 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1499 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1500 service->AddEndpoint(ok_endpoint);
1501 EXPECT_FALSE(service->ieee80211w_required());
1502 good_endpoint->ieee80211w_required_ = true;
1503 service->AddEndpoint(good_endpoint);
1504 EXPECT_TRUE(service->ieee80211w_required());
1505 service->RemoveEndpoint(good_endpoint);
1506 EXPECT_TRUE(service->ieee80211w_required());
1507}
1508
mukesh agrawalf6b32092013-04-10 15:49:55 -07001509TEST_F(WiFiServiceUpdateFromEndpointsTest, PhysicalMode) {
1510 EXPECT_CALL(adaptor, EmitUint16Changed(_, _)).Times(AnyNumber());
1511 EXPECT_CALL(adaptor, EmitStringChanged(_, _)).Times(AnyNumber());
1512 EXPECT_CALL(adaptor, EmitUint8Changed(_, _)).Times(AnyNumber());
1513 EXPECT_CALL(adaptor, EmitBoolChanged(_, _)).Times(AnyNumber());
1514
1515 // No endpoints -> undef.
1516 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1517
1518 // Endpoint has unknown physical mode -> undef.
1519 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyModeUndef;
1520 service->AddEndpoint(ok_endpoint);
1521 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1522
1523 // New endpoint with 802.11a -> 802.11a.
1524 good_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11a;
1525 service->AddEndpoint(good_endpoint);
1526 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11a, service->physical_mode());
1527
1528 // Remove 802.11a endpoint -> undef.
1529 service->RemoveEndpoint(good_endpoint);
1530 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1531
1532 // Change endpoint -> take endpoint's new value.
1533 ok_endpoint->physical_mode_ = Metrics::kWiFiNetworkPhyMode11n;
1534 service->NotifyEndpointUpdated(ok_endpoint);
1535 EXPECT_EQ(Metrics::kWiFiNetworkPhyMode11n, service->physical_mode());
1536
1537 // No endpoints -> undef.
1538 service->RemoveEndpoint(ok_endpoint);
1539 EXPECT_EQ(Metrics::kWiFiNetworkPhyModeUndef, service->physical_mode());
1540}
1541
Paul Stewart8653f462013-02-06 12:21:05 -08001542TEST_F(WiFiServiceUpdateFromEndpointsTest, WarningOnDisconnect) {
1543 service->AddEndpoint(ok_endpoint);
1544 service->SetState(Service::kStateAssociating);
1545 ScopedMockLog log;
1546 EXPECT_CALL(log, Log(_, _, _)).Times(AnyNumber());
1547 EXPECT_CALL(log, Log(logging::LOG_WARNING, _,
1548 EndsWith("disconnect due to no remaining endpoints.")));
1549 service->RemoveEndpoint(ok_endpoint);
1550}
1551
Paul Stewart6df20bd2013-03-13 19:31:25 -07001552TEST_F(WiFiServiceTest, SecurityFromCurrentEndpoint) {
1553 WiFiServiceRefPtr service(MakeSimpleService(flimflam::kSecurityPsk));
1554 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1555 WiFiEndpoint *endpoint = MakeOpenEndpoint(
1556 simple_ssid_string(), "00:00:00:00:00:00", 0, 0);
1557 service->AddEndpoint(endpoint);
1558 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1559 service->NotifyCurrentEndpoint(endpoint);
1560 EXPECT_EQ(flimflam::kSecurityNone, service->GetSecurity(NULL));
1561 service->NotifyCurrentEndpoint(NULL);
1562 EXPECT_EQ(flimflam::kSecurityPsk, service->GetSecurity(NULL));
1563}
1564
mukesh agrawal43970a22013-02-15 16:00:07 -08001565TEST_F(WiFiServiceTest, UpdateSecurity) {
1566 // Cleartext and pre-shared-key crypto.
1567 {
1568 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityNone);
1569 EXPECT_EQ(Service::kCryptoNone, service->crypto_algorithm());
1570 EXPECT_FALSE(service->key_rotation());
1571 EXPECT_FALSE(service->endpoint_auth());
1572 }
1573 {
1574 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1575 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1576 EXPECT_FALSE(service->key_rotation());
1577 EXPECT_FALSE(service->endpoint_auth());
1578 }
1579 {
1580 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityPsk);
1581 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1582 EXPECT_TRUE(service->key_rotation());
1583 EXPECT_FALSE(service->endpoint_auth());
1584 }
1585 {
1586 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWpa);
1587 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1588 EXPECT_TRUE(service->key_rotation());
1589 EXPECT_FALSE(service->endpoint_auth());
1590 }
1591 {
1592 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityRsn);
1593 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1594 EXPECT_TRUE(service->key_rotation());
1595 EXPECT_FALSE(service->endpoint_auth());
1596 }
1597
1598 // Crypto with 802.1X key management.
1599 {
1600 // WEP
1601 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurityWep);
1602 service->SetEAPKeyManagement("IEEE8021X");
1603 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1604 EXPECT_TRUE(service->key_rotation());
1605 EXPECT_TRUE(service->endpoint_auth());
1606 }
1607 {
1608 // WPA
1609 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1610 WiFiEndpointRefPtr endpoint =
1611 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false);
1612 service->AddEndpoint(endpoint);
1613 EXPECT_EQ(Service::kCryptoRc4, service->crypto_algorithm());
1614 EXPECT_TRUE(service->key_rotation());
1615 EXPECT_TRUE(service->endpoint_auth());
1616 }
1617 {
1618 // RSN
1619 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1620 WiFiEndpointRefPtr endpoint =
1621 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true);
1622 service->AddEndpoint(endpoint);
1623 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1624 EXPECT_TRUE(service->key_rotation());
1625 EXPECT_TRUE(service->endpoint_auth());
1626 }
1627 {
1628 // AP supports both WPA and RSN.
1629 WiFiServiceRefPtr service = MakeSimpleService(flimflam::kSecurity8021x);
1630 WiFiEndpointRefPtr endpoint =
1631 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true);
1632 service->AddEndpoint(endpoint);
1633 EXPECT_EQ(Service::kCryptoAes, service->crypto_algorithm());
1634 EXPECT_TRUE(service->key_rotation());
1635 EXPECT_TRUE(service->endpoint_auth());
1636 }
1637}
1638
1639TEST_F(WiFiServiceTest, ComputeCipher8021x) {
1640 // No endpoints.
1641 {
1642 const set<WiFiEndpointConstRefPtr> endpoints;
1643 EXPECT_EQ(Service::kCryptoNone,
1644 WiFiService::ComputeCipher8021x(endpoints));
1645 }
1646
1647 // Single endpoint, various configs.
1648 {
1649 set<WiFiEndpointConstRefPtr> endpoints;
1650 endpoints.insert(
1651 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1652 EXPECT_EQ(Service::kCryptoNone,
1653 WiFiService::ComputeCipher8021x(endpoints));
1654 }
1655 {
1656 set<WiFiEndpointConstRefPtr> endpoints;
1657 endpoints.insert(
1658 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1659 EXPECT_EQ(Service::kCryptoRc4,
1660 WiFiService::ComputeCipher8021x(endpoints));
1661 }
1662 {
1663 set<WiFiEndpointConstRefPtr> endpoints;
1664 endpoints.insert(
1665 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1666 EXPECT_EQ(Service::kCryptoAes,
1667 WiFiService::ComputeCipher8021x(endpoints));
1668 }
1669 {
1670 set<WiFiEndpointConstRefPtr> endpoints;
1671 endpoints.insert(
1672 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1673 EXPECT_EQ(Service::kCryptoAes,
1674 WiFiService::ComputeCipher8021x(endpoints));
1675 }
1676
1677 // Multiple endpoints.
1678 {
1679 set<WiFiEndpointConstRefPtr> endpoints;
1680 endpoints.insert(
1681 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1682 endpoints.insert(
1683 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, false));
1684 EXPECT_EQ(Service::kCryptoNone,
1685 WiFiService::ComputeCipher8021x(endpoints));
1686 }
1687 {
1688 set<WiFiEndpointConstRefPtr> endpoints;
1689 endpoints.insert(
1690 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, false));
1691 endpoints.insert(
1692 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1693 EXPECT_EQ(Service::kCryptoNone,
1694 WiFiService::ComputeCipher8021x(endpoints));
1695 }
1696 {
1697 set<WiFiEndpointConstRefPtr> endpoints;
1698 endpoints.insert(
1699 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1700 endpoints.insert(
1701 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, false));
1702 EXPECT_EQ(Service::kCryptoRc4,
1703 WiFiService::ComputeCipher8021x(endpoints));
1704 }
1705 {
1706 set<WiFiEndpointConstRefPtr> endpoints;
1707 endpoints.insert(
1708 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, false));
1709 endpoints.insert(
1710 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1711 EXPECT_EQ(Service::kCryptoRc4,
1712 WiFiService::ComputeCipher8021x(endpoints));
1713 }
1714 {
1715 set<WiFiEndpointConstRefPtr> endpoints;
1716 endpoints.insert(
1717 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, false, true));
1718 endpoints.insert(
1719 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, false, true));
1720 EXPECT_EQ(Service::kCryptoAes,
1721 WiFiService::ComputeCipher8021x(endpoints));
1722 }
1723 {
1724 set<WiFiEndpointConstRefPtr> endpoints;
1725 endpoints.insert(
1726 MakeEndpoint("a", "00:00:00:00:00:01", 0, 0, true, true));
1727 endpoints.insert(
1728 MakeEndpoint("a", "00:00:00:00:00:02", 0, 0, true, true));
1729 EXPECT_EQ(Service::kCryptoAes,
1730 WiFiService::ComputeCipher8021x(endpoints));
1731 }
1732}
1733
Albert Chaulk0e1cdea2013-02-27 15:32:55 -08001734TEST_F(WiFiServiceTest, Unload) {
1735 WiFiServiceRefPtr service = MakeServiceWithWiFi(flimflam::kSecurityNone);
1736 EXPECT_CALL(*wifi(), DestroyIPConfigLease(service->GetStorageIdentifier())).
1737 Times(1);
1738 service->Unload();
1739}
1740
mukesh agrawalcbfb34e2013-04-17 19:33:25 -07001741TEST_F(WiFiServiceTest, PropertyChanges) {
1742 WiFiServiceRefPtr service = MakeServiceWithMockManager();
1743 ServiceMockAdaptor *adaptor = GetAdaptor(service);
1744 TestCommonPropertyChanges(service, adaptor);
1745 TestAutoConnectPropertyChange(service, adaptor);
1746
1747 EXPECT_CALL(*adaptor,
1748 EmitRpcIdentifierChanged(flimflam::kDeviceProperty, _));
1749 SetWiFi(service, wifi());
1750 Mock::VerifyAndClearExpectations(adaptor);
1751
1752 EXPECT_CALL(*adaptor,
1753 EmitRpcIdentifierChanged(flimflam::kDeviceProperty, _));
1754 service->ResetWiFi();
1755 Mock::VerifyAndClearExpectations(adaptor);
1756}
Albert Chaulk0e1cdea2013-02-27 15:32:55 -08001757
mukesh agrawalbebf1b82013-04-23 15:06:33 -07001758// Custom property setters should return false, and make no changes, if
1759// the new value is the same as the old value.
1760TEST_F(WiFiServiceTest, CustomSetterNoopChange) {
1761 WiFiServiceRefPtr service = MakeServiceWithMockManager();
1762 TestCustomSetterNoopChange(service, mock_manager());
1763}
1764
Chris Masone34af2182011-08-22 11:59:36 -07001765} // namespace shill