| // 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/string_number_conversions.h> |
| #include <base/string_util.h> |
| #include <base/stringprintf.h> |
| #include <chromeos/dbus/service_constants.h> |
| #include <gtest/gtest.h> |
| |
| #include "shill/ieee80211.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_time.h" |
| #include "shill/mock_wifi_service.h" |
| #include "shill/nice_mock_control.h" |
| #include "shill/technology.h" |
| #include "shill/wifi_endpoint.h" |
| #include "shill/wpa_supplicant.h" |
| |
| using std::map; |
| using std::set; |
| using std::string; |
| using std::vector; |
| using ::testing::_; |
| using ::testing::ContainerEq; |
| using ::testing::Eq; |
| using ::testing::Invoke; |
| using ::testing::Mock; |
| using ::testing::NiceMock; |
| using ::testing::Return; |
| using ::testing::SetArgumentPointee; |
| 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_(NULL), |
| manager_(&control_, &dispatcher_, &metrics_, |
| reinterpret_cast<GLib *>(NULL)), |
| provider_(&control_, &dispatcher_, &metrics_, &manager_), |
| profile_( |
| new NiceMock<MockProfile>(&control_, &metrics_, &manager_, "")), |
| 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(*profile_, GetConstStorage()).WillRepeatedly(Return(&storage_)); |
| } |
| |
| 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; |
| } |
| |
| protected: |
| typedef scoped_refptr<MockWiFiService> MockWiFiServiceRefPtr; |
| |
| void CreateServicesFromProfile() { |
| provider_.CreateServicesFromProfile(profile_); |
| } |
| |
| void LoadAndFixupServiceEntries(bool is_default_profile) { |
| provider_.LoadAndFixupServiceEntries(&storage_, is_default_profile); |
| } |
| |
| void Save() { |
| provider_.Save(&storage_); |
| } |
| |
| const vector<WiFiServiceRefPtr> GetServices() { |
| return provider_.services_; |
| } |
| |
| const WiFiProvider::EndpointServiceMap &GetServiceByEndpoint() { |
| return provider_.service_by_endpoint_; |
| } |
| |
| bool GetRunning() { |
| return provider_.running_; |
| } |
| |
| void AddStringParameterToStorage(const string &id, |
| const string &key, |
| const string &value) { |
| EXPECT_CALL(storage_, GetString(id, key, _)) |
| .WillRepeatedly(DoAll(SetArgumentPointee<2>(value), |
| Return(true))); |
| } |
| |
| string AddServiceToStorage(const char *ssid, |
| const char *mode, |
| const char *security, |
| bool is_hidden, |
| bool provide_hidden) { |
| string id = StringToLowerASCII(base::StringPrintf("entry_%d", |
| storage_entry_index_)); |
| EXPECT_CALL(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(id, WiFiService::kStorageSSID, hex_ssid); |
| } |
| if (mode) { |
| AddStringParameterToStorage(id, WiFiService::kStorageMode, mode); |
| } |
| if (security) { |
| AddStringParameterToStorage(id, WiFiService::kStorageSecurity, security); |
| } |
| if (provide_hidden) { |
| EXPECT_CALL(storage_, GetBool(id, flimflam::kWifiHiddenSsid, _)) |
| .WillRepeatedly( |
| DoAll(SetArgumentPointee<2>(is_hidden), Return(true))); |
| } else { |
| EXPECT_CALL(storage_, GetBool(id, flimflam::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(flimflam::kTypeProperty, flimflam::kTypeWifi); |
| if (ssid) { |
| args->SetString(flimflam::kSSIDProperty, ssid); |
| } |
| if (mode) { |
| args->SetString(flimflam::kModeProperty, mode); |
| } |
| if (security) { |
| args->SetString(flimflam::kSecurityProperty, security); |
| } |
| if (provide_hidden) { |
| args->SetBool(flimflam::kWifiHiddenSsid, is_hidden); |
| } |
| } |
| |
| WiFiServiceRefPtr 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_.GetService(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 frequency, int16 signal_dbm) { |
| return WiFiEndpoint::MakeOpenEndpoint( |
| NULL, NULL, 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 freq; |
| int64 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", |
| flimflam::kTypeWifi, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone); |
| EXPECT_CALL(storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups)); |
| // Provide data for block[0] through block[2] (block[3] is empty). |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| |
| LoadAndFixupServiceEntries(true); |
| } |
| |
| map<string, vector<string>> profile_frequency_data_; |
| NiceMockControl control_; |
| MockEventDispatcher dispatcher_; |
| MockMetrics metrics_; |
| MockTime time_; |
| StrictMock<MockManager> manager_; |
| WiFiProvider provider_; |
| scoped_refptr<MockProfile> profile_; |
| StrictMock<MockStore> storage_; |
| int storage_entry_index_; |
| }; |
| |
| MATCHER(TypeWiFiPropertyMatch, "") { |
| return |
| arg.bool_properties().empty() && |
| arg.int_properties().empty() && |
| arg.uint_properties().empty() && |
| arg.string_properties().size() == 1 && |
| arg.LookupString(flimflam::kTypeProperty, "") == flimflam::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()); |
| } |
| |
| TEST_F(WiFiProviderTest, Stop) { |
| MockWiFiServiceRefPtr service0 = AddMockService(vector<uint8_t>(1, '0'), |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone, |
| false); |
| MockWiFiServiceRefPtr service1 = AddMockService(vector<uint8_t>(1, '1'), |
| flimflam::kModeManaged, |
| flimflam::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(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillOnce(Return(set<string>())); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSSID) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| NULL, flimflam::kModeManaged, flimflam::kSecurityNone, false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySSID) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "", flimflam::kModeManaged, flimflam::kSecurityNone, false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingMode) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", NULL, flimflam::kSecurityNone, false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptyMode) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", "", flimflam::kSecurityNone, false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingSecurity) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", flimflam::kModeManaged, NULL, false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileEmptySecurity) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", flimflam::kModeManaged, "", false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileMissingHidden) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", flimflam::kModeManaged, flimflam::kSecurityNone, false, false)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| CreateServicesFromProfile(); |
| EXPECT_TRUE(GetServices().empty()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileSingle) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert(AddServiceToStorage( |
| kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone, |
| false, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| CreateServicesFromProfile(); |
| 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(flimflam::kModeManaged, service->mode()); |
| EXPECT_TRUE(service->IsSecurityMatch(flimflam::kSecurityNone)); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| CreateServicesFromProfile(); |
| EXPECT_EQ(1, GetServices().size()); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenButConnected) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert(AddServiceToStorage( |
| kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone, |
| true, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0); |
| CreateServicesFromProfile(); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0); |
| CreateServicesFromProfile(); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateServicesFromProfileHiddenNotConnected) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| string kSSID("foo"); |
| groups.insert(AddServiceToStorage( |
| kSSID.c_str(), flimflam::kModeManaged, flimflam::kSecurityNone, |
| true, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(manager_, RequestScan(Device::kProgressiveScan, |
| flimflam::kTypeWifi, _)).Times(1); |
| CreateServicesFromProfile(); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| EXPECT_CALL(manager_, IsTechnologyConnected(_)).Times(0); |
| EXPECT_CALL(manager_, RequestScan(_, _, _)).Times(0); |
| CreateServicesFromProfile(); |
| } |
| |
| TEST_F(WiFiProviderTest, CreateTwoServices) { |
| string id; |
| StrictMock<MockStore> storage; |
| set<string> groups; |
| groups.insert(AddServiceToStorage( |
| "foo", flimflam::kModeManaged, flimflam::kSecurityNone, false, true)); |
| groups.insert(AddServiceToStorage( |
| "bar", flimflam::kModeManaged, flimflam::kSecurityNone, true, true)); |
| EXPECT_CALL(storage_, GetGroupsWithProperties(TypeWiFiPropertyMatch())) |
| .WillRepeatedly(Return(groups)); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(2); |
| EXPECT_CALL(manager_, IsTechnologyConnected(Technology::kWifi)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(manager_, RequestScan(_, flimflam::kTypeWifi, _)).Times(0); |
| CreateServicesFromProfile(); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_EQ(2, GetServices().size()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceEmptyMode) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", "", flimflam::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", NULL, flimflam::kSecurityNone, |
| false, false, &error).get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceBadMode) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", "BogoMesh", |
| flimflam::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(NULL, flimflam::kModeManaged, |
| flimflam::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("", flimflam::kModeManaged, |
| flimflam::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(), flimflam::kModeManaged, |
| flimflam::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(), flimflam::kModeManaged, |
| flimflam::kSecurityNone, false, false, |
| &error)); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| TEST_F(WiFiProviderTest, GetServiceBadSecurty) { |
| Error error; |
| EXPECT_FALSE(GetService("foo", flimflam::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(), flimflam::kModeManaged, |
| NULL, 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(flimflam::kModeManaged, service->mode()); |
| |
| // These two should be set to their default values if not specified. |
| EXPECT_TRUE(service->IsSecurityMatch(flimflam::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(), flimflam::kModeManaged, |
| flimflam::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(flimflam::kModeManaged, service0->mode()); |
| EXPECT_TRUE(service0->IsSecurityMatch(flimflam::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(), flimflam::kModeManaged, |
| flimflam::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(), flimflam::kModeManaged, |
| flimflam::kSecurityNone, true, true, &error); |
| Mock::VerifyAndClearExpectations(&manager_); |
| EXPECT_NE(service0.get(), service2.get()); |
| EXPECT_EQ(2, GetServices().size()); |
| } |
| |
| 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(), flimflam::kModeManaged, flimflam::kSecurityNone, |
| true, true, &args); |
| EXPECT_CALL(manager_, RegisterService(_)).Times(1); |
| Error get_service_error; |
| WiFiServiceRefPtr service = provider_.GetService(args, &get_service_error); |
| EXPECT_EQ(1, GetServices().size()); |
| |
| { |
| Error error; |
| WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(service.get(), find_service.get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| args.SetBool(flimflam::kWifiHiddenSsid, false); |
| |
| { |
| Error error; |
| WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(service.get(), find_service.get()); |
| EXPECT_TRUE(error.IsSuccess()); |
| } |
| |
| args.SetString(flimflam::kSecurityProperty, flimflam::kSecurityWpa); |
| |
| { |
| Error error; |
| WiFiServiceRefPtr find_service = provider_.FindSimilarService(args, &error); |
| EXPECT_EQ(NULL, 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(), flimflam::kModeManaged, |
| flimflam::kSecurityNone, true, true, &error); |
| EXPECT_EQ(1, GetServices().size()); |
| Mock::VerifyAndClearExpectations(&manager_); |
| |
| EXPECT_CALL(manager_, RegisterService(_)).Times(0); |
| WiFiServiceRefPtr service1 = |
| CreateTemporaryService(kSSID.c_str(), flimflam::kModeManaged, |
| flimflam::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(), flimflam::kModeManaged, flimflam::kSecurityRsn, |
| false, true, &error); |
| ASSERT_TRUE(service); |
| const vector<uint8_t> ssid_bytes(kSSID.begin(), kSSID.end()); |
| WiFiServiceRefPtr wpa_service(FindService(ssid_bytes, flimflam::kModeManaged, |
| flimflam::kSecurityWpa)); |
| EXPECT_TRUE(wpa_service); |
| EXPECT_EQ(service.get(), wpa_service.get()); |
| WiFiServiceRefPtr rsn_service(FindService(ssid_bytes, flimflam::kModeManaged, |
| flimflam::kSecurityRsn)); |
| EXPECT_TRUE(rsn_service.get()); |
| EXPECT_EQ(service.get(), rsn_service.get()); |
| WiFiServiceRefPtr psk_service(FindService(ssid_bytes, flimflam::kModeManaged, |
| flimflam::kSecurityPsk)); |
| EXPECT_EQ(service.get(), psk_service.get()); |
| WiFiServiceRefPtr wep_service(FindService(ssid_bytes, flimflam::kModeManaged, |
| flimflam::kSecurityWep)); |
| EXPECT_TRUE(service.get() != wep_service.get()); |
| EXPECT_EQ(NULL, 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(), flimflam::kModeManaged, flimflam::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(NULL, 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, flimflam::kModeManaged, |
| flimflam::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, flimflam::kModeManaged, |
| flimflam::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, flimflam::kModeManaged, |
| flimflam::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, flimflam::kModeManaged, |
| flimflam::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, flimflam::kModeManaged, |
| flimflam::kSecurityNone)); |
| WiFiEndpointRefPtr endpoint0 = MakeEndpoint(ssid0, "00:00:00:00:00:00", 0, 0); |
| endpoint0->set_security_mode(flimflam::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, flimflam::kModeManaged, |
| flimflam::kSecurityWpa)); |
| EXPECT_TRUE(service0); |
| EXPECT_TRUE(service0->HasEndpoints()); |
| EXPECT_EQ(flimflam::kSecurityPsk, service0->security_); |
| |
| WiFiEndpointRefPtr endpoint1 = MakeEndpoint(ssid0, "00:00:00:00:00:01", 0, 0); |
| endpoint1->set_security_mode(flimflam::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, flimflam::kModeManaged, |
| flimflam::kSecurityNone)); |
| WiFiEndpointRefPtr endpoint2 = MakeEndpoint(ssid1, "00:00:00:00:00:02", 0, 0); |
| endpoint2->set_security_mode(flimflam::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, flimflam::kModeManaged, |
| flimflam::kSecurityRsn)); |
| EXPECT_TRUE(service1); |
| EXPECT_TRUE(service1->HasEndpoints()); |
| EXPECT_EQ(flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone, |
| false); |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone, |
| false); |
| EXPECT_EQ(service0.get(), FindService(ssid0_bytes, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone, |
| false); |
| const string ssid1("another_ssid"); |
| const vector<uint8_t> ssid1_bytes(ssid1.begin(), ssid1.end()); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1_bytes, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::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, 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'), |
| flimflam::kModeManaged, |
| flimflam::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, LoadAndFixupServiceEntries) { |
| // 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(storage_, Flush()).Times(1); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", |
| flimflam::kTypeWifi, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone); |
| EXPECT_CALL(storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(false)); |
| EXPECT_CALL(storage_, |
| SetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(storage_, GetGroups()).WillRepeatedly(Return(groups)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Return(false)); |
| LoadAndFixupServiceEntries(true); |
| Mock::VerifyAndClearExpectations(&metrics_); |
| |
| EXPECT_CALL(metrics_, SendEnumToUMA( |
| "Network.Shill.Wifi.ServiceFixupEntries", |
| Metrics::kMetricServiceFixupUserProfile, |
| Metrics::kMetricServiceFixupMax)).Times(1); |
| EXPECT_CALL(storage_, Flush()).Times(1); |
| EXPECT_CALL(storage_, GetStringList(_, _, _)).Times(0); |
| LoadAndFixupServiceEntries(false); |
| } |
| |
| TEST_F(WiFiProviderTest, LoadAndFixupServiceEntriesNothingToDo) { |
| EXPECT_CALL(metrics_, SendEnumToUMA(_, _, _)).Times(0); |
| EXPECT_CALL(storage_, Flush()).Times(0); |
| const string kGroupId = |
| StringPrintf("%s_0_0_%s_%s", |
| flimflam::kTypeWifi, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone); |
| EXPECT_CALL(storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Return(true)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Return(false)); |
| LoadAndFixupServiceEntries(true); |
| } |
| |
| TEST_F(WiFiProviderTest, GetHiddenSSIDList) { |
| EXPECT_TRUE(provider_.GetHiddenSSIDList().empty()); |
| const vector<uint8_t> ssid0(1, '0'); |
| AddMockService(ssid0, flimflam::kModeManaged, |
| flimflam::kSecurityNone, false); |
| EXPECT_TRUE(provider_.GetHiddenSSIDList().empty()); |
| |
| const vector<uint8_t> ssid1(1, '1'); |
| MockWiFiServiceRefPtr service1 = AddMockService(ssid1, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::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, |
| flimflam::kModeManaged, |
| flimflam::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(storage_, SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0)]))); |
| EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1)]))); |
| EXPECT_CALL(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(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", |
| flimflam::kTypeWifi, |
| flimflam::kModeManaged, |
| flimflam::kSecurityNone); |
| EXPECT_CALL(storage_, |
| GetString(kGroupId, _, _)).WillRepeatedly(Return(true)); |
| set<string> groups; |
| groups.insert(kGroupId); |
| // Instead of block[1], return a block without the date. |
| EXPECT_CALL(storage_, GetGroups()).WillOnce(Return(groups)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetIllegalDayStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 2), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| EXPECT_CALL(storage_, GetStringList(WiFiProvider::kStorageId, |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 3), _)). |
| WillOnce(Invoke(this, &WiFiProviderTest::GetStringList)); |
| |
| LoadAndFixupServiceEntries(true); |
| |
| // 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(storage_, SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 0)]))); |
| EXPECT_CALL(storage_, SetStringList(WiFiProvider::kStorageId, _, |
| Eq(profile_frequency_data_[ |
| StringPrintf("%s%d", WiFiProvider::kStorageFrequencies, 1)]))). |
| Times(0); |
| EXPECT_CALL(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(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(_, _, _, _, _)); |
| 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(_, _, _, _, _)); |
| 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)); |
| } |
| |
| } // namespace shill |