• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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