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

Unified Diff: content/test/gpu/gpu_tests/cloud_storage_test_base.py

Issue 2618983004: Port Maps test to browser_test_runner harness. (Closed)
Patch Set: Created 3 years, 11 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 side-by-side diff with in-line comments
Download patch
Index: content/test/gpu/gpu_tests/cloud_storage_test_base.py
diff --git a/content/test/gpu/gpu_tests/cloud_storage_test_base.py b/content/test/gpu/gpu_tests/cloud_storage_test_base.py
deleted file mode 100644
index 418d091c037b4a4ecf09ffc5052c486afb1fadfb..0000000000000000000000000000000000000000
--- a/content/test/gpu/gpu_tests/cloud_storage_test_base.py
+++ /dev/null
@@ -1,309 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base classes for a test and validator which upload results
-(reference images, error images) to cloud storage."""
-
-import logging
-import os
-import re
-import tempfile
-
-from py_utils import cloud_storage
-from telemetry.page import legacy_page_test
-from telemetry.util import image_util
-from telemetry.util import rgba_color
-
-from gpu_tests import gpu_test_base
-
-test_data_dir = os.path.abspath(os.path.join(
- os.path.dirname(__file__), '..', '..', 'data', 'gpu'))
-
-default_generated_data_dir = os.path.join(test_data_dir, 'generated')
-
-error_image_cloud_storage_bucket = 'chromium-browser-gpu-tests'
-
-def _CompareScreenshotSamples(tab, screenshot, expectations, device_pixel_ratio,
- test_machine_name):
- # First scan through the expectations and see if there are any scale
- # factor overrides that would preempt the device pixel ratio. This
- # is mainly a workaround for complex tests like the Maps test.
- for expectation in expectations:
- if 'scale_factor_overrides' in expectation:
- for override in expectation['scale_factor_overrides']:
- # Require exact matches to avoid confusion, because some
- # machine models and names might be subsets of others
- # (e.g. Nexus 5 vs Nexus 5X).
- if ('device_type' in override and
- (tab.browser.platform.GetDeviceTypeName() ==
- override['device_type'])):
- logging.warning('Overriding device_pixel_ratio ' +
- str(device_pixel_ratio) + ' with scale factor ' +
- str(override['scale_factor']) + ' for device type ' +
- override['device_type'])
- device_pixel_ratio = override['scale_factor']
- break
- if (test_machine_name and 'machine_name' in override and
- override["machine_name"] == test_machine_name):
- logging.warning('Overriding device_pixel_ratio ' +
- str(device_pixel_ratio) + ' with scale factor ' +
- str(override['scale_factor']) + ' for machine name ' +
- test_machine_name)
- device_pixel_ratio = override['scale_factor']
- break
- # Only support one "scale_factor_overrides" in the expectation format.
- break
- for expectation in expectations:
- if "scale_factor_overrides" in expectation:
- continue
- location = expectation["location"]
- size = expectation["size"]
- x0 = int(location[0] * device_pixel_ratio)
- x1 = int((location[0] + size[0]) * device_pixel_ratio)
- y0 = int(location[1] * device_pixel_ratio)
- y1 = int((location[1] + size[1]) * device_pixel_ratio)
- for x in range(x0, x1):
- for y in range(y0, y1):
- if (x < 0 or y < 0 or x >= image_util.Width(screenshot) or
- y >= image_util.Height(screenshot)):
- raise legacy_page_test.Failure(
- ('Expected pixel location [%d, %d] is out of range on ' +
- '[%d, %d] image') %
- (x, y, image_util.Width(screenshot),
- image_util.Height(screenshot)))
-
- actual_color = image_util.GetPixelColor(screenshot, x, y)
- expected_color = rgba_color.RgbaColor(
- expectation["color"][0],
- expectation["color"][1],
- expectation["color"][2])
- if not actual_color.IsEqual(expected_color, expectation["tolerance"]):
- raise legacy_page_test.Failure('Expected pixel at ' + str(location) +
- ' (actual pixel (' + str(x) + ', ' + str(y) + ')) ' +
- ' to be ' +
- str(expectation["color"]) + " but got [" +
- str(actual_color.r) + ", " +
- str(actual_color.g) + ", " +
- str(actual_color.b) + "]")
-
-class ValidatorBase(gpu_test_base.ValidatorBase):
- def __init__(self):
- super(ValidatorBase, self).__init__()
- # Parameters for cloud storage reference images.
- self.vendor_id = None
- self.device_id = None
- self.vendor_string = None
- self.device_string = None
- self.msaa = False
- self.model_name = None
-
- ###
- ### Routines working with the local disk (only used for local
- ### testing without a cloud storage account -- the bots do not use
- ### this code path).
- ###
-
- def _UrlToImageName(self, url):
- image_name = re.sub(r'^(http|https|file)://(/*)', '', url)
- image_name = re.sub(r'\.\./', '', image_name)
- image_name = re.sub(r'(\.|/|-)', '_', image_name)
- return image_name
-
- def _WriteImage(self, image_path, png_image):
- output_dir = os.path.dirname(image_path)
- if not os.path.exists(output_dir):
- os.makedirs(output_dir)
- image_util.WritePngFile(png_image, image_path)
-
- def _WriteErrorImages(self, img_dir, img_name, screenshot, ref_png):
- full_image_name = img_name + '_' + str(self.options.build_revision)
- full_image_name = full_image_name + '.png'
-
- # Always write the failing image.
- self._WriteImage(
- os.path.join(img_dir, 'FAIL_' + full_image_name), screenshot)
-
- if ref_png is not None:
- # Save the reference image.
- # This ensures that we get the right revision number.
- self._WriteImage(
- os.path.join(img_dir, full_image_name), ref_png)
-
- # Save the difference image.
- diff_png = image_util.Diff(screenshot, ref_png)
- self._WriteImage(
- os.path.join(img_dir, 'DIFF_' + full_image_name), diff_png)
-
- ###
- ### Cloud storage code path -- the bots use this.
- ###
-
- def _ComputeGpuInfo(self, tab):
- if ((self.vendor_id and self.device_id) or
- (self.vendor_string and self.device_string)):
- return
- browser = tab.browser
- if not browser.supports_system_info:
- raise Exception('System info must be supported by the browser')
- system_info = browser.GetSystemInfo()
- if not system_info.gpu:
- raise Exception('GPU information was absent')
- device = system_info.gpu.devices[0]
- if device.vendor_id and device.device_id:
- self.vendor_id = device.vendor_id
- self.device_id = device.device_id
- elif device.vendor_string and device.device_string:
- self.vendor_string = device.vendor_string
- self.device_string = device.device_string
- else:
- raise Exception('GPU device information was incomplete')
- # TODO(senorblanco): This should probably be checking
- # for the presence of the extensions in system_info.gpu_aux_attributes
- # in order to check for MSAA, rather than sniffing the blacklist.
- self.msaa = not (
- ('disable_chromium_framebuffer_multisample' in
- system_info.gpu.driver_bug_workarounds) or
- ('disable_multisample_render_to_texture' in
- system_info.gpu.driver_bug_workarounds))
- self.model_name = system_info.model_name
-
- def _FormatGpuInfo(self, tab):
- self._ComputeGpuInfo(tab)
- msaa_string = '_msaa' if self.msaa else '_non_msaa'
- if self.vendor_id:
- return '%s_%04x_%04x%s' % (
- self.options.os_type, self.vendor_id, self.device_id, msaa_string)
- else:
- # This is the code path for Android devices. Include the model
- # name (e.g. "Nexus 9") in the GPU string to disambiguate
- # multiple devices on the waterfall which might have the same
- # device string ("NVIDIA Tegra") but different screen
- # resolutions and device pixel ratios.
- return '%s_%s_%s_%s%s' % (
- self.options.os_type, self.vendor_string, self.device_string,
- self.model_name, msaa_string)
-
- def _FormatReferenceImageName(self, img_name, page, tab):
- return '%s_v%s_%s.png' % (
- img_name,
- page.revision,
- self._FormatGpuInfo(tab))
-
- def _UploadBitmapToCloudStorage(self, bucket, name, bitmap, public=False):
- # This sequence of steps works on all platforms to write a temporary
- # PNG to disk, following the pattern in bitmap_unittest.py. The key to
- # avoiding PermissionErrors seems to be to not actually try to write to
- # the temporary file object, but to re-open its name for all operations.
- temp_file = tempfile.NamedTemporaryFile(suffix='.png').name
- image_util.WritePngFile(bitmap, temp_file)
- cloud_storage.Insert(bucket, name, temp_file, publicly_readable=public)
-
- def _ConditionallyUploadToCloudStorage(self, img_name, page, tab, screenshot):
- """Uploads the screenshot to cloud storage as the reference image
- for this test, unless it already exists. Returns True if the
- upload was actually performed."""
- if not self.options.refimg_cloud_storage_bucket:
- raise Exception('--refimg-cloud-storage-bucket argument is required')
- cloud_name = self._FormatReferenceImageName(img_name, page, tab)
- if not cloud_storage.Exists(self.options.refimg_cloud_storage_bucket,
- cloud_name):
- self._UploadBitmapToCloudStorage(self.options.refimg_cloud_storage_bucket,
- cloud_name,
- screenshot)
- return True
- return False
-
- def _DownloadFromCloudStorage(self, img_name, page, tab):
- """Downloads the reference image for the given test from cloud
- storage, returning it as a Telemetry Bitmap object."""
- # TODO(kbr): there's a race condition between the deletion of the
- # temporary file and gsutil's overwriting it.
- if not self.options.refimg_cloud_storage_bucket:
- raise Exception('--refimg-cloud-storage-bucket argument is required')
- temp_file = tempfile.NamedTemporaryFile(suffix='.png').name
- cloud_storage.Get(self.options.refimg_cloud_storage_bucket,
- self._FormatReferenceImageName(img_name, page, tab),
- temp_file)
- return image_util.FromPngFile(temp_file)
-
- def _UploadErrorImagesToCloudStorage(self, image_name, screenshot, ref_img):
- """For a failing run, uploads the failing image, reference image (if
- supplied), and diff image (if reference image was supplied) to cloud
- storage. This subsumes the functionality of the
- archive_gpu_pixel_test_results.py script."""
- machine_name = re.sub(r'\W+', '_', self.options.test_machine_name)
- upload_dir = '%s_%s_telemetry' % (self.options.build_revision, machine_name)
- base_bucket = '%s/runs/%s' % (error_image_cloud_storage_bucket, upload_dir)
- image_name_with_revision = '%s_%s.png' % (
- image_name, self.options.build_revision)
- self._UploadBitmapToCloudStorage(
- base_bucket + '/gen', image_name_with_revision, screenshot,
- public=True)
- if ref_img is not None:
- self._UploadBitmapToCloudStorage(
- base_bucket + '/ref', image_name_with_revision, ref_img, public=True)
- diff_img = image_util.Diff(screenshot, ref_img)
- self._UploadBitmapToCloudStorage(
- base_bucket + '/diff', image_name_with_revision, diff_img,
- public=True)
- print ('See http://%s.commondatastorage.googleapis.com/'
- 'view_test_results.html?%s for this run\'s test results') % (
- error_image_cloud_storage_bucket, upload_dir)
-
- def _ValidateScreenshotSamples(self, tab, url,
- screenshot, expectations, device_pixel_ratio):
- """Samples the given screenshot and verifies pixel color values.
- The sample locations and expected color values are given in expectations.
- In case any of the samples do not match the expected color, it raises
- a Failure and dumps the screenshot locally or cloud storage depending on
- what machine the test is being run."""
- try:
- _CompareScreenshotSamples(tab, screenshot, expectations,
- device_pixel_ratio,
- self.options.test_machine_name)
- except legacy_page_test.Failure:
- image_name = self._UrlToImageName(url)
- if self.options.test_machine_name:
- self._UploadErrorImagesToCloudStorage(image_name, screenshot, None)
- else:
- self._WriteErrorImages(self.options.generated_dir, image_name,
- screenshot, None)
- raise
-
-
-class CloudStorageTestBase(gpu_test_base.TestBase):
- @classmethod
- def AddBenchmarkCommandLineArgs(cls, group):
- group.add_option('--build-revision',
- help='Chrome revision being tested.',
- default="unknownrev")
- group.add_option('--upload-refimg-to-cloud-storage',
- dest='upload_refimg_to_cloud_storage',
- action='store_true', default=False,
- help='Upload resulting images to cloud storage as reference images')
- group.add_option('--download-refimg-from-cloud-storage',
- dest='download_refimg_from_cloud_storage',
- action='store_true', default=False,
- help='Download reference images from cloud storage')
- group.add_option('--refimg-cloud-storage-bucket',
- help='Name of the cloud storage bucket to use for reference images; '
- 'required with --upload-refimg-to-cloud-storage and '
- '--download-refimg-from-cloud-storage. Example: '
- '"chromium-gpu-archive/reference-images"')
- group.add_option('--os-type',
- help='Type of operating system on which the pixel test is being run, '
- 'used only to distinguish different operating systems with the same '
- 'graphics card. Any value is acceptable, but canonical values are '
- '"win", "mac", and "linux", and probably, eventually, "chromeos" '
- 'and "android").',
- default='')
- group.add_option('--test-machine-name',
- help='Name of the test machine. Specifying this argument causes this '
- 'script to upload failure images and diffs to cloud storage directly, '
- 'instead of relying on the archive_gpu_pixel_test_results.py script.',
- default='')
- group.add_option('--generated-dir',
- help='Overrides the default on-disk location for generated test images '
- '(only used for local testing without a cloud storage account)',
- default=default_generated_data_dir)
« no previous file with comments | « content/test/gpu/generate_buildbot_json.py ('k') | content/test/gpu/gpu_tests/context_lost_integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698