Commit b55d82b9 authored by chrishenry@google.com's avatar chrishenry@google.com

Merge PageMeasurement to PageTest, move MeasurementFailure to

page_test.py.

Fixed all files that refer to MeasurementFailure in this patch. Rest of
subclasses of PageMeasurement will be fixed in a follow up patch.

BUG=383635

Review URL: https://codereview.chromium.org/434443003

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287703 0039d316-1c4b-4281-b951-d872f2087c98
parent 47a6449e
......@@ -9,10 +9,10 @@ import urlparse
from integration_tests import chrome_proxy_metrics as metrics
from metrics import loading
from telemetry.core import util
from telemetry.page import page_measurement
from telemetry.page import page_test
class ChromeProxyLatency(page_measurement.PageMeasurement):
class ChromeProxyLatency(page_test.PageTest):
"""Chrome proxy latency measurement."""
def __init__(self, *args, **kwargs):
......@@ -27,7 +27,7 @@ class ChromeProxyLatency(page_measurement.PageMeasurement):
loading.LoadingMetric().AddResults(tab, results)
class ChromeProxyDataSaving(page_measurement.PageMeasurement):
class ChromeProxyDataSaving(page_test.PageTest):
"""Chrome proxy data daving measurement."""
def __init__(self, *args, **kwargs):
super(ChromeProxyDataSaving, self).__init__(*args, **kwargs)
......@@ -44,7 +44,7 @@ class ChromeProxyDataSaving(page_measurement.PageMeasurement):
self._metrics.AddResultsForDataSaving(tab, results)
class ChromeProxyValidation(page_measurement.PageMeasurement):
class ChromeProxyValidation(page_test.PageTest):
"""Base class for all chrome proxy correctness measurements."""
def __init__(self, restart_after_each_page=False):
......@@ -245,7 +245,7 @@ class ChromeProxySmoke(ChromeProxyValidation):
'safebrowsing': [self._metrics.AddResultsForSafebrowsing],
}
if not self._page.name in page_to_metrics:
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'Invalid page name (%s) in smoke. Page name must be one of:\n%s' % (
self._page.name, page_to_metrics.keys()))
for add_result in page_to_metrics[self._page.name]:
......
......@@ -7,11 +7,11 @@ import logging
import os
from integration_tests import network_metrics
from telemetry.page import page_measurement
from telemetry.page import page_test
from telemetry.value import scalar
class ChromeProxyMetricException(page_measurement.MeasurementFailure):
class ChromeProxyMetricException(page_test.MeasurementFailure):
pass
......
......@@ -10,14 +10,14 @@ import logging
import zlib
from metrics import Metric
from telemetry.page import page_measurement
from telemetry.page import page_test
# All network metrics are Chrome only for now.
from telemetry.core.backends.chrome import inspector_network
from telemetry.timeline import recording_options
from telemetry.value import scalar
class NetworkMetricException(page_measurement.MeasurementFailure):
class NetworkMetricException(page_test.MeasurementFailure):
pass
......
......@@ -6,12 +6,11 @@ import sys
import time
from telemetry.core.util import TimeoutException
from telemetry.page import page_measurement
from telemetry.page import page_test
from telemetry.value import scalar
class RasterizeAndRecordMicro(page_measurement.PageMeasurement):
class RasterizeAndRecordMicro(page_test.PageTest):
def __init__(self):
super(RasterizeAndRecordMicro, self).__init__('')
self._chrome_branch_number = None
......@@ -83,7 +82,7 @@ class RasterizeAndRecordMicro(page_measurement.PageMeasurement):
benchmark_id = tab.EvaluateJavaScript('window.benchmark_results.id')
if (not benchmark_id):
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'Failed to schedule rasterize_and_record_micro')
tab.WaitForJavaScriptExpression(
......
......@@ -3,10 +3,10 @@
# found in the LICENSE file.
from measurements import smoothness_controller
from telemetry.page import page_measurement
from telemetry.page import page_test
class Repaint(page_measurement.PageMeasurement):
class Repaint(page_test.PageTest):
def __init__(self):
super(Repaint, self).__init__('RunRepaint', False)
self._smoothness_controller = None
......@@ -62,7 +62,7 @@ class Repaint(page_measurement.PageMeasurement):
self._micro_benchmark_id = tab.EvaluateJavaScript(
'window.benchmark_results.id')
if (not self._micro_benchmark_id):
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'Failed to schedule invalidation_benchmark.')
def DidRunActions(self, page, tab):
......
......@@ -4,14 +4,14 @@
import glob
import os
from telemetry.page import page_measurement
from telemetry.page import page_test
from telemetry.value import scalar
_JS = 'chrome.gpuBenchmarking.printToSkPicture("{0}");'
class SkpicturePrinter(page_measurement.PageMeasurement):
class SkpicturePrinter(page_test.PageTest):
@classmethod
def AddCommandLineArgs(cls, parser):
parser.add_option('-s', '--skp-outdir',
......@@ -30,7 +30,7 @@ class SkpicturePrinter(page_measurement.PageMeasurement):
def MeasurePage(self, page, tab, results):
if tab.browser.platform.GetOSName() in ['android', 'chromeos']:
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'SkPicture printing not supported on this platform')
# Replace win32 path separator char '\' with '\\'.
......
......@@ -5,7 +5,7 @@ import sys
from measurements import smooth_gesture_util
from telemetry.timeline.model import TimelineModel
from telemetry.page import page_measurement
from telemetry.page import page_test
from telemetry.page.actions import action_runner
from telemetry.value import list_of_scalar_values
from telemetry.value import scalar
......@@ -22,7 +22,7 @@ DESCRIPTIONS = {
}
class MissingDisplayFrameRateError(page_measurement.MeasurementFailure):
class MissingDisplayFrameRateError(page_test.MeasurementFailure):
def __init__(self, name):
super(MissingDisplayFrameRateError, self).__init__(
'Missing display frame rate metrics: ' + name)
......
......@@ -5,44 +5,8 @@
from telemetry.page import page_test
class MeasurementFailure(page_test.Failure):
"""Exception that can be thrown from MeasurePage to indicate an undesired but
designed-for problem."""
class PageMeasurement(page_test.PageTest):
"""Glue code for running a measurement across a set of pages.
To use this, subclass from the measurement and override MeasurePage. For
example:
class BodyChildElementMeasurement(PageMeasurement):
def MeasurePage(self, page, tab, results):
body_child_count = tab.EvaluateJavaScript(
'document.body.children.length')
results.AddValue(scalar.ScalarValue(
page, 'body_children', 'count', body_child_count))
if __name__ == '__main__':
page_measurement.Main(BodyChildElementMeasurement())
To add test-specific options:
class BodyChildElementMeasurement(PageMeasurement):
def AddCommandLineArgs(parser):
parser.add_option('--element', action='store', default='body')
def MeasurePage(self, page, tab, results):
body_child_count = tab.EvaluateJavaScript(
'document.querySelector('%s').children.length')
results.AddValue(scalar.ScalarValue(
page, 'children', 'count', child_count))
is_action_name_to_run_optional determines what to do if action_name_to_run is
not empty but the page doesn't have that action. The page will run (without
any action) if is_action_name_to_run_optional is True, otherwise the page will
fail.
"""
"""DEPRECATED: Please extend page_test.PageTest directly."""
def __init__(self,
action_name_to_run='',
needs_browser_restart_after_each_page=False,
......@@ -55,30 +19,3 @@ class PageMeasurement(page_test.PageTest):
discard_first_result,
clear_cache_before_each_run,
is_action_name_to_run_optional=is_action_name_to_run_optional)
def ValidatePage(self, page, tab, results):
self.MeasurePage(page, tab, results)
def MeasurePage(self, page, tab, results):
"""Override to actually measure the page's performance.
page is a page_set.Page
tab is an instance of telemetry.core.Tab
Should call results.AddValue(...) for each result, or raise an
exception on failure. The name and units of each Add() call must be
the same across all iterations. The name 'url' must not be used.
Prefer field names that are in accordance with python variable style. E.g.
field_name.
Put together:
def MeasurePage(self, page, tab, results):
res = tab.EvaluateJavaScript('2+2')
if res != 4:
raise Exception('Oh, wow.')
results.AddValue(scalar.ScalarValue(
page, 'two_plus_two', 'count', res))
"""
raise NotImplementedError()
......@@ -9,53 +9,53 @@ from telemetry import benchmark
from telemetry.core import exceptions
from telemetry.core import wpr_modes
from telemetry.page import page as page_module
from telemetry.page import page_measurement
from telemetry.page import page_measurement_unittest_base
from telemetry.page import page_set
from telemetry.page import page_set_archive_info
from telemetry.page import page_test
from telemetry.unittest import options_for_unittests
from telemetry.value import scalar
class MeasurementThatFails(page_measurement.PageMeasurement):
class MeasurementThatFails(page_test.PageTest):
def MeasurePage(self, page, tab, results):
raise exceptions.IntentionalException
class MeasurementThatHasDefaults(page_measurement.PageMeasurement):
class MeasurementThatHasDefaults(page_test.PageTest):
def AddCommandLineArgs(self, parser):
parser.add_option('-x', dest='x', default=3)
def MeasurePage(self, page, tab, results):
if not hasattr(self.options, 'x'):
raise page_measurement.MeasurementFailure('Default option was not set.')
raise page_test.MeasurementFailure('Default option was not set.')
if self.options.x != 3:
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'Expected x == 3, got x == ' + self.options.x)
results.AddValue(scalar.ScalarValue(page, 'x', 'ms', 7))
class MeasurementForBlank(page_measurement.PageMeasurement):
class MeasurementForBlank(page_test.PageTest):
def MeasurePage(self, page, tab, results):
contents = tab.EvaluateJavaScript('document.body.textContent')
if contents.strip() != 'Hello world':
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'Page contents were: ' + contents)
class MeasurementForReplay(page_measurement.PageMeasurement):
class MeasurementForReplay(page_test.PageTest):
def MeasurePage(self, page, tab, results):
# Web Page Replay returns '404 Not found' if a page is not in the archive.
contents = tab.EvaluateJavaScript('document.body.textContent')
if '404 Not Found' in contents.strip():
raise page_measurement.MeasurementFailure('Page not in archive.')
raise page_test.MeasurementFailure('Page not in archive.')
class MeasurementQueryParams(page_measurement.PageMeasurement):
class MeasurementQueryParams(page_test.PageTest):
def MeasurePage(self, page, tab, results):
query = tab.EvaluateJavaScript('window.location.search')
expected = '?foo=1'
if query.strip() != expected:
raise page_measurement.MeasurementFailure(
raise page_test.MeasurementFailure(
'query was %s, not %s.' % (query, expected))
class MeasurementWithAction(page_measurement.PageMeasurement):
class MeasurementWithAction(page_test.PageTest):
def __init__(self):
super(MeasurementWithAction, self).__init__('RunTestAction')
......
......@@ -19,8 +19,56 @@ class TestNotSupportedOnPlatformFailure(Failure):
browser version."""
class MeasurementFailure(Failure):
"""Exception that can be thrown from MeasurePage to indicate an undesired but
designed-for problem."""
class PageTest(command_line.Command):
"""A class styled on unittest.TestCase for creating page-specific tests."""
"""A class styled on unittest.TestCase for creating page-specific tests.
This class also support running a measurement by default (but can be
overridden by overriding ValidatePage method).
To use this for measurement, subclass from the measurement and
override MeasurePage. For example:
class BodyChildElementMeasurement(PageTest):
def MeasurePage(self, page, tab, results):
body_child_count = tab.EvaluateJavaScript(
'document.body.children.length')
results.AddValue(scalar.ScalarValue(
page, 'body_children', 'count', body_child_count))
The class also provide hooks to add test-specific options. Here is
an example:
class BodyChildElementMeasurement(PageTest):
def AddCommandLineArgs(parser):
parser.add_option('--element', action='store', default='body')
def MeasurePage(self, page, tab, results):
body_child_count = tab.EvaluateJavaScript(
'document.querySelector('%s').children.length')
results.AddValue(scalar.ScalarValue(
page, 'children', 'count', child_count))
Args:
action_name_to_run: This is the method name in telemetry.page.Page
subclasses to run.
discard_first_run: Discard the first run of this page. This is
usually used with page_repeat and pageset_repeat options.
attempts: The number of attempts to run if we encountered
infrastructure problems (as opposed to test issues), such as
losing a browser.
max_failures: The number of page failures allowed before we stop
running other pages.
is_action_name_to_run_optional: Determines what to do if
action_name_to_run is not empty but the page doesn't have that
action. The page will run (without any action) if
is_action_name_to_run_optional is True, otherwise the page
will fail.
"""
options = {}
......@@ -218,8 +266,34 @@ class PageTest(command_line.Command):
def ValidatePage(self, page, tab, results):
"""Override to check the actual test assertions.
This is where most your test logic should go."""
raise NotImplementedError()
This is where most your test logic should go. By default it runs
self.MeasurePage.
"""
self.MeasurePage(page, tab, results)
def MeasurePage(self, page, tab, results):
"""Override to actually measure the page's performance.
Should call results.AddValue(...) for each result. Can raise an
exception of add a failure.FailureValue on failure.
Prefer metric value names that are in accordance with python
variable style. e.g., metric_name. The name 'url' must not be used.
Put together:
def MeasurePage(self, page, tab, results):
res = tab.EvaluateJavaScript('2+2')
if res != 4:
raise Exception('Oh, wow.')
results.AddValue(scalar.ScalarValue(
page, 'two_plus_two', 'count', res))
Args:
page: A telemetry.page.Page instance.
tab: A telemetry.core.Tab instance.
results: A telemetry.results.PageTestResults instance.
"""
def RunPage(self, page, tab, results):
# Run actions.
......
......@@ -4,7 +4,7 @@
import logging
from operator import attrgetter
from telemetry.page import page_measurement
from telemetry.page import page_test
from telemetry.web_perf.metrics import rendering_frame
# These are LatencyInfo component names indicating the various components
......@@ -19,7 +19,7 @@ BEGIN_COMP_NAME = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT'
END_COMP_NAME = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT'
class NotEnoughFramesError(page_measurement.MeasurementFailure):
class NotEnoughFramesError(page_test.MeasurementFailure):
def __init__(self, frame_count):
super(NotEnoughFramesError, self).__init__(
'Only %i frame timestamps were collected ' % frame_count +
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment