blob: cbbd54c52c80afc3bd4b2308b909cca06c3a92f8 [file] [log] [blame]
Omar El Ayachb8808082018-03-04 01:05:39 +00001#!/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
17import json
18import logging
19import math
20import os
21import re
Omar El Ayach432f4612018-03-22 02:33:00 +000022import statistics
Omar El Ayachb8808082018-03-04 01:05:39 +000023import time
24from acts import asserts
25from acts import base_test
26from acts import utils
27from acts.test_decorators import test_tracker_info
28from acts.test_utils.wifi import wifi_power_test_utils as wputils
29from acts.test_utils.wifi import wifi_retail_ap as retail_ap
30from acts.test_utils.wifi import wifi_test_utils as wutils
31
32SHORT_SLEEP = 1
33MED_SLEEP = 6
34STATION_DUMP = "iw wlan0 station dump"
35SCAN = "wpa_cli scan"
36SCAN_RESULTS = "wpa_cli scan_results"
37SIGNAL_POLL = "wpa_cli signal_poll"
38CONST_3dB = 3.01029995664
39RSSI_ERROR_VAL = float("nan")
40
41
42class WifiRssiTest(base_test.BaseTestClass):
43 def __init__(self, controllers):
44 base_test.BaseTestClass.__init__(self, controllers)
45
46 def setup_class(self):
47 self.dut = self.android_devices[0]
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -070048 req_params = ["rssi_test_params", "testbed_params", "main_network"]
Omar El Ayachb8808082018-03-04 01:05:39 +000049 opt_params = ["RetailAccessPoints"]
50 self.unpack_userparams(req_params, opt_params)
Omar El Ayach4232d892018-04-20 16:07:44 -070051 self.test_params = self.rssi_test_params
Omar El Ayachb8808082018-03-04 01:05:39 +000052 self.num_atten = self.attenuators[0].instrument.num_atten
53 self.iperf_server = self.iperf_servers[0]
54 self.access_points = retail_ap.create(self.RetailAccessPoints)
55 self.access_point = self.access_points[0]
56 self.log_path = os.path.join(logging.log_path, "results")
57 utils.create_dir(self.log_path)
58 self.log.info("Access Point Configuration: {}".format(
59 self.access_point.ap_settings))
60 self.testclass_results = []
61
62 def teardown_test(self):
63 self.iperf_server.stop()
64
Omar El Ayach432f4612018-03-22 02:33:00 +000065 def pass_fail_check_rssi_stability(self, rssi_result):
66 """Check the test result and decide if it passed or failed.
67
68 Checks the RSSI test result and fails the test if the standard
69 deviation of signal_poll_rssi is beyond the threshold defined in the
70 config file.
71
72 Args:
73 rssi_result: dict containing attenuation, rssi, and other meta
74 data. This dict is the output of self.post_process_results
75 """
76 # Save output as text file
77 test_name = self.current_test_name
78 results_file_path = "{}/{}.json".format(self.log_path,
79 self.current_test_name)
80 with open(results_file_path, 'w') as results_file:
81 json.dump(rssi_result, results_file, indent=4)
82
83 x_data = []
84 y_data = []
85 legends = []
86 std_deviations = {
87 "signal_poll_rssi": [],
88 "signal_poll_avg_rssi": [],
89 "chain_0_rssi": [],
90 "chain_1_rssi": [],
91 }
92 for data_point in rssi_result["rssi_result"]:
93 for key, val in data_point["connected_rssi"].items():
94 if type(val) == list:
95 x_data.append([
96 x * self.test_params["polling_frequency"]
97 for x in range(len(val))
98 ])
99 y_data.append(val)
100 legends.append(key)
101 std_deviations[key].append(
102 data_point["connected_rssi"]["stdev_" + key])
103 data_sets = [x_data, y_data]
104 x_label = 'Time (s)'
105 y_label = 'RSSI (dBm)'
106 fig_property = {
107 "title": test_name,
108 "x_label": x_label,
109 "y_label": y_label,
110 "linewidth": 3,
111 "markersize": 0
112 }
113 output_file_path = "{}/{}.html".format(self.log_path, test_name)
114 wputils.bokeh_plot(
115 data_sets,
116 legends,
117 fig_property,
118 shaded_region=None,
119 output_file_path=output_file_path)
120
121 test_failed = any([
122 stdev > self.test_params["stdev_tolerance"]
123 for stdev in std_deviations["signal_poll_rssi"]
124 ])
125 if test_failed:
126 asserts.fail(
127 "RSSI stability failed. Standard deviations were {0} dB "
128 "(limit {1}), per chain standard deviation [{2}, {3}] dB".
129 format([
130 float("{:.2f}".format(x))
131 for x in std_deviations["signal_poll_rssi"]
132 ], self.test_params["stdev_tolerance"], [
133 float("{:.2f}".format(x))
134 for x in std_deviations["chain_0_rssi"]
135 ], [
136 float("{:.2f}".format(x))
137 for x in std_deviations["chain_1_rssi"]
138 ]))
139 asserts.explicit_pass(
140 "RSSI stability passed. Standard deviations were {0} dB "
141 "(limit {1}), per chain standard deviation [{2}, {3}] dB".format([
142 float("{:.2f}".format(x))
143 for x in std_deviations["signal_poll_rssi"]
144 ], self.test_params["stdev_tolerance"], [
145 float("{:.2f}".format(x))
146 for x in std_deviations["chain_0_rssi"]
147 ], [
148 float("{:.2f}".format(x))
149 for x in std_deviations["chain_1_rssi"]
150 ]))
151
Omar El Ayachb8808082018-03-04 01:05:39 +0000152 def pass_fail_check_rssi_vs_attenuation(self, postprocessed_results):
153 """Check the test result and decide if it passed or failed.
154
155 Checks the RSSI test result and compares and compute its deviation from
156 the predicted RSSI. This computation is done for all reported RSSI
157 values. The test fails if any of the RSSI values specified in
158 rssi_under_test have an average error beyond what is specified in the
159 configuration file.
160
161 Args:
162 result: dict containing attenuation, rssi, and other meta
163 data. This dict is the output of self.post_process_results
164 """
165
166 error_data = {
167 "signal_poll_rssi": [
168 postprocessed_results["mean_signal_poll_rssi"][idx] -
169 postprocessed_results["predicted_rssi"][idx]
170 for idx in range(len(postprocessed_results["predicted_rssi"]))
171 ],
172 "signal_poll_avg_rssi": [
173 postprocessed_results["mean_signal_poll_avg_rssi"][idx] -
174 postprocessed_results["predicted_rssi"][idx]
175 for idx in range(len(postprocessed_results["predicted_rssi"]))
176 ],
177 "scan_rssi": [
178 postprocessed_results["mean_scan_rssi"][idx] -
179 postprocessed_results["predicted_rssi"][idx]
180 for idx in range(len(postprocessed_results["predicted_rssi"]))
181 ],
182 "chain_0_rssi": [
183 postprocessed_results["mean_chain_0_rssi"][idx] + CONST_3dB -
184 postprocessed_results["predicted_rssi"][idx]
185 for idx in range(len(postprocessed_results["predicted_rssi"]))
186 ],
187 "chain_1_rssi": [
188 postprocessed_results["mean_chain_1_rssi"][idx] + CONST_3dB -
189 postprocessed_results["predicted_rssi"][idx]
190 for idx in range(len(postprocessed_results["predicted_rssi"]))
191 ]
192 }
193
194 test_failed = False
195 test_message = ""
196 for key, val in error_data.items():
197 # Compute the error metrics ignoring invalid RSSI readings
198 # If all readings invalid, set error to RSSI_ERROR_VAL
199 filtered_errors = [x for x in val if not math.isnan(x)]
200 if filtered_errors:
201 avg_error = sum([abs(x) for x in filtered_errors
202 ]) / len(filtered_errors)
203 avg_shift = sum(filtered_errors) / len(filtered_errors)
204 else:
205 avg_error = RSSI_ERROR_VAL
206 rssi_failure = (avg_error > self.test_params["abs_tolerance"]
207 ) or math.isnan(avg_error)
208 if rssi_failure and key in self.test_params["rssi_under_test"]:
209 test_message = test_message + (
210 "{} failed. Average error is {:.2f} dB. "
211 "Average shift is {:.2f} dB.\n").format(
212 key, avg_error, avg_shift)
213 test_failed = True
214 elif rssi_failure:
215 test_message = test_message + (
216 "{} failed (ignored). Average error is {:.2f} dB. "
217 "Average shift is {:.2f} dB.\n").format(
218 key, avg_error, avg_shift)
219 else:
220 test_message = test_message + (
221 "{} passed. Average error is {:.2f} dB. "
222 "Average shift is {:.2f} dB.\n").format(
223 key, avg_error, avg_shift)
224
225 if test_failed:
226 asserts.fail(test_message)
227 asserts.explicit_pass(test_message)
228
Omar El Ayach432f4612018-03-22 02:33:00 +0000229 def post_process_rssi_vs_attenuation(self, rssi_result):
Omar El Ayachb8808082018-03-04 01:05:39 +0000230 """Saves plots and JSON formatted results.
231
232 Args:
233 rssi_result: dict containing attenuation, rssi and other meta
234 data
235 Returns:
236 postprocessed_results: compiled arrays of RSSI measurements used in
237 pass/fail check
238 """
239 # Save output as text file
240 test_name = self.current_test_name
241 results_file_path = "{}/{}.json".format(self.log_path,
242 self.current_test_name)
243 with open(results_file_path, 'w') as results_file:
Omar El Ayach432f4612018-03-22 02:33:00 +0000244 json.dump(rssi_result, results_file, indent=4)
Omar El Ayachb8808082018-03-04 01:05:39 +0000245 # Plot and save
246 total_attenuation = [
android-build-prod (mdb)198b8912018-05-08 15:15:36 -0700247 att + rssi_result["fixed_attenuation"] +
248 rssi_result["dut_front_end_loss"]
Omar El Ayachb8808082018-03-04 01:05:39 +0000249 for att in rssi_result["attenuation"]
250 ]
251 # Compile results into arrays of RSSIs suitable for plotting
252 postprocessed_results = {
253 "total_attenuation":
254 total_attenuation,
255 "mean_signal_poll_rssi": [
256 x["connected_rssi"]["mean_signal_poll_rssi"]
257 for x in rssi_result["rssi_result"]
258 ],
259 "mean_signal_poll_avg_rssi": [
260 x["connected_rssi"]["mean_signal_poll_avg_rssi"]
261 for x in rssi_result["rssi_result"]
262 ],
263 "mean_scan_rssi": [
264 x["scan_rssi"][rssi_result["connected_bssid"]]["avg_rssi"]
265 for x in rssi_result["rssi_result"]
266 ],
267 "mean_chain_0_rssi": [
268 x["connected_rssi"]["mean_chain_0_rssi"]
269 for x in rssi_result["rssi_result"]
270 ],
271 "mean_chain_1_rssi": [
272 x["connected_rssi"]["mean_chain_1_rssi"]
273 for x in rssi_result["rssi_result"]
274 ],
275 "predicted_rssi":
276 [rssi_result["ap_tx_power"] - att for att in total_attenuation]
277 }
278 data_sets = [[
279 total_attenuation, total_attenuation, total_attenuation,
280 total_attenuation, total_attenuation, total_attenuation
281 ], [
282 postprocessed_results["mean_signal_poll_rssi"],
283 postprocessed_results["mean_signal_poll_avg_rssi"],
284 postprocessed_results["mean_scan_rssi"],
285 postprocessed_results["mean_chain_0_rssi"],
286 postprocessed_results["mean_chain_1_rssi"],
287 postprocessed_results["predicted_rssi"]
288 ]]
289 legends = [
290 "Signal Poll RSSI", "Signal Poll AVG_RSSI", "Scan RSSI",
291 "Chain 0 RSSI", "Chain 1 RSSI", "Predicted RSSI"
292 ]
293 x_label = 'Attenuation (dB)'
294 y_label = 'RSSI (dBm)'
295 fig_property = {
296 "title": test_name,
297 "x_label": x_label,
298 "y_label": y_label,
299 "linewidth": 3,
300 "markersize": 10
301 }
302 output_file_path = "{}/{}.html".format(self.log_path, test_name)
303 wputils.bokeh_plot(
304 data_sets,
305 legends,
306 fig_property,
307 shaded_region=None,
308 output_file_path=output_file_path)
309 return postprocessed_results
310
311 def get_scan_rssi(self, tracked_bssids, num_measurements=1):
312 """Gets scan RSSI for specified BSSIDs.
313
314 Args:
315 tracked_bssids: array of BSSIDs to gather RSSI data for
316 num_measurements: number of scans done, and RSSIs collected
317 Returns:
318 scan_rssi: dict containing the measurement results as well as the
Omar El Ayach432f4612018-03-22 02:33:00 +0000319 statistics of the scan RSSI for all BSSIDs in tracked_bssids
Omar El Ayachb8808082018-03-04 01:05:39 +0000320 """
321 scan_rssi = {}
322 for bssid in tracked_bssids:
323 scan_rssi[bssid] = {"rssi": [], "avg_rssi": None}
324 for idx in range(num_measurements):
325 scan_output = self.dut.adb.shell(SCAN)
326 time.sleep(MED_SLEEP)
327 scan_output = self.dut.adb.shell(SCAN_RESULTS)
328 for bssid in tracked_bssids:
329 bssid_result = re.search(
330 bssid + ".*", scan_output, flags=re.IGNORECASE)
331 if bssid_result:
332 bssid_result = bssid_result.group(0).split("\t")
333 scan_rssi[bssid]["rssi"].append(int(bssid_result[2]))
334 else:
335 scan_rssi[bssid]["rssi"].append(RSSI_ERROR_VAL)
336 # Compute mean RSSIs. Only average valid readings.
337 # Output RSSI_ERROR_VAL if no readings found.
338 for key, val in scan_rssi.items():
339 filtered_rssi_values = [
340 x for x in val["rssi"] if not math.isnan(x)
341 ]
342 if filtered_rssi_values:
343 scan_rssi[key]["avg_rssi"] = sum(filtered_rssi_values) / len(
344 filtered_rssi_values)
Omar El Ayach432f4612018-03-22 02:33:00 +0000345 if len(filtered_rssi_values) > 1:
346 scan_rssi[key]["stdev"] = statistics.stdev(
347 filtered_rssi_values)
348 else:
349 scan_rssi[key]["stdev"] = 0
Omar El Ayachb8808082018-03-04 01:05:39 +0000350 else:
351 scan_rssi[key]["avg_rssi"] = RSSI_ERROR_VAL
Omar El Ayach432f4612018-03-22 02:33:00 +0000352 scan_rssi[key]["stdev"] = RSSI_ERROR_VAL
Omar El Ayachb8808082018-03-04 01:05:39 +0000353 return scan_rssi
354
355 def get_connected_rssi(self,
356 num_measurements=1,
357 polling_frequency=SHORT_SLEEP):
358 """Gets all RSSI values reported for the connected access point/BSSID.
359
360 Args:
361 num_measurements: number of scans done, and RSSIs collected
362 polling_frequency: time to wait between RSSI measurements
363 Returns:
364 connected_rssi: dict containing the measurements results for
365 all reported RSSI values (signal_poll, per chain, etc.) and their
Omar El Ayach432f4612018-03-22 02:33:00 +0000366 statistics
Omar El Ayachb8808082018-03-04 01:05:39 +0000367 """
368 connected_rssi = {
369 "signal_poll_rssi": [],
370 "signal_poll_avg_rssi": [],
371 "chain_0_rssi": [],
372 "chain_1_rssi": []
373 }
374 for idx in range(num_measurements):
Omar El Ayach4232d892018-04-20 16:07:44 -0700375 measurement_start_time = time.time()
Omar El Ayachb8808082018-03-04 01:05:39 +0000376 # Get signal poll RSSI
377 signal_poll_output = self.dut.adb.shell(SIGNAL_POLL)
378 match = re.search("RSSI=.*", signal_poll_output)
379 if match:
380 temp_rssi = int(match.group(0).split("=")[1])
381 if temp_rssi == -9999:
382 connected_rssi["signal_poll_rssi"].append(RSSI_ERROR_VAL)
383 else:
384 connected_rssi["signal_poll_rssi"].append(temp_rssi)
385 else:
386 connected_rssi["signal_poll_rssi"].append(RSSI_ERROR_VAL)
387 match = re.search("AVG_RSSI=.*", signal_poll_output)
388 if match:
389 connected_rssi["signal_poll_avg_rssi"].append(
390 int(match.group(0).split("=")[1]))
391 else:
392 connected_rssi["signal_poll_avg_rssi"].append(RSSI_ERROR_VAL)
393 # Get per chain RSSI
394 per_chain_rssi = self.dut.adb.shell(STATION_DUMP)
395 match = re.search(".*signal avg:.*", per_chain_rssi)
396 if match:
397 per_chain_rssi = per_chain_rssi[per_chain_rssi.find("[") + 1:
398 per_chain_rssi.find("]")]
399 per_chain_rssi = per_chain_rssi.split(", ")
400 connected_rssi["chain_0_rssi"].append(int(per_chain_rssi[0]))
401 connected_rssi["chain_1_rssi"].append(int(per_chain_rssi[1]))
402 else:
403 connected_rssi["chain_0_rssi"].append(RSSI_ERROR_VAL)
404 connected_rssi["chain_1_rssi"].append(RSSI_ERROR_VAL)
Omar El Ayach4232d892018-04-20 16:07:44 -0700405 measurement_elapsed_time = time.time() - measurement_start_time
406 time.sleep(max(0, polling_frequency - measurement_elapsed_time))
Omar El Ayached1d24b2018-04-13 12:49:33 -0700407
Omar El Ayachb8808082018-03-04 01:05:39 +0000408 # Compute mean RSSIs. Only average valid readings.
409 # Output RSSI_ERROR_VAL if no valid connected readings found.
410 for key, val in connected_rssi.copy().items():
411 filtered_rssi_values = [x for x in val if not math.isnan(x)]
412 if filtered_rssi_values:
413 connected_rssi["mean_{}".format(key)] = sum(
414 filtered_rssi_values) / len(filtered_rssi_values)
Omar El Ayach432f4612018-03-22 02:33:00 +0000415 if len(filtered_rssi_values) > 1:
416 connected_rssi["stdev_{}".format(key)] = statistics.stdev(
417 filtered_rssi_values)
418 else:
419 connected_rssi["stdev_{}".format(key)] = 0
Omar El Ayachb8808082018-03-04 01:05:39 +0000420 else:
421 connected_rssi["mean_{}".format(key)] = RSSI_ERROR_VAL
Omar El Ayach432f4612018-03-22 02:33:00 +0000422 connected_rssi["stdev_{}".format(key)] = RSSI_ERROR_VAL
Omar El Ayachb8808082018-03-04 01:05:39 +0000423 return connected_rssi
424
425 def rssi_test(self, iperf_traffic, connected_measurements,
426 scan_measurements, bssids, polling_frequency):
427 """Test function to run RSSI tests.
428
429 The function runs an RSSI test in the current device/AP configuration.
430 Function is called from another wrapper function that sets up the
431 testbed for the RvR test
432
433 Args:
434 iperf_traffic: boolean specifying whether or not to run traffic
435 during RSSI tests
436 connected_measurements: number of RSSI measurements to make for the
437 connected AP per attenuation point
438 scan_measurements: number of scans and scan RSSIs to make per
439 attenuation point
440 bssids: list of BSSIDs to monitor in scans
441 polling_frequency: time between connected AP measurements
442 Returns:
443 rssi_result: dict containing rssi_result and meta data
444 """
445 self.log.info("Start running RSSI test.")
446 rssi_result = []
447 # Start iperf traffic if required by test
448 if self.iperf_traffic:
449 self.iperf_server.start(tag=0)
450 self.dut.run_iperf_client_nb(
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700451 self.testbed_params["iperf_server_address"],
Omar El Ayachb8808082018-03-04 01:05:39 +0000452 self.iperf_args,
453 timeout=3600)
454 for atten in self.rssi_atten_range:
455 # Set Attenuation
456 self.log.info("Setting attenuation to {} dB".format(atten))
457 [
458 self.attenuators[i].set_atten(atten)
459 for i in range(self.num_atten)
460 ]
461 time.sleep(MED_SLEEP)
462 current_rssi = {}
463 current_rssi["connected_rssi"] = self.get_connected_rssi(
464 connected_measurements, polling_frequency)
465 current_rssi["scan_rssi"] = self.get_scan_rssi(
466 bssids, scan_measurements)
467 rssi_result.append(current_rssi)
468 self.log.info("Connected RSSI at {0:.2f} dB is {1:.2f} dB".format(
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700469 atten,
470 current_rssi["connected_rssi"]["mean_signal_poll_rssi"]))
Omar El Ayachb8808082018-03-04 01:05:39 +0000471 # Stop iperf traffic if needed
472 if self.iperf_traffic:
473 self.iperf_server.stop()
474 self.dut.adb.shell("pkill iperf3")
475 [self.attenuators[i].set_atten(0) for i in range(self.num_atten)]
476 return rssi_result
477
Omar El Ayach432f4612018-03-22 02:33:00 +0000478 def rssi_test_func(self, iperf_traffic, connected_measurements,
479 scan_measurements, bssids, polling_frequency):
Omar El Ayachb8808082018-03-04 01:05:39 +0000480 """Main function to test RSSI.
481
482 The function sets up the AP in the correct channel and mode
483 configuration and called rssi_test to sweep attenuation and measure
484 RSSI
485
486 Returns:
487 rssi_result: dict containing rssi_results and meta data
488 """
Omar El Ayach432f4612018-03-22 02:33:00 +0000489 #Initialize test settings
Omar El Ayachb8808082018-03-04 01:05:39 +0000490 rssi_result = {}
491 # Configure AP
492 band = self.access_point.band_lookup_by_channel(self.channel)
493 self.access_point.set_channel(band, self.channel)
494 self.access_point.set_bandwidth(band, self.mode)
495 self.log.info("Access Point Configuration: {}".format(
496 self.access_point.ap_settings))
497 # Set attenuator to starting attenuation
498 [
499 self.attenuators[i].set_atten(self.rssi_atten_range[0])
500 for i in range(self.num_atten)
501 ]
502 # Connect DUT to Network
503 wutils.wifi_toggle_state(self.dut, True)
504 wutils.reset_wifi(self.dut)
505 self.main_network[band]["channel"] = self.channel
506 wutils.wifi_connect(self.dut, self.main_network[band], num_of_tries=5)
507 time.sleep(5)
508 # Run RvR and log result
509 rssi_result["test_name"] = self.current_test_name
510 rssi_result["ap_settings"] = self.access_point.ap_settings.copy()
511 rssi_result["attenuation"] = list(self.rssi_atten_range)
512 rssi_result["connected_bssid"] = self.main_network[band]["BSSID"]
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700513 if "{}_{}".format(str(self.channel),
514 self.mode) in self.testbed_params["ap_tx_power"]:
515 rssi_result["ap_tx_power"] = self.testbed_params["ap_tx_power"][
516 "{}_{}".format(str(self.channel), self.mode)]
517 else:
518 rssi_result["ap_tx_power"] = self.testbed_params["ap_tx_power"][
519 str(self.channel)]
520 rssi_result["fixed_attenuation"] = self.testbed_params[
Omar El Ayachb8808082018-03-04 01:05:39 +0000521 "fixed_attenuation"][str(self.channel)]
android-build-prod (mdb)198b8912018-05-08 15:15:36 -0700522 rssi_result["dut_front_end_loss"] = self.testbed_params[
523 "dut_front_end_loss"][str(self.channel)]
Omar El Ayachb8808082018-03-04 01:05:39 +0000524 rssi_result["rssi_result"] = self.rssi_test(
Omar El Ayach432f4612018-03-22 02:33:00 +0000525 iperf_traffic, connected_measurements, scan_measurements, bssids,
526 polling_frequency)
Omar El Ayachb8808082018-03-04 01:05:39 +0000527 self.testclass_results.append(rssi_result)
528 return rssi_result
529
530 def _test_rssi_vs_atten(self):
531 """ Function that gets called for each test case of rssi_vs_atten
532
533 The function gets called in each rvr test case. The function customizes
Omar El Ayach432f4612018-03-22 02:33:00 +0000534 the test based on the test name of the test that called it
Omar El Ayachb8808082018-03-04 01:05:39 +0000535 """
536 test_params = self.current_test_name.split("_")
537 self.channel = int(test_params[4][2:])
538 self.mode = test_params[5]
539 self.iperf_traffic = "ActiveTraffic" in test_params[6]
540 self.iperf_args = '-i 1 -t 3600 -J -R'
Omar El Ayach432f4612018-03-22 02:33:00 +0000541 band = self.access_point.band_lookup_by_channel(self.channel)
542 num_atten_steps = int((self.test_params["rssi_atten_stop"] -
543 self.test_params["rssi_atten_start"]) /
544 self.test_params["rssi_atten_step"])
545 self.rssi_atten_range = [
546 self.test_params["rssi_atten_start"] +
547 x * self.test_params["rssi_atten_step"]
548 for x in range(0, num_atten_steps)
549 ]
550 rssi_result = self.rssi_test_func(
551 self.iperf_traffic, self.test_params["connected_measurements"],
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700552 self.test_params["scan_measurements"],
553 [self.main_network[band]["BSSID"]],
554 self.test_params["polling_frequency"])
Omar El Ayach432f4612018-03-22 02:33:00 +0000555 postprocessed_results = self.post_process_rssi_vs_attenuation(
556 rssi_result)
Omar El Ayachb8808082018-03-04 01:05:39 +0000557 self.pass_fail_check_rssi_vs_attenuation(postprocessed_results)
558
559 def _test_rssi_stability(self):
Omar El Ayach432f4612018-03-22 02:33:00 +0000560 """ Function that gets called for each test case of rssi_stability
Omar El Ayachb8808082018-03-04 01:05:39 +0000561
Omar El Ayach432f4612018-03-22 02:33:00 +0000562 The function gets called in each stability test case. The function
563 customizes test based on the test name of the test that called it
564 """
565 test_params = self.current_test_name.split("_")
566 self.channel = int(test_params[3][2:])
567 self.mode = test_params[4]
568 self.iperf_traffic = "ActiveTraffic" in test_params[5]
569 self.iperf_args = '-i 1 -t 3600 -J -R'
570 band = self.access_point.band_lookup_by_channel(self.channel)
571 self.rssi_atten_range = self.test_params["stability_test_atten"]
572 connected_measurements = int(
573 self.test_params["stability_test_duration"] /
574 self.test_params["polling_frequency"])
575 rssi_result = self.rssi_test_func(
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700576 self.iperf_traffic, connected_measurements, 0,
577 [self.main_network[band]["BSSID"]],
578 self.test_params["polling_frequency"])
Omar El Ayach432f4612018-03-22 02:33:00 +0000579 self.pass_fail_check_rssi_stability(rssi_result)
Omar El Ayach19a55672018-03-09 00:53:12 +0000580
Omar El Ayach432f4612018-03-22 02:33:00 +0000581 @test_tracker_info(uuid='519689b8-0a3c-4fd9-9227-fd7962d0f1a0')
582 def test_rssi_stability_ch1_VHT20_ActiveTraffic(self):
583 self._test_rssi_stability()
584
585 @test_tracker_info(uuid='23eca2ab-d0b4-4730-9f32-ec2d901ae493')
586 def test_rssi_stability_ch2_VHT20_ActiveTraffic(self):
587 self._test_rssi_stability()
588
589 @test_tracker_info(uuid='63d340c0-dcf9-4e14-87bd-a068a59836b2')
590 def test_rssi_stability_ch3_VHT20_ActiveTraffic(self):
591 self._test_rssi_stability()
592
593 @test_tracker_info(uuid='ddbe88d8-be20-40eb-8f29-55049e3fef28')
594 def test_rssi_stability_ch4_VHT20_ActiveTraffic(self):
595 self._test_rssi_stability()
596
597 @test_tracker_info(uuid='9c06304e-2b60-4619-8fb3-73fd2cb4b854')
598 def test_rssi_stability_ch5_VHT20_ActiveTraffic(self):
599 self._test_rssi_stability()
600
601 @test_tracker_info(uuid='74b656ca-132e-4d66-9584-560287081607')
602 def test_rssi_stability_ch6_VHT20_ActiveTraffic(self):
603 self._test_rssi_stability()
604
605 @test_tracker_info(uuid='23b5f19a-539b-4908-a197-06ce505d3d23')
606 def test_rssi_stability_ch7_VHT20_ActiveTraffic(self):
607 self._test_rssi_stability()
608
609 @test_tracker_info(uuid='e7b85167-f4c4-4adb-a111-04d8a5f10e1a')
610 def test_rssi_stability_ch8_VHT20_ActiveTraffic(self):
611 self._test_rssi_stability()
612
613 @test_tracker_info(uuid='2a0a9393-4b68-4c08-8787-3f35d1a8458b')
614 def test_rssi_stability_ch9_VHT20_ActiveTraffic(self):
615 self._test_rssi_stability()
616
617 @test_tracker_info(uuid='069c7acf-3e7e-4298-91cb-d292c6025ae1')
618 def test_rssi_stability_ch10_VHT20_ActiveTraffic(self):
619 self._test_rssi_stability()
620
621 @test_tracker_info(uuid='95c5a27c-1dea-47a4-a1c5-edf955545f12')
622 def test_rssi_stability_ch11_VHT20_ActiveTraffic(self):
623 self._test_rssi_stability()
624
625 @test_tracker_info(uuid='8aeab023-a096-4fbe-80dd-fd01466f9fac')
626 def test_rssi_stability_ch36_VHT20_ActiveTraffic(self):
627 self._test_rssi_stability()
628
629 @test_tracker_info(uuid='872fed9f-d0bb-4a7b-a2a7-bf8df7740b2d')
630 def test_rssi_stability_ch36_VHT40_ActiveTraffic(self):
631 self._test_rssi_stability()
632
633 @test_tracker_info(uuid='27395fd1-e286-473a-b98e-5a50db2a598a')
634 def test_rssi_stability_ch36_VHT80_ActiveTraffic(self):
635 self._test_rssi_stability()
636
637 @test_tracker_info(uuid='6f6b25e3-1a1e-4a61-930a-1d0aa25ba900')
638 def test_rssi_stability_ch40_VHT20_ActiveTraffic(self):
639 self._test_rssi_stability()
640
641 @test_tracker_info(uuid='c6717da7-855c-4c6e-a6e2-ee42b8feaaab')
642 def test_rssi_stability_ch44_VHT20_ActiveTraffic(self):
643 self._test_rssi_stability()
644
645 @test_tracker_info(uuid='2e34f735-079c-4619-9e74-b96dc8d0597f')
646 def test_rssi_stability_ch44_VHT40_ActiveTraffic(self):
647 self._test_rssi_stability()
648
649 @test_tracker_info(uuid='d543c019-1ff5-41d4-9b37-ccdc593f3edd')
650 def test_rssi_stability_ch48_VHT20_ActiveTraffic(self):
651 self._test_rssi_stability()
652
653 @test_tracker_info(uuid='2bb08914-36b2-4f58-9b3e-c3f3f4fac8ab')
654 def test_rssi_stability_ch149_VHT20_ActiveTraffic(self):
655 self._test_rssi_stability()
656
657 @test_tracker_info(uuid='e2f585f5-7811-4570-b987-23da301eb75d')
658 def test_rssi_stability_ch149_VHT40_ActiveTraffic(self):
659 self._test_rssi_stability()
660
661 @test_tracker_info(uuid='f3e74d5b-73f6-4723-abf3-c9c147db08e3')
662 def test_rssi_stability_ch149_VHT80_ActiveTraffic(self):
663 self._test_rssi_stability()
664
665 @test_tracker_info(uuid='06503ed0-baf3-4cd1-ac5e-4124e3c7f52f')
666 def test_rssi_stability_ch153_VHT20_ActiveTraffic(self):
667 self._test_rssi_stability()
668
669 @test_tracker_info(uuid='0cf8286f-a919-4e29-a9f2-e7738a4afe8f')
670 def test_rssi_stability_ch157_VHT20_ActiveTraffic(self):
671 self._test_rssi_stability()
672
673 @test_tracker_info(uuid='f9a0165c-468b-4096-8f4b-cc80bae564a0')
674 def test_rssi_stability_ch157_VHT40_ActiveTraffic(self):
675 self._test_rssi_stability()
676
677 @test_tracker_info(uuid='4b74dd46-4190-4556-8ad8-c55808e9e847')
678 def test_rssi_stability_ch161_VHT20_ActiveTraffic(self):
android-build-prod (mdb)5660fed2018-04-26 21:03:41 -0700679 self._test_rssi_stability()
Omar El Ayach19a55672018-03-09 00:53:12 +0000680
Omar El Ayachb8808082018-03-04 01:05:39 +0000681 @test_tracker_info(uuid='ae54b7cc-d76d-4460-8dcc-2c439265c7c9')
682 def test_rssi_vs_atten_ch1_VHT20_ActiveTraffic(self):
683 self._test_rssi_vs_atten()
684
685 @test_tracker_info(uuid='07fe7899-886d-45ba-9c1d-7daaf9844c9c')
686 def test_rssi_vs_atten_ch2_VHT20_ActiveTraffic(self):
687 self._test_rssi_vs_atten()
688
689 @test_tracker_info(uuid='9e86578b-a6cd-4de9-a79d-eabac5bd5f4e')
690 def test_rssi_vs_atten_ch3_VHT20_ActiveTraffic(self):
691 self._test_rssi_vs_atten()
692
693 @test_tracker_info(uuid='e9d258ca-8e70-408e-b704-782fce7a07c5')
694 def test_rssi_vs_atten_ch4_VHT20_ActiveTraffic(self):
695 self._test_rssi_vs_atten()
696
697 @test_tracker_info(uuid='1c5d71a0-7532-49e4-98a9-1c2d9d8d58d2')
698 def test_rssi_vs_atten_ch5_VHT20_ActiveTraffic(self):
699 self._test_rssi_vs_atten()
700
701 @test_tracker_info(uuid='107f01f3-b6b9-470b-9895-6345edfc9599')
702 def test_rssi_vs_atten_ch6_VHT20_ActiveTraffic(self):
703 self._test_rssi_vs_atten()
704
705 @test_tracker_info(uuid='88cb18b2-30bf-4c01-ac28-15451289e7cd')
706 def test_rssi_vs_atten_ch7_VHT20_ActiveTraffic(self):
707 self._test_rssi_vs_atten()
708
709 @test_tracker_info(uuid='c07a7442-bd1d-40c7-80ed-167e30b8cfaf')
710 def test_rssi_vs_atten_ch8_VHT20_ActiveTraffic(self):
711 self._test_rssi_vs_atten()
712
713 @test_tracker_info(uuid='b8946280-88d5-400d-a417-2bdc9d7e054a')
714 def test_rssi_vs_atten_ch9_VHT20_ActiveTraffic(self):
715 self._test_rssi_vs_atten()
716
717 @test_tracker_info(uuid='a05db91b-740d-4984-a447-79ab438034f0')
718 def test_rssi_vs_atten_ch10_VHT20_ActiveTraffic(self):
719 self._test_rssi_vs_atten()
720
721 @test_tracker_info(uuid='f4d565f8-f060-462c-9b3c-cd1f7d27b3ea')
722 def test_rssi_vs_atten_ch11_VHT20_ActiveTraffic(self):
723 self._test_rssi_vs_atten()
724
Omar El Ayachb8808082018-03-04 01:05:39 +0000725 @test_tracker_info(uuid='a33a93ac-604a-414f-ae96-42dffbe59a93')
726 def test_rssi_vs_atten_ch36_VHT20_ActiveTraffic(self):
727 self._test_rssi_vs_atten()
728
729 @test_tracker_info(uuid='39875ab0-e0e9-464b-8a47-4dedd65f066e')
730 def test_rssi_vs_atten_ch36_VHT40_ActiveTraffic(self):
731 self._test_rssi_vs_atten()
732
733 @test_tracker_info(uuid='c6ff8768-f124-4190-baf2-bbf14b612de3')
734 def test_rssi_vs_atten_ch36_VHT80_ActiveTraffic(self):
735 self._test_rssi_vs_atten()
736
737 @test_tracker_info(uuid='ed4705af-e202-4737-b410-8bab0515e79f')
738 def test_rssi_vs_atten_ch40_VHT20_ActiveTraffic(self):
739 self._test_rssi_vs_atten()
740
741 @test_tracker_info(uuid='1388df99-ecbf-4412-9ded-d66552f37ec5')
742 def test_rssi_vs_atten_ch44_VHT20_ActiveTraffic(self):
743 self._test_rssi_vs_atten()
744
745 @test_tracker_info(uuid='06868677-ad3c-4f50-9b9e-ae8d9455ae4d')
746 def test_rssi_vs_atten_ch44_VHT40_ActiveTraffic(self):
747 self._test_rssi_vs_atten()
748
749 @test_tracker_info(uuid='9b6676de-c736-4603-a9b3-97670bea8f25')
750 def test_rssi_vs_atten_ch48_VHT20_ActiveTraffic(self):
751 self._test_rssi_vs_atten()
752
753 @test_tracker_info(uuid='2641c4b8-0092-4e29-9139-fdb3b3f04d05')
754 def test_rssi_vs_atten_ch149_VHT20_ActiveTraffic(self):
755 self._test_rssi_vs_atten()
756
757 @test_tracker_info(uuid='c8bc3f7d-b459-4e40-9c73-b0bf534c6c08')
758 def test_rssi_vs_atten_ch149_VHT40_ActiveTraffic(self):
759 self._test_rssi_vs_atten()
760
761 @test_tracker_info(uuid='3e08f5b6-9f3c-4905-8b10-82e1ca830cc9')
762 def test_rssi_vs_atten_ch149_VHT80_ActiveTraffic(self):
763 self._test_rssi_vs_atten()
764
765 @test_tracker_info(uuid='2343efe3-fdda-4180-add7-4786d35e29bb')
766 def test_rssi_vs_atten_ch153_VHT20_ActiveTraffic(self):
767 self._test_rssi_vs_atten()
768
769 @test_tracker_info(uuid='89a16974-2399-4356-b720-17b765ff1c3a')
770 def test_rssi_vs_atten_ch157_VHT20_ActiveTraffic(self):
771 self._test_rssi_vs_atten()
772
773 @test_tracker_info(uuid='c8e0e44a-b962-4e71-ba8f-068f268c8823')
774 def test_rssi_vs_atten_ch157_VHT40_ActiveTraffic(self):
775 self._test_rssi_vs_atten()
776
777 @test_tracker_info(uuid='581b5794-239e-4d1c-b0ce-7c6dc5bd373f')
778 def test_rssi_vs_atten_ch161_VHT20_ActiveTraffic(self):
779 self._test_rssi_vs_atten()
Omar El Ayach432f4612018-03-22 02:33:00 +0000780
781
782class WifiRssi_2GHz_ActiveTraffic_Test(WifiRssiTest):
783 def __init__(self, controllers):
784 base_test.BaseTestClass.__init__(self, controllers)
785 self.tests = ("test_rssi_stability_ch1_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000786 "test_rssi_vs_atten_ch1_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000787 "test_rssi_stability_ch2_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000788 "test_rssi_vs_atten_ch2_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000789 "test_rssi_stability_ch3_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000790 "test_rssi_vs_atten_ch3_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000791 "test_rssi_stability_ch4_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000792 "test_rssi_vs_atten_ch4_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000793 "test_rssi_stability_ch5_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000794 "test_rssi_vs_atten_ch5_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000795 "test_rssi_stability_ch6_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000796 "test_rssi_vs_atten_ch6_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000797 "test_rssi_stability_ch7_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000798 "test_rssi_vs_atten_ch7_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000799 "test_rssi_stability_ch8_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000800 "test_rssi_vs_atten_ch8_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000801 "test_rssi_stability_ch9_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000802 "test_rssi_vs_atten_ch9_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000803 "test_rssi_stability_ch10_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000804 "test_rssi_vs_atten_ch10_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000805 "test_rssi_stability_ch11_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000806 "test_rssi_vs_atten_ch11_VHT20_ActiveTraffic")
807
808
809class WifiRssi_5GHz_ActiveTraffic_Test(WifiRssiTest):
810 def __init__(self, controllers):
811 base_test.BaseTestClass.__init__(self, controllers)
812 self.tests = ("test_rssi_stability_ch36_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000813 "test_rssi_vs_atten_ch36_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000814 "test_rssi_stability_ch36_VHT40_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000815 "test_rssi_vs_atten_ch36_VHT40_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000816 "test_rssi_stability_ch36_VHT80_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000817 "test_rssi_vs_atten_ch36_VHT80_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000818 "test_rssi_stability_ch40_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000819 "test_rssi_vs_atten_ch40_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000820 "test_rssi_stability_ch44_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000821 "test_rssi_vs_atten_ch44_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000822 "test_rssi_stability_ch44_VHT40_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000823 "test_rssi_vs_atten_ch44_VHT40_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000824 "test_rssi_stability_ch48_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000825 "test_rssi_vs_atten_ch48_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000826 "test_rssi_stability_ch149_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000827 "test_rssi_vs_atten_ch149_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000828 "test_rssi_stability_ch149_VHT40_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000829 "test_rssi_vs_atten_ch149_VHT40_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000830 "test_rssi_stability_ch149_VHT80_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000831 "test_rssi_vs_atten_ch149_VHT80_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000832 "test_rssi_stability_ch153_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000833 "test_rssi_vs_atten_ch153_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000834 "test_rssi_stability_ch157_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000835 "test_rssi_vs_atten_ch157_VHT20_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000836 "test_rssi_stability_ch157_VHT40_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000837 "test_rssi_vs_atten_ch157_VHT40_ActiveTraffic",
Omar El Ayach9b84ee12018-03-23 00:01:57 +0000838 "test_rssi_stability_ch161_VHT20_ActiveTraffic",
Omar El Ayach432f4612018-03-22 02:33:00 +0000839 "test_rssi_vs_atten_ch161_VHT20_ActiveTraffic")