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

Side by Side Diff: compute_engine_scripts/telemetry/telemetry_slave_scripts/write_json_summary.py

Issue 227673005: make CT skia_try_server work with updated render_pictures JSON (Closed) Base URL: https://skia.googlesource.com/buildbot.git@master
Patch Set: rebase Created 6 years, 8 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
« no previous file with comments | « compute_engine_scripts/telemetry/telemetry_slave_scripts/test_data/summary.json ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Module that outputs an JSON summary containing the comparision of images.""" 6 """Module that outputs an JSON summary containing the comparision of images."""
7 7
8 import json 8 import json
9 import optparse 9 import optparse
10 import os 10 import os
11 import posixpath 11 import posixpath
12 import sys 12 import sys
13 import traceback 13 import traceback
14 14
15 sys.path.append( 15 sys.path.append(
16 os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir)) 16 os.path.join(os.path.dirname(os.path.realpath(__file__)), os.pardir))
17 import json_summary_constants 17 import json_summary_constants
18 18
19 # TODO(epoger): These constants must be kept in sync with the ones in
20 # https://skia.googlesource.com/skia/+/master/tools/PictureRenderer.cpp
21 JSONKEY_HEADER = 'header'
22 JSONKEY_HEADER_TYPE = 'type'
23 JSONKEY_HEADER_REVISION = 'revision'
24 JSONKEY_IMAGE_CHECKSUMALGORITHM = 'checksumAlgorithm'
25 JSONKEY_IMAGE_CHECKSUMVALUE = 'checksumValue'
26 JSONKEY_IMAGE_COMPARISONRESULT = 'comparisonResult'
27 JSONKEY_IMAGE_FILEPATH = 'filepath'
28 JSONKEY_SOURCE_TILEDIMAGES = 'tiled-images'
29 JSONKEY_SOURCE_WHOLEIMAGE = 'whole-image'
30
31 JSONVALUE_HEADER_TYPE = 'ChecksummedImages'
32 JSONVALUE_HEADER_REVISION = 1
33
34 IMAGE_SOURCE = 'imageSource'
35
19 36
20 def WriteJsonSummary(img_root, nopatch_json, nopatch_images_base_url, 37 def WriteJsonSummary(img_root, nopatch_json, nopatch_images_base_url,
21 withpatch_json, withpatch_images_base_url, 38 withpatch_json, withpatch_images_base_url,
22 output_file_path, gs_output_dir, gs_skp_dir, slave_num, 39 output_file_path, gs_output_dir, gs_skp_dir, slave_num,
23 additions_to_sys_path): 40 additions_to_sys_path):
24 """Outputs the JSON summary of image comparisions. 41 """Outputs the JSON summary of image comparisions.
25 42
26 Args: 43 Args:
27 img_root: (str) The root directory on local disk where we store all images. 44 img_root: (str) The root directory on local disk where we store all images.
28 nopatch_json: (str) Location of the nopatch render_pictures JSON summary 45 nopatch_json: (str) Location of the nopatch render_pictures JSON summary
(...skipping 22 matching lines...) Expand all
51 68
52 # Modules from skia's gm/ and gm/rebaseline_server/ dirs. 69 # Modules from skia's gm/ and gm/rebaseline_server/ dirs.
53 try: 70 try:
54 import gm_json 71 import gm_json
55 import imagediffdb 72 import imagediffdb
56 except ImportError: 73 except ImportError:
57 print 'sys.path is [%s]' % sys.path 74 print 'sys.path is [%s]' % sys.path
58 traceback.print_exc() 75 traceback.print_exc()
59 raise Exception('You need to add gm/ and gm/rebaseline_server to sys.path') 76 raise Exception('You need to add gm/ and gm/rebaseline_server to sys.path')
60 77
61 files_to_checksums_nopatch = GetFilesAndChecksums(gm_json, nopatch_json) 78 all_image_descriptions_nopatch = GetImageDescriptions(gm_json, nopatch_json)
62 files_to_checksums_withpatch = GetFilesAndChecksums(gm_json, withpatch_json) 79 all_image_descriptions_withpatch = GetImageDescriptions(
80 gm_json, withpatch_json)
63 81
64 assert len(files_to_checksums_nopatch) == len(files_to_checksums_withpatch), ( 82 assert (len(all_image_descriptions_nopatch) ==
65 'Number of images in both JSON summary files are different') 83 len(all_image_descriptions_withpatch)), \
66 assert files_to_checksums_nopatch.keys() == \ 84 'Number of images in the two JSON summary files are different'
67 files_to_checksums_withpatch.keys(), ( 85 assert (all_image_descriptions_nopatch.keys() ==
68 'File names in both JSON summary files are different') 86 all_image_descriptions_withpatch.keys()), \
87 'SKP filenames in the two JSON summary files are different'
69 88
70 # Compare checksums in both directories and output differences. 89 # Compare checksums in both directories and output differences.
71 file_differences = [] 90 file_differences = []
72 slave_dict = { 91 slave_dict = {
73 json_summary_constants.JSONKEY_SKPS_LOCATION: gs_skp_dir, 92 json_summary_constants.JSONKEY_SKPS_LOCATION: gs_skp_dir,
74 json_summary_constants.JSONKEY_FAILED_FILES: file_differences, 93 json_summary_constants.JSONKEY_FAILED_FILES: file_differences,
75 json_summary_constants.JSONKEY_FILES_LOCATION_NOPATCH: posixpath.join( 94 json_summary_constants.JSONKEY_FILES_LOCATION_NOPATCH: posixpath.join(
76 gs_output_dir, 'slave%s' % slave_num, 'nopatch-images'), 95 gs_output_dir, 'slave%s' % slave_num, 'nopatch-images'),
77 json_summary_constants.JSONKEY_FILES_LOCATION_WITHPATCH: posixpath.join( 96 json_summary_constants.JSONKEY_FILES_LOCATION_WITHPATCH: posixpath.join(
78 gs_output_dir, 'slave%s' % slave_num, 'withpatch-images'), 97 gs_output_dir, 'slave%s' % slave_num, 'withpatch-images'),
79 json_summary_constants.JSONKEY_FILES_LOCATION_DIFFS: posixpath.join( 98 json_summary_constants.JSONKEY_FILES_LOCATION_DIFFS: posixpath.join(
80 gs_output_dir, 'slave%s' % slave_num, 'diffs'), 99 gs_output_dir, 'slave%s' % slave_num, 'diffs'),
81 json_summary_constants.JSONKEY_FILES_LOCATION_WHITE_DIFFS: posixpath.join( 100 json_summary_constants.JSONKEY_FILES_LOCATION_WHITE_DIFFS: posixpath.join(
82 gs_output_dir, 'slave%s' % slave_num, 'whitediffs') 101 gs_output_dir, 'slave%s' % slave_num, 'whitediffs')
83 } 102 }
84 json_summary = { 103 json_summary = {
85 'slave%s' % slave_num: slave_dict 104 'slave%s' % slave_num: slave_dict
86 } 105 }
87 106
88 image_diff_db = imagediffdb.ImageDiffDB(storage_root=img_root) 107 image_diff_db = imagediffdb.ImageDiffDB(storage_root=img_root)
89 for filename in files_to_checksums_nopatch: 108 for image_filepath in all_image_descriptions_nopatch:
90 algo_nopatch, checksum_nopatch = files_to_checksums_nopatch[filename] 109 image_desc_nopatch = all_image_descriptions_nopatch[image_filepath]
91 algo_withpatch, checksum_withpatch = files_to_checksums_withpatch[filename] 110 image_desc_withpatch = all_image_descriptions_withpatch[image_filepath]
92 assert algo_nopatch == algo_withpatch, 'Different checksum algorithms found' 111
112 algo_nopatch = image_desc_nopatch[JSONKEY_IMAGE_CHECKSUMALGORITHM]
113 algo_withpatch = image_desc_withpatch[JSONKEY_IMAGE_CHECKSUMALGORITHM]
114 assert algo_nopatch == algo_withpatch, 'Different checksum algorithms'
115
116 imagefile_nopatch = image_desc_nopatch[JSONKEY_IMAGE_FILEPATH]
117 imagefile_withpatch = image_desc_withpatch[JSONKEY_IMAGE_FILEPATH]
118 assert imagefile_nopatch == imagefile_withpatch, 'Different imagefile names'
119
120 skpfile_nopatch = image_desc_nopatch[IMAGE_SOURCE]
121 skpfile_withpatch = image_desc_withpatch[IMAGE_SOURCE]
122 assert skpfile_nopatch == skpfile_withpatch, 'Different skpfile names'
123
124 checksum_nopatch = image_desc_nopatch[JSONKEY_IMAGE_CHECKSUMVALUE]
125 checksum_withpatch = image_desc_withpatch[JSONKEY_IMAGE_CHECKSUMVALUE]
93 if checksum_nopatch != checksum_withpatch: 126 if checksum_nopatch != checksum_withpatch:
94 # TODO(epoger): It seems silly that we add this DiffRecord to ImageDiffDB 127 # TODO(epoger): It seems silly that we add this DiffRecord to ImageDiffDB
95 # and then pull it out again right away, but this is a stepping-stone 128 # and then pull it out again right away, but this is a stepping-stone
96 # to using ImagePairSet instead of replicating its behavior here. 129 # to using ImagePairSet instead of replicating its behavior here.
97 image_locator_base = os.path.splitext(filename)[0] 130 image_locator_base = os.path.splitext(imagefile_nopatch)[0]
98 image_locator_nopatch = image_locator_base + '_nopatch' 131 image_locator_nopatch = image_locator_base + '_nopatch'
99 image_locator_withpatch = image_locator_base + '_withpatch' 132 image_locator_withpatch = image_locator_base + '_withpatch'
100 image_diff_db.add_image_pair( 133 image_diff_db.add_image_pair(
101 expected_image_url=posixpath.join(nopatch_images_base_url, filename), 134 expected_image_url=posixpath.join(
135 nopatch_images_base_url, image_filepath),
102 expected_image_locator=image_locator_nopatch, 136 expected_image_locator=image_locator_nopatch,
103 actual_image_url=posixpath.join(withpatch_images_base_url, filename), 137 actual_image_url=posixpath.join(
138 withpatch_images_base_url, image_filepath),
104 actual_image_locator=image_locator_withpatch) 139 actual_image_locator=image_locator_withpatch)
105 diff_record = image_diff_db.get_diff_record( 140 diff_record = image_diff_db.get_diff_record(
106 expected_image_locator=image_locator_nopatch, 141 expected_image_locator=image_locator_nopatch,
107 actual_image_locator=image_locator_withpatch) 142 actual_image_locator=image_locator_withpatch)
108 file_differences.append({ 143 file_differences.append({
109 json_summary_constants.JSONKEY_FILE_NAME: filename, 144 json_summary_constants.JSONKEY_FILE_NAME: imagefile_nopatch,
110 json_summary_constants.JSONKEY_SKP_LOCATION: posixpath.join( 145 json_summary_constants.JSONKEY_SKP_LOCATION: posixpath.join(
111 gs_skp_dir, GetSkpFileName(filename)), 146 gs_skp_dir, skpfile_nopatch),
112 json_summary_constants.JSONKEY_NUM_PIXELS_DIFFERING: 147 json_summary_constants.JSONKEY_NUM_PIXELS_DIFFERING:
113 diff_record.get_num_pixels_differing(), 148 diff_record.get_num_pixels_differing(),
114 json_summary_constants.JSONKEY_PERCENT_PIXELS_DIFFERING: 149 json_summary_constants.JSONKEY_PERCENT_PIXELS_DIFFERING:
115 diff_record.get_percent_pixels_differing(), 150 diff_record.get_percent_pixels_differing(),
116 json_summary_constants.JSONKEY_WEIGHTED_DIFF_MEASURE: 151 json_summary_constants.JSONKEY_WEIGHTED_DIFF_MEASURE:
117 diff_record.get_weighted_diff_measure(), 152 diff_record.get_weighted_diff_measure(),
118 json_summary_constants.JSONKEY_MAX_DIFF_PER_CHANNEL: 153 json_summary_constants.JSONKEY_MAX_DIFF_PER_CHANNEL:
119 diff_record.get_max_diff_per_channel(), 154 diff_record.get_max_diff_per_channel(),
120 json_summary_constants.JSONKEY_PERCEPTUAL_DIFF: 155 json_summary_constants.JSONKEY_PERCEPTUAL_DIFF:
121 diff_record.get_perceptual_difference(), 156 diff_record.get_perceptual_difference(),
122 }) 157 })
123 if file_differences: 158 if file_differences:
124 slave_dict[json_summary_constants.JSONKEY_FAILED_FILES_COUNT] = len( 159 slave_dict[json_summary_constants.JSONKEY_FAILED_FILES_COUNT] = len(
125 file_differences) 160 file_differences)
126 with open(output_file_path, 'w') as f: 161 with open(output_file_path, 'w') as f:
127 f.write(json.dumps(json_summary, indent=4, sort_keys=True)) 162 f.write(json.dumps(json_summary, indent=4, sort_keys=True))
128 163
129 164
130 def GetSkpFileName(img_file_name): 165 def GetImageDescriptions(gm_json_mod, json_location):
131 """Determine the SKP file name from the image's file name.""" 166 """Reads the JSON summary and returns {ImageFilePath: ImageDescription} dict.
132 # TODO(rmistry): The below relies too much on the current output of render
133 # pictures to determine the root SKP.
134 return '%s_.skp' % '_'.join(img_file_name.split('_')[:-1])
135 167
168 Each ImageDescription is a dict of this form:
169 {
170 JSONKEY_IMAGE_CHECKSUMALGORITHM: 'bitmap-64bitMD5',
171 JSONKEY_IMAGE_CHECKSUMVALUE: 5815827069051002745,
172 JSONKEY_IMAGE_COMPARISONRESULT: 'no-comparison',
173 JSONKEY_IMAGE_FILEPATH: 'red_skp-tile0.png', # equals ImageFilePath dict key
174 IMAGE_SOURCE: 'red.skp'
175 }
176 """
177 json_data = gm_json_mod.LoadFromFile(json_location)
178 if json_data:
179 header_type = json_data[JSONKEY_HEADER][JSONKEY_HEADER_TYPE]
180 if header_type != JSONVALUE_HEADER_TYPE:
181 raise Exception('expected header_type %s but found %s' % (
182 JSONVALUE_HEADER_TYPE, header_type))
183 header_revision = json_data[JSONKEY_HEADER][JSONKEY_HEADER_REVISION]
184 if header_revision != JSONVALUE_HEADER_REVISION:
185 raise Exception('expected header_revision %s but found %s' % (
186 JSONVALUE_HEADER_REVISION, header_revision))
136 187
137 def GetFilesAndChecksums(gm_json_mod, json_location): 188 actual_results = json_data[gm_json_mod.JSONKEY_ACTUALRESULTS]
138 """Reads the JSON summary and returns dict of files to checksums.""" 189 newdict = {}
139 data = gm_json_mod.LoadFromFile(json_location) 190 for skp_file in actual_results:
140 if data: 191 whole_image_description = actual_results[skp_file].get(
141 return data[gm_json_mod.JSONKEY_ACTUALRESULTS][ 192 JSONKEY_SOURCE_WHOLEIMAGE, None)
142 gm_json_mod.JSONKEY_ACTUALRESULTS_NOCOMPARISON] 193 all_image_descriptions = actual_results[skp_file].get(
194 JSONKEY_SOURCE_TILEDIMAGES, [])
195 if whole_image_description:
196 all_image_descriptions.append(whole_image_description)
197 for image_description in all_image_descriptions:
198 image_filepath = image_description[JSONKEY_IMAGE_FILEPATH]
199 image_description[IMAGE_SOURCE] = skp_file
200 if image_filepath in newdict:
201 raise Exception('found two images with same filepath %s' %
202 image_filepath)
203 newdict[image_filepath] = image_description
204 return newdict
143 else: 205 else:
144 return {} 206 return {}
145 207
146 208
147 if '__main__' == __name__: 209 if '__main__' == __name__:
148 option_parser = optparse.OptionParser() 210 option_parser = optparse.OptionParser()
149 option_parser.add_option( 211 option_parser.add_option(
150 '', '--img_root', 212 '', '--img_root',
151 help='The root directory on local disk where we store all images.') 213 help='The root directory on local disk where we store all images.')
152 option_parser.add_option( 214 option_parser.add_option(
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 option_parser.error( 254 option_parser.error(
193 'Must specify img_root, nopatch_json, nopatch_images_base_url, ' 255 'Must specify img_root, nopatch_json, nopatch_images_base_url, '
194 'withpatch_json, withpatch_images_base_url, output_file_path, ' 256 'withpatch_json, withpatch_images_base_url, output_file_path, '
195 'gs_output_dir, gs_skp_dir, and slave_num.') 257 'gs_output_dir, gs_skp_dir, and slave_num.')
196 258
197 WriteJsonSummary(options.img_root, options.nopatch_json, 259 WriteJsonSummary(options.img_root, options.nopatch_json,
198 options.nopatch_images_base_url, options.withpatch_json, 260 options.nopatch_images_base_url, options.withpatch_json,
199 options.withpatch_images_base_url, options.output_file_path, 261 options.withpatch_images_base_url, options.output_file_path,
200 options.gs_output_dir, options.gs_skp_dir, options.slave_num, 262 options.gs_output_dir, options.gs_skp_dir, options.slave_num,
201 options.add_to_sys_path) 263 options.add_to_sys_path)
OLDNEW
« no previous file with comments | « compute_engine_scripts/telemetry/telemetry_slave_scripts/test_data/summary.json ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698