blob: 90df4a661271ef1e9b8c15298ba698b62150fab6 [file] [log] [blame]
borenet@google.com6dd15452013-07-11 18:05:25 +00001#!/usr/bin/python
2
3# Copyright (c) 2013 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7
8""" Look through skia-autogen, searching for all checksums which should have
9corresponding files in Google Storage, and verify that those files exist. """
10
11
12import json
13import posixpath
14import re
15import subprocess
16import sys
17
18
epoger@google.com61822a22013-07-16 18:56:32 +000019# TODO(borenet): Replace some/all of these with constants from gm/gm_json.py
borenet@google.com6dd15452013-07-11 18:05:25 +000020AUTOGEN_URL = 'http://skia-autogen.googlecode.com/svn/gm-actual'
21GS_URL = 'gs://chromium-skia-gm/gm'
22TEST_NAME_PATTERN = re.compile('(\S+)_(\S+).png')
23
24
25def FileNameToGSURL(filename, hash_type, hash_value):
26 """ Convert a file name given in a checksum file to the URL of the
27 corresponding image file in Google Storage.
28
29 filename: string; the file name to convert. Takes the form specified by
30 TEST_NAME_PATTERN.
31 hash_type: string; the type of the checksum.
32 hash_value: string; the checksum itself.
33 """
34 test_name = TEST_NAME_PATTERN.match(filename).group(1)
35 if not test_name:
36 raise Exception('Invalid test name for file: %s' % filename)
37 return '%s/%s/%s/%s.png' % (GS_URL, hash_type, test_name, hash_value)
38
39
40def FindURLSInJSON(json_file, gs_urls):
41 """ Extract Google Storage URLs from a JSON file in svn, adding them to the
42 gs_urls dictionary.
43
44 json_file: string; URL of the JSON file.
45 gs_urls: dict; stores Google Storage URLs as keys and lists of the JSON files
46 which reference them.
47
48 Example gs_urls:
49 { 'gs://chromium-skia-gm/gm/sometest/12345.png': [
epoger@google.comfd040112013-08-20 16:21:55 +000050 'http://skia-autogen.googlecode.com/svn/gm-actual/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/actual-results.json',
51 'http://skia-autogen.googlecode.com/svn/gm-actual/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/actual-results.json',
borenet@google.com6dd15452013-07-11 18:05:25 +000052 ]
53 }
54 """
55 output = subprocess.check_output(['svn', 'cat', json_file])
56 json_content = json.loads(output)
57 for dict_type in ['actual-results']:
58 for result_type in json_content[dict_type]:
59 if json_content[dict_type][result_type]:
60 for result in json_content[dict_type][result_type].keys():
61 hash_type, hash_value = json_content[dict_type][result_type][result]
62 gs_url = FileNameToGSURL(result, hash_type, str(hash_value))
63 if gs_urls.get(gs_url):
64 gs_urls[gs_url].append(json_file)
65 else:
66 gs_urls[gs_url] = [json_file]
67
68
69def _FindJSONFiles(url, json_files):
70 """ Helper function for FindJsonFiles. Recursively explore the repository,
71 adding JSON files to a list.
72
73 url: string; URL of the repository (or subdirectory thereof) to explore.
74 json_files: list to which JSON file urls will be added.
75 """
76 proc = subprocess.Popen(['svn', 'ls', url], stdout=subprocess.PIPE,
77 stderr=subprocess.STDOUT)
78 if proc.wait() != 0:
79 raise Exception('Failed to list svn directory.')
80 output = proc.communicate()[0].splitlines()
81 subdirs = []
82 for item in output:
83 if item.endswith(posixpath.sep):
84 subdirs.append(item)
85 elif item.endswith('.json'):
86 json_files.append(posixpath.join(url, item))
87 else:
88 print 'Warning: ignoring %s' % posixpath.join(url, item)
89 for subdir in subdirs:
90 _FindJSONFiles(posixpath.join(url, subdir), json_files)
91
92
93def FindJSONFiles(url):
94 """ Recursively explore the given repository and return a list of the JSON
95 files it contains.
96
97 url: string; URL of the repository to explore.
98 """
99 print 'Searching for JSON files in %s' % url
100 json_files = []
101 _FindJSONFiles(url, json_files)
102 return json_files
103
104
105def FindURLs(url):
106 """ Find Google Storage URLs inside of JSON files in the given repository.
107 Returns a dictionary whose keys are Google Storage URLs and values are lists
108 of the JSON files which reference them.
109
110 url: string; URL of the repository to explore.
111
112 Example output:
113 { 'gs://chromium-skia-gm/gm/sometest/12345.png': [
epoger@google.comfd040112013-08-20 16:21:55 +0000114 'http://skia-autogen.googlecode.com/svn/gm-actual/Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug/actual-results.json',
115 'http://skia-autogen.googlecode.com/svn/gm-actual/Test-Mac10.8-MacMini4.1-GeForce320M-x86-Debug/actual-results.json',
borenet@google.com6dd15452013-07-11 18:05:25 +0000116 ]
117 }
118 """
119 gs_urls = {}
120 for json_file in FindJSONFiles(url):
121 print 'Looking for checksums in %s' % json_file
122 FindURLSInJSON(json_file, gs_urls)
123 return gs_urls
124
125
126def VerifyURL(url):
127 """ Verify that the given URL exists.
128
129 url: string; the Google Storage URL of the image file in question.
130 """
131 proc = subprocess.Popen(['gsutil', 'ls', url], stdout=subprocess.PIPE,
132 stderr=subprocess.STDOUT)
133 if proc.wait() != 0:
134 return False
135 return True
136
137
138def VerifyURLs(urls):
139 """ Verify that each of the given URLs exists. Return a list of which URLs do
140 not exist.
141
142 urls: dictionary; URLs of the image files in question.
143 """
144 print 'Verifying that images exist for URLs...'
145 missing = []
146 for url in urls.iterkeys():
147 if not VerifyURL(url):
148 print 'Missing: %s, referenced by: \n %s' % (url, '\n '.join(urls[url]))
149 missing.append(url)
150 return missing
151
152
153def Main():
154 urls = FindURLs(AUTOGEN_URL)
155 missing = VerifyURLs(urls)
156 if missing:
157 print 'Found %d Missing files.' % len(missing)
158 return 1
159
160
161if __name__ == '__main__':
162 sys.exit(Main())