8556b5dfb8
We're currently using the tests standard error for reporting tests. We can add TAP later to integrate with other tools. Additionally, this patch simplifies the exclude patterns passed to collect_dirs_to_recurse.
190 lines
4.5 KiB
Python
190 lines
4.5 KiB
Python
#!/usr/bin/env python
|
|
# encoding: utf-8
|
|
|
|
from waflib import Logs
|
|
|
|
SOURCE_EXTS = [
|
|
'*.S',
|
|
'*.c',
|
|
'*.cpp',
|
|
]
|
|
|
|
UTILITY_SOURCE_EXTS = [ 'utility/' + glob for glob in SOURCE_EXTS ]
|
|
|
|
# TODO: Once HAL patches get in, need to filter out the HAL based
|
|
# on the bld.env.BOARD.
|
|
COMMON_VEHICLE_DEPENDENT_LIBRARIES = [
|
|
'AP_ADC',
|
|
'AP_ADC_AnalogSource',
|
|
'AP_AHRS',
|
|
'AP_Airspeed',
|
|
'AP_Baro',
|
|
'AP_BattMonitor',
|
|
'AP_BoardConfig',
|
|
'AP_Buffer',
|
|
'AP_Common',
|
|
'AP_Compass',
|
|
'AP_Declination',
|
|
'AP_GPS',
|
|
'AP_HAL',
|
|
'AP_HAL_Empty',
|
|
'AP_InertialSensor',
|
|
'AP_Math',
|
|
'AP_Mission',
|
|
'AP_NavEKF',
|
|
'AP_NavEKF2',
|
|
'AP_Notify',
|
|
'AP_OpticalFlow',
|
|
'AP_Param',
|
|
'AP_Progmem',
|
|
'AP_Rally',
|
|
'AP_RangeFinder',
|
|
'AP_Scheduler',
|
|
'AP_SerialManager',
|
|
'AP_Terrain',
|
|
'AP_Vehicle',
|
|
'DataFlash',
|
|
'Filter',
|
|
'GCS_MAVLink',
|
|
'RC_Channel',
|
|
'SITL',
|
|
'StorageManager',
|
|
]
|
|
|
|
def _get_legacy_defines(name):
|
|
return [
|
|
'APM_BUILD_DIRECTORY=' + name,
|
|
'SKETCH="' + name + '"',
|
|
'SKETCHNAME="' + name + '"',
|
|
]
|
|
|
|
IGNORED_AP_LIBRARIES = [
|
|
'doc',
|
|
'AP_Limits',
|
|
'GCS_Console',
|
|
]
|
|
|
|
def get_all_libraries(bld):
|
|
libraries = []
|
|
for lib_node in bld.srcnode.ant_glob('libraries/*', dir=True):
|
|
name = lib_node.name
|
|
if name in IGNORED_AP_LIBRARIES:
|
|
continue
|
|
if name.startswith('AP_HAL'):
|
|
continue
|
|
libraries.append(name)
|
|
libraries.extend(['AP_HAL', 'AP_HAL_Empty'])
|
|
return libraries
|
|
|
|
def program(bld, **kw):
|
|
if 'target' in kw:
|
|
bld.fatal('Do not pass target for program')
|
|
if 'defines' not in kw:
|
|
kw['defines'] = []
|
|
if 'source' not in kw:
|
|
kw['source'] = bld.path.ant_glob(SOURCE_EXTS)
|
|
|
|
name = bld.path.name
|
|
kw['defines'].extend(_get_legacy_defines(name))
|
|
|
|
target = bld.bldnode.make_node(name + '.' + bld.env.BOARD)
|
|
bld.program(
|
|
target=target,
|
|
**kw
|
|
)
|
|
|
|
# NOTE: Code in libraries/ is compiled multiple times. So ensure each
|
|
# compilation is independent by providing different index for each.
|
|
# The need for this should disappear when libraries change to be
|
|
# independent of vehicle type.
|
|
LAST_IDX = 0
|
|
|
|
def _get_next_idx():
|
|
global LAST_IDX
|
|
LAST_IDX += 1
|
|
return LAST_IDX
|
|
|
|
def vehicle_stlib(bld, **kw):
|
|
if 'name' not in kw:
|
|
bld.fatal('Missing name for vehicle_stlib')
|
|
if 'vehicle' not in kw:
|
|
bld.fatal('Missing vehicle for vehicle_stlib')
|
|
if 'libraries' not in kw:
|
|
bld.fatal('Missing libraries for vehicle_stlib')
|
|
|
|
sources = []
|
|
libraries = kw['libraries'] + bld.env.AP_LIBRARIES
|
|
|
|
for lib_name in libraries:
|
|
lib_node = bld.srcnode.find_dir('libraries/' + lib_name)
|
|
if lib_node is None:
|
|
bld.fatal('Could not find library ' + lib_name)
|
|
lib_sources = lib_node.ant_glob(SOURCE_EXTS + UTILITY_SOURCE_EXTS)
|
|
sources.extend(lib_sources)
|
|
|
|
name = kw['name']
|
|
vehicle = kw['vehicle']
|
|
|
|
bld.stlib(
|
|
source=sources,
|
|
target=name,
|
|
defines=_get_legacy_defines(vehicle),
|
|
idx=_get_next_idx(),
|
|
)
|
|
|
|
def find_tests(bld, use=[]):
|
|
features = ''
|
|
if bld.cmd == 'check':
|
|
features='test'
|
|
|
|
for f in bld.path.ant_glob(incl='*.cpp'):
|
|
target = f.change_ext('.' + bld.env.BOARD)
|
|
bld.program(
|
|
features=features,
|
|
target=target,
|
|
source=[f],
|
|
use=use,
|
|
)
|
|
|
|
def test_summary(bld):
|
|
from io import BytesIO
|
|
import sys
|
|
|
|
if not hasattr(bld, 'utest_results'):
|
|
Logs.info('check: no test run')
|
|
return
|
|
|
|
fails = []
|
|
|
|
for filename, exit_code, out, err in bld.utest_results:
|
|
Logs.pprint('GREEN' if exit_code == 0 else 'YELLOW',
|
|
' %s' % filename,
|
|
'returned %d' % exit_code)
|
|
|
|
if exit_code != 0:
|
|
fails.append(filename)
|
|
elif not bld.options.check_verbose:
|
|
continue
|
|
|
|
if len(out):
|
|
buf = BytesIO(out)
|
|
for line in buf:
|
|
print(" OUT: %s" % line.decode(), end='', file=sys.stderr)
|
|
print()
|
|
|
|
if len(err):
|
|
buf = BytesIO(err)
|
|
for line in buf:
|
|
print(" ERR: %s" % line.decode(), end='', file=sys.stderr)
|
|
print()
|
|
|
|
if not fails:
|
|
Logs.info('check: All %u tests passed!' % len(bld.utest_results))
|
|
return
|
|
|
|
Logs.error('check: %u of %u tests failed' %
|
|
(len(fails), len(bld.utest_results)))
|
|
|
|
for filename in fails:
|
|
Logs.error(' %s' % filename)
|