• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3.4
2#
3#   Copyright 2016 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import queue
18import time
19
20from acts import asserts
21from acts import base_test
22from acts import signals
23from acts.test_decorators import test_tracker_info
24from acts_contrib.test_utils.wifi import wifi_test_utils as wutils
25from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
26
27WifiChannelUS = wutils.WifiChannelUS
28WifiEnums = wutils.WifiEnums
29
30SCAN_EVENT_TAG = "WifiScannerScan"
31
32
33class WifiScanResultEvents():
34    """This class stores the setting of a scan, parameters generated
35    from starting the scan, and events reported later from the scan
36    for validation.
37
38    Attributes:
39        scan_setting: Setting used to perform the scan.
40        scan_channels: Channels used for scanning.
41        events: A list to store the scan result events.
42    """
43
44    def __init__(self, scan_setting, scan_channels):
45        self.scan_setting = scan_setting
46        self.scan_channels = scan_channels
47        self.results_events = []
48
49    def add_results_event(self, event):
50        self.results_events.append(event)
51
52    def check_interval(self, scan_result, scan_result_next):
53        """Verifies that the time gap between two consecutive results is within
54        expected range.
55
56        Right now it is hard coded to be 20 percent of the interval specified
57        by scan settings. This threshold can be imported from the configuration
58        file in the future if necessary later.
59
60        Note the scan result timestamps are in microseconds, but "periodInMs"
61        in scan settings is in milliseconds.
62
63        Args:
64            scan_result: A dictionary representing a scan result for a BSSID.
65            scan_result_next: A dictionary representing a scan result for a
66                BSSID, whose scan happened after scan_result.
67        """
68        actual_interval = scan_result_next["timestamp"] - scan_result[
69            "timestamp"]
70        expected_interval = self.scan_setting['periodInMs'] * 1000
71        delta = abs(actual_interval - expected_interval)
72        margin = expected_interval * 0.25  # 25% of the expected_interval
73        asserts.assert_true(
74            delta < margin, "The difference in time between scan %s and "
75            "%s is %dms, which is out of the expected range %sms" % (
76                scan_result, scan_result_next, delta / 1000,
77                self.scan_setting['periodInMs']))
78
79    def verify_one_scan_result(self, scan_result):
80        """Verifies the scan result of a single BSSID.
81
82        1. Verifies the frequency of the network is within the range requested
83        in the scan.
84
85        Args:
86            scan_result: A dictionary representing the scan result of a single
87                BSSID.
88        """
89        freq = scan_result["frequency"]
90        asserts.assert_true(
91            freq in self.scan_channels,
92            "Frequency %d of result entry %s is out of the expected range %s."
93            % (freq, scan_result, self.scan_channels))
94        # TODO(angli): add RSSI check.
95
96    def verify_one_scan_result_group(self, batch):
97        """Verifies a group of scan results obtained during one scan.
98
99        1. Verifies the number of BSSIDs in the batch is less than the
100        threshold set by scan settings.
101        2. Verifies each scan result for individual BSSID.
102
103        Args:
104            batch: A list of dictionaries, each dictionary represents a scan
105                result.
106        """
107        scan_results = batch["ScanResults"]
108        actual_num_of_results = len(scan_results)
109        expected_num_of_results = self.scan_setting['numBssidsPerScan']
110        asserts.assert_true(actual_num_of_results <= expected_num_of_results,
111                            "Expected no more than %d BSSIDs, got %d." %
112                            (expected_num_of_results, actual_num_of_results))
113        for scan_result in scan_results:
114            self.verify_one_scan_result(scan_result)
115
116    def have_enough_events(self):
117        """Check if there are enough events to properly validate the scan"""
118        return len(self.results_events) >= 2
119
120    def check_scan_results(self):
121        """Validate the reported scan results against the scan settings.
122        Assert if any error detected in the results.
123
124        1. For each scan setting there should be no less than 2 events received.
125        2. For batch scan, the number of buffered results in each event should
126           be exactly what the scan setting specified.
127        3. Each scan result should contain no more BBSIDs than what scan
128           setting specified.
129        4. The frequency reported by each scan result should comply with its
130           scan setting.
131        5. The time gap between two consecutive scan results should be
132           approximately equal to the scan interval specified by the scan
133           setting.
134        A scan result looks like this:
135        {
136          'data':
137           {
138             'Type': 'onResults',
139             'ResultElapsedRealtime': 4280931,
140             'Index': 10,
141             'Results': [
142                         {
143                          'Flags': 0,
144                          'Id': 4,
145                          'ScanResults':[
146                                          {
147                                           'is80211McRTTResponder': False,
148                                           'channelWidth': 0,
149                                           'numUsage': 0,
150                                           'SSID': '"wh_ap1_2g"',
151                                           'timestamp': 4280078660,
152                                           'BSSID': '30:b5:c2:33:f9:05',
153                                           'frequency': 2412,
154                                           'distanceSdCm': 0,
155                                           'distanceCm': 0,
156                                           'centerFreq1': 0,
157                                           'centerFreq0': 0,
158                                           'venueName': '',
159                                           'seen': 0,
160                                           'operatorFriendlyName': '',
161                                           'level': -31,
162                                           'passpointNetwork': False,
163                                           'untrusted': False
164                                          }
165                                        ]
166                         }
167                        ]
168            },
169          'time': 1491744576383,
170          'name': 'WifiScannerScan10onResults'
171        }
172        """
173        num_of_events = len(self.results_events)
174        asserts.assert_true(
175            num_of_events >= 2,
176            "Expected more than one scan result events, got %d." %
177            num_of_events)
178        for event_idx in range(num_of_events):
179            batches = self.results_events[event_idx]["data"]["Results"]
180            actual_num_of_batches = len(batches)
181            if not actual_num_of_batches:
182                raise signals.TestFailure("Scan returned empty Results list %s "
183                                          "% batches")
184            # For batch scan results.
185            report_type = self.scan_setting['reportEvents']
186            if not (report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN):
187                # Verifies that the number of buffered results matches the
188                # number defined in scan settings.
189                expected_num_of_batches = self.scan_setting['maxScansToCache']
190                asserts.assert_true(
191                    actual_num_of_batches <= expected_num_of_batches,
192                    "Expected to get at most %d batches in event No.%d, got %d."
193                    % (expected_num_of_batches, event_idx,
194                       actual_num_of_batches))
195            # Check the results within each event of batch scan
196            for batch_idx in range(actual_num_of_batches):
197                if not len(batches[batch_idx]["ScanResults"]):
198                    raise signals.TestFailure("Scan event %d returned empty"
199                    " scan results in batch %d" % (event_idx, batch_idx))
200                # Start checking interval from the second batch.
201                if batch_idx >=1:
202                    self.check_interval(
203                        batches[batch_idx - 1]["ScanResults"][0],
204                        batches[batch_idx]["ScanResults"][0])
205            for batch in batches:
206                self.verify_one_scan_result_group(batch)
207
208            # Check the time gap between the first result of an event and
209            # the last result of its previous event
210            # Skip the very first event.
211            if event_idx >= 1:
212                previous_batches = self.results_events[event_idx - 1]["data"][
213                    "Results"]
214                self.check_interval(previous_batches[-1]["ScanResults"][0],
215                                    batches[0]["ScanResults"][0])
216
217
218class WifiScannerMultiScanTest(WifiBaseTest):
219    """This class is the WiFi Scanner Multi-Scan Test suite.
220    It collects a number of test cases, sets up and executes
221    the tests, and validates the scan results.
222
223    Attributes:
224        tests: A collection of tests to excute.
225        leeway: Scan interval drift time (in seconds).
226        stime_channels: Dwell time plus 2ms.
227        dut: Android device(s).
228        wifi_chs: WiFi channels according to the device model.
229    """
230
231    def __init__(self, configs):
232        super().__init__(configs)
233        self.enable_packet_log = True
234        self.tests = (
235            'test_wifi_two_scans_at_same_interval',
236            'test_wifi_two_scans_at_different_interval',
237            'test_wifi_scans_24GHz_and_both',
238            'test_wifi_scans_5GHz_and_both',
239            'test_wifi_scans_batch_and_24GHz',
240            'test_wifi_scans_batch_and_5GHz',
241            'test_wifi_scans_24GHz_5GHz_full_result',)
242
243    def setup_class(self):
244        super().setup_class()
245        self.leeway = 5  # seconds, for event wait time computation
246        self.stime_channel = 47  #dwell time plus 2ms
247        self.dut = self.android_devices[0]
248        wutils.wifi_test_device_init(self.dut)
249        asserts.assert_true(self.dut.droid.wifiIsScannerSupported(),
250                            "Device %s doesn't support WifiScanner, abort." %
251                            self.dut.model)
252        """ Setup the required dependencies and fetch the user params from
253        config file.
254        """
255        opt_param = ["reference_networks"]
256        self.unpack_userparams(opt_param_names=opt_param)
257
258        if "AccessPoint" in self.user_params:
259            self.legacy_configure_ap_and_start()
260        elif "OpenWrtAP" in self.user_params:
261            self.configure_openwrt_ap_and_start(open_network=True)
262
263        self.wifi_chs = WifiChannelUS(self.dut.model)
264
265    def teardown_class(self):
266        if "AccessPoint" in self.user_params:
267            del self.user_params["reference_networks"]
268            del self.user_params["open_network"]
269
270    """ Helper Functions Begin """
271
272    def start_scan(self, scan_setting):
273        data = wutils.start_wifi_background_scan(self.dut, scan_setting)
274        idx = data["Index"]
275        # Calculate event wait time from scan setting plus leeway
276        scan_time, scan_channels = wutils.get_scan_time_and_channels(
277            self.wifi_chs, scan_setting, self.stime_channel)
278        scan_period = scan_setting['periodInMs']
279        report_type = scan_setting['reportEvents']
280        if report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN:
281            scan_time += scan_period
282        else:
283            max_scan = scan_setting['maxScansToCache']
284            scan_time += max_scan * scan_period
285        wait_time = scan_time / 1000 + self.leeway
286        return idx, wait_time, scan_channels
287
288    def validate_scan_results(self, scan_results_dict):
289        # Check to make sure the dict is not empty
290        asserts.assert_true(scan_results_dict, "Scan result dict is empty.")
291        for scan_result_obj in scan_results_dict.values():
292            # Validate the results received for each scan setting
293            scan_result_obj.check_scan_results()
294
295    def wait_for_scan_events(self, wait_time_list, scan_results_dict):
296        """Poll for WifiScanner events and record them"""
297
298        # Compute the event wait time
299        event_wait_time = min(wait_time_list)
300
301        # Compute the maximum test time that guarantee that even the scan
302        # which requires the most wait time will receive at least two
303        # results.
304        max_wait_time = max(wait_time_list)
305        max_end_time = time.monotonic() + max_wait_time
306        self.log.debug("Event wait time %s seconds", event_wait_time)
307
308        try:
309            # Wait for scan results on all the caller specified bands
310            event_name = SCAN_EVENT_TAG
311            while True:
312                self.log.debug("Waiting for events '%s' for up to %s seconds",
313                               event_name, event_wait_time)
314                events = self.dut.ed.pop_events(event_name, event_wait_time)
315                for event in events:
316                    self.log.debug("Event received: %s", event)
317                    # Event name is the key to the scan results dictionary
318                    actual_event_name = event["name"]
319                    asserts.assert_true(
320                        actual_event_name in scan_results_dict,
321                        "Expected one of these event names: %s, got '%s'." %
322                        (scan_results_dict.keys(), actual_event_name))
323
324                    # TODO validate full result callbacks also
325                    if event["name"].endswith("onResults"):
326                        # Append the event
327                        scan_results_dict[actual_event_name].add_results_event(
328                            event)
329
330                # If we time out then stop waiting for events.
331                if time.monotonic() >= max_end_time:
332                    break
333                # If enough scan results have been returned to validate the
334                # results then break early.
335                have_enough_events = True
336                for key in scan_results_dict:
337                    if not scan_results_dict[key].have_enough_events():
338                        have_enough_events = False
339                if have_enough_events:
340                    break
341        except queue.Empty:
342            asserts.fail("Event did not trigger for {} in {} seconds".format(
343                event_name, event_wait_time))
344
345    def scan_and_validate_results(self, scan_settings):
346        """Perform WifiScanner scans and check the scan results
347
348        Procedures:
349          * Start scans for each caller specified setting
350          * Wait for at least two results for each scan
351          * Check the results received for each scan
352        """
353        # Awlays get a clean start
354        self.dut.ed.clear_all_events()
355
356        # Start scanning with the caller specified settings and
357        # compute parameters for receiving events
358        idx_list = []
359        wait_time_list = []
360        scan_results_dict = {}
361
362        try:
363            for scan_setting in scan_settings:
364                self.log.debug(
365                    "Scan setting: band %s, interval %s, reportEvents "
366                    "%s, numBssidsPerScan %s", scan_setting["band"],
367                    scan_setting["periodInMs"], scan_setting["reportEvents"],
368                    scan_setting["numBssidsPerScan"])
369                idx, wait_time, scan_chan = self.start_scan(scan_setting)
370                self.log.debug(
371                    "Scan started for band %s: idx %s, wait_time %ss, scan_channels %s",
372                    scan_setting["band"], idx, wait_time, scan_chan)
373                idx_list.append(idx)
374                wait_time_list.append(wait_time)
375
376                report_type = scan_setting['reportEvents']
377                scan_results_events = WifiScanResultEvents(scan_setting,
378                                                           scan_chan)
379                scan_results_dict["{}{}onResults".format(
380                    SCAN_EVENT_TAG, idx)] = scan_results_events
381                if (scan_setting['reportEvents']
382                        & WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT):
383                    scan_results_dict["{}{}onFullResult".format(
384                        SCAN_EVENT_TAG, idx)] = scan_results_events
385
386            self.wait_for_scan_events(wait_time_list, scan_results_dict)
387
388            # Validate the scan results
389            self.validate_scan_results(scan_results_dict)
390
391        finally:
392            # Tear down and clean up
393            for idx in idx_list:
394                self.dut.droid.wifiScannerStopBackgroundScan(idx)
395            self.dut.ed.clear_all_events()
396
397    """ Helper Functions End """
398    """ Tests Begin """
399
400    @test_tracker_info(uuid="d490b146-5fc3-4fc3-9958-78ba0ad63211")
401    @WifiBaseTest.wifi_test_wrap
402    def test_wifi_two_scans_at_same_interval(self):
403        """Perform two WifiScanner background scans, one at 2.4GHz and the other
404        at 5GHz, the same interval and number of BSSIDs per scan.
405
406        Initial Conditions:
407          * Set multiple APs broadcasting 2.4GHz and 5GHz.
408
409        Expected Results:
410          * DUT reports success for starting both scans
411          * Scan results for each callback contains only the results on the
412            frequency scanned
413          * Wait for at least two scan results and confirm that separation
414            between them approximately equals to the expected interval
415          * Number of BSSIDs doesn't exceed
416        """
417        scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ,
418                          "periodInMs": 10000,  # ms
419                          "reportEvents":
420                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
421                          "numBssidsPerScan": 24},
422                         {"band": WifiEnums.WIFI_BAND_5_GHZ,
423                          "periodInMs": 10000,  # ms
424                          "reportEvents":
425                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
426                          "numBssidsPerScan": 24}]
427
428        self.scan_and_validate_results(scan_settings)
429
430    @test_tracker_info(uuid="0ec9a554-f942-41a9-8096-6b0b400f60b0")
431    @WifiBaseTest.wifi_test_wrap
432    def test_wifi_two_scans_at_different_interval(self):
433        """Perform two WifiScanner background scans, one at 2.4GHz and the other
434        at 5GHz, different interval and number of BSSIDs per scan.
435
436        Initial Conditions:
437          * Set multiple APs broadcasting 2.4GHz and 5GHz.
438
439        Expected Results:
440          * DUT reports success for starting both scans
441          * Scan results for each callback contains only the results on the
442            frequency scanned
443          * Wait for at least two scan results and confirm that separation
444            between them approximately equals to the expected interval
445          * Number of BSSIDs doesn't exceed
446        """
447        scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ,
448                          "periodInMs": 10000,  # ms
449                          "reportEvents":
450                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
451                          "numBssidsPerScan": 20},
452                         {"band": WifiEnums.WIFI_BAND_5_GHZ,
453                          "periodInMs": 30000,  # ms
454                          "reportEvents":
455                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
456                          "numBssidsPerScan": 24}]
457
458        self.scan_and_validate_results(scan_settings)
459
460    @test_tracker_info(uuid="0d616591-0d32-4be6-8fd4-e4a5e9ccdce0")
461    @WifiBaseTest.wifi_test_wrap
462    def test_wifi_scans_24GHz_and_both(self):
463        """Perform two WifiScanner background scans, one at 2.4GHz and
464           the other at both 2.4GHz and 5GHz
465
466        Initial Conditions:
467          * Set multiple APs broadcasting 2.4GHz and 5GHz.
468
469        Expected Results:
470          * DUT reports success for starting both scans
471          * Scan results for each callback contains only the results on the
472            frequency scanned
473          * Wait for at least two scan results and confirm that separation
474            between them approximately equals to the expected interval
475          * Number of BSSIDs doesn't exceed
476        """
477        scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH,
478                          "periodInMs": 10000,  # ms
479                          "reportEvents":
480                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
481                          "numBssidsPerScan": 24},
482                         {"band": WifiEnums.WIFI_BAND_24_GHZ,
483                          "periodInMs": 10000,  # ms
484                          "reportEvents":
485                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
486                          "numBssidsPerScan": 24}]
487
488        self.scan_and_validate_results(scan_settings)
489
490    @test_tracker_info(uuid="ddcf959e-512a-4e86-b3d3-18cebd0b22a0")
491    @WifiBaseTest.wifi_test_wrap
492    def test_wifi_scans_5GHz_and_both(self):
493        """Perform two WifiScanner scans, one at 5GHz and the other at both
494           2.4GHz and 5GHz
495
496        Initial Conditions:
497          * Set multiple APs broadcasting 2.4GHz and 5GHz.
498
499        Expected Results:
500          * DUT reports success for starting both scans
501          * Scan results for each callback contains only the results on the
502            frequency scanned
503          * Wait for at least two scan results and confirm that separation
504            between them approximately equals to the expected interval
505          * Number of BSSIDs doesn't exceed
506        """
507        scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH,
508                          "periodInMs": 10000,  # ms
509                          "reportEvents":
510                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
511                          "numBssidsPerScan": 24},
512                         {"band": WifiEnums.WIFI_BAND_5_GHZ,
513                          "periodInMs": 10000,  # ms
514                          "reportEvents":
515                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
516                          "numBssidsPerScan": 24}]
517
518        self.scan_and_validate_results(scan_settings)
519
520    @test_tracker_info(uuid="060469f1-fc6b-4255-ab6e-b1d5b54db53d")
521    @WifiBaseTest.wifi_test_wrap
522    def test_wifi_scans_24GHz_5GHz_and_DFS(self):
523        """Perform three WifiScanner scans, one at 5GHz, one at 2.4GHz and the
524        other at just 5GHz DFS channels
525
526        Initial Conditions:
527          * Set multiple APs broadcasting 2.4GHz and 5GHz.
528
529        Expected Results:
530          * DUT reports success for starting both scans
531          * Scan results for each callback contains only the results on the
532            frequency scanned
533          * Wait for at least two scan results and confirm that separation
534            between them approximately equals to the expected interval
535          * Number of BSSIDs doesn't exceed
536        """
537        scan_settings = [
538            {"band": WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY,
539             "periodInMs": 10000,  # ms
540             "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
541             "numBssidsPerScan": 24},
542            {"band": WifiEnums.WIFI_BAND_5_GHZ,
543             "periodInMs": 10000,  # ms
544             "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
545             "numBssidsPerScan": 24},
546            {"band": WifiEnums.WIFI_BAND_24_GHZ,
547             "periodInMs": 30000,  # ms
548             "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
549             "numBssidsPerScan": 24}
550        ]
551
552        self.scan_and_validate_results(scan_settings)
553
554    @test_tracker_info(uuid="14104e98-27a0-43d5-9525-b36b65ac3957")
555    @WifiBaseTest.wifi_test_wrap
556    def test_wifi_scans_batch_and_24GHz(self):
557        """Perform two WifiScanner background scans, one in batch mode for both
558        bands and the other in periodic mode at 2.4GHz
559
560        Initial Conditions:
561          * Set multiple APs broadcasting 2.4GHz and 5GHz.
562
563        Expected Results:
564          * DUT reports success for starting both scans
565          * Scan results for each callback contains only the results on the
566            frequency scanned
567          * Wait for at least two scan results and confirm that separation
568            between them approximately equals to the expected interval
569          * Number of results in batch mode should match the setting
570          * Number of BSSIDs doesn't exceed
571        """
572        scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH,
573                          "periodInMs": 10000,  # ms
574                          "reportEvents":
575                          WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL,
576                          "numBssidsPerScan": 24,
577                          "maxScansToCache": 2},
578                         {"band": WifiEnums.WIFI_BAND_24_GHZ,
579                          "periodInMs": 10000,  # ms
580                          "reportEvents":
581                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
582                          "numBssidsPerScan": 24}]
583
584        self.scan_and_validate_results(scan_settings)
585
586    @test_tracker_info(uuid="cd6064b5-840b-4334-8cd4-8320a6cda52f")
587    @WifiBaseTest.wifi_test_wrap
588    def test_wifi_scans_batch_and_5GHz(self):
589        """Perform two WifiScanner background scans, one in batch mode for both
590        bands and the other in periodic mode at 5GHz
591
592        Initial Conditions:
593          * Set multiple APs broadcasting 2.4GHz and 5GHz.
594
595        Expected Results:
596          * DUT reports success for starting both scans
597          * Scan results for each callback contains only the results on the
598            frequency scanned
599          * Wait for at least two scan results and confirm that separation
600            between them approximately equals to the expected interval
601          * Number of results in batch mode should match the setting
602          * Number of BSSIDs doesn't exceed
603        """
604        scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH,
605                          "periodInMs": 10000,  # ms
606                          "reportEvents":
607                          WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL,
608                          "numBssidsPerScan": 24,
609                          "maxScansToCache": 2},
610                         {"band": WifiEnums.WIFI_BAND_5_GHZ,
611                          "periodInMs": 10000,  # ms
612                          "reportEvents":
613                          WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
614                          "numBssidsPerScan": 24}]
615
616        self.scan_and_validate_results(scan_settings)
617
618    @test_tracker_info(uuid="9f48cb0c-de87-4cd2-9e50-857579d44079")
619    @WifiBaseTest.wifi_test_wrap
620    def test_wifi_scans_24GHz_5GHz_full_result(self):
621        """Perform two WifiScanner background scans, one at 2.4GHz and
622           the other at 5GHz. Report full scan results.
623
624        Initial Conditions:
625          * Set multiple APs broadcasting 2.4GHz and 5GHz.
626
627        Expected Results:
628          * DUT reports success for starting both scans
629          * Scan results for each callback contains only the results on the
630            frequency scanned
631          * Wait for at least two scan results and confirm that separation
632            between them approximately equals to the expected interval
633          * Number of BSSIDs doesn't exceed
634        """
635        scan_settings = [
636            {"band": WifiEnums.WIFI_BAND_24_GHZ,
637             "periodInMs": 10000,  # ms
638             "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT
639             | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
640             "numBssidsPerScan": 24},
641            {"band": WifiEnums.WIFI_BAND_5_GHZ,
642             "periodInMs": 10000,  # ms
643             "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT
644             | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN,
645             "numBssidsPerScan": 24}
646        ]
647
648        self.scan_and_validate_results(scan_settings)
649
650    """ Tests End """
651