254 lines
10 KiB
Python
254 lines
10 KiB
Python
|
|
#!/usr/bin/env python3.4
|
||
|
|
#
|
||
|
|
# Copyright 2018 - The Android Open Source Project
|
||
|
|
#
|
||
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
|
# you may not use this file except in compliance with the License.
|
||
|
|
# You may obtain a copy of the License at
|
||
|
|
#
|
||
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
#
|
||
|
|
# Unless required by applicable law or agreed to in writing, software
|
||
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
|
# See the License for the specific language governing permissions and
|
||
|
|
# limitations under the License.
|
||
|
|
|
||
|
|
import itertools
|
||
|
|
import time
|
||
|
|
|
||
|
|
import acts.base_test
|
||
|
|
import acts.signals as signals
|
||
|
|
from acts_contrib.test_utils.tel.tel_wifi_utils import WIFI_CONFIG_APBAND_2G
|
||
|
|
import acts_contrib.test_utils.wifi.wifi_test_utils as wutils
|
||
|
|
import acts.utils as utils
|
||
|
|
|
||
|
|
from acts import asserts
|
||
|
|
from acts.test_decorators import test_tracker_info
|
||
|
|
from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
|
||
|
|
|
||
|
|
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
|
||
|
|
GET_MAC_ADDRESS = ("ip addr show wlan0"
|
||
|
|
"| grep 'link/ether'"
|
||
|
|
"| cut -d ' ' -f6")
|
||
|
|
MAC_SETTING = "wifi_connected_mac_randomization_enabled"
|
||
|
|
GET_MAC_RANDOMIZATION_STATUS = "settings get global {}".format(MAC_SETTING)
|
||
|
|
TURN_ON_MAC_RANDOMIZATION = "settings put global {} 1".format(MAC_SETTING)
|
||
|
|
TURN_OFF_MAC_RANDOMIZATION = "settings put global {} 0".format(MAC_SETTING)
|
||
|
|
LOG_CLEAR = "logcat -c"
|
||
|
|
LOG_GREP = "logcat -d | grep {}"
|
||
|
|
|
||
|
|
|
||
|
|
class WifiConnectedMacRandomizationTest(WifiBaseTest):
|
||
|
|
"""Tests for Connected MAC Randomization.
|
||
|
|
|
||
|
|
Test Bed Requirement:
|
||
|
|
* Two Android devices with the first one supporting MAC randomization.
|
||
|
|
* At least two Wi-Fi networks to connect to.
|
||
|
|
"""
|
||
|
|
|
||
|
|
def setup_class(self):
|
||
|
|
super().setup_class()
|
||
|
|
|
||
|
|
self.dut = self.android_devices[0]
|
||
|
|
self.dut_softap = self.android_devices[1]
|
||
|
|
wutils.wifi_test_device_init(self.dut)
|
||
|
|
wutils.wifi_test_device_init(self.dut_softap)
|
||
|
|
|
||
|
|
self.reset_mac_address_to_factory_mac()
|
||
|
|
self.dut.adb.shell(TURN_ON_MAC_RANDOMIZATION)
|
||
|
|
asserts.assert_equal(
|
||
|
|
self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "1",
|
||
|
|
"Failed to enable Connected MAC Randomization on dut.")
|
||
|
|
|
||
|
|
req_params = ["reference_networks"]
|
||
|
|
opt_param = []
|
||
|
|
self.unpack_userparams(req_param_names=req_params,
|
||
|
|
opt_param_names=opt_param)
|
||
|
|
|
||
|
|
if "AccessPoint" in self.user_params:
|
||
|
|
self.legacy_configure_ap_and_start()
|
||
|
|
|
||
|
|
asserts.assert_true(
|
||
|
|
self.reference_networks[0]["2g"],
|
||
|
|
"Need at least 1 2.4Ghz reference network with psk.")
|
||
|
|
asserts.assert_true(
|
||
|
|
self.reference_networks[0]["5g"],
|
||
|
|
"Need at least 1 5Ghz reference network with psk.")
|
||
|
|
self.wpapsk_2g = self.reference_networks[0]["2g"]
|
||
|
|
self.wpapsk_5g = self.reference_networks[0]["5g"]
|
||
|
|
|
||
|
|
def setup_test(self):
|
||
|
|
super().setup_test()
|
||
|
|
self.dut.droid.wakeLockAcquireBright()
|
||
|
|
self.dut.droid.wakeUpNow()
|
||
|
|
wutils.wifi_toggle_state(self.dut, True)
|
||
|
|
wutils.wifi_toggle_state(self.dut_softap, False)
|
||
|
|
|
||
|
|
def teardown_test(self):
|
||
|
|
super().teardown_test()
|
||
|
|
self.dut.droid.wakeLockRelease()
|
||
|
|
self.dut.droid.goToSleepNow()
|
||
|
|
wutils.reset_wifi(self.dut)
|
||
|
|
wutils.reset_wifi(self.dut_softap)
|
||
|
|
|
||
|
|
def teardown_class(self):
|
||
|
|
wutils.stop_wifi_tethering(self.dut_softap)
|
||
|
|
self.reset_mac_address_to_factory_mac()
|
||
|
|
if "AccessPoint" in self.user_params:
|
||
|
|
del self.user_params["reference_networks"]
|
||
|
|
del self.user_params["open_network"]
|
||
|
|
|
||
|
|
"""Helper Functions"""
|
||
|
|
|
||
|
|
def get_current_mac_address(self, ad):
|
||
|
|
"""Get the device's wlan0 MAC address.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
ad: AndroidDevice to get MAC address of.
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
A MAC address string in the format of "12:34:56:78:90:12".
|
||
|
|
"""
|
||
|
|
return ad.adb.shell(GET_MAC_ADDRESS)
|
||
|
|
|
||
|
|
def is_valid_randomized_mac_address(self, mac):
|
||
|
|
"""Check if the given MAC address is a valid randomized MAC address.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
mac: MAC address to check in the format of "12:34:56:78:90:12".
|
||
|
|
"""
|
||
|
|
asserts.assert_true(
|
||
|
|
mac != self.dut_factory_mac,
|
||
|
|
"Randomized MAC address is same as factory MAC address.")
|
||
|
|
first_byte = int(mac[:2], 16)
|
||
|
|
asserts.assert_equal(first_byte & 1, 0, "MAC address is not unicast.")
|
||
|
|
asserts.assert_equal(first_byte & 2, 2, "MAC address is not local.")
|
||
|
|
|
||
|
|
def reset_mac_address_to_factory_mac(self):
|
||
|
|
"""Reset dut to and store factory MAC address by turning off
|
||
|
|
Connected MAC Randomization and rebooting dut.
|
||
|
|
"""
|
||
|
|
self.dut.adb.shell(TURN_OFF_MAC_RANDOMIZATION)
|
||
|
|
asserts.assert_equal(
|
||
|
|
self.dut.adb.shell(GET_MAC_RANDOMIZATION_STATUS), "0",
|
||
|
|
"Failed to disable Connected MAC Randomization on dut.")
|
||
|
|
self.dut.reboot()
|
||
|
|
time.sleep(DEFAULT_TIMEOUT)
|
||
|
|
self.dut_factory_mac = self.get_current_mac_address(self.dut)
|
||
|
|
|
||
|
|
def get_connection_data(self, ad, network):
|
||
|
|
"""Connect and get network id and ssid info from connection data.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
ad: AndroidDevice to use for connection
|
||
|
|
network: network info of the network to connect to
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
A convenience dict with the connected network's ID and SSID.
|
||
|
|
"""
|
||
|
|
wutils.connect_to_wifi_network(ad, network)
|
||
|
|
connect_data = ad.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
|
||
|
|
|
||
|
|
"""Tests"""
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="")
|
||
|
|
def test_wifi_connection_2G_with_mac_randomization(self):
|
||
|
|
"""Tests connection to 2G network with Connected MAC Randomization.
|
||
|
|
"""
|
||
|
|
wutils.connect_to_wifi_network(self.dut, self.wpapsk_2g)
|
||
|
|
mac = self.get_current_mac_address(self.dut)
|
||
|
|
self.is_valid_randomized_mac_address(mac)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="")
|
||
|
|
def test_wifi_connection_5G_with_mac_randomization(self):
|
||
|
|
"""Tests connection to 5G network with Connected MAC Randomization.
|
||
|
|
"""
|
||
|
|
wutils.connect_to_wifi_network(self.dut, self.wpapsk_5g)
|
||
|
|
mac = self.get_current_mac_address(self.dut)
|
||
|
|
self.is_valid_randomized_mac_address(mac)
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="")
|
||
|
|
def test_randomized_mac_persistent_between_connections(self):
|
||
|
|
"""Tests that randomized MAC address assigned to each network is
|
||
|
|
persistent between connections.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Connect to a 2GHz network.
|
||
|
|
2. Connect to a 5GHz network.
|
||
|
|
3. Reconnect to the 2GHz network using its network id.
|
||
|
|
4. Verify that MAC addresses in Steps 1 and 3 are equal.
|
||
|
|
5. Reconnect to the 5GHz network using its network id.
|
||
|
|
6. Verify that MAC addresses in Steps 2 and 5 are equal.
|
||
|
|
"""
|
||
|
|
connect_data_2g = self.get_connection_data(self.dut, self.wpapsk_2g)
|
||
|
|
old_mac_2g = self.get_current_mac_address(self.dut)
|
||
|
|
self.is_valid_randomized_mac_address(old_mac_2g)
|
||
|
|
|
||
|
|
connect_data_5g = self.get_connection_data(self.dut, self.wpapsk_5g)
|
||
|
|
old_mac_5g = self.get_current_mac_address(self.dut)
|
||
|
|
self.is_valid_randomized_mac_address(old_mac_5g)
|
||
|
|
|
||
|
|
asserts.assert_true(
|
||
|
|
old_mac_2g != old_mac_5g,
|
||
|
|
"Randomized MAC addresses for 2G and 5G networks are equal.")
|
||
|
|
|
||
|
|
reconnect_2g = wutils.connect_to_wifi_network_with_id(
|
||
|
|
self.dut, connect_data_2g[WifiEnums.NETID_KEY],
|
||
|
|
connect_data_2g[WifiEnums.SSID_KEY])
|
||
|
|
if not reconnect_2g:
|
||
|
|
raise signals.TestFailure("Device did not connect to the correct"
|
||
|
|
" 2GHz network.")
|
||
|
|
new_mac_2g = self.get_current_mac_address(self.dut)
|
||
|
|
asserts.assert_equal(
|
||
|
|
old_mac_2g, new_mac_2g,
|
||
|
|
"Randomized MAC for 2G is not persistent between connections.")
|
||
|
|
|
||
|
|
reconnect_5g = wutils.connect_to_wifi_network_with_id(
|
||
|
|
self.dut, connect_data_5g[WifiEnums.NETID_KEY],
|
||
|
|
connect_data_5g[WifiEnums.SSID_KEY])
|
||
|
|
if not reconnect_5g:
|
||
|
|
raise signals.TestFailure("Device did not connect to the correct"
|
||
|
|
" 5GHz network.")
|
||
|
|
new_mac_5g = self.get_current_mac_address(self.dut)
|
||
|
|
asserts.assert_equal(
|
||
|
|
old_mac_5g, new_mac_5g,
|
||
|
|
"Randomized MAC for 5G is not persistent between connections.")
|
||
|
|
|
||
|
|
@test_tracker_info(uuid="")
|
||
|
|
def test_randomized_mac_used_during_connection(self):
|
||
|
|
"""Verify that the randomized MAC address and not the factory
|
||
|
|
MAC address is used during connection by checking the softap logs.
|
||
|
|
|
||
|
|
Steps:
|
||
|
|
1. Set up softAP on dut_softap.
|
||
|
|
2. Have dut connect to the softAp.
|
||
|
|
3. Verify that only randomized MAC appears in softAp logs.
|
||
|
|
"""
|
||
|
|
self.dut_softap.adb.shell(LOG_CLEAR)
|
||
|
|
config = wutils.create_softap_config()
|
||
|
|
wutils.start_wifi_tethering(self.dut_softap,
|
||
|
|
config[wutils.WifiEnums.SSID_KEY],
|
||
|
|
config[wutils.WifiEnums.PWD_KEY],
|
||
|
|
WIFI_CONFIG_APBAND_2G)
|
||
|
|
|
||
|
|
# Internet validation fails when dut_softap does not have a valid sim
|
||
|
|
# supporting softap. Since this test is not checking for internet
|
||
|
|
# validation, we suppress failure signals.
|
||
|
|
wutils.connect_to_wifi_network(self.dut, config, assert_on_fail=False)
|
||
|
|
mac = self.get_current_mac_address(self.dut)
|
||
|
|
wutils.stop_wifi_tethering(self.dut_softap)
|
||
|
|
|
||
|
|
self.is_valid_randomized_mac_address(mac)
|
||
|
|
log = self.dut_softap.adb.shell(LOG_GREP.format(mac))
|
||
|
|
asserts.assert_true(len(log) > 0, "Randomized MAC not in log.")
|
||
|
|
log = self.dut_softap.adb.shell(LOG_GREP.format(self.dut_factory_mac))
|
||
|
|
asserts.assert_true(len(log) == 0, "Factory MAC is in log.")
|