Move to kernel style SPDX license identifiers
[babeltrace.git] / tests / utils / python / tap / tracker.py
CommitLineData
0235b0db
MJ
1# SPDX-License-Identifier: BSD-2-Clause
2#
b85894a3
MJ
3# Copyright (c) 2016, Matt Layman
4
5from __future__ import print_function
6import os
7import string
8import sys
9
10from tap.directive import Directive
11from tap.i18n import _
12from tap.line import Result
13
14
15class Tracker(object):
16
17 def __init__(
18 self, outdir=None, combined=False, streaming=False, stream=None,
19 header=True):
20 self.outdir = outdir
21
22 # Combine all the test results into one file.
23 self.combined = combined
24 self.combined_line_number = 0
25 # Test case ordering is important for the combined results
26 # because of how numbers are assigned. The test cases
27 # must be tracked in order so that reporting can sequence
28 # the line numbers properly.
29 self.combined_test_cases_seen = []
30
31 # Stream output directly to a stream instead of file output.
32 self.streaming = streaming
33 self.stream = stream
34
35 # Display the test case header unless told not to.
36 self.header = header
37
38 # Internal state for tracking each test case.
39 self._test_cases = {}
40
41 # Python versions 2 and 3 keep maketrans in different locations.
42 if sys.version_info[0] < 3:
43 self._sanitized_table = string.maketrans(' \\/\n', '----')
44 else: # pragma: no cover
45 self._sanitized_table = str.maketrans(' \\/\n', '----')
46
47 def _get_outdir(self):
48 return self._outdir
49
50 def _set_outdir(self, outdir):
51 self._outdir = outdir
52 if outdir and not os.path.exists(outdir):
53 os.makedirs(outdir)
54
55 outdir = property(_get_outdir, _set_outdir)
56
57 def _track(self, class_name):
58 """Keep track of which test cases have executed."""
59 if self._test_cases.get(class_name) is None:
60 if self.streaming and self.header:
61 self._write_test_case_header(class_name, self.stream)
62
63 self._test_cases[class_name] = []
64 if self.combined:
65 self.combined_test_cases_seen.append(class_name)
66
67 def add_ok(self, class_name, description, directive=''):
68 result = Result(
69 ok=True, number=self._get_next_line_number(class_name),
70 description=description, directive=Directive(directive))
71 self._add_line(class_name, result)
72
73 def add_not_ok(
74 self, class_name, description, directive='', diagnostics=None):
75 result = Result(
76 ok=False, number=self._get_next_line_number(class_name),
77 description=description, diagnostics=diagnostics,
78 directive=Directive(directive))
79 self._add_line(class_name, result)
80
81 def add_skip(self, class_name, description, reason):
82 directive = 'SKIP {0}'.format(reason)
83 result = Result(
84 ok=True, number=self._get_next_line_number(class_name),
85 description=description, directive=Directive(directive))
86 self._add_line(class_name, result)
87
88 def _add_line(self, class_name, result):
89 self._track(class_name)
90 if self.streaming:
91 print(result, file=self.stream)
92 self._test_cases[class_name].append(result)
93
94 def _get_next_line_number(self, class_name):
95 if self.combined or self.streaming:
96 # This has an obvious side effect. Oh well.
97 self.combined_line_number += 1
98 return self.combined_line_number
99 else:
100 try:
101 return len(self._test_cases[class_name]) + 1
102 except KeyError:
103 # A result is created before the call to _track so the test
104 # case may not be tracked yet. In that case, the line is 1.
105 return 1
106
107 def generate_tap_reports(self):
108 """Generate TAP reports.
109
110 The results are either combined into a single output file or
111 the output file name is generated from the test case.
112 """
113 if self.streaming:
114 # The results already went to the stream, record the plan.
115 print('1..{0}'.format(self.combined_line_number), file=self.stream)
116 return
117
118 if self.combined:
119 combined_file = 'testresults.tap'
120 if self.outdir:
121 combined_file = os.path.join(self.outdir, combined_file)
122 with open(combined_file, 'w') as out_file:
123 for test_case in self.combined_test_cases_seen:
124 self.generate_tap_report(
125 test_case, self._test_cases[test_case], out_file)
126 print(
127 '1..{0}'.format(self.combined_line_number), file=out_file)
128 else:
129 for test_case, tap_lines in self._test_cases.items():
130 with open(self._get_tap_file_path(test_case), 'w') as out_file:
131 self.generate_tap_report(test_case, tap_lines, out_file)
132
133 def generate_tap_report(self, test_case, tap_lines, out_file):
134 self._write_test_case_header(test_case, out_file)
135
136 for tap_line in tap_lines:
137 print(tap_line, file=out_file)
138
139 # For combined results, the plan is only output once after
140 # all the test cases complete.
141 if not self.combined:
142 print('1..{0}'.format(len(tap_lines)), file=out_file)
143
144 def _write_test_case_header(self, test_case, stream):
145 print(_('# TAP results for {test_case}').format(
146 test_case=test_case), file=stream)
147
148 def _get_tap_file_path(self, test_case):
149 """Get the TAP output file path for the test case."""
150 sanitized_test_case = test_case.translate(self._sanitized_table)
151 tap_file = sanitized_test_case + '.tap'
152 if self.outdir:
153 return os.path.join(self.outdir, tap_file)
154 return tap_file
This page took 0.053483 seconds and 4 git commands to generate.