1#!/usr/bin/env python3.4
2#
3#   Copyright 2017 - 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 copy
18import pprint
19import time
20
21import acts.base_test
22import acts.test_utils.wifi.wifi_test_utils as wutils
23
24from acts import asserts
25from acts.test_decorators import test_tracker_info
26from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
27
28SCAN_TIME = 30
29WAIT_TIME = 2
30
31
32class WifiPreFlightTest(WifiBaseTest):
33    """ Pre-flight checks for Wifi tests.
34
35    Test Bed Requirement:
36    * One Android device
37    * 4 reference networks - two 2G and two 5G networks
38    * Attenuators to attenuate each reference network
39
40    Tests:
41    * Check if reference networks show up in wifi scan
42    * Check if attenuators attenuate the correct network
43    """
44
45    def setup_class(self):
46        super().setup_class()
47        self.WIFI_2G = "2g"
48        self.WIFI_5G = "5g"
49        self.PASSWORD = "password"
50        self.MIN_SIGNAL_LEVEL = -45
51
52        self.dut = self.android_devices[0]
53        wutils.wifi_test_device_init(self.dut)
54        wutils.wifi_toggle_state(self.dut, True)
55
56        # Get reference networks as a list
57        opt_params = ["reference_networks"]
58        self.unpack_userparams(opt_param_names=opt_params)
59
60        if "AccessPoint" in self.user_params:
61            self.legacy_configure_ap_and_start(ap_count=2)
62        networks = []
63        for ref_net in self.reference_networks:
64            networks.append(ref_net[self.WIFI_2G])
65            networks.append(ref_net[self.WIFI_5G])
66        self.reference_networks = networks
67        asserts.assert_true(
68            len(self.reference_networks) == 4,
69            "Need at least 4 reference network with psk.")
70
71    def teardown_class(self):
72        wutils.reset_wifi(self.dut)
73        for a in self.attenuators:
74            a.set_atten(0)
75        if "AccessPoint" in self.user_params:
76            del self.user_params["reference_networks"]
77            del self.user_params["open_network"]
78
79    """ Helper functions """
80    def _find_reference_networks_no_attn(self):
81        """ Verify that when ATTN set to 0, all reference networks
82            show up in the scanned results
83
84            Args:
85            1. List of reference networks
86
87            Returns:
88            1. List of networks not found. Empty if all reference
89               networks are found
90        """
91        found_networks = copy.deepcopy(self.target_networks)
92        start_time = time.time()
93        while(time.time() < start_time + SCAN_TIME):
94            if not found_networks:
95                break
96            time.sleep(WAIT_TIME)
97            scanned_networks = self.dut.droid.wifiGetScanResults()
98            self.log.info("SCANNED RESULTS %s" % scanned_networks)
99            for net in self.target_networks:
100                if net in found_networks:
101                    result = wutils.match_networks(net, scanned_networks)
102                    if result and result[0]['level'] > self.MIN_SIGNAL_LEVEL:
103                        found_networks.remove(net)
104                    elif result:
105                        self.log.warn("Signal strength for %s is low: %sdBm"
106                                      % (net, result[0]['level']))
107        return found_networks
108
109    def _find_network_after_setting_attn(self, target_network):
110        """ Find network after setting attenuation
111
112            Args:
113            1. target_network to find in the scanned_results
114
115            Returns:
116            1. True if
117               a. if max_attn is set and target_network not found
118            2. False if not
119        """
120        start_time = time.time()
121        while(time.time() < start_time + SCAN_TIME):
122            time.sleep(WAIT_TIME)
123            scanned_networks = self.dut.droid.wifiGetScanResults()
124            self.log.info("SCANNED RESULTS %s" % scanned_networks)
125            result = wutils.match_networks(target_network, scanned_networks)
126            if not result:
127                return True
128        return False
129
130    """ Tests """
131    def test_attenuators(self):
132        """ Test if attenuating a channel, disables the correct
133            reference network
134
135            Reference networks for each testbed should match
136            attenuators as follows
137
138            wh_ap1_2g - channel 1
139            wh_ap1_5g - channel 2
140            wh_ap2_2g - channel 3
141            wh_ap2_5g - channel 4
142
143            Steps:
144            1. Set attenuation on each channel to 95
145            2. Verify that the corresponding network does not show
146               up in the scanned results
147        """
148        # Set attenuation to 0 and verify reference
149        # networks show up in the scanned results
150        self.log.info("Verify if all reference networks show with "
151                      "attenuation set to 0")
152        if getattr(self, "attenuators", []):
153            for a in self.attenuators:
154                a.set_atten(0)
155        self.target_networks = []
156        for ref_net in self.reference_networks:
157            self.target_networks.append( {'BSSID': ref_net['bssid']} )
158        result = self._find_reference_networks_no_attn()
159        asserts.assert_true(not result,
160                            "Did not find or signal strength too low "
161                            "for the following reference networks\n%s\n" % result)
162
163        # attenuate 1 channel at a time and find the network
164        self.log.info("Verify if attenuation channel matches with "
165                      "correct reference network")
166        found_networks = []
167        for i in range(len(self.attenuators)):
168            target_network = {}
169            target_network['BSSID'] = self.reference_networks[i]['bssid']
170
171            # set the attn to max and verify target network is not found
172            self.attenuators[i].set_atten(95)
173            result = self._find_network_after_setting_attn(target_network)
174            if result:
175                target_network['ATTN'] = i
176                found_networks.append(target_network)
177
178        asserts.assert_true(not found_networks,
179                            "Attenuators did not match the networks\n %s\n"
180                            % pprint.pformat(found_networks))
181