Index: build/android/pylib/python_test_caller.py |
diff --git a/build/android/pylib/python_test_caller.py b/build/android/pylib/python_test_caller.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..2cc5d7c22bc3e38e8af3ac54ca1ec9379021bc66 |
--- /dev/null |
+++ b/build/android/pylib/python_test_caller.py |
@@ -0,0 +1,85 @@ |
+# Copyright (c) 2012 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+"""Helper module for calling python-based tests.""" |
+ |
+ |
+import logging |
+import sys |
+import time |
+ |
+from test_result import TestResults |
+ |
+ |
+def CallPythonTest(test, device_id, shard_index): |
+ """Invokes a test function and translates Python exceptions into test results. |
+ |
+ This method invokes SetUp()/TearDown() on the test. It is intended to be |
+ resilient to exceptions in SetUp(), the test itself, and TearDown(). Any |
+ Python exception means the test is marked as failed, and the test result will |
+ contain information about the exception. |
+ |
+ If SetUp() raises an exception, the test is not run. |
+ |
+ If TearDown() raises an exception, the test is treated as a failure. However, |
+ if the test itself raised an exception beforehand, that stack trace will take |
+ precedence whether or not TearDown() also raised an exception. |
+ |
+ shard_index is not applicable in single-device scenarios, when test execution |
+ is serial rather than parallel. Tests can use this to bring up servers with |
+ unique port numbers, for example. See also python_test_sharder. |
+ |
+ Args: |
+ test: an object which is ostensibly a subclass of PythonTestBase. |
+ device_id: device ID against which the test will run. |
+ shard_index: index # of the shard on which this test is running |
+ |
+ Returns: |
+ A TestResults object which contains any results produced by the test or, in |
+ the case of a Python exception, the Python exception info. |
+ """ |
+ |
+ start_date_ms = int(time.time()) * 1000 |
+ failed = False |
+ |
+ try: |
+ test.SetUp(device_id, shard_index) |
+ except Exception: |
+ failed = True |
+ logging.exception( |
+ 'Caught exception while trying to run SetUp() for test: ' + |
+ test.qualified_name) |
+ # Tests whose SetUp() method has failed are likely to fail, or at least |
+ # yield invalid results. |
+ exc_info = sys.exc_info() |
+ return TestResults.FromPythonException(test.qualified_name, start_date_ms, |
+ exc_info) |
+ |
+ try: |
+ result = test.Run() |
+ except Exception: |
+ # Setting this lets TearDown() avoid stomping on our stack trace from Run() |
+ # should TearDown() also raise an exception. |
+ failed = True |
+ logging.exception('Caught exception while trying to run test: ' + |
+ test.qualified_name) |
+ exc_info = sys.exc_info() |
+ result = TestResults.FromPythonException(test.qualified_name, start_date_ms, |
+ exc_info) |
+ |
+ try: |
+ test.TearDown() |
+ except Exception: |
+ logging.exception( |
+ 'Caught exception while trying run TearDown() for test: ' + |
+ test.qualified_name) |
+ if not failed: |
+ # Don't stomp the error during the test if TearDown blows up. This is a |
+ # trade-off: if the test fails, this will mask any problem with TearDown |
+ # until the test is fixed. |
+ exc_info = sys.exc_info() |
+ result = TestResults.FromPythonException(test.qualified_name, |
+ start_date_ms, exc_info) |
+ |
+ return result |