1#!/usr/bin/env python3.4 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the 'License'); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an 'AS IS' BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17from retry import retry 18 19import acts_contrib.test_utils.power.PowerBaseTest as PBT 20from acts_contrib.test_utils.wifi import wifi_test_utils as wutils 21from acts_contrib.test_utils.wifi import wifi_power_test_utils as wputils 22from acts_contrib.test_utils.power import plot_utils 23 24IPERF_DURATION = 'iperf_duration' 25INITIAL_ATTEN = [0, 0, 90, 90] 26IPERF_TAIL = 5 27 28 29class PowerWiFiBaseTest(PBT.PowerBaseTest): 30 """Base class for WiFi power related tests. 31 32 Inherited from the PowerBaseTest class 33 """ 34 def setup_class(self): 35 36 super().setup_class() 37 if hasattr(self, 'access_points'): 38 self.access_point = self.access_points[0] 39 self.access_point_main = self.access_points[0] 40 if len(self.access_points) > 1: 41 self.access_point_aux = self.access_points[1] 42 if hasattr(self, 'attenuators'): 43 self.set_attenuation(INITIAL_ATTEN) 44 if hasattr(self, 'network_file'): 45 self.networks = self.unpack_custom_file(self.network_file, False) 46 self.main_network = self.networks['main_network'] 47 self.aux_network = self.networks['aux_network'] 48 if hasattr(self, 'packet_senders'): 49 self.pkt_sender = self.packet_senders[0] 50 if hasattr(self, 'iperf_servers'): 51 self.iperf_server = self.iperf_servers[0] 52 if self.iperf_duration: 53 self.mon_duration = self.iperf_duration - self.mon_offset - IPERF_TAIL 54 self.mon_info = self.create_monsoon_info() 55 try: 56 self._set_country_code() 57 except Exception as e: 58 self.log.warning('error in set country code with %s', e) 59 country_code = self.dut.droid.wifiGetCountryCode() 60 self.log.info('the country code is %s', country_code) 61 62 @retry(tries=5, delay=10) 63 def _set_country_code(self): 64 wutils.wifi_toggle_state(self.dut, True) 65 wutils.set_wifi_country_code(self.dut, 'US') 66 67 def teardown_test(self): 68 """Tear down necessary objects after test case is finished. 69 70 Bring down the AP interface, delete the bridge interface, stop the 71 packet sender, and reset the ethernet interface for the packet sender 72 """ 73 super().teardown_test() 74 if hasattr(self, 'pkt_sender'): 75 self._safe_teardown('pkt_sender stop sending', 76 self.pkt_sender.stop_sending, 77 ignore_status=True) 78 if hasattr(self, 'brconfigs'): 79 self._safe_teardown('brconfigs', self.access_point.bridge.teardown, 80 self.brconfigs) 81 delattr(self, 'brconfigs') 82 if hasattr(self, 'brconfigs_main'): 83 self._safe_teardown('brconfigs_main', 84 self.access_point_main.bridge.teardown, 85 self.brconfigs_main) 86 delattr(self, 'brconfigs_main') 87 if hasattr(self, 'brconfigs_aux'): 88 self._safe_teardown('brconfigs_aux', 89 self.access_point_aux.bridge.teardown, 90 self.brconfigs_aux) 91 delattr(self, 'brconfigs_aux') 92 if hasattr(self, 'access_points'): 93 for ap in self.access_points: 94 self._safe_teardown('access point {}'.format(ap.identifier), 95 ap.close) 96 if hasattr(self, 'pkt_sender'): 97 self._safe_teardown('pkt_sender reset host interface', 98 wputils.reset_host_interface, 99 self.pkt_sender.interface) 100 if hasattr(self, 'iperf_server'): 101 self._safe_teardown('iperf_server', self.iperf_server.stop); 102 103 def _safe_teardown(self, attr, teardown_method, *arg, **kwargs): 104 """Teardown the object with try block. 105 106 Adds a try block for each teardown step to make sure that each 107 teardown step is executed. 108 109 Args: 110 attr: the teardown attribute description for logging 111 teardown_method: the method for teardown 112 *arg: positional arguments for teardown_method 113 **kwargs: keyword arguments for teardown_method 114 """ 115 try: 116 self.log.info('teardown %s with %s', attr, teardown_method.__name__) 117 teardown_method(*arg, **kwargs) 118 except Exception as e: 119 self.log.warning('teardown of %s fails with %s', attr, e) 120 121 def teardown_class(self): 122 """Clean up the test class after tests finish running 123 124 """ 125 super().teardown_class() 126 if hasattr(self, 'access_points'): 127 for ap in self.access_points: 128 ap.close() 129 130 def setup_ap_connection(self, 131 network, 132 bandwidth=80, 133 connect=True, 134 ap=None, 135 dtim_period=None): 136 """Setup AP and connect DUT to it. 137 138 Args: 139 network: the network config for the AP to be setup 140 bandwidth: bandwidth of the WiFi network to be setup 141 connect: indicator of if connect dut to the network after setup 142 ap: access point object, default is None to find the main AP 143 dtim_period: the dtim period of access point 144 Returns: 145 self.brconfigs: dict for bridge interface configs 146 """ 147 wutils.wifi_toggle_state(self.dut, True) 148 if not dtim_period: 149 dtim_period = self.ap_dtim_period 150 if not ap: 151 if hasattr(self, 'access_points'): 152 self.brconfigs = wputils.ap_setup( 153 self.access_point, 154 network, 155 bandwidth=bandwidth, 156 dtim_period=dtim_period) 157 else: 158 self.brconfigs = wputils.ap_setup( 159 ap, network, bandwidth=bandwidth, dtim_period=dtim_period) 160 if connect: 161 wutils.wifi_connect(self.dut, network, num_of_tries=3) 162 163 if ap or (not ap and hasattr(self, 'access_points')): 164 return self.brconfigs 165 166 def collect_power_data(self): 167 """Measure power, plot and check pass/fail. 168 169 If IPERF is run, need to pull iperf results and attach it to the plot. 170 """ 171 samples = super().collect_power_data() 172 tag = '' 173 if self.iperf_duration: 174 throughput = self.process_iperf_results() 175 plot_title = ('{0}_{1}_{2}_RSSI_{3:d}dBm_Throughput_{4:.2f}' 176 'Mbps'.format(self.test_name, 177 self.dut.model, 178 self.dut.build_info['build_id'], 179 self.RSSI, 180 throughput)) 181 plot_utils.current_waveform_plot(samples, self.mon_voltage, 182 self.mon_info.data_path, 183 plot_title) 184 return samples 185 186 def setup_test(self): 187 """Set up test specific parameters or configs. 188 189 """ 190 super().setup_test() 191 192 wutils.reset_wifi(self.dut) 193 wutils.wifi_toggle_state(self.dut, False) 194