summaryrefslogtreecommitdiffstats
path: root/media/webrtc/trunk/build/android/pylib/test_result.py
diff options
context:
space:
mode:
Diffstat (limited to 'media/webrtc/trunk/build/android/pylib/test_result.py')
-rw-r--r--media/webrtc/trunk/build/android/pylib/test_result.py193
1 files changed, 193 insertions, 0 deletions
diff --git a/media/webrtc/trunk/build/android/pylib/test_result.py b/media/webrtc/trunk/build/android/pylib/test_result.py
new file mode 100644
index 000000000..31a546aca
--- /dev/null
+++ b/media/webrtc/trunk/build/android/pylib/test_result.py
@@ -0,0 +1,193 @@
+# 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.
+
+
+import json
+import logging
+import os
+import time
+import traceback
+
+import buildbot_report
+import constants
+
+
+class BaseTestResult(object):
+ """A single result from a unit test."""
+
+ def __init__(self, name, log):
+ self.name = name
+ self.log = log.replace('\r', '')
+
+
+class SingleTestResult(BaseTestResult):
+ """Result information for a single test.
+
+ Args:
+ full_name: Full name of the test.
+ start_date: Date in milliseconds when the test began running.
+ dur: Duration of the test run in milliseconds.
+ log: An optional string listing any errors.
+ """
+
+ def __init__(self, full_name, start_date, dur, log=''):
+ BaseTestResult.__init__(self, full_name, log)
+ name_pieces = full_name.rsplit('#')
+ if len(name_pieces) > 1:
+ self.test_name = name_pieces[1]
+ self.class_name = name_pieces[0]
+ else:
+ self.class_name = full_name
+ self.test_name = full_name
+ self.start_date = start_date
+ self.dur = dur
+
+
+class TestResults(object):
+ """Results of a test run."""
+
+ def __init__(self):
+ self.ok = []
+ self.failed = []
+ self.crashed = []
+ self.unknown = []
+ self.timed_out = False
+ self.overall_fail = False
+
+ @staticmethod
+ def FromRun(ok=None, failed=None, crashed=None, timed_out=False,
+ overall_fail=False):
+ ret = TestResults()
+ ret.ok = ok or []
+ ret.failed = failed or []
+ ret.crashed = crashed or []
+ ret.timed_out = timed_out
+ ret.overall_fail = overall_fail
+ return ret
+
+ @staticmethod
+ def FromTestResults(results):
+ """Combines a list of results in a single TestResults object."""
+ ret = TestResults()
+ for t in results:
+ ret.ok += t.ok
+ ret.failed += t.failed
+ ret.crashed += t.crashed
+ ret.unknown += t.unknown
+ if t.timed_out:
+ ret.timed_out = True
+ if t.overall_fail:
+ ret.overall_fail = True
+ return ret
+
+ @staticmethod
+ def FromPythonException(test_name, start_date_ms, exc_info):
+ """Constructs a TestResults with exception information for the given test.
+
+ Args:
+ test_name: name of the test which raised an exception.
+ start_date_ms: the starting time for the test.
+ exc_info: exception info, ostensibly from sys.exc_info().
+
+ Returns:
+ A TestResults object with a SingleTestResult in the failed list.
+ """
+ exc_type, exc_value, exc_traceback = exc_info
+ trace_info = ''.join(traceback.format_exception(exc_type, exc_value,
+ exc_traceback))
+ log_msg = 'Exception:\n' + trace_info
+ duration_ms = (int(time.time()) * 1000) - start_date_ms
+
+ exc_result = SingleTestResult(
+ full_name='PythonWrapper#' + test_name,
+ start_date=start_date_ms,
+ dur=duration_ms,
+ log=(str(exc_type) + ' ' + log_msg))
+
+ results = TestResults()
+ results.failed.append(exc_result)
+ return results
+
+ def _Log(self, sorted_list):
+ for t in sorted_list:
+ logging.critical(t.name)
+ if t.log:
+ logging.critical(t.log)
+
+ def GetAllBroken(self):
+ """Returns the all broken tests including failed, crashed, unknown."""
+ return self.failed + self.crashed + self.unknown
+
+ def LogFull(self, test_group, test_suite, build_type):
+ """Output broken test logs, summarize in a log file and the test output."""
+ # Output all broken tests or 'passed' if none broken.
+ logging.critical('*' * 80)
+ logging.critical('Final result')
+ if self.failed:
+ logging.critical('Failed:')
+ self._Log(sorted(self.failed))
+ if self.crashed:
+ logging.critical('Crashed:')
+ self._Log(sorted(self.crashed))
+ if self.unknown:
+ logging.critical('Unknown:')
+ self._Log(sorted(self.unknown))
+ if not self.GetAllBroken():
+ logging.critical('Passed')
+ logging.critical('*' * 80)
+
+ # Summarize in a log file, if tests are running on bots.
+ if test_group and test_suite and os.environ.get('BUILDBOT_BUILDERNAME'):
+ log_file_path = os.path.join(constants.CHROME_DIR, 'out',
+ build_type, 'test_logs')
+ if not os.path.exists(log_file_path):
+ os.mkdir(log_file_path)
+ full_file_name = os.path.join(log_file_path, test_group)
+ if not os.path.exists(full_file_name):
+ with open(full_file_name, 'w') as log_file:
+ print >> log_file, '\n%s results for %s build %s:' % (
+ test_group, os.environ.get('BUILDBOT_BUILDERNAME'),
+ os.environ.get('BUILDBOT_BUILDNUMBER'))
+ log_contents = [' %s result : %d tests ran' % (test_suite,
+ len(self.ok) +
+ len(self.failed) +
+ len(self.crashed) +
+ len(self.unknown))]
+ content_pairs = [('passed', len(self.ok)), ('failed', len(self.failed)),
+ ('crashed', len(self.crashed))]
+ for (result, count) in content_pairs:
+ if count:
+ log_contents.append(', %d tests %s' % (count, result))
+ with open(full_file_name, 'a') as log_file:
+ print >> log_file, ''.join(log_contents)
+ content = {'test_group': test_group,
+ 'ok': [t.name for t in self.ok],
+ 'failed': [t.name for t in self.failed],
+ 'crashed': [t.name for t in self.failed],
+ 'unknown': [t.name for t in self.unknown],}
+ with open(os.path.join(log_file_path, 'results.json'), 'a') as json_file:
+ print >> json_file, json.dumps(content)
+
+ # Summarize in the test output.
+ summary_string = 'Summary:\n'
+ summary_string += 'RAN=%d\n' % (len(self.ok) + len(self.failed) +
+ len(self.crashed) + len(self.unknown))
+ summary_string += 'PASSED=%d\n' % (len(self.ok))
+ summary_string += 'FAILED=%d %s\n' % (len(self.failed),
+ [t.name for t in self.failed])
+ summary_string += 'CRASHED=%d %s\n' % (len(self.crashed),
+ [t.name for t in self.crashed])
+ summary_string += 'UNKNOWN=%d %s\n' % (len(self.unknown),
+ [t.name for t in self.unknown])
+ logging.critical(summary_string)
+ return summary_string
+
+ def PrintAnnotation(self):
+ """Print buildbot annotations for test results."""
+ if self.timed_out:
+ buildbot_report.PrintWarning()
+ elif self.failed or self.crashed or self.overall_fail:
+ buildbot_report.PrintError()
+ else:
+ print 'Step success!' # No annotation needed