| // Copyright (c) 2013 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "shill/wifi_provider.h" |
| |
| #include <map> |
| #include <set> |
| #include <string> |
| #include <vector> |
| |
| #include <base/format_macros.h> |
| #include <base/strings/string_number_conversions.h> |
| #include <base/strings/string_util.h> |
| #include <base/strings/stringprintf.h> |
| #include <chromeos/dbus/service_constants.h> |
| #include <gtest/gtest.h> |
| |
| #include "shill/mock_event_dispatcher.h" |
| #include "shill/mock_manager.h" |
| #include "shill/mock_metrics.h" |
| #include "shill/mock_profile.h" |
| #include "shill/mock_store.h" |
| #include "shill/mock_wifi_service.h" |
| #include "shill/net/ieee80211.h" |
| #include "shill/net/mock_time.h" |
| #include "shill/nice_mock_control.h" |
| #include "shill/technology.h" |
| #include "shill/wifi_endpoint.h" |
| #include "shill/wpa_supplicant.h" |
| |
| using base::StringPrintf; |
| using std::map; |
| using std::set; |
| using std::string; |
| using std::vector; |
| using ::testing::_; |
| using ::testing::AnyNumber; |
| using ::testing::ContainerEq; |
| using ::testing::Eq; |
| using ::testing::Invoke; |
| using ::testing::Mock; |
| using ::testing::NiceMock; |
| using ::testing::Return; |
| using ::testing::SetArgumentPointee; |
| using ::testing::StartsWith; |
| using ::testing::StrictMock; |
| |
| namespace shill { |
| |
| namespace { |
| |
| const time_t kFirstWeek = 50; |
| const char kIllegalDayProfile[] = "IllegalDay"; |
| const time_t kSecondsPerWeek = 60 * 60 * 24 * 7; |
| const time_t kTestDays = 20; |
| |
| } // namespace |
| |
| class WiFiProviderTest : public testing::Test { |
| public: |
| WiFiProviderTest() |
| : metrics_(nullptr), |
| manager_(&control_, &dispatcher_, &metrics_, nullptr), |
| provider_(&control_, &dispatcher_, &metrics_, &manager_), |
| default_profile_( |
| new NiceMock<MockProfile>( |
| &control_, &metrics_, &manager_, "default")), |
| user_profile_( |
| new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "user")), |
| storage_entry_index_(0) { |
| provider_.time_ = &time_; |
| |
| string freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, |
| 0); |
| profile_frequency_data_[freq_string].push_back( |
| base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek))); |
| profile_frequency_data_[freq_string].push_back("5001:1"); |
| profile_frequency_data_[freq_string].push_back("5002:2"); |
| |
| freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1); |
| profile_frequency_data_[freq_string].push_back( |
| base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 1)); |
| // Overlap one entry with previous block. |
| profile_frequency_data_[freq_string].push_back("5001:1"); |
| profile_frequency_data_[freq_string].push_back("6001:1"); |
| profile_frequency_data_[freq_string].push_back("6002:2"); |
| |
| freq_string = StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2); |
| profile_frequency_data_[freq_string].push_back( |
| base::StringPrintf("@%" PRIu64, static_cast<uint64_t>(kFirstWeek) + 2)); |
| profile_frequency_data_[freq_string].push_back("7001:1"); |
| profile_frequency_data_[freq_string].push_back("7002:2"); |
| |
| profile_frequency_data_[kIllegalDayProfile].push_back("7001:1"); |
| profile_frequency_data_[kIllegalDayProfile].push_back("7002:2"); |
| } |
| |
| virtual ~WiFiProviderTest() {} |
| |
| virtual void SetUp() { |
| EXPECT_CALL(*default_profile_, IsDefault()).WillRepeatedly(Return(true)); |
| EXPECT_CALL(*default_profile_, GetStorage()) |
| .WillRepeatedly(Return(&default_profile_storage_)); |
| EXPECT_CALL(*default_profile_, GetConstStorage()) |
| .WillRepeatedly(Return(&default_profile_storage_)); |
| |
| EXPECT_CALL(*user_profile_, IsDefault()).WillRepeatedly(Return(false)); |
| EXPECT_CALL(*user_profile_, GetStorage()) |
| .WillRepeatedly(Return(&user_profile_storage_)); |
| EXPECT_CALL(*user_profile_, GetConstStorage()) |
| .WillRepeatedly(Return(&user_profile_storage_)); |
| |
| // Default expectations for UMA metrics. Individual test cases |
| // will override these, by adding later expectations. |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| _, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)) |
| .Times(AnyNumber()); |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedPrivateNetworkCount."), |
| _, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)) |
| .Times(AnyNumber()); |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedSharedNetworkCount."), |
| _, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)) |
| .Times(AnyNumber()); |
| } |
| |
| bool GetStringList(const std::string &/*group*/, |
| const std::string &key, |
| std::vector<std::string> *value) { |
| if (!value) { |
| return false; |
| } |
| if (ContainsKey(profile_frequency_data_, key)) { |
| *value = profile_frequency_data_[key]; |
| return true; |
| } |
| return false; |
| } |
| |
| bool GetIllegalDayStringList(const std::string &/*group*/, |
| const std::string &key, |
| std::vector<std::string> *value) { |
| if (!value) { |
| return false; |
| } |
| if (ContainsKey(profile_frequency_data_, key)) { |
| *value = profile_frequency_data_[kIllegalDayProfile]; |
| return true; |
| } |
| return false; |
| } |
| |
| // Used by mock invocations of RegisterService() to maintain the side-effect |
| // of assigning a profile to |service|. |
| void BindServiceToDefaultProfile(const ServiceRefPtr &service) { |
| service->set_profile(default_profile_); |
| } |
| void BindServiceToUserProfile(const ServiceRefPtr &service) { |
| service->set_profile(user_profile_); |
| } |
| |
| protected: |
| typedef scoped_refptr<MockWiFiService> MockWiFiServiceRefPtr; |
| |
| void CreateServicesFromProfile(Profile *profile) { |
| provider_.CreateServicesFromProfile(profile); |
| } |
| |
| void LoadAndFixupServiceEntries(Profile *profile) { |
| provider_.LoadAndFixupServiceEntries(profile); |
| } |
| |
| void Save() { |
| provider_.Save(&default_profile_storage_); |
| } |
| |
| const vector<WiFiServiceRefPtr> GetServices() { |
| return provider_.services_; |
| } |
| |
| const WiFiProvider::EndpointServiceMap &GetServiceByEndpoint() { |
| return provider_.service_by_endpoint_; |
| } |
| |
| bool GetRunning() { |
| return provider_.running_; |
| } |
| |
| void AddStringParameterToStorage(MockStore *storage, |
| const string &id, |
| const string &key, |
| const string &value) { |
| EXPECT_CALL(*storage, GetString(id, key, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(value), |
| Return(true))); |
| } |
| |
| // Adds service to profile's storage. But does not set profile on the Service. |
| string AddServiceToProfileStorage(Profile *profile, |
| const char *ssid, |
| const char *mode, |
| const char *security, |
| bool is_hidden, |
| bool provide_hidden) { |
| string id = base::StringToLowerASCII( |
| base::StringPrintf("entry_%d", storage_entry_index_)); |
| auto profile_storage = dynamic_cast<MockStore *>(profile->GetStorage()); |
| EXPECT_CALL(*profile_storage, GetString(id, _, _)) |
| .WillRepeatedly(Return(false)); |
| if (ssid) { |
| const string ssid_string(ssid); |
| const string hex_ssid( |
| base::HexEncode(ssid_string.data(), ssid_string.size())); |
| AddStringParameterToStorage( |
| profile_storage, id, WiFiService::kStorageSSID, hex_ssid); |
| } |
| if (mode) { |
| AddStringParameterToStorage( |
| profile_storage, id, WiFiService::kStorageMode, mode); |
| } |
| if (security) { |
| AddStringParameterToStorage( |
| profile_storage, id, WiFiService::kStorageSecurity, security); |
| } |
| if (provide_hidden) { |
| EXPECT_CALL(*profile_storage, GetBool(id, kWifiHiddenSsid, _)) |
| .WillRepeatedly( |
| DoAll(SetArgumentPointee<2>(is_hidden), Return(true))); |
| } else { |
| EXPECT_CALL(*profile_storage, GetBool(id, kWifiHiddenSsid, _)) |
| .WillRepeatedly(Return(false)); |
| } |
| storage_entry_index_++; |
| return id; |
| } |
| |
| void SetServiceParameters(const char *ssid, |
| const char *mode, |
| const char *security, |
| bool is_hidden, |
| bool provide_hidden, |
| KeyValueStore *args) { |
| args->SetString(kTypeProperty, kTypeWifi); |
| if (ssid) { |
| // TODO(pstew): When Chrome switches to using kWifiHexSsid primarily for |
| // GetService and friends, we should switch to doing so here ourselves. |
| args->SetString(kSSIDProperty, ssid); |
| } |
| if (mode) { |
| args->SetString(kModeProperty, mode); |
| } |
| if (security) { |
| args->SetString(kSecurityProperty, security); |
| } |
| if (provide_hidden) { |
| args->SetBool(kWifiHiddenSsid, is_hidden); |
| } |
| } |
| |
| ServiceRefPtr CreateTemporaryService(const char *ssid, |
| const char *mode, |
| const char *security, |
| bool is_hidden, |
| bool provide_hidden, |
| Error *error) { |
| KeyValueStore args; |
| SetServiceParameters( |
| ssid, mode, security, is_hidden, provide_hidden, &args); |
| return provider_.CreateTemporaryService(args, error); |
| } |
| |
| WiFiServiceRefPtr GetService(const char *ssid, |
| const char *mode, |
| const char *security, |
| bool is_hidden, |
| bool provide_hidden, |
| Error *error) { |
| KeyValueStore args; |
| SetServiceParameters( |
| ssid, mode, security, is_hidden, provide_hidden, &args); |
| return provider_.GetWiFiService(args, error); |
| } |
| |
| WiFiServiceRefPtr GetWiFiService(const KeyValueStore &args, Error *error) { |
| return provider_.GetWiFiService(args, error); |
| } |
| |
| WiFiServiceRefPtr FindService(const vector<uint8_t> &ssid, |
| const string &mode, |
| const string &security) { |
| return provider_.FindService(ssid, mode, security); |
| } |
| WiFiEndpointRefPtr MakeEndpoint(const string &ssid, const string &bssid, |
| uint16_t frequency, int16_t signal_dbm) { |
| return WiFiEndpoint::MakeOpenEndpoint( |
| nullptr, nullptr, ssid, bssid, |
| WPASupplicant::kNetworkModeInfrastructure, frequency, signal_dbm); |
| } |
| MockWiFiServiceRefPtr AddMockService(const vector<uint8_t> &ssid, |
| const string &mode, |
| const string &security, |
| bool hidden_ssid) { |
| MockWiFiServiceRefPtr service = new MockWiFiService( |
| &control_, |
| &dispatcher_, |
| &metrics_, |
| &manager_, |
| &provider_, |
| ssid, |
| mode, |
| security, |
| hidden_ssid); |
| provider_.services_.push_back(service); |
| return service; |
| } |
| void AddEndpointToService(WiFiServiceRefPtr service, |
| const WiFiEndpointConstRefPtr &endpoint) { |
| provider_.service_by_endpoint_[endpoint] = service; |
| } |
| |
| void BuildFreqCountStrings(vector<string> *strings) { |
| // NOTE: These strings match the frequencies in |BuildFreqCountMap|. They |
| // are also provided, here, in sorted order to match the frequency map |
| // (iterators for which will provide them in frequency-sorted order). |
| static const char *kStrings[] = { |
| "@20", "5180:14", "5240:16", "5745:7", "5765:4", "5785:14", "5805:5" |
| }; |
| if (!strings) { |
| LOG(ERROR) << "NULL |strings|."; |
| return; |
| } |
| for (size_t i = 0; i < arraysize(kStrings); ++i) { |
| (*strings).push_back(kStrings[i]); |
| } |
| } |
| |
| void BuildFreqCountMap(WiFiProvider::ConnectFrequencyMap *frequencies) { |
| // NOTE: These structures match the strings in |BuildFreqCountStrings|. |
| static const struct FreqCount { |
| uint16_t freq; |
| int64_t count; |
| } kConnectFreq[] = { |
| {5180, 14}, |
| {5240, 16}, |
| {5745, 7}, |
| {5765, 4}, |
| {5785, 14}, |
| {5805, 5} |
| }; |
| if (!frequencies) { |
| LOG(ERROR) << "NULL |frequencies|."; |
| return; |
| } |
| for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConnectFreq); ++i) { |
| (*frequencies)[kConnectFreq[i].freq] = kConnectFreq[i].count; |
| } |
| } |
| |
| void LoadConnectCountByFrequency(time_t today_seconds) { |
| provider_.time_ = &time_; |
| EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(today_seconds)); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone); |
| EXPECT_CALL(default_profile_storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups)); |
| // Provide data for block[0] through block[2] (block[3] is empty). |
| EXPECT_CALL( |
| default_profile_storage_, |
| GetStringList( |
| WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL( |
| default_profile_storage_, |
| GetStringList( |
| WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL( |
| default_profile_storage_, |
| GetStringList( |
| WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL( |
| default_profile_storage_, |
| GetStringList( |
| WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| |
| LoadAndFixupServiceEntries(default_profile_); |
| } |
| |
| map<string, vector<string>> profile_frequency_data_; |
| NiceMockControl control_; |
| MockEventDispatcher dispatcher_; |
| MockMetrics metrics_; |
| MockTime time_; |
| StrictMock<MockManager> manager_; |
| WiFiProvider provider_; |
| scoped_refptr<MockProfile> default_profile_; |
| scoped_refptr<MockProfile> user_profile_; |
| StrictMock<MockStore> default_profile_storage_; |
| StrictMock<MockStore> user_profile_storage_; |
| int storage_entry_index_; // shared across profiles |
| }; |
| |
| MATCHER(TypeWiFiPropertyMatch, "") { |
| return |
| arg.bool_properties().empty() && |
| arg.int_properties().empty() && |
| arg.uint_properties().empty() && |
| arg.string_properties().size() == 1 && |
| arg.LookupString(kTypeProperty, "") == kTypeWifi; |
| } |
| |
| MATCHER_P(RefPtrMatch, ref, "") { |
| return ref.get() == arg.get(); |
| } |
| |
| TEST_F(WiFiProviderTest, Start) { |
| // Doesn't do anything really. Just testing for no crash. |
| EXPECT_TRUE(GetServices().empty()); |
| EXPECT_FALSE(GetRunning()); |
| provider_.Start(); |
| EXPECT_TRUE(GetServices().empty()); |
| EXPECT_TRUE(GetRunning()); |
| EXPECT_TRUE(GetServiceByEndpoint().empty()); |
| EXPECT_FALSE(provider_.disable_vht()); |
| } |
| |
| TEST_F(WiFiProviderTest, Stop) { |
| MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'), |
| kModeManaged, |
| kSecurityNone, |
| false); |
| MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'), |
| kModeManaged, |
| kSecurityNone, |
| false); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint("", "00:00:00:00:00:00", 0, 0); |
| AddEndpointToService(service0, endpoint); |
| |
| EXPECT_EQ(2, GetServices().size()); |
| EXPECT_FALSE(GetServiceByEndpoint().empty()); |
| EXPECT_CALL(*service0, ResetWiFi()).Times(1); |
| EXPECT_CALL(*service1, ResetWiFi()).Times(1); |
| EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1); |
| EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service1))).Times(1); |
| provider_.Stop(); |
| // Verify now, so it's clear that this happened as a result of the call |
| // above, and not anything in the destructor(s). |
| Mock::VerifyAndClearExpectations(service0); |
| Mock::VerifyAndClearExpectations(service1); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_TRUE(GetServices().empty()); |
| EXPECT_TRUE(GetServiceByEndpoint().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileWithNoGroups) { |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillOnce(Return(set<string>())); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSSID) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, nullptr, kModeManaged, kSecurityNone, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySSID) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "", kModeManaged, kSecurityNone, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingMode) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", nullptr, kSecurityNone, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptyMode) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", "", kSecurityNone, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSecurity) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", kModeManaged, nullptr, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySecurity) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", kModeManaged, "", false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingHidden) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", kModeManaged, kSecurityNone, false, false)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileSingle) { |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, |
| kSSID.c_str(), kModeManaged, kSecurityNone, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 1, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2); |
| CreateServicesFromProfile(default_profile_); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| const WiFiServiceRefPtr service = GetServices().front(); |
| const string service_ssid(service->ssid().begin(), service->ssid().end()); |
| EXPECT_EQ(kSSID, service_ssid); |
| EXPECT_EQ(kModeManaged, service->mode()); |
| EXPECT_TRUE(service->IsSecurityMatch(kSecurityNone)); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| CreateServicesFromProfile(default_profile_); |
| EXPECT_EQ(1, GetServices().size()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenButConnected) { |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, |
| kSSID.c_str(), kModeManaged, kSecurityNone, true, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 1, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2); |
| CreateServicesFromProfile(default_profile_); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| CreateServicesFromProfile(default_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenNotConnected) { |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert(AddServiceToProfileStorage(default_profile_, |
| kSSID.c_str(), kModeManaged, kSecurityNone, true, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(manager_, RequestScan(Device::kProgressiveScan, |
| kTypeWifi, _)).Times(1); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 1, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)).Times(2); |
| CreateServicesFromProfile(default_profile_); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0); |
| EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| CreateServicesFromProfile(default_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateTwoServices) { |
| set<string> groups; |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", kModeManaged, kSecurityNone, false, true)); |
| groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "bar", kModeManaged, kSecurityNone, true, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .Times(2) |
| .WillRepeatedly( |
| Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(manager_, RequestScan(_, kTypeWifi, _)).Times(0); |
| EXPECT_CALL(metrics_, SendToUMA( |
| Metrics::kMetricRememberedWiFiNetworkCount, |
| 2, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(default_profile_); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_EQ(2, GetServices().size()); |
| } |
| |
| TEST_F(WiFiProviderTest, ServiceSourceStats) { |
| set<string> default_profile_groups; |
| default_profile_groups.insert( |
| AddServiceToProfileStorage( |
| default_profile_, "foo", kModeManaged, kSecurityWpa, false, true)); |
| EXPECT_CALL(default_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(default_profile_groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToDefaultProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| // Processing default profile does not generate UMA metrics. |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount."), |
| _, _, _, _)) |
| .Times(0); |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount."), |
| _, _, _, _)) |
| .Times(0); |
| CreateServicesFromProfile(default_profile_); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| set<string> user_profile_groups; |
| user_profile_groups.insert( |
| AddServiceToProfileStorage( |
| user_profile_, "bar", kModeManaged, kSecurityRsn, false, true)); |
| EXPECT_CALL(user_profile_storage_, |
| GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(user_profile_groups)); |
| EXPECT_CALL(manager_, RegisterService(_)) |
| .WillOnce(Invoke(this, &WiFiProviderTest::BindServiceToUserProfile)); |
| EXPECT_CALL(manager_, IsServiceEphemeral(_)).WillRepeatedly(Return(false)); |
| // Processing user profile generates metrics for both, default profile, |
| // and user profile. |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount."), |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)) |
| .Times(3); // none, wep, 802.1x |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount."), |
| 0, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)) |
| .Times(3); // none, wep, 802.1x |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedSystemNetworkCount.psk"), |
| 1, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| EXPECT_CALL(metrics_, SendToUMA( |
| StartsWith("Network.Shill.WiFi.RememberedUserNetworkCount.psk"), |
| 1, |
| Metrics::kMetricRememberedWiFiNetworkCountMin, |
| Metrics::kMetricRememberedWiFiNetworkCountMax, |
| Metrics::kMetricRememberedWiFiNetworkCountNumBuckets)); |
| CreateServicesFromProfile(user_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceEmptyMode) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", "", kSecurityNone, |
| false, false, &error).get()); |
| EXPECT_EQ(Error::kNotSupported, error.type()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceNoMode) { |
| Error error; |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_TRUE(GetService("foo", nullptr, kSecurityNone, |
| false, false, &error).get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceBadMode) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", "BogoMesh", |
| kSecurityNone, |
| false, false, &error).get()); |
| EXPECT_EQ(Error::kNotSupported, error.type()); |
| EXPECT_EQ("service mode is unsupported", error.message()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceNoSSID) { |
| Error error; |
| EXPECT_FALSE(GetService(nullptr, kModeManaged, |
| kSecurityNone, false, false, |
| &error).get()); |
| EXPECT_EQ(Error::kInvalidArguments, error.type()); |
| EXPECT_EQ("must specify SSID", error.message()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceEmptySSID) { |
| Error error; |
| EXPECT_FALSE(GetService("", kModeManaged, |
| kSecurityNone, false, false, |
| &error).get()); |
| EXPECT_EQ(Error::kInvalidNetworkName, error.type()); |
| EXPECT_EQ("SSID is too short", error.message()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceLongSSID) { |
| Error error; |
| string ssid(IEEE_80211::kMaxSSIDLen + 1, '0'); |
| EXPECT_FALSE(GetService(ssid.c_str(), kModeManaged, |
| kSecurityNone, false, false, |
| &error).get()); |
| EXPECT_EQ(Error::kInvalidNetworkName, error.type()); |
| EXPECT_EQ("SSID is too long", error.message()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceJustLongEnoughSSID) { |
| Error error; |
| string ssid(IEEE_80211::kMaxSSIDLen, '0'); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_TRUE(GetService(ssid.c_str(), kModeManaged, |
| kSecurityNone, false, false, |
| &error)); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceBadSecurty) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", kModeManaged, |
| "pig-80211", false, false, |
| &error)); |
| EXPECT_EQ(Error::kNotSupported, error.type()); |
| EXPECT_EQ("security mode is unsupported", error.message()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceMinimal) { |
| Error error; |
| const string kSSID("foo"); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| WiFiServiceRefPtr service = GetService(kSSID.c_str(), kModeManaged, |
| nullptr, false, false, &error); |
| EXPECT_TRUE(service.get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| const string service_ssid(service->ssid().begin(), service->ssid().end()); |
| EXPECT_EQ(kSSID, service_ssid); |
| EXPECT_EQ(kModeManaged, service->mode()); |
| |
| // These two should be set to their default values if not specified. |
| EXPECT_TRUE(service->IsSecurityMatch(kSecurityNone)); |
| EXPECT_TRUE(service->hidden_ssid()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceFullySpecified) { |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| const string kSSID("bar"); |
| Error error; |
| WiFiServiceRefPtr service0 = GetService( |
| kSSID.c_str(), kModeManaged, kSecurityPsk, false, true, &error); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_TRUE(error.IsSuccess()); |
| const string service_ssid(service0->ssid().begin(), service0->ssid().end()); |
| EXPECT_EQ(kSSID, service_ssid); |
| EXPECT_EQ(kModeManaged, service0->mode()); |
| EXPECT_TRUE(service0->IsSecurityMatch(kSecurityPsk)); |
| EXPECT_FALSE(service0->hidden_ssid()); |
| |
| // Getting the same service parameters (even with a different hidden |
| // parameter) should return the same service. |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| WiFiServiceRefPtr service1 = |
| GetService(kSSID.c_str(), kModeManaged, kSecurityPsk, true, true, &error); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(service0.get(), service1.get()); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| // Getting the same ssid with different other parameters should return |
| // a different service. |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| WiFiServiceRefPtr service2 = GetService( |
| kSSID.c_str(), kModeManaged, kSecurityNone, true, true, &error); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_NE(service0.get(), service2.get()); |
| EXPECT_EQ(2, GetServices().size()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceByHexSsid) { |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| const string kSSID("bar"); |
| const string kHexSsid(base::HexEncode(kSSID.c_str(), kSSID.length())); |
| |
| KeyValueStore args; |
| args.SetString(kTypeProperty, kTypeWifi); |
| args.SetString(kWifiHexSsid, kHexSsid); |
| args.SetString(kSecurityProperty, kSecurityPsk); |
| args.SetBool(kWifiHiddenSsid, false); |
| |
| Error error; |
| WiFiServiceRefPtr service = GetWiFiService(args, &error); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_TRUE(error.IsSuccess()); |
| const string service_ssid(service->ssid().begin(), service->ssid().end()); |
| EXPECT_EQ(kSSID, service_ssid); |
| EXPECT_EQ(kModeManaged, service->mode()); |
| EXPECT_TRUE(service->IsSecurityMatch(kSecurityPsk)); |
| EXPECT_FALSE(service->hidden_ssid()); |
| |
| |
| // While here, make sure FindSimilarService also supports kWifiHexSsid. |
| Error find_error; |
| ServiceRefPtr find_service = provider_.FindSimilarService(args, &find_error); |
| EXPECT_TRUE(find_error.IsSuccess()); |
| EXPECT_EQ(service.get(), find_service.get()); |
| } |
| |
| TEST_F(WiFiProviderTest, FindSimilarService) { |
| // Since CreateTemporyService uses exactly the same validation as |
| // GetService, don't bother with testing invalid parameters. |
| const string kSSID("foo"); |
| KeyValueStore args; |
| SetServiceParameters( |
| kSSID.c_str(), kModeManaged, kSecurityNone, |
| true, true, &args); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| Error get_service_error; |
| WiFiServiceRefPtr service = GetWiFiService(args, &get_service_error); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| { |
| Error error; |
| ServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(service.get(), find_service.get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| args.SetBool(kWifiHiddenSsid, false); |
| |
| { |
| Error error; |
| ServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(service.get(), find_service.get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| args.SetString(kSecurityProperty, kSecurityWpa); |
| |
| { |
| Error error; |
| ServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(nullptr, find_service.get()); |
| EXPECT_EQ(Error::kNotFound, error.type()); |
| } |
| } |
| |
| TEST_F(WiFiProviderTest, CreateTemporaryService) { |
| // Since CreateTemporyService uses exactly the same validation as |
| // GetService, don't bother with testing invalid parameters. |
| const string kSSID("foo"); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| Error error; |
| WiFiServiceRefPtr service0 = GetService( |
| kSSID.c_str(), kModeManaged, kSecurityNone, true, true, &error); |
| EXPECT_EQ(1, GetServices().size()); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| ServiceRefPtr service1 = |
| CreateTemporaryService(kSSID.c_str(), kModeManaged, |
| kSecurityNone, true, true, &error); |
| |
| // Test that a new service was created, but not registered with the |
| // manager or added to the provider's service list. |
| EXPECT_EQ(1, GetServices().size()); |
| EXPECT_TRUE(service0 != service1); |
| EXPECT_TRUE(service1->HasOneRef()); |
| } |
| |
| TEST_F(WiFiProviderTest, FindServiceWPA) { |
| const string kSSID("an_ssid"); |
| Error error; |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| WiFiServiceRefPtr service = GetService( |
| kSSID.c_str(), kModeManaged, kSecurityRsn, false, true, &error); |
| ASSERT_TRUE(service); |
| const vector<uint8_t> ssid_bytes(kSSID.begin(), kSSID.end()); |
| WiFiServiceRefPtr wpa_service(FindService(ssid_bytes, kModeManaged, |
| kSecurityWpa)); |
| EXPECT_TRUE(wpa_service); |
| EXPECT_EQ(service.get(), wpa_service.get()); |
| WiFiServiceRefPtr rsn_service(FindService(ssid_bytes, kModeManaged, |
| kSecurityRsn)); |
| EXPECT_TRUE(rsn_service.get()); |
| EXPECT_EQ(service.get(), rsn_service.get()); |
| WiFiServiceRefPtr psk_service(FindService(ssid_bytes, kModeManaged, |
| kSecurityPsk)); |
| EXPECT_EQ(service.get(), psk_service.get()); |
| WiFiServiceRefPtr wep_service(FindService(ssid_bytes, kModeManaged, |
| kSecurityWep)); |
| EXPECT_TRUE(service.get() != wep_service.get()); |
| EXPECT_EQ(nullptr, wep_service.get()); |
| } |
| |
| TEST_F(WiFiProviderTest, FindServiceForEndpoint) { |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| Error error; |
| const string kSSID("an_ssid"); |
| WiFiServiceRefPtr service = GetService( |
| kSSID.c_str(), kModeManaged, kSecurityNone, false, true, &error); |
| ASSERT_TRUE(service); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint(kSSID, "00:00:00:00:00:00", 0, 0); |
| WiFiServiceRefPtr endpoint_service = |
| provider_.FindServiceForEndpoint(endpoint); |
| // Just because a matching service exists, we shouldn't necessarily have |
| // it returned. We will test that this function returns the correct |
| // service if the endpoint is added below. |
| EXPECT_EQ(nullptr, endpoint_service.get()); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointAdded) { |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| EXPECT_FALSE(FindService(ssid0_bytes, kModeManaged, |
| kSecurityNone)); |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, UpdateService(_)).Times(1); |
| provider_.OnEndpointAdded(endpoint0); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(1, GetServices().size()); |
| WiFiServiceRefPtr service0(FindService(ssid0_bytes, kModeManaged, |
| kSecurityNone)); |
| EXPECT_TRUE(service0); |
| EXPECT_TRUE(service0->HasEndpoints()); |
| EXPECT_EQ(1, GetServiceByEndpoint().size()); |
| WiFiServiceRefPtr endpoint_service = |
| provider_.FindServiceForEndpoint(endpoint0); |
| EXPECT_EQ(service0.get(), endpoint_service.get()); |
| |
| WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| provider_.OnEndpointAdded(endpoint1); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| EXPECT_FALSE(FindService(ssid1_bytes, kModeManaged, |
| kSecurityNone)); |
| WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", |
| 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, UpdateService(_)).Times(1); |
| provider_.OnEndpointAdded(endpoint2); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(2, GetServices().size()); |
| |
| WiFiServiceRefPtr service1(FindService(ssid1_bytes, kModeManaged, |
| kSecurityNone)); |
| EXPECT_TRUE(service1); |
| EXPECT_TRUE(service1->HasEndpoints()); |
| EXPECT_TRUE(service1 != service0); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointAddedWithSecurity) { |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| EXPECT_FALSE(FindService(ssid0_bytes, kModeManaged, |
| kSecurityNone)); |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| endpoint0->set_security_mode(kSecurityRsn); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, UpdateService(_)).Times(1); |
| provider_.OnEndpointAdded(endpoint0); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(1, GetServices().size()); |
| WiFiServiceRefPtr service0(FindService(ssid0_bytes, kModeManaged, |
| kSecurityWpa)); |
| EXPECT_TRUE(service0); |
| EXPECT_TRUE(service0->HasEndpoints()); |
| EXPECT_EQ(kSecurityPsk, service0->security_); |
| |
| WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0); |
| endpoint1->set_security_mode(kSecurityWpa); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| provider_.OnEndpointAdded(endpoint1); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| EXPECT_FALSE(FindService(ssid1_bytes, kModeManaged, |
| kSecurityNone)); |
| WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0); |
| endpoint2->set_security_mode(kSecurityWpa); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, UpdateService(_)).Times(1); |
| provider_.OnEndpointAdded(endpoint2); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_EQ(2, GetServices().size()); |
| |
| WiFiServiceRefPtr service1(FindService(ssid1_bytes, kModeManaged, |
| kSecurityRsn)); |
| EXPECT_TRUE(service1); |
| EXPECT_TRUE(service1->HasEndpoints()); |
| EXPECT_EQ(kSecurityPsk, service1->security_); |
| EXPECT_TRUE(service1 != service0); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointAddedWhileStopped) { |
| // If we don't call provider_.Start(), OnEndpointAdded should have no effect. |
| const string ssid("an_ssid"); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(_)).Times(0); |
| provider_.OnEndpointAdded(endpoint); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointAddedToMockService) { |
| // The previous test allowed the provider to create its own "real" |
| // WiFiServices, which hides some of what we can test with mock |
| // services. Re-do an add-endpoint operation by seeding the provider |
| // with a mock service. |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_EQ(service0.get(), FindService(ssid0_bytes, |
| kModeManaged, |
| kSecurityNone).get()); |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint0))).Times(1); |
| EXPECT_CALL(*service1, AddEndpoint(_)).Times(0); |
| provider_.OnEndpointAdded(endpoint0); |
| Mock::VerifyAndClearExpectations(&manager_); |
| Mock::VerifyAndClearExpectations(service0); |
| Mock::VerifyAndClearExpectations(service1); |
| |
| WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| EXPECT_CALL(*service0, AddEndpoint(RefPtrMatch(endpoint1))).Times(1); |
| EXPECT_CALL(*service1, AddEndpoint(_)).Times(0); |
| provider_.OnEndpointAdded(endpoint1); |
| Mock::VerifyAndClearExpectations(&manager_); |
| Mock::VerifyAndClearExpectations(service0); |
| Mock::VerifyAndClearExpectations(service1); |
| |
| WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service1))).Times(1); |
| EXPECT_CALL(*service0, AddEndpoint(_)).Times(0); |
| EXPECT_CALL(*service1, AddEndpoint(RefPtrMatch(endpoint2))).Times(1); |
| provider_.OnEndpointAdded(endpoint2); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointRemoved) { |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_EQ(2, GetServices().size()); |
| |
| // Remove the last endpoint of a non-remembered service. |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| AddEndpointToService(service0, endpoint0); |
| EXPECT_EQ(1, GetServiceByEndpoint().size()); |
| |
| EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1); |
| EXPECT_CALL(*service1, RemoveEndpoint(_)).Times(0); |
| EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(false)); |
| EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(false)); |
| EXPECT_CALL(*service0, ResetWiFi()).Times(1); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(0); |
| EXPECT_CALL(manager_, DeregisterService(RefPtrMatch(service0))).Times(1); |
| provider_.OnEndpointRemoved(endpoint0); |
| // Verify now, so it's clear that this happened as a result of the call |
| // above, and not anything in the destructor(s). |
| Mock::VerifyAndClearExpectations(&manager_); |
| Mock::VerifyAndClearExpectations(service0); |
| Mock::VerifyAndClearExpectations(service1); |
| EXPECT_EQ(1, GetServices().size()); |
| EXPECT_EQ(service1.get(), GetServices().front().get()); |
| EXPECT_TRUE(GetServiceByEndpoint().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointRemovedButHasEndpoints) { |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| // Remove an endpoint of a non-remembered service. |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| AddEndpointToService(service0, endpoint0); |
| EXPECT_EQ(1, GetServiceByEndpoint().size()); |
| |
| EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1); |
| EXPECT_CALL(*service0, HasEndpoints()).WillOnce(Return(true)); |
| EXPECT_CALL(*service0, IsRemembered()).WillRepeatedly(Return(false)); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| EXPECT_CALL(*service0, ResetWiFi()).Times(0); |
| EXPECT_CALL(manager_, DeregisterService(_)).Times(0); |
| provider_.OnEndpointRemoved(endpoint0); |
| // Verify now, so it's clear that this happened as a result of the call |
| // above, and not anything in the destructor(s). |
| Mock::VerifyAndClearExpectations(&manager_); |
| Mock::VerifyAndClearExpectations(service0); |
| EXPECT_EQ(1, GetServices().size()); |
| EXPECT_TRUE(GetServiceByEndpoint().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointRemovedButIsRemembered) { |
| provider_.Start(); |
| const string ssid0("an_ssid"); |
| const vector<uint8_t> ssid0_bytes(ssid0.begin(), ssid0.end()); |
| MockWiFiServiceRefPtr service0 = AddMockService(ssid0_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| // Remove the last endpoint of a remembered service. |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| AddEndpointToService(service0, endpoint0); |
| EXPECT_EQ(1, GetServiceByEndpoint().size()); |
| |
| EXPECT_CALL(*service0, RemoveEndpoint(RefPtrMatch(endpoint0))).Times(1); |
| EXPECT_CALL(*service0, HasEndpoints()).WillRepeatedly(Return(false)); |
| EXPECT_CALL(*service0, IsRemembered()).WillOnce(Return(true)); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(service0))).Times(1); |
| EXPECT_CALL(*service0, ResetWiFi()).Times(0); |
| EXPECT_CALL(manager_, DeregisterService(_)).Times(0); |
| provider_.OnEndpointRemoved(endpoint0); |
| // Verify now, so it's clear that this happened as a result of the call |
| // above, and not anything in the destructor(s). |
| Mock::VerifyAndClearExpectations(&manager_); |
| Mock::VerifyAndClearExpectations(service0); |
| EXPECT_EQ(1, GetServices().size()); |
| EXPECT_TRUE(GetServiceByEndpoint().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointRemovedWhileStopped) { |
| // If we don't call provider_.Start(), OnEndpointRemoved should not |
| // cause a crash even if a service matching the endpoint does not exist. |
| const string ssid("an_ssid"); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0); |
| provider_.OnEndpointRemoved(endpoint); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointUpdated) { |
| provider_.Start(); |
| |
| // Create an endpoint and associate it with a mock service. |
| const string ssid("an_ssid"); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0); |
| |
| const vector<uint8_t> ssid_bytes(ssid.begin(), ssid.end()); |
| MockWiFiServiceRefPtr open_service = AddMockService(ssid_bytes, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_CALL(*open_service, AddEndpoint(RefPtrMatch(endpoint))); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(open_service))); |
| provider_.OnEndpointAdded(endpoint); |
| Mock::VerifyAndClearExpectations(open_service); |
| |
| // WiFiProvider is running and endpoint matches this service. |
| EXPECT_CALL(*open_service, NotifyEndpointUpdated(RefPtrMatch(endpoint))); |
| EXPECT_CALL(*open_service, AddEndpoint(_)).Times(0); |
| provider_.OnEndpointUpdated(endpoint); |
| Mock::VerifyAndClearExpectations(open_service); |
| |
| // If the endpoint is changed in a way that causes it to match a different |
| // service, the provider should transfer the endpoint from one service to |
| // the other. |
| MockWiFiServiceRefPtr rsn_service = AddMockService(ssid_bytes, |
| kModeManaged, |
| kSecurityRsn, |
| false); |
| EXPECT_CALL(*open_service, RemoveEndpoint(RefPtrMatch(endpoint))); |
| // We are playing out a scenario where the open service is not removed |
| // since it still claims to have more endpoints remaining. |
| EXPECT_CALL(*open_service, HasEndpoints()).WillOnce(Return(true)); |
| EXPECT_CALL(*rsn_service, AddEndpoint(RefPtrMatch(endpoint))); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(open_service))); |
| EXPECT_CALL(manager_, UpdateService(RefPtrMatch(rsn_service))); |
| endpoint->set_security_mode(kSecurityRsn); |
| provider_.OnEndpointUpdated(endpoint); |
| } |
| |
| TEST_F(WiFiProviderTest, OnEndpointUpdatedWhileStopped) { |
| // If we don't call provider_.Start(), OnEndpointUpdated should not |
| // cause a crash even if a service matching the endpoint does not exist. |
| const string ssid("an_ssid"); |
| WiFiEndpointRefPtr endpoint = MakeEndpoint(ssid, "00:00:00:00:00:00", 0, 0); |
| provider_.OnEndpointUpdated(endpoint); |
| } |
| |
| TEST_F(WiFiProviderTest, OnServiceUnloaded) { |
| // This function should never unregister services itself -- the Manager |
| // will automatically deregister the service if OnServiceUnloaded() |
| // returns true (via WiFiService::Unload()). |
| EXPECT_CALL(manager_, DeregisterService(_)).Times(0); |
| |
| MockWiFiServiceRefPtr service = AddMockService(vector<uint8_t>(1, '0'), |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_EQ(1, GetServices().size()); |
| EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(true)); |
| EXPECT_CALL(*service, ResetWiFi()).Times(0); |
| EXPECT_FALSE(provider_.OnServiceUnloaded(service)); |
| EXPECT_EQ(1, GetServices().size()); |
| Mock::VerifyAndClearExpectations(service); |
| |
| EXPECT_CALL(*service, HasEndpoints()).WillOnce(Return(false)); |
| EXPECT_CALL(*service, ResetWiFi()).Times(1); |
| EXPECT_TRUE(provider_.OnServiceUnloaded(service)); |
| // Verify now, so it's clear that this happened as a result of the call |
| // above, and not anything in the destructor(s). |
| Mock::VerifyAndClearExpectations(service); |
| EXPECT_TRUE(GetServices().empty()); |
| |
| Mock::VerifyAndClearExpectations(&manager_); |
| } |
| |
| TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesDefaultProfile) { |
| // We test LoadAndFixupServiceEntries indirectly since it calls a static |
| // method in WiFiService. |
| EXPECT_CALL(metrics_, SendEnumToUMA( |
| "Network.Shill.Wifi.ServiceFixupEntries", |
| Metrics::kMetricServiceFixupDefaultProfile, |
| Metrics::kMetricServiceFixupMax)).Times(1); |
| EXPECT_CALL(default_profile_storage_, Flush()).Times(1); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone); |
| EXPECT_CALL(default_profile_storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(default_profile_storage_, |
| SetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(default_profile_storage_, GetGroups()) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Return(false)); |
| LoadAndFixupServiceEntries(default_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesUserProfile) { |
| EXPECT_CALL(metrics_, SendEnumToUMA( |
| "Network.Shill.Wifi.ServiceFixupEntries", |
| Metrics::kMetricServiceFixupUserProfile, |
| Metrics::kMetricServiceFixupMax)).Times(1); |
| EXPECT_CALL(user_profile_storage_, Flush()).Times(1); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone); |
| EXPECT_CALL(user_profile_storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(user_profile_storage_, |
| SetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(user_profile_storage_, GetGroups()) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(user_profile_storage_, GetStringList(_, _, _)).Times(0); |
| LoadAndFixupServiceEntries(user_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo) { |
| EXPECT_CALL(metrics_, SendEnumToUMA(_, _, _)).Times(0); |
| EXPECT_CALL(default_profile_storage_, Flush()).Times(0); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone); |
| EXPECT_CALL(default_profile_storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Return(false)); |
| LoadAndFixupServiceEntries(default_profile_); |
| } |
| |
| TEST_F(WiFiProviderTest, GetHiddenSSIDList) { |
| EXPECT_TRUE(provider_.GetHiddenSSIDList().empty()); |
| const vector<uint8_t> ssid0(1, '0'); |
| AddMockService(ssid0, kModeManaged, kSecurityNone, false); |
| EXPECT_TRUE(provider_.GetHiddenSSIDList().empty()); |
| |
| const vector<uint8_t> ssid1(1, '1'); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1, |
| kModeManaged, |
| kSecurityNone, |
| true); |
| EXPECT_CALL(*service1, IsRemembered()).WillRepeatedly(Return(false)); |
| EXPECT_TRUE(provider_.GetHiddenSSIDList().empty()); |
| |
| const vector<uint8_t> ssid2(1, '2'); |
| MockWiFiServiceRefPtr service2 = AddMockService(ssid2, |
| kModeManaged, |
| kSecurityNone, |
| true); |
| EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true)); |
| ByteArrays ssid_list = provider_.GetHiddenSSIDList(); |
| |
| EXPECT_EQ(1, ssid_list.size()); |
| EXPECT_TRUE(ssid_list[0] == ssid2); |
| |
| const vector<uint8_t> ssid3(1, '3'); |
| MockWiFiServiceRefPtr service3 = AddMockService(ssid3, |
| kModeManaged, |
| kSecurityNone, |
| false); |
| EXPECT_CALL(*service2, IsRemembered()).WillRepeatedly(Return(true)); |
| |
| ssid_list = provider_.GetHiddenSSIDList(); |
| EXPECT_EQ(1, ssid_list.size()); |
| EXPECT_TRUE(ssid_list[0] == ssid2); |
| |
| const vector<uint8_t> ssid4(1, '4'); |
| MockWiFiServiceRefPtr service4 = AddMockService(ssid4, |
| kModeManaged, |
| kSecurityNone, |
| true); |
| EXPECT_CALL(*service4, IsRemembered()).WillRepeatedly(Return(true)); |
| |
| ssid_list = provider_.GetHiddenSSIDList(); |
| EXPECT_EQ(2, ssid_list.size()); |
| EXPECT_TRUE(ssid_list[0] == ssid2); |
| EXPECT_TRUE(ssid_list[1] == ssid4); |
| } |
| |
| TEST_F(WiFiProviderTest, StringListToFrequencyMap) { |
| vector<string> strings; |
| BuildFreqCountStrings(&strings); |
| WiFiProvider::ConnectFrequencyMap frequencies_result; |
| time_t days = WiFiProvider::StringListToFrequencyMap(strings, |
| &frequencies_result); |
| |
| WiFiProvider::ConnectFrequencyMap frequencies_expect; |
| BuildFreqCountMap(&frequencies_expect); |
| EXPECT_THAT(frequencies_result, ContainerEq(frequencies_expect)); |
| EXPECT_EQ(days, kTestDays); |
| } |
| |
| TEST_F(WiFiProviderTest, StringListToFrequencyMapEmpty) { |
| vector<string> strings; |
| strings.push_back("@50"); |
| WiFiProvider::ConnectFrequencyMap frequencies_result; |
| time_t days = WiFiProvider::StringListToFrequencyMap(strings, |
| &frequencies_result); |
| EXPECT_TRUE(frequencies_result.empty()); |
| EXPECT_EQ(days, 50); |
| } |
| |
| TEST_F(WiFiProviderTest, FrequencyMapToStringList) { |
| WiFiProvider::ConnectFrequencyMap frequencies; |
| BuildFreqCountMap(&frequencies); |
| vector<string> strings_result; |
| WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies, |
| &strings_result); |
| |
| vector<string> strings_expect; |
| BuildFreqCountStrings(&strings_expect); |
| EXPECT_THAT(strings_result, ContainerEq(strings_expect)); |
| } |
| |
| TEST_F(WiFiProviderTest, FrequencyMapToStringListEmpty) { |
| WiFiProvider::ConnectFrequencyMap frequencies; |
| vector<string> strings_result; |
| WiFiProvider::FrequencyMapToStringList(kTestDays, frequencies, |
| &strings_result); |
| EXPECT_EQ(1, strings_result.size()); |
| EXPECT_EQ(*strings_result.begin(), "@20"); |
| } |
| |
| TEST_F(WiFiProviderTest, FrequencyMapBasicAging) { |
| const time_t kThisWeek = kFirstWeek + |
| WiFiProvider::kWeeksToKeepFrequencyCounts - 1; |
| LoadConnectCountByFrequency(kThisWeek * kSecondsPerWeek); |
| |
| // Make sure we have data for all 3 blocks. |
| WiFiProvider::ConnectFrequencyMap expected; |
| expected[5001] = 2; |
| expected[5002] = 2; |
| expected[6001] = 1; |
| expected[6002] = 2; |
| expected[7001] = 1; |
| expected[7002] = 2; |
| EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected)); |
| |
| // And, then, make sure we output the expected blocks of data. |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 0)]))); |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 1)]))); |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 2)]))); |
| vector<string> frequencies; |
| frequencies.push_back(base::StringPrintf("@%" PRIu64, |
| static_cast<uint64_t>(kThisWeek))); |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, Eq(frequencies))).Times(0); |
| Save(); |
| } |
| |
| TEST_F(WiFiProviderTest, FrequencyMapAgingIllegalDay) { |
| provider_.time_ = &time_; |
| const time_t kThisWeek = kFirstWeek + |
| WiFiProvider::kWeeksToKeepFrequencyCounts - 1; |
| const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek; |
| EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds)); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", kTypeWifi, kModeManaged, kSecurityNone); |
| EXPECT_CALL(default_profile_storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| // Instead of block[1], return a block without the date. |
| EXPECT_CALL(default_profile_storage_, GetGroups()).WillOnce(Return(groups)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetIllegalDayStringList)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(default_profile_storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| |
| LoadAndFixupServiceEntries(default_profile_); |
| |
| // Verify that the received information only includes block[0] and block[2]. |
| WiFiProvider::ConnectFrequencyMap expected; |
| expected[5001] = 1; |
| expected[5002] = 2; |
| expected[7001] = 1; |
| expected[7002] = 2; |
| EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected)); |
| |
| // And, then, make sure we output the expected blocks of data. |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 0)]))); |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 1)]))). |
| Times(0); |
| EXPECT_CALL( |
| default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf( |
| "%s%d", WiFiProvider::kStorageFrequencies, 2)]))); |
| vector<string> frequencies; |
| frequencies.push_back(base::StringPrintf("@%" PRIu64, |
| static_cast<uint64_t>(kThisWeek))); |
| EXPECT_CALL(default_profile_storage_, |
| SetStringList(WiFiProvider::kStorageId, _, Eq(frequencies))) |
| .Times(0); |
| Save(); |
| } |
| |
| TEST_F(WiFiProviderTest, IncrementConnectCount) { |
| const time_t kThisWeek = kFirstWeek + |
| WiFiProvider::kWeeksToKeepFrequencyCounts - 1; |
| const time_t kThisWeekSeconds = kThisWeek * kSecondsPerWeek; |
| LoadConnectCountByFrequency(kThisWeekSeconds); |
| |
| EXPECT_CALL(time_, GetSecondsSinceEpoch()).WillOnce(Return(kThisWeekSeconds)); |
| EXPECT_CALL(manager_, UpdateWiFiProvider()); |
| EXPECT_CALL(metrics_, SendToUMA(Metrics::kMetricFrequenciesConnectedEver, |
| _, _, _, _)); |
| time_t newest_week_at_start = |
| provider_.connect_count_by_frequency_dated_.crbegin()->first; |
| provider_.IncrementConnectCount(6002); |
| |
| // Make sure we have data for all 3 blocks. |
| WiFiProvider::ConnectFrequencyMap expected; |
| expected[5001] = 2; |
| expected[5002] = 2; |
| expected[6001] = 1; |
| expected[6002] = 3; |
| expected[7001] = 1; |
| expected[7002] = 2; |
| EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected)); |
| // Make sure we didn't delete the oldest block. |
| EXPECT_TRUE(ContainsKey(provider_.connect_count_by_frequency_dated_, |
| kFirstWeek)); |
| // Make sure we didn't create a new block. |
| time_t newest_week_at_end = |
| provider_.connect_count_by_frequency_dated_.crbegin()->first; |
| EXPECT_EQ(newest_week_at_start, newest_week_at_end); |
| } |
| |
| TEST_F(WiFiProviderTest, IncrementConnectCountCreateNew) { |
| time_t this_week = kFirstWeek + WiFiProvider::kWeeksToKeepFrequencyCounts - 1; |
| LoadConnectCountByFrequency(this_week * kSecondsPerWeek); |
| |
| this_week += 2; |
| EXPECT_CALL(time_, GetSecondsSinceEpoch()). |
| WillOnce(Return(this_week * kSecondsPerWeek)); |
| EXPECT_CALL(manager_, UpdateWiFiProvider()); |
| EXPECT_CALL(metrics_, SendToUMA(Metrics::kMetricFrequenciesConnectedEver, |
| _, _, _, _)); |
| time_t newest_week_at_start = |
| provider_.connect_count_by_frequency_dated_.crbegin()->first; |
| provider_.IncrementConnectCount(6001); |
| |
| // Make sure we have data for newest 2 blocks (only). |
| WiFiProvider::ConnectFrequencyMap expected; |
| expected[5001] = 1; |
| expected[6001] = 2; |
| expected[6002] = 2; |
| expected[7001] = 1; |
| expected[7002] = 2; |
| EXPECT_THAT(provider_.connect_count_by_frequency_, ContainerEq(expected)); |
| // Verify that the oldest block is gone. |
| EXPECT_FALSE(ContainsKey(provider_.connect_count_by_frequency_dated_, |
| kFirstWeek)); |
| // Make sure we created a new block and that it is for the current week. |
| time_t newest_week_at_end = |
| provider_.connect_count_by_frequency_dated_.crbegin()->first; |
| EXPECT_NE(newest_week_at_start, newest_week_at_end); |
| EXPECT_TRUE(ContainsKey(provider_.connect_count_by_frequency_dated_, |
| this_week)); |
| } |
| |
| TEST_F(WiFiProviderTest, ReportAutoConnectableServices) { |
| MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'), |
| kModeManaged, |
| kSecurityNone, |
| false); |
| MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'), |
| kModeManaged, |
| kSecurityNone, |
| false); |
| service0->EnableAndRetainAutoConnect(); |
| service0->SetConnectable(true); |
| service1->EnableAndRetainAutoConnect(); |
| service1->SetConnectable(true); |
| |
| EXPECT_CALL(*service0, IsAutoConnectable(_)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(*service1, IsAutoConnectable(_)) |
| .WillRepeatedly(Return(false)); |
| |
| // With 1 auto connectable service. |
| EXPECT_CALL(metrics_, NotifyWifiAutoConnectableServices(1)); |
| provider_.ReportAutoConnectableServices(); |
| |
| // With no auto connectable service. |
| EXPECT_CALL(metrics_, NotifyWifiAutoConnectableServices(_)).Times(0); |
| provider_.ReportAutoConnectableServices(); |
| } |
| |
| } // namespace shill |