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.ap_lib import hostapd_constants 21from acts.controllers.ap_lib.radvd import Radvd 22from acts.controllers.ap_lib import radvd_constants 23from acts.controllers.ap_lib.radvd_config import RadvdConfig 24from acts.controllers.ap_lib.hostapd_security import Security 25from acts.controllers.attenuator import get_attenuators_for_device 26from acts.controllers.iperf_server import IPerfResult 27from acts.test_utils.abstract_devices.utils_lib.wlan_utils import associate 28from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap 29from acts.test_utils.abstract_devices.wlan_device import create_wlan_device 30from acts.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(WifiBaseTest): 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 if self.router_adv_daemon: 194 self.router_adv_daemon.stop() 195 if hasattr(self, "android_devices"): 196 for ad in self.android_devices: 197 ad.droid.wakeLockRelease() 198 ad.droid.goToSleepNow() 199 if self.iperf_server: 200 self.iperf_server.stop() 201 self.dut.turn_location_off_and_scan_toggle_off() 202 self.dut.disconnect() 203 self.dut.reset_wifi() 204 self.access_point.stop_all_aps() 205 206 def teardown_class(self): 207 if self.router_adv_daemon: 208 self.router_adv_daemon.stop() 209 try: 210 output_path = context.get_current_context().get_base_output_path() 211 test_class_name = context.get_current_context().test_class_name 212 213 output_file(f'{output_path}/{test_class_name}/rvr_summary.html', 214 title='RvR Sumamry') 215 save(list(self.rvr_graph_summary)) 216 except Exception as e: 217 self.log.info('Unable to generate RvR summary file due ' 218 'to Exception') 219 self.log.info(e) 220 221 def on_fail(self, test_name, begin_time): 222 self.dut.take_bug_report(test_name, begin_time) 223 self.dut.get_log(test_name, begin_time) 224 225 def run_rvr(self, 226 ssid, 227 password=None, 228 band='2g', 229 traffic_dir='tx', 230 ip_version=4): 231 """Setups and runs the RvR test 232 233 Args: 234 ssid: The SSID for the client to associate to. 235 password: Password for the network, if necessary. 236 band: 2g or 5g 237 traffic_dir: rx or tx, bi is not supported by iperf3 238 ip_version: 4 or 6 239 240 Returns: 241 The bokeh graph data. 242 """ 243 throughput = [] 244 relative_attn = [] 245 self.check_if_has_private_local_ipv6_address = True 246 if band == '2g': 247 rvr_attenuators = self.attenuators_2g 248 elif band == '5g': 249 rvr_attenuators = self.attenuators_5g 250 else: 251 raise ValueError('Invalid WLAN band specified: %s' % band) 252 if ip_version == 6: 253 ravdvd_config = RadvdConfig( 254 prefix=RADVD_PREFIX, 255 adv_send_advert=radvd_constants.ADV_SEND_ADVERT_ON, 256 adv_on_link=radvd_constants.ADV_ON_LINK_ON, 257 adv_autonomous=radvd_constants.ADV_AUTONOMOUS_ON) 258 self.router_adv_daemon = Radvd( 259 self.access_point.ssh, 260 self.access_point.interfaces.get_bridge_interface()[0]) 261 self.router_adv_daemon.start(ravdvd_config) 262 263 for rvr_loop_counter in range(0, self.debug_loop_count): 264 for rvr_attenuator in rvr_attenuators: 265 rvr_attenuator.set_atten(self.starting_attn) 266 267 associate_counter = 0 268 associate_max_attempts = 3 269 while associate_counter < associate_max_attempts: 270 if associate(self.dut, 271 ssid, 272 password, 273 check_connectivity=False): 274 break 275 else: 276 associate_counter += 1 277 if associate_counter == associate_max_attempts: 278 asserts.fail('Unable to associate at starting ' 279 'attenuation: %s' % self.starting_attn) 280 281 ip_address_checker_counter = 0 282 ip_address_checker_max_attempts = 3 283 while ip_address_checker_counter < ip_address_checker_max_attempts: 284 self.iperf_server.renew_test_interface_ip_address() 285 iperf_server_ip_addresses = ( 286 self.iperf_server.get_interface_ip_addresses( 287 self.iperf_server.test_interface)) 288 dut_ip_addresses = self.dut.get_interface_ip_addresses( 289 self.dut_iperf_client.test_interface) 290 self.log.info('IPerf server IP info: %s' % 291 iperf_server_ip_addresses) 292 self.log.info('DUT IP info: %s' % dut_ip_addresses) 293 if ip_version == 4: 294 if iperf_server_ip_addresses['ipv4_private']: 295 iperf_server_ip_address = ( 296 iperf_server_ip_addresses['ipv4_private'][0]) 297 if not dut_ip_addresses['ipv4_private']: 298 self.log.warn('Unable to get IPv4 address at starting ' 299 'attenuation: %s Retrying.' % 300 self.starting_attn) 301 ip_address_checker_counter += 1 302 time.sleep(1) 303 else: 304 break 305 elif ip_version == 6: 306 if iperf_server_ip_addresses['ipv6_private_local']: 307 iperf_server_ip_address = ( 308 iperf_server_ip_addresses['ipv6_private_local'][0]) 309 else: 310 self.check_if_has_private_local_ipv6_address = False 311 iperf_server_ip_address = ( 312 '%s%%%s' % 313 (iperf_server_ip_addresses['ipv6_link_local'][0], 314 self.dut_iperf_client.test_interface)) 315 if self.check_if_has_private_local_ipv6_address: 316 if not dut_ip_addresses['ipv6_private_local']: 317 self.log.warn('Unable to get IPv6 address at ' 318 'starting attenuation: %s' % 319 self.starting_attn) 320 ip_address_checker_counter += 1 321 time.sleep(1) 322 else: 323 break 324 else: 325 break 326 else: 327 raise ValueError('Invalid IP version: %s' % ip_version) 328 if ip_address_checker_counter == ip_address_checker_max_attempts: 329 if self.dut.ping(iperf_server_ip_address): 330 self.log.error('IPerf server is pingable. Continuing with ' 331 'test. The missing IP address information ' 332 'should be marked as a bug.') 333 else: 334 asserts.fail('DUT was unable to get IPv%s address and ' 335 'could not ping the IPerf server.' % 336 str(ip_version)) 337 throughput, relative_attn = (self.rvr_loop( 338 traffic_dir, 339 rvr_attenuators, 340 iperf_server_ip_address, 341 ip_version, 342 throughput=throughput, 343 relative_attn=relative_attn)) 344 if self.reverse_rvr_after_forward: 345 throughput, relative_attn = self.rvr_loop( 346 traffic_dir, 347 rvr_attenuators, 348 iperf_server_ip_address, 349 ip_version, 350 ssid=ssid, 351 password=password, 352 reverse=True, 353 throughput=throughput, 354 relative_attn=relative_attn) 355 self.dut.disconnect() 356 357 throughput_vs_attn = { 358 'throughput': throughput, 359 'relative_attn': relative_attn, 360 'x_label': 'Attenuation(db)', 361 'y_label': 'Throughput(%s)' % REPORTING_SPEED_UNITS 362 } 363 graph_data = {'throughput_vs_attn': throughput_vs_attn} 364 return graph_data 365 366 def rvr_loop(self, 367 traffic_dir, 368 rvr_attenuators, 369 iperf_server_ip_address, 370 ip_version, 371 ssid=None, 372 password=None, 373 reverse=False, 374 throughput=None, 375 relative_attn=None): 376 """The loop that goes through each attenuation level and runs the iperf 377 throughput pair. 378 Args: 379 traffic_dir: The traffic direction from the perspective of the DUT. 380 rvr_attenuators: A list of attenuators to set. 381 iperf_server_ip_address: The IP address of the iperf server. 382 ssid: The ssid of the wireless network that the should associated 383 to. 384 password: Password of the wireless network. 385 reverse: Whether to run RvR test starting from the highest 386 attenuation and going to the lowest. This is run after the 387 normal low attenuation to high attenuation RvR test. 388 throughput: The list of throughput data for the test. 389 relative_attn: The list of attenuation data for the test. 390 391 Returns: 392 throughput: The list of throughput data for the test. 393 relative_attn: The list of attenuation data for the test. 394 """ 395 iperf_flags = self.iperf_flags 396 if traffic_dir == 'rx': 397 iperf_flags = '%s -R' % self.iperf_flags 398 starting_attn = self.starting_attn 399 ending_attn = self.ending_attn 400 step_size_in_db = self.step_size_in_db 401 if reverse: 402 starting_attn = self.ending_attn 403 ending_attn = self.starting_attn 404 step_size_in_db = step_size_in_db * -1 405 self.dut.disconnect() 406 for step in range(starting_attn, ending_attn, step_size_in_db): 407 try: 408 for attenuator in rvr_attenuators: 409 attenuator.set_atten(step) 410 except ValueError: 411 self.log.info('%s is beyond the max or min of the testbed ' 412 'attenuator\'s capability. Stopping.') 413 break 414 415 associated = self.dut.is_connected() 416 if associated: 417 self.log.info('DUT is currently associated.') 418 else: 419 self.log.info('DUT is not currently associated.') 420 421 if reverse: 422 if not associated: 423 self.log.info('Trying to associate at relative ' 424 'attenuation of %s db' % step) 425 if associate(self.dut, 426 ssid, 427 password, 428 check_connectivity=False): 429 associated = True 430 self.log.info('Successfully associated.') 431 else: 432 associated = False 433 self.log.info( 434 'Association failed. Marking a 0 %s for' 435 ' throughput. Skipping running traffic.' % 436 REPORTING_SPEED_UNITS) 437 attn_value_inserted = False 438 value_to_insert = str(step) 439 while not attn_value_inserted: 440 if value_to_insert in relative_attn: 441 value_to_insert = '%s ' % value_to_insert 442 else: 443 relative_attn.append(value_to_insert) 444 attn_value_inserted = True 445 446 dut_ip_addresses = self.dut.get_interface_ip_addresses( 447 self.dut_iperf_client.test_interface) 448 if ip_version == 4: 449 if not dut_ip_addresses['ipv4_private']: 450 self.log.info('DUT does not have an IPv4 address. ' 451 'Traffic attempt to be run if the server ' 452 'is pingable.') 453 else: 454 self.log.info('DUT has the following IPv4 address: "%s"' % 455 dut_ip_addresses['ipv4_private'][0]) 456 elif ip_version == 6: 457 if self.check_if_has_private_local_ipv6_address: 458 if not dut_ip_addresses['ipv6_private_local']: 459 self.log.info( 460 'DUT does not have an IPv6 address. ' 461 'Traffic attempt to be run if the server ' 462 'is pingable.') 463 else: 464 self.log.info( 465 'DUT has the following IPv6 address: "%s"' % 466 dut_ip_addresses['ipv6_private_local'][0]) 467 else: 468 self.log.info('DUT has the following IPv6 address: "%s"' % 469 dut_ip_addresses['ipv6_link_local'][0]) 470 server_pingable = self.dut.ping(iperf_server_ip_address) 471 if not server_pingable: 472 self.log.info('Iperf server "%s" is not pingable. Marking ' 473 'a 0 %s for throughput. Skipping running ' 474 'traffic.' % 475 (iperf_server_ip_address, REPORTING_SPEED_UNITS)) 476 else: 477 self.log.info('Iperf server "%s" is pingable.' % 478 iperf_server_ip_address) 479 if self.debug_pre_traffic_cmd: 480 self.log.info('\nDEBUG: Sending command \'%s\' to DUT' % 481 self.debug_pre_traffic_cmd) 482 self.log.info( 483 '\n%s' % self.dut.send_command(self.debug_pre_traffic_cmd)) 484 if server_pingable: 485 if traffic_dir == 'tx': 486 self.log.info('Running traffic DUT to %s at relative ' 487 'attenuation of %s' % 488 (iperf_server_ip_address, step)) 489 elif traffic_dir == 'rx': 490 self.log.info('Running traffic %s to DUT at relative ' 491 'attenuation of %s' % 492 (iperf_server_ip_address, step)) 493 else: 494 raise ValueError('Invalid traffic direction') 495 try: 496 iperf_tag = 'decreasing' 497 if reverse: 498 iperf_tag = 'increasing' 499 iperf_results_file = self.dut_iperf_client.start( 500 iperf_server_ip_address, 501 iperf_flags, 502 '%s_%s_%s' % 503 (iperf_tag, traffic_dir, self.starting_attn), 504 timeout=(self.dwell_time_in_secs * 2)) 505 except TimeoutError: 506 iperf_results_file = None 507 self.log.info('Iperf traffic timed out. Marking 0 %s for ' 508 'throughput.' % REPORTING_SPEED_UNITS) 509 510 if not iperf_results_file: 511 throughput.append(0) 512 else: 513 try: 514 iperf_results = IPerfResult( 515 iperf_results_file, 516 reporting_speed_units=REPORTING_SPEED_UNITS) 517 if iperf_results.error: 518 self.iperf_server.stop() 519 self.iperf_server.start() 520 self.log.info('\nErrors in iperf logs:\n%s' % 521 iperf_results.error) 522 if not iperf_results.avg_send_rate: 523 throughput.append(0) 524 else: 525 throughput.append(iperf_results.avg_send_rate) 526 except ValueError: 527 self.iperf_server.stop() 528 self.iperf_server.start() 529 self.log.info( 530 'No data in Iperf file. Marking 0 %s for ' 531 'throughput.' % REPORTING_SPEED_UNITS) 532 throughput.append(0) 533 except Exception as e: 534 self.iperf_server.stop() 535 self.iperf_server.start() 536 self.log.info('Unknown exception. Marking 0 %s for ' 537 'throughput.' % REPORTING_SPEED_UNITS) 538 self.log.error(e) 539 throughput.append(0) 540 541 self.log.info( 542 'Iperf traffic complete. %s traffic received at ' 543 '%s %s at relative attenuation of %s db' % 544 (traffic_dir, throughput[-1], REPORTING_SPEED_UNITS, 545 str(relative_attn[-1]).strip())) 546 547 else: 548 self.log.debug('DUT Associated: %s' % associated) 549 self.log.debug('%s pingable: %s' % 550 (iperf_server_ip_address, server_pingable)) 551 throughput.append(0) 552 if self.debug_post_traffic_cmd: 553 self.log.info('\nDEBUG: Sending command \'%s\' to DUT' % 554 self.debug_post_traffic_cmd) 555 self.log.info( 556 '\n%s' % 557 self.dut.send_command(self.debug_post_traffic_cmd)) 558 return throughput, relative_attn 559 560 def test_rvr_11ac_5g_80mhz_open_tx_ipv4(self): 561 ssid = rand_ascii_str(20) 562 setup_ap(access_point=self.access_point, 563 profile_name='whirlwind', 564 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 565 ssid=ssid, 566 setup_bridge=True) 567 graph_data = self.run_rvr(ssid, 568 band='5g', 569 traffic_dir='tx', 570 ip_version=4) 571 for rvr_graph in create_rvr_graph( 572 self.test_name, 573 context.get_current_context().get_full_output_path(), 574 graph_data): 575 self.rvr_graph_summary.append(rvr_graph) 576 write_csv_rvr_data( 577 self.test_name, 578 context.get_current_context().get_full_output_path(), graph_data) 579 580 def test_rvr_11ac_5g_80mhz_open_rx_ipv4(self): 581 ssid = rand_ascii_str(20) 582 setup_ap(access_point=self.access_point, 583 profile_name='whirlwind', 584 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 585 ssid=ssid, 586 setup_bridge=True) 587 graph_data = self.run_rvr(ssid, 588 band='5g', 589 traffic_dir='rx', 590 ip_version=4) 591 for rvr_graph in create_rvr_graph( 592 self.test_name, 593 context.get_current_context().get_full_output_path(), 594 graph_data): 595 self.rvr_graph_summary.append(rvr_graph) 596 write_csv_rvr_data( 597 self.test_name, 598 context.get_current_context().get_full_output_path(), graph_data) 599 600 def test_rvr_11ac_5g_80mhz_open_tx_ipv6(self): 601 ssid = rand_ascii_str(20) 602 setup_ap(access_point=self.access_point, 603 profile_name='whirlwind', 604 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 605 ssid=ssid, 606 setup_bridge=True) 607 graph_data = self.run_rvr(ssid, 608 band='5g', 609 traffic_dir='tx', 610 ip_version=6) 611 for rvr_graph in create_rvr_graph( 612 self.test_name, 613 context.get_current_context().get_full_output_path(), 614 graph_data): 615 self.rvr_graph_summary.append(rvr_graph) 616 write_csv_rvr_data( 617 self.test_name, 618 context.get_current_context().get_full_output_path(), graph_data) 619 620 def test_rvr_11ac_5g_80mhz_open_rx_ipv6(self): 621 ssid = rand_ascii_str(20) 622 setup_ap(access_point=self.access_point, 623 profile_name='whirlwind', 624 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 625 ssid=ssid, 626 setup_bridge=True) 627 graph_data = self.run_rvr(ssid, 628 band='5g', 629 traffic_dir='rx', 630 ip_version=6) 631 for rvr_graph in create_rvr_graph( 632 self.test_name, 633 context.get_current_context().get_full_output_path(), 634 graph_data): 635 self.rvr_graph_summary.append(rvr_graph) 636 write_csv_rvr_data( 637 self.test_name, 638 context.get_current_context().get_full_output_path(), graph_data) 639 640 def test_rvr_11ac_5g_80mhz_wpa2_tx_ipv4(self): 641 ssid = rand_ascii_str(20) 642 password = rand_ascii_str(20) 643 security_profile = Security(security_mode='wpa2', password=password) 644 setup_ap(access_point=self.access_point, 645 profile_name='whirlwind', 646 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 647 ssid=ssid, 648 security=security_profile, 649 setup_bridge=True) 650 graph_data = self.run_rvr(ssid, 651 password=password, 652 band='5g', 653 traffic_dir='tx', 654 ip_version=4) 655 for rvr_graph in create_rvr_graph( 656 self.test_name, 657 context.get_current_context().get_full_output_path(), 658 graph_data): 659 self.rvr_graph_summary.append(rvr_graph) 660 write_csv_rvr_data( 661 self.test_name, 662 context.get_current_context().get_full_output_path(), graph_data) 663 664 def test_rvr_11ac_5g_80mhz_wpa2_rx_ipv4(self): 665 ssid = rand_ascii_str(20) 666 password = rand_ascii_str(20) 667 security_profile = Security(security_mode='wpa2', password=password) 668 setup_ap(access_point=self.access_point, 669 profile_name='whirlwind', 670 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 671 ssid=ssid, 672 security=security_profile, 673 setup_bridge=True) 674 graph_data = self.run_rvr(ssid, 675 password=password, 676 band='5g', 677 traffic_dir='rx', 678 ip_version=4) 679 for rvr_graph in create_rvr_graph( 680 self.test_name, 681 context.get_current_context().get_full_output_path(), 682 graph_data): 683 self.rvr_graph_summary.append(rvr_graph) 684 write_csv_rvr_data( 685 self.test_name, 686 context.get_current_context().get_full_output_path(), graph_data) 687 688 def test_rvr_11ac_5g_80mhz_wpa2_tx_ipv6(self): 689 ssid = rand_ascii_str(20) 690 password = rand_ascii_str(20) 691 security_profile = Security(security_mode='wpa2', password=password) 692 setup_ap(access_point=self.access_point, 693 profile_name='whirlwind', 694 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 695 ssid=ssid, 696 security=security_profile, 697 setup_bridge=True) 698 graph_data = self.run_rvr(ssid, 699 password=password, 700 band='5g', 701 traffic_dir='tx', 702 ip_version=6) 703 for rvr_graph in create_rvr_graph( 704 self.test_name, 705 context.get_current_context().get_full_output_path(), 706 graph_data): 707 self.rvr_graph_summary.append(rvr_graph) 708 write_csv_rvr_data( 709 self.test_name, 710 context.get_current_context().get_full_output_path(), graph_data) 711 712 def test_rvr_11ac_5g_80mhz_wpa2_rx_ipv6(self): 713 ssid = rand_ascii_str(20) 714 password = rand_ascii_str(20) 715 security_profile = Security(security_mode='wpa2', password=password) 716 setup_ap(access_point=self.access_point, 717 profile_name='whirlwind', 718 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G, 719 ssid=ssid, 720 security=security_profile, 721 setup_bridge=True) 722 graph_data = self.run_rvr(ssid, 723 password=password, 724 band='5g', 725 traffic_dir='rx', 726 ip_version=6) 727 for rvr_graph in create_rvr_graph( 728 self.test_name, 729 context.get_current_context().get_full_output_path(), 730 graph_data): 731 self.rvr_graph_summary.append(rvr_graph) 732 write_csv_rvr_data( 733 self.test_name, 734 context.get_current_context().get_full_output_path(), graph_data) 735 736 def test_rvr_11n_2g_20mhz_open_tx_ipv4(self): 737 ssid = rand_ascii_str(20) 738 setup_ap(access_point=self.access_point, 739 profile_name='whirlwind', 740 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 741 ssid=ssid, 742 setup_bridge=True) 743 graph_data = self.run_rvr(ssid, 744 band='2g', 745 traffic_dir='tx', 746 ip_version=4) 747 for rvr_graph in create_rvr_graph( 748 self.test_name, 749 context.get_current_context().get_full_output_path(), 750 graph_data): 751 self.rvr_graph_summary.append(rvr_graph) 752 write_csv_rvr_data( 753 self.test_name, 754 context.get_current_context().get_full_output_path(), graph_data) 755 756 def test_rvr_11n_2g_20mhz_open_rx_ipv4(self): 757 ssid = rand_ascii_str(20) 758 setup_ap(access_point=self.access_point, 759 profile_name='whirlwind', 760 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 761 ssid=ssid, 762 setup_bridge=True) 763 graph_data = self.run_rvr(ssid, 764 band='2g', 765 traffic_dir='rx', 766 ip_version=4) 767 for rvr_graph in create_rvr_graph( 768 self.test_name, 769 context.get_current_context().get_full_output_path(), 770 graph_data): 771 self.rvr_graph_summary.append(rvr_graph) 772 write_csv_rvr_data( 773 self.test_name, 774 context.get_current_context().get_full_output_path(), graph_data) 775 776 def test_rvr_11n_2g_20mhz_open_tx_ipv6(self): 777 ssid = rand_ascii_str(20) 778 setup_ap(access_point=self.access_point, 779 profile_name='whirlwind', 780 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 781 ssid=ssid, 782 setup_bridge=True) 783 graph_data = self.run_rvr(ssid, 784 band='2g', 785 traffic_dir='tx', 786 ip_version=6) 787 for rvr_graph in create_rvr_graph( 788 self.test_name, 789 context.get_current_context().get_full_output_path(), 790 graph_data): 791 self.rvr_graph_summary.append(rvr_graph) 792 write_csv_rvr_data( 793 self.test_name, 794 context.get_current_context().get_full_output_path(), graph_data) 795 796 def test_rvr_11n_2g_20mhz_open_rx_ipv6(self): 797 ssid = rand_ascii_str(20) 798 setup_ap(access_point=self.access_point, 799 profile_name='whirlwind', 800 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 801 ssid=ssid, 802 setup_bridge=True) 803 graph_data = self.run_rvr(ssid, 804 band='2g', 805 traffic_dir='rx', 806 ip_version=6) 807 for rvr_graph in create_rvr_graph( 808 self.test_name, 809 context.get_current_context().get_full_output_path(), 810 graph_data): 811 self.rvr_graph_summary.append(rvr_graph) 812 write_csv_rvr_data( 813 self.test_name, 814 context.get_current_context().get_full_output_path(), graph_data) 815 816 def test_rvr_11n_2g_20mhz_wpa2_tx_ipv4(self): 817 ssid = rand_ascii_str(20) 818 password = rand_ascii_str(20) 819 security_profile = Security(security_mode='wpa2', password=password) 820 setup_ap(access_point=self.access_point, 821 profile_name='whirlwind', 822 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 823 ssid=ssid, 824 security=security_profile, 825 setup_bridge=True) 826 graph_data = self.run_rvr(ssid, 827 password=password, 828 band='2g', 829 traffic_dir='tx', 830 ip_version=4) 831 for rvr_graph in create_rvr_graph( 832 self.test_name, 833 context.get_current_context().get_full_output_path(), 834 graph_data): 835 self.rvr_graph_summary.append(rvr_graph) 836 write_csv_rvr_data( 837 self.test_name, 838 context.get_current_context().get_full_output_path(), graph_data) 839 840 def test_rvr_11n_2g_20mhz_wpa2_rx_ipv4(self): 841 ssid = rand_ascii_str(20) 842 password = rand_ascii_str(20) 843 security_profile = Security(security_mode='wpa2', password=password) 844 setup_ap(access_point=self.access_point, 845 profile_name='whirlwind', 846 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 847 ssid=ssid, 848 security=security_profile, 849 setup_bridge=True) 850 graph_data = self.run_rvr(ssid, 851 password=password, 852 band='2g', 853 traffic_dir='rx', 854 ip_version=4) 855 for rvr_graph in create_rvr_graph( 856 self.test_name, 857 context.get_current_context().get_full_output_path(), 858 graph_data): 859 self.rvr_graph_summary.append(rvr_graph) 860 write_csv_rvr_data( 861 self.test_name, 862 context.get_current_context().get_full_output_path(), graph_data) 863 864 def test_rvr_11n_2g_20mhz_wpa2_tx_ipv6(self): 865 ssid = rand_ascii_str(20) 866 password = rand_ascii_str(20) 867 security_profile = Security(security_mode='wpa2', password=password) 868 setup_ap(access_point=self.access_point, 869 profile_name='whirlwind', 870 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G, 871 ssid=ssid, 872 security=security_profile, 873 setup_bridge=True) 874 graph_data = self.run_rvr(ssid, 875 password=password, 876 band='2g', 877 traffic_dir='tx', 878 ip_version=6) 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_rx_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 password=password, 900 band='2g', 901 traffic_dir='rx', 902 ip_version=6) 903 for rvr_graph in create_rvr_graph( 904 self.test_name, 905 context.get_current_context().get_full_output_path(), 906 graph_data): 907 self.rvr_graph_summary.append(rvr_graph) 908 write_csv_rvr_data( 909 self.test_name, 910 context.get_current_context().get_full_output_path(), graph_data) 911