Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(362)

Side by Side Diff: tools/rebaseline_imagefiles.py

Issue 17379004: rebaseline.py: split image-based rebaselining, which will go away soon, into its own script (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: sync_to_r9687 Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 ''' 3 '''
4 Copyright 2012 Google Inc. 4 Copyright 2013 Google Inc.
5 5
6 Use of this source code is governed by a BSD-style license that can be 6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file. 7 found in the LICENSE file.
8 ''' 8 '''
9 9
10 ''' 10 '''
11 Rebaselines the given GM tests, on all bots and all configurations. 11 Rebaselines GM test results as individual image files
12 Must be run from the gm-expected directory. If run from a git or SVN 12 (the "old way", before https://goto.google.com/ChecksumTransitionDetail ).
13 checkout, the files will be added to the staging area for commit. 13
14 Once we have switched our expectations to JSON form for all platforms,
15 we can delete this file.
16
17 There is a lot of code duplicated between here and rebaseline.py, but
18 that's fine because we will delete this file soon.
14 ''' 19 '''
15 20
16 # System-level imports 21 # System-level imports
17 import argparse
18 import os 22 import os
19 import re 23 import re
20 import subprocess 24 import subprocess
21 import sys 25 import sys
22 import urllib2 26 import urllib2
23 27
24 # Imports from within Skia 28 # Imports from within Skia
25 # 29 #
26 # We need to add the 'gm' directory, so that we can import gm_json.py within 30 # We need to add the 'gm' directory, so that we can import gm_json.py within
27 # that directory. That script allows us to parse the actual-results.json file 31 # that directory. That script allows us to parse the actual-results.json file
28 # written out by the GM tool. 32 # written out by the GM tool.
29 # Make sure that the 'gm' dir is in the PYTHONPATH, but add it at the *end* 33 # Make sure that the 'gm' dir is in the PYTHONPATH, but add it at the *end*
30 # so any dirs that are already in the PYTHONPATH will be preferred. 34 # so any dirs that are already in the PYTHONPATH will be preferred.
31 # 35 #
32 # This assumes that the 'gm' directory has been checked out as a sibling of 36 # This assumes that the 'gm' directory has been checked out as a sibling of
33 # the 'tools' directory containing this script, which will be the case if 37 # the 'tools' directory containing this script, which will be the case if
34 # 'trunk' was checked out as a single unit. 38 # 'trunk' was checked out as a single unit.
35 GM_DIRECTORY = os.path.realpath( 39 GM_DIRECTORY = os.path.realpath(
36 os.path.join(os.path.dirname(os.path.dirname(__file__)), 'gm')) 40 os.path.join(os.path.dirname(os.path.dirname(__file__)), 'gm'))
37 if GM_DIRECTORY not in sys.path: 41 if GM_DIRECTORY not in sys.path:
38 sys.path.append(GM_DIRECTORY) 42 sys.path.append(GM_DIRECTORY)
39 import gm_json 43 import gm_json
40 44
41 45
42 # Mapping of gm-expectations subdir (under
43 # https://skia.googlecode.com/svn/gm-expected/ )
44 # to builder name (see list at http://108.170.217.252:10117/builders )
45 SUBDIR_MAPPING = {
46 'base-shuttle-win7-intel-float':
47 'Test-Win7-ShuttleA-HD2000-x86-Release',
48 'base-shuttle-win7-intel-angle':
49 'Test-Win7-ShuttleA-HD2000-x86-Release-ANGLE',
50 'base-shuttle-win7-intel-directwrite':
51 'Test-Win7-ShuttleA-HD2000-x86-Release-DirectWrite',
52 'base-shuttle_ubuntu12_ati5770':
53 'Test-Ubuntu12-ShuttleA-ATI5770-x86_64-Release',
54 'base-macmini':
55 'Test-Mac10.6-MacMini4.1-GeForce320M-x86-Release',
56 'base-macmini-lion-float':
57 'Test-Mac10.7-MacMini4.1-GeForce320M-x86-Release',
58 'base-android-galaxy-nexus':
59 'Test-Android-GalaxyNexus-SGX540-Arm7-Debug',
60 'base-android-nexus-7':
61 'Test-Android-Nexus7-Tegra3-Arm7-Release',
62 'base-android-nexus-s':
63 'Test-Android-NexusS-SGX540-Arm7-Release',
64 'base-android-xoom':
65 'Test-Android-Xoom-Tegra2-Arm7-Release',
66 'base-android-nexus-10':
67 'Test-Android-Nexus10-MaliT604-Arm7-Release',
68 }
69
70
71 class CommandFailedException(Exception): 46 class CommandFailedException(Exception):
72 pass 47 pass
73 48
74 class Rebaseliner(object): 49 class ImageRebaseliner(object):
75 50
76 # params: 51 # params:
52 # expectations_root: root directory of all expectations
77 # json_base_url: base URL from which to read json_filename 53 # json_base_url: base URL from which to read json_filename
78 # json_filename: filename (under json_base_url) from which to read a 54 # json_filename: filename (under json_base_url) from which to read a
79 # summary of results; typically "actual-results.json" 55 # summary of results; typically "actual-results.json"
80 # subdirs: which platform subdirectories to rebaseline; if not specified,
81 # rebaseline all platform subdirectories
82 # tests: list of tests to rebaseline, or None if we should rebaseline 56 # tests: list of tests to rebaseline, or None if we should rebaseline
83 # whatever files the JSON results summary file tells us to 57 # whatever files the JSON results summary file tells us to
84 # configs: which configs to run for each test; this should only be 58 # configs: which configs to run for each test; this should only be
85 # specified if the list of tests was also specified (otherwise, 59 # specified if the list of tests was also specified (otherwise,
86 # the JSON file will give us test names and configs) 60 # the JSON file will give us test names and configs)
87 # dry_run: if True, instead of actually downloading files or adding 61 # dry_run: if True, instead of actually downloading files or adding
88 # files to checkout, display a list of operations that 62 # files to checkout, display a list of operations that
89 # we would normally perform 63 # we would normally perform
90 # add_new: if True, add expectations for tests which don't have any yet 64 # add_new: if True, add expectations for tests which don't have any yet
91 def __init__(self, json_base_url, json_filename, 65 # missing_json_is_fatal: whether to halt execution if we cannot read a
92 subdirs=None, tests=None, configs=None, dry_run=False, 66 # JSON actual result summary file
93 add_new=False): 67 def __init__(self, expectations_root, json_base_url, json_filename,
68 tests=None, configs=None, dry_run=False,
69 add_new=False, missing_json_is_fatal=False):
94 if configs and not tests: 70 if configs and not tests:
95 raise ValueError('configs should only be specified if tests ' + 71 raise ValueError('configs should only be specified if tests ' +
96 'were specified also') 72 'were specified also')
73 self._expectations_root = expectations_root
97 self._tests = tests 74 self._tests = tests
98 self._configs = configs 75 self._configs = configs
99 if not subdirs:
100 self._subdirs = sorted(SUBDIR_MAPPING.keys())
101 self._missing_json_is_fatal = False
102 else:
103 self._subdirs = subdirs
104 self._missing_json_is_fatal = True
105 self._json_base_url = json_base_url 76 self._json_base_url = json_base_url
106 self._json_filename = json_filename 77 self._json_filename = json_filename
107 self._dry_run = dry_run 78 self._dry_run = dry_run
108 self._add_new = add_new 79 self._add_new = add_new
80 self._missing_json_is_fatal = missing_json_is_fatal
109 self._googlestorage_gm_actuals_root = ( 81 self._googlestorage_gm_actuals_root = (
110 'http://chromium-skia-gm.commondatastorage.googleapis.com/gm') 82 'http://chromium-skia-gm.commondatastorage.googleapis.com/gm')
111 self._testname_pattern = re.compile('(\S+)_(\S+).png') 83 self._testname_pattern = re.compile('(\S+)_(\S+).png')
112 self._is_svn_checkout = ( 84 self._is_svn_checkout = (
113 os.path.exists('.svn') or 85 os.path.exists('.svn') or
114 os.path.exists(os.path.join(os.pardir, '.svn'))) 86 os.path.exists(os.path.join(os.pardir, '.svn')))
115 self._is_git_checkout = ( 87 self._is_git_checkout = (
116 os.path.exists('.git') or 88 os.path.exists('.git') or
117 os.path.exists(os.path.join(os.pardir, '.git'))) 89 os.path.exists(os.path.join(os.pardir, '.git')))
118 90
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 if (expectations_subdir == 'base-shuttle-win7-intel-angle'): 297 if (expectations_subdir == 'base-shuttle-win7-intel-angle'):
326 configs = [ 'angle', 'anglemsaa16' ] 298 configs = [ 'angle', 'anglemsaa16' ]
327 else: 299 else:
328 configs = [ '565', '8888', 'gpu', 'pdf', 'mesa', 'msaa16', 300 configs = [ '565', '8888', 'gpu', 'pdf', 'mesa', 'msaa16',
329 'msaa4' ] 301 'msaa4' ]
330 if self._dry_run: 302 if self._dry_run:
331 print '' 303 print ''
332 print '# ' + expectations_subdir + ':' 304 print '# ' + expectations_subdir + ':'
333 for config in configs: 305 for config in configs:
334 infilename = test + '_' + config + '.png' 306 infilename = test + '_' + config + '.png'
335 outfilename = os.path.join(expectations_subdir, infilename); 307 outfilename = os.path.join(self._expectations_root,
308 expectations_subdir, infilename);
336 self._RebaselineOneFile(expectations_subdir=expectations_subdir, 309 self._RebaselineOneFile(expectations_subdir=expectations_subdir,
337 builder_name=builder_name, 310 builder_name=builder_name,
338 infilename=infilename, 311 infilename=infilename,
339 outfilename=outfilename, 312 outfilename=outfilename,
340 all_results=all_results) 313 all_results=all_results)
341 314
342 # Rebaseline all platforms/tests/types we specified in the constructor. 315 # Rebaseline all tests/types we specified in the constructor,
343 def RebaselineAll(self): 316 # within this gm-expectations subdir.
344 for subdir in self._subdirs: 317 #
345 if not subdir in SUBDIR_MAPPING.keys(): 318 # params:
346 raise Exception(('unrecognized platform subdir "%s"; ' + 319 # subdir : e.g. 'base-shuttle-win7-intel-float'
347 'should be one of %s') % ( 320 # builder : e.g. 'Test-Win7-ShuttleA-HD2000-x86-Release'
348 subdir, SUBDIR_MAPPING.keys())) 321 def RebaselineSubdir(self, subdir, builder):
349 builder_name = SUBDIR_MAPPING[subdir] 322 json_url = '/'.join([self._json_base_url,
350 json_url = '/'.join([self._json_base_url, 323 subdir, builder, subdir,
351 subdir, builder_name, subdir, 324 self._json_filename])
352 self._json_filename]) 325 all_results = self._GetActualResults(json_url=json_url)
353 all_results = self._GetActualResults(json_url=json_url)
354 326
355 if self._tests: 327 if self._tests:
356 for test in self._tests: 328 for test in self._tests:
357 self._RebaselineOneTest(expectations_subdir=subdir, 329 self._RebaselineOneTest(expectations_subdir=subdir,
358 builder_name=builder_name, 330 builder_name=builder,
359 test=test, all_results=all_results) 331 test=test, all_results=all_results)
360 else: # get the raw list of files that need rebaselining from JSON 332 else: # get the raw list of files that need rebaselining from JSON
361 filenames = self._GetFilesToRebaseline(json_url=json_url, 333 filenames = self._GetFilesToRebaseline(json_url=json_url,
362 add_new=self._add_new) 334 add_new=self._add_new)
363 for filename in filenames: 335 for filename in filenames:
364 outfilename = os.path.join(subdir, filename); 336 outfilename = os.path.join(subdir, filename);
365 self._RebaselineOneFile(expectations_subdir=subdir, 337 self._RebaselineOneFile(expectations_subdir=subdir,
366 builder_name=builder_name, 338 builder_name=builder,
367 infilename=filename, 339 infilename=filename,
368 outfilename=outfilename, 340 outfilename=outfilename,
369 all_results=all_results) 341 all_results=all_results)
370
371 # main...
372
373 parser = argparse.ArgumentParser()
374 parser.add_argument('--add-new', action='store_true',
375 help='in addition to the standard behavior of ' +
376 'updating expectations for failing tests, add ' +
377 'expectations for tests which don\'t have expectations ' +
378 'yet.')
379 parser.add_argument('--configs', metavar='CONFIG', nargs='+',
380 help='which configurations to rebaseline, e.g. ' +
381 '"--configs 565 8888"; if unspecified, run a default ' +
382 'set of configs. This should ONLY be specified if ' +
383 '--tests has also been specified.')
384 parser.add_argument('--dry-run', action='store_true',
385 help='instead of actually downloading files or adding ' +
386 'files to checkout, display a list of operations that ' +
387 'we would normally perform')
388 parser.add_argument('--json-base-url',
389 help='base URL from which to read JSON_FILENAME ' +
390 'files; defaults to %(default)s',
391 default='http://skia-autogen.googlecode.com/svn/gm-actual')
392 parser.add_argument('--json-filename',
393 help='filename (under JSON_BASE_URL) to read a summary ' +
394 'of results from; defaults to %(default)s',
395 default='actual-results.json')
396 parser.add_argument('--subdirs', metavar='SUBDIR', nargs='+',
397 help='which platform subdirectories to rebaseline; ' +
398 'if unspecified, rebaseline all subdirs, same as ' +
399 '"--subdirs %s"' % ' '.join(sorted(SUBDIR_MAPPING.keys())))
400 parser.add_argument('--tests', metavar='TEST', nargs='+',
401 help='which tests to rebaseline, e.g. ' +
402 '"--tests aaclip bigmatrix"; if unspecified, then all ' +
403 'failing tests (according to the actual-results.json ' +
404 'file) will be rebaselined.')
405 args = parser.parse_args()
406 rebaseliner = Rebaseliner(tests=args.tests, configs=args.configs,
407 subdirs=args.subdirs, dry_run=args.dry_run,
408 json_base_url=args.json_base_url,
409 json_filename=args.json_filename,
410 add_new=args.add_new)
411 rebaseliner.RebaselineAll()
OLDNEW
« no previous file with comments | « tools/rebaseline.py ('k') | tools/tests/rebaseline/input/json1/base-android-galaxy-nexus/expected-results.json » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698