blob: 64aaf13428d6e5a52cec9caa94d7747146afe4e0 [file] [log] [blame]
Paul Stewart21f2aae2013-01-17 17:10:08 -08001// Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2// 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_provider.h"
6
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07007#include <map>
8#include <set>
9#include <string>
10#include <vector>
11
12#include <base/format_macros.h>
Paul Stewart3c504012013-01-17 17:49:58 -080013#include <base/string_number_conversions.h>
14#include <base/string_util.h>
15#include <base/stringprintf.h>
16#include <chromeos/dbus/service_constants.h>
Paul Stewart21f2aae2013-01-17 17:10:08 -080017#include <gtest/gtest.h>
18
Paul Stewart3c504012013-01-17 17:49:58 -080019#include "shill/ieee80211.h"
20#include "shill/mock_event_dispatcher.h"
Paul Stewart21f2aae2013-01-17 17:10:08 -080021#include "shill/mock_manager.h"
22#include "shill/mock_metrics.h"
Paul Stewart3c504012013-01-17 17:49:58 -080023#include "shill/mock_profile.h"
24#include "shill/mock_store.h"
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070025#include "shill/mock_time.h"
Paul Stewart3c504012013-01-17 17:49:58 -080026#include "shill/mock_wifi_service.h"
Paul Stewart21f2aae2013-01-17 17:10:08 -080027#include "shill/nice_mock_control.h"
Paul Stewart3c504012013-01-17 17:49:58 -080028#include "shill/technology.h"
29#include "shill/wifi_endpoint.h"
30#include "shill/wpa_supplicant.h"
31
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070032using std::map;
Paul Stewart3c504012013-01-17 17:49:58 -080033using std::set;
34using std::string;
35using std::vector;
36using ::testing::_;
Wade Guthrie60a37062013-04-02 11:39:09 -070037using ::testing::ContainerEq;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070038using ::testing::Eq;
39using ::testing::Invoke;
Paul Stewart3c504012013-01-17 17:49:58 -080040using ::testing::Mock;
41using ::testing::NiceMock;
42using ::testing::Return;
43using ::testing::SetArgumentPointee;
44using ::testing::StrictMock;
Paul Stewart21f2aae2013-01-17 17:10:08 -080045
46namespace shill {
47
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070048namespace {
49
50const time_t kFirstWeek = 50;
51const char kIllegalDayProfile[] = "IllegalDay";
52const time_t kSecondsPerWeek = 60 * 60 * 24 * 7;
53const time_t kTestDays = 20;
54
55} // namespace
56
Paul Stewart21f2aae2013-01-17 17:10:08 -080057class WiFiProviderTest : public testing::Test {
58 public:
59 WiFiProviderTest()
Thieu Le6c1e3bb2013-02-06 15:20:35 -080060 : metrics_(NULL),
Paul Stewart3c504012013-01-17 17:49:58 -080061 manager_(&control_, &dispatcher_, &metrics_,
62 reinterpret_cast<GLib *>(NULL)),
63 provider_(&control_, &dispatcher_, &metrics_, &manager_),
Thieu Le5133b712013-02-19 14:47:21 -080064 profile_(
65 new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "")),
Wade Guthrie7c2d34e2013-05-09 14:02:20 -070066 storage_entry_index_(0) {
67 provider_.time_ = &time_;
68
69 string freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies,
70 0);
71 profile_frequency_data_[freq_string].push_back(
72 base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek)));
73 profile_frequency_data_[freq_string].push_back("5001:1");
74 profile_frequency_data_[freq_string].push_back("5002:2");
75
76 freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1);
77 profile_frequency_data_[freq_string].push_back(
78 base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 1));
79 // Overlap one entry with previous block.
80 profile_frequency_data_[freq_string].push_back("5001:1");
81 profile_frequency_data_[freq_string].push_back("6001:1");
82 profile_frequency_data_[freq_string].push_back("6002:2");
83
84 freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2);
85 profile_frequency_data_[freq_string].push_back(
86 base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 2));
87 profile_frequency_data_[freq_string].push_back("7001:1");
88 profile_frequency_data_[freq_string].push_back("7002:2");
89
90 profile_frequency_data_[kIllegalDayProfile].push_back("7001:1");
91 profile_frequency_data_[kIllegalDayProfile].push_back("7002:2");
92 }
Paul Stewart21f2aae2013-01-17 17:10:08 -080093
94 virtual ~WiFiProviderTest() {}
95
Paul Stewart3c504012013-01-17 17:49:58 -080096 virtual void SetUp() {
97 EXPECT_CALL(*profile_, GetConstStorage()).WillRepeatedly(Return(&storage_));
98 }
99
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700100 bool GetStringList(const std::string &/*group*/,
101 const std::string &key,
102 std::vector<std::string> *value) {
103 if (!value) {
104 return false;
105 }
106 if (ContainsKey(profile_frequency_data_, key)) {
107 *value = profile_frequency_data_[key];
108 return true;
109 }
110 return false;
111 }
112
113 bool GetIllegalDayStringList(const std::string &/*group*/,
114 const std::string &key,
115 std::vector<std::string> *value) {
116 if (!value) {
117 return false;
118 }
119 if (ContainsKey(profile_frequency_data_, key)) {
120 *value = profile_frequency_data_[kIllegalDayProfile];
121 return true;
122 }
123 return false;
124 }
125
Paul Stewart21f2aae2013-01-17 17:10:08 -0800126 protected:
Paul Stewart3c504012013-01-17 17:49:58 -0800127 typedef scoped_refptr<MockWiFiService> MockWiFiServiceRefPtr;
128
129 void CreateServicesFromProfile() {
130 provider_.CreateServicesFromProfile(profile_);
131 }
132
Wade Guthrie60a37062013-04-02 11:39:09 -0700133 void LoadAndFixupServiceEntries(bool is_default_profile) {
134 provider_.LoadAndFixupServiceEntries(&storage_, is_default_profile);
Paul Stewart3c504012013-01-17 17:49:58 -0800135 }
136
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700137 void Save() {
138 provider_.Save(&storage_);
139 }
140
Paul Stewart3c504012013-01-17 17:49:58 -0800141 const vector<WiFiServiceRefPtr> GetServices() {
142 return provider_.services_;
143 }
144
Paul Stewart0427cc12013-03-25 13:50:39 -0700145 const WiFiProvider::EndpointServiceMap &GetServiceByEndpoint() {
146 return provider_.service_by_endpoint_;
147 }
148
Paul Stewart6c351ff2013-02-25 15:13:03 -0800149 bool GetRunning() {
150 return provider_.running_;
151 }
152
Paul Stewart3c504012013-01-17 17:49:58 -0800153 void AddStringParameterToStorage(const string &id,
154 const string &key,
155 const string &value) {
156 EXPECT_CALL(storage_, GetString(id, key, _))
157 .WillRepeatedly(DoAll(SetArgumentPointee<2>(value),
158 Return(true)));
159 }
160
161 string AddServiceToStorage(const char *ssid,
162 const char *mode,
163 const char *security,
164 bool is_hidden,
165 bool provide_hidden) {
166 string id = StringToLowerASCII(base::StringPrintf("entry_%d",
167 storage_entry_index_));
168 EXPECT_CALL(storage_, GetString(id, _, _)).WillRepeatedly(Return(false));
169 if (ssid) {
170 const string ssid_string(ssid);
171 const string hex_ssid(
172 base::HexEncode(ssid_string.data(), ssid_string.size()));
173 AddStringParameterToStorage(id, WiFiService::kStorageSSID, hex_ssid);
174 }
175 if (mode) {
176 AddStringParameterToStorage(id, WiFiService::kStorageMode, mode);
177 }
178 if (security) {
179 AddStringParameterToStorage(id, WiFiService::kStorageSecurity, security);
180 }
181 if (provide_hidden) {
182 EXPECT_CALL(storage_, GetBool(id, flimflam::kWifiHiddenSsid, _))
183 .WillRepeatedly(
184 DoAll(SetArgumentPointee<2>(is_hidden), Return(true)));
185 } else {
186 EXPECT_CALL(storage_, GetBool(id, flimflam::kWifiHiddenSsid, _))
187 .WillRepeatedly(Return(false));
188 }
189 storage_entry_index_++;
190 return id;
191 }
192
Paul Stewartd2e1c362013-03-03 19:06:07 -0800193 void SetServiceParameters(const char *ssid,
194 const char *mode,
195 const char *security,
196 bool is_hidden,
197 bool provide_hidden,
198 KeyValueStore *args) {
199 args->SetString(flimflam::kTypeProperty, flimflam::kTypeWifi);
200 if (ssid) {
201 args->SetString(flimflam::kSSIDProperty, ssid);
202 }
203 if (mode) {
204 args->SetString(flimflam::kModeProperty, mode);
205 }
206 if (security) {
207 args->SetString(flimflam::kSecurityProperty, security);
208 }
209 if (provide_hidden) {
210 args->SetBool(flimflam::kWifiHiddenSsid, is_hidden);
211 }
212 }
213
214 WiFiServiceRefPtr CreateTemporaryService(const char *ssid,
215 const char *mode,
216 const char *security,
217 bool is_hidden,
218 bool provide_hidden,
219 Error *error) {
220 KeyValueStore args;
221 SetServiceParameters(
222 ssid, mode, security, is_hidden, provide_hidden, &args);
223 return provider_.CreateTemporaryService(args, error);
224 }
225
Paul Stewart3c504012013-01-17 17:49:58 -0800226 WiFiServiceRefPtr GetService(const char *ssid,
227 const char *mode,
228 const char *security,
229 bool is_hidden,
230 bool provide_hidden,
231 Error *error) {
232 KeyValueStore args;
Paul Stewartd2e1c362013-03-03 19:06:07 -0800233 SetServiceParameters(
234 ssid, mode, security, is_hidden, provide_hidden, &args);
Paul Stewart3c504012013-01-17 17:49:58 -0800235 return provider_.GetService(args, error);
236 }
237
238 WiFiServiceRefPtr FindService(const vector<uint8_t> &ssid,
239 const string &mode,
240 const string &security) {
241 return provider_.FindService(ssid, mode, security);
242 }
243 WiFiEndpointRefPtr MakeEndpoint(const string &ssid, const string &bssid,
244 uint16 frequency, int16 signal_dbm) {
245 return WiFiEndpoint::MakeOpenEndpoint(
Paul Stewart0654ece2013-03-26 15:21:26 -0700246 NULL, NULL, ssid, bssid, WPASupplicant::kNetworkModeInfrastructure,
Paul Stewart3c504012013-01-17 17:49:58 -0800247 frequency, signal_dbm);
248 }
249 MockWiFiServiceRefPtr AddMockService(const vector<uint8_t> &ssid,
250 const string &mode,
251 const string &security,
252 bool hidden_ssid) {
253 MockWiFiServiceRefPtr service = new MockWiFiService(
254 &control_,
255 &dispatcher_,
256 &metrics_,
257 &manager_,
258 &provider_,
259 ssid,
260 mode,
261 security,
262 hidden_ssid);
263 provider_.services_.push_back(service);
264 return service;
265 }
Paul Stewart0427cc12013-03-25 13:50:39 -0700266 void AddEndpointToService(WiFiServiceRefPtr service,
267 const WiFiEndpointConstRefPtr &endpoint) {
268 provider_.service_by_endpoint_[endpoint] = service;
269 }
Wade Guthrie60a37062013-04-02 11:39:09 -0700270
271 void BuildFreqCountStrings(vector<string> *strings) {
272 // NOTE: These strings match the frequencies in |BuildFreqCountMap|. They
273 // are also provided, here, in sorted order to match the frequency map
274 // (iterators for which will provide them in frequency-sorted order).
275 static const char *kStrings[] = {
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700276 "@20", "5180:14", "5240:16", "5745:7", "5765:4", "5785:14", "5805:5"
Wade Guthrie60a37062013-04-02 11:39:09 -0700277 };
278 if (!strings) {
279 LOG(ERROR) << "NULL |strings|.";
280 return;
281 }
282 for (size_t i = 0; i < arraysize(kStrings); ++i) {
283 (*strings).push_back(kStrings[i]);
284 }
285 }
286
287 void BuildFreqCountMap(WiFiProvider::ConnectFrequencyMap *frequencies) {
288 // NOTE: These structures match the strings in |BuildFreqCountStrings|.
289 static const struct FreqCount {
290 uint16 freq;
291 int64 count;
292 } kConnectFreq[] = {
293 {5180, 14},
294 {5240, 16},
295 {5745, 7},
296 {5765, 4},
297 {5785, 14},
298 {5805, 5}
299 };
300 if (!frequencies) {
301 LOG(ERROR) << "NULL |frequencies|.";
302 return;
303 }
304 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConnectFreq); ++i) {
305 (*frequencies)[kConnectFreq[i].freq] = kConnectFreq[i].count;
306 }
307 }
308
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700309 void LoadConnectCountByFrequency(time_t today_seconds) {
310 provider_.time_ = &time_;
311 EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(today_seconds));
312 const string kGroupId =
313 StringPrintf("%s_0_0_%s_%s",
314 flimflam::kTypeWifi,
315 flimflam::kModeManaged,
316 flimflam::kSecurityNone);
317 EXPECT_CALL(storage_,
318 GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
319 set<string> groups;
320 groups.insert(kGroupId);
321 EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups));
322 // Provide data for block[0] through block[2] (block[3] is empty).
323 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
324 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
325 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
326 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
327 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
328 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
329 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
330 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
331 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
332 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
333 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
334 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
335
336 LoadAndFixupServiceEntries(true);
337 }
338
339 map<string, vector<string>> profile_frequency_data_;
Paul Stewart21f2aae2013-01-17 17:10:08 -0800340 NiceMockControl control_;
Paul Stewart3c504012013-01-17 17:49:58 -0800341 MockEventDispatcher dispatcher_;
Paul Stewart21f2aae2013-01-17 17:10:08 -0800342 MockMetrics metrics_;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -0700343 MockTime time_;
Paul Stewart3c504012013-01-17 17:49:58 -0800344 StrictMock<MockManager> manager_;
Paul Stewart21f2aae2013-01-17 17:10:08 -0800345 WiFiProvider provider_;
Paul Stewart3c504012013-01-17 17:49:58 -0800346 scoped_refptr<MockProfile> profile_;
347 StrictMock<MockStore> storage_;
348 int storage_entry_index_;
Paul Stewart21f2aae2013-01-17 17:10:08 -0800349};
350
Paul Stewart3c504012013-01-17 17:49:58 -0800351MATCHER(TypeWiFiPropertyMatch, "") {
352 return
353 arg.bool_properties().empty() &&
354 arg.int_properties().empty() &&
355 arg.uint_properties().empty() &&
356 arg.string_properties().size() == 1 &&
357 arg.LookupString(flimflam::kTypeProperty, "") == flimflam::kTypeWifi;
358}
359
360MATCHER_P(RefPtrMatch, ref, "") {
361 return ref.get() == arg.get();
362}
363
364TEST_F(WiFiProviderTest, Start) {
365 // Doesn't do anything really. Just testing for no crash.
366 EXPECT_TRUE(GetServices().empty());
Paul Stewart6c351ff2013-02-25 15:13:03 -0800367 EXPECT_FALSE(GetRunning());
Paul Stewart3c504012013-01-17 17:49:58 -0800368 provider_.Start();
369 EXPECT_TRUE(GetServices().empty());
Paul Stewart6c351ff2013-02-25 15:13:03 -0800370 EXPECT_TRUE(GetRunning());
Paul Stewart0427cc12013-03-25 13:50:39 -0700371 EXPECT_TRUE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -0800372}
373
374TEST_F(WiFiProviderTest, Stop) {
375 MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'),
376 flimflam::kModeManaged,
377 flimflam::kSecurityNone,
378 false);
379 MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'),
380 flimflam::kModeManaged,
381 flimflam::kSecurityNone,
382 false);
Paul Stewart0427cc12013-03-25 13:50:39 -0700383 WiFiEndpointRefPtr endpoint = MakeEndpoint("", "00:00:00:00:00:00", 0, 0);
384 AddEndpointToService(service0, endpoint);
385
Paul Stewart3c504012013-01-17 17:49:58 -0800386 EXPECT_EQ(2, GetServices().size());
Paul Stewart0427cc12013-03-25 13:50:39 -0700387 EXPECT_FALSE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -0800388 EXPECT_CALL(*service0, ResetWiFi()).Times(1);
389 EXPECT_CALL(*service1, ResetWiFi()).Times(1);
390 EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1);
391 EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service1))).Times(1);
392 provider_.Stop();
393 // Verify now, so it's clear that this happened as a result of the call
394 // above, and not anything in the destructor(s).
395 Mock::VerifyAndClearExpectations(service0);
396 Mock::VerifyAndClearExpectations(service1);
397 Mock::VerifyAndClearExpectations(&manager_);
398 EXPECT_TRUE(GetServices().empty());
Paul Stewart0427cc12013-03-25 13:50:39 -0700399 EXPECT_TRUE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -0800400}
401
402TEST_F(WiFiProviderTest, CreateServicesFromProfileWithNoGroups) {
403 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
404 .WillOnce(Return(set<string>()));
405 CreateServicesFromProfile();
406 EXPECT_TRUE(GetServices().empty());
407}
408
409TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSSID) {
410 string id;
411 StrictMock<MockStore> storage;
412 set<string> groups;
413 groups.insert(AddServiceToStorage(
414 NULL, flimflam::kModeManaged, flimflam::kSecurityNone, false, true));
415 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
416 .WillRepeatedly(Return(groups));
417 CreateServicesFromProfile();
418 EXPECT_TRUE(GetServices().empty());
419}
420
421TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySSID) {
422 string id;
423 StrictMock<MockStore> storage;
424 set<string> groups;
425 groups.insert(AddServiceToStorage(
426 "", flimflam::kModeManaged, flimflam::kSecurityNone, false, true));
427 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
428 .WillRepeatedly(Return(groups));
429 CreateServicesFromProfile();
430 EXPECT_TRUE(GetServices().empty());
431}
432
433TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingMode) {
434 string id;
435 StrictMock<MockStore> storage;
436 set<string> groups;
437 groups.insert(AddServiceToStorage(
438 "foo", NULL, flimflam::kSecurityNone, false, true));
439 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
440 .WillRepeatedly(Return(groups));
441 CreateServicesFromProfile();
442 EXPECT_TRUE(GetServices().empty());
443}
444
445TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptyMode) {
446 string id;
447 StrictMock<MockStore> storage;
448 set<string> groups;
449 groups.insert(AddServiceToStorage(
450 "foo", "", flimflam::kSecurityNone, false, true));
451 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
452 .WillRepeatedly(Return(groups));
453 CreateServicesFromProfile();
454 EXPECT_TRUE(GetServices().empty());
455}
456
457TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSecurity) {
458 string id;
459 StrictMock<MockStore> storage;
460 set<string> groups;
461 groups.insert(AddServiceToStorage(
462 "foo", flimflam::kModeManaged, NULL, false, true));
463 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
464 .WillRepeatedly(Return(groups));
465 CreateServicesFromProfile();
466 EXPECT_TRUE(GetServices().empty());
467}
468
469TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySecurity) {
470 string id;
471 StrictMock<MockStore> storage;
472 set<string> groups;
473 groups.insert(AddServiceToStorage(
474 "foo", flimflam::kModeManaged, "", false, true));
475 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
476 .WillRepeatedly(Return(groups));
477 CreateServicesFromProfile();
478 EXPECT_TRUE(GetServices().empty());
479}
480
481TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingHidden) {
482 string id;
483 StrictMock<MockStore> storage;
484 set<string> groups;
485 groups.insert(AddServiceToStorage(
486 "foo", flimflam::kModeManaged, flimflam::kSecurityNone, false, false));
487 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
488 .WillRepeatedly(Return(groups));
489 CreateServicesFromProfile();
490 EXPECT_TRUE(GetServices().empty());
491}
492
493TEST_F(WiFiProviderTest, CreateServicesFromProfileSingle) {
494 string id;
495 StrictMock<MockStore> storage;
496 set<string> groups;
497 string kSSID("foo");
498 groups.insert(AddServiceToStorage(
499 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone,
500 false, true));
501 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
502 .WillRepeatedly(Return(groups));
503 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
504 CreateServicesFromProfile();
505 Mock::VerifyAndClearExpectations(&manager_);
506 EXPECT_EQ(1, GetServices().size());
507
508 const WiFiServiceRefPtr service = GetServices().front();
509 const string service_ssid(service->ssid().begin(), service->ssid().end());
510 EXPECT_EQ(kSSID, service_ssid);
511 EXPECT_EQ(flimflam::kModeManaged, service->mode());
512 EXPECT_TRUE(service->IsSecurityMatch(flimflam::kSecurityNone));
513
514 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
515 CreateServicesFromProfile();
516 EXPECT_EQ(1, GetServices().size());
517}
518
519TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenButConnected) {
520 string id;
521 StrictMock<MockStore> storage;
522 set<string> groups;
523 string kSSID("foo");
524 groups.insert(AddServiceToStorage(
525 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone,
526 true, true));
527 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
528 .WillRepeatedly(Return(groups));
529 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
530 EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
531 .WillOnce(Return(true));
Wade Guthrie68d41092013-04-02 12:56:02 -0700532 EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0);
Paul Stewart3c504012013-01-17 17:49:58 -0800533 CreateServicesFromProfile();
534 Mock::VerifyAndClearExpectations(&manager_);
535
536 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
537 EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0);
538 CreateServicesFromProfile();
539}
540
541TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenNotConnected) {
542 string id;
543 StrictMock<MockStore> storage;
544 set<string> groups;
545 string kSSID("foo");
546 groups.insert(AddServiceToStorage(
547 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone,
548 true, true));
549 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
550 .WillRepeatedly(Return(groups));
551 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
552 EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
553 .WillOnce(Return(false));
Wade Guthrie68d41092013-04-02 12:56:02 -0700554 EXPECT_CALL(manager_, RequestScan(Device::kProgressiveScan,
555 flimflam::kTypeWifi, _)).Times(1);
Paul Stewart3c504012013-01-17 17:49:58 -0800556 CreateServicesFromProfile();
557 Mock::VerifyAndClearExpectations(&manager_);
558
559 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
560 EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0);
Wade Guthrie68d41092013-04-02 12:56:02 -0700561 EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0);
Paul Stewart3c504012013-01-17 17:49:58 -0800562 CreateServicesFromProfile();
563}
564
565TEST_F(WiFiProviderTest, CreateTwoServices) {
566 string id;
567 StrictMock<MockStore> storage;
568 set<string> groups;
569 groups.insert(AddServiceToStorage(
570 "foo", flimflam::kModeManaged, flimflam::kSecurityNone, false, true));
571 groups.insert(AddServiceToStorage(
572 "bar", flimflam::kModeManaged, flimflam::kSecurityNone, true, true));
573 EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch()))
574 .WillRepeatedly(Return(groups));
575 EXPECT_CALL(manager_, RegisterService(_)).Times(2);
576 EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi))
577 .WillOnce(Return(true));
Wade Guthrie68d41092013-04-02 12:56:02 -0700578 EXPECT_CALL(manager_, RequestScan(_, flimflam::kTypeWifi, _)).Times(0);
Paul Stewart3c504012013-01-17 17:49:58 -0800579 CreateServicesFromProfile();
580 Mock::VerifyAndClearExpectations(&manager_);
581
582 EXPECT_EQ(2, GetServices().size());
583}
584
Paul Stewart4fe4ec22013-02-22 07:47:29 -0800585TEST_F(WiFiProviderTest, GetServiceEmptyMode) {
Paul Stewart3c504012013-01-17 17:49:58 -0800586 Error error;
587 EXPECT_FALSE(GetService("foo", "", flimflam::kSecurityNone,
588 false, false, &error).get());
589 EXPECT_EQ(Error::kNotSupported, error.type());
590}
591
Paul Stewart4fe4ec22013-02-22 07:47:29 -0800592TEST_F(WiFiProviderTest, GetServiceNoMode) {
593 Error error;
594 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
595 EXPECT_TRUE(GetService("foo", NULL, flimflam::kSecurityNone,
596 false, false, &error).get());
597 EXPECT_TRUE(error.IsSuccess());
598}
599
Paul Stewart3c504012013-01-17 17:49:58 -0800600TEST_F(WiFiProviderTest, GetServiceBadMode) {
601 Error error;
Paul Stewartd2e1c362013-03-03 19:06:07 -0800602 EXPECT_FALSE(GetService("foo", "BogoMesh",
Paul Stewart3c504012013-01-17 17:49:58 -0800603 flimflam::kSecurityNone,
604 false, false, &error).get());
605 EXPECT_EQ(Error::kNotSupported, error.type());
606 EXPECT_EQ("service mode is unsupported", error.message());
607}
608
609TEST_F(WiFiProviderTest, GetServiceNoSSID) {
610 Error error;
611 EXPECT_FALSE(GetService(NULL, flimflam::kModeManaged,
612 flimflam::kSecurityNone, false, false,
613 &error).get());
614 EXPECT_EQ(Error::kInvalidArguments, error.type());
615 EXPECT_EQ("must specify SSID", error.message());
616}
617
618TEST_F(WiFiProviderTest, GetServiceEmptySSID) {
619 Error error;
620 EXPECT_FALSE(GetService("", flimflam::kModeManaged,
621 flimflam::kSecurityNone, false, false,
622 &error).get());
623 EXPECT_EQ(Error::kInvalidNetworkName, error.type());
624 EXPECT_EQ("SSID is too short", error.message());
625}
626
627TEST_F(WiFiProviderTest, GetServiceLongSSID) {
628 Error error;
629 string ssid(IEEE_80211::kMaxSSIDLen + 1, '0');
630 EXPECT_FALSE(GetService(ssid.c_str(), flimflam::kModeManaged,
631 flimflam::kSecurityNone, false, false,
632 &error).get());
633 EXPECT_EQ(Error::kInvalidNetworkName, error.type());
634 EXPECT_EQ("SSID is too long", error.message());
635}
636
637TEST_F(WiFiProviderTest, GetServiceJustLongEnoughSSID) {
638 Error error;
639 string ssid(IEEE_80211::kMaxSSIDLen, '0');
640 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
641 EXPECT_TRUE(GetService(ssid.c_str(), flimflam::kModeManaged,
642 flimflam::kSecurityNone, false, false,
643 &error));
644 EXPECT_TRUE(error.IsSuccess());
645}
646
647TEST_F(WiFiProviderTest, GetServiceBadSecurty) {
648 Error error;
649 EXPECT_FALSE(GetService("foo", flimflam::kModeManaged,
650 "pig-80211", false, false,
651 &error));
652 EXPECT_EQ(Error::kNotSupported, error.type());
653 EXPECT_EQ("security mode is unsupported", error.message());
654}
655
656TEST_F(WiFiProviderTest, GetServiceMinimal) {
657 Error error;
658 const string kSSID("foo");
659 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
660 WiFiServiceRefPtr service = GetService(kSSID.c_str(), flimflam::kModeManaged,
661 NULL, false, false, &error);
662 EXPECT_TRUE(service.get());
663 EXPECT_TRUE(error.IsSuccess());
664 const string service_ssid(service->ssid().begin(), service->ssid().end());
665 EXPECT_EQ(kSSID, service_ssid);
666 EXPECT_EQ(flimflam::kModeManaged, service->mode());
667
668 // These two should be set to their default values if not specified.
669 EXPECT_TRUE(service->IsSecurityMatch(flimflam::kSecurityNone));
670 EXPECT_TRUE(service->hidden_ssid());
671}
672
673TEST_F(WiFiProviderTest, GetServiceFullySpecified) {
674 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
675 const string kSSID("bar");
676 Error error;
677 WiFiServiceRefPtr service0 =
678 GetService(kSSID.c_str(), flimflam::kModeManaged,
679 flimflam::kSecurityPsk, false, true, &error);
680 Mock::VerifyAndClearExpectations(&manager_);
681 EXPECT_TRUE(error.IsSuccess());
682 const string service_ssid(service0->ssid().begin(), service0->ssid().end());
683 EXPECT_EQ(kSSID, service_ssid);
684 EXPECT_EQ(flimflam::kModeManaged, service0->mode());
685 EXPECT_TRUE(service0->IsSecurityMatch(flimflam::kSecurityPsk));
686 EXPECT_FALSE(service0->hidden_ssid());
687
688 // Getting the same service parameters (even with a different hidden
689 // parameter) should return the same service.
690 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
691 WiFiServiceRefPtr service1 =
692 GetService(kSSID.c_str(), flimflam::kModeManaged,
693 flimflam::kSecurityPsk, true, true, &error);
694 Mock::VerifyAndClearExpectations(&manager_);
695 EXPECT_EQ(service0.get(), service1.get());
696 EXPECT_EQ(1, GetServices().size());
697
698 // Getting the same ssid with different other parameters should return
699 // a different service.
700 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
701 WiFiServiceRefPtr service2 =
702 GetService(kSSID.c_str(), flimflam::kModeManaged,
703 flimflam::kSecurityNone, true, true, &error);
704 Mock::VerifyAndClearExpectations(&manager_);
705 EXPECT_NE(service0.get(), service2.get());
706 EXPECT_EQ(2, GetServices().size());
707}
708
Paul Stewartd2e1c362013-03-03 19:06:07 -0800709TEST_F(WiFiProviderTest, FindSimilarService) {
710 // Since CreateTemporyService uses exactly the same validation as
711 // GetService, don't bother with testing invalid parameters.
712 const string kSSID("foo");
713 KeyValueStore args;
714 SetServiceParameters(
715 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone,
716 true, true, &args);
717 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
718 Error get_service_error;
719 WiFiServiceRefPtr service = provider_.GetService(args, &get_service_error);
720 EXPECT_EQ(1, GetServices().size());
721
722 {
723 Error error;
724 WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
725 EXPECT_EQ(service.get(), find_service.get());
726 EXPECT_TRUE(error.IsSuccess());
727 }
728
729 args.SetBool(flimflam::kWifiHiddenSsid, false);
730
731 {
732 Error error;
733 WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
734 EXPECT_EQ(service.get(), find_service.get());
735 EXPECT_TRUE(error.IsSuccess());
736 }
737
738 args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityWpa);
739
740 {
741 Error error;
742 WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error);
743 EXPECT_EQ(NULL, find_service.get());
744 EXPECT_EQ(Error::kNotFound, error.type());
745 }
746}
747
748TEST_F(WiFiProviderTest, CreateTemporaryService) {
749 // Since CreateTemporyService uses exactly the same validation as
750 // GetService, don't bother with testing invalid parameters.
751 const string kSSID("foo");
752 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
753 Error error;
754 WiFiServiceRefPtr service0 =
755 GetService(kSSID.c_str(), flimflam::kModeManaged,
756 flimflam::kSecurityNone, true, true, &error);
757 EXPECT_EQ(1, GetServices().size());
758 Mock::VerifyAndClearExpectations(&manager_);
759
760 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
761 WiFiServiceRefPtr service1 =
762 CreateTemporaryService(kSSID.c_str(), flimflam::kModeManaged,
763 flimflam::kSecurityNone, true, true, &error);
764
765 // Test that a new service was created, but not registered with the
766 // manager or added to the provider's service list.
767 EXPECT_EQ(1, GetServices().size());
768 EXPECT_TRUE(service0 != service1);
769 EXPECT_TRUE(service1->HasOneRef());
770}
771
Paul Stewart3c504012013-01-17 17:49:58 -0800772TEST_F(WiFiProviderTest, FindServiceWPA) {
773 const string kSSID("an_ssid");
774 Error error;
775 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
776 WiFiServiceRefPtr service = GetService(
777 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityRsn,
778 false, true, &error);
779 ASSERT_TRUE(service);
780 const vector<uint8_t> ssid_bytes(kSSID.begin(), kSSID.end());
781 WiFiServiceRefPtr wpa_service(FindService(ssid_bytes, flimflam::kModeManaged,
782 flimflam::kSecurityWpa));
783 EXPECT_TRUE(wpa_service);
784 EXPECT_EQ(service.get(), wpa_service.get());
785 WiFiServiceRefPtr rsn_service(FindService(ssid_bytes, flimflam::kModeManaged,
786 flimflam::kSecurityRsn));
787 EXPECT_TRUE(rsn_service.get());
788 EXPECT_EQ(service.get(), rsn_service.get());
789 WiFiServiceRefPtr psk_service(FindService(ssid_bytes, flimflam::kModeManaged,
790 flimflam::kSecurityPsk));
791 EXPECT_EQ(service.get(), psk_service.get());
792 WiFiServiceRefPtr wep_service(FindService(ssid_bytes, flimflam::kModeManaged,
793 flimflam::kSecurityWep));
794 EXPECT_TRUE(service.get() != wep_service.get());
795 EXPECT_EQ(NULL, wep_service.get());
796}
797
798TEST_F(WiFiProviderTest, FindServiceForEndpoint) {
799 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
800 Error error;
801 const string kSSID("an_ssid");
802 WiFiServiceRefPtr service = GetService(
803 kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone,
804 false, true, &error);
805 ASSERT_TRUE(service);
806 WiFiEndpointRefPtr endpoint = MakeEndpoint(kSSID, "00:00:00:00:00:00", 0, 0);
807 WiFiServiceRefPtr endpoint_service =
808 provider_.FindServiceForEndpoint(endpoint);
Paul Stewart0427cc12013-03-25 13:50:39 -0700809 // Just because a matching service exists, we shouldn't necessarily have
810 // it returned. We will test that this function returns the correct
811 // service if the endpoint is added below.
812 EXPECT_EQ(NULL, endpoint_service.get());
Paul Stewart3c504012013-01-17 17:49:58 -0800813}
814
815TEST_F(WiFiProviderTest, OnEndpointAdded) {
Paul Stewart6c351ff2013-02-25 15:13:03 -0800816 provider_.Start();
Paul Stewart3c504012013-01-17 17:49:58 -0800817 const string ssid0("an_ssid");
818 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
819 EXPECT_FALSE(FindService(ssid0_bytes, flimflam::kModeManaged,
820 flimflam::kSecurityNone));
821 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
822 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
823 EXPECT_CALL(manager_, UpdateService(_)).Times(1);
824 provider_.OnEndpointAdded(endpoint0);
825 Mock::VerifyAndClearExpectations(&manager_);
826 EXPECT_EQ(1, GetServices().size());
827 WiFiServiceRefPtr service0(FindService(ssid0_bytes, flimflam::kModeManaged,
828 flimflam::kSecurityNone));
829 EXPECT_TRUE(service0);
830 EXPECT_TRUE(service0->HasEndpoints());
Paul Stewart0427cc12013-03-25 13:50:39 -0700831 EXPECT_EQ(1, GetServiceByEndpoint().size());
832 WiFiServiceRefPtr endpoint_service =
833 provider_.FindServiceForEndpoint(endpoint0);
834 EXPECT_EQ(service0.get(), endpoint_service.get());
Paul Stewart3c504012013-01-17 17:49:58 -0800835
836 WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
837 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
838 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
839 provider_.OnEndpointAdded(endpoint1);
840 Mock::VerifyAndClearExpectations(&manager_);
841 EXPECT_EQ(1, GetServices().size());
842
843 const string ssid1("another_ssid");
844 const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
845 EXPECT_FALSE(FindService(ssid1_bytes, flimflam::kModeManaged,
846 flimflam::kSecurityNone));
847 WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02",
848 0, 0);
849 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
850 EXPECT_CALL(manager_, UpdateService(_)).Times(1);
851 provider_.OnEndpointAdded(endpoint2);
852 Mock::VerifyAndClearExpectations(&manager_);
853 EXPECT_EQ(2, GetServices().size());
854
855 WiFiServiceRefPtr service1(FindService(ssid1_bytes, flimflam::kModeManaged,
856 flimflam::kSecurityNone));
857 EXPECT_TRUE(service1);
858 EXPECT_TRUE(service1->HasEndpoints());
859 EXPECT_TRUE(service1 != service0);
860}
861
Paul Stewart08a54eb2013-03-11 12:07:36 -0700862TEST_F(WiFiProviderTest, OnEndpointAddedWithSecurity) {
863 provider_.Start();
864 const string ssid0("an_ssid");
865 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
866 EXPECT_FALSE(FindService(ssid0_bytes, flimflam::kModeManaged,
867 flimflam::kSecurityNone));
868 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
869 endpoint0->set_security_mode(flimflam::kSecurityRsn);
870 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
871 EXPECT_CALL(manager_, UpdateService(_)).Times(1);
872 provider_.OnEndpointAdded(endpoint0);
873 Mock::VerifyAndClearExpectations(&manager_);
874 EXPECT_EQ(1, GetServices().size());
875 WiFiServiceRefPtr service0(FindService(ssid0_bytes, flimflam::kModeManaged,
876 flimflam::kSecurityWpa));
877 EXPECT_TRUE(service0);
878 EXPECT_TRUE(service0->HasEndpoints());
879 EXPECT_EQ(flimflam::kSecurityPsk, service0->security_);
880
881 WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
882 endpoint1->set_security_mode(flimflam::kSecurityWpa);
883 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
884 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
885 provider_.OnEndpointAdded(endpoint1);
886 Mock::VerifyAndClearExpectations(&manager_);
887 EXPECT_EQ(1, GetServices().size());
888
889 const string ssid1("another_ssid");
890 const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
891 EXPECT_FALSE(FindService(ssid1_bytes, flimflam::kModeManaged,
892 flimflam::kSecurityNone));
893 WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0);
894 endpoint2->set_security_mode(flimflam::kSecurityWpa);
895 EXPECT_CALL(manager_, RegisterService(_)).Times(1);
896 EXPECT_CALL(manager_, UpdateService(_)).Times(1);
897 provider_.OnEndpointAdded(endpoint2);
898 Mock::VerifyAndClearExpectations(&manager_);
899 EXPECT_EQ(2, GetServices().size());
900
901 WiFiServiceRefPtr service1(FindService(ssid1_bytes, flimflam::kModeManaged,
902 flimflam::kSecurityRsn));
903 EXPECT_TRUE(service1);
904 EXPECT_TRUE(service1->HasEndpoints());
905 EXPECT_EQ(flimflam::kSecurityPsk, service1->security_);
906 EXPECT_TRUE(service1 != service0);
907}
908
Paul Stewart6c351ff2013-02-25 15:13:03 -0800909TEST_F(WiFiProviderTest, OnEndpointAddedWhileStopped) {
910 // If we don't call provider_.Start(), OnEndpointAdded should have no effect.
911 const string ssid("an_ssid");
912 WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);
913 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
914 EXPECT_CALL(manager_, UpdateService(_)).Times(0);
915 provider_.OnEndpointAdded(endpoint);
916 EXPECT_TRUE(GetServices().empty());
917}
918
Paul Stewart3c504012013-01-17 17:49:58 -0800919TEST_F(WiFiProviderTest, OnEndpointAddedToMockService) {
920 // The previous test allowed the provider to create its own "real"
921 // WiFiServices, which hides some of what we can test with mock
922 // services. Re-do an add-endpoint operation by seeding the provider
923 // with a mock service.
Paul Stewart6c351ff2013-02-25 15:13:03 -0800924 provider_.Start();
Paul Stewart3c504012013-01-17 17:49:58 -0800925 const string ssid0("an_ssid");
926 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
927 MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
928 flimflam::kModeManaged,
929 flimflam::kSecurityNone,
930 false);
931 const string ssid1("another_ssid");
932 const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
933 MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes,
934 flimflam::kModeManaged,
935 flimflam::kSecurityNone,
936 false);
937 EXPECT_EQ(service0.get(), FindService(ssid0_bytes,
938 flimflam::kModeManaged,
939 flimflam::kSecurityNone).get());
940 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
941 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
942 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
943 EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint0))).Times(1);
944 EXPECT_CALL(*service1, AddEndpoint(_)).Times(0);
945 provider_.OnEndpointAdded(endpoint0);
946 Mock::VerifyAndClearExpectations(&manager_);
947 Mock::VerifyAndClearExpectations(service0);
948 Mock::VerifyAndClearExpectations(service1);
949
950 WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0);
951 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
952 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
953 EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint1))).Times(1);
954 EXPECT_CALL(*service1, AddEndpoint(_)).Times(0);
955 provider_.OnEndpointAdded(endpoint1);
956 Mock::VerifyAndClearExpectations(&manager_);
957 Mock::VerifyAndClearExpectations(service0);
958 Mock::VerifyAndClearExpectations(service1);
959
960 WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0);
961 EXPECT_CALL(manager_, RegisterService(_)).Times(0);
962 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service1))).Times(1);
963 EXPECT_CALL(*service0, AddEndpoint(_)).Times(0);
964 EXPECT_CALL(*service1, AddEndpoint(RefPtrMatch(endpoint2))).Times(1);
965 provider_.OnEndpointAdded(endpoint2);
966}
967
968TEST_F(WiFiProviderTest, OnEndpointRemoved) {
Paul Stewart6c351ff2013-02-25 15:13:03 -0800969 provider_.Start();
Paul Stewart3c504012013-01-17 17:49:58 -0800970 const string ssid0("an_ssid");
971 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
972 MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
973 flimflam::kModeManaged,
974 flimflam::kSecurityNone,
975 false);
976 const string ssid1("another_ssid");
977 const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end());
978 MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes,
979 flimflam::kModeManaged,
980 flimflam::kSecurityNone,
981 false);
982 EXPECT_EQ(2, GetServices().size());
983
984 // Remove the last endpoint of a non-remembered service.
985 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
Paul Stewart0427cc12013-03-25 13:50:39 -0700986 AddEndpointToService(service0, endpoint0);
987 EXPECT_EQ(1, GetServiceByEndpoint().size());
988
Paul Stewart3c504012013-01-17 17:49:58 -0800989 EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
990 EXPECT_CALL(*service1, RemoveEndpoint(_)).Times(0);
991 EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(false));
992 EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(false));
993 EXPECT_CALL(*service0, ResetWiFi()).Times(1);
994 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(0);
995 EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1);
996 provider_.OnEndpointRemoved(endpoint0);
997 // Verify now, so it's clear that this happened as a result of the call
998 // above, and not anything in the destructor(s).
999 Mock::VerifyAndClearExpectations(&manager_);
1000 Mock::VerifyAndClearExpectations(service0);
1001 Mock::VerifyAndClearExpectations(service1);
1002 EXPECT_EQ(1, GetServices().size());
1003 EXPECT_EQ(service1.get(), GetServices().front().get());
Paul Stewart0427cc12013-03-25 13:50:39 -07001004 EXPECT_TRUE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -08001005}
1006
1007TEST_F(WiFiProviderTest, OnEndpointRemovedButHasEndpoints) {
Paul Stewart6c351ff2013-02-25 15:13:03 -08001008 provider_.Start();
Paul Stewart3c504012013-01-17 17:49:58 -08001009 const string ssid0("an_ssid");
1010 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
1011 MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
1012 flimflam::kModeManaged,
1013 flimflam::kSecurityNone,
1014 false);
1015 EXPECT_EQ(1, GetServices().size());
1016
1017 // Remove an endpoint of a non-remembered service.
1018 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
Paul Stewart0427cc12013-03-25 13:50:39 -07001019 AddEndpointToService(service0, endpoint0);
1020 EXPECT_EQ(1, GetServiceByEndpoint().size());
1021
Paul Stewart3c504012013-01-17 17:49:58 -08001022 EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
1023 EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(true));
1024 EXPECT_CALL(*service0, IsRemembered()).WillRepeatedly(Return(false));
1025 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
1026 EXPECT_CALL(*service0, ResetWiFi()).Times(0);
1027 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
1028 provider_.OnEndpointRemoved(endpoint0);
1029 // Verify now, so it's clear that this happened as a result of the call
1030 // above, and not anything in the destructor(s).
1031 Mock::VerifyAndClearExpectations(&manager_);
1032 Mock::VerifyAndClearExpectations(service0);
1033 EXPECT_EQ(1, GetServices().size());
Paul Stewart0427cc12013-03-25 13:50:39 -07001034 EXPECT_TRUE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -08001035}
1036
1037TEST_F(WiFiProviderTest, OnEndpointRemovedButIsRemembered) {
Paul Stewart6c351ff2013-02-25 15:13:03 -08001038 provider_.Start();
Paul Stewart3c504012013-01-17 17:49:58 -08001039 const string ssid0("an_ssid");
1040 const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end());
1041 MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes,
1042 flimflam::kModeManaged,
1043 flimflam::kSecurityNone,
1044 false);
1045 EXPECT_EQ(1, GetServices().size());
1046
1047 // Remove the last endpoint of a remembered service.
1048 WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0);
Paul Stewart0427cc12013-03-25 13:50:39 -07001049 AddEndpointToService(service0, endpoint0);
1050 EXPECT_EQ(1, GetServiceByEndpoint().size());
1051
Paul Stewart3c504012013-01-17 17:49:58 -08001052 EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1);
1053 EXPECT_CALL(*service0, HasEndpoints()).WillRepeatedly(Return(false));
1054 EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(true));
1055 EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1);
1056 EXPECT_CALL(*service0, ResetWiFi()).Times(0);
1057 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
1058 provider_.OnEndpointRemoved(endpoint0);
1059 // Verify now, so it's clear that this happened as a result of the call
1060 // above, and not anything in the destructor(s).
1061 Mock::VerifyAndClearExpectations(&manager_);
1062 Mock::VerifyAndClearExpectations(service0);
1063 EXPECT_EQ(1, GetServices().size());
Paul Stewart0427cc12013-03-25 13:50:39 -07001064 EXPECT_TRUE(GetServiceByEndpoint().empty());
Paul Stewart3c504012013-01-17 17:49:58 -08001065}
1066
Paul Stewart6c351ff2013-02-25 15:13:03 -08001067TEST_F(WiFiProviderTest, OnEndpointRemovedWhileStopped) {
1068 // If we don't call provider_.Start(), OnEndpointRemoved should not
1069 // cause a crash even if a service matching the endpoint does not exist.
1070 const string ssid("an_ssid");
1071 WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0);
1072 provider_.OnEndpointRemoved(endpoint);
1073}
1074
Paul Stewart3c504012013-01-17 17:49:58 -08001075TEST_F(WiFiProviderTest, OnServiceUnloaded) {
1076 // This function should never unregister services itself -- the Manager
1077 // will automatically deregister the service if OnServiceUnloaded()
1078 // returns true (via WiFiService::Unload()).
1079 EXPECT_CALL(manager_, DeregisterService(_)).Times(0);
1080
1081 MockWiFiServiceRefPtr service = AddMockService(vector<uint8_t>(1, '0'),
Paul Stewart6c351ff2013-02-25 15:13:03 -08001082 flimflam::kModeManaged,
1083 flimflam::kSecurityNone,
1084 false);
Paul Stewart3c504012013-01-17 17:49:58 -08001085 EXPECT_EQ(1, GetServices().size());
1086 EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(true));
1087 EXPECT_CALL(*service, ResetWiFi()).Times(0);
1088 EXPECT_FALSE(provider_.OnServiceUnloaded(service));
1089 EXPECT_EQ(1, GetServices().size());
1090 Mock::VerifyAndClearExpectations(service);
1091
1092 EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(false));
1093 EXPECT_CALL(*service, ResetWiFi()).Times(1);
1094 EXPECT_TRUE(provider_.OnServiceUnloaded(service));
1095 // Verify now, so it's clear that this happened as a result of the call
1096 // above, and not anything in the destructor(s).
1097 Mock::VerifyAndClearExpectations(service);
1098 EXPECT_TRUE(GetServices().empty());
1099
1100 Mock::VerifyAndClearExpectations(&manager_);
1101}
1102
Wade Guthrie60a37062013-04-02 11:39:09 -07001103TEST_F(WiFiProviderTest, LoadAndFixupServiceEntries) {
1104 // We test LoadAndFixupServiceEntries indirectly since it calls a static
1105 // method in WiFiService.
Paul Stewart3c504012013-01-17 17:49:58 -08001106 EXPECT_CALL(metrics_, SendEnumToUMA(
1107 "Network.Shill.Wifi.ServiceFixupEntries",
1108 Metrics::kMetricServiceFixupDefaultProfile,
1109 Metrics::kMetricServiceFixupMax)).Times(1);
1110 EXPECT_CALL(storage_, Flush()).Times(1);
1111 const string kGroupId =
1112 StringPrintf("%s_0_0_%s_%s",
1113 flimflam::kTypeWifi,
1114 flimflam::kModeManaged,
1115 flimflam::kSecurityNone);
1116 EXPECT_CALL(storage_,
1117 GetString(kGroupId, _, _)).WillRepeatedly(Return(false));
1118 EXPECT_CALL(storage_,
1119 SetString(kGroupId, _, _)).WillRepeatedly(Return(true));
1120 set<string> groups;
1121 groups.insert(kGroupId);
1122 EXPECT_CALL(storage_, GetGroups()).WillRepeatedly(Return(groups));
Wade Guthrie60a37062013-04-02 11:39:09 -07001123 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001124 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
1125 WillOnce(Return(true));
1126 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1127 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
1128 WillOnce(Return(true));
1129 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1130 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
1131 WillOnce(Return(true));
1132 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1133 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
1134 WillOnce(Return(false));
Wade Guthrie60a37062013-04-02 11:39:09 -07001135 LoadAndFixupServiceEntries(true);
Paul Stewart3c504012013-01-17 17:49:58 -08001136 Mock::VerifyAndClearExpectations(&metrics_);
1137
1138 EXPECT_CALL(metrics_, SendEnumToUMA(
1139 "Network.Shill.Wifi.ServiceFixupEntries",
1140 Metrics::kMetricServiceFixupUserProfile,
1141 Metrics::kMetricServiceFixupMax)).Times(1);
1142 EXPECT_CALL(storage_, Flush()).Times(1);
Wade Guthrie60a37062013-04-02 11:39:09 -07001143 EXPECT_CALL(storage_, GetStringList(_, _, _)).Times(0);
1144 LoadAndFixupServiceEntries(false);
Paul Stewart3c504012013-01-17 17:49:58 -08001145}
1146
Wade Guthrie60a37062013-04-02 11:39:09 -07001147TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo) {
Paul Stewart3c504012013-01-17 17:49:58 -08001148 EXPECT_CALL(metrics_, SendEnumToUMA(_, _, _)).Times(0);
1149 EXPECT_CALL(storage_, Flush()).Times(0);
1150 const string kGroupId =
1151 StringPrintf("%s_0_0_%s_%s",
1152 flimflam::kTypeWifi,
1153 flimflam::kModeManaged,
1154 flimflam::kSecurityNone);
1155 EXPECT_CALL(storage_,
1156 GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
1157 set<string> groups;
1158 groups.insert(kGroupId);
1159 EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups));
Wade Guthrie60a37062013-04-02 11:39:09 -07001160 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001161 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
1162 WillOnce(Return(true));
1163 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1164 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
1165 WillOnce(Return(true));
1166 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1167 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
1168 WillOnce(Return(true));
1169 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1170 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
1171 WillOnce(Return(false));
Wade Guthrie60a37062013-04-02 11:39:09 -07001172 LoadAndFixupServiceEntries(true);
Paul Stewart3c504012013-01-17 17:49:58 -08001173}
1174
1175TEST_F(WiFiProviderTest, GetHiddenSSIDList) {
1176 EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());
1177 const vector<uint8_t> ssid0(1, '0');
1178 AddMockService(ssid0, flimflam::kModeManaged,
1179 flimflam::kSecurityNone, false);
1180 EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());
1181
1182 const vector<uint8_t> ssid1(1, '1');
1183 MockWiFiServiceRefPtr service1 = AddMockService(ssid1,
1184 flimflam::kModeManaged,
1185 flimflam::kSecurityNone,
1186 true);
1187 EXPECT_CALL(*service1, IsRemembered()).WillRepeatedly(Return(false));
1188 EXPECT_TRUE(provider_.GetHiddenSSIDList().empty());
1189
1190 const vector<uint8_t> ssid2(1, '2');
1191 MockWiFiServiceRefPtr service2 = AddMockService(ssid2,
1192 flimflam::kModeManaged,
1193 flimflam::kSecurityNone,
1194 true);
1195 EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true));
1196 ByteArrays ssid_list = provider_.GetHiddenSSIDList();
1197
1198 EXPECT_EQ(1, ssid_list.size());
1199 EXPECT_TRUE(ssid_list[0] == ssid2);
1200
1201 const vector<uint8_t> ssid3(1, '3');
1202 MockWiFiServiceRefPtr service3 = AddMockService(ssid3,
1203 flimflam::kModeManaged,
1204 flimflam::kSecurityNone,
1205 false);
1206 EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true));
1207
1208 ssid_list = provider_.GetHiddenSSIDList();
1209 EXPECT_EQ(1, ssid_list.size());
1210 EXPECT_TRUE(ssid_list[0] == ssid2);
1211
1212 const vector<uint8_t> ssid4(1, '4');
1213 MockWiFiServiceRefPtr service4 = AddMockService(ssid4,
1214 flimflam::kModeManaged,
1215 flimflam::kSecurityNone,
1216 true);
1217 EXPECT_CALL(*service4, IsRemembered()).WillRepeatedly(Return(true));
1218
1219 ssid_list = provider_.GetHiddenSSIDList();
1220 EXPECT_EQ(2, ssid_list.size());
1221 EXPECT_TRUE(ssid_list[0] == ssid2);
1222 EXPECT_TRUE(ssid_list[1] == ssid4);
Paul Stewart21f2aae2013-01-17 17:10:08 -08001223}
1224
Wade Guthrie60a37062013-04-02 11:39:09 -07001225TEST_F(WiFiProviderTest, StringListToFrequencyMap) {
1226 vector<string> strings;
1227 BuildFreqCountStrings(&strings);
1228 WiFiProvider::ConnectFrequencyMap frequencies_result;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001229 time_t days = WiFiProvider::StringListToFrequencyMap(strings,
1230 &frequencies_result);
Wade Guthrie60a37062013-04-02 11:39:09 -07001231
1232 WiFiProvider::ConnectFrequencyMap frequencies_expect;
1233 BuildFreqCountMap(&frequencies_expect);
1234 EXPECT_THAT(frequencies_result, ContainerEq(frequencies_expect));
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001235 EXPECT_EQ(days, kTestDays);
1236}
1237
1238TEST_F(WiFiProviderTest, StringListToFrequencyMapEmpty) {
1239 vector<string> strings;
1240 strings.push_back("@50");
1241 WiFiProvider::ConnectFrequencyMap frequencies_result;
1242 time_t days = WiFiProvider::StringListToFrequencyMap(strings,
1243 &frequencies_result);
1244 EXPECT_TRUE(frequencies_result.empty());
1245 EXPECT_EQ(days, 50);
Wade Guthrie60a37062013-04-02 11:39:09 -07001246}
1247
1248TEST_F(WiFiProviderTest, FrequencyMapToStringList) {
1249 WiFiProvider::ConnectFrequencyMap frequencies;
1250 BuildFreqCountMap(&frequencies);
1251 vector<string> strings_result;
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001252 WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies,
1253 &strings_result);
Wade Guthrie60a37062013-04-02 11:39:09 -07001254
1255 vector<string> strings_expect;
1256 BuildFreqCountStrings(&strings_expect);
1257 EXPECT_THAT(strings_result, ContainerEq(strings_expect));
1258}
1259
Wade Guthrie7c2d34e2013-05-09 14:02:20 -07001260TEST_F(WiFiProviderTest, FrequencyMapToStringListEmpty) {
1261 WiFiProvider::ConnectFrequencyMap frequencies;
1262 vector<string> strings_result;
1263 WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies,
1264 &strings_result);
1265 EXPECT_EQ(1, strings_result.size());
1266 EXPECT_EQ(*strings_result.begin(), "@20");
1267}
1268
1269TEST_F(WiFiProviderTest, FrequencyMapBasicAging) {
1270 const time_t kThisWeek = kFirstWeek +
1271 WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
1272 LoadConnectCountByFrequency(kThisWeek * kSecondsPerWeek);
1273
1274 // Make sure we have data for all 3 blocks.
1275 WiFiProvider::ConnectFrequencyMap expected;
1276 expected[5001] = 2;
1277 expected[5002] = 2;
1278 expected[6001] = 1;
1279 expected[6002] = 2;
1280 expected[7001] = 1;
1281 expected[7002] = 2;
1282 EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
1283
1284 // And, then, make sure we output the expected blocks of data.
1285 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1286 Eq(profile_frequency_data_[
1287 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0)])));
1288 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1289 Eq(profile_frequency_data_[
1290 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1)])));
1291 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1292 Eq(profile_frequency_data_[
1293 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2)])));
1294 vector<string> frequencies;
1295 frequencies.push_back(base::StringPrintf("@%" PRIu64,
1296 static_cast<uint64_t>(kThisWeek)));
1297 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1298 Eq(frequencies))).Times(0);
1299 Save();
1300}
1301
1302TEST_F(WiFiProviderTest, FrequencyMapAgingIllegalDay) {
1303 provider_.time_ = &time_;
1304 const time_t kThisWeek = kFirstWeek +
1305 WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
1306 const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek;
1307 EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds));
1308 const string kGroupId =
1309 StringPrintf("%s_0_0_%s_%s",
1310 flimflam::kTypeWifi,
1311 flimflam::kModeManaged,
1312 flimflam::kSecurityNone);
1313 EXPECT_CALL(storage_,
1314 GetString(kGroupId, _, _)).WillRepeatedly(Return(true));
1315 set<string> groups;
1316 groups.insert(kGroupId);
1317 // Instead of block[1], return a block without the date.
1318 EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups));
1319 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1320 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)).
1321 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
1322 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1323 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)).
1324 WillOnce(Invoke(this, &WiFiProviderTest::GetIllegalDayStringList));
1325 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1326 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)).
1327 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
1328 EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId,
1329 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)).
1330 WillOnce(Invoke(this, &WiFiProviderTest::GetStringList));
1331
1332 LoadAndFixupServiceEntries(true);
1333
1334 // Verify that the received information only includes block[0] and block[2].
1335 WiFiProvider::ConnectFrequencyMap expected;
1336 expected[5001] = 1;
1337 expected[5002] = 2;
1338 expected[7001] = 1;
1339 expected[7002] = 2;
1340 EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
1341
1342 // And, then, make sure we output the expected blocks of data.
1343 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1344 Eq(profile_frequency_data_[
1345 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0)])));
1346 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1347 Eq(profile_frequency_data_[
1348 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1)]))).
1349 Times(0);
1350 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1351 Eq(profile_frequency_data_[
1352 StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2)])));
1353 vector<string> frequencies;
1354 frequencies.push_back(base::StringPrintf("@%" PRIu64,
1355 static_cast<uint64_t>(kThisWeek)));
1356 EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _,
1357 Eq(frequencies))).Times(0);
1358 Save();
1359}
1360
1361TEST_F(WiFiProviderTest, IncrementConnectCount) {
1362 const time_t kThisWeek = kFirstWeek +
1363 WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
1364 const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek;
1365 LoadConnectCountByFrequency(kThisWeekSeconds);
1366
1367 EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds));
1368 EXPECT_CALL(manager_, UpdateWiFiProvider());
1369 EXPECT_CALL(metrics_, SendToUMA(_, _, _, _, _));
1370 time_t newest_week_at_start =
1371 provider_.connect_count_by_frequency_dated_.crbegin()->first;
1372 provider_.IncrementConnectCount(6002);
1373
1374 // Make sure we have data for all 3 blocks.
1375 WiFiProvider::ConnectFrequencyMap expected;
1376 expected[5001] = 2;
1377 expected[5002] = 2;
1378 expected[6001] = 1;
1379 expected[6002] = 3;
1380 expected[7001] = 1;
1381 expected[7002] = 2;
1382 EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
1383 // Make sure we didn't delete the oldest block.
1384 EXPECT_TRUE(ContainsKey(provider_.connect_count_by_frequency_dated_,
1385 kFirstWeek));
1386 // Make sure we didn't create a new block.
1387 time_t newest_week_at_end =
1388 provider_.connect_count_by_frequency_dated_.crbegin()->first;
1389 EXPECT_EQ(newest_week_at_start, newest_week_at_end);
1390}
1391
1392TEST_F(WiFiProviderTest, IncrementConnectCountCreateNew) {
1393 time_t this_week = kFirstWeek + WiFiProvider::kWeeksToKeepFrequencyCounts - 1;
1394 LoadConnectCountByFrequency(this_week * kSecondsPerWeek);
1395
1396 this_week += 2;
1397 EXPECT_CALL(time_, GetSecondsSinceEpoch()).
1398 WillOnce(Return(this_week * kSecondsPerWeek));
1399 EXPECT_CALL(manager_, UpdateWiFiProvider());
1400 EXPECT_CALL(metrics_, SendToUMA(_, _, _, _, _));
1401 time_t newest_week_at_start =
1402 provider_.connect_count_by_frequency_dated_.crbegin()->first;
1403 provider_.IncrementConnectCount(6001);
1404
1405 // Make sure we have data for newest 2 blocks (only).
1406 WiFiProvider::ConnectFrequencyMap expected;
1407 expected[5001] = 1;
1408 expected[6001] = 2;
1409 expected[6002] = 2;
1410 expected[7001] = 1;
1411 expected[7002] = 2;
1412 EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected));
1413 // Verify that the oldest block is gone.
1414 EXPECT_FALSE(ContainsKey(provider_.connect_count_by_frequency_dated_,
1415 kFirstWeek));
1416 // Make sure we created a new block and that it is for the current week.
1417 time_t newest_week_at_end =
1418 provider_.connect_count_by_frequency_dated_.crbegin()->first;
1419 EXPECT_NE(newest_week_at_start, newest_week_at_end);
1420 EXPECT_TRUE(ContainsKey(provider_.connect_count_by_frequency_dated_,
1421 this_week));
1422}
1423
Paul Stewart21f2aae2013-01-17 17:10:08 -08001424} // namespace shill