OLD | NEW |
(Empty) | |
| 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. |
| 5 |
| 6 """Runs install and update tests. |
| 7 |
| 8 Install tests are performed using a single Chrome build, whereas two or more |
| 9 builds are needed for Update tests. There are separate command arguments for |
| 10 the builds that will be used for each of the tests. If a test file contains |
| 11 both types of tests(Install and Update), both arguments should be specified. |
| 12 Otherwise, specify only the command argument that is required for the test. |
| 13 This script can be used as an executable to run other Install/Upgrade tests. |
| 14 |
| 15 Example: |
| 16 $ python run_install_test.py <script_name> --url=<chrome_builds_url> \ |
| 17 --install-build=24.0.1290.0 --update-builds=24.0.1289.0,24.0.1290.0 |
| 18 """ |
| 19 |
| 20 import fnmatch |
| 21 import logging |
| 22 import optparse |
| 23 import os |
| 24 import re |
| 25 import sys |
| 26 import unittest |
| 27 |
| 28 import chrome_installer_win |
| 29 from install_test import InstallTest |
| 30 import sample_updater |
| 31 |
| 32 _DIRECTORY = os.path.dirname(os.path.abspath(__file__)) |
| 33 sys.path.append(os.path.join(os.path.dirname(_DIRECTORY), 'pyautolib')) |
| 34 |
| 35 import pyauto_utils |
| 36 |
| 37 |
| 38 class Main(object): |
| 39 """Main program for running 'Fresh Install' and 'Updater' tests.""" |
| 40 |
| 41 def __init__(self): |
| 42 self._SetLoggingConfiguration() |
| 43 self._ParseArgs() |
| 44 self._Run() |
| 45 |
| 46 def _ParseArgs(self): |
| 47 """Parses command line arguments.""" |
| 48 parser = optparse.OptionParser() |
| 49 parser.add_option( |
| 50 '-u', '--url', type='string', default='', dest='url', |
| 51 help='Specifies the build url, without the build number.') |
| 52 parser.add_option( |
| 53 '-o', '--options', type='string', default='', |
| 54 help='Specifies any additional Chrome options (i.e. --system-level).') |
| 55 parser.add_option( |
| 56 '--install-build', type='string', default='', dest='install_build', |
| 57 help='Specifies the build to be used for fresh install testing.') |
| 58 parser.add_option( |
| 59 '--update-builds', type='string', default='', dest='update_builds', |
| 60 help='Specifies the builds to be used for updater testing.') |
| 61 parser.add_option( |
| 62 '--install-type', type='string', default='user', dest='install_type', |
| 63 help='Type of installation (i.e., user, system, or both)') |
| 64 parser.add_option( |
| 65 '-f', '--filter', type='string', default='*', dest='filter', |
| 66 help='Filter that specifies the test or testsuite to run.') |
| 67 self._opts, self._args = parser.parse_args() |
| 68 self._ValidateArgs() |
| 69 if(self._opts.install_type == 'system' or |
| 70 self._opts.install_type == 'user'): |
| 71 install_type = ({ |
| 72 'system' : chrome_installer_win.InstallationType.SYSTEM, |
| 73 'user' : chrome_installer_win.InstallationType.USER}).get( |
| 74 self._opts.install_type) |
| 75 InstallTest.SetInstallType(install_type) |
| 76 update_builds = (self._opts.update_builds.split(',') if |
| 77 self._opts.update_builds else []) |
| 78 options = self._opts.options.split(',') if self._opts.options else [] |
| 79 InstallTest.InitTestFixture(self._opts.install_build, update_builds, |
| 80 self._opts.url, options) |
| 81 |
| 82 def _ValidateArgs(self): |
| 83 """Verifies the sanity of the command arguments. |
| 84 |
| 85 Confirms that all specified builds have a valid version number, and the |
| 86 build urls are valid. |
| 87 """ |
| 88 builds = [] |
| 89 if self._opts.install_build: |
| 90 builds.append(self._opts.install_build) |
| 91 if self._opts.update_builds: |
| 92 builds.extend(self._opts.update_builds.split(',')) |
| 93 builds = list(frozenset(builds)) |
| 94 for build in builds: |
| 95 if not re.match('\d+\.\d+\.\d+\.\d+', build): |
| 96 raise RuntimeError('Invalid build number: %s' % build) |
| 97 if not pyauto_utils.DoesUrlExist('%s/%s/' % (self._opts.url, build)): |
| 98 raise RuntimeError('Could not locate build no. %s' % build) |
| 99 |
| 100 def _SetLoggingConfiguration(self): |
| 101 """Sets the basic logging configuration.""" |
| 102 log_format = '%(asctime)s %(levelname)-8s %(message)s' |
| 103 logging.basicConfig(level=logging.INFO, format=log_format) |
| 104 |
| 105 def _GetTestsFromSuite(self, suite): |
| 106 """Returns all the tests from a given test suite. |
| 107 |
| 108 Args: |
| 109 suite: A unittest.TestSuite object. |
| 110 |
| 111 Returns: |
| 112 A list that contains all the tests found in the suite. |
| 113 """ |
| 114 tests = [] |
| 115 for test in suite: |
| 116 if isinstance(test, unittest.TestSuite): |
| 117 tests += self._GetTestsFromSuite(test) |
| 118 else: |
| 119 tests += [test] |
| 120 return tests |
| 121 |
| 122 def _GetTestName(self, test): |
| 123 """Gets the test name of the given unittest test. |
| 124 |
| 125 Args: |
| 126 test: A unittest test. |
| 127 |
| 128 Returns: |
| 129 A string representing the full test name. |
| 130 """ |
| 131 return '.'.join([test.__module__, test.__class__.__name__, |
| 132 test._testMethodName]) |
| 133 |
| 134 def _FilterTestSuite(self, suite, gtest_filter): |
| 135 """Returns a new filtered test suite based on the given gtest filter. |
| 136 |
| 137 See http://code.google.com/p/googletest/wiki/AdvancedGuide for |
| 138 gtest_filter specification. |
| 139 |
| 140 Args: |
| 141 suite: A unittest.TestSuite object, which can be obtained by calling |
| 142 |unittest.defaultTestLoader.loadTestsFromName|. |
| 143 gtest_filter: The gtest filter to use. Filter can be passed as follows: |
| 144 --filter=*className* or --filter=*testcaseName. |
| 145 |
| 146 Returns: |
| 147 A unittest.TestSuite object that contains tests that match the gtest |
| 148 filter. |
| 149 """ |
| 150 return unittest.TestSuite( |
| 151 self._FilterTests(self._GetTestsFromSuite(suite), gtest_filter)) |
| 152 |
| 153 def _FilterTests(self, all_tests, gtest_filter): |
| 154 """Returns a filtered list of tests based on the given gtest filter. |
| 155 |
| 156 Args: |
| 157 all_tests: A list that contains all unittests in a given suite. This |
| 158 list must be obtained by calling |_GetTestsFromSuite|. |
| 159 gtest_filter: The gtest filter to use. Filter can be passed as follows: |
| 160 *className* or *testcaseName. |
| 161 |
| 162 Returns: |
| 163 A list that contains all tests that match the given gtest filter. |
| 164 """ |
| 165 pattern_groups = gtest_filter.split('-') |
| 166 positive_patterns = pattern_groups[0].split(':') |
| 167 negative_patterns = None |
| 168 if len(pattern_groups) > 1: |
| 169 negative_patterns = pattern_groups[1].split(':') |
| 170 tests = [] |
| 171 for test in all_tests: |
| 172 test_name = self._GetTestName(test) |
| 173 # Test name must by matched by one positive pattern. |
| 174 for pattern in positive_patterns: |
| 175 if fnmatch.fnmatch(test_name, pattern): |
| 176 break |
| 177 else: |
| 178 continue |
| 179 # Test name must not be matched by any negative patterns. |
| 180 for pattern in negative_patterns or []: |
| 181 if fnmatch.fnmatch(test_name, pattern): |
| 182 break |
| 183 else: |
| 184 tests += [test] |
| 185 return tests |
| 186 |
| 187 def _Run(self): |
| 188 """Runs the unit tests.""" |
| 189 all_tests = unittest.defaultTestLoader.loadTestsFromModule(sample_updater) |
| 190 tests = self._FilterTestSuite(all_tests, self._opts.filter) |
| 191 result = pyauto_utils.GTestTextTestRunner(verbosity=1).run(tests) |
| 192 del(tests) |
| 193 if not result.wasSuccessful(): |
| 194 print >>sys.stderr, ('Not all tests were successful.') |
| 195 sys.exit(1) |
| 196 sys.exit(0) |
| 197 |
| 198 |
| 199 if __name__ == '__main__': |
| 200 Main() |
OLD | NEW |