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

Side by Side Diff: gm/rebaseline_server/compare_rendered_pictures.py

Issue 480153002: Added 'renderMode' and 'builder' as columns to the SKP front-end. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Addressing issues from CR Created 6 years, 4 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
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 2
3 """ 3 """
4 Copyright 2014 Google Inc. 4 Copyright 2014 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 Compare results of two render_pictures runs. 9 Compare results of two render_pictures runs.
10 10
11 TODO(epoger): Start using this module to compare ALL images (whether they 11 TODO(epoger): Start using this module to compare ALL images (whether they
12 were generated from GMs or SKPs), and rename it accordingly. 12 were generated from GMs or SKPs), and rename it accordingly.
13 """ 13 """
14 14
15 # System-level imports 15 # System-level imports
16 import logging 16 import logging
17 import os 17 import os
18 import shutil 18 import shutil
19 import subprocess 19 import subprocess
20 import tempfile 20 import tempfile
21 import time 21 import time
22 22
23 # Must fix up PYTHONPATH before importing from within Skia 23 # Must fix up PYTHONPATH before importing from within Skia
24 import fix_pythonpath # pylint: disable=W0611 24 import rs_fixpypath # pylint: disable=W0611
25 25
26 # Imports from within Skia 26 # Imports from within Skia
27 from py.utils import git_utils 27 from py.utils import git_utils
28 from py.utils import gs_utils 28 from py.utils import gs_utils
29 from py.utils import url_utils 29 from py.utils import url_utils
30 import buildbot_globals 30 import buildbot_globals
31 import column 31 import column
32 import gm_json 32 import gm_json
33 import imagediffdb 33 import imagediffdb
34 import imagepair 34 import imagepair
35 import imagepairset 35 import imagepairset
36 import results 36 import results
37 37
38 # URL under which all render_pictures images can be found in Google Storage. 38 # URL under which all render_pictures images can be found in Google Storage.
39 # 39 #
40 # TODO(epoger): In order to allow live-view of GMs and other images, read this 40 # TODO(epoger): In order to allow live-view of GMs and other images, read this
41 # from the input summary files, or allow the caller to set it within the 41 # from the input summary files, or allow the caller to set it within the
42 # GET_live_results call. 42 # GET_live_results call.
43 DEFAULT_IMAGE_BASE_GS_URL = 'gs://' + buildbot_globals.Get('skp_images_bucket') 43 DEFAULT_IMAGE_BASE_GS_URL = 'gs://' + buildbot_globals.Get('skp_images_bucket')
44 44
45 # Column descriptors, and display preferences for them. 45 # Column descriptors, and display preferences for them.
46 COLUMN__RESULT_TYPE = results.KEY__EXTRACOLUMNS__RESULT_TYPE 46 COLUMN__RESULT_TYPE = results.KEY__EXTRACOLUMNS__RESULT_TYPE
47 COLUMN__SOURCE_SKP = 'sourceSkpFile' 47 COLUMN__SOURCE_SKP = 'sourceSkpFile'
48 COLUMN__TILED_OR_WHOLE = 'tiledOrWhole' 48 COLUMN__TILED_OR_WHOLE = 'tiledOrWhole'
49 COLUMN__TILENUM = 'tilenum' 49 COLUMN__TILENUM = 'tilenum'
50 COLUMN__BUILDER_A = 'builderA'
51 COLUMN__RENDER_MODE_A = 'renderModeA'
52 COLUMN__BUILDER_B = 'builderB'
53 COLUMN__RENDER_MODE_B = 'renderModeB'
54
50 FREEFORM_COLUMN_IDS = [ 55 FREEFORM_COLUMN_IDS = [
51 COLUMN__SOURCE_SKP, 56 COLUMN__SOURCE_SKP,
52 COLUMN__TILENUM, 57 COLUMN__TILENUM,
53 ] 58 ]
54 ORDERED_COLUMN_IDS = [ 59 ORDERED_COLUMN_IDS = [
55 COLUMN__RESULT_TYPE, 60 COLUMN__RESULT_TYPE,
56 COLUMN__SOURCE_SKP, 61 COLUMN__SOURCE_SKP,
57 COLUMN__TILED_OR_WHOLE, 62 COLUMN__TILED_OR_WHOLE,
58 COLUMN__TILENUM, 63 COLUMN__TILENUM,
64 COLUMN__BUILDER_A,
65 COLUMN__RENDER_MODE_A,
66 COLUMN__BUILDER_B,
67 COLUMN__RENDER_MODE_B,
59 ] 68 ]
60 69
61 # A special "repo:" URL type that we use to refer to Skia repo contents. 70 # A special "repo:" URL type that we use to refer to Skia repo contents.
62 # (Useful for comparing against expectations files we store in our repo.) 71 # (Useful for comparing against expectations files we store in our repo.)
63 REPO_URL_PREFIX = 'repo:' 72 REPO_URL_PREFIX = 'repo:'
64 REPO_BASEPATH = os.path.abspath(os.path.join( 73 REPO_BASEPATH = os.path.abspath(os.path.join(
65 os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir)) 74 os.path.dirname(os.path.abspath(__file__)), os.pardir, os.pardir))
66 75
67 # Which sections within a JSON summary file can contain results. 76 # Which sections within a JSON summary file can contain results.
68 ALLOWED_SECTION_NAMES = [ 77 ALLOWED_SECTION_NAMES = [
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
255 (dict_num, num_union_dict_paths, dict_path)) 264 (dict_num, num_union_dict_paths, dict_path))
256 265
257 dictA = self.get_default(setA_dicts, None, dict_path) 266 dictA = self.get_default(setA_dicts, None, dict_path)
258 self._validate_dict_version(dictA) 267 self._validate_dict_version(dictA)
259 dictA_results = self.get_default(dictA, {}, setA_section) 268 dictA_results = self.get_default(dictA, {}, setA_section)
260 269
261 dictB = self.get_default(setB_dicts, None, dict_path) 270 dictB = self.get_default(setB_dicts, None, dict_path)
262 self._validate_dict_version(dictB) 271 self._validate_dict_version(dictB)
263 dictB_results = self.get_default(dictB, {}, setB_section) 272 dictB_results = self.get_default(dictB, {}, setB_section)
264 273
274 # get the builders and render modes for each set
275 builder_A = self.get_default(dictA, None,
epoger 2014/08/18 20:34:49 Ravi will cite https://engdoc.corp.google.com/eng/
276 gm_json.JSONKEY_DESCRIPTIONS,
277 gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
278 render_mode_A = self.get_default(dictA, None,
279 gm_json.JSONKEY_DESCRIPTIONS,
280 gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
281 builder_B = self.get_default(dictB, None,
282 gm_json.JSONKEY_DESCRIPTIONS,
283 gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
284 render_mode_B = self.get_default(dictB, None,
285 gm_json.JSONKEY_DESCRIPTIONS,
286 gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
287
265 skp_names = sorted(set(dictA_results.keys() + dictB_results.keys())) 288 skp_names = sorted(set(dictA_results.keys() + dictB_results.keys()))
266 # Just for manual testing... truncate to an arbitrary subset. 289 # Just for manual testing... truncate to an arbitrary subset.
267 if self.truncate_results: 290 if self.truncate_results:
268 skp_names = skp_names[1:3] 291 skp_names = skp_names[1:3]
269 for skp_name in skp_names: 292 for skp_name in skp_names:
270 imagepairs_for_this_skp = [] 293 imagepairs_for_this_skp = []
271 294
272 whole_image_A = self.get_default( 295 whole_image_A = self.get_default(
273 dictA_results, None, 296 dictA_results, None,
274 skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE) 297 skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
275 whole_image_B = self.get_default( 298 whole_image_B = self.get_default(
276 dictB_results, None, 299 dictB_results, None,
277 skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE) 300 skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
278 imagepairs_for_this_skp.append(self._create_image_pair( 301 imagepairs_for_this_skp.append(self._create_image_pair(
279 image_dict_A=whole_image_A, image_dict_B=whole_image_B, 302 image_dict_A=whole_image_A, image_dict_B=whole_image_B,
303 builder_A=builder_A, render_mode_A=render_mode_A,
304 builder_B=builder_B, render_mode_B=render_mode_B,
280 source_skp_name=skp_name, tilenum=None)) 305 source_skp_name=skp_name, tilenum=None))
281 306
282 tiled_images_A = self.get_default( 307 tiled_images_A = self.get_default(
283 dictA_results, [], 308 dictA_results, [],
284 skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES) 309 skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
285 tiled_images_B = self.get_default( 310 tiled_images_B = self.get_default(
286 dictB_results, [], 311 dictB_results, [],
287 skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES) 312 skp_name, gm_json.JSONKEY_SOURCE_TILEDIMAGES)
288 if tiled_images_A or tiled_images_B: 313 if tiled_images_A or tiled_images_B:
289 num_tiles_A = len(tiled_images_A) 314 num_tiles_A = len(tiled_images_A)
290 num_tiles_B = len(tiled_images_B) 315 num_tiles_B = len(tiled_images_B)
291 num_tiles = max(num_tiles_A, num_tiles_B) 316 num_tiles = max(num_tiles_A, num_tiles_B)
292 for tile_num in range(num_tiles): 317 for tile_num in range(num_tiles):
293 imagepairs_for_this_skp.append(self._create_image_pair( 318 imagepairs_for_this_skp.append(self._create_image_pair(
294 image_dict_A=(tiled_images_A[tile_num] 319 image_dict_A=(tiled_images_A[tile_num]
295 if tile_num < num_tiles_A else None), 320 if tile_num < num_tiles_A else None),
296 image_dict_B=(tiled_images_B[tile_num] 321 image_dict_B=(tiled_images_B[tile_num]
297 if tile_num < num_tiles_B else None), 322 if tile_num < num_tiles_B else None),
323 builder_A=builder_A, render_mode_A=render_mode_A,
324 builder_B=builder_B, render_mode_B=render_mode_B,
298 source_skp_name=skp_name, tilenum=tile_num)) 325 source_skp_name=skp_name, tilenum=tile_num))
299 326
300 for one_imagepair in imagepairs_for_this_skp: 327 for one_imagepair in imagepairs_for_this_skp:
301 if one_imagepair: 328 if one_imagepair:
302 all_image_pairs.add_image_pair(one_imagepair) 329 all_image_pairs.add_image_pair(one_imagepair)
303 result_type = one_imagepair.extra_columns_dict\ 330 result_type = one_imagepair.extra_columns_dict\
304 [COLUMN__RESULT_TYPE] 331 [COLUMN__RESULT_TYPE]
305 if result_type != results.KEY__RESULT_TYPE__SUCCEEDED: 332 if result_type != results.KEY__RESULT_TYPE__SUCCEEDED:
306 failing_image_pairs.add_image_pair(one_imagepair) 333 failing_image_pairs.add_image_pair(one_imagepair)
307 334
(...skipping 25 matching lines...) Expand all
333 header = result_dict[gm_json.JSONKEY_HEADER] 360 header = result_dict[gm_json.JSONKEY_HEADER]
334 header_type = header[gm_json.JSONKEY_HEADER_TYPE] 361 header_type = header[gm_json.JSONKEY_HEADER_TYPE]
335 if header_type != expected_header_type: 362 if header_type != expected_header_type:
336 raise Exception('expected header_type "%s", but got "%s"' % ( 363 raise Exception('expected header_type "%s", but got "%s"' % (
337 expected_header_type, header_type)) 364 expected_header_type, header_type))
338 header_revision = header[gm_json.JSONKEY_HEADER_REVISION] 365 header_revision = header[gm_json.JSONKEY_HEADER_REVISION]
339 if header_revision != expected_header_revision: 366 if header_revision != expected_header_revision:
340 raise Exception('expected header_revision %d, but got %d' % ( 367 raise Exception('expected header_revision %d, but got %d' % (
341 expected_header_revision, header_revision)) 368 expected_header_revision, header_revision))
342 369
343 def _create_image_pair(self, image_dict_A, image_dict_B, source_skp_name, 370 def _create_image_pair(self, image_dict_A, image_dict_B,
371 builder_A, render_mode_A,
372 builder_B, render_mode_B,
373 source_skp_name,
344 tilenum): 374 tilenum):
345 """Creates an ImagePair object for this pair of images. 375 """Creates an ImagePair object for this pair of images.
346 376
347 Args: 377 Args:
348 image_dict_A: dict with JSONKEY_IMAGE_* keys, or None if no image 378 image_dict_A: dict with JSONKEY_IMAGE_* keys, or None if no image
349 image_dict_B: dict with JSONKEY_IMAGE_* keys, or None if no image 379 image_dict_B: dict with JSONKEY_IMAGE_* keys, or None if no image
380 builder_A: builder that created image set A or None if unknow
381 render_mode_A: render mode used to generate image set A or None if
382 unknown.
383 builder_B: builder that created image set A or None if unknow
384 render_mode_B: render mode used to generate image set A or None if
385 unknown.
350 source_skp_name: string; name of the source SKP file 386 source_skp_name: string; name of the source SKP file
351 tilenum: which tile, or None if a wholeimage 387 tilenum: which tile, or None if a wholeimage
352 388
353 Returns: 389 Returns:
354 An ImagePair object, or None if both image_dict_A and image_dict_B are 390 An ImagePair object, or None if both image_dict_A and image_dict_B are
355 None. 391 None.
356 """ 392 """
357 if (not image_dict_A) and (not image_dict_B): 393 if (not image_dict_A) and (not image_dict_B):
358 return None 394 return None
359 395
(...skipping 15 matching lines...) Expand all
375 elif not imageB_checksum: 411 elif not imageB_checksum:
376 result_type = results.KEY__RESULT_TYPE__NOCOMPARISON 412 result_type = results.KEY__RESULT_TYPE__NOCOMPARISON
377 elif imageA_checksum == imageB_checksum: 413 elif imageA_checksum == imageB_checksum:
378 result_type = results.KEY__RESULT_TYPE__SUCCEEDED 414 result_type = results.KEY__RESULT_TYPE__SUCCEEDED
379 else: 415 else:
380 result_type = results.KEY__RESULT_TYPE__FAILED 416 result_type = results.KEY__RESULT_TYPE__FAILED
381 417
382 extra_columns_dict = { 418 extra_columns_dict = {
383 COLUMN__RESULT_TYPE: result_type, 419 COLUMN__RESULT_TYPE: result_type,
384 COLUMN__SOURCE_SKP: source_skp_name, 420 COLUMN__SOURCE_SKP: source_skp_name,
421 COLUMN__BUILDER_A: builder_A,
422 COLUMN__RENDER_MODE_A: render_mode_A,
423 COLUMN__BUILDER_B: builder_B,
424 COLUMN__RENDER_MODE_B: render_mode_B,
385 } 425 }
386 if tilenum == None: 426 if tilenum == None:
387 extra_columns_dict[COLUMN__TILED_OR_WHOLE] = 'whole' 427 extra_columns_dict[COLUMN__TILED_OR_WHOLE] = 'whole'
388 extra_columns_dict[COLUMN__TILENUM] = 'N/A' 428 extra_columns_dict[COLUMN__TILENUM] = 'N/A'
389 else: 429 else:
390 extra_columns_dict[COLUMN__TILED_OR_WHOLE] = 'tiled' 430 extra_columns_dict[COLUMN__TILED_OR_WHOLE] = 'tiled'
391 extra_columns_dict[COLUMN__TILENUM] = str(tilenum) 431 extra_columns_dict[COLUMN__TILENUM] = str(tilenum)
392 432
393 try: 433 try:
394 return imagepair.ImagePair( 434 return imagepair.ImagePair(
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
441 if source_dir.lower().startswith(REPO_URL_PREFIX): 481 if source_dir.lower().startswith(REPO_URL_PREFIX):
442 repo_dir = os.path.join(REPO_BASEPATH, source_dir[len(REPO_URL_PREFIX):]) 482 repo_dir = os.path.join(REPO_BASEPATH, source_dir[len(REPO_URL_PREFIX):])
443 revision = subprocess.check_output( 483 revision = subprocess.check_output(
444 args=[git_utils.GIT, 'rev-parse', 'HEAD'], cwd=repo_dir).strip() 484 args=[git_utils.GIT, 'rev-parse', 'HEAD'], cwd=repo_dir).strip()
445 if assert_if_not and revision != assert_if_not: 485 if assert_if_not and revision != assert_if_not:
446 raise Exception('found revision %s that did not match %s' % ( 486 raise Exception('found revision %s that did not match %s' % (
447 revision, assert_if_not)) 487 revision, assert_if_not))
448 return revision 488 return revision
449 else: 489 else:
450 return None 490 return None
OLDNEW
« no previous file with comments | « gm/rebaseline_server/compare_configs_test.py ('k') | gm/rebaseline_server/compare_rendered_pictures_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698