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