shill: improve conformance with WiFiRoaming tests
This patch makes several changes to get shill passing more of
the WiFiRoaming suite. shill now passes 13 of the 18 tests.
Overview of changes:
- Clean up Services when their last Endpoint disappers.
- Make a new WiFi connection request pre-empt an existing one.
- Make Device::SelectService no-op if new service is same as old.
(part of resolving crosbug.com/23703)
- Move auto-connect logic to its own function, and run that function
in a deferred task (partly resolves crosbug.com/24276)
- Add a non-deferred variant of Service::Connect (part of resolving
crosbug.com/24276).
- Have service sort order reflect whether or not services are
connecting, failed, connectable, and configured for auto-connect.
BUG=chromium-os:24276,chromium-os:23223,chromium-os:22943,chromium-os:23703
TEST=WiFiRoaming, unit tests, manual
Manual testing: per https://gerrit.chromium.org/gerrit/12963
Collateral changes:
- updated TESTING
- added crosbug.com/24461 for problem with autotest and profiles
- declared some functions as const
- removed some useless comments
Change-Id: I36d6eb7108a377dbf409d3e5673deffb85c0633e
Reviewed-on: https://gerrit.chromium.org/gerrit/12687
Reviewed-by: Thieu Le <thieule@chromium.org>
Tested-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: mukesh agrawal <quiche@chromium.org>
diff --git a/wifi_unittest.cc b/wifi_unittest.cc
index 5598988..649ee95 100644
--- a/wifi_unittest.cc
+++ b/wifi_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
+// Copyright (c) 2012 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.
@@ -206,8 +206,9 @@
SupplicantProcessProxyInterface *GetSupplicantProcessProxy() {
return wifi_->supplicant_process_proxy_.get();
}
- SupplicantInterfaceProxyInterface *GetSupplicantInterfaceProxy() {
- return wifi_->supplicant_interface_proxy_.get();
+ MockSupplicantInterfaceProxy *GetSupplicantInterfaceProxy() {
+ return dynamic_cast<MockSupplicantInterfaceProxy *>(
+ wifi_->supplicant_interface_proxy_.get());
}
const string &GetSupplicantState() {
return wifi_->supplicant_state_;
@@ -223,25 +224,7 @@
return wifi_->link_up_;
}
WiFiEndpointRefPtr MakeEndpoint(const string &ssid, const string &bssid) {
- map <string, ::DBus::Variant> args;
- ::DBus::MessageIter writer;
-
- writer = args[wpa_supplicant::kBSSPropertySSID].writer();
- writer << vector<uint8_t>(ssid.begin(), ssid.end());
-
- string bssid_nosep;
- RemoveChars(bssid, ":", &bssid_nosep);
- vector<uint8_t> bssid_bytes;
- base::HexStringToBytes(bssid_nosep, &bssid_bytes);
- writer = args[wpa_supplicant::kBSSPropertyBSSID].writer();
- writer << bssid_bytes;
-
- args[wpa_supplicant::kBSSPropertySignal].writer().append_int16(0);
- args[wpa_supplicant::kBSSPropertyMode].writer().append_string(
- wpa_supplicant::kNetworkModeInfrastructure);
- // We indicate this is an open BSS by leaving out all security properties.
-
- return new WiFiEndpoint(args);
+ return WiFiEndpoint::MakeOpenEndpoint(ssid, bssid);
}
MockWiFiServiceRefPtr MakeMockService() {
vector<uint8_t> ssid(1, 'a');
@@ -554,10 +537,45 @@
EXPECT_EQ(1, GetServices().size());
EXPECT_TRUE(GetServices().front()->IsVisible());
- EXPECT_CALL(*manager(), UpdateService(_));
+ EXPECT_CALL(*manager(), DeregisterService(_));
RemoveBSS("bss0");
- EXPECT_FALSE(GetServices().front()->IsVisible());
+ EXPECT_TRUE(GetServices().empty());
+}
+
+TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnected) {
+ StartWiFi();
+ ReportBSS("bss0", "ssid", "00:00:00:00:00:00", 0, kNetworkModeAdHoc);
+ ReportScanDone();
+ ReportCurrentBSSChanged("bss0");
+
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
+ EXPECT_CALL(*manager(), DeregisterService(_));
+ RemoveBSS("bss0");
+ EXPECT_TRUE(GetServices().empty());
+}
+
+TEST_F(WiFiMainTest, LoneBSSRemovedWhileConnectedToHidden) {
+ StartWiFi();
+
+ Error e;
+ WiFiServiceRefPtr service =
+ GetServiceInner(flimflam::kTypeWifi, "ssid", flimflam::kModeManaged,
+ NULL, NULL, true, &e);
EXPECT_EQ(1, GetServices().size());
+
+ ReportBSS("bss", "ssid", "00:00:00:00:00:01", 0, kNetworkModeInfrastructure);
+ ReportScanDone();
+ ReportCurrentBSSChanged("bss");
+ EXPECT_EQ(1, GetServices().size());
+
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
+ EXPECT_CALL(*manager(), UpdateService(_));
+ RemoveBSS("bss");
+ EXPECT_TRUE(manager()->HasService(service));
+ EXPECT_EQ(1, GetServices().size());
+ // Verify expectations now, because WiFi may call UpdateService when
+ // WiFi is Stop()-ed (during TearDown()).
+ Mock::VerifyAndClearExpectations(manager());
}
TEST_F(WiFiMainTest, NonSolitaryBSSRemoved) {
@@ -1183,7 +1201,7 @@
EXPECT_EQ(NULL, GetPendingService().get());
ReportCurrentBSSChanged(wpa_supplicant::kCurrentBSSNull);
- EXPECT_EQ(Service::kStateIdle, service->state());
+ EXPECT_EQ(Service::kStateFailure, service->state());
EXPECT_EQ(NULL, GetCurrentService().get());
EXPECT_EQ(NULL, GetPendingService().get());
}
@@ -1245,4 +1263,36 @@
kNetworkModeInfrastructure);
}
+TEST_F(WiFiMainTest, NewConnectPreemptsPending) {
+ WiFiEndpointRefPtr ap1 = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
+ WiFiEndpointRefPtr ap2 = MakeEndpoint("another_ssid", "01:02:03:04:05:06");
+ WiFiServiceRefPtr service1 = CreateServiceForEndpoint(*ap1);
+ WiFiServiceRefPtr service2 = CreateServiceForEndpoint(*ap2);
+
+ StartWiFi();
+ ReportBSS("ap1", ap1->ssid_string(), ap1->bssid_string(), 0,
+ kNetworkModeInfrastructure);
+ ReportBSS("ap2", ap2->ssid_string(), ap2->bssid_string(), 0,
+ kNetworkModeInfrastructure);
+ InitiateConnect(service1);
+ EXPECT_EQ(service1.get(), GetPendingService().get());
+
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), Disconnect());
+ EXPECT_CALL(*GetSupplicantInterfaceProxy(), AddNetwork(_));
+ InitiateConnect(service2);
+ EXPECT_EQ(service2.get(), GetPendingService().get());
+}
+
+TEST_F(WiFiMainTest, IsIdle) {
+ StartWiFi();
+ EXPECT_TRUE(wifi()->IsIdle());
+
+ WiFiEndpointRefPtr ap = MakeEndpoint("an_ssid", "00:01:02:03:04:05");
+ WiFiServiceRefPtr service = CreateServiceForEndpoint(*ap);
+ Error error;
+ service->AddEndpoint(ap);
+ service->AutoConnect();
+ EXPECT_FALSE(wifi()->IsIdle());
+}
+
} // namespace shill