aboutsummaryrefslogtreecommitdiffhomepage
path: root/gm/rebaseline_server
diff options
context:
space:
mode:
authorGravatar rmistry <rmistry@google.com>2014-08-22 04:46:30 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-08-22 04:46:30 -0700
commit2529f2e72cddf87904c8ad4b613942cbef802cfb (patch)
tree0c2dc416fcfec3ce529cef029a8327728859313c /gm/rebaseline_server
parent85b438dfab7f6ec1fd46dbc19215ccf2171ad6ae (diff)
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
Diffstat (limited to 'gm/rebaseline_server')
-rwxr-xr-xgm/rebaseline_server/compare_configs.py3
-rwxr-xr-xgm/rebaseline_server/compare_rendered_pictures.py42
-rwxr-xr-xgm/rebaseline_server/compare_rendered_pictures_test.py69
-rwxr-xr-xgm/rebaseline_server/compare_to_expectations.py3
-rw-r--r--gm/rebaseline_server/imagepair.py19
-rwxr-xr-xgm/rebaseline_server/imagepair_test.py5
-rw-r--r--gm/rebaseline_server/imagepairset.py27
-rwxr-xr-xgm/rebaseline_server/imagepairset_test.py28
-rw-r--r--gm/rebaseline_server/testdata/outputs/expected/compare_rendered_pictures_test.CompareRenderedPicturesTest.test_endToEnd_withImageBaseGSUrl/compare_rendered_pictures.json237
9 files changed, 387 insertions, 46 deletions
diff --git a/gm/rebaseline_server/compare_configs.py b/gm/rebaseline_server/compare_configs.py
index 73a5570cf5..36c7f86530 100755
--- a/gm/rebaseline_server/compare_configs.py
+++ b/gm/rebaseline_server/compare_configs.py
@@ -151,7 +151,8 @@ class ConfigComparisons(results.BaseComparisons):
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 399117d611..73cb36b430 100755
--- a/gm/rebaseline_server/compare_rendered_pictures.py
+++ b/gm/rebaseline_server/compare_rendered_pictures.py
@@ -268,18 +268,25 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 @@ class RenderedPicturesComparisons(results.BaseComparisons):
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 c50c1a00af..2b15462111 100755
--- a/gm/rebaseline_server/compare_rendered_pictures_test.py
+++ b/gm/rebaseline_server/compare_rendered_pictures_test.py
@@ -32,6 +32,7 @@ import compare_rendered_pictures
import find_run_binary
import gm_json
import imagediffdb
+import imagepairset
import results
@@ -78,6 +79,64 @@ class CompareRenderedPicturesTest(base_unittest.TestCase):
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 @@ class CompareRenderedPicturesTest(base_unittest.TestCase):
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 @@ class CompareRenderedPicturesTest(base_unittest.TestCase):
# 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 a93d9b9fdf..303294c0ae 100755
--- a/gm/rebaseline_server/compare_to_expectations.py
+++ b/gm/rebaseline_server/compare_to_expectations.py
@@ -347,7 +347,8 @@ class ExpectationComparisons(results.BaseComparisons):
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 0ac0c42138..e85c21948b 100644
--- a/gm/rebaseline_server/imagepair.py
+++ b/gm/rebaseline_server/imagepair.py
@@ -32,17 +32,19 @@ class ImagePair(object):
"""
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 @@ class ImagePair(object):
(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 @@ class ImagePair(object):
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 c82e4b59cd..773f6a376c 100755
--- a/gm/rebaseline_server/imagepair_test.py
+++ b/gm/rebaseline_server/imagepair_test.py
@@ -91,7 +91,7 @@ class ImagePairTest(unittest.TestCase):
'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 @@ class ImagePairTest(unittest.TestCase):
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 a6101b9087..b492d9f021 100644
--- a/gm/rebaseline_server/imagepairset.py
+++ b/gm/rebaseline_server/imagepairset.py
@@ -57,7 +57,8 @@ class ImagePairSet(object):
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 @@ class ImagePairSet(object):
"""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 @@ class ImagePairSet(object):
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:
+ 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:
- value_base_url = self._image_base_url
+ 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 @@ class ImagePairSet(object):
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 5e17faa2f1..a931e047aa 100755
--- a/gm/rebaseline_server/imagepairset_test.py
+++ b/gm/rebaseline_server/imagepairset_test.py
@@ -79,9 +79,12 @@ class ImagePairSetTest(unittest.TestCase):
"""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 @@ class ImagePairSetTest(unittest.TestCase):
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 @@ class ImagePairSetTest(unittest.TestCase):
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 ImagePairSetTest(unittest.TestCase):
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 0000000000..e62b5cbc63
--- /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