[Tests]Adding tests for connection with network id
Includes new tests for connecting to a network with network id in
various scenarios.
wifi_test_utils is updated for making appropriate calls to
the newly added facade for connection with network id.
Bug: 34774763
Test: Tested and verified all tests locally.
Change-Id: I19de30e7d45ddfb81c509342350087781ac5d8d8
diff --git a/acts/framework/acts/test_utils/wifi/wifi_constants.py b/acts/framework/acts/test_utils/wifi/wifi_constants.py
index 1810130..f51c336 100644
--- a/acts/framework/acts/test_utils/wifi/wifi_constants.py
+++ b/acts/framework/acts/test_utils/wifi/wifi_constants.py
@@ -21,3 +21,4 @@
# These constants will be used by the ACTS wifi tests.
CONNECT_BY_CONFIG_SUCCESS = 'WifiManagerConnectByConfigOnSuccess'
+CONNECT_BY_NETID_SUCCESS = 'WifiManagerConnectByNetIdOnSuccess'
diff --git a/acts/framework/acts/test_utils/wifi/wifi_test_utils.py b/acts/framework/acts/test_utils/wifi/wifi_test_utils.py
index 382f172..ac9b5e7 100755
--- a/acts/framework/acts/test_utils/wifi/wifi_test_utils.py
+++ b/acts/framework/acts/test_utils/wifi/wifi_test_utils.py
@@ -49,6 +49,7 @@
class WifiEnums():
SSID_KEY = "SSID"
+ NETID_KEY = "network_id"
BSSID_KEY = "BSSID"
PWD_KEY = "password"
frequency_key = "frequency"
@@ -571,6 +572,40 @@
"Failed to remove these configured Wi-Fi networks: %s" % networks)
+ def toggle_airplane_mode_on_and_off(self):
+ """Turn ON and OFF Airplane mode.
+
+ Args: None.
+ Returns: Assert if turning on/off Airplane mode fails.
+
+ """
+ self.log.debug("Toggling Airplane mode ON.")
+ asserts.assert_true(
+ force_airplane_mode(self.dut, True),
+ "Can not turn on airplane mode on: %s" % self.dut.serial)
+ time.sleep(DEFAULT_TIMEOUT)
+ self.log.debug("Toggling Airplane mode OFF.")
+ asserts.assert_true(
+ force_airplane_mode(self.dut, False),
+ "Can not turn on airplane mode on: %s" % self.dut.serial)
+ time.sleep(DEFAULT_TIMEOUT)
+
+
+ def toggle_wifi_off_and_on(self):
+ """Turn OFF and ON WiFi.
+
+ Args: None.
+ Returns: Assert if turning off/on WiFi fails.
+
+ """
+ self.log.debug("Toggling wifi OFF.")
+ wutils.wifi_toggle_state(self.dut, False)
+ time.sleep(DEFAULT_TIMEOUT)
+ self.log.debug("Toggling wifi ON.")
+ wutils.wifi_toggle_state(self.dut, True)
+ time.sleep(DEFAULT_TIMEOUT)
+
+
def wifi_forget_network(ad, net_ssid):
"""Remove configured Wifi network on an android device.
@@ -807,6 +842,43 @@
ad.droid.wifiStopTrackingStateChange()
+def wait_for_connect(ad, tries):
+ """Wait for a connect event on queue and pop when available.
+
+ Args:
+ ad: An Android device object.
+ tries: An integer that is the number of times to try before failing.
+
+ Returns:
+ A dict with details of the connection data, which looks like this:
+ {
+ 'time': 1485460337798,
+ 'name': 'WifiNetworkConnected',
+ 'data': {
+ 'rssi': -27,
+ 'is_24ghz': True,
+ 'mac_address': '02:00:00:00:00:00',
+ 'network_id': 1,
+ 'BSSID': '30:b5:c2:33:d3:fc',
+ 'ip_address': 117483712,
+ 'link_speed': 54,
+ 'supplicant_state': 'completed',
+ 'hidden_ssid': False,
+ 'SSID': 'wh_ap1_2g',
+ 'is_5ghz': False}
+ }
+
+ """
+ connect_result = None
+ for i in range(tries):
+ try:
+ connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED, 30)
+ break
+ except Empty:
+ pass
+ return connect_result
+
+
def wifi_connect(ad, network, num_of_tries=1, assert_on_fail=True):
"""Connect an Android device to a wifi network.
@@ -825,8 +897,8 @@
failure signals.
Returns:
- If assert_on_fail is False, function returns True if the toggle was
- successful, False otherwise. If assert_on_fail is True, no return value.
+ Returns a value only if assert_on_fail is false.
+ Returns True if the connection was successful, False otherwise.
"""
return _assert_on_fail_handler(
_wifi_connect, assert_on_fail, ad, network, num_of_tries=num_of_tries)
@@ -856,14 +928,7 @@
ad.log.info("Starting connection process to %s", expected_ssid)
try:
event = ad.ed.pop_event(wifi_constants.CONNECT_BY_CONFIG_SUCCESS, 30)
- connect_result = None
- for i in range(num_of_tries):
- try:
- connect_result = ad.ed.pop_event(wifi_constants.WIFI_CONNECTED,
- 30)
- break
- except Empty:
- pass
+ connect_result = wait_for_connect(ad, num_of_tries)
asserts.assert_true(connect_result,
"Failed to connect to Wi-Fi network %s on %s" %
(network, ad.serial))
@@ -893,6 +958,81 @@
ad.droid.wifiStopTrackingStateChange()
+def wifi_connect_by_id(ad, network_id, num_of_tries=1, assert_on_fail=True):
+ """Connect an Android device to a wifi network using network Id.
+
+ Start connection to the wifi network, with the given network Id, wait for
+ the "connected" event, then verify the connected network is the one requested.
+
+ This will directly fail a test if anything goes wrong.
+
+ Args:
+ ad: android_device object to initiate connection on.
+ network_id: Integer specifying the network id of the network.
+ num_of_tries: An integer that is the number of times to try before
+ delaring failure. Default is 1.
+ assert_on_fail: If True, error checks in this function will raise test
+ failure signals.
+
+ Returns:
+ Returns a value only if assert_on_fail is false.
+ Returns True if the connection was successful, False otherwise.
+ """
+ _assert_on_fail_handler(_wifi_connect_by_id, assert_on_fail, ad,
+ network_id, num_of_tries)
+
+
+def _wifi_connect_by_id(ad, network_id, num_of_tries=1):
+ """Connect an Android device to a wifi network using it's network id.
+
+ Start connection to the wifi network, with the given network id, wait for
+ the "connected" event, then verify the connected network is the one requested.
+
+ Args:
+ ad: android_device object to initiate connection on.
+ network_id: Integer specifying the network id of the network.
+ num_of_tries: An integer that is the number of times to try before
+ delaring failure. Default is 1.
+ """
+ # Clear all previous connect events.
+ ad.ed.clear_events(wifi_constants.WIFI_CONNECTED)
+ ad.droid.wifiStartTrackingStateChange()
+ ad.droid.wifiConnectByNetworkId(network_id)
+ ad.log.info("Starting connection to network with id %d", network_id)
+ try:
+ event = ad.ed.pop_event(wifi_constants.CONNECT_BY_NETID_SUCCESS, 60)
+ connect_result = wait_for_connect(ad, num_of_tries)
+ asserts.assert_true(connect_result,
+ "Failed to connect to Wi-Fi network using network id")
+ ad.log.debug("Wi-Fi connection result: %s", connect_result)
+ actual_id = connect_result['data'][WifiEnums.NETID_KEY]
+ asserts.assert_equal(actual_id, network_id,
+ "Connected to the wrong network on %s."
+ "Expected network id = %d, but got %d." %
+ (ad.serial, network_id, actual_id))
+ expected_ssid = connect_result['data'][WifiEnums.SSID_KEY]
+ ad.log.info("Connected to Wi-Fi network %s with %d network id.",
+ expected_ssid, network_id)
+
+ # Wait for data connection to stabilize.
+ time.sleep(5)
+
+ internet = validate_connection(ad, DEFAULT_PING_ADDR)
+ if not internet:
+ raise signals.TestFailure("Failed to connect to internet on %s" %
+ expected_ssid)
+ except Empty:
+ asserts.fail("Failed to connect to network with id %d on %s" %
+ (network_id, ad.serial))
+ except Exception as error:
+ ad.log.error("Failed to connect to network with id %d with error %s",
+ network_id, error)
+ raise signals.TestFailure("Failed to connect to network with network"
+ " id %d" % network_id)
+ finally:
+ ad.droid.wifiStopTrackingStateChange()
+
+
def start_wifi_single_scan(ad, scan_setting):
"""Starts wifi single shot scan.
diff --git a/acts/tests/google/wifi/WifiManagerTest.py b/acts/tests/google/wifi/WifiManagerTest.py
index 8532d24..55ef8cf 100755
--- a/acts/tests/google/wifi/WifiManagerTest.py
+++ b/acts/tests/google/wifi/WifiManagerTest.py
@@ -27,7 +27,11 @@
from acts import asserts
WifiEnums = wutils.WifiEnums
-
+# Default timeout used for reboot, toggle WiFi and Airplane mode,
+# for the system to settle down after the operation.
+DEFAULT_TIMEOUT = 10
+BAND_2GHZ = 0
+BAND_5GHZ = 1
class WifiManagerTest(acts.base_test.BaseTestClass):
"""Tests for APIs in Android's WifiManager class.
@@ -49,7 +53,7 @@
self.user_params["additional_energy_info_models"] = []
self.user_params["additional_tdls_models"] = []
req_params = ("iot_networks", "open_network", "config_store_networks",
- "iperf_server_address")
+ "iperf_server_address", "reference_networks")
opt_param = ("additional_energy_info_models", "additional_tdls_models")
self.unpack_userparams(
req_param_names=req_params, opt_param_names=opt_param)
@@ -65,12 +69,17 @@
self.user_params["tdls_models"] = list(
set(self.user_params["tdls_models"]))
asserts.assert_true(
+ len(self.reference_networks) > 0,
+ "Need at least one reference network with psk.")
+ asserts.assert_true(
len(self.iot_networks) > 0,
"Need at least one iot network with psk.")
wutils.wifi_toggle_state(self.dut, True)
self.iot_networks = self.iot_networks + [self.open_network]
self.iperf_server = self.iperf_servers[0]
self.iot_test_prefix = "test_connection_to-"
+ self.wpapsk_2g = self.reference_networks[0]["2g"]
+ self.wpapsk_5g = self.reference_networks[0]["5g"]
def setup_test(self):
self.dut.droid.wakeLockAcquireBright()
@@ -106,6 +115,62 @@
wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results)
wutils.wifi_connect(ad, network, num_of_tries=3)
+ def get_connection_data(self, dut, network):
+ """Get network id and ssid info from connection data.
+
+ Args:
+ dut: The Android device object under test.
+ network: dict representing the network to connect to.
+
+ Returns:
+ A convenience dict with the connected network's ID and SSID.
+
+ """
+ params = (network, dut)
+ self.connect_to_wifi_network(params)
+ connect_data = dut.droid.wifiGetConnectionInfo()
+ ssid_id_dict = dict()
+ ssid_id_dict[WifiEnums.NETID_KEY] = connect_data[WifiEnums.NETID_KEY]
+ ssid_id_dict[WifiEnums.SSID_KEY] = connect_data[WifiEnums.SSID_KEY]
+ return ssid_id_dict
+
+ def connect_multiple_networks(self, dut):
+ """Connect to one 2.4GHz and one 5Ghz network.
+
+ Args:
+ dut: The Android device object under test.
+
+ Returns:
+ A list with the connection details for the 2GHz and 5GHz networks.
+
+ """
+ network_list = list()
+ connect_2g_data = self.get_connection_data(dut, self.wpapsk_2g)
+ network_list.append(connect_2g_data)
+ connect_5g_data = self.get_connection_data(dut, self.wpapsk_5g)
+ network_list.append(connect_5g_data)
+ return network_list
+
+ def connect_to_wifi_network_with_id(self, network_id, network_ssid):
+ """Connect to the given network using network id and verify SSID.
+
+ Args:
+ network_id: int Network Id of the network.
+ network_ssid: string SSID of the network.
+
+ Returns: True if connect using network id was successful;
+ False otherwise.
+
+ """
+ wutils.wifi_connect_by_id(self.dut, network_id)
+ connect_data = self.dut.droid.wifiGetConnectionInfo()
+ connect_ssid = reconnect_data[WifiEnums.SSID_KEY]
+ self.log.debug("Expected SSID = %s Connected SSID = %s" %(network_ssid,
+ connect_ssid))
+ if connect_ssid != network_ssid:
+ return False
+ return True
+
def run_iperf_client(self, params):
"""Run iperf traffic after connection.
@@ -234,6 +299,100 @@
nw[WifiEnums.BSSID_KEY] != ssid,
"Found forgotten network %s in configured networks." % ssid)
+ def test_reconnect_to_connected_network(self):
+ """Connect to a network and immediately issue reconnect.
+
+ Steps:
+ 1. Connect to a 2GHz network.
+ 2. Reconnect to the network using its network id.
+ 3. Connect to a 5GHz network.
+ 4. Reconnect to the network using its network id.
+
+ """
+ connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
+ reconnect_2g = self.connect_to_wifi_network_with_id(
+ connect_2g_data[WifiEnums.NETID_KEY],
+ connect_2g_data[WifiEnums.SSID_KEY])
+ if not reconnect_2g:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " 2GHz network.")
+ connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
+ reconnect_5g = self.connect_to_wifi_network_with_id(
+ connect_5g_data[WifiEnums.NETID_KEY],
+ connect_5g_data[WifiEnums.SSID_KEY])
+ if not reconnect_5g:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " 5GHz network.")
+
+ def test_reconnect_to_previously_connected(self):
+ """Connect to multiple networks and reconnect to the previous network.
+
+ Steps:
+ 1. Connect to a 2GHz network.
+ 2. Connect to a 5GHz network.
+ 3. Reconnect to the 2GHz network using its network id.
+ 4. Reconnect to the 5GHz network using its network id.
+
+ """
+ connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
+ connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
+ reconnect_2g = self.connect_to_wifi_network_with_id(
+ connect_2g_data[WifiEnums.NETID_KEY],
+ connect_2g_data[WifiEnums.SSID_KEY])
+ if not reconnect_2g:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " 2GHz network.")
+ reconnect_5g = self.connect_to_wifi_network_with_id(
+ connect_5g_data[WifiEnums.NETID_KEY],
+ connect_5g_data[WifiEnums.SSID_KEY])
+ if not reconnect_5g:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " 5GHz network.")
+
+ def test_reconnect_toggle_wifi(self):
+ """Connect to multiple networks, turn off/on wifi, then reconnect to
+ a previously connected network.
+
+ Steps:
+ 1. Connect to a 2GHz network.
+ 2. Connect to a 5GHz network.
+ 3. Turn WiFi OFF/ON.
+ 4. Reconnect to the non-current network.
+
+ """
+ connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
+ connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
+ wutils.toggle_wifi_off_and_on()
+ reconnect_to = self.get_enabled_network(connect_2g_data, connect_5g_data)
+ reconnect = self.connect_to_wifi_network_with_id(
+ reconnect_to[WifiEnums.NETID_KEY],
+ reconnect_to[WifiEnums.SSID_KEY])
+ if not reconnect:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " network after toggling WiFi.")
+
+ def test_reconnect_toggle_airplane(self):
+ """Connect to multiple networks, turn on/off Airplane moce, then
+ reconnect a previously connected network.
+
+ Steps:
+ 1. Connect to a 2GHz network.
+ 2. Connect to a 5GHz network.
+ 3. Turn ON/OFF Airplane mode.
+ 4. Reconnect to the non-current network.
+
+ """
+ connect_2g_data = self.get_connection_data(self.dut, self.wpapsk_2g)
+ connect_5g_data = self.get_connection_data(self.dut, self.wpapsk_5g)
+ wutils.toggle_airplane_mode_on_and_off()
+ reconnect_to = self.get_enabled_network(connect_2g_data, connect_5g_data)
+ reconnect = self.connect_to_wifi_network_with_id(
+ reconnect_to[WifiEnums.NETID_KEY],
+ reconnect_to[WifiEnums.SSID_KEY])
+ if not reconnect:
+ raise signals.TestFailure("Device did not connect to the correct"
+ " network after toggling Airplane mode.")
+
@acts.signals.generated_test
def test_iot_with_password(self):
params = list(