Add ability to output ImageBaseGSUrl to render_picture and use in rebaseline server.
BUG=skia:2230
R=epoger@google.com
Author: rmistry@google.com
Review URL: https://codereview.chromium.org/479613002
diff --git a/gm/gm_json.py b/gm/gm_json.py
index 1a53997..109bba3 100644
--- a/gm/gm_json.py
+++ b/gm/gm_json.py
@@ -94,6 +94,7 @@
JSONKEY_IMAGE_FILEPATH = 'filepath'
JSONKEY_SOURCE_TILEDIMAGES = 'tiled-images'
JSONKEY_SOURCE_WHOLEIMAGE = 'whole-image'
+JSONKEY_IMAGE_BASE_GS_URL = 'image-base-gs-url'
# Root directory where the buildbots store their actually-generated images...
diff --git a/gm/rebaseline_server/compare_configs.py b/gm/rebaseline_server/compare_configs.py
index 73a5570..36c7f86 100755
--- a/gm/rebaseline_server/compare_configs.py
+++ b/gm/rebaseline_server/compare_configs.py
@@ -151,7 +151,8 @@
try:
image_pair = imagepair.ImagePair(
image_diff_db=self._image_diff_db,
- base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+ imageA_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+ imageB_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
imageA_relative_url=configA_image_relative_url,
imageB_relative_url=configB_image_relative_url,
extra_columns=extra_columns_dict)
diff --git a/gm/rebaseline_server/compare_rendered_pictures.py b/gm/rebaseline_server/compare_rendered_pictures.py
index 399117d..73cb36b 100755
--- a/gm/rebaseline_server/compare_rendered_pictures.py
+++ b/gm/rebaseline_server/compare_rendered_pictures.py
@@ -268,18 +268,25 @@
self._validate_dict_version(dictB)
dictB_results = self.get_default(dictB, {}, setB_section)
+ image_A_base_url = self.get_default(
+ setA_dicts, self._image_base_gs_url, dict_path,
+ gm_json.JSONKEY_IMAGE_BASE_GS_URL)
+ image_B_base_url = self.get_default(
+ setB_dicts, self._image_base_gs_url, dict_path,
+ gm_json.JSONKEY_IMAGE_BASE_GS_URL)
+
# get the builders and render modes for each set
- builder_A = self.get_default(dictA, None,
- gm_json.JSONKEY_DESCRIPTIONS,
+ builder_A = self.get_default(dictA, None,
+ gm_json.JSONKEY_DESCRIPTIONS,
gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
- render_mode_A = self.get_default(dictA, None,
- gm_json.JSONKEY_DESCRIPTIONS,
+ render_mode_A = self.get_default(dictA, None,
+ gm_json.JSONKEY_DESCRIPTIONS,
gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
- builder_B = self.get_default(dictB, None,
- gm_json.JSONKEY_DESCRIPTIONS,
+ builder_B = self.get_default(dictB, None,
+ gm_json.JSONKEY_DESCRIPTIONS,
gm_json.JSONKEY_DESCRIPTIONS_BUILDER)
- render_mode_B = self.get_default(dictB, None,
- gm_json.JSONKEY_DESCRIPTIONS,
+ render_mode_B = self.get_default(dictB, None,
+ gm_json.JSONKEY_DESCRIPTIONS,
gm_json.JSONKEY_DESCRIPTIONS_RENDER_MODE)
skp_names = sorted(set(dictA_results.keys() + dictB_results.keys()))
@@ -295,8 +302,11 @@
whole_image_B = self.get_default(
dictB_results, None,
skp_name, gm_json.JSONKEY_SOURCE_WHOLEIMAGE)
+
imagepairs_for_this_skp.append(self._create_image_pair(
image_dict_A=whole_image_A, image_dict_B=whole_image_B,
+ image_A_base_url=image_A_base_url,
+ image_B_base_url=image_B_base_url,
builder_A=builder_A, render_mode_A=render_mode_A,
builder_B=builder_B, render_mode_B=render_mode_B,
source_json_file=dict_path,
@@ -318,6 +328,8 @@
if tile_num < num_tiles_A else None),
image_dict_B=(tiled_images_B[tile_num]
if tile_num < num_tiles_B else None),
+ image_A_base_url=image_A_base_url,
+ image_B_base_url=image_B_base_url,
builder_A=builder_A, render_mode_A=render_mode_A,
builder_B=builder_B, render_mode_B=render_mode_B,
source_json_file=dict_path,
@@ -368,8 +380,9 @@
raise Exception('expected header_revision %d, but got %d' % (
expected_header_revision, header_revision))
- def _create_image_pair(self, image_dict_A, image_dict_B,
- builder_A, render_mode_A,
+ def _create_image_pair(self, image_dict_A, image_dict_B,
+ image_A_base_url, image_B_base_url,
+ builder_A, render_mode_A,
builder_B, render_mode_B,
source_json_file,
source_skp_name, tilenum):
@@ -378,11 +391,13 @@
Args:
image_dict_A: dict with JSONKEY_IMAGE_* keys, or None if no image
image_dict_B: dict with JSONKEY_IMAGE_* keys, or None if no image
+ image_A_base_url: base URL for image A
+ image_B_base_url: base URL for image B
builder_A: builder that created image set A or None if unknow
- render_mode_A: render mode used to generate image set A or None if
+ render_mode_A: render mode used to generate image set A or None if
unknown.
builder_B: builder that created image set A or None if unknow
- render_mode_B: render mode used to generate image set A or None if
+ render_mode_B: render mode used to generate image set A or None if
unknown.
source_json_file: string; relative path of the JSON file where this
result came from, within setA and setB.
@@ -436,7 +451,8 @@
try:
return imagepair.ImagePair(
image_diff_db=self._image_diff_db,
- base_url=self._image_base_gs_url,
+ imageA_base_url=image_A_base_url,
+ imageB_base_url=image_B_base_url,
imageA_relative_url=imageA_relative_url,
imageB_relative_url=imageB_relative_url,
extra_columns=extra_columns_dict,
diff --git a/gm/rebaseline_server/compare_rendered_pictures_test.py b/gm/rebaseline_server/compare_rendered_pictures_test.py
index c50c1a0..2b15462 100755
--- a/gm/rebaseline_server/compare_rendered_pictures_test.py
+++ b/gm/rebaseline_server/compare_rendered_pictures_test.py
@@ -32,6 +32,7 @@
import find_run_binary
import gm_json
import imagediffdb
+import imagepairset
import results
@@ -78,6 +79,64 @@
results.KEY__HEADER__RESULTS_ALL),
os.path.join(self.output_dir_actual, 'compare_rendered_pictures.json'))
+ def test_endToEnd_withImageBaseGSUrl(self):
+ """Generate two sets of SKPs, run render_pictures over both, and compare
+ the results."""
+ setA_subdir = 'before_patch'
+ setB_subdir = 'after_patch'
+ imageA_gs_base = 'superman/kent-camera/pictures'
+ imageB_gs_base = 'batman/batarang/pictures'
+ self._generate_skps_and_run_render_pictures(
+ subdir=setA_subdir, skpdict={
+ 'changed.skp': 200,
+ 'unchanged.skp': 100,
+ 'only-in-before.skp': 128,
+ },
+ image_base_gs_url='gs://%s' % imageA_gs_base)
+ self._generate_skps_and_run_render_pictures(
+ subdir=setB_subdir, skpdict={
+ 'changed.skp': 201,
+ 'unchanged.skp': 100,
+ 'only-in-after.skp': 128,
+ },
+ image_base_gs_url='gs://%s' % imageB_gs_base)
+
+ results_obj = compare_rendered_pictures.RenderedPicturesComparisons(
+ setA_dir=os.path.join(self.temp_dir, setA_subdir),
+ setB_dir=os.path.join(self.temp_dir, setB_subdir),
+ setA_section=gm_json.JSONKEY_ACTUALRESULTS,
+ setB_section=gm_json.JSONKEY_ACTUALRESULTS,
+ image_diff_db=imagediffdb.ImageDiffDB(self.temp_dir),
+ image_base_gs_url='gs://fakebucket/fake/path',
+ diff_base_url='/static/generated-images')
+ results_obj.get_timestamp = mock_get_timestamp
+
+ output_dict = results_obj.get_packaged_results_of_type(
+ results.KEY__HEADER__RESULTS_ALL)
+ # Assert that the baseURLs are as expected.
+ self.assertEquals(
+ output_dict[imagepairset.KEY__ROOT__IMAGESETS]
+ [imagepairset.KEY__IMAGESETS__SET__IMAGE_A]
+ [imagepairset.KEY__IMAGESETS__FIELD__BASE_URL],
+ 'http://storage.cloud.google.com/%s' % imageA_gs_base)
+ self.assertEquals(
+ output_dict[imagepairset.KEY__ROOT__IMAGESETS]
+ [imagepairset.KEY__IMAGESETS__SET__IMAGE_B]
+ [imagepairset.KEY__IMAGESETS__FIELD__BASE_URL],
+ 'http://storage.cloud.google.com/%s' % imageB_gs_base)
+ # Overwrite elements within the results that change from one test run
+ # to the next.
+ # pylint: disable=W0212
+ results_obj._setA_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+ 'before-patch-fake-dir']
+ results_obj._setB_descriptions[results.KEY__SET_DESCRIPTIONS__DIR] = [
+ 'after-patch-fake-dir']
+
+ gm_json.WriteToFile(
+ output_dict,
+ os.path.join(self.output_dir_actual,
+ 'compare_rendered_pictures.json'))
+
def test_repo_url(self):
"""Use repo: URL to specify summary files."""
base_repo_url = 'repo:gm/rebaseline_server/testdata/inputs/skp-summaries'
@@ -104,7 +163,8 @@
results.KEY__HEADER__RESULTS_ALL),
os.path.join(self.output_dir_actual, 'compare_rendered_pictures.json'))
- def _generate_skps_and_run_render_pictures(self, subdir, skpdict):
+ def _generate_skps_and_run_render_pictures(self, subdir, skpdict,
+ image_base_gs_url=None):
"""Generate SKPs and run render_pictures on them.
Args:
@@ -121,13 +181,16 @@
# and fix its result! (imageURLs within whole-image entries are wrong when
# I tried adding that)
binary = find_run_binary.find_path_to_program('render_pictures')
- return subprocess.check_output([
+ render_pictures_cmd = [
binary,
'--config', '8888',
'-r', out_path,
'--writeChecksumBasedFilenames',
'--writeJsonSummaryPath', os.path.join(out_path, 'summary.json'),
- '--writePath', out_path])
+ '--writePath', out_path]
+ if image_base_gs_url:
+ render_pictures_cmd.extend(['--imageBaseGSUrl', image_base_gs_url])
+ return subprocess.check_output(render_pictures_cmd)
def _run_skpmaker(self, output_path, red=0, green=0, blue=0,
width=640, height=400):
diff --git a/gm/rebaseline_server/compare_to_expectations.py b/gm/rebaseline_server/compare_to_expectations.py
index a93d9b9..303294c 100755
--- a/gm/rebaseline_server/compare_to_expectations.py
+++ b/gm/rebaseline_server/compare_to_expectations.py
@@ -347,7 +347,8 @@
try:
image_pair = imagepair.ImagePair(
image_diff_db=self._image_diff_db,
- base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+ imageA_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
+ imageB_base_url=gm_json.GM_ACTUALS_ROOT_HTTP_URL,
imageA_relative_url=expected_image_relative_url,
imageB_relative_url=actual_image_relative_url,
expectations=expectations_dict,
diff --git a/gm/rebaseline_server/imagepair.py b/gm/rebaseline_server/imagepair.py
index 0ac0c42..e85c219 100644
--- a/gm/rebaseline_server/imagepair.py
+++ b/gm/rebaseline_server/imagepair.py
@@ -32,17 +32,19 @@
"""
def __init__(self, image_diff_db,
- base_url, imageA_relative_url, imageB_relative_url,
+ imageA_base_url, imageB_base_url,
+ imageA_relative_url, imageB_relative_url,
expectations=None, extra_columns=None, source_json_file=None,
download_all_images=False):
"""
Args:
image_diff_db: ImageDiffDB instance we use to generate/store image diffs
- base_url: base of all image URLs
+ imageA_base_url: string; base URL for image A
+ imageB_base_url: string; base URL for image B
imageA_relative_url: string; URL pointing at an image, relative to
- base_url; or None, if this image is missing
+ imageA_base_url; or None, if this image is missing
imageB_relative_url: string; URL pointing at an image, relative to
- base_url; or None, if this image is missing
+ imageB_base_url; or None, if this image is missing
expectations: optional dictionary containing expectations-specific
metadata (ignore-failure, bug numbers, etc.)
extra_columns: optional dictionary containing more metadata (test name,
@@ -55,7 +57,8 @@
(imageA == imageB, or one of them is missing)
"""
self._image_diff_db = image_diff_db
- self.base_url = base_url
+ self.imageA_base_url = imageA_base_url
+ self.imageB_base_url = imageB_base_url
self.imageA_relative_url = imageA_relative_url
self.imageB_relative_url = imageB_relative_url
self.expectations_dict = expectations
@@ -76,9 +79,11 @@
if self._diff_record != None or download_all_images:
image_diff_db.add_image_pair(
expected_image_locator=imageA_relative_url,
- expected_image_url=self.posixpath_join(base_url, imageA_relative_url),
+ expected_image_url=self.posixpath_join(imageA_base_url,
+ imageA_relative_url),
actual_image_locator=imageB_relative_url,
- actual_image_url=self.posixpath_join(base_url, imageB_relative_url))
+ actual_image_url=self.posixpath_join(imageB_base_url,
+ imageB_relative_url))
def as_dict(self):
"""Returns a dictionary describing this ImagePair.
diff --git a/gm/rebaseline_server/imagepair_test.py b/gm/rebaseline_server/imagepair_test.py
index c82e4b5..773f6a3 100755
--- a/gm/rebaseline_server/imagepair_test.py
+++ b/gm/rebaseline_server/imagepair_test.py
@@ -91,7 +91,7 @@
'perceptualDifference': 0.06620300000000157,
'diffUrl': 'arcofzorro_16206093933823793653_png_png-vs-' +
'arcofzorro_13786535001616823825_png_png.png',
- 'whiteDiffUrl': 'arcofzorro_16206093933823793653_png_png' +
+ 'whiteDiffUrl': 'arcofzorro_16206093933823793653_png_png' +
'-vs-arcofzorro_13786535001616823825_png_png.png',
},
'imageAUrl': 'arcofzorro/16206093933823793653.png',
@@ -195,7 +195,8 @@
for selftest in selftests:
image_pair = imagepair.ImagePair(
image_diff_db=db,
- base_url=IMG_URL_BASE,
+ imageA_base_url=IMG_URL_BASE,
+ imageB_base_url=IMG_URL_BASE,
imageA_relative_url=selftest[0],
imageB_relative_url=selftest[1],
expectations=selftest[2],
diff --git a/gm/rebaseline_server/imagepairset.py b/gm/rebaseline_server/imagepairset.py
index a6101b9..b492d9f 100644
--- a/gm/rebaseline_server/imagepairset.py
+++ b/gm/rebaseline_server/imagepairset.py
@@ -57,7 +57,8 @@
self._descriptions = descriptions or DEFAULT_DESCRIPTIONS
self._extra_column_tallies = {} # maps column_id -> values
# -> instances_per_value
- self._image_base_url = None
+ self._imageA_base_url = None
+ self._imageB_base_url = None
self._diff_base_url = diff_base_url
# We build self._image_pair_objects incrementally as calls come into
@@ -70,11 +71,15 @@
"""Adds an ImagePair; this may be repeated any number of times."""
# Special handling when we add the first ImagePair...
if not self._image_pair_objects:
- self._image_base_url = image_pair.base_url
+ self._imageA_base_url = image_pair.imageA_base_url
+ self._imageB_base_url = image_pair.imageB_base_url
- if image_pair.base_url != self._image_base_url:
+ if(image_pair.imageA_base_url != self._imageA_base_url):
raise Exception('added ImagePair with base_url "%s" instead of "%s"' % (
- image_pair.base_url, self._image_base_url))
+ image_pair.imageA_base_url, self._imageA_base_url))
+ if(image_pair.imageB_base_url != self._imageB_base_url):
+ raise Exception('added ImagePair with base_url "%s" instead of "%s"' % (
+ image_pair.imageB_base_url, self._imageB_base_url))
self._image_pair_objects.append(image_pair)
extra_columns_dict = image_pair.extra_columns_dict
if extra_columns_dict:
@@ -171,10 +176,14 @@
key_description = KEY__IMAGESETS__FIELD__DESCRIPTION
key_base_url = KEY__IMAGESETS__FIELD__BASE_URL
- if gs_utils.GSUtils.is_gs_url(self._image_base_url):
- value_base_url = self._convert_gs_url_to_http_url(self._image_base_url)
+ if gs_utils.GSUtils.is_gs_url(self._imageA_base_url):
+ valueA_base_url = self._convert_gs_url_to_http_url(self._imageA_base_url)
else:
- value_base_url = self._image_base_url
+ valueA_base_url = self._imageA_base_url
+ if gs_utils.GSUtils.is_gs_url(self._imageB_base_url):
+ valueB_base_url = self._convert_gs_url_to_http_url(self._imageB_base_url)
+ else:
+ valueB_base_url = self._imageB_base_url
# We've waited as long as we can to ask ImageDiffDB for details of the
# image diffs, so that it has time to compute them.
@@ -188,11 +197,11 @@
KEY__ROOT__IMAGESETS: {
KEY__IMAGESETS__SET__IMAGE_A: {
key_description: self._descriptions[0],
- key_base_url: value_base_url,
+ key_base_url: valueA_base_url,
},
KEY__IMAGESETS__SET__IMAGE_B: {
key_description: self._descriptions[1],
- key_base_url: value_base_url,
+ key_base_url: valueB_base_url,
},
KEY__IMAGESETS__SET__DIFFS: {
key_description: 'color difference per channel',
diff --git a/gm/rebaseline_server/imagepairset_test.py b/gm/rebaseline_server/imagepairset_test.py
index 5e17faa..a931e04 100755
--- a/gm/rebaseline_server/imagepairset_test.py
+++ b/gm/rebaseline_server/imagepairset_test.py
@@ -79,9 +79,12 @@
"""Assembles some ImagePairs into an ImagePairSet, and validates results.
"""
image_pairs = [
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT),
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT),
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_3_AS_DICT),
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_1_AS_DICT),
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_2_AS_DICT),
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_3_AS_DICT),
]
expected_imageset_dict = {
'extraColumnHeaders': {
@@ -150,12 +153,14 @@
image_pair_set = imagepairset.ImagePairSet(
diff_base_url=DIFF_BASE_URL)
image_pair_set.add_image_pair(
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT))
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_1_AS_DICT))
image_pair_set.add_image_pair(
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT))
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_2_AS_DICT))
with self.assertRaises(Exception):
image_pair_set.add_image_pair(
- MockImagePair(base_url=BASE_URL_2,
+ MockImagePair(imageA_base_url=BASE_URL_2, imageB_base_url=BASE_URL_2,
dict_to_return=IMAGEPAIR_3_AS_DICT))
def test_missing_column_ids(self):
@@ -164,9 +169,11 @@
image_pair_set = imagepairset.ImagePairSet(
diff_base_url=DIFF_BASE_URL)
image_pair_set.add_image_pair(
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_1_AS_DICT))
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_1_AS_DICT))
image_pair_set.add_image_pair(
- MockImagePair(base_url=BASE_URL_1, dict_to_return=IMAGEPAIR_2_AS_DICT))
+ MockImagePair(imageA_base_url=BASE_URL_1, imageB_base_url=BASE_URL_1,
+ dict_to_return=IMAGEPAIR_2_AS_DICT))
# Call as_dict() with default or reasonable column_ids_in_order.
image_pair_set.as_dict()
image_pair_set.as_dict(column_ids_in_order=['test', 'builder'])
@@ -178,13 +185,14 @@
class MockImagePair(object):
"""Mock ImagePair object, which will return canned results."""
- def __init__(self, base_url, dict_to_return):
+ def __init__(self, imageA_base_url, imageB_base_url, dict_to_return):
"""
Args:
base_url: base_url attribute for this object
dict_to_return: dictionary to return from as_dict()
"""
- self.base_url = base_url
+ self.imageA_base_url = imageA_base_url
+ self.imageB_base_url = imageB_base_url
self.extra_columns_dict = dict_to_return.get(
imagepair.KEY__IMAGEPAIRS__EXTRACOLUMNS, None)
self._dict_to_return = dict_to_return
diff --git a/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json
new file mode 100644
index 0000000..e62b5cb
--- /dev/null
+++ b/gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json
@@ -0,0 +1,237 @@
+{
+ "extraColumnHeaders": {
+ "builderA": {
+ "headerText": "builderA",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ null,
+ 4
+ ]
+ ]
+ },
+ "builderB": {
+ "headerText": "builderB",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ null,
+ 4
+ ]
+ ]
+ },
+ "renderModeA": {
+ "headerText": "renderModeA",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ null,
+ 4
+ ]
+ ]
+ },
+ "renderModeB": {
+ "headerText": "renderModeB",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ null,
+ 4
+ ]
+ ]
+ },
+ "resultType": {
+ "headerText": "resultType",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ "failed",
+ 1
+ ],
+ [
+ "no-comparison",
+ 2
+ ],
+ [
+ "succeeded",
+ 1
+ ]
+ ]
+ },
+ "sourceSkpFile": {
+ "headerText": "sourceSkpFile",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": true,
+ "valuesAndCounts": [
+ [
+ "changed.skp",
+ 1
+ ],
+ [
+ "only-in-after.skp",
+ 1
+ ],
+ [
+ "only-in-before.skp",
+ 1
+ ],
+ [
+ "unchanged.skp",
+ 1
+ ]
+ ]
+ },
+ "tiledOrWhole": {
+ "headerText": "tiledOrWhole",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": false,
+ "valuesAndCounts": [
+ [
+ "whole",
+ 4
+ ]
+ ]
+ },
+ "tilenum": {
+ "headerText": "tilenum",
+ "isFilterable": true,
+ "isSortable": true,
+ "useFreeformFilter": true,
+ "valuesAndCounts": [
+ [
+ "N/A",
+ 4
+ ]
+ ]
+ }
+ },
+ "extraColumnOrder": [
+ "resultType",
+ "sourceSkpFile",
+ "tiledOrWhole",
+ "tilenum",
+ "builderA",
+ "renderModeA",
+ "builderB",
+ "renderModeB"
+ ],
+ "header": {
+ "dataHash": "-5707186260478709107",
+ "isEditable": false,
+ "isExported": true,
+ "schemaVersion": 5,
+ "setA": {
+ "dir": [
+ "before-patch-fake-dir"
+ ],
+ "repoRevision": null,
+ "section": "actual-results"
+ },
+ "setB": {
+ "dir": [
+ "after-patch-fake-dir"
+ ],
+ "repoRevision": null,
+ "section": "actual-results"
+ },
+ "timeNextUpdateAvailable": null,
+ "timeUpdated": 12345678,
+ "type": "all"
+ },
+ "imagePairs": [
+ {
+ "extraColumns": {
+ "builderA": null,
+ "builderB": null,
+ "renderModeA": null,
+ "renderModeB": null,
+ "resultType": "failed",
+ "sourceSkpFile": "changed.skp",
+ "tiledOrWhole": "whole",
+ "tilenum": "N/A"
+ },
+ "imageAUrl": "changed_skp/bitmap-64bitMD5_3101044995537104462.png",
+ "imageBUrl": "changed_skp/bitmap-64bitMD5_13623922271964399662.png",
+ "isDifferent": true,
+ "sourceJsonFile": "./summary.json"
+ },
+ {
+ "extraColumns": {
+ "builderA": null,
+ "builderB": null,
+ "renderModeA": null,
+ "renderModeB": null,
+ "resultType": "no-comparison",
+ "sourceSkpFile": "only-in-after.skp",
+ "tiledOrWhole": "whole",
+ "tilenum": "N/A"
+ },
+ "imageAUrl": null,
+ "imageBUrl": "only-in-after_skp/bitmap-64bitMD5_2320185040577047131.png",
+ "isDifferent": true,
+ "sourceJsonFile": "./summary.json"
+ },
+ {
+ "extraColumns": {
+ "builderA": null,
+ "builderB": null,
+ "renderModeA": null,
+ "renderModeB": null,
+ "resultType": "no-comparison",
+ "sourceSkpFile": "only-in-before.skp",
+ "tiledOrWhole": "whole",
+ "tilenum": "N/A"
+ },
+ "imageAUrl": "only-in-before_skp/bitmap-64bitMD5_2320185040577047131.png",
+ "imageBUrl": null,
+ "isDifferent": true,
+ "sourceJsonFile": "./summary.json"
+ },
+ {
+ "extraColumns": {
+ "builderA": null,
+ "builderB": null,
+ "renderModeA": null,
+ "renderModeB": null,
+ "resultType": "succeeded",
+ "sourceSkpFile": "unchanged.skp",
+ "tiledOrWhole": "whole",
+ "tilenum": "N/A"
+ },
+ "imageAUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png",
+ "imageBUrl": "unchanged_skp/bitmap-64bitMD5_3322248763049618493.png",
+ "isDifferent": false,
+ "sourceJsonFile": "./summary.json"
+ }
+ ],
+ "imageSets": {
+ "diffs": {
+ "baseUrl": "/static/generated-images/diffs",
+ "description": "color difference per channel"
+ },
+ "imageA": {
+ "baseUrl": "http://storage.cloud.google.com/superman/kent-camera/pictures",
+ "description": "setA"
+ },
+ "imageB": {
+ "baseUrl": "http://storage.cloud.google.com/batman/batarang/pictures",
+ "description": "setB"
+ },
+ "whiteDiffs": {
+ "baseUrl": "/static/generated-images/whitediffs",
+ "description": "differing pixels in white"
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/image_expectations.cpp b/tools/image_expectations.cpp
index f0c9cfb..05a905d 100644
--- a/tools/image_expectations.cpp
+++ b/tools/image_expectations.cpp
@@ -30,6 +30,7 @@
const static char kJsonKey_ActualResults[] = "actual-results";
const static char kJsonKey_Descriptions[] = "descriptions";
const static char kJsonKey_ExpectedResults[] = "expected-results";
+const static char kJsonKey_ImageBaseGSUrl[] = "image-base-gs-url";
const static char kJsonKey_Header[] = "header";
const static char kJsonKey_Header_Type[] = "type";
const static char kJsonKey_Header_Revision[] = "revision";
@@ -198,6 +199,10 @@
fDescriptions[key] = value;
}
+ void ImageResultsAndExpectations::setImageBaseGSUrl(const char *imageBaseGSUrl) {
+ fImageBaseGSUrl = imageBaseGSUrl;
+ }
+
Expectation ImageResultsAndExpectations::getExpectation(const char *sourceName,
const int *tileNumber) {
if (fExpectedResults.isNull()) {
@@ -228,6 +233,7 @@
root[kJsonKey_ActualResults] = fActualResults;
root[kJsonKey_Descriptions] = fDescriptions;
root[kJsonKey_Header] = header;
+ root[kJsonKey_ImageBaseGSUrl] = fImageBaseGSUrl;
std::string jsonStdString = root.toStyledString();
SkFILEWStream stream(filename);
stream.write(jsonStdString.c_str(), jsonStdString.length());
diff --git a/tools/image_expectations.h b/tools/image_expectations.h
index 2d58b92..422c64d 100644
--- a/tools/image_expectations.h
+++ b/tools/image_expectations.h
@@ -185,6 +185,13 @@
void addDescription(const char *key, const char *value);
/**
+ * Adds the image base Google Storage URL to the summary of results.
+ *
+ * @param imageBaseGSUrl the image base Google Storage URL
+ */
+ void setImageBaseGSUrl(const char *imageBaseGSUrl);
+
+ /**
* Returns the Expectation for this test.
*
* @param sourceName name of the source file that generated this result
@@ -217,6 +224,7 @@
Json::Value fDescriptions;
Json::Value fExpectedJsonRoot;
Json::Value fExpectedResults;
+ Json::Value fImageBaseGSUrl;
};
} // namespace sk_tools
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp
index 595a78e..d508510 100644
--- a/tools/render_pictures_main.cpp
+++ b/tools/render_pictures_main.cpp
@@ -30,6 +30,7 @@
DECLARE_bool(deferImageDecoding);
DEFINE_string(descriptions, "", "one or more key=value pairs to add to the descriptions section "
"of the JSON summary.");
+DEFINE_string(imageBaseGSUrl, "", "The Google Storage image base URL the images are stored in.");
DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Components that differ "
"by more than this amount are considered errors, though all diffs are reported. "
"Requires --validate.");
@@ -498,6 +499,9 @@
SkASSERT(tokens.count() == 2);
jsonSummary.addDescription(tokens[0].c_str(), tokens[1].c_str());
}
+ if (FLAGS_imageBaseGSUrl.count() == 1) {
+ jsonSummary.setImageBaseGSUrl(FLAGS_imageBaseGSUrl[0]);
+ }
jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]);
}
return 0;
diff --git a/tools/tests/render_pictures_test.py b/tools/tests/render_pictures_test.py
index 9ff3226..6daadd8 100755
--- a/tools/tests/render_pictures_test.py
+++ b/tools/tests/render_pictures_test.py
@@ -197,6 +197,7 @@
'--writeWholeImage'])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -233,6 +234,7 @@
modified_red_tiles[5]['comparisonResult'] = 'failure-ignored'
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -270,6 +272,7 @@
modified_red_tiles[5]['comparisonResult'] = 'no-comparison'
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -315,6 +318,7 @@
if expected_summary_dict == None:
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -340,6 +344,7 @@
pass
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -370,6 +375,7 @@
])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : {
"builder": "builderName",
"renderMode": "renderModeName",
@@ -421,6 +427,7 @@
'--writeJsonSummaryPath', output_json_path])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -449,6 +456,7 @@
'--writeJsonSummaryPath', output_json_path])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -484,6 +492,7 @@
'--writeJsonSummaryPath', output_json_path])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {
@@ -515,6 +524,7 @@
'--writeJsonSummaryPath', output_json_path])
expected_summary_dict = {
"header" : EXPECTED_HEADER_CONTENTS,
+ "image-base-gs-url" : None,
"descriptions" : None,
"actual-results" : {
"red.skp": {