OLD | NEW |
---|---|
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2012 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 """Test fixture for tests involving installing/updating Chrome. | 5 """Test fixture for tests involving installing/updating Chrome. |
6 | 6 |
7 Provides an interface to install or update chrome from within a testcase, and | 7 Provides an interface to install or update chrome from within a testcase, and |
8 allows users to run tests using installed version of Chrome. User and system | 8 allows users to run tests using installed version of Chrome. User and system |
9 level installations are supported, and either one can be used for running the | 9 level installations are supported, and either one can be used for running the |
10 tests. Currently the only platform it supports is Windows. | 10 tests. Currently the only platform it supports is Windows. |
11 """ | 11 """ |
12 | 12 |
13 import atexit | 13 import atexit |
14 import fnmatch | |
14 import logging | 15 import logging |
15 import optparse | 16 import optparse |
16 import os | 17 import os |
17 import platform | 18 import platform |
18 import re | 19 import re |
19 import shutil | 20 import shutil |
20 import stat | 21 import stat |
21 import sys | 22 import sys |
22 import tempfile | 23 import tempfile |
23 import unittest | 24 import unittest |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
243 help='Specifies any additional Chrome options (i.e. --system-level).') | 244 help='Specifies any additional Chrome options (i.e. --system-level).') |
244 parser.add_option( | 245 parser.add_option( |
245 '--install-build', type='string', default='', dest='install_build', | 246 '--install-build', type='string', default='', dest='install_build', |
246 help='Specifies the build to be used for fresh install testing.') | 247 help='Specifies the build to be used for fresh install testing.') |
247 parser.add_option( | 248 parser.add_option( |
248 '--update-builds', type='string', default='', dest='update_builds', | 249 '--update-builds', type='string', default='', dest='update_builds', |
249 help='Specifies the builds to be used for updater testing.') | 250 help='Specifies the builds to be used for updater testing.') |
250 parser.add_option( | 251 parser.add_option( |
251 '--install-type', type='string', default='user', dest='install_type', | 252 '--install-type', type='string', default='user', dest='install_type', |
252 help='Type of installation (i.e., user, system, or both)') | 253 help='Type of installation (i.e., user, system, or both)') |
254 parser.add_option( | |
255 '-f', '--filter', type='string', default=None, dest='filter', | |
256 help='Filter that specifies the test or testsuite to run.') | |
253 self._opts, self._args = parser.parse_args() | 257 self._opts, self._args = parser.parse_args() |
254 self._ValidateArgs() | 258 self._ValidateArgs() |
255 if(self._opts.install_type == 'system' or | 259 if(self._opts.install_type == 'system' or |
256 self._opts.install_type == 'user'): | 260 self._opts.install_type == 'user'): |
257 install_type = ({ | 261 install_type = ({ |
258 'system' : chrome_installer_win.InstallationType.SYSTEM, | 262 'system' : chrome_installer_win.InstallationType.SYSTEM, |
259 'user' : chrome_installer_win.InstallationType.USER}).get( | 263 'user' : chrome_installer_win.InstallationType.USER}).get( |
260 self._opts.install_type) | 264 self._opts.install_type) |
261 InstallTest.SetInstallType(install_type) | 265 InstallTest.SetInstallType(install_type) |
262 update_builds = (self._opts.update_builds.split(',') if | 266 update_builds = (self._opts.update_builds.split(',') if |
263 self._opts.update_builds else []) | 267 self._opts.update_builds else []) |
264 options = self._opts.options.split(',') if self._opts.options else [] | 268 options = self._opts.options.split(',') if self._opts.options else [] |
265 InstallTest.InitTestFixture(self._opts.install_build, | 269 InstallTest.InitTestFixture(self._opts.install_build, update_builds, |
266 update_builds, | 270 self._opts.url, options) |
267 self._opts.url, | 271 self._mod_name = os.path.splitext(os.path.basename(sys.argv[0]))[0] |
268 options) | 272 if os.path.dirname(sys.argv[0]) not in sys.path: |
kkania
2012/10/24 15:19:54
I think this is unnecessary. sys.argv[0] was just
nkang
2012/10/24 23:35:14
I agree. I was thinking the same thing that it sho
| |
273 sys.path.append(os.path.dirname(sys.argv[0])) | |
269 | 274 |
270 def _ValidateArgs(self): | 275 def _ValidateArgs(self): |
271 """Verifies the sanity of the command arguments. | 276 """Verifies the sanity of the command arguments. |
272 | 277 |
273 Confirms that all specified builds have a valid version number, and the | 278 Confirms that all specified builds have a valid version number, and the |
274 build urls are valid. | 279 build urls are valid. |
275 """ | 280 """ |
276 builds = [] | 281 builds = [] |
277 if self._opts.install_build: | 282 if self._opts.install_build: |
278 builds.append(self._opts.install_build) | 283 builds.append(self._opts.install_build) |
279 if self._opts.update_builds: | 284 if self._opts.update_builds: |
280 builds.extend(self._opts.update_builds.split(',')) | 285 builds.extend(self._opts.update_builds.split(',')) |
281 builds = list(frozenset(builds)) | 286 builds = list(frozenset(builds)) |
282 for build in builds: | 287 for build in builds: |
283 if not re.match('\d+\.\d+\.\d+\.\d+', build): | 288 if not re.match('\d+\.\d+\.\d+\.\d+', build): |
284 raise RuntimeError('Invalid build number: %s' % build) | 289 raise RuntimeError('Invalid build number: %s' % build) |
285 if not pyauto_utils.DoesUrlExist('%s/%s/' % (self._opts.url, build)): | 290 if not pyauto_utils.DoesUrlExist('%s/%s/' % (self._opts.url, build)): |
286 raise RuntimeError('Could not locate build no. %s' % build) | 291 raise RuntimeError('Could not locate build no. %s' % build) |
287 | 292 |
288 def _SetLoggingConfiguration(self): | 293 def _SetLoggingConfiguration(self): |
289 """Sets the basic logging configuration.""" | 294 """Sets the basic logging configuration.""" |
290 log_format = '%(asctime)s %(levelname)-8s %(message)s' | 295 log_format = '%(asctime)s %(levelname)-8s %(message)s' |
291 logging.basicConfig(level=logging.INFO, format=log_format) | 296 logging.basicConfig(level=logging.INFO, format=log_format) |
292 | 297 |
293 def _GetTests(self): | 298 def _GetFilteredTests(self): |
kkania
2012/10/24 15:19:54
move this whole Main class out to a new file, call
nkang
2012/10/24 23:35:14
Moved Main to a new file called run_install_tests.
| |
294 """Returns a list of unittests from the calling script.""" | 299 """Returns a list of filtered unittests from the calling script.""" |
295 mod_name = [os.path.splitext(os.path.basename(sys.argv[0]))[0]] | 300 all_tests = unittest.defaultTestLoader.loadTestsFromName(self._mod_name) |
296 if os.path.dirname(sys.argv[0]) not in sys.path: | 301 return self._FilterTestSuite(all_tests, self._opts.filter) |
297 sys.path.append(os.path.dirname(sys.argv[0])) | 302 |
298 return unittest.defaultTestLoader.loadTestsFromNames(mod_name) | 303 def _GetTestsFromSuite(self, suite): |
304 """Returns all the tests from a given test suite. | |
305 | |
306 Args: | |
307 suite: A unittest.TestSuite object. | |
308 | |
309 Returns: | |
310 A list that contains all the tests found in the suite. | |
311 """ | |
312 tests = [] | |
313 for test in suite: | |
314 if isinstance(test, unittest.TestSuite): | |
315 tests += self._GetTestsFromSuite(test) | |
316 else: | |
317 tests += [test] | |
318 return tests | |
319 | |
320 def _GetTestName(self, test): | |
321 """Gets the test name of the given unittest test. | |
322 | |
323 Args: | |
324 test: A unittest test. | |
325 | |
326 Returns: | |
327 A string representing the full test name. | |
328 """ | |
329 return '.'.join([test.__module__, test.__class__.__name__, | |
330 test._testMethodName]) | |
331 | |
332 def _FilterTestSuite(self, suite, gtest_filter): | |
333 """Returns a new filtered test suite based on the given gtest filter. | |
334 | |
335 See http://code.google.com/p/googletest/wiki/AdvancedGuide for | |
336 gtest_filter specification. | |
337 | |
338 Args: | |
339 suite: A unittest.TestSuite object, which can be obtained by calling | |
340 |unittest.defaultTestLoader.loadTestsFromName|. | |
341 gtest_filter: The gtest filter to use. Filter can be passed as follows: | |
342 --filter=*className* or --filter=*testcaseName. | |
343 | |
344 Returns: | |
345 A unittest.TestSuite object that contains tests that match the gtest | |
346 filter. | |
347 """ | |
348 return unittest.TestSuite( | |
349 self._FilterTests(self._GetTestsFromSuite(suite), gtest_filter)) | |
350 | |
351 def _FilterTests(self, all_tests, gtest_filter): | |
352 """Returns a filtered list of tests based on the given gtest filter. | |
353 | |
354 Args: | |
355 all_tests: A list that contains all unittests in a given suite. This | |
356 list must be obtained by calling |_GetTestsFromSuite|. | |
357 gtest_filter: The gtest filter to use. Filter can be passed as follows: | |
358 *className* or *testcaseName. | |
359 | |
360 Returns: | |
361 A list that contains all tests that match the given gtest filter. | |
362 """ | |
363 pattern_groups = gtest_filter.split('-') | |
364 positive_patterns = pattern_groups[0].split(':') | |
365 negative_patterns = None | |
366 if len(pattern_groups) > 1: | |
367 negative_patterns = pattern_groups[1].split(':') | |
368 tests = [] | |
369 for test in all_tests: | |
370 test_name = self._GetTestName(test) | |
371 # Test name must by matched by one positive pattern. | |
372 for pattern in positive_patterns: | |
373 if fnmatch.fnmatch(test_name, pattern): | |
374 break | |
375 else: | |
376 continue | |
377 # Test name must not be matched by any negative patterns. | |
378 for pattern in negative_patterns or []: | |
379 if fnmatch.fnmatch(test_name, pattern): | |
380 break | |
381 else: | |
382 tests += [test] | |
383 return tests | |
299 | 384 |
300 def _Run(self): | 385 def _Run(self): |
301 """Runs the unit tests.""" | 386 """Runs the unit tests.""" |
302 tests = self._GetTests() | 387 if self._opts.filter: |
388 tests = self._GetFilteredTests() | |
389 else: | |
390 tests = unittest.defaultTestLoader.loadTestsFromName(self._mod_name) | |
303 result = pyauto_utils.GTestTextTestRunner(verbosity=1).run(tests) | 391 result = pyauto_utils.GTestTextTestRunner(verbosity=1).run(tests) |
304 del(tests) | 392 del(tests) |
305 if not result.wasSuccessful(): | 393 if not result.wasSuccessful(): |
306 print >>sys.stderr, ('Not all tests were successful.') | 394 print >>sys.stderr, ('Not all tests were successful.') |
307 sys.exit(1) | 395 sys.exit(1) |
308 sys.exit(0) | 396 sys.exit(0) |
OLD | NEW |