OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Utilities for managing I-Spy test results in Google Cloud Storage.""" | 5 """Utilities for managing I-Spy test results in Google Cloud Storage.""" |
6 | 6 |
7 import collections | 7 import collections |
8 import itertools | 8 import itertools |
9 import json | 9 import json |
10 import os | 10 import os |
11 import sys | 11 import sys |
12 | 12 |
13 import image_tools | 13 import image_tools |
14 | 14 |
15 | 15 |
16 _INVALID_EXPECTATION_CHARS = ['/', '\\', ' ', '"', '\''] | |
17 | |
18 | |
19 def IsValidExpectationName(expectationName): | |
craigdh
2013/12/03 00:30:50
return any(c in _INVALID_EXPECTATION_CHARS for c i
craigdh
2013/12/03 00:30:50
expectationName -> expectation_name
baxley
2013/12/03 00:53:16
Done.
baxley
2013/12/03 00:53:16
Done.
| |
20 for char in _INVALID_EXPECTATION_CHARS: | |
21 if expectationName.find(char) != -1: | |
22 return False | |
23 return True | |
24 | |
25 | |
16 def GetExpectationPath(expectation, file_name=''): | 26 def GetExpectationPath(expectation, file_name=''): |
17 """Get the path to a test file in the given test run and expectation. | 27 """Get the path to a test file in the given test run and expectation. |
18 | 28 |
19 Args: | 29 Args: |
20 expectation: name of the expectation. | 30 expectation: name of the expectation. |
21 file_name: name of the file. | 31 file_name: name of the file. |
22 | 32 |
23 Returns: | 33 Returns: |
24 the path as a string relative to the bucket. | 34 the path as a string relative to the bucket. |
25 """ | 35 """ |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
89 def GenerateExpectation(self, expectation, images): | 99 def GenerateExpectation(self, expectation, images): |
90 """Creates and uploads an expectation to GS from a set of images and name. | 100 """Creates and uploads an expectation to GS from a set of images and name. |
91 | 101 |
92 This method generates a mask from the uploaded images, then | 102 This method generates a mask from the uploaded images, then |
93 uploads the mask and first of the images to GS as a expectation. | 103 uploads the mask and first of the images to GS as a expectation. |
94 | 104 |
95 Args: | 105 Args: |
96 expectation: name for this expectation, any existing expectation with the | 106 expectation: name for this expectation, any existing expectation with the |
97 name will be replaced. | 107 name will be replaced. |
98 images: a list of RGB encoded PIL.Images | 108 images: a list of RGB encoded PIL.Images |
109 | |
110 Raises: | |
111 ValueError: if the expectation name is invalid. | |
99 """ | 112 """ |
113 if not IsValidExpectationName(expectation): | |
114 raise ValueError("Expectation contains an illegal value: %s." % | |
115 str(_INVALID_EXPECTATION_CHARS)) | |
116 | |
100 mask = image_tools.InflateMask(image_tools.CreateMask(images), 7) | 117 mask = image_tools.InflateMask(image_tools.CreateMask(images), 7) |
101 self.UploadImage( | 118 self.UploadImage( |
102 GetExpectationPath(expectation, 'expected.png'), images[0]) | 119 GetExpectationPath(expectation, 'expected.png'), images[0]) |
103 self.UploadImage(GetExpectationPath(expectation, 'mask.png'), mask) | 120 self.UploadImage(GetExpectationPath(expectation, 'mask.png'), mask) |
104 | 121 |
105 def PerformComparison(self, test_run, expectation, actual): | 122 def PerformComparison(self, test_run, expectation, actual): |
106 """Runs an image comparison, and uploads discrepancies to GS. | 123 """Runs an image comparison, and uploads discrepancies to GS. |
107 | 124 |
108 Args: | 125 Args: |
109 test_run: the name of the test_run. | 126 test_run: the name of the test_run. |
110 expectation: the name of the expectation to use for comparison. | 127 expectation: the name of the expectation to use for comparison. |
111 actual: an RGB-encoded PIL.Image that is the actual result. | 128 actual: an RGB-encoded PIL.Image that is the actual result. |
112 | 129 |
113 Raises: | 130 Raises: |
114 cloud_bucket.NotFoundError: if the given expectation is not found. | 131 cloud_bucket.NotFoundError: if the given expectation is not found. |
132 ValueError: if the expectation name is invalid. | |
115 """ | 133 """ |
134 if not IsValidExpectationName(expectation): | |
135 raise ValueError("Expectation name contains an illegal character: %s." % | |
136 str(_INVALID_EXPECTATION_CHARS)) | |
137 | |
116 expectation_tuple = self.GetExpectation(expectation) | 138 expectation_tuple = self.GetExpectation(expectation) |
117 if not image_tools.SameImage( | 139 if not image_tools.SameImage( |
118 actual, expectation_tuple.expected, mask=expectation_tuple.mask): | 140 actual, expectation_tuple.expected, mask=expectation_tuple.mask): |
119 self.UploadImage( | 141 self.UploadImage( |
120 GetFailurePath(test_run, expectation, 'actual.png'), actual) | 142 GetFailurePath(test_run, expectation, 'actual.png'), actual) |
121 diff, diff_pxls = image_tools.VisualizeImageDifferences( | 143 diff, diff_pxls = image_tools.VisualizeImageDifferences( |
122 expectation_tuple.expected, actual, mask=expectation_tuple.mask) | 144 expectation_tuple.expected, actual, mask=expectation_tuple.mask) |
123 self.UploadImage(GetFailurePath(test_run, expectation, 'diff.png'), diff) | 145 self.UploadImage(GetFailurePath(test_run, expectation, 'diff.png'), diff) |
124 self.cloud_bucket.UploadFile( | 146 self.cloud_bucket.UploadFile( |
125 GetFailurePath(test_run, expectation, 'info.txt'), | 147 GetFailurePath(test_run, expectation, 'info.txt'), |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 self.cloud_bucket.RemoveFile(path) | 213 self.cloud_bucket.RemoveFile(path) |
192 | 214 |
193 def GenerateExpectationPinkOut(self, expectation, images, pint_out, rgb): | 215 def GenerateExpectationPinkOut(self, expectation, images, pint_out, rgb): |
194 """Uploads an ispy-test to GS with the pink_out workaround. | 216 """Uploads an ispy-test to GS with the pink_out workaround. |
195 | 217 |
196 Args: | 218 Args: |
197 expectation: the name of the expectation to be uploaded. | 219 expectation: the name of the expectation to be uploaded. |
198 images: a json encoded list of base64 encoded png images. | 220 images: a json encoded list of base64 encoded png images. |
199 pink_out: an image. | 221 pink_out: an image. |
200 RGB: a json list representing the RGB values of a color to mask out. | 222 RGB: a json list representing the RGB values of a color to mask out. |
223 | |
224 Raises: | |
225 ValueError: if expectation name is invalid. | |
201 """ | 226 """ |
227 if not IsValidExpectationName(expectation): | |
228 raise ValueError("Expectation name contains an illegal character: %s." % | |
229 str(_INVALID_EXPECTATION_CHARS)) | |
230 | |
202 # convert the pink_out into a mask | 231 # convert the pink_out into a mask |
203 black = (0, 0, 0, 255) | 232 black = (0, 0, 0, 255) |
204 white = (255, 255, 255, 255) | 233 white = (255, 255, 255, 255) |
205 pink_out.putdata( | 234 pink_out.putdata( |
206 [black if px == (rgb[0], rgb[1], rgb[2], 255) else white | 235 [black if px == (rgb[0], rgb[1], rgb[2], 255) else white |
207 for px in pink_out.getdata()]) | 236 for px in pink_out.getdata()]) |
208 mask = image_tools.CreateMask(images) | 237 mask = image_tools.CreateMask(images) |
209 mask = image_tools.InflateMask(image_tools.CreateMask(images), 7) | 238 mask = image_tools.InflateMask(image_tools.CreateMask(images), 7) |
210 combined_mask = image_tools.AddMasks([mask, pink_out]) | 239 combined_mask = image_tools.AddMasks([mask, pink_out]) |
211 self.UploadImage(GetExpectationPath(expectation, 'expected.png'), images[0]) | 240 self.UploadImage(GetExpectationPath(expectation, 'expected.png'), images[0]) |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 | 283 |
255 Args: | 284 Args: |
256 prefix: the prefix to filter files in GS by. | 285 prefix: the prefix to filter files in GS by. |
257 | 286 |
258 Returns: | 287 Returns: |
259 a list containing urls to all objects that started with | 288 a list containing urls to all objects that started with |
260 the prefix. | 289 the prefix. |
261 """ | 290 """ |
262 return self.cloud_bucket.GetAllPaths(prefix) | 291 return self.cloud_bucket.GetAllPaths(prefix) |
263 | 292 |
OLD | NEW |