1 # 2 # Copyright 2016 - The Android Open Source Project 3 # 4 # Licensed under the Apache License, Version 2.0 (the "License"); 5 # you may not use this file except in compliance with the License. 6 # You may obtain a copy of the License at 7 # 8 # http://www.apache.org/licenses/LICENSE-2.0 9 # 10 # Unless required by applicable law or agreed to in writing, software 11 # distributed under the License is distributed on an "AS IS" BASIS, 12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 # See the License for the specific language governing permissions and 14 # limitations under the License. 15 16 import pprint 17 import random 18 import time 19 20 import acts.base_test 21 import acts.signals 22 import acts.test_utils.wifi.wifi_test_utils as wutils 23 24 from acts import asserts 25 26 WifiEnums = wutils.WifiEnums 27 28 # EAP Macros 29 EAP = WifiEnums.Eap 30 EapPhase2 = WifiEnums.EapPhase2 31 32 # Enterprise Config Macros 33 Ent = WifiEnums.Enterprise 34 35 class WifiEnterpriseRoamingTest(acts.base_test.BaseTestClass): 36 37 def __init__(self, controllers): 38 acts.base_test.BaseTestClass.__init__(self, controllers) 39 self.tests = ( 40 "test_roaming_with_different_auth_method", 41 ) 42 43 def setup_class(self): 44 self.dut = self.android_devices[0] 45 wutils.wifi_test_device_init(self.dut) 46 req_params = ( 47 "ent_roaming_ssid", 48 "bssid_a", 49 "bssid_b", 50 "attn_vals", 51 # Expected time within which roaming should finish, in seconds. 52 "roam_interval", 53 "ca_cert", 54 "client_cert", 55 "client_key", 56 "eap_identity", 57 "eap_password", 58 "device_password" 59 ) 60 self.unpack_userparams(req_params) 61 self.config_peap = { 62 Ent.EAP: EAP.PEAP, 63 Ent.CA_CERT: self.ca_cert, 64 Ent.IDENTITY: self.eap_identity, 65 Ent.PASSWORD: self.eap_password, 66 Ent.PHASE2: EapPhase2.MSCHAPV2, 67 WifiEnums.SSID_KEY: self.ent_roaming_ssid 68 } 69 self.config_tls = { 70 Ent.EAP: EAP.TLS, 71 Ent.CA_CERT: self.ca_cert, 72 WifiEnums.SSID_KEY: self.ent_roaming_ssid, 73 Ent.CLIENT_CERT: self.client_cert, 74 Ent.PRIVATE_KEY_ID: self.client_key, 75 Ent.IDENTITY: self.eap_identity, 76 } 77 self.config_ttls = { 78 Ent.EAP: EAP.TTLS, 79 Ent.CA_CERT: self.ca_cert, 80 Ent.IDENTITY: self.eap_identity, 81 Ent.PASSWORD: self.eap_password, 82 Ent.PHASE2: EapPhase2.MSCHAPV2, 83 WifiEnums.SSID_KEY: self.ent_roaming_ssid 84 } 85 self.config_sim = { 86 Ent.EAP: EAP.SIM, 87 WifiEnums.SSID_KEY: self.ent_roaming_ssid, 88 } 89 self.attn_a = self.attenuators[0] 90 self.attn_b = self.attenuators[1] 91 # Set screen lock password so ConfigStore is unlocked. 92 self.dut.droid.setDevicePassword(self.device_password) 93 self.set_attns("default") 94 95 def teardown_class(self): 96 wutils.reset_wifi(self.dut) 97 self.dut.droid.disableDevicePassword() 98 self.dut.ed.clear_all_events() 99 self.set_attns("default") 100 101 def setup_test(self): 102 self.dut.droid.wifiStartTrackingStateChange() 103 self.dut.droid.wakeLockAcquireBright() 104 self.dut.droid.wakeUpNow() 105 wutils.reset_wifi(self.dut) 106 self.dut.ed.clear_all_events() 107 return True 108 109 def teardown_test(self): 110 self.dut.droid.wakeLockRelease() 111 self.dut.droid.goToSleepNow() 112 self.dut.droid.wifiStopTrackingStateChange() 113 self.set_attns("default") 114 115 def on_fail(self, test_name, begin_time): 116 self.dut.cat_adb_log(test_name, begin_time) 117 118 def set_attns(self, attn_val_name): 119 """Sets attenuation values on attenuators used in this test. 120 121 Args: 122 attn_val_name: Name of the attenuation value pair to use. 123 """ 124 msg = "Set attenuation values to %s" % self.attn_vals[attn_val_name] 125 self.log.info(msg) 126 try: 127 self.attn_a.set_atten(self.attn_vals[attn_val_name][0]) 128 self.attn_b.set_atten(self.attn_vals[attn_val_name][1]) 129 except: 130 msg = "Failed to set attenuation values %s." % attn_val_name 131 self.log.error(msg) 132 raise 133 134 def gen_eap_configs(self): 135 """Generates configurations for different EAP authentication types. 136 137 Returns: 138 A list of dicts each representing an EAP configuration. 139 """ 140 configs = [self.config_tls] 141 # self.config_sim 142 configs += wutils.expand_enterprise_config_by_phase2(self.config_ttls) 143 configs += wutils.expand_enterprise_config_by_phase2(self.config_peap) 144 return configs 145 146 def gen_eap_roaming_test_name(self, config): 147 """Generates a test case name based on an EAP configuration. 148 149 Args: 150 config: A dict representing an EAP credential. 151 152 Returns: 153 A string representing the name of a generated EAP test case. 154 """ 155 name = "test_roaming-%s" % config[Ent.EAP].name 156 if Ent.PHASE2 in config: 157 name += "-{}".format(config[Ent.PHASE2].name) 158 return name 159 160 def trigger_roaming_and_validate(self, attn_val_name, expected_con): 161 """Sets attenuators to trigger roaming and validate the DUT connected 162 to the BSSID expected. 163 164 Args: 165 attn_val_name: Name of the attenuation value pair to use. 166 expected_con: The expected info of the network to we expect the DUT 167 to roam to. 168 """ 169 self.set_attns(attn_val_name) 170 self.log.info("Wait %ss for roaming to finish." % self.roam_interval) 171 time.sleep(self.roam_interval) 172 try: 173 self.dut.droid.wakeLockAcquireBright() 174 self.dut.droid.wakeUpNow() 175 wutils.verify_wifi_connection_info(self.dut, expected_con) 176 expected_bssid = expected_con[WifiEnums.BSSID_KEY] 177 self.log.info("Roamed to %s successfully" % expected_bssid) 178 finally: 179 self.dut.droid.wifiLockRelease() 180 self.dut.droid.goToSleepNow() 181 182 def roaming_between_a_and_b_logic(self, config): 183 """Test roaming between two enterprise APs. 184 185 Steps: 186 1. Make bssid_a visible, bssid_b not visible. 187 2. Connect to ent_roaming_ssid. Expect DUT to connect to bssid_a. 188 3. Make bssid_a not visible, bssid_b visible. 189 4. Expect DUT to roam to bssid_b. 190 5. Make bssid_a visible, bssid_b not visible. 191 6. Expect DUT to roam back to bssid_a. 192 """ 193 expected_con_to_a = { 194 WifiEnums.SSID_KEY: self.ent_roaming_ssid, 195 WifiEnums.BSSID_KEY: self.bssid_a, 196 } 197 expected_con_to_b = { 198 WifiEnums.SSID_KEY: self.ent_roaming_ssid, 199 WifiEnums.BSSID_KEY: self.bssid_b, 200 } 201 self.set_attns("a_on_b_off") 202 asserts.assert_true( 203 wutils.eap_connect(config, self.dut, validate_con=False), 204 "Failed to connect to %s" % config 205 ) 206 wutils.verify_wifi_connection_info(self.dut, expected_con_to_a) 207 self.log.info("Roaming from %s to %s" % (self.bssid_a, self.bssid_b)) 208 self.trigger_roaming_and_validate("b_on_a_off", expected_con_to_b) 209 self.log.info("Roaming from %s to %s" % (self.bssid_b, self.bssid_a)) 210 self.trigger_roaming_and_validate("a_on_b_off", expected_con_to_a) 211 return True 212 213 """ Tests Begin """ 214 @acts.signals.generated_test 215 def test_roaming_with_different_auth_method(self): 216 eap_configs = self.gen_eap_configs() 217 self.log.info("Testing %d different configs." % len(eap_configs)) 218 random.shuffle(eap_configs) 219 failed = self.run_generated_testcases( 220 self.roaming_between_a_and_b_logic, 221 eap_configs, 222 name_func=self.gen_eap_roaming_test_name) 223 msg = ("The following configs failed enterprise roaming test: %s" % 224 pprint.pformat(failed)) 225 asserts.assert_true(len(failed) == 0, msg) 226 """ Tests End """ 227