OLD | NEW |
---|---|
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
3 | 3 |
4 from __future__ import print_function | 4 from __future__ import print_function |
5 import argparse | 5 import argparse |
6 import BaseHTTPServer | 6 import BaseHTTPServer |
7 import json | 7 import json |
8 import os | 8 import os |
9 import os.path | 9 import os.path |
10 import re | 10 import re |
11 import subprocess | |
11 import sys | 12 import sys |
12 import tempfile | 13 import tempfile |
13 import urllib2 | 14 import urllib2 |
14 | 15 |
15 # Grab the script path because that is where all the static assets are | 16 # Grab the script path because that is where all the static assets are |
16 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | 17 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) |
17 | 18 |
18 # Find the tools directory for python imports | 19 # Find the tools directory for python imports |
19 TOOLS_DIR = os.path.dirname(SCRIPT_DIR) | 20 TOOLS_DIR = os.path.dirname(SCRIPT_DIR) |
20 | 21 |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
92 | 93 |
93 | 94 |
94 def download_gm_image(image_name, image_path, hash_val): | 95 def download_gm_image(image_name, image_path, hash_val): |
95 """Download the gm result into the given path. | 96 """Download the gm result into the given path. |
96 | 97 |
97 @param image_name The GM file name, for example imageblur_gpu.png. | 98 @param image_name The GM file name, for example imageblur_gpu.png. |
98 @param image_path Path to place the image. | 99 @param image_path Path to place the image. |
99 @param hash_val The hash value of the image. | 100 @param hash_val The hash value of the image. |
100 """ | 101 """ |
101 | 102 |
102 # Seperate the test name from a image name | 103 # Separate the test name from a image name |
103 image_match = IMAGE_FILENAME_RE.match(image_name) | 104 image_match = IMAGE_FILENAME_RE.match(image_name) |
104 test_name = image_match.group(1) | 105 test_name = image_match.group(1) |
105 | 106 |
106 # Calculate the URL of the requested image | 107 # Calculate the URL of the requested image |
107 image_url = gm_json.CreateGmActualUrl( | 108 image_url = gm_json.CreateGmActualUrl( |
108 test_name, gm_json.JSONKEY_HASHTYPE_BITMAP_64BITMD5, hash_val) | 109 test_name, gm_json.JSONKEY_HASHTYPE_BITMAP_64BITMD5, hash_val) |
109 | 110 |
110 # Download the image as requested | 111 # Download the image as requested |
111 download_file(image_url, image_path) | 112 download_file(image_url, image_path) |
112 | 113 |
113 | 114 |
114 def download_changed_images(expectations_dir, expected_name, updated_name, | |
115 expected_image_dir, actual_image_dir): | |
116 | |
117 """Download the expected and actual GMs that changed into the given paths. | |
118 Determining what changed will be done by comparing each expected_name JSON | |
119 results file to its corresponding updated_name JSON results file if it | |
120 exists. | |
121 | |
122 @param expectations_dir The directory to traverse for results files. This | |
123 should resmble expectations/gm in the Skia trunk. | |
124 @param expected_name The name of the expected result files. These are | |
125 in the format of expected-results.json. | |
126 @param updated_name The name of the updated expected result files. | |
127 Normally this matches --expectations-filename-output for the | |
128 rebaseline.py tool. | |
129 @param expected_image_dir The directory to place downloaded expected images | |
130 into. | |
131 @param actual_image_dir The directory to place downloaded actual images | |
132 into. | |
133 """ | |
134 | |
135 differ = jsondiff.GMDiffer() | |
136 | |
137 # Look through expectations for hashes that changed | |
138 for root, dirs, files in os.walk(expectations_dir): | |
139 for expectation_file in files: | |
140 # There are many files in the expectations directory. We only care | |
141 # about expected results. | |
142 if expectation_file != expected_name: | |
143 continue | |
144 | |
145 # Get the name of the results file, and be sure there is an updated | |
146 # result to compare against. If there is not, there is no point in | |
147 # diffing this device. | |
148 expected_file_path = os.path.join(root, expected_name) | |
149 updated_file_path = os.path.join(root, updated_name) | |
150 if not os.path.isfile(updated_file_path): | |
151 continue | |
152 | |
153 # Find all expectations that did not match. | |
154 expected_diff = differ.GenerateDiffDict(expected_file_path, | |
155 updated_file_path) | |
156 | |
157 # The name of the device corresponds to the name of the folder we | |
158 # are in. | |
159 device_name = os.path.basename(root) | |
160 | |
161 # Create name prefixes to store the devices old and new GM results | |
162 expected_image_prefix = os.path.join(expected_image_dir, | |
163 device_name) + '-' | |
164 | |
165 actual_image_prefix = os.path.join(actual_image_dir, | |
166 device_name) + '-' | |
167 | |
168 # Download each image that had a differing result | |
169 for image_name, hashes in expected_diff.iteritems(): | |
170 print('Downloading', image_name, 'for device', device_name) | |
171 download_gm_image(image_name, | |
172 expected_image_prefix + image_name, | |
173 hashes['old']) | |
174 download_gm_image(image_name, | |
175 actual_image_prefix + image_name, | |
176 hashes['new']) | |
177 | |
178 | |
179 def get_image_set_from_skpdiff(skpdiff_records): | 115 def get_image_set_from_skpdiff(skpdiff_records): |
180 """Get the set of all images references in the given records. | 116 """Get the set of all images references in the given records. |
181 | 117 |
182 @param skpdiff_records An array of records, which are dictionary objects. | 118 @param skpdiff_records An array of records, which are dictionary objects. |
183 """ | 119 """ |
184 expected_set = frozenset([r['baselinePath'] for r in skpdiff_records]) | 120 expected_set = frozenset([r['baselinePath'] for r in skpdiff_records]) |
185 actual_set = frozenset([r['testPath'] for r in skpdiff_records]) | 121 actual_set = frozenset([r['testPath'] for r in skpdiff_records]) |
186 return expected_set | actual_set | 122 return expected_set | actual_set |
187 | 123 |
188 | 124 |
125 def set_expected_hash_in_json(expected_results_json, image_name, hash_value): | |
126 """Set the expected hash for the object extracted from | |
127 expected-results.json. | |
128 | |
129 @param expected_results_json The Python dictionary with the results to | |
130 modify. | |
131 @param image_name The name of the image to set the hash of. | |
132 @param hash_value The hash to set for the image. | |
133 """ | |
134 expected_results = expected_results_json[gm_json.JSONKEY_EXPECTEDRESULTS] | |
135 | |
136 if image_name in expected_results: | |
137 expected_results[image_name][gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGE STS][0][1] = hash_value | |
Zach Reizner
2013/08/01 22:24:40
Curse you 80 character line length.
epoger
2013/08/02 14:33:06
Indeed.
If you want to, you can split it like so
Zach Reizner
2013/08/02 21:30:58
I do not want to.
epoger
2013/08/06 15:26:43
Fine, be that way.
| |
138 else: | |
139 expected_results[image_name] = { | |
140 gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS: | |
141 [ | |
142 [ | |
143 'bitmap-64bitMD5', | |
epoger
2013/08/02 14:33:06
please use the constant reference to this string v
Zach Reizner
2013/08/02 21:30:58
Done.
| |
144 hash_value | |
145 ] | |
146 ] | |
147 } | |
148 | |
149 | |
150 def get_git_version(path): | |
epoger
2013/08/02 14:33:06
IMHO, get_head_version or get_base_version would b
Zach Reizner
2013/08/02 21:30:58
Done.
| |
151 """Get the version of the file at the given path stored inside the HEAD of | |
152 the git repository. It is returned as a string. | |
153 | |
154 @param path The path of the file whose HEAD is returned. It is assumed the | |
155 path is inside a git repo rooted at SKIA_ROOT_DIR. | |
156 """ | |
157 | |
158 # git-show will only work with paths relative to the root of the git repo. | |
epoger
2013/08/02 14:33:06
This is great, but FYI, git-show works with a path
Zach Reizner
2013/08/02 21:30:58
Thanks
| |
159 # This ensures we give it that relative path. | |
160 git_path = os.path.relpath(path, SKIA_ROOT_DIR) | |
161 git_show_proc = subprocess.Popen(['git', 'show', 'HEAD:' + git_path], | |
162 stdout=subprocess.PIPE) | |
163 | |
164 # When invoked outside a shell, git will output the last committed version | |
165 # of the file directly to stdout. | |
166 git_version_content, _ = git_show_proc.communicate() | |
167 return git_version_content | |
168 | |
169 | |
170 class ExpectationsManager: | |
171 def __init__(self, expectations_dir, expected_name, updated_name, | |
172 skpdiff_path): | |
173 """ | |
174 @param expectations_dir The directory to traverse for results files. | |
175 This should resmble expectations/gm in the Skia trunk. | |
176 @param expected_name The name of the expected result files. These | |
177 are in the format of expected-results.json. | |
178 @param updated_name The name of the updated expected result files. | |
179 Normally this matches --expectations-filename-output for the | |
epoger
2013/08/02 14:33:06
I don't understand why we need the updated expecte
Zach Reizner
2013/08/02 21:30:58
You make an excellent point.
Derek and I have bee
| |
180 rebaseline.py tool. | |
181 @param skpdiff_path The path used to execute the skpdiff command. | |
182 """ | |
183 self.expectations_dir = expectations_dir | |
epoger
2013/08/02 14:33:06
Typically, we would use underscored (self._expecta
Zach Reizner
2013/08/02 21:30:58
Done.
| |
184 self.expected_name = expected_name | |
185 self.updated_name = updated_name | |
186 self.skpdiff_path = skpdiff_path | |
187 self.generate_gm_comparison() | |
188 | |
189 def generate_gm_comparison(self): | |
190 """Generate all the data needed to compare GMs including downloading the | |
191 changed images and comparing them skpdiff. | |
epoger
2013/08/02 14:33:06
I think it would be clearer in bullet list form:
Zach Reizner
2013/08/02 21:30:58
Done.
| |
192 """ | |
193 # Create a temporary file tree that makes sense for skpdiff to operate | |
194 # on. | |
195 image_output_dir = tempfile.mkdtemp('skpdiff') | |
196 expected_image_dir = os.path.join(image_output_dir, 'expected') | |
197 actual_image_dir = os.path.join(image_output_dir, 'actual') | |
198 os.mkdir(expected_image_dir) | |
199 os.mkdir(actual_image_dir) | |
200 | |
201 # Download expected and actual images that differed into the temporary | |
202 # file tree. | |
203 self.download_changed_images(expected_image_dir, actual_image_dir) | |
204 | |
205 # Invoke skpdiff with our downloaded images and place its results in the | |
206 # temporary directory. | |
207 self.skpdiff_output_path = os.path.join(image_output_dir, | |
208 'skpdiff_output.json') | |
209 skpdiff_cmd = SKPDIFF_INVOKE_FORMAT.format(self.skpdiff_path, | |
210 self.skpdiff_output_path, | |
211 expected_image_dir, | |
212 actual_image_dir) | |
213 os.system(skpdiff_cmd) | |
214 | |
215 def download_changed_images(self, expected_image_dir, actual_image_dir): | |
epoger
2013/08/02 14:33:06
Ultimately, it would be good for us to have self-t
| |
216 """Download the expected and actual GMs that changed into the given | |
217 paths. Determining what changed will be done by comparing each | |
218 expected_name JSON results file to its corresponding updated_name JSON | |
219 results file if it exists. | |
220 | |
221 @param expected_image_dir The directory to place downloaded expected | |
epoger
2013/08/02 14:33:06
maybe clearer to call this "The directory to downl
Zach Reizner
2013/08/02 21:30:58
Done.
| |
222 into. | |
223 @param actual_image_dir The directory to place downloaded actual | |
224 images into. | |
225 """ | |
226 image_map = {} | |
227 differ = jsondiff.GMDiffer() | |
228 | |
229 # Look through expectations for hashes that changed | |
230 for root, dirs, files in os.walk(self.expectations_dir): | |
231 for expectation_file in files: | |
232 # There are many files in the expectations directory. We only | |
233 # care about expected results. | |
234 if expectation_file != self.expected_name: | |
235 continue | |
236 | |
237 # Get the name of the results file, and be sure there is an | |
238 # updated result to compare against. If there is not, there is | |
239 # no point in diffing this device. | |
240 expected_file_path = os.path.join(root, self.expected_name) | |
241 updated_file_path = os.path.join(root, self.updated_name) | |
242 if not os.path.isfile(updated_file_path): | |
243 continue | |
244 | |
245 # Always get the expected results from git because we may have | |
246 # changed them in a previous instance of the server. | |
247 expected_contents = get_git_version(expected_file_path) | |
248 updated_contents = None | |
249 with open(updated_file_path, 'rb') as updated_file: | |
250 updated_contents = updated_file.read() | |
251 | |
252 # Find all expectations that did not match. | |
253 expected_diff = differ.GenerateDiffDictFromStrings( | |
254 expected_contents, | |
255 updated_contents) | |
256 | |
257 # The name of the device corresponds to the name of the folder | |
258 # we are in. | |
259 device_name = os.path.basename(root) | |
260 | |
261 # Creat name prefixes to store the device's old and new GM | |
262 # results. | |
263 expected_image_prefix = os.path.join(expected_image_dir, | |
264 device_name) + '-' | |
265 | |
266 actual_image_prefix = os.path.join(actual_image_dir, | |
267 device_name) + '-' | |
268 | |
269 # Download each image that had a differing result. We take care | |
270 # to store metadata about each image so that we know about an | |
271 # image from its path on disk alone. That is all we will know | |
272 # after skpdiff outputs its results. | |
273 for image_name, hashes in expected_diff.iteritems(): | |
274 print('Downloading', image_name, 'for device', device_name) | |
275 download_gm_image(image_name, | |
276 expected_image_prefix + image_name, | |
277 hashes['old']) | |
278 image_map[expected_image_prefix + image_name] = ( | |
279 device_name, image_name, hashes['old']) | |
280 download_gm_image(image_name, | |
281 actual_image_prefix + image_name, | |
282 hashes['new']) | |
283 image_map[actual_image_prefix + image_name] = ( | |
284 device_name, image_name, hashes['new']) | |
285 | |
286 self.image_map = image_map | |
287 | |
288 def set_expected_hash(self, device_name, image_name, hash_value): | |
289 """Set the expected hash for the image of the given device. This always | |
290 writes directly to the expected results file of the given device | |
291 | |
292 @param device_name The name of the device to write the hash to. | |
293 @param image_name The name of the image whose hash to set. | |
294 @param hash_value The value of the hash to set. | |
295 """ | |
296 | |
297 # Retrieve the expected results file as it is in the working tree | |
298 json_path = os.path.join(self.expectations_dir, device_name, | |
299 self.expected_name) | |
300 expectations = gm_json.LoadFromFile(json_path) | |
301 | |
302 # Set the specified hash. | |
303 set_expected_hash_in_json(expectations, image_name, hash_value) | |
304 | |
305 # Write it out to disk using gm_json to keep the formatting consistent. | |
306 gm_json.WriteToFile(expectations, json_path) | |
307 | |
308 def use_hash_of(self, image_path): | |
309 """Determine the hash of the image at the path using the records, and | |
310 set it as the expected hash for its device and image config. | |
311 | |
312 @param image_path The path of the image as it was stored in the output | |
313 of skpdiff_path | |
314 """ | |
315 | |
316 # Get the metadata about the image at the path. | |
317 device_name, image_name, hash_value = self.image_map[image_path] | |
318 | |
319 # Write out that image's hash directly to the expected results file. | |
320 self.set_expected_hash(device_name, image_name, hash_value) | |
321 | |
322 | |
189 class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 323 class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
190 def send_file(self, file_path): | 324 def send_file(self, file_path): |
191 # Grab the extension if there is one | 325 # Grab the extension if there is one |
192 extension = os.path.splitext(file_path)[1] | 326 extension = os.path.splitext(file_path)[1] |
193 if len(extension) >= 1: | 327 if len(extension) >= 1: |
194 extension = extension[1:] | 328 extension = extension[1:] |
195 | 329 |
196 # Determine the MIME type of the file from its extension | 330 # Determine the MIME type of the file from its extension |
197 mime_type = MIME_TYPE_MAP.get(extension, MIME_TYPE_MAP['']) | 331 mime_type = MIME_TYPE_MAP.get(extension, MIME_TYPE_MAP['']) |
198 | 332 |
199 # Open the file and send it over HTTP | 333 # Open the file and send it over HTTP |
200 if os.path.isfile(file_path): | 334 if os.path.isfile(file_path): |
201 with open(file_path, 'rb') as sending_file: | 335 with open(file_path, 'rb') as sending_file: |
202 self.send_response(200) | 336 self.send_response(200) |
203 self.send_header('Content-type', mime_type) | 337 self.send_header('Content-type', mime_type) |
204 self.end_headers() | 338 self.end_headers() |
205 self.wfile.write(sending_file.read()) | 339 self.wfile.write(sending_file.read()) |
206 else: | 340 else: |
207 self.send_error(404) | 341 self.send_error(404) |
208 | 342 |
209 def serve_if_in_dir(self, dir_path, file_path): | 343 def serve_if_in_dir(self, dir_path, file_path): |
210 # Determine if the file exists relative to the given dir_path AND exists | 344 # Determine if the file exists relative to the given dir_path AND exists |
211 # under the dir_path. This is to prevent accidentally serving files | 345 # under the dir_path. This is to prevent accidentally serving files |
212 # outside the directory intended using symlinks, or '../'. | 346 # outside the directory intended using symlinks, or '../'. |
213 real_path = os.path.normpath(os.path.join(dir_path, file_path)) | 347 real_path = os.path.normpath(os.path.join(dir_path, file_path)) |
214 print(repr(real_path)) | |
215 if os.path.commonprefix([real_path, dir_path]) == dir_path: | 348 if os.path.commonprefix([real_path, dir_path]) == dir_path: |
216 if os.path.isfile(real_path): | 349 if os.path.isfile(real_path): |
217 self.send_file(real_path) | 350 self.send_file(real_path) |
218 return True | 351 return True |
219 return False | 352 return False |
220 | 353 |
221 def do_GET(self): | 354 def do_GET(self): |
222 # Simple rewrite rule of the root path to 'viewer.html' | 355 # Simple rewrite rule of the root path to 'viewer.html' |
223 if self.path == '' or self.path == '/': | 356 if self.path == '' or self.path == '/': |
224 self.path = '/viewer.html' | 357 self.path = '/viewer.html' |
(...skipping 16 matching lines...) Expand all Loading... | |
241 | 374 |
242 # WARNING: Serving any file the user wants is incredibly insecure. Its | 375 # WARNING: Serving any file the user wants is incredibly insecure. Its |
243 # redeeming quality is that we only serve gm files on a white list. | 376 # redeeming quality is that we only serve gm files on a white list. |
244 if self.path in self.server.image_set: | 377 if self.path in self.server.image_set: |
245 self.send_file(self.path) | 378 self.send_file(self.path) |
246 return | 379 return |
247 | 380 |
248 # If no file to send was found, just give the standard 404 | 381 # If no file to send was found, just give the standard 404 |
249 self.send_error(404) | 382 self.send_error(404) |
250 | 383 |
384 def do_POST(self): | |
385 if self.path == '/set_hash': | |
386 content_length = int(self.headers['Content-length']) | |
387 request_data = json.loads(self.rfile.read(content_length)) | |
388 self.server.expectations_manager.use_hash_of(request_data['path']) | |
389 self.send_response(200) | |
390 self.send_header('Content-type', 'application/json') | |
391 self.end_headers() | |
392 self.wfile.write('{"success":true}') | |
393 return | |
251 | 394 |
252 def run_server(skpdiff_output_path, port=8080): | 395 # If the we have no handler for this path, give em' the 404 |
396 self.send_error(404) | |
397 | |
398 | |
399 def run_server(expectations_manager, port=8080): | |
253 # Preload the skpdiff results file. This is so we can perform some | 400 # Preload the skpdiff results file. This is so we can perform some |
254 # processing on it. | 401 # processing on it. |
255 skpdiff_output_json = '' | 402 skpdiff_output_json = '' |
256 with open(skpdiff_output_path, 'rb') as records_file: | 403 with open(expectations_manager.skpdiff_output_path, 'rb') as records_file: |
257 skpdiff_output_json = records_file.read() | 404 skpdiff_output_json = records_file.read() |
258 | 405 |
259 # It's important to parse the results file so that we can make a set of | 406 # It's important to parse the results file so that we can make a set of |
260 # images that the web page might request. | 407 # images that the web page might request. |
261 skpdiff_records = json.loads(skpdiff_output_json)['records'] | 408 skpdiff_records = json.loads(skpdiff_output_json)['records'] |
262 image_set = get_image_set_from_skpdiff(skpdiff_records) | 409 image_set = get_image_set_from_skpdiff(skpdiff_records) |
263 | 410 |
411 for record in skpdiff_records: | |
412 record['device'] = os.path.basename(record['baselinePath']) | |
413 | |
264 # Add JSONP padding to the JSON because the web page expects it. It expects | 414 # Add JSONP padding to the JSON because the web page expects it. It expects |
265 # it because it was designed to run with or without a web server. Without a | 415 # it because it was designed to run with or without a web server. Without a |
266 # web server, the only way to load JSON is with JSONP. | 416 # web server, the only way to load JSON is with JSONP. |
267 skpdiff_output_json = 'var SkPDiffRecords = ' + skpdiff_output_json | 417 skpdiff_output_json = ('var SkPDiffRecords = ' + |
418 json.dumps({'records': skpdiff_records}) + ';') | |
268 | 419 |
269 # Do not bind to interfaces other than localhost because the server will | 420 # Do not bind to interfaces other than localhost because the server will |
270 # attempt to serve files relative to the root directory as a last resort | 421 # attempt to serve files relative to the root directory as a last resort |
271 # before 404ing. This means all of your files can be accessed from this | 422 # before 404ing. This means all of your files can be accessed from this |
272 # server, so DO NOT let this server listen to anything but localhost. | 423 # server, so DO NOT let this server listen to anything but localhost. |
273 server_address = ('127.0.0.1', port) | 424 server_address = ('127.0.0.1', port) |
274 http_server = BaseHTTPServer.HTTPServer(server_address, SkPDiffHandler) | 425 http_server = BaseHTTPServer.HTTPServer(server_address, SkPDiffHandler) |
275 http_server.image_set = image_set | 426 http_server.image_set = image_set |
276 http_server.skpdiff_output_json = skpdiff_output_json | 427 http_server.skpdiff_output_json = skpdiff_output_json |
277 print('Navigate thine browser to: http://{}:{}'.format(*server_address)) | 428 http_server.expectations_manager = expectations_manager |
429 print('Navigate thine browser to: http://{}:{}/'.format(*server_address)) | |
278 http_server.serve_forever() | 430 http_server.serve_forever() |
279 | 431 |
280 | 432 |
281 def main(): | 433 def main(): |
282 parser = argparse.ArgumentParser() | 434 parser = argparse.ArgumentParser() |
283 parser.add_argument('--port', '-p', metavar='PORT', | 435 parser.add_argument('--port', '-p', metavar='PORT', |
284 type=int, | 436 type=int, |
285 default=8080, | 437 default=8080, |
286 help='port to bind the server to; ' + | 438 help='port to bind the server to; ' + |
287 'defaults to %(default)s', | 439 'defaults to %(default)s', |
(...skipping 25 matching lines...) Expand all Loading... | |
313 'defaults to out/Release/skpdiff or out/Default/skpdiff' | 465 'defaults to out/Release/skpdiff or out/Default/skpdiff' |
314 ) | 466 ) |
315 | 467 |
316 args = vars(parser.parse_args()) # Convert args into a python dict | 468 args = vars(parser.parse_args()) # Convert args into a python dict |
317 | 469 |
318 # Make sure we have access to an skpdiff binary | 470 # Make sure we have access to an skpdiff binary |
319 skpdiff_path = get_skpdiff_path(args['skpdiff_path']) | 471 skpdiff_path = get_skpdiff_path(args['skpdiff_path']) |
320 if skpdiff_path is None: | 472 if skpdiff_path is None: |
321 sys.exit(1) | 473 sys.exit(1) |
322 | 474 |
323 # Create a temporary file tree that makes sense for skpdiff.to operate on | |
324 image_output_dir = tempfile.mkdtemp('skpdiff') | |
325 expected_image_dir = os.path.join(image_output_dir, 'expected') | |
326 actual_image_dir = os.path.join(image_output_dir, 'actual') | |
327 os.mkdir(expected_image_dir) | |
328 os.mkdir(actual_image_dir) | |
329 | |
330 # Print out the paths of things for easier debugging | 475 # Print out the paths of things for easier debugging |
331 print('script dir :', SCRIPT_DIR) | 476 print('script dir :', SCRIPT_DIR) |
332 print('tools dir :', TOOLS_DIR) | 477 print('tools dir :', TOOLS_DIR) |
333 print('root dir :', SKIA_ROOT_DIR) | 478 print('root dir :', SKIA_ROOT_DIR) |
334 print('expectations dir :', args['expectations_dir']) | 479 print('expectations dir :', args['expectations_dir']) |
335 print('skpdiff path :', skpdiff_path) | 480 print('skpdiff path :', skpdiff_path) |
336 print('tmp dir :', image_output_dir) | |
337 print('expected image dir :', expected_image_dir) | |
338 print('actual image dir :', actual_image_dir) | |
339 | 481 |
340 # Download expected and actual images that differed into the temporary file | 482 expectations_manager = ExpectationsManager(args['expectations_dir'], |
341 # tree. | 483 args['expected'], |
342 download_changed_images(args['expectations_dir'], | 484 args['updated'], |
343 args['expected'], args['updated'], | 485 skpdiff_path) |
344 expected_image_dir, actual_image_dir) | |
345 | 486 |
346 # Invoke skpdiff with our downloaded images and place its results in the | 487 run_server(expectations_manager, port=args['port']) |
347 # temporary directory. | |
348 skpdiff_output_path = os.path.join(image_output_dir, 'skpdiff_output.json') | |
349 skpdiff_cmd = SKPDIFF_INVOKE_FORMAT.format(skpdiff_path, | |
350 skpdiff_output_path, | |
351 expected_image_dir, | |
352 actual_image_dir) | |
353 os.system(skpdiff_cmd) | |
354 | |
355 run_server(skpdiff_output_path, port=args['port']) | |
356 | 488 |
357 if __name__ == '__main__': | 489 if __name__ == '__main__': |
358 main() | 490 main() |
OLD | NEW |