OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # | 2 # |
3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 3 # Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
4 # Use of this source code is governed by a BSD-style license that can be | 4 # Use of this source code is governed by a BSD-style license that can be |
5 # found in the LICENSE file. | 5 # found in the LICENSE file. |
6 | 6 |
7 """Wrapper for tests that are run on builders.""" | 7 """Wrapper for tests that are run on builders.""" |
8 | 8 |
9 import fileinput | 9 import fileinput |
10 import optparse | 10 import optparse |
11 import os | 11 import os |
| 12 import re |
12 import sys | 13 import sys |
13 import traceback | 14 import traceback |
14 import urllib | 15 import urllib |
| 16 import HTMLParser |
15 | 17 |
16 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) | 18 sys.path.append(os.path.join(os.path.dirname(__file__), '../lib')) |
17 from cros_build_lib import Info, RunCommand, ReinterpretPathForChroot | 19 from cros_build_lib import Info |
| 20 from cros_build_lib import ReinterpretPathForChroot |
| 21 from cros_build_lib import RunCommand |
| 22 from cros_build_lib import Warning |
18 | 23 |
19 _IMAGE_TO_EXTRACT = 'chromiumos_test_image.bin' | 24 _IMAGE_TO_EXTRACT = 'chromiumos_test_image.bin' |
20 | 25 |
| 26 class HTMLDirectoryParser(HTMLParser.HTMLParser): |
| 27 """HTMLParser for parsing the default apache file index.""" |
| 28 |
| 29 def __init__(self, regex): |
| 30 HTMLParser.HTMLParser.__init__(self) |
| 31 self.regex_object = re.compile(regex) |
| 32 self.link_list = [] |
| 33 |
| 34 def handle_starttag(self, tag, attrs): |
| 35 """Overrides from HTMLParser and is called at the start of every tag. |
| 36 |
| 37 This implementation grabs attributes from links (i.e. <a ... > </a> |
| 38 and adds the target from href=<target> if the <target> matches the |
| 39 regex given at the start. |
| 40 """ |
| 41 if not tag.lower() == 'a': |
| 42 return |
| 43 |
| 44 for attr in attrs: |
| 45 if not attr[0].lower() == 'href': |
| 46 continue |
| 47 |
| 48 match = self.regex_object.match(attr[1]) |
| 49 if match: |
| 50 self.link_list.append(match.group(0).rstrip('/')) |
| 51 |
21 | 52 |
22 def ModifyBootDesc(download_folder, redirect_file=None): | 53 def ModifyBootDesc(download_folder, redirect_file=None): |
23 """Modifies the boot description of a downloaded image to work with path. | 54 """Modifies the boot description of a downloaded image to work with path. |
24 | 55 |
25 The default boot.desc from another system is specific to the directory | 56 The default boot.desc from another system is specific to the directory |
26 it was created in. This modifies the boot description to be compatiable | 57 it was created in. This modifies the boot description to be compatiable |
27 with the download folder. | 58 with the download folder. |
28 | 59 |
29 Args: | 60 Args: |
30 download_folder: Absoulte path to the download folder. | 61 download_folder: Absoulte path to the download folder. |
(...skipping 24 matching lines...) Expand all Loading... |
55 Info('Replacing line %s with %s' % (line, new_line)) | 86 Info('Replacing line %s with %s' % (line, new_line)) |
56 redirect_file.write('%s\n' % new_line) | 87 redirect_file.write('%s\n' % new_line) |
57 continue | 88 continue |
58 | 89 |
59 # Line does not need to be modified. | 90 # Line does not need to be modified. |
60 redirect_file.write(line) | 91 redirect_file.write(line) |
61 | 92 |
62 fileinput.close() | 93 fileinput.close() |
63 | 94 |
64 | 95 |
| 96 def GetLatestLinkFromPage(url, regex): |
| 97 """Returns the latest link from the given url that matches regex. |
| 98 |
| 99 Args: |
| 100 url: Url to download and parse. |
| 101 regex: Regular expression to match links against. |
| 102 """ |
| 103 url_file = urllib.urlopen(url) |
| 104 url_html = url_file.read() |
| 105 url_file.close() |
| 106 |
| 107 # Parses links with versions embedded. |
| 108 url_parser = HTMLDirectoryParser(regex=regex) |
| 109 url_parser.feed(url_html) |
| 110 return max(url_parser.link_list) |
| 111 |
| 112 |
| 113 def GetNewestLinkFromZipBase(board, channel, zip_server_base): |
| 114 """Returns the url to the newest image from the zip server. |
| 115 |
| 116 Args: |
| 117 board: board for the image zip. |
| 118 channel: channel for the image zip. |
| 119 zip_server_base: base url for zipped images. |
| 120 """ |
| 121 zip_base = os.path.join(zip_server_base, channel, board) |
| 122 latest_version = GetLatestLinkFromPage(zip_base, '\d+\.\d+\.\d+\.\d+/') |
| 123 |
| 124 zip_dir = os.path.join(zip_base, latest_version) |
| 125 zip_name = GetLatestLinkFromPage(zip_dir, |
| 126 'ChromeOS-\d+\.\d+\.\d+\.\d+-.*\.zip') |
| 127 return os.path.join(zip_dir, zip_name) |
| 128 |
| 129 |
65 def GetLatestZipUrl(board, channel, latest_url_base, zip_server_base): | 130 def GetLatestZipUrl(board, channel, latest_url_base, zip_server_base): |
66 """Returns the url of the latest image zip for the given arguments. | 131 """Returns the url of the latest image zip for the given arguments. |
67 | 132 |
68 Args: | 133 Args: |
69 board: board for the image zip. | 134 board: board for the image zip. |
70 channel: channel for the image zip. | 135 channel: channel for the image zip. |
71 latest_url_base: base url for latest links. | 136 latest_url_base: base url for latest links. |
72 zip_server_base: base url for zipped images. | 137 zip_server_base: base url for zipped images. |
73 """ | 138 """ |
74 # Grab the latest image info. | 139 if latest_url_base: |
75 latest_file_url = os.path.join(latest_url_base, channel, | 140 try: |
76 'LATEST-%s' % board) | 141 # Grab the latest image info. |
77 latest_image_file = urllib.urlopen(latest_file_url) | 142 latest_file_url = os.path.join(latest_url_base, channel, |
78 latest_image = latest_image_file.read() | 143 'LATEST-%s' % board) |
79 latest_image_file.close() | 144 latest_image_file = urllib.urlopen(latest_file_url) |
| 145 latest_image = latest_image_file.read() |
| 146 latest_image_file.close() |
| 147 # Convert bin.gz into zip. |
| 148 latest_image = latest_image.replace('.bin.gz', '.zip') |
| 149 version = latest_image.split('-')[1] |
| 150 zip_base = os.path.join(zip_server_base, channel, board) |
| 151 return os.path.join(zip_base, version, latest_image) |
| 152 except IOError: |
| 153 Warning(('Could not use latest link provided, defaulting to parsing' |
| 154 ' latest from zip url base.')) |
80 | 155 |
81 # Convert bin.gz into zip. | 156 return GetNewestLinkFromZipBase(board, channel, zip_server_base) |
82 latest_image = latest_image.replace('.bin.gz', '.zip') | |
83 version = latest_image.split('-')[1] | |
84 zip_base = os.path.join(zip_server_base, channel, board) | |
85 return os.path.join(zip_base, version, latest_image) | |
86 | 157 |
87 | 158 |
88 def GrabZipAndExtractImage(zip_url, download_folder, image_name) : | 159 def GrabZipAndExtractImage(zip_url, download_folder, image_name) : |
89 """Downloads the zip and extracts the given image. | 160 """Downloads the zip and extracts the given image. |
90 | 161 |
91 Doesn't re-download if matching version found already in download folder. | 162 Doesn't re-download if matching version found already in download folder. |
92 Args: | 163 Args: |
93 zip_url - url for the image. | 164 zip_url - url for the image. |
94 download_folder - download folder to store zip file and extracted images. | 165 download_folder - download folder to store zip file and extracted images. |
95 image_name - name of the image to extract from the zip file. | 166 image_name - name of the image to extract from the zip file. |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 265 |
195 if args: | 266 if args: |
196 parser.error('Extra args found %s.' % args) | 267 parser.error('Extra args found %s.' % args) |
197 | 268 |
198 if not options.board: | 269 if not options.board: |
199 parser.error('Need board for image to compare against.') | 270 parser.error('Need board for image to compare against.') |
200 | 271 |
201 if not options.channel: | 272 if not options.channel: |
202 parser.error('Need channel for image to compare against.') | 273 parser.error('Need channel for image to compare against.') |
203 | 274 |
204 if not options.latestbase: | |
205 parser.error('Need latest url base to get images.') | |
206 | |
207 if not options.zipbase: | 275 if not options.zipbase: |
208 parser.error('Need zip url base to get images.') | 276 parser.error('Need zip url base to get images.') |
209 | 277 |
210 RunAUTestHarness(options.board, options.channel, options.latestbase, | 278 RunAUTestHarness(options.board, options.channel, options.latestbase, |
211 options.zipbase, options.no_graphics, options.type, | 279 options.zipbase, options.no_graphics, options.type, |
212 options.remote) | 280 options.remote) |
213 | 281 |
214 | 282 |
215 if __name__ == '__main__': | 283 if __name__ == '__main__': |
216 try: | 284 try: |
217 main() | 285 main() |
218 except Exception: | 286 except Exception: |
219 print "Got exception." | 287 print "Got exception." |
220 traceback.print_exc(file=sys.stdout) | 288 traceback.print_exc(file=sys.stdout) |
221 | 289 |
OLD | NEW |