1 import sys
, re
, traceback
3 # these statuses are ordered such that a status earlier in the list will
4 # override a status later in a list (e.g. ERROR during a test will override
5 # prior GOOD results, but WARN will not override a FAIL)
6 job_statuses
= ["TEST_NA", "ABORT", "ERROR", "FAIL", "WARN", "GOOD", "ALERT",
9 def is_valid_status(status
):
10 if not re
.match(r
'(START|INFO|(END )?(' + '|'.join(job_statuses
) + '))$',
17 def is_failure(status
):
18 if not is_valid_status(status
):
20 if status
in ('START', 'INFO'):
22 if status
.startswith('END '):
23 status
= status
[len('END '):]
24 return job_statuses
.index(status
) <= job_statuses
.index("FAIL")
29 Generic method decorator for logging calls under the
30 assumption that return=GOOD, exception=FAIL. The method
31 determines parameters as:
32 subdir = self.subdir if it exists, or None
33 operation = "class name"."method name"
34 status = None on GOOD, str(exception) on FAIL
35 The object using this method must have a job attribute
36 for the logging to actually occur, otherwise the logging
39 Logging can explicitly be disabled for a call by passing
40 a logged=False parameter
42 def recorded_func(self
, *args
, **dargs
):
43 logged
= dargs
.pop('logged', True)
44 job
= getattr(self
, 'job', None)
45 # if logging is disabled/unavailable, just
47 if not logged
or job
is None:
48 return fn(self
, *args
, **dargs
)
49 # logging is available, so wrap the method call
50 # in success/failure logging
51 subdir
= getattr(self
, 'subdir', None)
52 operation
= '%s.%s' % (self
.__class
__.__name
__,
55 result
= fn(self
, *args
, **dargs
)
56 job
.record('GOOD', subdir
, operation
)
57 except Exception, detail
:
58 job
.record('FAIL', subdir
, operation
, str(detail
))
64 def log_and_ignore_errors(msg
):
65 """ A decorator for wrapping functions in a 'log exception and ignore'
68 def decorated_func(*args
, **dargs
):
73 traceback
.print_exc(file=sys
.stdout
)