Files
paparazzi/tests/modules/TAP/__init__.py
T
Gautier Hattenberger 494e3f3ad9 [tests] add a compilation test node to modules (#2653)
When adding a test node to a makefile section, with required compilation
flags, include and other options, all the files (not arch dependent
files) can be compiled with a TAP compatible program, included in the
standard tests of the CI servers.
Not all module's XML files are converted, but a large part of the most
important parts are already covered. More will be added later. The
number of tested airframes (full compilation of all targets) have been
reduced to speed the CI compile time but still covers the relevant
architecture and boards.
The main benefit is that the overall coverage is already better than
before as previous test aircraft were compiling more or less the same
part of the airborne code, while this new mechanism is more efficient to
test modules not included in any config.
2021-02-08 17:24:19 +01:00

102 lines
2.7 KiB
Python

import sys
import atexit
# todo: make written-to stream passable
class Plan(object):
def __init__(self, plan, param=None):
self.counter = 0
self.expected_tests = None
self.ended = False
if isinstance(plan, int):
self.expected_tests = plan
print(("1..%u" % self.expected_tests))
elif plan == "no_plan" or plan == None: 1
elif plan == "skip_all":
print(("1..0 # skip %s" % param))
raise SystemExit(0) # ??? this is what T::B does, but sucks
else:
raise TestBadPlan(plan)
def increment_counter(self):
self.counter += 1
def __del__(self):
if self.ended: return
self.ended = True
if self.expected_tests is None:
print(("1..%u" % self.counter))
elif self.counter != self.expected_tests:
print(("# Looks like you planned %u tests but ran %u." \
% (self.expected_tests, self.counter)))
class Builder(object):
global_defaults = {
"_plan": None,
"current": 1,
"has_plan": False,
}
global_test_builder = global_defaults.copy()
def __init__(self, plan=None, plan_param=None):
self.__dict__ = self.global_test_builder
if plan: self.set_plan(plan, plan_param)
@classmethod
def create(cls, plan=None, plan_param=None):
return Builder(plan, plan_param)
def set_plan(self, plan, plan_param=None):
if self.get_plan(): raise TestPlannedAlready(plan, plan_param)
self._plan = Plan(plan, plan_param)
atexit.register(self._plan.__del__)
def get_plan(self): return self._plan
def ok(self, is_ok, desc=None, skip=None, todo=None):
self.get_plan().increment_counter()
if skip and todo: raise TestBadDirective(self)
if is_ok: report = "ok"
else: report = "not ok"
sys.stdout.write("%s %u" % (report, self.current))
if desc: sys.stdout.write(" - %s" % desc)
if skip: sys.stdout.write(" # SKIP %s" % skip)
if todo: sys.stdout.write(" # TODO %s" % todo)
print("")
self.current += 1
return is_ok
def reset(self):
self.__dict__.clear()
for key in list(self.global_defaults.keys()):
self.__dict__[key] = self.global_defaults[key]
class TestPlannedAlready(Exception):
def __init__(self, plan, param=None):
self.plan = plan
self.param = param
def __str__(self):
return "tried to plan twice; second plan: %s, %s" % self.plan, self.param
class TestWithoutPlan(Exception):
def __str__(self):
return "tried running tests without a plan"
class TestBadPlan(Exception):
def __init__(self, plan):
self.plan = plan
def __str__(self):
return "didn't understand plan '%s'" % self.plan
class TestBadDirective(Exception):
def __str__(self):
return "tried running a test with more than one directive"