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 unittest | 5 import unittest |
| 6 import StringIO |
| 7 import sys |
6 | 8 |
7 from telemetry import benchmark | 9 from telemetry import benchmark |
8 from telemetry import user_story | 10 from telemetry import user_story |
| 11 from telemetry.core import exceptions |
9 from telemetry.page import page_test | 12 from telemetry.page import page_test |
10 from telemetry.page import test_expectations | 13 from telemetry.page import test_expectations |
11 from telemetry.results import results_options | 14 from telemetry.results import results_options |
12 from telemetry.unittest_util import options_for_unittests | 15 from telemetry.unittest_util import options_for_unittests |
| 16 from telemetry.unittest_util import system_stub |
13 from telemetry.user_story import shared_user_story_state | 17 from telemetry.user_story import shared_user_story_state |
14 from telemetry.user_story import user_story_runner | 18 from telemetry.user_story import user_story_runner |
15 from telemetry.user_story import user_story_set | 19 from telemetry.user_story import user_story_set |
| 20 from telemetry.util import exception_formatter as exception_formatter_module |
| 21 from telemetry.value import scalar |
| 22 from telemetry.value import string |
16 | 23 |
17 | 24 |
18 class FakePlatform(object): | 25 class FakePlatform(object): |
19 def CanMonitorThermalThrottling(self): | 26 def CanMonitorThermalThrottling(self): |
20 return False | 27 return False |
21 | 28 |
22 | 29 |
23 class TestSharedUserStoryState(shared_user_story_state.SharedUserStoryState): | 30 class TestSharedUserStoryState(shared_user_story_state.SharedUserStoryState): |
24 | 31 |
25 _platform = FakePlatform() | 32 _platform = FakePlatform() |
26 | 33 |
27 @classmethod | 34 @classmethod |
28 def SetTestPlatform(cls, platform): | 35 def SetTestPlatform(cls, platform): |
29 cls._platform = platform | 36 cls._platform = platform |
30 | 37 |
31 def __init__(self, test, options, user_story_setz): | 38 def __init__(self, test, options, user_story_setz): |
32 super(TestSharedUserStoryState, self).__init__( | 39 super(TestSharedUserStoryState, self).__init__( |
33 test, options, user_story_setz) | 40 test, options, user_story_setz) |
| 41 self._test = test |
| 42 self._current_user_story = None |
34 | 43 |
35 @property | 44 @property |
36 def platform(self): | 45 def platform(self): |
37 return self._platform | 46 return self._platform |
38 | 47 |
39 def WillRunUserStory(self, user_storyz): | 48 def WillRunUserStory(self, user_storyz): |
40 pass | 49 self._current_user_story = user_storyz |
41 | 50 |
42 def GetTestExpectationAndSkipValue(self, expectations): | 51 def GetTestExpectationAndSkipValue(self, expectations): |
43 return 'pass', None | 52 return 'pass', None |
44 | 53 |
45 def RunUserStory(self, results): | 54 def RunUserStory(self, results): |
46 pass | 55 self._test.RunPage(self._current_user_story, None, results) |
| 56 |
47 | 57 |
48 def DidRunUserStory(self, results): | 58 def DidRunUserStory(self, results): |
49 pass | 59 pass |
50 | 60 |
51 def TearDownState(self, results): | 61 def TearDownState(self, results): |
52 pass | 62 pass |
53 | 63 |
54 | 64 |
55 class FooUserStoryState(TestSharedUserStoryState): | 65 class FooUserStoryState(TestSharedUserStoryState): |
56 pass | 66 pass |
57 | 67 |
58 | 68 |
59 class BarUserStoryState(TestSharedUserStoryState): | 69 class BarUserStoryState(TestSharedUserStoryState): |
60 pass | 70 pass |
61 | 71 |
62 | 72 |
63 class DummyTest(page_test.PageTest): | 73 class DummyTest(page_test.PageTest): |
64 def ValidatePage(self, *_): | 74 def RunPage(self, *_): |
65 pass | 75 pass |
66 | 76 |
67 | 77 |
68 class EmptyMetadataForTest(benchmark.BenchmarkMetadata): | 78 class EmptyMetadataForTest(benchmark.BenchmarkMetadata): |
69 def __init__(self): | 79 def __init__(self): |
70 super(EmptyMetadataForTest, self).__init__('') | 80 super(EmptyMetadataForTest, self).__init__('') |
71 | 81 |
72 | 82 |
73 def _GetOptionForUnittest(): | 83 def _GetOptionForUnittest(): |
74 options = options_for_unittests.GetCopy() | 84 options = options_for_unittests.GetCopy() |
75 options.output_formats = ['none'] | 85 options.output_formats = ['none'] |
76 options.suppress_gtest_report = True | 86 options.suppress_gtest_report = True |
77 parser = options.CreateParser() | 87 parser = options.CreateParser() |
78 user_story_runner.AddCommandLineArgs(parser) | 88 user_story_runner.AddCommandLineArgs(parser) |
79 options.MergeDefaultValues(parser.get_default_values()) | 89 options.MergeDefaultValues(parser.get_default_values()) |
80 user_story_runner.ProcessCommandLineArgs(parser, options) | 90 user_story_runner.ProcessCommandLineArgs(parser, options) |
81 return options | 91 return options |
82 | 92 |
83 | 93 |
| 94 class FakeExceptionFormatterModule(object): |
| 95 @staticmethod |
| 96 def PrintFormattedException( |
| 97 exception_class=None, exception=None, tb=None, msg=None): |
| 98 pass |
| 99 |
| 100 |
| 101 def GetNumberOfSuccessfulPageRuns(results): |
| 102 return len([run for run in results.all_page_runs if run.ok or run.skipped]) |
| 103 |
| 104 |
84 class UserStoryRunnerTest(unittest.TestCase): | 105 class UserStoryRunnerTest(unittest.TestCase): |
85 | 106 |
86 def setUp(self): | 107 def setUp(self): |
87 self.options = _GetOptionForUnittest() | 108 self.options = _GetOptionForUnittest() |
88 self.expectations = test_expectations.TestExpectations() | 109 self.expectations = test_expectations.TestExpectations() |
89 self.results = results_options.CreateResults( | 110 self.results = results_options.CreateResults( |
90 EmptyMetadataForTest(), self.options) | 111 EmptyMetadataForTest(), self.options) |
| 112 self._user_story_runner_logging_stub = None |
| 113 |
| 114 def SuppressExceptionFormatting(self): |
| 115 ''' Fake out exception formatter to avoid spamming the unittest stdout. ''' |
| 116 user_story_runner.exception_formatter = FakeExceptionFormatterModule |
| 117 self._user_story_runner_logging_stub = system_stub.Override( |
| 118 user_story_runner, ['logging']) |
| 119 |
| 120 def RestoreExceptionFormatter(self): |
| 121 user_story_runner.exception_formatter = exception_formatter_module |
| 122 if self._user_story_runner_logging_stub: |
| 123 self._user_story_runner_logging_stub.Restore() |
| 124 self._user_story_runner_logging_stub = None |
| 125 |
| 126 def tearDown(self): |
| 127 self.RestoreExceptionFormatter() |
91 | 128 |
92 def testGetUserStoryGroupsWithSameSharedUserStoryClass(self): | 129 def testGetUserStoryGroupsWithSameSharedUserStoryClass(self): |
93 us = user_story_set.UserStorySet() | 130 us = user_story_set.UserStorySet() |
94 us.AddUserStory(user_story.UserStory(FooUserStoryState)) | 131 us.AddUserStory(user_story.UserStory(FooUserStoryState)) |
95 us.AddUserStory(user_story.UserStory(FooUserStoryState)) | 132 us.AddUserStory(user_story.UserStory(FooUserStoryState)) |
96 us.AddUserStory(user_story.UserStory(BarUserStoryState)) | 133 us.AddUserStory(user_story.UserStory(BarUserStoryState)) |
97 us.AddUserStory(user_story.UserStory(FooUserStoryState)) | 134 us.AddUserStory(user_story.UserStory(FooUserStoryState)) |
98 story_groups = ( | 135 story_groups = ( |
99 user_story_runner.GetUserStoryGroupsWithSameSharedUserStoryClass( | 136 user_story_runner.GetUserStoryGroupsWithSameSharedUserStoryClass( |
100 us)) | 137 us)) |
101 self.assertEqual(len(story_groups), 3) | 138 self.assertEqual(len(story_groups), 3) |
102 self.assertEqual(story_groups[0].shared_user_story_state_class, | 139 self.assertEqual(story_groups[0].shared_user_story_state_class, |
103 FooUserStoryState) | 140 FooUserStoryState) |
104 self.assertEqual(story_groups[1].shared_user_story_state_class, | 141 self.assertEqual(story_groups[1].shared_user_story_state_class, |
105 BarUserStoryState) | 142 BarUserStoryState) |
106 self.assertEqual(story_groups[2].shared_user_story_state_class, | 143 self.assertEqual(story_groups[2].shared_user_story_state_class, |
107 FooUserStoryState) | 144 FooUserStoryState) |
108 | 145 |
109 def testSuccefulUserStoryTest(self): | 146 def testSuccefulUserStoryTest(self): |
110 us = user_story_set.UserStorySet() | 147 us = user_story_set.UserStorySet() |
111 us.AddUserStory(user_story.UserStory(FooUserStoryState)) | 148 us.AddUserStory(user_story.UserStory(FooUserStoryState)) |
112 us.AddUserStory(user_story.UserStory(FooUserStoryState)) | 149 us.AddUserStory(user_story.UserStory(FooUserStoryState)) |
113 us.AddUserStory(user_story.UserStory(BarUserStoryState)) | 150 us.AddUserStory(user_story.UserStory(BarUserStoryState)) |
114 user_story_runner.Run( | 151 user_story_runner.Run( |
115 DummyTest(), us, self.expectations, self.options, self.results) | 152 DummyTest(), us, self.expectations, self.options, self.results) |
116 self.assertEquals(0, len(self.results.failures)) | 153 self.assertEquals(0, len(self.results.failures)) |
117 self.assertEquals(3, len(self.results.pages_that_succeeded)) | 154 self.assertEquals(3, GetNumberOfSuccessfulPageRuns(self.results)) |
| 155 |
| 156 def testHandlingOfCrashedApp(self): |
| 157 self.SuppressExceptionFormatting() |
| 158 us = user_story_set.UserStorySet() |
| 159 class SharedUserStoryThatCausesAppCrash(TestSharedUserStoryState): |
| 160 def WillRunUserStory(self, user_storyz): |
| 161 raise exceptions.AppCrashException() |
| 162 |
| 163 us.AddUserStory(user_story.UserStory(SharedUserStoryThatCausesAppCrash)) |
| 164 user_story_runner.Run( |
| 165 DummyTest(), us, self.expectations, self.options, self.results) |
| 166 self.assertEquals(1, len(self.results.failures)) |
| 167 self.assertEquals(0, GetNumberOfSuccessfulPageRuns(self.results)) |
| 168 |
| 169 def testHandlingOfTestThatRaisesWithNonFatalUnknownExceptions(self): |
| 170 self.SuppressExceptionFormatting() |
| 171 us = user_story_set.UserStorySet() |
| 172 |
| 173 class ExpectedException(Exception): |
| 174 pass |
| 175 |
| 176 class Test(page_test.PageTest): |
| 177 def __init__(self, *args): |
| 178 super(Test, self).__init__(*args) # pylint: disable=bad-super-call |
| 179 self.run_count = 0 |
| 180 def RunPage(self, *_): |
| 181 old_run_count = self.run_count |
| 182 self.run_count += 1 |
| 183 if old_run_count == 0: |
| 184 raise ExpectedException() |
| 185 |
| 186 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 187 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 188 test = Test() |
| 189 user_story_runner.Run( |
| 190 test, us, self.expectations, self.options, self.results) |
| 191 self.assertEquals(2, test.run_count) |
| 192 self.assertEquals(1, len(self.results.failures)) |
| 193 self.assertEquals(1, GetNumberOfSuccessfulPageRuns(self.results)) |
| 194 |
| 195 def testRaiseBrowserGoneExceptionFromRunPage(self): |
| 196 self.SuppressExceptionFormatting() |
| 197 us = user_story_set.UserStorySet() |
| 198 |
| 199 class Test(page_test.PageTest): |
| 200 def __init__(self, *args): |
| 201 super(Test, self).__init__(*args) # pylint: disable=bad-super-call |
| 202 self.run_count = 0 |
| 203 def RunPage(self, *_): |
| 204 old_run_count = self.run_count |
| 205 self.run_count += 1 |
| 206 if old_run_count == 0: |
| 207 raise exceptions.BrowserGoneException() |
| 208 |
| 209 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 210 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 211 test = Test() |
| 212 user_story_runner.Run( |
| 213 test, us, self.expectations, self.options, self.results) |
| 214 self.assertEquals(2, test.run_count) |
| 215 self.assertEquals(1, len(self.results.failures)) |
| 216 self.assertEquals(1, GetNumberOfSuccessfulPageRuns(self.results)) |
| 217 |
| 218 def testDiscardFirstResult(self): |
| 219 us = user_story_set.UserStorySet() |
| 220 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 221 us.AddUserStory(user_story.UserStory(TestSharedUserStoryState)) |
| 222 class Measurement(page_test.PageTest): |
| 223 @property |
| 224 def discard_first_result(self): |
| 225 return True |
| 226 |
| 227 def RunPage(self, page, _, results): |
| 228 results.AddValue(string.StringValue(page, 'test', 't', page.name)) |
| 229 |
| 230 results = results_options.CreateResults( |
| 231 EmptyMetadataForTest(), self.options) |
| 232 user_story_runner.Run( |
| 233 Measurement(), us, self.expectations, self.options, results) |
| 234 |
| 235 self.assertEquals(0, GetNumberOfSuccessfulPageRuns(results)) |
| 236 self.assertEquals(0, len(results.failures)) |
| 237 self.assertEquals(0, len(results.all_page_specific_values)) |
| 238 |
| 239 |
| 240 results = results_options.CreateResults( |
| 241 EmptyMetadataForTest(), self.options) |
| 242 self.options.page_repeat = 1 |
| 243 self.options.pageset_repeat = 2 |
| 244 user_story_runner.Run( |
| 245 Measurement(), us, self.expectations, self.options, results) |
| 246 self.assertEquals(2, GetNumberOfSuccessfulPageRuns(results)) |
| 247 self.assertEquals(0, len(results.failures)) |
| 248 self.assertEquals(2, len(results.all_page_specific_values)) |
| 249 |
| 250 results = results_options.CreateResults( |
| 251 EmptyMetadataForTest(), self.options) |
| 252 self.options.page_repeat = 2 |
| 253 self.options.pageset_repeat = 1 |
| 254 user_story_runner.Run( |
| 255 Measurement(), us, self.expectations, self.options, results) |
| 256 self.assertEquals(2, GetNumberOfSuccessfulPageRuns(results)) |
| 257 self.assertEquals(0, len(results.failures)) |
| 258 self.assertEquals(2, len(results.all_page_specific_values)) |
| 259 |
| 260 results = results_options.CreateResults( |
| 261 EmptyMetadataForTest(), self.options) |
| 262 self.options.page_repeat = 1 |
| 263 self.options.pageset_repeat = 1 |
| 264 user_story_runner.Run( |
| 265 Measurement(), us, self.expectations, self.options, results) |
| 266 self.assertEquals(0, GetNumberOfSuccessfulPageRuns(results)) |
| 267 self.assertEquals(0, len(results.failures)) |
| 268 self.assertEquals(0, len(results.all_page_specific_values)) |
| 269 |
| 270 def testPagesetRepeat(self): |
| 271 us = user_story_set.UserStorySet() |
| 272 us.AddUserStory(user_story.UserStory( |
| 273 TestSharedUserStoryState, name='blank')) |
| 274 us.AddUserStory(user_story.UserStory( |
| 275 TestSharedUserStoryState, name='green')) |
| 276 |
| 277 class Measurement(page_test.PageTest): |
| 278 i = 0 |
| 279 def RunPage(self, page, _, results): |
| 280 self.i += 1 |
| 281 results.AddValue(scalar.ScalarValue( |
| 282 page, 'metric', 'unit', self.i)) |
| 283 |
| 284 self.options.page_repeat = 1 |
| 285 self.options.pageset_repeat = 2 |
| 286 self.options.output_formats = ['buildbot'] |
| 287 output = StringIO.StringIO() |
| 288 real_stdout = sys.stdout |
| 289 sys.stdout = output |
| 290 try: |
| 291 results = results_options.CreateResults( |
| 292 EmptyMetadataForTest(), self.options) |
| 293 user_story_runner.Run( |
| 294 Measurement(), us, self.expectations, self.options, results) |
| 295 results.PrintSummary() |
| 296 contents = output.getvalue() |
| 297 self.assertEquals(4, GetNumberOfSuccessfulPageRuns(results)) |
| 298 self.assertEquals(0, len(results.failures)) |
| 299 self.assertIn('RESULT metric: blank= [1,3] unit', contents) |
| 300 self.assertIn('RESULT metric: green= [2,4] unit', contents) |
| 301 self.assertIn('*RESULT metric: metric= [1,2,3,4] unit', contents) |
| 302 finally: |
| 303 sys.stdout = real_stdout |
OLD | NEW |