Initial import of block device refactoring.
[barrelfish] / tools / harness / results.py
1 ##########################################################################
2 # Copyright (c) 2009, ETH Zurich.
3 # All rights reserved.
4 #
5 # This file is distributed under the terms in the attached LICENSE file.
6 # If you do not find this file, copies can be found by writing to:
7 # ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8 ##########################################################################
9
10 from stats import Stats
11
12 class ResultsBase(object):
13     def __init__(self, name=None, reason=""):
14         self.name = name
15         self.fail_reason = reason
16
17     def reason(self):
18         return self.fail_reason
19
20     def passed(self):
21         """Returns true iff the test is considered to have passed."""
22         raise NotImplementedError
23
24     def to_file(self, filehandle):
25         """May be used to write formatted results to a file."""
26         raise NotImplementedError
27
28
29 class PassFailResult(ResultsBase):
30     """Stores results of test that is purely pass/fail."""
31     def __init__(self, passed, reason=""):
32         super(PassFailResult, self).__init__(reason=reason)
33         self.passfail = passed
34
35     def passed(self):
36         return self.passfail
37
38
39 class PassFailMultiResult(ResultsBase):
40     def __init__(self, name, errors=[]):
41         self.errors = errors
42         self.name = name
43
44     def reason(self):
45         return str(errors)
46
47     def passed(self):
48         return len(self.errors) == 0
49
50     def to_file(self, fh):
51         if len(self.errors) > 0:
52             fh.write('%d error(s) in %s\n' % (len(self.errors), self.name))
53             for error in self.errors:
54                 fh.write(error)
55
56 class RowResults(ResultsBase):
57     """Results class that maintains numeric values grouped by rows.
58     """
59     def __init__(self, colnames, name=None):
60         super(RowResults, self).__init__(name)
61         self.colnames = colnames
62         self.rows = []
63         self.failed = False
64
65     def passed(self):
66         if self.failed:
67             return False
68         return self.rows != []
69
70     def to_file(self, fh):
71         """Produce a file in a format suitable for gnuplot."""
72         fh.write('# %s\n' % '\t'.join(self.colnames))
73         for r in self.rows:
74             fh.write('\t'.join(map(str, r)) + '\n')
75
76     def mark_failed(self, reason):
77         """Mark this test as having failed."""
78         self.failed = True
79         self.fail_reason = reason
80
81     def add_row(self, row):
82         assert(len(row) == len(self.colnames))
83         self.rows.append(row)
84
85
86 class RawResults(RowResults):
87     """Results class suitable for processing statistics on raw data
88     (eg. microbenchmarks where we have each individual measurement)"""
89
90     def __init__(self, groupheader, name=None):
91         headers = 'nvalues median mean stddev min max'.split()
92         super(RawResults, self).__init__([groupheader] + headers, name=name)
93
94     def add_group(self, identifier, data):
95         st = Stats(data)
96         self.add_row([identifier, st.nvalues, st.median, st.mean, st.stddev,
97                       st.minimum, st.maximum])