summaryrefslogtreecommitdiffstats
path: root/build/android/test_result.py
blob: 7d9b21600c44cb1a34f49b7ceb7fa561d07674cc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# 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 logging


# Language values match constants in Sponge protocol buffer (sponge.proto).
JAVA = 5
PYTHON = 7


class BaseTestResult(object):
  """A single result from a unit test."""

  def __init__(self, name, log):
    self.name = name
    self.log = log


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.
    lang: Language of the test (JAVA or PYTHON).
    log: An optional string listing any errors.
    error: A tuple of a short error message and a longer version used by Sponge
    if test resulted in a fail or error.  An empty tuple implies a pass.
  """

  def __init__(self, full_name, start_date, dur, lang, log='', error=()):
    BaseTestResult.__init__(self, full_name, log)
    name_pieces = full_name.rsplit('#')
    if len(name_pieces) > 0:
      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
    self.error = error
    self.lang = lang


class TestResults(object):
  """Results of a test run."""

  def __init__(self):
    self.ok = []
    self.failed = []
    self.crashed = []
    self.unknown = []
    self.disabled = []
    self.unexpected_pass = []
    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
      ret.disabled += t.disabled
      ret.unexpected_pass += t.unexpected_pass
      if t.timed_out:
        ret.timed_out = True
      if t.overall_fail:
        ret.overall_fail = True
    return ret

  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):
    """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 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