diff options
author | 2013-08-07 18:06:39 +0000 | |
---|---|---|
committer | 2013-08-07 18:06:39 +0000 | |
commit | 74c5ab19fd69d3c030f53e5b64493d548b74f916 (patch) | |
tree | bd57d431e3817665da5872a066f03ec5a2cf283c /tools/skpdiff/skpdiff_server.py | |
parent | e57c62d039cbd67a4e52776b3e95c5d002b818d2 (diff) |
add ui for mutli-rebaselining
R=epoger@google.com
Review URL: https://codereview.chromium.org/22580004
git-svn-id: http://skia.googlecode.com/svn/trunk@10618 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'tools/skpdiff/skpdiff_server.py')
-rwxr-xr-x | tools/skpdiff/skpdiff_server.py | 107 |
1 files changed, 74 insertions, 33 deletions
diff --git a/tools/skpdiff/skpdiff_server.py b/tools/skpdiff/skpdiff_server.py index 14035403a2..053291af9a 100755 --- a/tools/skpdiff/skpdiff_server.py +++ b/tools/skpdiff/skpdiff_server.py @@ -99,6 +99,8 @@ def download_gm_image(image_name, image_path, hash_val): @param image_path Path to place the image. @param hash_val The hash value of the image. """ + if hash_val is None: + return # Separate the test name from a image name image_match = IMAGE_FILENAME_RE.match(image_name) @@ -174,14 +176,18 @@ class GMInstance: - image_name = the GM test name and config - expected_hash = the current expected hash value - actual_hash = the actual hash value + - is_rebaselined = True if actual_hash is what is currently in the expected + results file, False otherwise. """ def __init__(self, device_name, image_name, - expected_hash, actual_hash): + expected_hash, actual_hash, + is_rebaselined): self.device_name = device_name self.image_name = image_name self.expected_hash = expected_hash self.actual_hash = actual_hash + self.is_rebaselined = is_rebaselined class ExpectationsManager: @@ -228,13 +234,14 @@ class ExpectationsManager: # Invoke skpdiff with our downloaded images and place its results in the # temporary directory. - self.skpdiff_output_path = os.path.join(image_output_dir, + self._skpdiff_output_path = os.path.join(image_output_dir, 'skpdiff_output.json') skpdiff_cmd = SKPDIFF_INVOKE_FORMAT.format(self._skpdiff_path, - self.skpdiff_output_path, + self._skpdiff_output_path, expected_image_dir, actual_image_dir) os.system(skpdiff_cmd) + self._load_skpdiff_output() def _get_expectations(self): @@ -267,11 +274,25 @@ class ExpectationsManager: with open(updated_file_path, 'rb') as updated_file: updated_contents = updated_file.read() + # Read the expected results on disk to determine what we've + # already rebaselined. + commited_contents = None + with open(expected_file_path, 'rb') as expected_file: + commited_contents = expected_file.read() + # Find all expectations that did not match. expected_diff = differ.GenerateDiffDictFromStrings( expected_contents, updated_contents) + # Generate a set of images that have already been rebaselined + # onto disk. + rebaselined_diff = differ.GenerateDiffDictFromStrings( + expected_contents, + commited_contents) + + rebaselined_set = set(rebaselined_diff.keys()) + # The name of the device corresponds to the name of the folder # we are in. device_name = os.path.basename(root) @@ -280,7 +301,18 @@ class ExpectationsManager: for image_name, hashes in expected_diff.iteritems(): self._expectations.append( GMInstance(device_name, image_name, - hashes['old'], hashes['new'])) + hashes['old'], hashes['new'], + image_name in rebaselined_set)) + + def _load_skpdiff_output(self): + """Loads the results of skpdiff and annotates them with whether they + have already been rebaselined or not. The resulting data is store in + self.skpdiff_records.""" + self.skpdiff_records = None + with open(self._skpdiff_output_path, 'rb') as skpdiff_output_file: + self.skpdiff_records = json.load(skpdiff_output_file)['records'] + for record in self.skpdiff_records: + record['isRebaselined'] = self.image_map[record['baselinePath']][1].is_rebaselined def _download_expectation_images(self, expected_image_dir, actual_image_dir): @@ -346,23 +378,36 @@ class ExpectationsManager: # Write it out to disk using gm_json to keep the formatting consistent. gm_json.WriteToFile(expectations, json_path) - def use_hash_of(self, image_path): - """Determine the hash of the image at the path using the records, and - set it as the expected hash for its device and image config. + def commit_rebaselines(self, rebaselines): + """Sets the expected results file to use the hashes of the images in + the rebaselines list. If a expected result image is not in rebaselines + at all, the old hash will be used. - @param image_path The path of the image as it was stored in the output - of skpdiff_path + @param rebaselines A list of image paths to use the hash of. """ + # Reset all expectations to their old hashes because some of them may + # have been set to the new hash by a previous call to this function. + for expectation in self._expectations: + expectation.is_rebaselined = False + self._set_expected_hash(expectation.device_name, + expectation.image_name, + expectation.expected_hash) + + # Take all the images to rebaseline + for image_path in rebaselines: + # Get the metadata about the image at the path. + is_actual, expectation = self.image_map[image_path] - # Get the metadata about the image at the path. - is_actual, expectation = self.image_map[image_path] + expectation.is_rebaselined = is_actual + expectation_hash = expectation.actual_hash if is_actual else\ + expectation.expected_hash - expectation_hash = expectation.actual_hash if is_actual else\ - expectation.expected_hash + # Write out that image's hash directly to the expected results file. + self._set_expected_hash(expectation.device_name, + expectation.image_name, + expectation_hash) - # Write out that image's hash directly to the expected results file. - self._set_expected_hash(expectation.device_name, expectation.image_name, - expectation_hash) + self._load_skpdiff_output() class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): @@ -410,7 +455,15 @@ class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.send_response(200) self.send_header('Content-type', MIME_TYPE_MAP['json']) self.end_headers() - self.wfile.write(self.server.skpdiff_output_json) + + # Add JSONP padding to the JSON because the web page expects it. It + # expects it because it was designed to run with or without a web + # server. Without a web server, the only way to load JSON is with + # JSONP. + skpdiff_records = self.server.expectations_manager.skpdiff_records + self.wfile.write('var SkPDiffRecords = ') + json.dump({'records': skpdiff_records}, self.wfile) + self.wfile.write(';') return # Attempt to send static asset files first. @@ -427,10 +480,11 @@ class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): self.send_error(404) def do_POST(self): - if self.path == '/set_hash': + if self.path == '/commit_rebaselines': content_length = int(self.headers['Content-length']) request_data = json.loads(self.rfile.read(content_length)) - self.server.expectations_manager.use_hash_of(request_data['path']) + rebaselines = request_data['rebaselines'] + self.server.expectations_manager.commit_rebaselines(rebaselines) self.send_response(200) self.send_header('Content-type', 'application/json') self.end_headers() @@ -442,23 +496,11 @@ class SkPDiffHandler(BaseHTTPServer.BaseHTTPRequestHandler): def run_server(expectations_manager, port=8080): - # Preload the skpdiff results file. This is so we can perform some - # processing on it. - skpdiff_output_json = '' - with open(expectations_manager.skpdiff_output_path, 'rb') as records_file: - skpdiff_output_json = records_file.read() - # It's important to parse the results file so that we can make a set of # images that the web page might request. - skpdiff_records = json.loads(skpdiff_output_json)['records'] + skpdiff_records = expectations_manager.skpdiff_records image_set = get_image_set_from_skpdiff(skpdiff_records) - # Add JSONP padding to the JSON because the web page expects it. It expects - # it because it was designed to run with or without a web server. Without a - # web server, the only way to load JSON is with JSONP. - skpdiff_output_json = ('var SkPDiffRecords = ' + - json.dumps({'records': skpdiff_records}) + ';') - # Do not bind to interfaces other than localhost because the server will # attempt to serve files relative to the root directory as a last resort # before 404ing. This means all of your files can be accessed from this @@ -466,7 +508,6 @@ def run_server(expectations_manager, port=8080): server_address = ('127.0.0.1', port) http_server = BaseHTTPServer.HTTPServer(server_address, SkPDiffHandler) http_server.image_set = image_set - http_server.skpdiff_output_json = skpdiff_output_json http_server.expectations_manager = expectations_manager print('Navigate thine browser to: http://{}:{}/'.format(*server_address)) http_server.serve_forever() |