aboutsummaryrefslogtreecommitdiff
path: root/automation/clients/report/dejagnu/manifest.py
blob: 5831d1b0f6ad9c383e31cfcf7f22c886a5debfe4 (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
# Copyright 2011 Google Inc. All Rights Reserved.
# Author: kbaclawski@google.com (Krystian Baclawski)
#

__author__ = 'kbaclawski@google.com (Krystian Baclawski)'

from collections import namedtuple
from cStringIO import StringIO
import logging

from summary import DejaGnuTestResult


class Manifest(namedtuple('Manifest', 'tool board results')):
  """Stores a list of unsuccessful tests.

  Any line that starts with '#@' marker carries auxiliary data in form of a
  key-value pair, for example:

  #@ tool: *
  #@ board: unix

  So far tool and board parameters are recognized.  Their value can contain
  arbitrary glob expression.  Based on aforementioned parameters given manifest
  will be applied for all test results, but only in selected test runs.  Note
  that all parameters are optional.  Their default value is '*' (i.e. for all
  tools/boards).

  The meaning of lines above is as follows: corresponding test results to follow
  should only be suppressed if test run was performed on "unix" board.

  The summary line used to build the test result should have this format:

  attrlist | UNRESOLVED: gcc.dg/unroll_1.c (test for excess errors)
  ^^^^^^^^   ^^^^^^^^^^  ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^
  optional   result      name              variant
  attributes
  """
  SUPPRESSIBLE_RESULTS = ['FAIL', 'UNRESOLVED', 'XPASS', 'ERROR']

  @classmethod
  def FromDejaGnuTestRun(cls, test_run):
    results = [result
               for result in test_run.results
               if result.result in cls.SUPPRESSIBLE_RESULTS]

    return cls(test_run.tool, test_run.board, results)

  @classmethod
  def FromFile(cls, filename):
    """Creates manifest instance from a file in format described above."""
    params = {}
    results = []

    with open(filename, 'r') as manifest_file:
      for line in manifest_file:
        if line.startswith('#@'):
          # parse a line with a parameter
          try:
            key, value = line[2:].split(':', 1)
          except ValueError:
            logging.warning('Malformed parameter line: "%s".', line)
          else:
            params[key.strip()] = value.strip()
        else:
          # remove comment
          try:
            line, _ = line.split('#', 1)
          except ValueError:
            pass

          line = line.strip()

          if line:
            # parse a line with a test result
            result = DejaGnuTestResult.FromLine(line)

            if result:
              results.append(result)
            else:
              logging.warning('Malformed test result line: "%s".', line)

    tool = params.get('tool', '*')
    board = params.get('board', '*')

    return cls(tool, board, results)

  def Generate(self):
    """Dumps manifest to string."""
    text = StringIO()

    for name in ['tool', 'board']:
      text.write('#@ {0}: {1}\n'.format(name, getattr(self, name)))

    text.write('\n')

    for result in sorted(self.results, key=lambda r: r.result):
      text.write('{0}\n'.format(result))

    return text.getvalue()

  def __iter__(self):
    return iter(self.results)