Omar El Ayach | b880808 | 2018-03-04 01:05:39 +0000 | [diff] [blame] | 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 | |
| 17 | import json |
| 18 | import logging |
| 19 | import math |
| 20 | import os |
| 21 | import re |
| 22 | import time |
| 23 | from acts import asserts |
| 24 | from acts import base_test |
| 25 | from acts import utils |
| 26 | from acts.test_decorators import test_tracker_info |
| 27 | from acts.test_utils.wifi import wifi_power_test_utils as wputils |
| 28 | from acts.test_utils.wifi import wifi_retail_ap as retail_ap |
| 29 | from acts.test_utils.wifi import wifi_test_utils as wutils |
| 30 | |
| 31 | SHORT_SLEEP = 1 |
| 32 | MED_SLEEP = 6 |
| 33 | STATION_DUMP = "iw wlan0 station dump" |
| 34 | SCAN = "wpa_cli scan" |
| 35 | SCAN_RESULTS = "wpa_cli scan_results" |
| 36 | SIGNAL_POLL = "wpa_cli signal_poll" |
| 37 | CONST_3dB = 3.01029995664 |
| 38 | RSSI_ERROR_VAL = float("nan") |
| 39 | |
| 40 | |
| 41 | class WifiRssiTest(base_test.BaseTestClass): |
| 42 | def __init__(self, controllers): |
| 43 | base_test.BaseTestClass.__init__(self, controllers) |
| 44 | |
| 45 | def setup_class(self): |
| 46 | self.dut = self.android_devices[0] |
| 47 | req_params = ["test_params", "main_network"] |
| 48 | opt_params = ["RetailAccessPoints"] |
| 49 | self.unpack_userparams(req_params, opt_params) |
| 50 | self.num_atten = self.attenuators[0].instrument.num_atten |
| 51 | self.iperf_server = self.iperf_servers[0] |
| 52 | self.access_points = retail_ap.create(self.RetailAccessPoints) |
| 53 | self.access_point = self.access_points[0] |
| 54 | self.log_path = os.path.join(logging.log_path, "results") |
| 55 | utils.create_dir(self.log_path) |
| 56 | self.log.info("Access Point Configuration: {}".format( |
| 57 | self.access_point.ap_settings)) |
| 58 | self.testclass_results = [] |
| 59 | |
| 60 | def teardown_test(self): |
| 61 | self.iperf_server.stop() |
| 62 | |
| 63 | def pass_fail_check_rssi_vs_attenuation(self, postprocessed_results): |
| 64 | """Check the test result and decide if it passed or failed. |
| 65 | |
| 66 | Checks the RSSI test result and compares and compute its deviation from |
| 67 | the predicted RSSI. This computation is done for all reported RSSI |
| 68 | values. The test fails if any of the RSSI values specified in |
| 69 | rssi_under_test have an average error beyond what is specified in the |
| 70 | configuration file. |
| 71 | |
| 72 | Args: |
| 73 | result: dict containing attenuation, rssi, and other meta |
| 74 | data. This dict is the output of self.post_process_results |
| 75 | """ |
| 76 | |
| 77 | error_data = { |
| 78 | "signal_poll_rssi": [ |
| 79 | postprocessed_results["mean_signal_poll_rssi"][idx] - |
| 80 | postprocessed_results["predicted_rssi"][idx] |
| 81 | for idx in range(len(postprocessed_results["predicted_rssi"])) |
| 82 | ], |
| 83 | "signal_poll_avg_rssi": [ |
| 84 | postprocessed_results["mean_signal_poll_avg_rssi"][idx] - |
| 85 | postprocessed_results["predicted_rssi"][idx] |
| 86 | for idx in range(len(postprocessed_results["predicted_rssi"])) |
| 87 | ], |
| 88 | "scan_rssi": [ |
| 89 | postprocessed_results["mean_scan_rssi"][idx] - |
| 90 | postprocessed_results["predicted_rssi"][idx] |
| 91 | for idx in range(len(postprocessed_results["predicted_rssi"])) |
| 92 | ], |
| 93 | "chain_0_rssi": [ |
| 94 | postprocessed_results["mean_chain_0_rssi"][idx] + CONST_3dB - |
| 95 | postprocessed_results["predicted_rssi"][idx] |
| 96 | for idx in range(len(postprocessed_results["predicted_rssi"])) |
| 97 | ], |
| 98 | "chain_1_rssi": [ |
| 99 | postprocessed_results["mean_chain_1_rssi"][idx] + CONST_3dB - |
| 100 | postprocessed_results["predicted_rssi"][idx] |
| 101 | for idx in range(len(postprocessed_results["predicted_rssi"])) |
| 102 | ] |
| 103 | } |
| 104 | |
| 105 | test_failed = False |
| 106 | test_message = "" |
| 107 | for key, val in error_data.items(): |
| 108 | # Compute the error metrics ignoring invalid RSSI readings |
| 109 | # If all readings invalid, set error to RSSI_ERROR_VAL |
| 110 | filtered_errors = [x for x in val if not math.isnan(x)] |
| 111 | if filtered_errors: |
| 112 | avg_error = sum([abs(x) for x in filtered_errors |
| 113 | ]) / len(filtered_errors) |
| 114 | avg_shift = sum(filtered_errors) / len(filtered_errors) |
| 115 | else: |
| 116 | avg_error = RSSI_ERROR_VAL |
| 117 | rssi_failure = (avg_error > self.test_params["abs_tolerance"] |
| 118 | ) or math.isnan(avg_error) |
| 119 | if rssi_failure and key in self.test_params["rssi_under_test"]: |
| 120 | test_message = test_message + ( |
| 121 | "{} failed. Average error is {:.2f} dB. " |
| 122 | "Average shift is {:.2f} dB.\n").format( |
| 123 | key, avg_error, avg_shift) |
| 124 | test_failed = True |
| 125 | elif rssi_failure: |
| 126 | test_message = test_message + ( |
| 127 | "{} failed (ignored). Average error is {:.2f} dB. " |
| 128 | "Average shift is {:.2f} dB.\n").format( |
| 129 | key, avg_error, avg_shift) |
| 130 | else: |
| 131 | test_message = test_message + ( |
| 132 | "{} passed. Average error is {:.2f} dB. " |
| 133 | "Average shift is {:.2f} dB.\n").format( |
| 134 | key, avg_error, avg_shift) |
| 135 | |
| 136 | if test_failed: |
| 137 | asserts.fail(test_message) |
| 138 | asserts.explicit_pass(test_message) |
| 139 | |
| 140 | def post_process_results(self, rssi_result): |
| 141 | """Saves plots and JSON formatted results. |
| 142 | |
| 143 | Args: |
| 144 | rssi_result: dict containing attenuation, rssi and other meta |
| 145 | data |
| 146 | Returns: |
| 147 | postprocessed_results: compiled arrays of RSSI measurements used in |
| 148 | pass/fail check |
| 149 | """ |
| 150 | # Save output as text file |
| 151 | test_name = self.current_test_name |
| 152 | results_file_path = "{}/{}.json".format(self.log_path, |
| 153 | self.current_test_name) |
| 154 | with open(results_file_path, 'w') as results_file: |
| 155 | json.dump(rssi_result, results_file) |
| 156 | # Plot and save |
| 157 | total_attenuation = [ |
| 158 | att + rssi_result["fixed_attenuation"] |
| 159 | for att in rssi_result["attenuation"] |
| 160 | ] |
| 161 | # Compile results into arrays of RSSIs suitable for plotting |
| 162 | postprocessed_results = { |
| 163 | "total_attenuation": |
| 164 | total_attenuation, |
| 165 | "mean_signal_poll_rssi": [ |
| 166 | x["connected_rssi"]["mean_signal_poll_rssi"] |
| 167 | for x in rssi_result["rssi_result"] |
| 168 | ], |
| 169 | "mean_signal_poll_avg_rssi": [ |
| 170 | x["connected_rssi"]["mean_signal_poll_avg_rssi"] |
| 171 | for x in rssi_result["rssi_result"] |
| 172 | ], |
| 173 | "mean_scan_rssi": [ |
| 174 | x["scan_rssi"][rssi_result["connected_bssid"]]["avg_rssi"] |
| 175 | for x in rssi_result["rssi_result"] |
| 176 | ], |
| 177 | "mean_chain_0_rssi": [ |
| 178 | x["connected_rssi"]["mean_chain_0_rssi"] |
| 179 | for x in rssi_result["rssi_result"] |
| 180 | ], |
| 181 | "mean_chain_1_rssi": [ |
| 182 | x["connected_rssi"]["mean_chain_1_rssi"] |
| 183 | for x in rssi_result["rssi_result"] |
| 184 | ], |
| 185 | "predicted_rssi": |
| 186 | [rssi_result["ap_tx_power"] - att for att in total_attenuation] |
| 187 | } |
| 188 | data_sets = [[ |
| 189 | total_attenuation, total_attenuation, total_attenuation, |
| 190 | total_attenuation, total_attenuation, total_attenuation |
| 191 | ], [ |
| 192 | postprocessed_results["mean_signal_poll_rssi"], |
| 193 | postprocessed_results["mean_signal_poll_avg_rssi"], |
| 194 | postprocessed_results["mean_scan_rssi"], |
| 195 | postprocessed_results["mean_chain_0_rssi"], |
| 196 | postprocessed_results["mean_chain_1_rssi"], |
| 197 | postprocessed_results["predicted_rssi"] |
| 198 | ]] |
| 199 | legends = [ |
| 200 | "Signal Poll RSSI", "Signal Poll AVG_RSSI", "Scan RSSI", |
| 201 | "Chain 0 RSSI", "Chain 1 RSSI", "Predicted RSSI" |
| 202 | ] |
| 203 | x_label = 'Attenuation (dB)' |
| 204 | y_label = 'RSSI (dBm)' |
| 205 | fig_property = { |
| 206 | "title": test_name, |
| 207 | "x_label": x_label, |
| 208 | "y_label": y_label, |
| 209 | "linewidth": 3, |
| 210 | "markersize": 10 |
| 211 | } |
| 212 | output_file_path = "{}/{}.html".format(self.log_path, test_name) |
| 213 | wputils.bokeh_plot( |
| 214 | data_sets, |
| 215 | legends, |
| 216 | fig_property, |
| 217 | shaded_region=None, |
| 218 | output_file_path=output_file_path) |
| 219 | return postprocessed_results |
| 220 | |
| 221 | def get_scan_rssi(self, tracked_bssids, num_measurements=1): |
| 222 | """Gets scan RSSI for specified BSSIDs. |
| 223 | |
| 224 | Args: |
| 225 | tracked_bssids: array of BSSIDs to gather RSSI data for |
| 226 | num_measurements: number of scans done, and RSSIs collected |
| 227 | Returns: |
| 228 | scan_rssi: dict containing the measurement results as well as the |
| 229 | average scan RSSI for all BSSIDs in tracked_bssids |
| 230 | """ |
| 231 | scan_rssi = {} |
| 232 | for bssid in tracked_bssids: |
| 233 | scan_rssi[bssid] = {"rssi": [], "avg_rssi": None} |
| 234 | for idx in range(num_measurements): |
| 235 | scan_output = self.dut.adb.shell(SCAN) |
| 236 | time.sleep(MED_SLEEP) |
| 237 | scan_output = self.dut.adb.shell(SCAN_RESULTS) |
| 238 | for bssid in tracked_bssids: |
| 239 | bssid_result = re.search( |
| 240 | bssid + ".*", scan_output, flags=re.IGNORECASE) |
| 241 | if bssid_result: |
| 242 | bssid_result = bssid_result.group(0).split("\t") |
| 243 | scan_rssi[bssid]["rssi"].append(int(bssid_result[2])) |
| 244 | else: |
| 245 | scan_rssi[bssid]["rssi"].append(RSSI_ERROR_VAL) |
| 246 | # Compute mean RSSIs. Only average valid readings. |
| 247 | # Output RSSI_ERROR_VAL if no readings found. |
| 248 | for key, val in scan_rssi.items(): |
| 249 | filtered_rssi_values = [ |
| 250 | x for x in val["rssi"] if not math.isnan(x) |
| 251 | ] |
| 252 | if filtered_rssi_values: |
| 253 | scan_rssi[key]["avg_rssi"] = sum(filtered_rssi_values) / len( |
| 254 | filtered_rssi_values) |
| 255 | else: |
| 256 | scan_rssi[key]["avg_rssi"] = RSSI_ERROR_VAL |
| 257 | return scan_rssi |
| 258 | |
| 259 | def get_connected_rssi(self, |
| 260 | num_measurements=1, |
| 261 | polling_frequency=SHORT_SLEEP): |
| 262 | """Gets all RSSI values reported for the connected access point/BSSID. |
| 263 | |
| 264 | Args: |
| 265 | num_measurements: number of scans done, and RSSIs collected |
| 266 | polling_frequency: time to wait between RSSI measurements |
| 267 | Returns: |
| 268 | connected_rssi: dict containing the measurements results for |
| 269 | all reported RSSI values (signal_poll, per chain, etc.) and their |
| 270 | averages |
| 271 | """ |
| 272 | connected_rssi = { |
| 273 | "signal_poll_rssi": [], |
| 274 | "signal_poll_avg_rssi": [], |
| 275 | "chain_0_rssi": [], |
| 276 | "chain_1_rssi": [] |
| 277 | } |
| 278 | for idx in range(num_measurements): |
| 279 | # Get signal poll RSSI |
| 280 | signal_poll_output = self.dut.adb.shell(SIGNAL_POLL) |
| 281 | match = re.search("RSSI=.*", signal_poll_output) |
| 282 | if match: |
| 283 | temp_rssi = int(match.group(0).split("=")[1]) |
| 284 | if temp_rssi == -9999: |
| 285 | connected_rssi["signal_poll_rssi"].append(RSSI_ERROR_VAL) |
| 286 | else: |
| 287 | connected_rssi["signal_poll_rssi"].append(temp_rssi) |
| 288 | else: |
| 289 | connected_rssi["signal_poll_rssi"].append(RSSI_ERROR_VAL) |
| 290 | match = re.search("AVG_RSSI=.*", signal_poll_output) |
| 291 | if match: |
| 292 | connected_rssi["signal_poll_avg_rssi"].append( |
| 293 | int(match.group(0).split("=")[1])) |
| 294 | else: |
| 295 | connected_rssi["signal_poll_avg_rssi"].append(RSSI_ERROR_VAL) |
| 296 | # Get per chain RSSI |
| 297 | per_chain_rssi = self.dut.adb.shell(STATION_DUMP) |
| 298 | match = re.search(".*signal avg:.*", per_chain_rssi) |
| 299 | if match: |
| 300 | per_chain_rssi = per_chain_rssi[per_chain_rssi.find("[") + 1: |
| 301 | per_chain_rssi.find("]")] |
| 302 | per_chain_rssi = per_chain_rssi.split(", ") |
| 303 | connected_rssi["chain_0_rssi"].append(int(per_chain_rssi[0])) |
| 304 | connected_rssi["chain_1_rssi"].append(int(per_chain_rssi[1])) |
| 305 | else: |
| 306 | connected_rssi["chain_0_rssi"].append(RSSI_ERROR_VAL) |
| 307 | connected_rssi["chain_1_rssi"].append(RSSI_ERROR_VAL) |
| 308 | time.sleep(polling_frequency) |
| 309 | # Compute mean RSSIs. Only average valid readings. |
| 310 | # Output RSSI_ERROR_VAL if no valid connected readings found. |
| 311 | for key, val in connected_rssi.copy().items(): |
| 312 | filtered_rssi_values = [x for x in val if not math.isnan(x)] |
| 313 | if filtered_rssi_values: |
| 314 | connected_rssi["mean_{}".format(key)] = sum( |
| 315 | filtered_rssi_values) / len(filtered_rssi_values) |
| 316 | else: |
| 317 | connected_rssi["mean_{}".format(key)] = RSSI_ERROR_VAL |
| 318 | return connected_rssi |
| 319 | |
| 320 | def rssi_test(self, iperf_traffic, connected_measurements, |
| 321 | scan_measurements, bssids, polling_frequency): |
| 322 | """Test function to run RSSI tests. |
| 323 | |
| 324 | The function runs an RSSI test in the current device/AP configuration. |
| 325 | Function is called from another wrapper function that sets up the |
| 326 | testbed for the RvR test |
| 327 | |
| 328 | Args: |
| 329 | iperf_traffic: boolean specifying whether or not to run traffic |
| 330 | during RSSI tests |
| 331 | connected_measurements: number of RSSI measurements to make for the |
| 332 | connected AP per attenuation point |
| 333 | scan_measurements: number of scans and scan RSSIs to make per |
| 334 | attenuation point |
| 335 | bssids: list of BSSIDs to monitor in scans |
| 336 | polling_frequency: time between connected AP measurements |
| 337 | Returns: |
| 338 | rssi_result: dict containing rssi_result and meta data |
| 339 | """ |
| 340 | self.log.info("Start running RSSI test.") |
| 341 | rssi_result = [] |
| 342 | # Start iperf traffic if required by test |
| 343 | if self.iperf_traffic: |
| 344 | self.iperf_server.start(tag=0) |
| 345 | self.dut.run_iperf_client_nb( |
| 346 | self.test_params["iperf_server_address"], |
| 347 | self.iperf_args, |
| 348 | timeout=3600) |
| 349 | for atten in self.rssi_atten_range: |
| 350 | # Set Attenuation |
| 351 | self.log.info("Setting attenuation to {} dB".format(atten)) |
| 352 | [ |
| 353 | self.attenuators[i].set_atten(atten) |
| 354 | for i in range(self.num_atten) |
| 355 | ] |
| 356 | time.sleep(MED_SLEEP) |
| 357 | current_rssi = {} |
| 358 | current_rssi["connected_rssi"] = self.get_connected_rssi( |
| 359 | connected_measurements, polling_frequency) |
| 360 | current_rssi["scan_rssi"] = self.get_scan_rssi( |
| 361 | bssids, scan_measurements) |
| 362 | rssi_result.append(current_rssi) |
| 363 | self.log.info("Connected RSSI at {0:.2f} dB is {1:.2f} dB".format( |
| 364 | atten, current_rssi["connected_rssi"][ |
| 365 | "mean_signal_poll_rssi"])) |
| 366 | # Stop iperf traffic if needed |
| 367 | if self.iperf_traffic: |
| 368 | self.iperf_server.stop() |
| 369 | self.dut.adb.shell("pkill iperf3") |
| 370 | [self.attenuators[i].set_atten(0) for i in range(self.num_atten)] |
| 371 | return rssi_result |
| 372 | |
| 373 | def rssi_test_func(self): |
| 374 | """Main function to test RSSI. |
| 375 | |
| 376 | The function sets up the AP in the correct channel and mode |
| 377 | configuration and called rssi_test to sweep attenuation and measure |
| 378 | RSSI |
| 379 | |
| 380 | Returns: |
| 381 | rssi_result: dict containing rssi_results and meta data |
| 382 | """ |
| 383 | #Initialize test parameters |
| 384 | num_atten_steps = int((self.test_params["rssi_atten_stop"] - |
| 385 | self.test_params["rssi_atten_start"]) / |
| 386 | self.test_params["rssi_atten_step"]) |
| 387 | self.rssi_atten_range = [ |
| 388 | self.test_params["rssi_atten_start"] + |
| 389 | x * self.test_params["rssi_atten_step"] |
| 390 | for x in range(0, num_atten_steps) |
| 391 | ] |
| 392 | |
| 393 | rssi_result = {} |
| 394 | # Configure AP |
| 395 | band = self.access_point.band_lookup_by_channel(self.channel) |
| 396 | self.access_point.set_channel(band, self.channel) |
| 397 | self.access_point.set_bandwidth(band, self.mode) |
| 398 | self.log.info("Access Point Configuration: {}".format( |
| 399 | self.access_point.ap_settings)) |
| 400 | # Set attenuator to starting attenuation |
| 401 | [ |
| 402 | self.attenuators[i].set_atten(self.rssi_atten_range[0]) |
| 403 | for i in range(self.num_atten) |
| 404 | ] |
| 405 | # Connect DUT to Network |
| 406 | wutils.wifi_toggle_state(self.dut, True) |
| 407 | wutils.reset_wifi(self.dut) |
| 408 | self.main_network[band]["channel"] = self.channel |
| 409 | wutils.wifi_connect(self.dut, self.main_network[band], num_of_tries=5) |
| 410 | time.sleep(5) |
| 411 | # Run RvR and log result |
| 412 | rssi_result["test_name"] = self.current_test_name |
| 413 | rssi_result["ap_settings"] = self.access_point.ap_settings.copy() |
| 414 | rssi_result["attenuation"] = list(self.rssi_atten_range) |
| 415 | rssi_result["connected_bssid"] = self.main_network[band]["BSSID"] |
| 416 | rssi_result["ap_tx_power"] = self.test_params["ap_tx_power"][str( |
| 417 | self.channel)] |
| 418 | rssi_result["fixed_attenuation"] = self.test_params[ |
| 419 | "fixed_attenuation"][str(self.channel)] |
| 420 | rssi_result["rssi_result"] = self.rssi_test( |
| 421 | self.iperf_traffic, self.test_params["connected_measurements"], |
| 422 | self.test_params["scan_measurements"], [ |
| 423 | self.main_network[band]["BSSID"] |
| 424 | ], self.test_params["polling_frequency"]) |
| 425 | self.testclass_results.append(rssi_result) |
| 426 | return rssi_result |
| 427 | |
| 428 | def _test_rssi_vs_atten(self): |
| 429 | """ Function that gets called for each test case of rssi_vs_atten |
| 430 | |
| 431 | The function gets called in each rvr test case. The function customizes |
| 432 | the rvr test based on the test name of the test that called it |
| 433 | """ |
| 434 | test_params = self.current_test_name.split("_") |
| 435 | self.channel = int(test_params[4][2:]) |
| 436 | self.mode = test_params[5] |
| 437 | self.iperf_traffic = "ActiveTraffic" in test_params[6] |
| 438 | self.iperf_args = '-i 1 -t 3600 -J -R' |
| 439 | rssi_result = self.rssi_test_func() |
| 440 | postprocessed_results = self.post_process_results(rssi_result) |
| 441 | self.pass_fail_check_rssi_vs_attenuation(postprocessed_results) |
| 442 | |
| 443 | def _test_rssi_stability(self): |
| 444 | #TODO: Implement test that looks at RSSI stability at fixed attenuation |
| 445 | pass |
| 446 | |
Omar El Ayach | 19a5567 | 2018-03-09 00:53:12 +0000 | [diff] [blame^] | 447 | |
| 448 | class WifiRssi_2GHz_ActiveTraffic_Test(WifiRssiTest): |
| 449 | def __init__(self, controllers): |
| 450 | base_test.BaseTestClass.__init__(self, controllers) |
| 451 | |
Omar El Ayach | b880808 | 2018-03-04 01:05:39 +0000 | [diff] [blame] | 452 | @test_tracker_info(uuid='ae54b7cc-d76d-4460-8dcc-2c439265c7c9') |
| 453 | def test_rssi_vs_atten_ch1_VHT20_ActiveTraffic(self): |
| 454 | self._test_rssi_vs_atten() |
| 455 | |
| 456 | @test_tracker_info(uuid='07fe7899-886d-45ba-9c1d-7daaf9844c9c') |
| 457 | def test_rssi_vs_atten_ch2_VHT20_ActiveTraffic(self): |
| 458 | self._test_rssi_vs_atten() |
| 459 | |
| 460 | @test_tracker_info(uuid='9e86578b-a6cd-4de9-a79d-eabac5bd5f4e') |
| 461 | def test_rssi_vs_atten_ch3_VHT20_ActiveTraffic(self): |
| 462 | self._test_rssi_vs_atten() |
| 463 | |
| 464 | @test_tracker_info(uuid='e9d258ca-8e70-408e-b704-782fce7a07c5') |
| 465 | def test_rssi_vs_atten_ch4_VHT20_ActiveTraffic(self): |
| 466 | self._test_rssi_vs_atten() |
| 467 | |
| 468 | @test_tracker_info(uuid='1c5d71a0-7532-49e4-98a9-1c2d9d8d58d2') |
| 469 | def test_rssi_vs_atten_ch5_VHT20_ActiveTraffic(self): |
| 470 | self._test_rssi_vs_atten() |
| 471 | |
| 472 | @test_tracker_info(uuid='107f01f3-b6b9-470b-9895-6345edfc9599') |
| 473 | def test_rssi_vs_atten_ch6_VHT20_ActiveTraffic(self): |
| 474 | self._test_rssi_vs_atten() |
| 475 | |
| 476 | @test_tracker_info(uuid='88cb18b2-30bf-4c01-ac28-15451289e7cd') |
| 477 | def test_rssi_vs_atten_ch7_VHT20_ActiveTraffic(self): |
| 478 | self._test_rssi_vs_atten() |
| 479 | |
| 480 | @test_tracker_info(uuid='c07a7442-bd1d-40c7-80ed-167e30b8cfaf') |
| 481 | def test_rssi_vs_atten_ch8_VHT20_ActiveTraffic(self): |
| 482 | self._test_rssi_vs_atten() |
| 483 | |
| 484 | @test_tracker_info(uuid='b8946280-88d5-400d-a417-2bdc9d7e054a') |
| 485 | def test_rssi_vs_atten_ch9_VHT20_ActiveTraffic(self): |
| 486 | self._test_rssi_vs_atten() |
| 487 | |
| 488 | @test_tracker_info(uuid='a05db91b-740d-4984-a447-79ab438034f0') |
| 489 | def test_rssi_vs_atten_ch10_VHT20_ActiveTraffic(self): |
| 490 | self._test_rssi_vs_atten() |
| 491 | |
| 492 | @test_tracker_info(uuid='f4d565f8-f060-462c-9b3c-cd1f7d27b3ea') |
| 493 | def test_rssi_vs_atten_ch11_VHT20_ActiveTraffic(self): |
| 494 | self._test_rssi_vs_atten() |
| 495 | |
Omar El Ayach | 19a5567 | 2018-03-09 00:53:12 +0000 | [diff] [blame^] | 496 | |
| 497 | class WifiRssi_5GHz_ActiveTraffic_Test(WifiRssiTest): |
| 498 | def __init__(self, controllers): |
| 499 | base_test.BaseTestClass.__init__(self, controllers) |
| 500 | |
Omar El Ayach | b880808 | 2018-03-04 01:05:39 +0000 | [diff] [blame] | 501 | @test_tracker_info(uuid='a33a93ac-604a-414f-ae96-42dffbe59a93') |
| 502 | def test_rssi_vs_atten_ch36_VHT20_ActiveTraffic(self): |
| 503 | self._test_rssi_vs_atten() |
| 504 | |
| 505 | @test_tracker_info(uuid='39875ab0-e0e9-464b-8a47-4dedd65f066e') |
| 506 | def test_rssi_vs_atten_ch36_VHT40_ActiveTraffic(self): |
| 507 | self._test_rssi_vs_atten() |
| 508 | |
| 509 | @test_tracker_info(uuid='c6ff8768-f124-4190-baf2-bbf14b612de3') |
| 510 | def test_rssi_vs_atten_ch36_VHT80_ActiveTraffic(self): |
| 511 | self._test_rssi_vs_atten() |
| 512 | |
| 513 | @test_tracker_info(uuid='ed4705af-e202-4737-b410-8bab0515e79f') |
| 514 | def test_rssi_vs_atten_ch40_VHT20_ActiveTraffic(self): |
| 515 | self._test_rssi_vs_atten() |
| 516 | |
| 517 | @test_tracker_info(uuid='1388df99-ecbf-4412-9ded-d66552f37ec5') |
| 518 | def test_rssi_vs_atten_ch44_VHT20_ActiveTraffic(self): |
| 519 | self._test_rssi_vs_atten() |
| 520 | |
| 521 | @test_tracker_info(uuid='06868677-ad3c-4f50-9b9e-ae8d9455ae4d') |
| 522 | def test_rssi_vs_atten_ch44_VHT40_ActiveTraffic(self): |
| 523 | self._test_rssi_vs_atten() |
| 524 | |
| 525 | @test_tracker_info(uuid='9b6676de-c736-4603-a9b3-97670bea8f25') |
| 526 | def test_rssi_vs_atten_ch48_VHT20_ActiveTraffic(self): |
| 527 | self._test_rssi_vs_atten() |
| 528 | |
| 529 | @test_tracker_info(uuid='2641c4b8-0092-4e29-9139-fdb3b3f04d05') |
| 530 | def test_rssi_vs_atten_ch149_VHT20_ActiveTraffic(self): |
| 531 | self._test_rssi_vs_atten() |
| 532 | |
| 533 | @test_tracker_info(uuid='c8bc3f7d-b459-4e40-9c73-b0bf534c6c08') |
| 534 | def test_rssi_vs_atten_ch149_VHT40_ActiveTraffic(self): |
| 535 | self._test_rssi_vs_atten() |
| 536 | |
| 537 | @test_tracker_info(uuid='3e08f5b6-9f3c-4905-8b10-82e1ca830cc9') |
| 538 | def test_rssi_vs_atten_ch149_VHT80_ActiveTraffic(self): |
| 539 | self._test_rssi_vs_atten() |
| 540 | |
| 541 | @test_tracker_info(uuid='2343efe3-fdda-4180-add7-4786d35e29bb') |
| 542 | def test_rssi_vs_atten_ch153_VHT20_ActiveTraffic(self): |
| 543 | self._test_rssi_vs_atten() |
| 544 | |
| 545 | @test_tracker_info(uuid='89a16974-2399-4356-b720-17b765ff1c3a') |
| 546 | def test_rssi_vs_atten_ch157_VHT20_ActiveTraffic(self): |
| 547 | self._test_rssi_vs_atten() |
| 548 | |
| 549 | @test_tracker_info(uuid='c8e0e44a-b962-4e71-ba8f-068f268c8823') |
| 550 | def test_rssi_vs_atten_ch157_VHT40_ActiveTraffic(self): |
| 551 | self._test_rssi_vs_atten() |
| 552 | |
| 553 | @test_tracker_info(uuid='581b5794-239e-4d1c-b0ce-7c6dc5bd373f') |
| 554 | def test_rssi_vs_atten_ch161_VHT20_ActiveTraffic(self): |
| 555 | self._test_rssi_vs_atten() |