Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 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 """This script tests the installer with test cases specified in the config file. | 5 """This script tests the installer with test cases specified in the config file. |
| 6 | 6 |
| 7 For each test case, it checks that the machine states after the execution of | 7 For each test case, it checks that the machine states after the execution of |
| 8 each command match the expected machine states. For more details, take a look at | 8 each command match the expected machine states. For more details, take a look at |
| 9 the design documentation at http://goo.gl/Q0rGM6 | 9 the design documentation at http://goo.gl/Q0rGM6 |
| 10 """ | 10 """ |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 """ | 33 """ |
| 34 def __init__(self): | 34 def __init__(self): |
| 35 self.states = {} | 35 self.states = {} |
| 36 self.actions = {} | 36 self.actions = {} |
| 37 self.tests = [] | 37 self.tests = [] |
| 38 | 38 |
| 39 | 39 |
| 40 class InstallerTest(unittest.TestCase): | 40 class InstallerTest(unittest.TestCase): |
| 41 """Tests a test case in the config file.""" | 41 """Tests a test case in the config file.""" |
| 42 | 42 |
| 43 def __init__(self, name, test, config, variable_expander): | 43 def __init__(self, name, test, config, variable_expander, verbose): |
| 44 """Constructor. | 44 """Constructor. |
| 45 | 45 |
| 46 Args: | 46 Args: |
| 47 name: The name of this test. | 47 name: The name of this test. |
| 48 test: An array of alternating state names and action names, starting and | 48 test: An array of alternating state names and action names, starting and |
| 49 ending with state names. | 49 ending with state names. |
| 50 config: The Config object. | 50 config: The Config object. |
| 51 variable_expander: A VariableExpander object. | 51 variable_expander: A VariableExpander object. |
| 52 """ | 52 """ |
| 53 super(InstallerTest, self).__init__() | 53 super(InstallerTest, self).__init__() |
| 54 self._name = name | 54 self._name = name |
| 55 self._test = test | 55 self._test = test |
| 56 self._config = config | 56 self._config = config |
| 57 self._variable_expander = variable_expander | 57 self._variable_expander = variable_expander |
| 58 self._verbose = verbose | |
| 58 self._verifier_runner = verifier_runner.VerifierRunner() | 59 self._verifier_runner = verifier_runner.VerifierRunner() |
| 59 self._clean_on_teardown = True | 60 self._clean_on_teardown = True |
| 60 | 61 |
| 61 def __str__(self): | 62 def __str__(self): |
| 62 """Returns a string representing the test case. | 63 """Returns a string representing the test case. |
| 63 | 64 |
| 64 Returns: | 65 Returns: |
| 65 A string created by joining state names and action names together with | 66 A string created by joining state names and action names together with |
| 66 ' -> ', for example, 'Test: clean -> install chrome -> chrome_installed'. | 67 ' -> ', for example, 'Test: clean -> install chrome -> chrome_installed'. |
| 67 """ | 68 """ |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 80 # and ending with state names. Therefore, its length must be odd. | 81 # and ending with state names. Therefore, its length must be odd. |
| 81 self.assertEqual(1, len(self._test) % 2, | 82 self.assertEqual(1, len(self._test) % 2, |
| 82 'The length of test array must be odd') | 83 'The length of test array must be odd') |
| 83 | 84 |
| 84 state = self._test[0] | 85 state = self._test[0] |
| 85 self._VerifyState(state) | 86 self._VerifyState(state) |
| 86 | 87 |
| 87 # Starting at index 1, we loop through pairs of (action, state). | 88 # Starting at index 1, we loop through pairs of (action, state). |
| 88 for i in range(1, len(self._test), 2): | 89 for i in range(1, len(self._test), 2): |
| 89 action = self._test[i] | 90 action = self._test[i] |
| 91 if self._verbose: | |
| 92 sys.stderr.write('Beginning action %s\n' % action) | |
| 90 RunCommand(self._config.actions[action], self._variable_expander) | 93 RunCommand(self._config.actions[action], self._variable_expander) |
| 94 if self._verbose: | |
| 95 sys.stderr.write('Finished action %s\n' % action) | |
|
gab
2014/09/09 15:50:10
Shouldn't this go to stdout instead? (i.e. this is
grt (UTC plus 2)
2014/09/09 15:56:48
I would have thought so, but since the whole unitt
| |
| 91 | 96 |
| 92 state = self._test[i + 1] | 97 state = self._test[i + 1] |
| 93 self._VerifyState(state) | 98 self._VerifyState(state) |
| 94 | 99 |
| 95 # If the test makes it here, it means it was successful, because RunCommand | 100 # If the test makes it here, it means it was successful, because RunCommand |
| 96 # and _VerifyState throw an exception on failure. | 101 # and _VerifyState throw an exception on failure. |
| 97 self._clean_on_teardown = False | 102 self._clean_on_teardown = False |
| 98 | 103 |
| 99 def tearDown(self): | 104 def tearDown(self): |
| 100 """Cleans up the machine if the test case fails.""" | 105 """Cleans up the machine if the test case fails.""" |
| 101 if self._clean_on_teardown: | 106 if self._clean_on_teardown: |
| 102 RunCleanCommand(True, self._variable_expander) | 107 RunCleanCommand(True, self._variable_expander) |
| 103 | 108 |
| 104 def shortDescription(self): | 109 def shortDescription(self): |
| 105 """Overridden from unittest.TestCase. | 110 """Overridden from unittest.TestCase. |
| 106 | 111 |
| 107 We return None as the short description to suppress its printing. | 112 We return None as the short description to suppress its printing. |
| 108 The default implementation of this method returns the docstring of the | 113 The default implementation of this method returns the docstring of the |
| 109 runTest method, which is not useful since it's the same for every test case. | 114 runTest method, which is not useful since it's the same for every test case. |
| 110 The description from the __str__ method is informative enough. | 115 The description from the __str__ method is informative enough. |
| 111 """ | 116 """ |
| 112 return None | 117 return None |
| 113 | 118 |
| 114 def _VerifyState(self, state): | 119 def _VerifyState(self, state): |
| 115 """Verifies that the current machine state matches a given state. | 120 """Verifies that the current machine state matches a given state. |
| 116 | 121 |
| 117 Args: | 122 Args: |
| 118 state: A state name. | 123 state: A state name. |
| 119 """ | 124 """ |
| 125 if self._verbose: | |
| 126 sys.stderr.write('Verifying state %s\n' % state) | |
| 120 try: | 127 try: |
| 121 self._verifier_runner.VerifyAll(self._config.states[state], | 128 self._verifier_runner.VerifyAll(self._config.states[state], |
| 122 self._variable_expander) | 129 self._variable_expander) |
| 123 except AssertionError as e: | 130 except AssertionError as e: |
| 124 # If an AssertionError occurs, we intercept it and add the state name | 131 # If an AssertionError occurs, we intercept it and add the state name |
| 125 # to the error message so that we know where the test fails. | 132 # to the error message so that we know where the test fails. |
| 126 raise AssertionError("In state '%s', %s" % (state, e)) | 133 raise AssertionError("In state '%s', %s" % (state, e)) |
| 127 | 134 |
| 128 | 135 |
| 129 def RunCommand(command, variable_expander): | 136 def RunCommand(command, variable_expander): |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 282 | 289 |
| 283 variable_expander = VariableExpander(mini_installer_path) | 290 variable_expander = VariableExpander(mini_installer_path) |
| 284 RunCleanCommand(args.force_clean, variable_expander) | 291 RunCleanCommand(args.force_clean, variable_expander) |
| 285 for test in config.tests: | 292 for test in config.tests: |
| 286 # If tests were specified via |tests|, their names are formatted like so: | 293 # If tests were specified via |tests|, their names are formatted like so: |
| 287 test_name = '%s.%s.%s' % (InstallerTest.__module__, | 294 test_name = '%s.%s.%s' % (InstallerTest.__module__, |
| 288 InstallerTest.__name__, | 295 InstallerTest.__name__, |
| 289 test['name']) | 296 test['name']) |
| 290 if not args.test or test_name in args.test: | 297 if not args.test or test_name in args.test: |
| 291 suite.addTest(InstallerTest(test['name'], test['traversal'], config, | 298 suite.addTest(InstallerTest(test['name'], test['traversal'], config, |
| 292 variable_expander)) | 299 variable_expander, args.verbose)) |
| 293 | 300 |
| 294 result = unittest.TextTestRunner(verbosity=(args.verbose + 1)).run(suite) | 301 result = unittest.TextTestRunner(verbosity=(args.verbose + 1)).run(suite) |
| 295 if is_component_build: | 302 if is_component_build: |
| 296 print ('Component build is currently unsupported by the mini_installer: ' | 303 print ('Component build is currently unsupported by the mini_installer: ' |
| 297 'http://crbug.com/377839') | 304 'http://crbug.com/377839') |
| 298 if args.write_full_results_to: | 305 if args.write_full_results_to: |
| 299 with open(args.write_full_results_to, 'w') as fp: | 306 with open(args.write_full_results_to, 'w') as fp: |
| 300 json.dump(_FullResults(suite, result, {}), fp, indent=2) | 307 json.dump(_FullResults(suite, result, {}), fp, indent=2) |
| 301 fp.write("\n") | 308 fp.write("\n") |
| 302 return 0 if result.wasSuccessful() else 1 | 309 return 0 if result.wasSuccessful() else 1 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 trie[path] = value | 371 trie[path] = value |
| 365 return | 372 return |
| 366 directory, rest = path.split(TEST_SEPARATOR, 1) | 373 directory, rest = path.split(TEST_SEPARATOR, 1) |
| 367 if directory not in trie: | 374 if directory not in trie: |
| 368 trie[directory] = {} | 375 trie[directory] = {} |
| 369 _AddPathToTrie(trie[directory], rest, value) | 376 _AddPathToTrie(trie[directory], rest, value) |
| 370 | 377 |
| 371 | 378 |
| 372 if __name__ == '__main__': | 379 if __name__ == '__main__': |
| 373 sys.exit(main()) | 380 sys.exit(main()) |
| OLD | NEW |