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