Commit 7f4660dc authored by nednguyen's avatar nednguyen Committed by Commit bot

[Telemetry] Introduce shared_user_story_state for real.

Move page.page_runner --> user_story.user_story_runner.

BUG=418278

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

Cr-Commit-Position: refs/heads/master@{#305119}
parent 53513eb6
......@@ -5,9 +5,9 @@
import unittest
from telemetry.core import browser_options
from telemetry.page import page_runner
from telemetry.results import page_test_results
from telemetry.unittest_util import simple_mock
from telemetry.user_story import user_story_runner
from measurements import page_cycler
......@@ -106,11 +106,11 @@ class PageCyclerUnitTest(unittest.TestCase):
options = browser_options.BrowserFinderOptions()
options.browser_options.platform = FakePlatform()
parser = options.CreateParser()
page_runner.AddCommandLineArgs(parser)
user_story_runner.AddCommandLineArgs(parser)
args = ['--page-repeat=%i' % page_repeat,
'--pageset-repeat=%i' % pageset_repeat]
parser.parse_args(args)
page_runner.ProcessCommandLineArgs(parser, options)
user_story_runner.ProcessCommandLineArgs(parser, options)
cycler.CustomizeBrowserOptions(options.browser_options)
if setup_memory_module:
......
......@@ -206,7 +206,7 @@ class ExtensionsProfileCreator(profile_creator.ProfileCreator):
# Phase 1: When the first page is loaded: we wait for a timeout to allow
# all extensions to install and to prime safe browsing and other
# caches. Extensions may open tabs as part of the install process.
# Phase 2: When the second page loads, page_runner closes all tabs -
# Phase 2: When the second page loads, user_story_runner closes all tabs -
# we are left with one open tab, wait for that to finish loading.
# Sleep for a bit to allow safe browsing and other data to load +
......
......@@ -13,7 +13,7 @@ from telemetry import decorators
from telemetry.core import browser_finder
from telemetry.core import command_line
from telemetry.core import util
from telemetry.page import page_runner
from telemetry.user_story import user_story_runner
from telemetry.page import page_set
from telemetry.page import page_test
from telemetry.page import test_expectations
......@@ -102,7 +102,7 @@ class Benchmark(command_line.Command):
benchmark_metadata = self.GetMetadata()
results = results_options.CreateResults(benchmark_metadata, finder_options)
try:
page_runner.Run(pt, us, expectations, finder_options, results)
user_story_runner.Run(pt, us, expectations, finder_options, results)
except page_test.TestNotSupportedOnPlatformFailure as failure:
logging.warning(str(failure))
......@@ -215,8 +215,8 @@ class Benchmark(command_line.Command):
def AddCommandLineArgs(parser):
page_runner.AddCommandLineArgs(parser)
user_story_runner.AddCommandLineArgs(parser)
def ProcessCommandLineArgs(parser, args):
page_runner.ProcessCommandLineArgs(parser, args)
user_story_runner.ProcessCommandLineArgs(parser, args)
......@@ -10,7 +10,6 @@ from telemetry.core import util
from telemetry.core.backends import codepen_credentials_backend
from telemetry.core.backends import facebook_credentials_backend
from telemetry.core.backends import google_credentials_backend
from telemetry.page.actions import action_runner
from telemetry.unittest_util import options_for_unittests
......@@ -59,6 +58,7 @@ class BrowserCredentials(object):
'Unrecognized credentials type: %s', credentials_type)
if credentials_type not in self._credentials:
return False
from telemetry.page.actions import action_runner
runner = action_runner.ActionRunner(tab)
return self._backends[credentials_type].LoginNeeded(
tab, runner, self._credentials[credentials_type])
......
......@@ -7,6 +7,7 @@ import os
import urlparse
from telemetry import user_story
from telemetry.page import shared_page_state
from telemetry.util import cloud_storage
from telemetry.util import path
......@@ -24,7 +25,7 @@ def _UpdateCredentials(credentials_path):
class Page(user_story.UserStory):
def __init__(self, url, page_set=None, base_dir=None, name='',
credentials_path=None, labels=None):
super(Page, self).__init__(name, labels)
super(Page, self).__init__(shared_page_state.SharedPageState, name, labels)
self._url = url
self._page_set = page_set
# Default value of base_dir is the directory of the file that defines the
......
......@@ -16,10 +16,10 @@ from telemetry import benchmark
from telemetry.core import browser_options
from telemetry.core import discover
from telemetry.core import util
from telemetry.page import page_runner
from telemetry.page import profile_creator
from telemetry.page import test_expectations
from telemetry.results import results_options
from telemetry.user_story import user_story_runner
def _DiscoverProfileCreatorClasses():
......@@ -76,7 +76,7 @@ def GenerateProfiles(profile_creator_class, profile_creator_name, options):
results = results_options.CreateResults(
benchmark.BenchmarkMetadata(test.__class__.__name__), options)
page_runner.Run(test, test.page_set, expectations, options, results)
user_story_runner.Run(test, test.page_set, expectations, options, results)
if results.failures:
logging.warning('Some pages failed.')
......@@ -100,7 +100,7 @@ def GenerateProfiles(profile_creator_class, profile_creator_name, options):
def AddCommandLineArgs(parser):
page_runner.AddCommandLineArgs(parser)
user_story_runner.AddCommandLineArgs(parser)
profile_creators = _DiscoverProfileCreatorClasses().keys()
legal_profile_creators = '|'.join(profile_creators)
......@@ -114,7 +114,7 @@ def AddCommandLineArgs(parser):
def ProcessCommandLineArgs(parser, args):
page_runner.ProcessCommandLineArgs(parser, args)
user_story_runner.ProcessCommandLineArgs(parser, args)
if not args.profile_type_to_generate:
parser.error("Must specify --profile-type-to-generate option.")
......
......@@ -10,12 +10,12 @@ from telemetry.core import browser_options
from telemetry.core import discover
from telemetry.core import util
from telemetry.core import wpr_modes
from telemetry.page import page_runner
from telemetry.page import page_set
from telemetry.page import page_test
from telemetry.page import profile_creator
from telemetry.page import test_expectations
from telemetry.results import results_options
from telemetry.user_story import user_story_runner
class RecorderPageTest(page_test.PageTest): # pylint: disable=W0223
......@@ -154,7 +154,7 @@ class WprRecorder(object):
def _AddCommandLineArgs(self):
self._parser.add_option('--page-set-base-dir', action='store',
type='string')
page_runner.AddCommandLineArgs(self._parser)
user_story_runner.AddCommandLineArgs(self._parser)
if self._benchmark is not None:
self._benchmark.AddCommandLineArgs(self._parser)
self._benchmark.SetArgumentDefaults(self._parser)
......@@ -168,7 +168,7 @@ class WprRecorder(object):
self._parser.parse_args(args_to_parse)
def _ProcessCommandLineArgs(self):
page_runner.ProcessCommandLineArgs(self._parser, self._options)
user_story_runner.ProcessCommandLineArgs(self._parser, self._options)
if self._benchmark is not None:
self._benchmark.ProcessCommandLineArgs(self._parser, self._options)
......@@ -186,7 +186,7 @@ class WprRecorder(object):
'Pageset archive_data_file path must be specified.')
self._page_set.wpr_archive_info.AddNewTemporaryRecording()
self._record_page_test.CustomizeBrowserOptions(self._options)
page_runner.Run(self._record_page_test, self._page_set,
user_story_runner.Run(self._record_page_test, self._page_set,
test_expectations.TestExpectations(), self._options, results)
def HandleResults(self, results):
......
......@@ -12,6 +12,7 @@ from telemetry.core import browser_info
from telemetry.core import util
from telemetry.core import wpr_modes
from telemetry.page import page_test
from telemetry.user_story import shared_user_story_state
from telemetry.util import file_handle
from telemetry.value import skip
from telemetry.core.platform.profiler import profiler_finder
......@@ -28,10 +29,11 @@ def _PrepareFinderOptions(finder_options, test, page_set):
profiler_class.CustomizeBrowserOptions(browser_options.browser_type,
finder_options)
class SharedPageState(object):
def __init__(self, test, finder_options, page_set):
class SharedPageState(shared_user_story_state.SharedUserStoryState):
def __init__(self, test, finder_options, user_story_set):
super(SharedPageState, self).__init__(test, finder_options, user_story_set)
self.browser = None
_PrepareFinderOptions(finder_options, test, page_set)
_PrepareFinderOptions(finder_options, test, user_story_set)
self._finder_options = finder_options
self._possible_browser = self._GetPossibleBrowser(test, finder_options)
......@@ -64,7 +66,7 @@ class SharedPageState(object):
sys.exit(0)
return possible_browser
def DidRunPage(self, results):
def DidRunUserStory(self, results):
if self._finder_options.profiler:
self._StopProfiling(results)
util.CloseConnections(self._current_tab)
......@@ -103,7 +105,8 @@ class SharedPageState(object):
archive_path, wpr_mode, browser_options.netsim,
browser_options.extra_wpr_args, make_javascript_deterministic)
def WillRunPage(self, page, page_set):
def WillRunUserStory(self, page):
page_set = page.page_set
self._current_page = page
if self._test.RestartBrowserBeforeEachPage() or page.startup_url:
self._StopBrowser()
......@@ -178,7 +181,7 @@ class SharedPageState(object):
if self._finder_options.profiler:
self._StartProfiling(self._current_page)
def GetPageExpectationAndSkipValue(self, expectations):
def GetTestExpectationAndSkipValue(self, expectations):
skip_value = None
if not self._current_page.CanRunOnBrowser(
browser_info.BrowserInfo(self.browser)):
......@@ -220,14 +223,15 @@ class SharedPageState(object):
self._test.RunNavigateSteps(self._current_page, self._current_tab)
self._test.DidNavigateToPage(self._current_page, self._current_tab)
def RunPage(self, results):
def RunUserStory(self, results):
self._PreparePage()
self._ImplicitPageNavigation()
self._test.RunPage(self._current_page, self._current_tab, results)
def TearDown(self, results):
# NOTE: this is a HACK to get page_runner to be generic enough for any
# user_story. Other SharedUserStory should not call DidRunTest this way.
def TearDownState(self, results):
# NOTE: this is a HACK to get user_story_runner to be generic enough for any
# user_story while maintaing existing usecases of page tests. Other
# SharedUserStory should not call DidRunTest this way.
self._test.DidRunTest(self.browser, results)
self._StopBrowser()
......
......@@ -7,17 +7,17 @@ import unittest
from telemetry.core import wpr_modes
from telemetry.page import shared_page_state
from telemetry.page import page_runner
from telemetry.page import page_set
from telemetry.page import page_test
from telemetry.unittest_util import options_for_unittests
from telemetry.user_story import user_story_runner
def SetUpPageRunnerArguments(options):
parser = options.CreateParser()
page_runner.AddCommandLineArgs(parser)
user_story_runner.AddCommandLineArgs(parser)
options.MergeDefaultValues(parser.get_default_values())
page_runner.ProcessCommandLineArgs(parser, options)
user_story_runner.ProcessCommandLineArgs(parser, options)
class DummyTest(page_test.PageTest):
......
......@@ -10,12 +10,12 @@ from telemetry import benchmark
from telemetry.core import exceptions
from telemetry.core import util
from telemetry.page import page as page_module
from telemetry.page import page_runner
from telemetry.page import page_set as page_set_module
from telemetry.page import page_test
from telemetry.page import test_expectations
from telemetry.results import results_options
from telemetry.unittest_util import options_for_unittests
from telemetry.user_story import user_story_runner
class BasicTestPage(page_module.Page):
......@@ -56,7 +56,7 @@ class PageTestTestCase(unittest.TestCase):
options = options_for_unittests.GetCopy()
assert options
temp_parser = options.CreateParser()
page_runner.AddCommandLineArgs(temp_parser)
user_story_runner.AddCommandLineArgs(temp_parser)
defaults = temp_parser.get_default_values()
for k, v in defaults.__dict__.items():
if hasattr(options, k):
......@@ -68,9 +68,9 @@ class PageTestTestCase(unittest.TestCase):
options.output_formats = ['none']
options.suppress_gtest_report = True
options.output_trace_tag = None
page_runner.ProcessCommandLineArgs(temp_parser, options)
user_story_runner.ProcessCommandLineArgs(temp_parser, options)
results = results_options.CreateResults(EmptyMetadataForTest(), options)
page_runner.Run(measurement, ps, expectations, options, results)
user_story_runner.Run(measurement, ps, expectations, options, results)
return results
def TestTracingCleanedUp(self, measurement_class, options=None):
......
......@@ -3,12 +3,32 @@
# found in the LICENSE file.
import re
from telemetry.user_story import shared_user_story_state
_next_user_story_id = 0
class UserStory(object):
def __init__(self, name='', labels=None):
"""A class styled on unittest.TestCase for creating user story tests.
Test should override Run to maybe start the application and perform actions
onto it. To share state between different tests, one can define a
shared_user_story_state which contains hooks that will be called before &
after mutiple user stories run and in between runs.
Args:
shared_user_story_state_class: subclass of
telemetry.user_story.shared_user_story_state.SharedUserStoryState.
name: string name of this user story that can be used for identifying user
story in results output.
labels: A list or set of string labels that are used for filtering. See
user_story.user_story_filter for more information.
"""
def __init__(self, shared_user_story_state_class, name='', labels=None):
assert issubclass(shared_user_story_state_class,
shared_user_story_state.SharedUserStoryState)
self._shared_user_story_state_class = shared_user_story_state_class
self._name = name
global _next_user_story_id
self._id = _next_user_story_id
......@@ -25,6 +45,10 @@ class UserStory(object):
def labels(self):
return self._labels
@property
def shared_user_story_state_class(self):
return self._shared_user_story_state_class
@property
def id(self):
return self._id
......
# Copyright 2014 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.
class SharedUserStoryState(object):
"""A class that manages the test state across multiple user stories.
It's styled on unittest.TestCase for handling test setup & teardown logic.
"""
def __init__(self, test, options, user_story_set):
""" This method is styled on unittest.TestCase.setUpClass.
Override to do any action before running user stories that
share this same state.
Args:
test: a page_test.PageTest instance.
options: a BrowserFinderOptions instance that contains command line
options.
user_story_set: a user_story_set.UserStorySet instance.
"""
pass
@property
def platform(self):
""" Override to return the platform which user stories that share this same
state will be run on.
"""
raise NotImplementedError()
def WillRunUserStory(self, user_story):
""" Override to do any action before running each one of all user stories
that share this same state.
This method is styled on unittest.TestCase.setUp.
"""
raise NotImplementedError()
def DidRunUserStory(self, results):
""" Override to do any action after running each of all user stories that
share this same state.
This method is styled on unittest.TestCase.tearDown.
"""
raise NotImplementedError()
def GetTestExpectationAndSkipValue(self, expectations):
""" Return test expectation and skip value instance in case expectation
is 'skip'. This is run after WillRunUserStory and before RunUserStory.
"""
raise NotImplementedError()
def RunUserStory(self, results):
""" Override to do any action before running each one of all user stories
that share this same state.
This method is styled on unittest.TestCase.run.
"""
raise NotImplementedError()
def TearDownState(self, results):
""" Override to do any action after running multiple user stories that
share this same state.
This method is styled on unittest.TestCase.tearDownClass.
"""
raise NotImplementedError()
# Copyright 2014 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.
import unittest
from telemetry import benchmark
from telemetry import user_story
from telemetry.page import page_test
from telemetry.page import test_expectations
from telemetry.results import results_options
from telemetry.unittest_util import options_for_unittests
from telemetry.user_story import shared_user_story_state
from telemetry.user_story import user_story_runner
from telemetry.user_story import user_story_set
class FakePlatform(object):
def CanMonitorThermalThrottling(self):
return False
class TestSharedUserStoryState(shared_user_story_state.SharedUserStoryState):
_platform = FakePlatform()
@classmethod
def SetTestPlatform(cls, platform):
cls._platform = platform
def __init__(self, test, options, user_story_setz):
super(TestSharedUserStoryState, self).__init__(
test, options, user_story_setz)
@property
def platform(self):
return self._platform
def WillRunUserStory(self, user_storyz):
pass
def GetTestExpectationAndSkipValue(self, expectations):
return 'pass', None
def RunUserStory(self, results):
pass
def DidRunUserStory(self, results):
pass
def TearDownState(self, results):
pass
class FooUserStoryState(TestSharedUserStoryState):
pass
class BarUserStoryState(TestSharedUserStoryState):
pass
class DummyTest(page_test.PageTest):
def ValidatePage(self, *_):
pass
class EmptyMetadataForTest(benchmark.BenchmarkMetadata):
def __init__(self):
super(EmptyMetadataForTest, self).__init__('')
def _GetOptionForUnittest():
options = options_for_unittests.GetCopy()
options.output_formats = ['none']
options.suppress_gtest_report = True
parser = options.CreateParser()
user_story_runner.AddCommandLineArgs(parser)
options.MergeDefaultValues(parser.get_default_values())
user_story_runner.ProcessCommandLineArgs(parser, options)
return options
class UserStoryRunnerTest(unittest.TestCase):
def setUp(self):
self.options = _GetOptionForUnittest()
self.expectations = test_expectations.TestExpectations()
self.results = results_options.CreateResults(
EmptyMetadataForTest(), self.options)
def testGetUserStoryGroupsWithSameSharedUserStoryClass(self):
us = user_story_set.UserStorySet()
us.AddUserStory(user_story.UserStory(FooUserStoryState))
us.AddUserStory(user_story.UserStory(FooUserStoryState))
us.AddUserStory(user_story.UserStory(BarUserStoryState))
us.AddUserStory(user_story.UserStory(FooUserStoryState))
story_groups = (
user_story_runner.GetUserStoryGroupsWithSameSharedUserStoryClass(
us))
self.assertEqual(len(story_groups), 3)
self.assertEqual(story_groups[0].shared_user_story_state_class,
FooUserStoryState)
self.assertEqual(story_groups[1].shared_user_story_state_class,
BarUserStoryState)
self.assertEqual(story_groups[2].shared_user_story_state_class,
FooUserStoryState)
def testSuccefulUserStoryTest(self):
us = user_story_set.UserStorySet()
us.AddUserStory(user_story.UserStory(FooUserStoryState))
us.AddUserStory(user_story.UserStory(FooUserStoryState))
us.AddUserStory(user_story.UserStory(BarUserStoryState))
user_story_runner.Run(
DummyTest(), us, self.expectations, self.options, self.results)
self.assertEquals(0, len(self.results.failures))
self.assertEquals(3, len(self.results.pages_that_succeeded))
......@@ -34,6 +34,9 @@ class UserStorySet(object):
else:
return ''
def ShuffleAndFilterUserStorySet(self, finder_options):
pass
def __iter__(self):
return self.user_stories.__iter__()
......
......@@ -5,15 +5,24 @@
import unittest
from telemetry import user_story
from telemetry.user_story import shared_user_story_state
class UserStoryFoo(user_story.UserStory):
# pylint: disable=abstract-method
class SharedUserStoryStateBar(shared_user_story_state.SharedUserStoryState):
pass
class UserStoryFoo(user_story.UserStory):
def __init__(self, name='', labels=None):
super(UserStoryFoo, self).__init__(
SharedUserStoryStateBar, name, labels)
class UserStoryTest(unittest.TestCase):
def testUserStoriesHaveDifferentIds(self):
u0 = user_story.UserStory('foo')
u1 = user_story.UserStory('bar')
u0 = user_story.UserStory(SharedUserStoryStateBar, 'foo')
u1 = user_story.UserStory(SharedUserStoryStateBar, 'bar')
self.assertNotEqual(u0.id, u1.id)
def testNamelessUserStoryDisplayName(self):
......@@ -29,13 +38,13 @@ class UserStoryTest(unittest.TestCase):
self.assertEquals('Foo_Bar_Baz_0', u.file_safe_name)
def testNamelessUserStoryAsDict(self):
u = user_story.UserStory()
u = user_story.UserStory(SharedUserStoryStateBar)
u_dict = u.AsDict()
self.assertEquals(u_dict['id'], u.id)
self.assertNotIn('name', u_dict)
def testNamedUserStoryAsDict(self):
u = user_story.UserStory('Foo')
u = user_story.UserStory(SharedUserStoryStateBar, 'Foo')
u_dict = u.AsDict()
self.assertEquals(u_dict['id'], u.id)
self.assertEquals('Foo', u_dict['name'])
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