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

Unified Diff: tools/telemetry/telemetry/user_story/user_story_runner.py

Issue 1103163008: Move user_story.user_story_runner to story.story_runner. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move to internal, not story. Created 5 years, 8 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: tools/telemetry/telemetry/user_story/user_story_runner.py
diff --git a/tools/telemetry/telemetry/user_story/user_story_runner.py b/tools/telemetry/telemetry/user_story/user_story_runner.py
deleted file mode 100644
index a69b888fc76a5a6e36ac786fd4d2fca13abde8b3..0000000000000000000000000000000000000000
--- a/tools/telemetry/telemetry/user_story/user_story_runner.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# 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 logging
-import optparse
-import os
-import sys
-import time
-
-from telemetry.core import exceptions
-from telemetry.core import wpr_modes
-from telemetry.internal.actions import page_action
-from telemetry.page import page_test
-from telemetry.results import results_options
-from telemetry.story import story_filter
-from telemetry.util import cloud_storage
-from telemetry.util import exception_formatter
-from telemetry.value import failure
-from telemetry.value import skip
-
-
-class ArchiveError(Exception):
- pass
-
-
-def AddCommandLineArgs(parser):
- story_filter.StoryFilter.AddCommandLineArgs(parser)
- results_options.AddResultsOptions(parser)
-
- # Page set options
- group = optparse.OptionGroup(parser, 'Page set repeat options')
- group.add_option('--page-repeat', default=1, type='int',
- help='Number of times to repeat each individual page '
- 'before proceeding with the next page in the pageset.')
- group.add_option('--pageset-repeat', default=1, type='int',
- help='Number of times to repeat the entire pageset.')
- group.add_option('--max-failures', default=None, type='int',
- help='Maximum number of test failures before aborting '
- 'the run. Defaults to the number specified by the '
- 'PageTest.')
- parser.add_option_group(group)
-
- # WPR options
- group = optparse.OptionGroup(parser, 'Web Page Replay options')
- group.add_option('--use-live-sites',
- dest='use_live_sites', action='store_true',
- help='Run against live sites and ignore the Web Page Replay archives.')
- parser.add_option_group(group)
-
- parser.add_option('-d', '--also-run-disabled-tests',
- dest='run_disabled_tests',
- action='store_true', default=False,
- help='Ignore @Disabled and @Enabled restrictions.')
-
-def ProcessCommandLineArgs(parser, args):
- story_filter.StoryFilter.ProcessCommandLineArgs(parser, args)
- results_options.ProcessCommandLineArgs(parser, args)
-
- # Page set options
- if args.page_repeat < 1:
- parser.error('--page-repeat must be a positive integer.')
- if args.pageset_repeat < 1:
- parser.error('--pageset-repeat must be a positive integer.')
-
-
-def _RunUserStoryAndProcessErrorIfNeeded(expectations, user_story, results,
- state):
- def ProcessError():
- if expectation == 'fail':
- msg = 'Expected exception while running %s' % user_story.display_name
- exception_formatter.PrintFormattedException(msg=msg)
- else:
- msg = 'Exception while running %s' % user_story.display_name
- results.AddValue(failure.FailureValue(user_story, sys.exc_info()))
- try:
- expectation = None
- state.WillRunUserStory(user_story)
- expectation, skip_value = state.GetTestExpectationAndSkipValue(expectations)
- if expectation == 'skip':
- assert skip_value
- results.AddValue(skip_value)
- return
- state.RunUserStory(results)
- except (page_test.Failure, exceptions.TimeoutException,
- exceptions.LoginException, exceptions.ProfilingException):
- ProcessError()
- except exceptions.Error:
- ProcessError()
- raise
- except page_action.PageActionNotSupported as e:
- results.AddValue(
- skip.SkipValue(user_story, 'Unsupported page action: %s' % e))
- except Exception:
- results.AddValue(
- failure.FailureValue(
- user_story, sys.exc_info(), 'Unhandlable exception raised.'))
- raise
- else:
- if expectation == 'fail':
- logging.warning(
- '%s was expected to fail, but passed.\n', user_story.display_name)
- finally:
- has_existing_exception = sys.exc_info() is not None
- try:
- state.DidRunUserStory(results)
- except Exception:
- if not has_existing_exception:
- raise
- # Print current exception and propagate existing exception.
- exception_formatter.PrintFormattedException(
- msg='Exception from DidRunUserStory: ')
-
-class UserStoryGroup(object):
- def __init__(self, shared_state_class):
- self._shared_state_class = shared_state_class
- self._user_stories = []
-
- @property
- def shared_state_class(self):
- return self._shared_state_class
-
- @property
- def user_stories(self):
- return self._user_stories
-
- def AddUserStory(self, user_story):
- assert (user_story.shared_state_class is
- self._shared_state_class)
- self._user_stories.append(user_story)
-
-
-def StoriesGroupedByStateClass(user_story_set, allow_multiple_groups):
- """ Returns a list of user story groups which each contains user stories with
- the same shared_state_class.
-
- Example:
- Assume A1, A2, A3 are user stories with same shared user story class, and
- similar for B1, B2.
- If their orders in user story set is A1 A2 B1 B2 A3, then the grouping will
- be [A1 A2] [B1 B2] [A3].
-
- It's purposefully done this way to make sure that order of user
- stories are the same of that defined in user_story_set. It's recommended that
- user stories with the same states should be arranged next to each others in
- user story sets to reduce the overhead of setting up & tearing down the
- shared user story state.
- """
- user_story_groups = []
- user_story_groups.append(
- UserStoryGroup(user_story_set[0].shared_state_class))
- for user_story in user_story_set:
- if (user_story.shared_state_class is not
- user_story_groups[-1].shared_state_class):
- if not allow_multiple_groups:
- raise ValueError('This UserStorySet is only allowed to have one '
- 'SharedState but contains the following '
- 'SharedState classes: %s, %s.\n Either '
- 'remove the extra SharedStates or override '
- 'allow_mixed_story_states.' % (
- user_story_groups[-1].shared_state_class,
- user_story.shared_state_class))
- user_story_groups.append(
- UserStoryGroup(user_story.shared_state_class))
- user_story_groups[-1].AddUserStory(user_story)
- return user_story_groups
-
-
-def Run(test, user_story_set, expectations, finder_options, results,
- max_failures=None):
- """Runs a given test against a given page_set with the given options.
-
- Stop execution for unexpected exceptions such as KeyboardInterrupt.
- We "white list" certain exceptions for which the user story runner
- can continue running the remaining user stories.
- """
- # Filter page set based on options.
- user_stories = filter(story_filter.StoryFilter.IsSelected,
- user_story_set)
-
- if (not finder_options.use_live_sites and user_story_set.bucket and
- finder_options.browser_options.wpr_mode != wpr_modes.WPR_RECORD):
- serving_dirs = user_story_set.serving_dirs
- for directory in serving_dirs:
- cloud_storage.GetFilesInDirectoryIfChanged(directory,
- user_story_set.bucket)
- if not _UpdateAndCheckArchives(
- user_story_set.archive_data_file, user_story_set.wpr_archive_info,
- user_stories):
- return
-
- if not user_stories:
- return
-
- # Effective max failures gives priority to command-line flag value.
- effective_max_failures = finder_options.max_failures
- if effective_max_failures is None:
- effective_max_failures = max_failures
-
- user_story_groups = StoriesGroupedByStateClass(
- user_stories,
- user_story_set.allow_mixed_story_states)
-
- for group in user_story_groups:
- state = None
- try:
- for _ in xrange(finder_options.pageset_repeat):
- for user_story in group.user_stories:
- for _ in xrange(finder_options.page_repeat):
- if not state:
- state = group.shared_state_class(
- test, finder_options, user_story_set)
- results.WillRunPage(user_story)
- try:
- _WaitForThermalThrottlingIfNeeded(state.platform)
- _RunUserStoryAndProcessErrorIfNeeded(
- expectations, user_story, results, state)
- except exceptions.Error:
- # Catch all Telemetry errors to give the story a chance to retry.
- # The retry is enabled by tearing down the state and creating
- # a new state instance in the next iteration.
- try:
- # If TearDownState raises, do not catch the exception.
- # (The Error was saved as a failure value.)
- state.TearDownState(results)
- finally:
- # Later finally-blocks use state, so ensure it is cleared.
- state = None
- finally:
- has_existing_exception = sys.exc_info() is not None
- try:
- if state:
- _CheckThermalThrottling(state.platform)
- results.DidRunPage(user_story)
- except Exception:
- if not has_existing_exception:
- raise
- # Print current exception and propagate existing exception.
- exception_formatter.PrintFormattedException(
- msg='Exception from result processing:')
- if (effective_max_failures is not None and
- len(results.failures) > effective_max_failures):
- logging.error('Too many failures. Aborting.')
- return
- finally:
- if state:
- has_existing_exception = sys.exc_info() is not None
- try:
- state.TearDownState(results)
- except Exception:
- if not has_existing_exception:
- raise
- # Print current exception and propagate existing exception.
- exception_formatter.PrintFormattedException(
- msg='Exception from TearDownState:')
-
-
-def _UpdateAndCheckArchives(archive_data_file, wpr_archive_info,
- filtered_user_stories):
- """Verifies that all user stories are local or have WPR archives.
-
- Logs warnings and returns False if any are missing.
- """
- # Report any problems with the entire user story set.
- if any(not user_story.is_local for user_story in filtered_user_stories):
- if not archive_data_file:
- logging.error('The user story set is missing an "archive_data_file" '
- 'property.\nTo run from live sites pass the flag '
- '--use-live-sites.\nTo create an archive file add an '
- 'archive_data_file property to the user story set and then '
- 'run record_wpr.')
- raise ArchiveError('No archive data file.')
- if not wpr_archive_info:
- logging.error('The archive info file is missing.\n'
- 'To fix this, either add svn-internal to your '
- '.gclient using http://goto/read-src-internal, '
- 'or create a new archive using record_wpr.')
- raise ArchiveError('No archive info file.')
- wpr_archive_info.DownloadArchivesIfNeeded()
-
- # Report any problems with individual user story.
- user_stories_missing_archive_path = []
- user_stories_missing_archive_data = []
- for user_story in filtered_user_stories:
- if not user_story.is_local:
- archive_path = wpr_archive_info.WprFilePathForUserStory(user_story)
- if not archive_path:
- user_stories_missing_archive_path.append(user_story)
- elif not os.path.isfile(archive_path):
- user_stories_missing_archive_data.append(user_story)
- if user_stories_missing_archive_path:
- logging.error(
- 'The user story set archives for some user stories do not exist.\n'
- 'To fix this, record those user stories using record_wpr.\n'
- 'To ignore this warning and run against live sites, '
- 'pass the flag --use-live-sites.')
- logging.error(
- 'User stories without archives: %s',
- ', '.join(user_story.display_name
- for user_story in user_stories_missing_archive_path))
- if user_stories_missing_archive_data:
- logging.error(
- 'The user story set archives for some user stories are missing.\n'
- 'Someone forgot to check them in, uploaded them to the '
- 'wrong cloud storage bucket, or they were deleted.\n'
- 'To fix this, record those user stories using record_wpr.\n'
- 'To ignore this warning and run against live sites, '
- 'pass the flag --use-live-sites.')
- logging.error(
- 'User stories missing archives: %s',
- ', '.join(user_story.display_name
- for user_story in user_stories_missing_archive_data))
- if user_stories_missing_archive_path or user_stories_missing_archive_data:
- raise ArchiveError('Archive file is missing user stories.')
- # Only run valid user stories if no problems with the user story set or
- # individual user stories.
- return True
-
-
-def _WaitForThermalThrottlingIfNeeded(platform):
- if not platform.CanMonitorThermalThrottling():
- return
- thermal_throttling_retry = 0
- while (platform.IsThermallyThrottled() and
- thermal_throttling_retry < 3):
- logging.warning('Thermally throttled, waiting (%d)...',
- thermal_throttling_retry)
- thermal_throttling_retry += 1
- time.sleep(thermal_throttling_retry * 2)
-
- if thermal_throttling_retry and platform.IsThermallyThrottled():
- logging.warning('Device is thermally throttled before running '
- 'performance tests, results will vary.')
-
-
-def _CheckThermalThrottling(platform):
- if not platform.CanMonitorThermalThrottling():
- return
- if platform.HasBeenThermallyThrottled():
- logging.warning('Device has been thermally throttled during '
- 'performance tests, results will vary.')

Powered by Google App Engine
This is Rietveld 408576698