blob: c4b878a2ac48a1807e20a3df2534f25f8892416e [file] [log] [blame]
Bindu Mahadevb270aa22018-08-27 13:34:58 -07001#!/usr/bin/env python3.4
2#
3# Copyright 2018 - 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
Bindu Mahadev7d8c17e2018-11-16 23:32:57 -080017import re
Bindu Mahadev28138142018-09-17 15:34:07 -070018import sys
Bindu Mahadevb270aa22018-08-27 13:34:58 -070019import time
20
21import acts.controllers.packet_capture as packet_capture
Bindu Mahadev6b946792018-09-11 16:26:00 -070022import acts.signals as signals
Bindu Mahadevb270aa22018-08-27 13:34:58 -070023import acts.test_utils.wifi.rpm_controller_utils as rutils
Bindu Mahadev28138142018-09-17 15:34:07 -070024import acts.test_utils.wifi.wifi_datastore_utils as dutils
25import acts.test_utils.wifi.wifi_test_utils as wutils
Bindu Mahadevb270aa22018-08-27 13:34:58 -070026
27from acts import asserts
Bindu Mahadev28138142018-09-17 15:34:07 -070028from acts.base_test import BaseTestClass
Bindu Mahadevb270aa22018-08-27 13:34:58 -070029from acts.controllers.ap_lib import hostapd_constants
30from acts.test_decorators import test_tracker_info
31from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
32
33WifiEnums = wutils.WifiEnums
34
35WAIT_BEFORE_CONNECTION = 1
36SINGLE_BAND = 1
37DUAL_BAND = 2
38
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -080039TIMEOUT = 60
Bindu Mahadevb270aa22018-08-27 13:34:58 -070040PING_ADDR = 'www.google.com'
41
Bindu Mahadev28138142018-09-17 15:34:07 -070042
Bindu Mahadevb270aa22018-08-27 13:34:58 -070043class WifiChaosTest(WifiBaseTest):
44 """ Tests for wifi IOT
45
46 Test Bed Requirement:
47 * One Android device
48 * Wi-Fi IOT networks visible to the device
49 """
50
Bindu Mahadev28138142018-09-17 15:34:07 -070051 def __init__(self, configs):
52 BaseTestClass.__init__(self, configs)
53 self.generate_interop_tests()
54
55 def generate_interop_testcase(self, base_test, testcase_name, ssid_dict):
56 """Generates a single test case from the given data.
57
58 Args:
59 base_test: The base test case function to run.
60 testcase_name: The name of the test case.
61 ssid_dict: The information about the network under test.
62 """
63 ssid = testcase_name
64 test_tracker_uuid = ssid_dict[testcase_name]['uuid']
65 hostname = ssid_dict[testcase_name]['host']
66 if not testcase_name.startswith('test_'):
67 testcase_name = 'test_%s' % testcase_name
68 test_case = test_tracker_info(uuid=test_tracker_uuid)(
69 lambda: base_test(ssid, hostname))
70 setattr(self, testcase_name, test_case)
71 self.tests.append(testcase_name)
72
73 def generate_interop_tests(self):
74 for ssid_dict in self.user_params['interop_ssid']:
75 testcase_name = list(ssid_dict)[0]
76 self.generate_interop_testcase(self.interop_base_test,
77 testcase_name, ssid_dict)
78
Bindu Mahadevb270aa22018-08-27 13:34:58 -070079 def setup_class(self):
80 self.dut = self.android_devices[0]
81 wutils.wifi_test_device_init(self.dut)
Bindu Mahadev97ab1812018-10-02 16:33:36 -070082 # Set country code explicitly to "US".
83 self.dut.droid.wifiSetCountryCode(wutils.WifiEnums.CountryCode.US)
Bindu Mahadevb270aa22018-08-27 13:34:58 -070084
Bindu Mahadevb270aa22018-08-27 13:34:58 -070085 asserts.assert_true(
Bindu Mahadev28138142018-09-17 15:34:07 -070086 self.lock_pcap(),
87 "Could not lock a Packet Capture. Aborting Interop test.")
Bindu Mahadevb270aa22018-08-27 13:34:58 -070088
89 wutils.wifi_toggle_state(self.dut, True)
90
Bindu Mahadev28138142018-09-17 15:34:07 -070091 def lock_pcap(self):
92 """Lock a Packet Capturere to use for the test."""
93
94 # Get list of devices from the datastore.
95 locked_pcap = False
96 devices = dutils.get_devices()
97
98 for device in devices:
99
100 device_name = device['hostname']
101 device_type = device['ap_label']
102 if device_type == 'PCAP'and dutils.lock_device(device_name):
103 host = device['ip_address']
104 self.log.info("Locked Packet Capture device: %s" % device_name)
105 locked_pcap = True
106 break
107
108 elif device_type == 'PCAP':
109 self.log.warning("Failed to lock %s PCAP.")
110
111 if not locked_pcap:
112 return False
113
114 pcap_config = {'ssh_config':{'user':'root'} }
115 pcap_config['ssh_config']['host'] = host
116
117 self.pcap = packet_capture.PacketCapture(pcap_config)
118 return True
119
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700120 def setup_test(self):
121 self.dut.droid.wakeLockAcquireBright()
122 self.dut.droid.wakeUpNow()
123
Bindu Mahadev7d8c17e2018-11-16 23:32:57 -0800124 def on_pass(self, test_name, begin_time):
125 wutils.stop_pcap(self.pcap, self.pcap_pid, False)
126
127 def on_fail(self, test_name, begin_time):
128 wutils.stop_pcap(self.pcap, self.pcap_pid, False)
129
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700130 def teardown_test(self):
131 self.dut.droid.wakeLockRelease()
132 self.dut.droid.goToSleepNow()
133 wutils.reset_wifi(self.dut)
134
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700135
136 """Helper Functions"""
137
138 def scan_and_connect_by_id(self, network, net_id):
139 """Scan for network and connect using network id.
140
141 Args:
142 net_id: Integer specifying the network id of the network.
143
144 """
145 ssid = network[WifiEnums.SSID_KEY]
146 wutils.start_wifi_connection_scan_and_ensure_network_found(self.dut,
Bindu Mahadev28138142018-09-17 15:34:07 -0700147 ssid)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700148 wutils.wifi_connect_by_id(self.dut, net_id)
149
150 def run_ping(self, sec):
151 """Run ping for given number of seconds.
152
153 Args:
154 sec: Time in seconds to run teh ping traffic.
155
156 """
157 self.log.info("Running ping for %d seconds" % sec)
158 result = self.dut.adb.shell("ping -w %d %s" % (sec, PING_ADDR),
Bindu Mahadev28138142018-09-17 15:34:07 -0700159 timeout=sec + 1)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700160 self.log.debug("Ping Result = %s" % result)
161 if "100% packet loss" in result:
162 raise signals.TestFailure("100% packet loss during ping")
163
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800164 def unlock_and_turn_off_ap(self, hostname, rpm_port, rpm_ip):
165 """UNlock the AP in datastore and turn off the AP.
166
167 Args:
168 hostname: Hostname of the AP.
169 rpm_port: Port number on the RPM for the AP.
170 rpm_ip: RPM's IP address.
171
172 """
173 # Un-Lock AP in datastore.
174 self.log.debug("Un-lock AP in datastore")
175 if not dutils.unlock_device(hostname):
176 self.log.warning("Failed to unlock %s AP. Check AP in datastore.")
177 # Turn OFF AP from the RPM port.
178 rutils.turn_off_ap(rpm_port, rpm_ip)
179
180 def run_connect_disconnect(self, network, hostname, rpm_port, rpm_ip,
181 release_ap):
Bindu Mahadev28138142018-09-17 15:34:07 -0700182 """Run connect/disconnect to a given network in loop.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700183
Bindu Mahadev28138142018-09-17 15:34:07 -0700184 Args:
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800185 network: Dict, network information.
186 hostname: Hostanme of the AP to connect to.
187 rpm_port: Port number on the RPM for the AP.
188 rpm_ip: Port number on the RPM for the AP.
189 release_ap: Flag to determine if we should turn off the AP yet.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700190
Bindu Mahadev28138142018-09-17 15:34:07 -0700191 Raises: TestFailure if the network connection fails.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700192
193 """
Bindu Mahadev28138142018-09-17 15:34:07 -0700194 for attempt in range(1):
195 # TODO:(bmahadev) Change it to 5 or more attempts later.
196 try:
197 begin_time = time.time()
198 ssid = network[WifiEnums.SSID_KEY]
199 net_id = self.dut.droid.wifiAddNetwork(network)
200 asserts.assert_true(net_id != -1, "Add network %s failed" % network)
201 self.log.info("Connecting to %s" % ssid)
202 self.scan_and_connect_by_id(network, net_id)
203 self.run_ping(1)
204 wutils.wifi_forget_network(self.dut, ssid)
205 time.sleep(WAIT_BEFORE_CONNECTION)
206 except:
207 self.log.error("Connection to %s network failed on the %d "
208 "attempt." % (ssid, attempt))
Bindu Mahadevbe757572018-09-25 10:23:51 -0700209 # TODO:(bmahadev) Uncomment after scan issue is fixed.
210 # self.dut.take_bug_report(ssid, begin_time)
211 # self.dut.cat_adb_log(ssid, begin_time)
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800212 if release_ap:
213 self.unlock_and_turn_off_ap(hostname, rpm_port, rpm_ip)
Bindu Mahadev28138142018-09-17 15:34:07 -0700214 raise signals.TestFailure("Failed to connect to %s" % ssid)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700215
Bindu Mahadev7d8c17e2018-11-16 23:32:57 -0800216 def get_band_and_chan(self, ssid):
217 """Get the band and channel information from SSID.
218
219 Args:
220 ssid: SSID of the network.
221
222 """
223 ssid_info = ssid.split('_')
224 self.band = ssid_info[-1]
225 for item in ssid_info:
Bindu Mahadev044cabd2018-11-26 14:56:57 -0800226 # Skip over the router model part.
227 if 'ch' in item and item != ssid_info[0]:
Bindu Mahadev7d8c17e2018-11-16 23:32:57 -0800228 self.chan = re.search(r'(\d+)',item).group(0)
229 return
230 raise signals.TestFailure("Channel information not found in SSID.")
231
Bindu Mahadev28138142018-09-17 15:34:07 -0700232 def interop_base_test(self, ssid, hostname):
233 """Base test for all the connect-disconnect interop tests.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700234
Bindu Mahadev28138142018-09-17 15:34:07 -0700235 Args:
236 ssid: string, SSID of the network to connect to.
237 hostname: string, hostname of the AP.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700238
Bindu Mahadev28138142018-09-17 15:34:07 -0700239 Steps:
240 1. Lock AP in datstore.
241 2. Turn on AP on the rpm switch.
242 3. Run connect-disconnect in loop.
243 4. Turn off AP on the rpm switch.
244 5. Unlock AP in datastore.
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700245
Bindu Mahadev28138142018-09-17 15:34:07 -0700246 """
247 network = {}
248 network['password'] = 'password'
249 network['SSID'] = ssid
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800250 release_ap = False
Bindu Mahadev28138142018-09-17 15:34:07 -0700251 wutils.reset_wifi(self.dut)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700252
Bindu Mahadev28138142018-09-17 15:34:07 -0700253 # Lock AP in datastore.
254 self.log.info("Lock AP in datastore")
255 if not dutils.lock_device(hostname):
256 self.log.warning("Failed to lock %s AP. Unlock AP in datastore"
257 " and try again.")
258 raise signals.TestFailure("Failed to lock AP")
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700259
Bindu Mahadev28138142018-09-17 15:34:07 -0700260 ap_info = dutils.show_device(hostname)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700261
Bindu Mahadev28138142018-09-17 15:34:07 -0700262 band = SINGLE_BAND
263 if ('ssid_2g' in ap_info) and ('ssid_5g' in ap_info):
264 band = DUAL_BAND
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800265 if (band == SINGLE_BAND) or (
266 band == DUAL_BAND and '5G' in ssid):
267 release_ap = True
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700268
Bindu Mahadev28138142018-09-17 15:34:07 -0700269 # Get AP RPM attributes and Turn ON AP.
270 rpm_ip = ap_info['rpm_ip']
271 rpm_port = ap_info['rpm_port']
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700272
Bindu Mahadev28138142018-09-17 15:34:07 -0700273 rutils.turn_on_ap(self.pcap, ssid, rpm_port, rpm_ip=rpm_ip)
274 self.log.info("Finished turning ON AP.")
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800275 # Experimental. Some APs take upto a min to come online.
276 time.sleep(60)
Bindu Mahadev6b946792018-09-11 16:26:00 -0700277
Bindu Mahadev7d8c17e2018-11-16 23:32:57 -0800278 self.get_band_and_chan(ssid)
279 self.pcap.configure_monitor_mode(self.band, self.chan)
280 self.pcap_pid = wutils.start_pcap(
281 self.pcap, self.band.lower(), self.log_path, self.test_name)
282 self.run_connect_disconnect(network, hostname, rpm_port, rpm_ip,
283 release_ap)
Bindu Mahadevb270aa22018-08-27 13:34:58 -0700284
Bindu Mahadev28138142018-09-17 15:34:07 -0700285 # Un-lock only if it's a single band AP or we are running the last band.
Bindu Mahadev02dd5ac2018-11-05 12:40:03 -0800286 if release_ap:
287 self.unlock_and_turn_off_ap(hostname, rpm_port, rpm_ip)