Merge "[WifiBaseTest] Add support for Wifi Enterprise in hostapd"
diff --git a/acts/framework/acts/test_utils/power/PowerBaseTest.py b/acts/framework/acts/test_utils/power/PowerBaseTest.py
index c5cdf77..ddd10d1 100644
--- a/acts/framework/acts/test_utils/power/PowerBaseTest.py
+++ b/acts/framework/acts/test_utils/power/PowerBaseTest.py
@@ -95,8 +95,8 @@
     def __init__(self, controllers):
 
         base_test.BaseTestClass.__init__(self, controllers)
-        BlackboxMetricLogger.for_test_case(metric_name='avg_current',
-                                           result_attr='test_result')
+        BlackboxMetricLogger.for_test_case(
+            metric_name='avg_current', result_attr='test_result')
 
     def setup_class(self):
 
@@ -445,22 +445,28 @@
         if retry_measure > MEASUREMENT_RETRY_COUNT:
             self.log.error('Test failed after maximum measurement retry')
 
-    def setup_ap_connection(self, network, bandwidth=80, connect=True):
+    def setup_ap_connection(self, network, bandwidth=80, connect=True,
+                            ap=None):
         """Setup AP and connect DUT to it.
 
         Args:
             network: the network config for the AP to be setup
             bandwidth: bandwidth of the WiFi network to be setup
             connect: indicator of if connect dut to the network after setup
+            ap: access point object, default is None to find the main AP
         Returns:
             self.brconfigs: dict for bridge interface configs
         """
         wutils.wifi_toggle_state(self.dut, True)
-        if hasattr(self, 'access_points'):
-            self.brconfigs = wputils.ap_setup(
-                self.access_point, network, bandwidth=bandwidth)
+        if not ap:
+            if hasattr(self, 'access_points'):
+                self.brconfigs = wputils.ap_setup(
+                    self.access_point, network, bandwidth=bandwidth)
+        else:
+            self.brconfigs = wputils.ap_setup(ap, network, bandwidth=bandwidth)
         if connect:
-            wutils.wifi_connect(self.dut, network)
+            wutils.wifi_connect(self.dut, network, num_of_tries=3)
+        return self.brconfigs
 
     def process_iperf_results(self):
         """Get the iperf results and process.
diff --git a/acts/tests/google/power/tel/lab/PowerTelTrafficTest.py b/acts/tests/google/power/tel/lab/PowerTelTrafficTest.py
index 7beae2b..14d6e8e 100644
--- a/acts/tests/google/power/tel/lab/PowerTelTrafficTest.py
+++ b/acts/tests/google/power/tel/lab/PowerTelTrafficTest.py
@@ -34,7 +34,11 @@
     """
 
     # Keywords for test name parameters
-    PARAM_TRAFFIC_PATTERN = 'pattern'
+    PARAM_DIRECTION = 'direction'
+    PARAM_DIRECTION_UL = 'ul'
+    PARAM_DIRECTION_DL = 'dl'
+    PARAM_DIRECTION_UL_DL = 'uldl'
+    PARAM_BANDWIDTH_LIMIT = 'blimit'
 
     # Iperf waiting time
     IPERF_MARGIN = 10
@@ -47,10 +51,12 @@
 
         super().__init__(controllers)
 
-        # Traffic pattern variables. Values are set later
-        # when reading config from test name.
-        self.traffic_pattern_dl = 0
-        self.traffic_pattern_ul = 0
+        # These variables are passed to iPerf when starting data
+        # traffic with the -b parameter to limit throughput on
+        # the application layer.
+        self.bandwidth_limit_dl = None
+        self.bandwidth_limit_ul = None
+
 
     def setup_test(self):
         """ Executed before every test case.
@@ -64,14 +70,38 @@
             return False
 
         try:
-            values = self.consume_parameter(self.PARAM_TRAFFIC_PATTERN, 2)
-            self.traffic_pattern_dl = int(values[1])
-            self.traffic_pattern_ul = int(values[2])
+            values = self.consume_parameter(self.PARAM_DIRECTION, 1)
+            self.traffic_direction = values[1]
         except:
-            self.log.error("The test name has to include parameter {} followed by two int values separated by an "
-                           "underscore indicating DL and UL traffic percentage.".format(self.PARAM_TRAFFIC_PATTERN))
+            self.log.error("The test name has to include parameter {} followed by {}/{}/{}.".format(
+                self.PARAM_DIRECTION,
+                self.PARAM_DIRECTION_UL,
+                self.PARAM_DIRECTION_DL,
+                self.PARAM_DIRECTION_UL_DL
+            ))
             return False
 
+
+        try:
+            values = self.consume_parameter(self.PARAM_BANDWIDTH_LIMIT, 2)
+
+            if values:
+              self.bandwidth_limit_dl = values[1]
+              self.bandwidth_limit_ul = values[2]
+            else:
+              self.bandwidth_limit_dl = 0
+              self.bandwidth_limit_ul = 0
+
+        except:
+            self.log.error(
+              "Parameter {} has to be followed by two strings indicating "
+              "downlink and uplink bandwidth limits for iPerf.".format(
+                self.PARAM_BANDWIDTH_LIMIT
+              )
+            )
+            return False
+
+        # No errors when parsing parameters
         return True
 
     def teardown_test(self):
@@ -130,20 +160,13 @@
         # Start iPerf traffic
         iperf_helpers = []
 
-        if self.traffic_pattern_ul > 0 and self.traffic_pattern_dl > 0:
-            # Bidirectional traffic
-            # Calculate traffic limit to do traffic shaping
-            max_t_ul = self.simulation.maximum_uplink_throughput() * 0.98 * self.traffic_pattern_ul / 100
-            max_t_dl = self.simulation.maximum_downlink_throughput() * 0.98 * self.traffic_pattern_dl / 100
-            # Initiate traffic
-            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='UL', bandwidth=max_t_ul))
-            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='DL', bandwidth=max_t_dl))
-        elif self.traffic_pattern_ul > 0:
-            # Uplink traffic
-            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='UL'))
-        elif self.traffic_pattern_dl > 0:
+        if self.traffic_direction in [self.PARAM_DIRECTION_DL, self.PARAM_DIRECTION_UL_DL]:
             # Downlink traffic
-            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='DL'))
+            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='DL', bandwidth=self.bandwidth_limit_dl))
+
+        if self.traffic_direction in [self.PARAM_DIRECTION_UL, self.PARAM_DIRECTION_UL_DL]:
+            # Uplink traffic
+            iperf_helpers.append(self.start_iperf_traffic(client_host, server_idx=len(iperf_helpers), traffic_direction='UL', bandwidth=self.bandwidth_limit_ul))
 
         return iperf_helpers
 
@@ -362,3 +385,4 @@
             return False
 
         return True
+
diff --git a/acts/tests/google/power/wifi/PowerWiFiroamingTest.py b/acts/tests/google/power/wifi/PowerWiFiroamingTest.py
index 6f9dcdd..3a03223 100644
--- a/acts/tests/google/power/wifi/PowerWiFiroamingTest.py
+++ b/acts/tests/google/power/wifi/PowerWiFiroamingTest.py
@@ -14,6 +14,7 @@
 #   See the License for the specific language governing permissions and
 #   limitations under the License.
 
+import copy
 import time
 from acts import utils
 from acts.controllers.ap_lib import hostapd_constants as hc
@@ -25,6 +26,11 @@
 
 
 class PowerWiFiroamingTest(PWBT.PowerWiFiBaseTest):
+    def teardown_test(self):
+        # Delete the brconfigs attributes as this is duplicated with one of the
+        # ap's bridge interface config
+        delattr(self, 'brconfigs')
+        super().teardown_test()
 
     # Test cases
     @test_tracker_info(uuid='392622d3-0c5c-4767-afa2-abfb2058b0b8')
@@ -33,13 +39,17 @@
         Change the attenuation level to trigger roaming between two APs
 
         """
-        self.log.info('Set attenuation to connect device to both APs')
-        self.set_attenuation(self.atten_level['zero_atten'])
         # Setup both APs
-        network_main = self.main_network[hc.BAND_2G]
-        network_aux = self.aux_network[hc.BAND_2G]
-        self.brconfigs_aux = self.setup_ap_connection(network_aux)
-        self.brconfigs_main = self.setup_ap_connection(network_main)
+        network_main = copy.deepcopy(self.main_network)[hc.BAND_2G]
+        network_aux = copy.deepcopy(self.aux_network)[hc.BAND_2G]
+        self.log.info('Set attenuation to connect device to the aux AP')
+        self.set_attenuation(self.atten_level[wc.AP_AUX])
+        self.brconfigs_aux = self.setup_ap_connection(
+            network_aux, ap=self.access_point_aux)
+        self.log.info('Set attenuation to connect device to the main AP')
+        self.set_attenuation(self.atten_level[wc.AP_MAIN])
+        self.brconfigs_main = self.setup_ap_connection(
+            network_main, ap=self.access_point_main)
         self.dut.droid.goToSleepNow()
         time.sleep(5)
         # Set attenuator to trigger roaming
@@ -51,20 +61,22 @@
     def test_screenoff_fastroaming(self):
 
         # Setup the aux AP
-        network_main = self.main_network[hc.BAND_2G]
-        network_aux = self.aux_network[hc.BAND_2G]
+        network_main = copy.deepcopy(self.main_network)[hc.BAND_2G]
+        network_aux = copy.deepcopy(self.aux_network)[hc.BAND_2G]
         # Set the same SSID for the AUX AP for fastroaming purpose
         network_aux[wc.SSID] = network_main[wc.SSID]
         # Set attenuator to connect the phone to the aux AP
         self.log.info('Set attenuation to connect device to the aux AP')
         self.set_attenuation(self.atten_level[wc.AP_AUX])
-        self.brconfigs_aux = self.setup_ap_connection(network_aux)
+        self.brconfigs_aux = self.setup_ap_connection(
+            network_aux, ap=self.access_point_aux)
         # Set attenuator to connect the phone to main AP
         self.log.info('Set attenuation to connect device to the main AP')
         self.set_attenuation(self.atten_level[wc.AP_MAIN])
-        self.brconfigs_main = self.setup_ap_connection(network_main)
-        time.sleep(5)
+        self.brconfigs_main = self.setup_ap_connection(
+            network_main, ap=self.access_point_main)
         self.dut.droid.goToSleepNow()
+        time.sleep(5)
         # Trigger fastroaming
         self.dut.log.info('Trigger fastroaming now')
         self.set_attenuation(self.atten_level[wc.AP_AUX])
@@ -74,13 +86,19 @@
     def test_screenoff_toggle_between_AP(self):
 
         # Set attenuator to connect phone to both networks
-        self.log.info('Set attenuation to connect device to both APs')
-        self.set_attenuation(self.atten_level[self.current_test_name])
+        network_main = copy.deepcopy(self.main_network)[hc.BAND_2G]
+        network_aux = copy.deepcopy(self.aux_network)[hc.BAND_2G]
         # Connect to both APs
         network_main = self.main_network[hc.BAND_2G]
         network_aux = self.aux_network[hc.BAND_2G]
-        self.brconfigs_main = self.setup_ap_connection(network_main)
-        self.brconfigs_aux = self.setup_ap_connection(network_aux)
+        self.log.info('Set attenuation to connect device to the main AP')
+        self.set_attenuation(self.atten_level[wc.AP_MAIN])
+        self.brconfigs_main = self.setup_ap_connection(
+            network_main, ap=self.access_point_main)
+        self.log.info('Set attenuation to connect device to the aux AP')
+        self.set_attenuation(self.atten_level[wc.AP_AUX])
+        self.brconfigs_aux = self.setup_ap_connection(
+            network_aux, ap=self.access_point_aux)
         self.mon_info.duration = self.toggle_interval
         self.dut.droid.goToSleepNow()
         time.sleep(5)
@@ -89,31 +107,35 @@
         for i in range(self.toggle_times):
             self.dut.log.info('Connecting to %s' % network_main[wc.SSID])
             self.dut.droid.wifiConnect(network_main)
-            file_path, avg_current = wputils.monsoon_data_collect_save(
-                self.dut, self.mon_info, self.current_test_name)
+            file_path, avg_current = self.monsoon_data_collect_save()
             self.dut.log.info('Connecting to %s' % network_aux[wc.SSID])
             self.dut.droid.wifiConnect(network_aux)
-            file_path, avg_current = wputils.monsoon_data_collect_save(
-                self.dut, self.mon_info, self.current_test_name)
+            file_path, avg_current = self.monsoon_data_collect_save()
         [plot, dt] = wputils.monsoon_data_plot(self.mon_info, file_path)
-        avg_current = dt.source.data['y0'][0]
+        self.test_result = dt.source.data['y0'][0]
         # Take Bugreport
         if self.bug_report:
             self.dut.take_bug_report(self.test_name, begin_time)
         # Path fail check
-        wputils.pass_fail_check(self, avg_current)
+        self.pass_fail_check()
 
     @test_tracker_info(uuid='e5ff95c0-b17e-425c-a903-821ba555a9b9')
     def test_screenon_toggle_between_AP(self):
 
         # Set attenuator to connect phone to both networks
-        self.log.info('Set attenuation to connect device to both APs')
-        self.set_attenuation(self.atten_level[self.current_test_name])
+        network_main = copy.deepcopy(self.main_network)[hc.BAND_2G]
+        network_aux = copy.deepcopy(self.aux_network)[hc.BAND_2G]
         # Connect to both APs
         network_main = self.main_network[hc.BAND_2G]
         network_aux = self.aux_network[hc.BAND_2G]
-        self.brconfigs_main = self.setup_ap_connection(network_main)
-        self.brconfigs_aux = self.setup_ap_connection(network_aux)
+        self.log.info('Set attenuation to connect device to the main AP')
+        self.set_attenuation(self.atten_level[wc.AP_MAIN])
+        self.brconfigs_main = self.setup_ap_connection(
+            network_main, ap=self.access_point_main)
+        self.log.info('Set attenuation to connect device to the aux AP')
+        self.set_attenuation(self.atten_level[wc.AP_AUX])
+        self.brconfigs_aux = self.setup_ap_connection(
+            network_aux, ap=self.access_point_aux)
         self.mon_info.duration = self.toggle_interval
         time.sleep(5)
         # Toggle between two networks
@@ -121,31 +143,35 @@
         for i in range(self.toggle_times):
             self.dut.log.info('Connecting to %s' % network_main[wc.SSID])
             self.dut.droid.wifiConnect(network_main)
-            file_path, avg_current = wputils.monsoon_data_collect_save(
-                self.dut, self.mon_info, self.current_test_name)
+            file_path, avg_current = self.monsoon_data_collect_save()
             self.dut.log.info('Connecting to %s' % network_aux[wc.SSID])
             self.dut.droid.wifiConnect(network_aux)
-            file_path, avg_current = wputils.monsoon_data_collect_save(
-                self.dut, self.mon_info, self.current_test_name)
+            file_path, avg_current = self.monsoon_data_collect_save()
         [plot, dt] = wputils.monsoon_data_plot(self.mon_info, file_path)
-        avg_current = dt.source.data['y0'][0]
+        self.test_result = dt.source.data['y0'][0]
         # Take Bugreport
         if self.bug_report:
             self.dut.take_bug_report(self.test_name, begin_time)
         # Path fail check
-        wputils.pass_fail_check(self, avg_current)
+        self.pass_fail_check()
 
     @test_tracker_info(uuid='a16ae337-326f-4d09-990f-42232c3c0dc4')
     def test_screenoff_wifi_wedge(self):
 
         # Set attenuator to connect phone to both networks
-        self.log.info('Set attenuation to connect device to both APs')
-        self.set_attenuation(self.atten_level['zero_atten'])
+        network_main = copy.deepcopy(self.main_network)[hc.BAND_2G]
+        network_aux = copy.deepcopy(self.aux_network)[hc.BAND_2G]
         # Connect to both APs
         network_main = self.main_network[hc.BAND_2G]
         network_aux = self.aux_network[hc.BAND_2G]
-        self.brconfigs_main = self.setup_ap_connection(network_main)
-        self.brconfigs_aux = self.setup_ap_connection(network_aux)
+        self.log.info('Set attenuation to connect device to the main AP')
+        self.set_attenuation(self.atten_level[wc.AP_MAIN])
+        self.brconfigs_main = self.setup_ap_connection(
+            network_main, ap=self.access_point_main)
+        self.log.info('Set attenuation to connect device to the aux AP')
+        self.set_attenuation(self.atten_level[wc.AP_AUX])
+        self.brconfigs_aux = self.setup_ap_connection(
+            network_aux, ap=self.access_point_aux)
         self.log.info('Forget network {}'.format(network_aux[wc.SSID]))
         wutils.wifi_forget_network(self.dut, network_aux[wc.SSID])
         self.log.info('Set attenuation to trigger wedge condition')