media/webrtc/trunk/build/android/pylib/base_test_sharder.py

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

michael@0 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
michael@0 2 # Use of this source code is governed by a BSD-style license that can be
michael@0 3 # found in the LICENSE file.
michael@0 4
michael@0 5
michael@0 6 import logging
michael@0 7 import multiprocessing
michael@0 8
michael@0 9 from test_result import TestResults
michael@0 10
michael@0 11
michael@0 12 def _ShardedTestRunnable(test):
michael@0 13 """Standalone function needed by multiprocessing.Pool."""
michael@0 14 log_format = '[' + test.device + '] # %(asctime)-15s: %(message)s'
michael@0 15 if logging.getLogger().handlers:
michael@0 16 logging.getLogger().handlers[0].setFormatter(logging.Formatter(log_format))
michael@0 17 else:
michael@0 18 logging.basicConfig(format=log_format)
michael@0 19 # Handle SystemExit here since python has a bug to exit current process
michael@0 20 try:
michael@0 21 return test.Run()
michael@0 22 except SystemExit:
michael@0 23 return TestResults()
michael@0 24
michael@0 25 def SetTestsContainer(tests_container):
michael@0 26 """Sets tests container.
michael@0 27
michael@0 28 multiprocessing.Queue can't be pickled across processes, so we need to set
michael@0 29 this as a 'global', per process, via multiprocessing.Pool.
michael@0 30 """
michael@0 31 BaseTestSharder.tests_container = tests_container
michael@0 32
michael@0 33
michael@0 34 class BaseTestSharder(object):
michael@0 35 """Base class for sharding tests across multiple devices.
michael@0 36
michael@0 37 Args:
michael@0 38 attached_devices: A list of attached devices.
michael@0 39 """
michael@0 40 # See more in SetTestsContainer.
michael@0 41 tests_container = None
michael@0 42
michael@0 43 def __init__(self, attached_devices):
michael@0 44 self.attached_devices = attached_devices
michael@0 45 self.retries = 1
michael@0 46 self.tests = []
michael@0 47
michael@0 48 def CreateShardedTestRunner(self, device, index):
michael@0 49 """Factory function to create a suite-specific test runner.
michael@0 50
michael@0 51 Args:
michael@0 52 device: Device serial where this shard will run
michael@0 53 index: Index of this device in the pool.
michael@0 54
michael@0 55 Returns:
michael@0 56 An object of BaseTestRunner type (that can provide a "Run()" method).
michael@0 57 """
michael@0 58 pass
michael@0 59
michael@0 60 def SetupSharding(self, tests):
michael@0 61 """Called before starting the shards."""
michael@0 62 pass
michael@0 63
michael@0 64 def OnTestsCompleted(self, test_runners, test_results):
michael@0 65 """Notifies that we completed the tests."""
michael@0 66 pass
michael@0 67
michael@0 68 def RunShardedTests(self):
michael@0 69 """Runs the tests in all connected devices.
michael@0 70
michael@0 71 Returns:
michael@0 72 A TestResults object.
michael@0 73 """
michael@0 74 logging.warning('*' * 80)
michael@0 75 logging.warning('Sharding in ' + str(len(self.attached_devices)) +
michael@0 76 ' devices.')
michael@0 77 logging.warning('Note that the output is not synchronized.')
michael@0 78 logging.warning('Look for the "Final result" banner in the end.')
michael@0 79 logging.warning('*' * 80)
michael@0 80 final_results = TestResults()
michael@0 81 for retry in xrange(self.retries):
michael@0 82 logging.warning('Try %d of %d', retry + 1, self.retries)
michael@0 83 self.SetupSharding(self.tests)
michael@0 84 test_runners = []
michael@0 85 for index, device in enumerate(self.attached_devices):
michael@0 86 logging.warning('*' * 80)
michael@0 87 logging.warning('Creating shard %d for %s', index, device)
michael@0 88 logging.warning('*' * 80)
michael@0 89 test_runner = self.CreateShardedTestRunner(device, index)
michael@0 90 test_runners += [test_runner]
michael@0 91 logging.warning('Starting...')
michael@0 92 pool = multiprocessing.Pool(len(self.attached_devices),
michael@0 93 SetTestsContainer,
michael@0 94 [BaseTestSharder.tests_container])
michael@0 95 # map can't handle KeyboardInterrupt exception. It's a python bug.
michael@0 96 # So use map_async instead.
michael@0 97 async_results = pool.map_async(_ShardedTestRunnable, test_runners)
michael@0 98 results_lists = async_results.get(999999)
michael@0 99 test_results = TestResults.FromTestResults(results_lists)
michael@0 100 if retry == self.retries - 1:
michael@0 101 all_passed = final_results.ok + test_results.ok
michael@0 102 final_results = test_results
michael@0 103 final_results.ok = all_passed
michael@0 104 break
michael@0 105 else:
michael@0 106 final_results.ok += test_results.ok
michael@0 107 self.tests = []
michael@0 108 for t in test_results.GetAllBroken():
michael@0 109 self.tests += [t.name]
michael@0 110 if not self.tests:
michael@0 111 break
michael@0 112 self.OnTestsCompleted(test_runners, final_results)
michael@0 113 return final_results

mercurial