1#!/usr/bin/env python3 2# 3# Copyright 2019 - The Android secure 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. 16import os 17import time 18 19from acts import asserts 20from acts import context 21from acts.controllers.access_point import setup_ap 22from acts.controllers.ap_lib import hostapd_constants 23from acts.controllers.ap_lib.radvd import Radvd 24from acts.controllers.ap_lib import radvd_constants 25from acts.controllers.ap_lib.radvd_config import RadvdConfig 26from acts.controllers.ap_lib.hostapd_security import Security 27from acts.controllers.attenuator import get_attenuators_for_device 28from acts.controllers.iperf_server import IPerfResult 29from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 30from acts_contrib.test_utils.abstract_devices.wlan_device import create_wlan_device 31from acts.utils import rand_ascii_str 32 33from bokeh.plotting import ColumnDataSource 34from bokeh.plotting import figure 35from bokeh.plotting import output_file 36from bokeh.plotting import save 37 38AP_11ABG_PROFILE_NAME = 'whirlwind_11ag_legacy' 39REPORTING_SPEED_UNITS = 'Mbps' 40 41RVR_GRAPH_SUMMARY_FILE = 'rvr_summary.html' 42 43DAD_TIMEOUT_SEC = 30 44 45 46def create_rvr_graph(test_name, graph_path, graph_data): 47 """Creates the RvR graphs 48 Args: 49 test_name: The name of test that was run. This is the title of the 50 graph 51 graph_path: Where to put the graph html file. 52 graph_data: A dictionary of the data to be graphed. 53 Returns: 54 A list of bokeh graph objects. 55 """ 56 output_file('%srvr_throughput_vs_attn_%s.html' % (graph_path, test_name), 57 title=test_name) 58 throughput_vs_attn_data = ColumnDataSource(data=dict( 59 relative_attn=graph_data['throughput_vs_attn']['relative_attn'], 60 throughput=graph_data['throughput_vs_attn']['throughput'])) 61 TOOLTIPS = [("Attenuation", "@relative_attn"), 62 ("Throughput", "@throughput")] 63 throughput_vs_attn_graph = figure( 64 title="Throughput vs Relative Attenuation (Test Case: %s)" % test_name, 65 x_axis_label=graph_data['throughput_vs_attn']['x_label'], 66 y_axis_label=graph_data['throughput_vs_attn']['y_label'], 67 x_range=graph_data['throughput_vs_attn']['relative_attn'], 68 tooltips=TOOLTIPS) 69 throughput_vs_attn_graph.sizing_mode = 'stretch_width' 70 throughput_vs_attn_graph.title.align = 'center' 71 throughput_vs_attn_graph.line('relative_attn', 72 'throughput', 73 source=throughput_vs_attn_data, 74 line_width=2) 75 throughput_vs_attn_graph.circle('relative_attn', 76 'throughput', 77 source=throughput_vs_attn_data, 78 size=10) 79 save([throughput_vs_attn_graph]) 80 return [throughput_vs_attn_graph] 81 82 83def write_csv_rvr_data(test_name, csv_path, csv_data): 84 """Writes the CSV data for the RvR test 85 Args: 86 test_name: The name of test that was run. 87 csv_path: Where to put the csv file. 88 csv_data: A dictionary of the data to be put in the csv file. 89 """ 90 csv_file_name = '%srvr_throughput_vs_attn_%s.csv' % (csv_path, test_name) 91 throughput = csv_data['throughput_vs_attn']['throughput'] 92 relative_attn = csv_data['throughput_vs_attn']['relative_attn'] 93 with open(csv_file_name, 'w+') as csv_fileId: 94 csv_fileId.write('%s,%s\n' % 95 (csv_data['throughput_vs_attn']['x_label'], 96 csv_data['throughput_vs_attn']['y_label'])) 97 for csv_loop_counter in range(0, len(relative_attn)): 98 csv_fileId.write('%s,%s\n' % (int(relative_attn[csv_loop_counter]), 99 throughput[csv_loop_counter])) 100 101 102class WlanRvrTest(WifiBaseTest): 103 """Tests running WLAN RvR. 104 105 Test Bed Requirement: 106 * One Android device or Fuchsia device 107 * One Access Point 108 * One attenuator 109 * One Linux iPerf Server 110 """ 111 112 def __init__(self, controllers): 113 super().__init__(controllers) 114 self.rvr_graph_summary = [] 115 116 def setup_class(self): 117 super().setup_class() 118 if 'dut' in self.user_params: 119 if self.user_params['dut'] == 'fuchsia_devices': 120 self.dut = create_wlan_device(self.fuchsia_devices[0]) 121 elif self.user_params['dut'] == 'android_devices': 122 self.dut = create_wlan_device(self.android_devices[0]) 123 else: 124 raise ValueError('Invalid DUT specified in config. (%s)' % 125 self.user_params['dut']) 126 else: 127 # Default is an android device, just like the other tests 128 self.dut = create_wlan_device(self.android_devices[0]) 129 130 self.starting_attn = (self.user_params['rvr_settings'].get( 131 'starting_attn', 0)) 132 133 self.ending_attn = (self.user_params['rvr_settings'].get( 134 'ending_attn', 95)) 135 136 self.step_size_in_db = (self.user_params['rvr_settings'].get( 137 'step_size_in_db', 1)) 138 139 self.dwell_time_in_secs = (self.user_params['rvr_settings'].get( 140 'dwell_time_in_secs', 10)) 141 142 self.reverse_rvr_after_forward = bool( 143 (self.user_params['rvr_settings'].get('reverse_rvr_after_forward', 144 None))) 145 146 self.iperf_flags = (self.user_params['rvr_settings'].get( 147 'iperf_flags', '-i 1')) 148 149 self.iperf_flags = '%s -t %s -J' % (self.iperf_flags, 150 self.dwell_time_in_secs) 151 152 self.debug_loop_count = (self.user_params['rvr_settings'].get( 153 'debug_loop_count', 1)) 154 155 self.debug_pre_traffic_cmd = (self.user_params['rvr_settings'].get( 156 'debug_pre_traffic_cmd', None)) 157 158 self.debug_post_traffic_cmd = (self.user_params['rvr_settings'].get( 159 'debug_post_traffic_cmd', None)) 160 161 self.router_adv_daemon = None 162 163 if self.ending_attn == 'auto': 164 self.use_auto_end = True 165 self.ending_attn = 100 166 if self.step_size_in_db > 2: 167 asserts.fail('When using an ending attenuation of \'auto\' ' 168 'please use a value < 2db. Larger jumps will ' 169 'break the test reporting.') 170 171 self.access_point = self.access_points[0] 172 self.attenuators_2g = get_attenuators_for_device( 173 self.controller_configs['AccessPoint'][0]['Attenuator'], 174 self.attenuators, 'attenuator_ports_wifi_2g') 175 self.attenuators_5g = get_attenuators_for_device( 176 self.controller_configs['AccessPoint'][0]['Attenuator'], 177 self.attenuators, 'attenuator_ports_wifi_5g') 178 179 self.iperf_server = self.iperf_servers[0] 180 181 if hasattr(self, "iperf_clients") and self.iperf_clients: 182 self.dut_iperf_client = self.iperf_clients[0] 183 else: 184 self.dut_iperf_client = self.dut.create_iperf_client() 185 186 self.access_point.stop_all_aps() 187 188 def setup_test(self): 189 if self.iperf_server: 190 self.iperf_server.start() 191 if hasattr(self, "android_devices"): 192 for ad in self.android_devices: 193 ad.droid.wakeLockAcquireBright() 194 ad.droid.wakeUpNow() 195 self.dut.wifi_toggle_state(True) 196 197 def teardown_test(self): 198 self.cleanup_tests() 199 200 def teardown_class(self): 201 if self.router_adv_daemon: 202 self.router_adv_daemon.stop() 203 try: 204 output_path = context.get_current_context().get_base_output_path() 205 test_class_name = context.get_current_context().test_class_name 206 207 output_file(f'{output_path}/{test_class_name}/rvr_summary.html', 208 title='RvR Sumamry') 209 save(list(self.rvr_graph_summary)) 210 except Exception as e: 211 self.log.error(f'Unable to generate RvR summary file: {e}') 212 213 super().teardown_class() 214 215 def on_fail(self, test_name, begin_time): 216 super().on_fail(test_name, begin_time) 217 self.cleanup_tests() 218 219 def cleanup_tests(self): 220 """Cleans up all the dangling pieces of the tests, for example, the 221 iperf server, radvd, all the currently running APs, and the various 222 clients running during the tests. 223 """ 224 225 if self.router_adv_daemon: 226 output_path = context.get_current_context().get_base_output_path() 227 full_output_path = os.path.join(output_path, "radvd_log.txt") 228 radvd_log_file = open(full_output_path, 'w') 229 radvd_log_file.write(self.router_adv_daemon.pull_logs()) 230 radvd_log_file.close() 231 self.router_adv_daemon.stop() 232 if hasattr(self, "android_devices"): 233 for ad in self.android_devices: 234 ad.droid.wakeLockRelease() 235 ad.droid.goToSleepNow() 236 if self.iperf_server: 237 self.iperf_server.stop() 238 self.dut.turn_location_off_and_scan_toggle_off() 239 self.dut.disconnect() 240 self.dut.reset_wifi() 241 self.download_ap_logs() 242 self.access_point.stop_all_aps() 243 244 def _wait_for_ipv4_addrs(self): 245 """Wait for an IPv4 addresses to become available on the DUT and iperf 246 server. 247 248 Returns: 249 A string containing the private IPv4 address of the iperf server. 250 251 Raises: 252 TestFailure: If unable to acquire a IPv4 address. 253 """ 254 ip_address_checker_counter = 0 255 ip_address_checker_max_attempts = 3 256 while ip_address_checker_counter < ip_address_checker_max_attempts: 257 self.iperf_server.renew_test_interface_ip_address() 258 iperf_server_ip_addresses = ( 259 self.iperf_server.get_interface_ip_addresses( 260 self.iperf_server.test_interface)) 261 dut_ip_addresses = self.dut.device.get_interface_ip_addresses( 262 self.dut_iperf_client.test_interface) 263 264 self.log.info( 265 'IPerf server IP info: {}'.format(iperf_server_ip_addresses)) 266 self.log.info('DUT IP info: {}'.format(dut_ip_addresses)) 267 268 if not iperf_server_ip_addresses['ipv4_private']: 269 self.log.warn('Unable to get the iperf server IPv4 ' 270 'address. Retrying...') 271 ip_address_checker_counter += 1 272 time.sleep(1) 273 continue 274 275 if dut_ip_addresses['ipv4_private']: 276 return iperf_server_ip_addresses['ipv4_private'][0] 277 278 self.log.warn('Unable to get the DUT IPv4 address starting at ' 279 'attenuation "{}". Retrying...'.format( 280 self.starting_attn)) 281 ip_address_checker_counter += 1 282 time.sleep(1) 283 284 asserts.fail( 285 'IPv4 addresses are not available on both the DUT and iperf server.' 286 ) 287 288 # TODO (b/258264565): Merge with fuchsia_device wait_for_ipv6_addr. 289 def _wait_for_dad(self, device, test_interface): 290 """Wait for Duplicate Address Detection to resolve so that an 291 private-local IPv6 address is available for test. 292 293 Args: 294 device: implementor of get_interface_ip_addresses 295 test_interface: name of interface that DAD is operating on 296 297 Returns: 298 A string containing the private-local IPv6 address of the device. 299 300 Raises: 301 TestFailure: If unable to acquire an IPv6 address. 302 """ 303 now = time.time() 304 start = now 305 elapsed = now - start 306 307 while elapsed < DAD_TIMEOUT_SEC: 308 addrs = device.get_interface_ip_addresses(test_interface) 309 now = time.time() 310 elapsed = now - start 311 if addrs['ipv6_private_local']: 312 # DAD has completed 313 addr = addrs['ipv6_private_local'][0] 314 self.log.info('DAD resolved with "{}" after {}s'.format( 315 addr, elapsed)) 316 return addr 317 time.sleep(1) 318 else: 319 asserts.fail( 320 'Unable to acquire a private-local IPv6 address for testing ' 321 'after {}s'.format(elapsed)) 322 323 def run_rvr(self, 324 ssid, 325 security_mode=None, 326 password=None, 327 band='2g', 328 traffic_dir='tx', 329 ip_version=4): 330 """Setups and runs the RvR test 331 332 Args: 333 ssid: The SSID for the client to associate to. 334 password: Password for the network, if necessary. 335 band: 2g or 5g 336 traffic_dir: rx or tx, bi is not supported by iperf3 337 ip_version: 4 or 6 338 339 Returns: 340 The bokeh graph data. 341 """ 342 throughput = [] 343 relative_attn = [] 344 if band == '2g': 345 rvr_attenuators = self.attenuators_2g 346 elif band == '5g': 347 rvr_attenuators = self.attenuators_5g 348 else: 349 raise ValueError('Invalid WLAN band specified: %s' % band) 350 if ip_version == 6: 351 self.router_adv_daemon = Radvd( 352 self.access_point.ssh, 353 self.access_point.interfaces.get_bridge_interface()[0]) 354 radvd_config = RadvdConfig() 355 self.router_adv_daemon.start(radvd_config) 356 357 for _ in range(0, self.debug_loop_count): 358 for rvr_attenuator in rvr_attenuators: 359 rvr_attenuator.set_atten(self.starting_attn) 360 361 associate_counter = 0 362 associate_max_attempts = 3 363 while associate_counter < associate_max_attempts: 364 if self.dut.associate( 365 ssid, 366 target_pwd=password, 367 target_security=hostapd_constants. 368 SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get( 369 security_mode), 370 check_connectivity=False): 371 break 372 else: 373 associate_counter += 1 374 else: 375 asserts.fail('Unable to associate at starting ' 376 'attenuation: %s' % self.starting_attn) 377 378 if ip_version == 4: 379 iperf_server_ip_address = self._wait_for_ipv4_addrs() 380 elif ip_version == 6: 381 self.iperf_server.renew_test_interface_ip_address() 382 self.log.info('Waiting for iperf server to complete Duplicate ' 383 'Address Detection...') 384 iperf_server_ip_address = self._wait_for_dad( 385 self.iperf_server, self.iperf_server.test_interface) 386 387 self.log.info('Waiting for DUT to complete Duplicate Address ' 388 'Detection for "{}"...'.format( 389 self.dut_iperf_client.test_interface)) 390 _ = self._wait_for_dad(self.dut.device, 391 self.dut_iperf_client.test_interface) 392 else: 393 raise ValueError('Invalid IP version: {}'.format(ip_version)) 394 395 throughput, relative_attn = (self.rvr_loop( 396 traffic_dir, 397 rvr_attenuators, 398 iperf_server_ip_address, 399 ip_version, 400 throughput=throughput, 401 relative_attn=relative_attn)) 402 if self.reverse_rvr_after_forward: 403 throughput, relative_attn = self.rvr_loop( 404 traffic_dir, 405 rvr_attenuators, 406 iperf_server_ip_address, 407 ip_version, 408 ssid=ssid, 409 security_mode=security_mode, 410 password=password, 411 reverse=True, 412 throughput=throughput, 413 relative_attn=relative_attn) 414 self.dut.disconnect() 415 416 throughput_vs_attn = { 417 'throughput': throughput, 418 'relative_attn': relative_attn, 419 'x_label': 'Attenuation(db)', 420 'y_label': 'Throughput(%s)' % REPORTING_SPEED_UNITS 421 } 422 graph_data = {'throughput_vs_attn': throughput_vs_attn} 423 return graph_data 424 425 def rvr_loop(self, 426 traffic_dir, 427 rvr_attenuators, 428 iperf_server_ip_address, 429 ip_version, 430 ssid=None, 431 security_mode=None, 432 password=None, 433 reverse=False, 434 throughput=None, 435 relative_attn=None): 436 """The loop that goes through each attenuation level and runs the iperf 437 throughput pair. 438 Args: 439 traffic_dir: The traffic direction from the perspective of the DUT. 440 rvr_attenuators: A list of attenuators to set. 441 iperf_server_ip_address: The IP address of the iperf server. 442 ssid: The ssid of the wireless network that the should associated 443 to. 444 password: Password of the wireless network. 445 reverse: Whether to run RvR test starting from the highest 446 attenuation and going to the lowest. This is run after the 447 normal low attenuation to high attenuation RvR test. 448 throughput: The list of throughput data for the test. 449 relative_attn: The list of attenuation data for the test. 450 451 Returns: 452 throughput: The list of throughput data for the test. 453 relative_attn: The list of attenuation data for the test. 454 """ 455 iperf_flags = self.iperf_flags 456 if traffic_dir == 'rx': 457 iperf_flags = '%s -R' % self.iperf_flags 458 starting_attn = self.starting_attn 459 ending_attn = self.ending_attn 460 step_size_in_db = self.step_size_in_db 461 if reverse: 462 starting_attn = self.ending_attn 463 ending_attn = self.starting_attn 464 step_size_in_db = step_size_in_db * -1 465 self.dut.disconnect() 466 for step in range(starting_attn, ending_attn, step_size_in_db): 467 try: 468 for attenuator in rvr_attenuators: 469 attenuator.set_atten(step) 470 except ValueError as e: 471 self.log.error( 472 f'{step} is beyond the max or min of the testbed ' 473 f'attenuator\'s capability. Stopping. {e}') 474 break 475 self.log.info('Set relative attenuation to %s db' % step) 476 477 associated = self.dut.is_connected() 478 if associated: 479 self.log.info('DUT is currently associated.') 480 else: 481 self.log.info('DUT is not currently associated.') 482 483 if reverse: 484 if not associated: 485 self.log.info('Trying to associate at relative ' 486 'attenuation of %s db' % step) 487 if self.dut.associate( 488 ssid, 489 target_pwd=password, 490 target_security=hostapd_constants. 491 SECURITY_STRING_TO_DEFAULT_TARGET_SECURITY.get( 492 security_mode), 493 check_connectivity=False): 494 associated = True 495 self.log.info('Successfully associated.') 496 else: 497 associated = False 498 self.log.info( 499 'Association failed. Marking a 0 %s for' 500 ' throughput. Skipping running traffic.' % 501 REPORTING_SPEED_UNITS) 502 attn_value_inserted = False 503 value_to_insert = str(step) 504 while not attn_value_inserted: 505 if value_to_insert in relative_attn: 506 value_to_insert = '%s ' % value_to_insert 507 else: 508 relative_attn.append(value_to_insert) 509 attn_value_inserted = True 510 511 dut_ip_addresses = self.dut.device.get_interface_ip_addresses( 512 self.dut_iperf_client.test_interface) 513 if ip_version == 4: 514 if not dut_ip_addresses['ipv4_private']: 515 self.log.info('DUT does not have an IPv4 address. ' 516 'Traffic attempt to be run if the server ' 517 'is pingable.') 518 else: 519 self.log.info('DUT has the following IPv4 address: "%s"' % 520 dut_ip_addresses['ipv4_private'][0]) 521 elif ip_version == 6: 522 if not dut_ip_addresses['ipv6_private_local']: 523 self.log.info('DUT does not have an IPv6 address. ' 524 'Traffic attempt to be run if the server ' 525 'is pingable.') 526 else: 527 self.log.info('DUT has the following IPv6 address: "%s"' % 528 dut_ip_addresses['ipv6_private_local'][0]) 529 server_pingable = self.dut.can_ping(iperf_server_ip_address) 530 if not server_pingable: 531 self.log.info('Iperf server "%s" is not pingable. Marking ' 532 'a 0 %s for throughput. Skipping running ' 533 'traffic.' % 534 (iperf_server_ip_address, REPORTING_SPEED_UNITS)) 535 else: 536 self.log.info('Iperf server "%s" is pingable.' % 537 iperf_server_ip_address) 538 if self.debug_pre_traffic_cmd: 539 self.log.info('\nDEBUG: Sending command \'%s\' to DUT' % 540 self.debug_pre_traffic_cmd) 541 self.log.info( 542 '\n%s' % self.dut.send_command(self.debug_pre_traffic_cmd)) 543 if server_pingable: 544 if traffic_dir == 'tx': 545 self.log.info('Running traffic DUT to %s at relative ' 546 'attenuation of %s' % 547 (iperf_server_ip_address, step)) 548 elif traffic_dir == 'rx': 549 self.log.info('Running traffic %s to DUT at relative ' 550 'attenuation of %s' % 551 (iperf_server_ip_address, step)) 552 else: 553 raise ValueError('Invalid traffic direction') 554 try: 555 iperf_tag = 'decreasing' 556 if reverse: 557 iperf_tag = 'increasing' 558 iperf_results_file = self.dut_iperf_client.start( 559 iperf_server_ip_address, 560 iperf_flags, 561 '%s_%s_%s' % 562 (iperf_tag, traffic_dir, self.starting_attn), 563 timeout=(self.dwell_time_in_secs * 2)) 564 except TimeoutError as e: 565 iperf_results_file = None 566 self.log.error( 567 f'Iperf traffic timed out. Marking 0 {REPORTING_SPEED_UNITS} for ' 568 f'throughput. {e}') 569 570 if not iperf_results_file: 571 throughput.append(0) 572 else: 573 try: 574 iperf_results = IPerfResult( 575 iperf_results_file, 576 reporting_speed_units=REPORTING_SPEED_UNITS) 577 if iperf_results.error: 578 self.iperf_server.stop() 579 self.iperf_server.start() 580 self.log.error( 581 f'Errors in iperf logs:\n{iperf_results.error}' 582 ) 583 if not iperf_results.avg_send_rate: 584 throughput.append(0) 585 else: 586 throughput.append(iperf_results.avg_send_rate) 587 except ValueError as e: 588 self.iperf_server.stop() 589 self.iperf_server.start() 590 self.log.error( 591 f'No data in iPerf3 file. Marking 0 {REPORTING_SPEED_UNITS} ' 592 f'for throughput: {e}') 593 throughput.append(0) 594 except Exception as e: 595 self.iperf_server.stop() 596 self.iperf_server.start() 597 self.log.error( 598 f'Unknown exception. Marking 0 {REPORTING_SPEED_UNITS} for ' 599 f'throughput: {e}') 600 self.log.error(e) 601 throughput.append(0) 602 603 self.log.info( 604 'Iperf traffic complete. %s traffic received at ' 605 '%s %s at relative attenuation of %s db' % 606 (traffic_dir, throughput[-1], REPORTING_SPEED_UNITS, 607 str(relative_attn[-1]).strip())) 608 609 else: 610 self.log.debug('DUT Associated: %s' % associated) 611 self.log.debug('%s pingable: %s' % 612 (iperf_server_ip_address, server_pingable)) 613 throughput.append(0) 614 if self.debug_post_traffic_cmd: 615 self.log.info('\nDEBUG: Sending command \'%s\' to DUT' % 616 self.debug_post_traffic_cmd) 617 self.log.info( 618 '\n%s' % 619 self.dut.send_command(self.debug_post_traffic_cmd)) 620 return throughput, relative_attn 621 622 def test_rvr_11ac_5g_80mhz_open_tx_ipv4(self): 623 ssid = rand_ascii_str(20) 624 setup_ap(access_point=self.access_point, 625 profile_name='whirlwind', 626 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 627 ssid=ssid, 628 setup_bridge=True) 629 graph_data = self.run_rvr(ssid, 630 band='5g', 631 traffic_dir='tx', 632 ip_version=4) 633 for rvr_graph in create_rvr_graph( 634 self.test_name, 635 context.get_current_context().get_full_output_path(), 636 graph_data): 637 self.rvr_graph_summary.append(rvr_graph) 638 write_csv_rvr_data( 639 self.test_name, 640 context.get_current_context().get_full_output_path(), graph_data) 641 642 def test_rvr_11ac_5g_80mhz_open_rx_ipv4(self): 643 ssid = rand_ascii_str(20) 644 setup_ap(access_point=self.access_point, 645 profile_name='whirlwind', 646 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 647 ssid=ssid, 648 setup_bridge=True) 649 graph_data = self.run_rvr(ssid, 650 band='5g', 651 traffic_dir='rx', 652 ip_version=4) 653 for rvr_graph in create_rvr_graph( 654 self.test_name, 655 context.get_current_context().get_full_output_path(), 656 graph_data): 657 self.rvr_graph_summary.append(rvr_graph) 658 write_csv_rvr_data( 659 self.test_name, 660 context.get_current_context().get_full_output_path(), graph_data) 661 662 def test_rvr_11ac_5g_80mhz_open_tx_ipv6(self): 663 ssid = rand_ascii_str(20) 664 setup_ap(access_point=self.access_point, 665 profile_name='whirlwind', 666 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 667 ssid=ssid, 668 setup_bridge=True) 669 graph_data = self.run_rvr(ssid, 670 band='5g', 671 traffic_dir='tx', 672 ip_version=6) 673 for rvr_graph in create_rvr_graph( 674 self.test_name, 675 context.get_current_context().get_full_output_path(), 676 graph_data): 677 self.rvr_graph_summary.append(rvr_graph) 678 write_csv_rvr_data( 679 self.test_name, 680 context.get_current_context().get_full_output_path(), graph_data) 681 682 def test_rvr_11ac_5g_80mhz_open_rx_ipv6(self): 683 ssid = rand_ascii_str(20) 684 setup_ap(access_point=self.access_point, 685 profile_name='whirlwind', 686 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 687 ssid=ssid, 688 setup_bridge=True) 689 graph_data = self.run_rvr(ssid, 690 band='5g', 691 traffic_dir='rx', 692 ip_version=6) 693 for rvr_graph in create_rvr_graph( 694 self.test_name, 695 context.get_current_context().get_full_output_path(), 696 graph_data): 697 self.rvr_graph_summary.append(rvr_graph) 698 write_csv_rvr_data( 699 self.test_name, 700 context.get_current_context().get_full_output_path(), graph_data) 701 702 def test_rvr_11ac_5g_80mhz_wpa2_tx_ipv4(self): 703 ssid = rand_ascii_str(20) 704 password = rand_ascii_str(20) 705 security_profile = Security(security_mode='wpa2', password=password) 706 setup_ap(access_point=self.access_point, 707 profile_name='whirlwind', 708 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 709 ssid=ssid, 710 security=security_profile, 711 setup_bridge=True) 712 graph_data = self.run_rvr(ssid, 713 security_mode='wpa2', 714 password=password, 715 band='5g', 716 traffic_dir='tx', 717 ip_version=4) 718 for rvr_graph in create_rvr_graph( 719 self.test_name, 720 context.get_current_context().get_full_output_path(), 721 graph_data): 722 self.rvr_graph_summary.append(rvr_graph) 723 write_csv_rvr_data( 724 self.test_name, 725 context.get_current_context().get_full_output_path(), graph_data) 726 727 def test_rvr_11ac_5g_80mhz_wpa2_rx_ipv4(self): 728 ssid = rand_ascii_str(20) 729 password = rand_ascii_str(20) 730 security_profile = Security(security_mode='wpa2', password=password) 731 setup_ap(access_point=self.access_point, 732 profile_name='whirlwind', 733 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 734 ssid=ssid, 735 security=security_profile, 736 setup_bridge=True) 737 graph_data = self.run_rvr(ssid, 738 security_mode='wpa2', 739 password=password, 740 band='5g', 741 traffic_dir='rx', 742 ip_version=4) 743 for rvr_graph in create_rvr_graph( 744 self.test_name, 745 context.get_current_context().get_full_output_path(), 746 graph_data): 747 self.rvr_graph_summary.append(rvr_graph) 748 write_csv_rvr_data( 749 self.test_name, 750 context.get_current_context().get_full_output_path(), graph_data) 751 752 def test_rvr_11ac_5g_80mhz_wpa2_tx_ipv6(self): 753 ssid = rand_ascii_str(20) 754 password = rand_ascii_str(20) 755 security_profile = Security(security_mode='wpa2', password=password) 756 setup_ap(access_point=self.access_point, 757 profile_name='whirlwind', 758 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 759 ssid=ssid, 760 security=security_profile, 761 setup_bridge=True) 762 graph_data = self.run_rvr(ssid, 763 security_mode='wpa2', 764 password=password, 765 band='5g', 766 traffic_dir='tx', 767 ip_version=6) 768 for rvr_graph in create_rvr_graph( 769 self.test_name, 770 context.get_current_context().get_full_output_path(), 771 graph_data): 772 self.rvr_graph_summary.append(rvr_graph) 773 write_csv_rvr_data( 774 self.test_name, 775 context.get_current_context().get_full_output_path(), graph_data) 776 777 def test_rvr_11ac_5g_80mhz_wpa2_rx_ipv6(self): 778 ssid = rand_ascii_str(20) 779 password = rand_ascii_str(20) 780 security_profile = Security(security_mode='wpa2', password=password) 781 setup_ap(access_point=self.access_point, 782 profile_name='whirlwind', 783 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 784 ssid=ssid, 785 security=security_profile, 786 setup_bridge=True) 787 graph_data = self.run_rvr(ssid, 788 security_mode='wpa2', 789 password=password, 790 band='5g', 791 traffic_dir='rx', 792 ip_version=6) 793 for rvr_graph in create_rvr_graph( 794 self.test_name, 795 context.get_current_context().get_full_output_path(), 796 graph_data): 797 self.rvr_graph_summary.append(rvr_graph) 798 write_csv_rvr_data( 799 self.test_name, 800 context.get_current_context().get_full_output_path(), graph_data) 801 802 def test_rvr_11n_2g_20mhz_open_tx_ipv4(self): 803 ssid = rand_ascii_str(20) 804 setup_ap(access_point=self.access_point, 805 profile_name='whirlwind', 806 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 807 ssid=ssid, 808 setup_bridge=True) 809 graph_data = self.run_rvr(ssid, 810 band='2g', 811 traffic_dir='tx', 812 ip_version=4) 813 for rvr_graph in create_rvr_graph( 814 self.test_name, 815 context.get_current_context().get_full_output_path(), 816 graph_data): 817 self.rvr_graph_summary.append(rvr_graph) 818 write_csv_rvr_data( 819 self.test_name, 820 context.get_current_context().get_full_output_path(), graph_data) 821 822 def test_rvr_11n_2g_20mhz_open_rx_ipv4(self): 823 ssid = rand_ascii_str(20) 824 setup_ap(access_point=self.access_point, 825 profile_name='whirlwind', 826 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 827 ssid=ssid, 828 setup_bridge=True) 829 graph_data = self.run_rvr(ssid, 830 band='2g', 831 traffic_dir='rx', 832 ip_version=4) 833 for rvr_graph in create_rvr_graph( 834 self.test_name, 835 context.get_current_context().get_full_output_path(), 836 graph_data): 837 self.rvr_graph_summary.append(rvr_graph) 838 write_csv_rvr_data( 839 self.test_name, 840 context.get_current_context().get_full_output_path(), graph_data) 841 842 def test_rvr_11n_2g_20mhz_open_tx_ipv6(self): 843 ssid = rand_ascii_str(20) 844 setup_ap(access_point=self.access_point, 845 profile_name='whirlwind', 846 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 847 ssid=ssid, 848 setup_bridge=True) 849 graph_data = self.run_rvr(ssid, 850 band='2g', 851 traffic_dir='tx', 852 ip_version=6) 853 for rvr_graph in create_rvr_graph( 854 self.test_name, 855 context.get_current_context().get_full_output_path(), 856 graph_data): 857 self.rvr_graph_summary.append(rvr_graph) 858 write_csv_rvr_data( 859 self.test_name, 860 context.get_current_context().get_full_output_path(), graph_data) 861 862 def test_rvr_11n_2g_20mhz_open_rx_ipv6(self): 863 ssid = rand_ascii_str(20) 864 setup_ap(access_point=self.access_point, 865 profile_name='whirlwind', 866 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 867 ssid=ssid, 868 setup_bridge=True) 869 graph_data = self.run_rvr(ssid, 870 band='2g', 871 traffic_dir='rx', 872 ip_version=6) 873 for rvr_graph in create_rvr_graph( 874 self.test_name, 875 context.get_current_context().get_full_output_path(), 876 graph_data): 877 self.rvr_graph_summary.append(rvr_graph) 878 write_csv_rvr_data( 879 self.test_name, 880 context.get_current_context().get_full_output_path(), graph_data) 881 882 def test_rvr_11n_2g_20mhz_wpa2_tx_ipv4(self): 883 ssid = rand_ascii_str(20) 884 password = rand_ascii_str(20) 885 security_profile = Security(security_mode='wpa2', password=password) 886 setup_ap(access_point=self.access_point, 887 profile_name='whirlwind', 888 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 889 ssid=ssid, 890 security=security_profile, 891 setup_bridge=True) 892 graph_data = self.run_rvr(ssid, 893 security_mode='wpa2', 894 password=password, 895 band='2g', 896 traffic_dir='tx', 897 ip_version=4) 898 for rvr_graph in create_rvr_graph( 899 self.test_name, 900 context.get_current_context().get_full_output_path(), 901 graph_data): 902 self.rvr_graph_summary.append(rvr_graph) 903 write_csv_rvr_data( 904 self.test_name, 905 context.get_current_context().get_full_output_path(), graph_data) 906 907 def test_rvr_11n_2g_20mhz_wpa2_rx_ipv4(self): 908 ssid = rand_ascii_str(20) 909 password = rand_ascii_str(20) 910 security_profile = Security(security_mode='wpa2', password=password) 911 setup_ap(access_point=self.access_point, 912 profile_name='whirlwind', 913 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 914 ssid=ssid, 915 security=security_profile, 916 setup_bridge=True) 917 graph_data = self.run_rvr(ssid, 918 security_mode='wpa2', 919 password=password, 920 band='2g', 921 traffic_dir='rx', 922 ip_version=4) 923 for rvr_graph in create_rvr_graph( 924 self.test_name, 925 context.get_current_context().get_full_output_path(), 926 graph_data): 927 self.rvr_graph_summary.append(rvr_graph) 928 write_csv_rvr_data( 929 self.test_name, 930 context.get_current_context().get_full_output_path(), graph_data) 931 932 def test_rvr_11n_2g_20mhz_wpa2_tx_ipv6(self): 933 ssid = rand_ascii_str(20) 934 password = rand_ascii_str(20) 935 security_profile = Security(security_mode='wpa2', password=password) 936 setup_ap(access_point=self.access_point, 937 profile_name='whirlwind', 938 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 939 ssid=ssid, 940 security=security_profile, 941 setup_bridge=True) 942 graph_data = self.run_rvr(ssid, 943 security_mode='wpa2', 944 password=password, 945 band='2g', 946 traffic_dir='tx', 947 ip_version=6) 948 for rvr_graph in create_rvr_graph( 949 self.test_name, 950 context.get_current_context().get_full_output_path(), 951 graph_data): 952 self.rvr_graph_summary.append(rvr_graph) 953 write_csv_rvr_data( 954 self.test_name, 955 context.get_current_context().get_full_output_path(), graph_data) 956 957 def test_rvr_11n_2g_20mhz_wpa2_rx_ipv6(self): 958 ssid = rand_ascii_str(20) 959 password = rand_ascii_str(20) 960 security_profile = Security(security_mode='wpa2', password=password) 961 setup_ap(access_point=self.access_point, 962 profile_name='whirlwind', 963 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 964 ssid=ssid, 965 security=security_profile, 966 setup_bridge=True) 967 graph_data = self.run_rvr(ssid, 968 security_mode='wpa2', 969 password=password, 970 band='2g', 971 traffic_dir='rx', 972 ip_version=6) 973 for rvr_graph in create_rvr_graph( 974 self.test_name, 975 context.get_current_context().get_full_output_path(), 976 graph_data): 977 self.rvr_graph_summary.append(rvr_graph) 978 write_csv_rvr_data( 979 self.test_name, 980 context.get_current_context().get_full_output_path(), graph_data) 981