blob: 80f866e4a7fb41fc97f69b83416632a07c6b3565 [file] [log] [blame]
epoger@google.com20ad5ac2012-01-17 21:26:05 +00001'''
2TODO: THIS IS AN OLD VERSION OF DOWNLOAD-BASELINES THAT DOWNLOADS BASELINES
3DIRECTLY FROM THE BUILDBOT SLAVES. ONCE THE NEW VERSION IS WORKING CORRECTLY,
4WE SHOULD DELETE THIS VERSION.
5
6Downloads the actual gm results most recently generated by the Skia buildbots,
7and adds any new ones to SVN control.
8
9This tool makes it much easier to check in new baselines, via the following
10steps:
11
12cd .../trunk
13svn update
14# make sure there are no files awaiting svn commit
15python tools/download-baselines-old.py gm/base-macmini-lion-fixed # or other gm/ subdir
16# upload CL for review
17# validate that the new images look right
18# commit CL
19
20Launch with --help to see more options.
21
22
23Copyright 2011 Google Inc.
24
25Use of this source code is governed by a BSD-style license that can be
26found in the LICENSE file.
27'''
28
29# common Python modules
30import optparse
31import os
32import re
33import sys
34import urllib2
35
36# modules declared within this same directory
37import svn
38
39# Where to download recently generated baseline images for each baseline type.
40#
41# For now this only works for our Mac buildbots; our other buildbots aren't
42# uploading their results to a web server yet.
43#
44# Note also that these will currently work only within the Google corporate
45# network; that will also change soon.
46ACTUALS_BY_BASELINE_SUBDIR = {
47 'gm/base-macmini':
48 'http://172.29.92.185/b/build/slave/Skia_Mac_Float_NoDebug/gm/actual',
49 'gm/base-macmini-fixed':
50 'http://172.29.92.185/b/build/slave/Skia_Mac_Fixed_NoDebug/gm/actual',
51 'gm/base-macmini-lion-fixed':
52 'http://172.29.92.179/b/build/slave/Skia_MacMiniLion_Fixed_NoDebug/gm/actual',
53 'gm/base-macmini-lion-float':
54 'http://172.29.92.179/b/build/slave/Skia_MacMiniLion_Float_NoDebug/gm/actual',
55}
56
57USAGE_STRING = 'usage: %s [options] <baseline_subdir>'
58OPTION_IGNORE_LOCAL_MODS = '--ignore-local-mods'
59OPTION_ADD_NEW_FILES = '--add-new-files'
60
61IMAGE_REGEX = '.+\.png'
62IMAGE_MIMETYPE = 'image/png'
63
64def GetPlatformUrl(baseline_subdir):
65 """Return URL within which the buildbots store generated baseline images,
66 as of multiple svn revisions.
67
68 Raises KeyError if we don't have a URL matching this baseline_subdir.
69
70 @param baseline_subdir indicates which platform we want images for
71 """
72 try:
73 return ACTUALS_BY_BASELINE_SUBDIR[baseline_subdir]
74 except KeyError:
75 raise KeyError(
76 'unknown baseline_subdir "%s", try one of these instead: %s' % (
77 baseline_subdir, ACTUALS_BY_BASELINE_SUBDIR.keys()))
78
79def GetLatestResultsUrl(baseline_subdir):
80 """Return URL from which we can download the MOST RECENTLY generated
81 images for this baseline type.
82
83 @param baseline_subdir indicates which platform we want images for
84 """
85 base_platform_url = GetPlatformUrl(baseline_subdir)
86 print 'base_platform_url is %s' % base_platform_url
87
88 # Find the most recently generated baseline images within base_platform_url
89 response = urllib2.urlopen(base_platform_url)
90 html = response.read()
91 link_regex = re.compile('<a href="(.*)">')
92 links = link_regex.findall(html)
93 last_link = links[-1]
94 most_recent_result_url = '%s/%s' % (base_platform_url, last_link)
95 print 'most_recent_result_url is %s' % most_recent_result_url
96 return most_recent_result_url
97
98def DownloadMatchingFiles(source_url, filename_regex, dest_dir,
99 only_download_updates=False):
100 """Download all files from source_url that match filename_regex, and save
101 them (with their original filenames) in dest_dir.
102
103 @param source_url
104 @param filename_regex only download files that match this regex
105 @param dest_dir where to save the downloaded files
106 @param only_download_updates if True, only download files that are already
107 present in dest_dir (download updated versions of those files)
108 """
109 while source_url.endswith('/'):
110 source_url = source_url[:-1]
111 response = urllib2.urlopen(source_url)
112 html = response.read()
113 link_regex = re.compile('<a href="(%s)">' % filename_regex)
114 links = link_regex.findall(html)
115 for link in links:
116 dest_path = os.path.join(dest_dir, link)
117 if only_download_updates and not os.path.isfile(dest_path):
118 continue
119 DownloadBinaryFile('%s/%s' % (source_url, link), dest_path)
120
121def DownloadBinaryFile(source_url, dest_path):
122 """Download a single file from its source_url and save it to local disk
123 at dest_path.
124
125 @param source_url
126 @param dest_path
127 """
128 print 'DownloadBinaryFile: %s -> %s' % (source_url, dest_path)
129 url_fh = urllib2.urlopen(source_url)
130 local_fh = open(dest_path, 'wb')
131 local_fh.write(url_fh.read())
132 local_fh.close()
133
134def Main(options, args):
135 """Download most recently generated baseline images for a given platform,
136 and add any new ones to SVN control.
137
138 @param options
139 @param args
140 """
141 num_args = len(args)
142 if num_args != 1:
143 RaiseUsageException()
144
145 baseline_subdir = args[0]
146 while baseline_subdir.endswith('/'):
147 baseline_subdir = baseline_subdir[:-1]
148 svn_handler = svn.Svn(baseline_subdir)
149
150 # If there are any locally modified files in that directory, exit
151 # (so that we don't risk overwriting the user's previous work).
152 new_and_modified_files = svn_handler.GetNewAndModifiedFiles()
153 if not options.ignore_local_mods:
154 if new_and_modified_files:
155 raise Exception('Exiting because there are already new and/or '
156 'modified files in %s. To continue in spite of '
157 'that, run with %s option.' % (
158 baseline_subdir, OPTION_IGNORE_LOCAL_MODS))
159
160 # Download the actual results from the appropriate buildbot.
161 results_url = GetLatestResultsUrl(baseline_subdir)
162 DownloadMatchingFiles(source_url=results_url, filename_regex=IMAGE_REGEX,
163 dest_dir=baseline_subdir,
164 only_download_updates=(not options.add_new_files))
165
166 # Add any new files to SVN control (if we are running with add_new_files).
167 new_files = svn_handler.GetNewFiles()
168 if new_files and options.add_new_files:
169 svn_handler.AddFiles(new_files)
170 svn_handler.SetProperty(new_files, svn.PROPERTY_MIMETYPE,
171 IMAGE_MIMETYPE)
172
173def RaiseUsageException():
174 raise Exception(USAGE_STRING % __file__)
175
176if __name__ == '__main__':
177 parser = optparse.OptionParser(USAGE_STRING % '%prog')
178 parser.add_option(OPTION_IGNORE_LOCAL_MODS,
179 action='store_true', default=False,
180 help='allow tool to run even if there are already '
181 'local modifications in the baseline_subdir')
182 parser.add_option(OPTION_ADD_NEW_FILES,
183 action='store_true', default=False,
184 help='in addition to downloading new versions of '
185 'existing baselines, also download baselines that are '
186 'not under SVN control yet')
187 (options, args) = parser.parse_args()
188 Main(options, args)