| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import logging | 5 import logging |
| 6 import optparse | 6 import optparse |
| 7 import os | 7 import os |
| 8 import sys | 8 import sys |
| 9 import time | 9 import time |
| 10 | 10 |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 164 'remove the extra SharedStates or override ' | 164 'remove the extra SharedStates or override ' |
| 165 'allow_mixed_story_states.' % ( | 165 'allow_mixed_story_states.' % ( |
| 166 story_groups[-1].shared_state_class, | 166 story_groups[-1].shared_state_class, |
| 167 story.shared_state_class)) | 167 story.shared_state_class)) |
| 168 story_groups.append( | 168 story_groups.append( |
| 169 StoryGroup(story.shared_state_class)) | 169 StoryGroup(story.shared_state_class)) |
| 170 story_groups[-1].AddStory(story) | 170 story_groups[-1].AddStory(story) |
| 171 return story_groups | 171 return story_groups |
| 172 | 172 |
| 173 | 173 |
| 174 def Run(test, story_set, finder_options, results, max_failures=None): | 174 def Run(test, story_set, finder_options, results, max_failures=None, |
| 175 should_tear_down_state_after_each_story_run=False): |
| 175 """Runs a given test against a given page_set with the given options. | 176 """Runs a given test against a given page_set with the given options. |
| 176 | 177 |
| 177 Stop execution for unexpected exceptions such as KeyboardInterrupt. | 178 Stop execution for unexpected exceptions such as KeyboardInterrupt. |
| 178 We "white list" certain exceptions for which the story runner | 179 We "white list" certain exceptions for which the story runner |
| 179 can continue running the remaining stories. | 180 can continue running the remaining stories. |
| 180 """ | 181 """ |
| 181 # Filter page set based on options. | 182 # Filter page set based on options. |
| 182 stories = filter(story_module.StoryFilter.IsSelected, story_set) | 183 stories = filter(story_module.StoryFilter.IsSelected, story_set) |
| 183 | 184 |
| 184 if (not finder_options.use_live_sites and story_set.bucket and | 185 if (not finder_options.use_live_sites and story_set.bucket and |
| (...skipping 19 matching lines...) Expand all Loading... |
| 204 stories, | 205 stories, |
| 205 story_set.allow_mixed_story_states) | 206 story_set.allow_mixed_story_states) |
| 206 | 207 |
| 207 for group in story_groups: | 208 for group in story_groups: |
| 208 state = None | 209 state = None |
| 209 try: | 210 try: |
| 210 for _ in xrange(finder_options.pageset_repeat): | 211 for _ in xrange(finder_options.pageset_repeat): |
| 211 for story in group.stories: | 212 for story in group.stories: |
| 212 for _ in xrange(finder_options.page_repeat): | 213 for _ in xrange(finder_options.page_repeat): |
| 213 if not state: | 214 if not state: |
| 215 # Construct shared state by using a copy of finder_options. Shared |
| 216 # state may update the finder_options. If we tear down the shared |
| 217 # state after this story run, we want to construct the shared |
| 218 # state for the next story from the original finder_options. |
| 214 state = group.shared_state_class( | 219 state = group.shared_state_class( |
| 215 test, finder_options, story_set) | 220 test, finder_options.Copy(), story_set) |
| 216 results.WillRunPage(story) | 221 results.WillRunPage(story) |
| 217 try: | 222 try: |
| 218 _WaitForThermalThrottlingIfNeeded(state.platform) | 223 _WaitForThermalThrottlingIfNeeded(state.platform) |
| 219 _RunStoryAndProcessErrorIfNeeded(story, results, state, test) | 224 _RunStoryAndProcessErrorIfNeeded(story, results, state, test) |
| 220 except exceptions.Error: | 225 except exceptions.Error: |
| 221 # Catch all Telemetry errors to give the story a chance to retry. | 226 # Catch all Telemetry errors to give the story a chance to retry. |
| 222 # The retry is enabled by tearing down the state and creating | 227 # The retry is enabled by tearing down the state and creating |
| 223 # a new state instance in the next iteration. | 228 # a new state instance in the next iteration. |
| 224 try: | 229 try: |
| 225 # If TearDownState raises, do not catch the exception. | 230 # If TearDownState raises, do not catch the exception. |
| 226 # (The Error was saved as a failure value.) | 231 # (The Error was saved as a failure value.) |
| 227 state.TearDownState() | 232 state.TearDownState() |
| 228 finally: | 233 finally: |
| 229 # Later finally-blocks use state, so ensure it is cleared. | 234 # Later finally-blocks use state, so ensure it is cleared. |
| 230 state = None | 235 state = None |
| 231 finally: | 236 finally: |
| 232 has_existing_exception = sys.exc_info() != (None, None, None) | 237 has_existing_exception = sys.exc_info() != (None, None, None) |
| 233 try: | 238 try: |
| 234 if state: | 239 if state: |
| 235 _CheckThermalThrottling(state.platform) | 240 _CheckThermalThrottling(state.platform) |
| 236 results.DidRunPage(story) | 241 results.DidRunPage(story) |
| 237 except Exception: | 242 except Exception: |
| 238 if not has_existing_exception: | 243 if not has_existing_exception: |
| 239 raise | 244 raise |
| 240 # Print current exception and propagate existing exception. | 245 # Print current exception and propagate existing exception. |
| 241 exception_formatter.PrintFormattedException( | 246 exception_formatter.PrintFormattedException( |
| 242 msg='Exception from result processing:') | 247 msg='Exception from result processing:') |
| 248 if state and should_tear_down_state_after_each_story_run: |
| 249 state.TearDownState() |
| 250 state = None |
| 243 if (effective_max_failures is not None and | 251 if (effective_max_failures is not None and |
| 244 len(results.failures) > effective_max_failures): | 252 len(results.failures) > effective_max_failures): |
| 245 logging.error('Too many failures. Aborting.') | 253 logging.error('Too many failures. Aborting.') |
| 246 return | 254 return |
| 247 finally: | 255 finally: |
| 248 if state: | 256 if state: |
| 249 has_existing_exception = sys.exc_info() != (None, None, None) | 257 has_existing_exception = sys.exc_info() != (None, None, None) |
| 250 try: | 258 try: |
| 251 state.TearDownState() | 259 state.TearDownState() |
| 252 except Exception: | 260 except Exception: |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 if any(not isinstance(p, page.Page) for p in stories.stories): | 300 if any(not isinstance(p, page.Page) for p in stories.stories): |
| 293 raise Exception( | 301 raise Exception( |
| 294 'PageTest must be used with StorySet containing only ' | 302 'PageTest must be used with StorySet containing only ' |
| 295 'telemetry.page.Page stories.') | 303 'telemetry.page.Page stories.') |
| 296 | 304 |
| 297 benchmark_metadata = benchmark.GetMetadata() | 305 benchmark_metadata = benchmark.GetMetadata() |
| 298 with results_options.CreateResults( | 306 with results_options.CreateResults( |
| 299 benchmark_metadata, finder_options, | 307 benchmark_metadata, finder_options, |
| 300 benchmark.ValueCanBeAddedPredicate) as results: | 308 benchmark.ValueCanBeAddedPredicate) as results: |
| 301 try: | 309 try: |
| 302 Run(pt, stories, finder_options, results, benchmark.max_failures) | 310 Run(pt, stories, finder_options, results, benchmark.max_failures, |
| 311 benchmark.ShouldTearDownStateAfterEachStoryRun()) |
| 303 return_code = min(254, len(results.failures)) | 312 return_code = min(254, len(results.failures)) |
| 304 except Exception: | 313 except Exception: |
| 305 exception_formatter.PrintFormattedException() | 314 exception_formatter.PrintFormattedException() |
| 306 return_code = 255 | 315 return_code = 255 |
| 307 | 316 |
| 308 try: | 317 try: |
| 309 bucket = cloud_storage.BUCKET_ALIASES[finder_options.upload_bucket] | 318 bucket = cloud_storage.BUCKET_ALIASES[finder_options.upload_bucket] |
| 310 if finder_options.upload_results: | 319 if finder_options.upload_results: |
| 311 results.UploadTraceFilesToCloud(bucket) | 320 results.UploadTraceFilesToCloud(bucket) |
| 312 results.UploadProfilingFilesToCloud(bucket) | 321 results.UploadProfilingFilesToCloud(bucket) |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 logging.warning('Device is thermally throttled before running ' | 401 logging.warning('Device is thermally throttled before running ' |
| 393 'performance tests, results will vary.') | 402 'performance tests, results will vary.') |
| 394 | 403 |
| 395 | 404 |
| 396 def _CheckThermalThrottling(platform): | 405 def _CheckThermalThrottling(platform): |
| 397 if not platform.CanMonitorThermalThrottling(): | 406 if not platform.CanMonitorThermalThrottling(): |
| 398 return | 407 return |
| 399 if platform.HasBeenThermallyThrottled(): | 408 if platform.HasBeenThermallyThrottled(): |
| 400 logging.warning('Device has been thermally throttled during ' | 409 logging.warning('Device has been thermally throttled during ' |
| 401 'performance tests, results will vary.') | 410 'performance tests, results will vary.') |
| OLD | NEW |