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

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

Issue 24274003: Create HTTP-based GM results viewer. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | gm/rebaseline_server/server.py » ('j') | gm/rebaseline_server/server.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:executable
+ *
OLDNEW
(Empty)
1 #!/usr/bin/python
2
3 '''
4 Copyright 2013 Google Inc.
5
6 Use of this source code is governed by a BSD-style license that can be
7 found in the LICENSE file.
8 '''
9
10 '''
11 Repackage expected/actual GM results as needed by our HTML rebaseline viewer.
12 '''
13
14 # System-level imports
15 import fnmatch
16 import json
17 import os
18 import re
19 import sys
20
21 # Imports from within Skia
22 #
23 # We need to add the 'gm' directory, so that we can import gm_json.py within
24 # that directory. That script allows us to parse the actual-results.json file
25 # written out by the GM tool.
26 # Make sure that the 'gm' dir is in the PYTHONPATH, but add it at the *end*
27 # so any dirs that are already in the PYTHONPATH will be preferred.
28 GM_DIRECTORY = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
29 if GM_DIRECTORY not in sys.path:
30 sys.path.append(GM_DIRECTORY)
31 import gm_json
32
33 IMAGE_FILENAME_RE = re.compile(gm_json.IMAGE_FILENAME_PATTERN)
34
35 class Results(object):
36 """ Loads actual and expected results from all builders, supplying combined
37 reports as requested. """
38
39 def __init__(self, actuals_root, expected_root):
40 """
41 params:
42 actuals_root: root directory containing all actual-results.json files
43 expected_root: root directory containing all expected-results.json files
44 """
45 self._actual_builder_dicts = Results._GetDictsFromRoot(actuals_root)
46 self._expected_builder_dicts = Results._GetDictsFromRoot(expected_root)
47
48 @staticmethod
49 def _GetDictsFromRoot(root, pattern='*.json'):
50 """Read all JSON dictionaries within a directory tree, returning them within
51 a meta-dictionary (keyed by the builder type for each dictionary).
52
53 params:
54 root: path to root of directory tree
55 pattern: which files to read within root (fnmatch-style pattern)
56 """
57 meta_dict = {}
58 for dirpath, dirnames, filenames in os.walk(root):
59 for matching_filename in fnmatch.filter(filenames, pattern):
60 builder = os.path.basename(dirpath)
61 # EPOGER: make this check configurable?
62 if builder.endswith('-Trybot'):
63 continue
64 fullpath = os.path.join(dirpath, matching_filename)
65 meta_dict[builder] = gm_json.LoadFromFile(fullpath)
66 return meta_dict
67
68 def OfType(self, result_type):
69 """Returns an array of all tests, across all builders, of a certain
70 result_type. Returns the array in this form:
71
72 [
73 {
74 "builder": "Test-Mac10.6-MacMini4.1-GeForce320M-x86-Debug",
75 "test": "bigmatrix",
76 "config": "8888",
77 "expectedHashType": "bitmap-64bitMD5",
78 "expectedHashDigest": "10894408024079689926",
79 "actualHashType": "bitmap-64bitMD5",
80 "actualHashDigest": "2409857384569",
81 },
82 ...
83 ]
84
85 params:
86 result_type: string describing result type, such as 'failed'; should be
87 one of the gm_json.JSONKEY_ACTUALRESULTS_* strings.
88 """
89 # EPOGER: validate that result_type is one of the gm_json.JSONKEY_ACTUALRESU LTS_* strings?
90 array = []
91 for builder in sorted(self._actual_builder_dicts.keys()):
92 results_of_this_type = self._actual_builder_dicts[builder][gm_json.JSONKEY _ACTUALRESULTS][result_type]
93 if not results_of_this_type:
94 continue
95 for image_name in sorted(results_of_this_type.keys()):
96 actual_image = results_of_this_type[image_name]
97 try:
98 # EPOGER: assumes a single allowed digest per test
99 expected_image = self._expected_builder_dicts[builder][gm_json.JSONKEY _EXPECTEDRESULTS][image_name][gm_json.JSONKEY_EXPECTEDRESULTS_ALLOWEDDIGESTS][0]
100 except (KeyError, TypeError):
101 # It's OK to find no expectations, if this is a NOCOMPARISON test!
102 # But we still want to look for expectations, in case someone has
103 # committed expectations and the bots just haven't tested them yet.
104 if result_type != gm_json.JSONKEY_ACTUALRESULTS_NOCOMPARISON:
105 raise
106 expected_image = [None, None]
107
108 # If this test was recently rebaselined, it will remain in the "failed"
109 # set of actuals until all the bots have cycled (although the
110 # expectations have indeed been set from the most recent actuals).
111 # Weed out such cases.
112 # EPOGER: make this optional?
113 if expected_image == actual_image:
114 continue
115
116 # EPOGER: call re.match just once for both test and config?
117 array.append({
118 "builder": builder,
119 "test": IMAGE_FILENAME_RE.match(image_name).group(1),
120 "config": IMAGE_FILENAME_RE.match(image_name).group(2),
121 "actualHashType": actual_image[0],
122 "actualHashDigest": str(actual_image[1]),
123 "expectedHashType": expected_image[0],
124 "expectedHashDigest": str(expected_image[1]),
125 })
126 return array
127
128
129 if __name__ == '__main__':
130 # EPOGER: actual_root should point at a separate checkout of gm-actual
131 # EPOGER: expected_root should point at a separately checked-out expectations/ gm workspace
132 results = Results(
133 actuals_root='/usr/local/google/home/epoger/src/rebaseline-mockup/gm-actua l',
134 expected_root=os.path.join(GM_DIRECTORY, os.pardir, 'expectations', 'gm'))
135 for result_type in ['failed', 'failure-ignored', 'no-comparison']:
136 gm_json.WriteToFile(results.OfType(result_type), os.path.join('EPOGER-result s', result_type + '.json'))
OLDNEW
« no previous file with comments | « no previous file | gm/rebaseline_server/server.py » ('j') | gm/rebaseline_server/server.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698