|
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=None, dest='filter', | |
kkania
2012/10/24 23:44:05
set default to '*'
nkang
2012/10/24 23:52:46
Done.
| |
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 _GetFilteredTests(self): | |
106 """Returns a list of filtered unittests from the calling script.""" | |
107 all_tests = unittest.defaultTestLoader.loadTestsFromModule(sample_updater) | |
108 return self._FilterTestSuite(all_tests, self._opts.filter) | |
109 | |
110 def _GetTestsFromSuite(self, suite): | |
111 """Returns all the tests from a given test suite. | |
112 | |
113 Args: | |
114 suite: A unittest.TestSuite object. | |
115 | |
116 Returns: | |
117 A list that contains all the tests found in the suite. | |
118 """ | |
119 tests = [] | |
120 for test in suite: | |
121 if isinstance(test, unittest.TestSuite): | |
122 tests += self._GetTestsFromSuite(test) | |
123 else: | |
124 tests += [test] | |
125 return tests | |
126 | |
127 def _GetTestName(self, test): | |
128 """Gets the test name of the given unittest test. | |
129 | |
130 Args: | |
131 test: A unittest test. | |
132 | |
133 Returns: | |
134 A string representing the full test name. | |
135 """ | |
136 return '.'.join([test.__module__, test.__class__.__name__, | |
137 test._testMethodName]) | |
138 | |
139 def _FilterTestSuite(self, suite, gtest_filter): | |
140 """Returns a new filtered test suite based on the given gtest filter. | |
141 | |
142 See http://code.google.com/p/googletest/wiki/AdvancedGuide for | |
143 gtest_filter specification. | |
144 | |
145 Args: | |
146 suite: A unittest.TestSuite object, which can be obtained by calling | |
147 |unittest.defaultTestLoader.loadTestsFromName|. | |
148 gtest_filter: The gtest filter to use. Filter can be passed as follows: | |
149 --filter=*className* or --filter=*testcaseName. | |
150 | |
151 Returns: | |
152 A unittest.TestSuite object that contains tests that match the gtest | |
153 filter. | |
154 """ | |
155 return unittest.TestSuite( | |
156 self._FilterTests(self._GetTestsFromSuite(suite), gtest_filter)) | |
157 | |
158 def _FilterTests(self, all_tests, gtest_filter): | |
159 """Returns a filtered list of tests based on the given gtest filter. | |
160 | |
161 Args: | |
162 all_tests: A list that contains all unittests in a given suite. This | |
163 list must be obtained by calling |_GetTestsFromSuite|. | |
164 gtest_filter: The gtest filter to use. Filter can be passed as follows: | |
165 *className* or *testcaseName. | |
166 | |
167 Returns: | |
168 A list that contains all tests that match the given gtest filter. | |
169 """ | |
170 pattern_groups = gtest_filter.split('-') | |
171 positive_patterns = pattern_groups[0].split(':') | |
172 negative_patterns = None | |
173 if len(pattern_groups) > 1: | |
174 negative_patterns = pattern_groups[1].split(':') | |
175 tests = [] | |
176 for test in all_tests: | |
177 test_name = self._GetTestName(test) | |
178 # Test name must by matched by one positive pattern. | |
179 for pattern in positive_patterns: | |
180 if fnmatch.fnmatch(test_name, pattern): | |
181 break | |
182 else: | |
183 continue | |
184 # Test name must not be matched by any negative patterns. | |
185 for pattern in negative_patterns or []: | |
186 if fnmatch.fnmatch(test_name, pattern): | |
187 break | |
188 else: | |
189 tests += [test] | |
190 return tests | |
191 | |
192 def _Run(self): | |
193 """Runs the unit tests.""" | |
194 if self._opts.filter: | |
kkania
2012/10/24 23:44:05
i don't like the if and else here, instead just do
nkang
2012/10/24 23:52:46
Got rid of the if/else statement and the _GetFilte
| |
195 tests = self._GetFilteredTests() | |
196 else: | |
197 tests = unittest.defaultTestLoader.loadTestsFromModule(sample_updater) | |
198 result = pyauto_utils.GTestTextTestRunner(verbosity=1).run(tests) | |
199 del(tests) | |
200 if not result.wasSuccessful(): | |
201 print >>sys.stderr, ('Not all tests were successful.') | |
202 sys.exit(1) | |
203 sys.exit(0) | |
204 | |
205 | |
206 if __name__ == '__main__': | |
207 sys.exit(Main()) | |
kkania
2012/10/24 23:44:05
remove the sys.exit() and just keep Main()
nkang
2012/10/24 23:52:46
Done.
| |
OLD | NEW |