Merge "Merge "Test script change for better reliability" am: 627603416e" into oc-dev am: 99c4354b09
am: 08ad631576

Change-Id: I920fd27b9147db4a69caab3e0a842b16766a9c35
diff --git a/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py b/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
index e98c5e3..a389d85 100644
--- a/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
+++ b/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
@@ -21,6 +21,7 @@
 from acts import utils
 from acts.controllers import monsoon
 from acts.libs.proc import job
+from acts.controllers.ap_lib import bridge_interface as bi
 from acts.test_utils.wifi import wifi_test_utils as wutils
 from bokeh.layouts import layout
 from bokeh.models import CustomJS, ColumnDataSource
@@ -64,6 +65,7 @@
 GET_FROM_AP = 'get_from_ap'
 PHONE_BATTERY_VOLTAGE = 4.2
 MONSOON_MAX_CURRENT = 8.0
+MONSOON_RECOVER_TIME = 60
 
 
 def dut_rockbottom(ad):
@@ -121,17 +123,22 @@
 
     Args:
         test_class: the specific test class where test is running
-        avg_current: the average current as the test result
+        test_result: the average current as the test result
     """
     test_name = test_class.current_test_name
     current_threshold = test_class.threshold[test_name]
-    asserts.assert_true(
-        abs(test_result - current_threshold) / current_threshold <
-        THRESHOLD_TOLERANCE,
-        ("Measured average current in [%s]: %s, which is "
-         "more than %d percent off than acceptable threshold %.2fmA") %
-        (test_name, test_result, THRESHOLD_TOLERANCE * 100, current_threshold))
-    asserts.explicit_pass("Measurement finished for %s." % test_name)
+    if test_result:
+        asserts.assert_true(
+            abs(test_result - current_threshold) / current_threshold <
+            THRESHOLD_TOLERANCE,
+            ("Measured average current in [%s]: %s, which is "
+             "more than %d percent off than acceptable threshold %.2fmA") %
+            (test_name, test_result, THRESHOLD_TOLERANCE * 100,
+             current_threshold))
+        asserts.explicit_pass("Measurement finished for %s." % test_name)
+    else:
+        asserts.fail(
+            "Something happened, measurement is not complete, test failed")
 
 
 def monsoon_data_collect_save(ad, mon_info, test_name):
@@ -152,21 +159,29 @@
                    measurement
         avg_current: the average current of the test
     """
-    log = logging.getLogger()
-    log.info("Starting power measurement with monsoon box")
-    tag = (test_name + '_' + ad.model + '_' + ad.build_info['build_id'])
-    #Resets the battery status right before the test started
-    ad.adb.shell(RESET_BATTERY_STATS)
-    #Start the power measurement using monsoon
-    result = mon_info['dut'].measure_power(
-        mon_info['freq'],
-        mon_info['duration'],
-        tag=tag,
-        offset=mon_info['offset'])
-    data_path = os.path.join(mon_info['data_path'], "%s.txt" % tag)
-    avg_current = result.average_current
-    monsoon.MonsoonData.save_to_text_file([result], data_path)
-    log.info("Power measurement done")
+    try:
+        log = logging.getLogger()
+        log.info("Starting power measurement with monsoon box")
+        tag = (test_name + '_' + ad.model + '_' + ad.build_info['build_id'])
+        #Resets the battery status right before the test started
+        ad.adb.shell(RESET_BATTERY_STATS)
+        #Start the power measurement using monsoon
+        result = mon_info['dut'].measure_power(
+            mon_info['freq'],
+            mon_info['duration'],
+            tag=tag,
+            offset=mon_info['offset'])
+        data_path = os.path.join(mon_info['data_path'], "%s.txt" % tag)
+        avg_current = result.average_current
+        monsoon.MonsoonData.save_to_text_file([result], data_path)
+        log.info("Power measurement done")
+    except monsoon.MonsoonError:
+        # For exceptions due to Monsoon error, wait until Monsoon recovers
+        log.warning(
+            'Monsoon Exception happened during data collection, stop this test and wait for the system to recover'
+        )
+        avg_current = 0
+        time.sleep(MONSOON_RECOVER_TIME)
 
     return data_path, avg_current
 
@@ -211,14 +226,15 @@
     color = ['navy'] * len(current_data)
 
     #Preparing the data and source link for bokehn java callback
-    source = ColumnDataSource(data=dict(
-        x0=time_relative, y0=current_data, color=color))
-    s2 = ColumnDataSource(data=dict(
-        z0=[mon_info['duration']],
-        y0=[round(avg_current, 2)],
-        x0=[round(avg_current * voltage, 2)],
-        z1=[round(avg_current * voltage * mon_info['duration'], 2)],
-        z2=[round(avg_current * mon_info['duration'], 2)]))
+    source = ColumnDataSource(
+        data=dict(x0=time_relative, y0=current_data, color=color))
+    s2 = ColumnDataSource(
+        data=dict(
+            z0=[mon_info['duration']],
+            y0=[round(avg_current, 2)],
+            x0=[round(avg_current * voltage, 2)],
+            z1=[round(avg_current * voltage * mon_info['duration'], 2)],
+            z2=[round(avg_current * mon_info['duration'], 2)]))
     #Setting up data table for the output
     columns = [
         TableColumn(field='z0', title='Total Duration (s)'),
@@ -357,6 +373,8 @@
         network: dict with information of the network, including ssid, password
                  bssid, channel etc.
         bandwidth: the operation bandwidth for the AP, default 80MHz
+    Returns:
+        brconfigs: the bridge interface configs
     """
     log = logging.getLogger()
     bss_settings = []
@@ -377,8 +395,13 @@
         profile_name='whirlwind',
         iface_wlan_2g=ap.wlan_2g,
         iface_wlan_5g=ap.wlan_5g)
+    config_bridge = ap.generate_bridge_configs(channel)
+    brconfigs = bi.BridgeInterfaceConfigs(config_bridge[0], config_bridge[1],
+                                          config_bridge[2])
+    ap.bridge.startup(brconfigs)
     ap.start_ap(config)
     log.info("AP started on channel {} with SSID {}".format(channel, ssid))
+    return brconfigs
 
 
 def bokeh_plot(data_sets, legends, fig_property, output_file_path=None):
diff --git a/acts/tests/google/power/wifi/PowerbaselineTest.py b/acts/tests/google/power/wifi/PowerbaselineTest.py
index baee4e5..10da555 100644
--- a/acts/tests/google/power/wifi/PowerbaselineTest.py
+++ b/acts/tests/google/power/wifi/PowerbaselineTest.py
@@ -49,14 +49,14 @@
 
     def teardown_class(self):
         """Tearing down the entire test class.
-        
+
         """
         self.log.info('Tearing down the test class')
         self.mon.usb('on')
 
     def teardown_test(self):
         """Tearing down the test case.
-        
+
         """
         self.log.info('Tearing down the test')
         self.mon.usb('on')
diff --git a/acts/tests/google/power/wifi/PowerdtimTest.py b/acts/tests/google/power/wifi/PowerdtimTest.py
index 0f4f041..7fc9aef 100644
--- a/acts/tests/google/power/wifi/PowerdtimTest.py
+++ b/acts/tests/google/power/wifi/PowerdtimTest.py
@@ -52,6 +52,7 @@
         Bring down the AP interface and connect device back on.
         """
         self.log.info('Tearing down the test case')
+        self.access_point.bridge.teardown(self.brconfigs)
         self.access_point.close()
         self.mon.usb('on')
 
@@ -89,8 +90,9 @@
             self.attenuators[i].set_atten(self.atten_level['zero_atten'][i])
             for i in range(self.num_atten)
         ]
-        self.log.info('Set attenuation level to connect the main AP')
-        wputils.ap_setup(self.access_point, network)
+        self.log.info('Set attenuation level to connect to the AP')
+        # Set up the AP
+        self.brconfigs = wputils.ap_setup(self.access_point, network, 20)
         wutils.wifi_connect(self.dut, network)
         if screen_status == 'OFF':
             self.dut.droid.goToSleepNow()
diff --git a/acts/tests/google/power/wifi/PowermulticastTest.py b/acts/tests/google/power/wifi/PowermulticastTest.py
index 480a0bb..c25e9e1 100644
--- a/acts/tests/google/power/wifi/PowermulticastTest.py
+++ b/acts/tests/google/power/wifi/PowermulticastTest.py
@@ -20,7 +20,6 @@
 
 from acts import base_test
 from acts import utils
-from acts.controllers.ap_lib import bridge_interface as bi
 from acts.controllers.ap_lib import hostapd_constants as hc
 from acts.test_decorators import test_tracker_info
 from acts.test_utils.wifi import wifi_test_utils as wutils
@@ -110,13 +109,8 @@
             self.attenuators[attn].set_atten(
                 self.atten_level['zero_atten'][attn])
         self.log.info('Set attenuation level to all zero')
-        channel = network['channel']
         iface_eth = self.pkt_sender.interface
-        brconfigs = self.access_point.generate_bridge_configs(channel)
-        self.brconfigs = bi.BridgeInterfaceConfigs(brconfigs[0], brconfigs[1],
-                                                   brconfigs[2])
-        self.access_point.bridge.startup(self.brconfigs)
-        wputils.ap_setup(self.access_point, network)
+        self.brconfigs = wputils.ap_setup(self.access_point, network)
         wutils.wifi_connect(self.dut, network)
 
         # Wait for DHCP with timeout of 60 seconds
diff --git a/acts/tests/google/power/wifi/PowerroamingTest.py b/acts/tests/google/power/wifi/PowerroamingTest.py
index 1c1ca82..cf13e9f 100644
--- a/acts/tests/google/power/wifi/PowerroamingTest.py
+++ b/acts/tests/google/power/wifi/PowerroamingTest.py
@@ -56,6 +56,8 @@
         """
         self.log.info('Tearing down the test case')
         self.mon.usb('on')
+        self.access_point_main.bridge.teardown(self.brconfigs_main)
+        self.access_point_aux.bridge.teardown(self.brconfigs_aux)
         for ap in self.access_points:
             ap.close()
 
@@ -82,9 +84,11 @@
         """
         # Setup both APs
         network_main = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_main, network_main)
+        self.brconfigs_main = wputils.ap_setup(self.access_point_main,
+                                               network_main)
         network_aux = self.aux_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_aux, network_aux)
+        self.brconfigs_aux = wputils.ap_setup(self.access_point_aux,
+                                              network_aux)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
@@ -127,7 +131,8 @@
         network_aux = 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]
-        wputils.ap_setup(self.access_point_aux, network_aux)
+        self.brconfigs_aux = wputils.ap_setup(self.access_point_aux,
+                                              network_aux)
         # Set attenuator and add two networks to the phone
         self.log.info('Set attenuation to connect device to the aux AP')
         [
@@ -137,7 +142,8 @@
         wutils.wifi_connect(self.dut, network_aux)
         time.sleep(5)
         # Setup the main AP
-        wputils.ap_setup(self.access_point_main, network_main)
+        self.brconfigs_main = wputils.ap_setup(self.access_point_main,
+                                               network_main)
         # Set attenuator to connect the phone to main AP
         self.log.info('Set attenuation to connect device to the main AP')
         [
@@ -168,9 +174,11 @@
 
         # Setup both APs
         network_main = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_main, network_main)
+        self.brconfigs_main = wputils.ap_setup(self.access_point_main,
+                                               network_main)
         network_aux = self.aux_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_aux, network_aux)
+        self.brconfigs_aux = wputils.ap_setup(self.access_point_aux,
+                                              network_aux)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
@@ -207,9 +215,11 @@
 
         # Setup both APs
         network_main = self.main_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point_main, network_main)
+        self.brconfigs_main = wputils.ap_setup(self.access_point_main,
+                                               network_main)
         network_aux = self.aux_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point_aux, network_aux)
+        self.brconfigs_aux = wputils.ap_setup(self.access_point_aux,
+                                              network_aux)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
@@ -244,9 +254,11 @@
 
         # Setup both APs
         network_main = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_main, network_main)
+        self.brconfigs_main = wputils.ap_setup(self.access_point_main,
+                                               network_main)
         network_aux = self.aux_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point_aux, network_aux)
+        self.brconfigs_aux = wputils.ap_setup(self.access_point_aux,
+                                              network_aux)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
diff --git a/acts/tests/google/power/wifi/PowerscanTest.py b/acts/tests/google/power/wifi/PowerscanTest.py
index 38fe6eb..0363e05 100644
--- a/acts/tests/google/power/wifi/PowerscanTest.py
+++ b/acts/tests/google/power/wifi/PowerscanTest.py
@@ -89,6 +89,7 @@
         Bring down the AP interface and connect device back online
         """
         self.log.info('Tearing down the test case')
+        self.access_point.bridge.teardown(self.brconfigs)
         self.access_point.close()
         self.mon.usb('on')
 
@@ -98,12 +99,20 @@
         self.access_point.close()
         self.mon.usb('on')
 
-    def powrapk_scan_test_func(self, scan_command):
+    def powrapk_scan_test_func(self, scan_command, band):
         """Test function for power.apk triggered scans.
         Args:
             scan_command: the adb shell command to trigger scans
 
         """
+        network = self.main_network[band]
+        self.brconfigs = wputils.ap_setup(self.access_point, network)
+        self.log.info('Set attenuation to get high RSSI at {}'.format(band))
+        [
+            self.attenuators[i].set_atten(
+                self.atten_level[self.current_test_name][i])
+            for i in range(self.num_atten)
+        ]
         self.mon_info['offset'] == 0
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
@@ -128,111 +137,47 @@
     @test_tracker_info(uuid='e5539b01-e208-43c6-bebf-6f1e73d8d8cb')
     def test_single_shot_scan_2g_highRSSI(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation to get high RSSI at 2g')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_2G)
 
     @test_tracker_info(uuid='14c5a762-95bc-40ea-9fd4-27126df7d86c')
     def test_single_shot_scan_2g_lowRSSI(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation to get low RSSI at 2g')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_2G)
 
     @test_tracker_info(uuid='a6506600-c567-43b5-9c25-86b505099b97')
     def test_single_shot_scan_2g_noAP(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation so all AP is out of reach ')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_2G)
 
     @test_tracker_info(uuid='1a458248-1159-4c8e-a39f-92fc9e69c4dd')
     def test_single_shot_scan_5g_highRSSI(self):
 
-        network = self.main_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation to get high RSSI at 5g')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_5G)
 
     @test_tracker_info(uuid='bd4da426-a621-4131-9f89-6e5a77f321d2')
     def test_single_shot_scan_5g_lowRSSI(self):
 
-        network = self.main_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation to get low RSSI at 5g')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_5G)
 
     @test_tracker_info(uuid='288b3add-8925-4803-81c0-53debf157ffc')
     def test_single_shot_scan_5g_noAP(self):
 
-        network = self.main_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point, network)
-        self.log.info('Set attenuation so all AP is out of reach ')
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN)
+        self.powrapk_scan_test_func(self.SINGLE_SHOT_SCAN, hc.BAND_5G)
 
     @test_tracker_info(uuid='f401c66c-e515-4f51-8ef2-2a03470d8ff2')
     def test_background_scan(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        self.powrapk_scan_test_func(self.BACKGROUND_SCAN)
+        self.powrapk_scan_test_func(self.BACKGROUND_SCAN, hc.BAND_5G)
 
     @test_tracker_info(uuid='fe38c1c7-937c-42c0-9381-98356639df8f')
     def test_wifi_scan_2g(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.WIFI_SCAN)
+        self.powrapk_scan_test_func(self.WIFI_SCAN, hc.BAND_2G)
 
     @test_tracker_info(uuid='8eedefd1-3a08-4ac2-ba55-5eb438def3d4')
     def test_wifi_scan_5g(self):
 
-        network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
-        [
-            self.attenuators[i].set_atten(
-                self.atten_level[self.current_test_name][i])
-            for i in range(self.num_atten)
-        ]
-        self.powrapk_scan_test_func(self.WIFI_SCAN)
+        self.powrapk_scan_test_func(self.WIFI_SCAN, hc.BAND_5G)
 
     @test_tracker_info(uuid='ff5ea952-ee31-4968-a190-82935ce7a8cb')
     def test_scan_wifidisconnected_turnonscreen(self):
@@ -259,7 +204,7 @@
     def test_scan_wificonnected_turnonscreen(self):
 
         network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
+        self.brconfigs = wputils.ap_setup(self.access_point, network)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
@@ -291,7 +236,7 @@
     def test_scan_screenoff_below_rssi_threshold(self):
 
         network = self.main_network[hc.BAND_2G]
-        wputils.ap_setup(self.access_point, network)
+        self.brconfigs = wputils.ap_setup(self.access_point, network)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
@@ -325,7 +270,7 @@
     def test_scan_screenoff_lost_wificonnection(self):
 
         network = self.main_network[hc.BAND_5G]
-        wputils.ap_setup(self.access_point, network)
+        self.brconfigs = wputils.ap_setup(self.access_point, network)
         # Initialize the dut to rock-bottom state
         wputils.dut_rockbottom(self.dut)
         wutils.wifi_toggle_state(self.dut, True)
diff --git a/acts/tests/google/power/wifi/PowertrafficTest.py b/acts/tests/google/power/wifi/PowertrafficTest.py
index fd12d4a..a149504 100644
--- a/acts/tests/google/power/wifi/PowertrafficTest.py
+++ b/acts/tests/google/power/wifi/PowertrafficTest.py
@@ -20,7 +20,6 @@
 import time
 from acts import base_test
 from acts import utils
-from acts.controllers.ap_lib import bridge_interface as bi
 from acts.test_decorators import test_tracker_info
 from acts.test_utils.wifi import wifi_test_utils as wutils
 from acts.test_utils.wifi import wifi_power_test_utils as wputils
@@ -107,12 +106,8 @@
 
         # Set up the AP
         network = self.main_network[band]
-        channel = network['channel']
-        configs = self.access_point.generate_bridge_configs(channel)
-        self.brconfigs = bi.BridgeInterfaceConfigs(configs[0], configs[1],
-                                                   configs[2])
-        self.access_point.bridge.startup(self.brconfigs)
-        wputils.ap_setup(self.access_point, network, bandwidth)
+        self.brconfigs = wputils.ap_setup(self.access_point, network,
+                                          bandwidth)
 
         # Wait for DHCP on the ethernet port and get IP as Iperf server address
         # Time out in 60 seconds if not getting DHCP address
@@ -180,7 +175,7 @@
         # Monsoon Power data plot with IPerf throughput information
         tag = '_RSSI_{0:d}dBm_Throughput_{1:.2f}Mbps'.format(RSSI, throughput)
         wputils.monsoon_data_plot(self.mon_info, file_path, tag)
-        
+
         # Take Bugreport
         if bool(self.bug_report) == True:
             self.dut.take_bug_report(self.test_name, begin_time)