| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
| 3 # Use of this source code is governed by a BSD-style license that can be | |
| 4 # found in the LICENSE file. | |
| 5 | |
| 6 import hashlib | |
| 7 import logging | |
| 8 import os | |
| 9 import time | |
| 10 import urllib2 | |
| 11 | |
| 12 import pyauto_functional # Must be imported before pyauto | |
| 13 import pyauto | |
| 14 import pyauto_utils | |
| 15 import chromeos_network | |
| 16 | |
| 17 | |
| 18 MAX_WAIT_TIME_IN_MSEC = 15 * 60 * 1000 | |
| 19 | |
| 20 | |
| 21 class WifiDownloadsTest(chromeos_network.PyNetworkUITest): | |
| 22 """TestCase for ChromeOS Wifi Downloads | |
| 23 | |
| 24 This test makes a few assumptions. It needs to have access to the power | |
| 25 strip used in pyautolib/chromeos/wifi_downloads.py. It also assumes access | |
| 26 to the server 172.22.12.98:8080. If the server is passed a filname in the | |
| 27 format <integer>.lf, it will generate a file of size <integer> in KB. In | |
| 28 addition the name of the file returned is the md5 checksum of the file. | |
| 29 | |
| 30 In addition the download times are written to a file in | |
| 31 /tmp/wifi_download_time.csv. All times are appended to the file if it | |
| 32 already exists. | |
| 33 """ | |
| 34 | |
| 35 def setUp(self): | |
| 36 chromeos_network.PyNetworkUITest.setUp(self) | |
| 37 self.InitWifiPowerStrip() | |
| 38 # The power strip is a shared resource and if we every crash in the middle | |
| 39 # of a test we will be in an unknown state. This returns us to 'all off'. | |
| 40 self.TurnOffAllRouters() | |
| 41 # Downloading files of a large size, can take a while, bump the timeout | |
| 42 self.changer = pyauto.PyUITest.ActionTimeoutChanger(self, 4 * 1000 * 60) | |
| 43 self.log_file_path = '/tmp/wifi_download_time.csv' | |
| 44 | |
| 45 def _WriteTimeToFile(self, output_file, router_name, file_size, dl_time): | |
| 46 """Write or append a time into a csv file. | |
| 47 | |
| 48 This method will create or append the amount of time a download took for a | |
| 49 given filesize and router to a file at the given path. | |
| 50 | |
| 51 The format of the output file is as follows: | |
| 52 <router name A>,<file size A>,time,time,time,time,time,time,time,time | |
| 53 <router name A>,<file size B>,time,time,time,time,time,time,time,time | |
| 54 <router name B>,<file size C>,time,time,time,time,time,time,time,time | |
| 55 | |
| 56 Args: | |
| 57 output_file: the complete path of the file to write to | |
| 58 file_size: the size of the file, this is the row header | |
| 59 dl_time: the amount of time in seconds | |
| 60 """ | |
| 61 file_data = [] | |
| 62 if os.path.exists(output_file): | |
| 63 file_handle = open(output_file) | |
| 64 lines = file_handle.readlines() | |
| 65 file_handle.close() | |
| 66 # Convert the file to a full data structure. | |
| 67 for line in lines: | |
| 68 values = line.strip().split(',') | |
| 69 file_data.append(values) | |
| 70 for values in file_data: | |
| 71 found_existing_time = False | |
| 72 if values[0] == router_name and values[1] == file_size: | |
| 73 values.append('%2.2f' % dl_time) | |
| 74 found_existing_time = True | |
| 75 break | |
| 76 if not found_existing_time: | |
| 77 new_line = [router_name, file_size, ('%2.2f' % dl_time)] | |
| 78 file_data.append(new_line) | |
| 79 else: | |
| 80 file_data = [[router_name, file_size, ('%2.2f' % dl_time)]] | |
| 81 # Write the data back out | |
| 82 file_handle = open(output_file, 'w') | |
| 83 for line in file_data: | |
| 84 if len(line) > 2: | |
| 85 file_handle.write(','.join(line)) | |
| 86 file_handle.write('\n') | |
| 87 file_handle.close() | |
| 88 | |
| 89 def _Md5Checksum(self, file_path): | |
| 90 """Returns the md5 checksum of a file at a given path. | |
| 91 | |
| 92 Args: | |
| 93 file_path: The complete path of the file to generate the md5 checksum for. | |
| 94 """ | |
| 95 file_handle = open(file_path, 'rb') | |
| 96 m = hashlib.md5() | |
| 97 while True: | |
| 98 data = file_handle.read(8192) | |
| 99 if not data: | |
| 100 break | |
| 101 m.update(data) | |
| 102 file_handle.close() | |
| 103 return m.hexdigest() | |
| 104 | |
| 105 def _ConnectToRouterAndVerify(self, router_name): | |
| 106 """Generic routine for connecting to a router. | |
| 107 | |
| 108 Args: | |
| 109 router_name: The name of the router to connect to. | |
| 110 """ | |
| 111 router = self.GetRouterConfig(router_name) | |
| 112 self.RouterPower(router_name, True) | |
| 113 | |
| 114 self.assertTrue(self.WaitUntilWifiNetworkAvailable(router['ssid']), | |
| 115 'Wifi network %s never showed up.' % router['ssid']) | |
| 116 | |
| 117 # Verify connect did not have any errors. | |
| 118 error = self.ConnectToWifiRouter(router_name) | |
| 119 self.assertFalse(error, 'Failed to connect to wifi network %s. ' | |
| 120 'Reason: %s.' % (router['ssid'], error)) | |
| 121 | |
| 122 # Verify the network we connected to. | |
| 123 ssid = self.GetConnectedWifi() | |
| 124 self.assertEqual(ssid, router['ssid'], | |
| 125 'Did not successfully connect to wifi network %s.' % ssid) | |
| 126 | |
| 127 def _DownloadAndVerifyFile(self, download_url): | |
| 128 """Downloads a file at a given URL and validates it | |
| 129 | |
| 130 This method downloads a file from a server whose filename matches the md5 | |
| 131 checksum. Then we manually generate the md5 and check it against the | |
| 132 filename. | |
| 133 | |
| 134 Args: | |
| 135 download_url: URL of the file to download. | |
| 136 | |
| 137 Returns: | |
| 138 The download time in seconds. | |
| 139 """ | |
| 140 start = time.time() | |
| 141 # Make a copy of the download directory now to work around segfault | |
| 142 downloads_dir = self.GetDownloadDirectory().value() | |
| 143 try: | |
| 144 self.DownloadAndWaitForStart(download_url) | |
| 145 except AssertionError: | |
| 146 # We need to redo this since the external server may not respond the | |
| 147 # first time. | |
| 148 logging.info('Could not start download. Retrying ...') | |
| 149 self.DownloadAndWaitForStart(download_url) | |
| 150 # Maximum wait time is set as 15 mins as an 100MB file may take somewhere | |
| 151 # between 8-12 mins to download. | |
| 152 self.WaitForAllDownloadsToComplete(timeout=MAX_WAIT_TIME_IN_MSEC) | |
| 153 end = time.time() | |
| 154 logging.info('Download took %2.2f seconds to complete' % (end - start)) | |
| 155 downloaded_files = os.listdir(downloads_dir) | |
| 156 self.assertEquals(len(downloaded_files), 1, | |
| 157 msg='Expected only one file in the Downloads folder. ' | |
| 158 'but got this instead: %s' % ', '.join(downloaded_files)) | |
| 159 filename = os.path.splitext(downloaded_files[0])[0] | |
| 160 file_path = os.path.join(self.GetDownloadDirectory().value(), | |
| 161 downloaded_files[0]) | |
| 162 md5_sum = self._Md5Checksum(file_path) | |
| 163 md5_url = download_url[:-4] + '.md5' # replacing .slf with .md5 | |
| 164 md5_file = urllib2.urlopen(md5_url).readlines()[0] | |
| 165 self.assertTrue(md5_file.rstrip().endswith(md5_sum.encode()), | |
| 166 msg='Unexpected checksum. The download is incomplete.') | |
| 167 return end - start | |
| 168 | |
| 169 def testDownload1MBFile(self): | |
| 170 """Test downloading a 1MB file from a wireless router.""" | |
| 171 download_url = 'http://172.22.12.98:80/downloads/1M.slf' | |
| 172 router_name = 'Nfiniti' | |
| 173 self._ConnectToRouterAndVerify(router_name) | |
| 174 download_time = self._DownloadAndVerifyFile(download_url) | |
| 175 self._WriteTimeToFile(self.log_file_path, router_name, '1MB', | |
| 176 download_time) | |
| 177 self.DisconnectFromWifiNetwork() | |
| 178 | |
| 179 def testDownload10MBFile(self): | |
| 180 """Test downloading a 10MB file from a wireless router.""" | |
| 181 download_url = 'http://172.22.12.98:80/downloads/10M.slf' | |
| 182 router_name = 'Linksys_WRT54G2' | |
| 183 self._ConnectToRouterAndVerify(router_name) | |
| 184 download_time = self._DownloadAndVerifyFile(download_url) | |
| 185 self._WriteTimeToFile(self.log_file_path, router_name, '10MB', | |
| 186 download_time) | |
| 187 self.DisconnectFromWifiNetwork() | |
| 188 | |
| 189 def testDownload100MBFile(self): | |
| 190 """Test downloading a 100MB file from a wireless router.""" | |
| 191 download_url = 'http://172.22.12.98:80/downloads/100M.slf' | |
| 192 router_name = 'Trendnet_639gr_4' | |
| 193 self._ConnectToRouterAndVerify(router_name) | |
| 194 download_time = self._DownloadAndVerifyFile(download_url) | |
| 195 self._WriteTimeToFile(self.log_file_path, router_name, '100MB', | |
| 196 download_time) | |
| 197 self.DisconnectFromWifiNetwork() | |
| 198 | |
| 199 | |
| 200 if __name__ == '__main__': | |
| 201 pyauto_functional.Main() | |
| OLD | NEW |