blob: f3f3803c8805ab3db28aa24346ba0df29751264d [file] [log] [blame]
Vaas Krishnamurthyff446f32019-05-24 16:16:05 -07001#!/usr/bin/env python3
2#
3# Copyright (C) 2018 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may not
6# use this file except in compliance with the License. You may obtain a copy of
7# 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, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations under
15# the License.
16"""
17Script for testing various download stress scenarios.
18
19"""
20import os
21import threading
22import uuid
23
24from acts.base_test import BaseTestClass
25from acts import signals
26from acts.controllers.ap_lib import hostapd_constants
Xianyuan Jiaa4913cd2020-11-16 11:58:29 -080027from acts.test_utils.abstract_devices.utils_lib.wlan_utils import setup_ap_and_associate
28from acts.test_utils.abstract_devices.wlan_device import create_wlan_device
29from acts.test_utils.fuchsia import utils
30from acts.test_utils.tel.tel_test_utils import setup_droid_properties
Vaas Krishnamurthyff446f32019-05-24 16:16:05 -070031from acts.utils import rand_ascii_str
32
33
34class DownloadStressTest(BaseTestClass):
35 # Default number of test iterations here.
36 # Override using parameter in config file.
37 # Eg: "download_stress_test_iterations": "10"
38 num_of_iterations = 3
39
40 # Timeout for download thread in seconds
41 download_timeout_s = 60 * 5
42
43 # Download urls
44 url_20MB = 'http://ipv4.download.thinkbroadband.com/20MB.zip'
45 url_40MB = 'http://ipv4.download.thinkbroadband.com/40MB.zip'
46 url_60MB = 'http://ipv4.download.thinkbroadband.com/60MB.zip'
47 url_512MB = 'http://ipv4.download.thinkbroadband.com/512MB.zip'
48
49 # Constants used in test_one_large_multiple_small_downloads
50 download_small_url = url_20MB
51 download_large_url = url_512MB
52 num_of_small_downloads = 5
53 download_threads_result = []
54
Xianyuan Jiab6f6f542019-09-17 12:13:49 -070055 def setup_class(self):
56 super().setup_class()
Vaas Krishnamurthyff446f32019-05-24 16:16:05 -070057 self.ssid = rand_ascii_str(10)
58 self.fd = self.fuchsia_devices[0]
59 self.wlan_device = create_wlan_device(self.fd)
60 self.ap = self.access_points[0]
61 self.num_of_iterations = int(
62 self.user_params.get("download_stress_test_iterations",
63 self.num_of_iterations))
64
Vaas Krishnamurthyff446f32019-05-24 16:16:05 -070065 setup_ap_and_associate(
66 access_point=self.ap,
67 client=self.wlan_device,
68 profile_name='whirlwind',
69 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
70 ssid=self.ssid)
71
72 def teardown_test(self):
73 self.download_threads_result.clear()
74 self.wlan_device.disconnect()
75 self.wlan_device.reset_wifi()
76 self.ap.stop_all_aps()
77
78 def test_download_small(self):
79 self.log.info("Downloading small file")
80 return self.download_file(self.url_20MB)
81
82 def test_download_large(self):
83 return self.download_file(self.url_512MB)
84
85 def test_continuous_download(self):
86 for x in range(0, self.num_of_iterations):
87 if not self.download_file(self.url_512MB):
88 return False
89 return True
90
91 def download_file(self, url):
92 self.log.info("Start downloading: %s" % url)
93 return utils.http_file_download_by_curl(
94 self.fd,
95 url,
96 additional_args='--max-time %d --silent' % self.download_timeout_s)
97
98 def download_thread(self, url):
99 download_status = self.download_file(url)
100 if download_status:
101 self.log.info("Success downloading: %s" % url)
102 else:
103 self.log.info("Failure downloading: %s" % url)
104
105 self.download_threads_result.append(download_status)
106 return download_status
107
108 def test_multi_downloads(self):
109 download_urls = [self.url_20MB, self.url_40MB, self.url_60MB]
110 download_threads = []
111
112 try:
113 # Start multiple downloads at the same time
114 for index, url in enumerate(download_urls):
115 self.log.info('Create and start thread %d.' % index)
116 t = threading.Thread(target=self.download_thread, args=(url, ))
117 download_threads.append(t)
118 t.start()
119
120 # Wait for all threads to complete or timeout
121 for t in download_threads:
122 t.join(self.download_timeout_s)
123
124 finally:
125 is_alive = False
126
127 for index, t in enumerate(download_threads):
128 if t.isAlive():
129 t = None
130 is_alive = True
131
132 if is_alive:
133 raise signals.TestFailure('Thread %d timedout' % index)
134
135 for index in range(0, len(self.download_threads_result)):
136 if not self.download_threads_result[index]:
137 self.log.info("Download failed for %d" % index)
138 raise signals.TestFailure(
139 'Thread %d failed to download' % index)
140 return False
141
142 return True
143
144 def test_one_large_multiple_small_downloads(self):
145 for index in range(self.num_of_iterations):
146 download_threads = []
147 try:
148 large_thread = threading.Thread(
149 target=self.download_thread,
150 args=(self.download_large_url, ))
151 download_threads.append(large_thread)
152 large_thread.start()
153
154 for i in range(self.num_of_small_downloads):
155 # Start small file download
156 t = threading.Thread(
157 target=self.download_thread,
158 args=(self.download_small_url, ))
159 download_threads.append(t)
160 t.start()
161 # Wait for thread to exit before starting the next iteration
162 t.join(self.download_timeout_s)
163
164 # Wait for the large file download thread to complete
165 large_thread.join(self.download_timeout_s)
166
167 finally:
168 is_alive = False
169
170 for index, t in enumerate(download_threads):
171 if t.isAlive():
172 t = None
173 is_alive = True
174
175 if is_alive:
176 raise signals.TestFailure('Thread %d timedout' % index)
177
178 for index in range(0, len(self.download_threads_result)):
179 if not self.download_threads_result[index]:
180 self.log.info("Download failed for %d" % index)
181 raise signals.TestFailure(
182 'Thread %d failed to download' % index)
183 return False
184
185 # Clear results before looping again
186 self.download_threads_result.clear()
187
188 return True