2011-10-30 23:50:34 -03:00
|
|
|
#!/usr/bin/env python
|
|
|
|
# APM automatic test suite
|
|
|
|
# Andrew Tridgell, October 2011
|
|
|
|
|
2011-12-02 00:21:15 -04:00
|
|
|
import pexpect, os, sys, shutil, atexit
|
2012-06-15 03:52:55 -03:00
|
|
|
import optparse, fnmatch, time, glob, traceback, signal
|
2011-10-30 23:50:34 -03:00
|
|
|
|
2011-12-02 00:21:15 -04:00
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)), 'pysim'))
|
2013-06-18 03:24:26 -03:00
|
|
|
|
2012-04-27 00:32:22 -03:00
|
|
|
import util
|
2011-12-02 00:21:15 -04:00
|
|
|
|
2011-11-25 23:44:07 -04:00
|
|
|
os.environ['PYTHONUNBUFFERED'] = '1'
|
|
|
|
|
2011-11-01 08:31:01 -03:00
|
|
|
os.putenv('TMPDIR', util.reltopdir('tmp'))
|
2011-10-30 23:50:34 -03:00
|
|
|
|
2016-05-21 12:19:50 -03:00
|
|
|
def get_default_params(atype, binary):
|
2011-10-30 23:50:34 -03:00
|
|
|
'''get default parameters'''
|
2015-03-25 22:57:46 -03:00
|
|
|
|
|
|
|
# use rover simulator so SITL is not starved of input
|
|
|
|
from pymavlink import mavutil
|
|
|
|
HOME=mavutil.location(40.071374969556928,-105.22978898137808,1583.702759,246)
|
2016-05-21 12:19:50 -03:00
|
|
|
if binary.find("plane") != -1 or binary.find("rover") != -1:
|
|
|
|
frame = "rover"
|
2015-05-04 20:26:31 -03:00
|
|
|
else:
|
2016-05-21 12:19:50 -03:00
|
|
|
frame = "+"
|
2015-03-25 22:57:46 -03:00
|
|
|
|
2015-05-05 03:56:17 -03:00
|
|
|
home = "%f,%f,%u,%u" % (HOME.lat, HOME.lng, HOME.alt, HOME.heading)
|
2016-05-21 12:19:50 -03:00
|
|
|
sil = util.start_SIL(binary, wipe=True, model=frame, home=home, speedup=10)
|
2011-10-30 23:50:34 -03:00
|
|
|
mavproxy = util.start_MAVProxy_SIL(atype)
|
2011-11-26 03:12:19 -04:00
|
|
|
print("Dumping defaults")
|
2011-10-30 23:50:34 -03:00
|
|
|
idx = mavproxy.expect(['Please Run Setup', 'Saved [0-9]+ parameters to (\S+)'])
|
|
|
|
if idx == 0:
|
|
|
|
# we need to restart it after eeprom erase
|
2011-11-09 00:45:18 -04:00
|
|
|
util.pexpect_close(mavproxy)
|
|
|
|
util.pexpect_close(sil)
|
2016-05-21 12:19:50 -03:00
|
|
|
sil = util.start_SIL(binary, model=frame, home=home, speedup=10)
|
2011-10-30 23:50:34 -03:00
|
|
|
mavproxy = util.start_MAVProxy_SIL(atype)
|
|
|
|
idx = mavproxy.expect('Saved [0-9]+ parameters to (\S+)')
|
|
|
|
parmfile = mavproxy.match.group(1)
|
2015-05-10 19:37:49 -03:00
|
|
|
dest = util.reltopdir('../buildlogs/%s-defaults.parm' % atype)
|
2011-10-30 23:50:34 -03:00
|
|
|
shutil.copy(parmfile, dest)
|
2011-11-09 00:45:18 -04:00
|
|
|
util.pexpect_close(mavproxy)
|
|
|
|
util.pexpect_close(sil)
|
2011-10-30 23:50:34 -03:00
|
|
|
print("Saved defaults for %s to %s" % (atype, dest))
|
2011-11-09 01:15:53 -04:00
|
|
|
return True
|
2011-11-07 07:55:21 -04:00
|
|
|
|
2012-02-19 02:05:21 -04:00
|
|
|
def build_all():
|
|
|
|
'''run the build_all.sh script'''
|
|
|
|
print("Running build_all.sh")
|
2012-02-19 18:16:57 -04:00
|
|
|
if util.run_cmd(util.reltopdir('Tools/scripts/build_all.sh'), dir=util.reltopdir('.')) != 0:
|
2012-02-19 02:05:21 -04:00
|
|
|
print("Failed build_all.sh")
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2013-03-10 03:16:56 -03:00
|
|
|
def build_binaries():
|
|
|
|
'''run the build_binaries.sh script'''
|
|
|
|
print("Running build_binaries.sh")
|
2013-03-23 00:54:53 -03:00
|
|
|
import shutil
|
|
|
|
# copy the script as it changes git branch, which can change the script while running
|
|
|
|
orig=util.reltopdir('Tools/scripts/build_binaries.sh')
|
|
|
|
copy=util.reltopdir('./build_binaries.sh')
|
|
|
|
shutil.copyfile(orig, copy)
|
|
|
|
shutil.copymode(orig, copy)
|
|
|
|
if util.run_cmd(copy, dir=util.reltopdir('.')) != 0:
|
2013-03-10 03:16:56 -03:00
|
|
|
print("Failed build_binaries.sh")
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2014-10-29 21:12:17 -03:00
|
|
|
def build_devrelease():
|
|
|
|
'''run the build_devrelease.sh script'''
|
|
|
|
print("Running build_devrelease.sh")
|
|
|
|
import shutil
|
|
|
|
# copy the script as it changes git branch, which can change the script while running
|
|
|
|
orig=util.reltopdir('Tools/scripts/build_devrelease.sh')
|
|
|
|
copy=util.reltopdir('./build_devrelease.sh')
|
|
|
|
shutil.copyfile(orig, copy)
|
|
|
|
shutil.copymode(orig, copy)
|
|
|
|
if util.run_cmd(copy, dir=util.reltopdir('.')) != 0:
|
|
|
|
print("Failed build_devrelease.sh")
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2012-11-24 06:12:05 -04:00
|
|
|
def build_examples():
|
2016-06-01 07:17:13 -03:00
|
|
|
'''build examples'''
|
|
|
|
for target in 'px4-v2', 'navio':
|
|
|
|
print("Running build.examples for %s" % target)
|
|
|
|
try:
|
|
|
|
util.build_examples(target)
|
|
|
|
except Exception as e:
|
|
|
|
print("Failed build_examples on board=%s" % target)
|
|
|
|
print(str(e))
|
|
|
|
return False
|
|
|
|
|
2012-11-24 06:12:05 -04:00
|
|
|
return True
|
|
|
|
|
2013-05-21 04:01:59 -03:00
|
|
|
def build_parameters():
|
|
|
|
'''run the param_parse.py script'''
|
|
|
|
print("Running param_parse.py")
|
|
|
|
if util.run_cmd(util.reltopdir('Tools/autotest/param_metadata/param_parse.py'), dir=util.reltopdir('.')) != 0:
|
|
|
|
print("Failed param_parse.py")
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
2012-02-19 02:05:21 -04:00
|
|
|
|
2011-11-09 05:27:00 -04:00
|
|
|
def convert_gpx():
|
2013-04-28 02:01:31 -03:00
|
|
|
'''convert any tlog files to GPX and KML'''
|
2011-11-09 05:27:00 -04:00
|
|
|
import glob
|
2015-05-10 19:37:49 -03:00
|
|
|
mavlog = glob.glob(util.reltopdir("../buildlogs/*.tlog"))
|
2011-11-09 05:27:00 -04:00
|
|
|
for m in mavlog:
|
2016-04-26 10:01:19 -03:00
|
|
|
util.run_cmd(util.reltopdir("modules/mavlink/pymavlink/tools/mavtogpx.py") + " --nofixcheck " + m)
|
2011-11-09 05:27:00 -04:00
|
|
|
gpx = m + '.gpx'
|
|
|
|
kml = m + '.kml'
|
2011-11-12 19:11:25 -04:00
|
|
|
util.run_cmd('gpsbabel -i gpx -f %s -o kml,units=m,floating=1,extrude=1 -F %s' % (gpx, kml), checkfail=False)
|
2011-11-13 15:37:58 -04:00
|
|
|
util.run_cmd('zip %s.kmz %s.kml' % (m, m), checkfail=False)
|
2013-11-22 06:03:31 -04:00
|
|
|
util.run_cmd("mavflightview.py --imagefile=%s.png %s" % (m,m))
|
2011-11-09 05:27:00 -04:00
|
|
|
return True
|
|
|
|
|
|
|
|
|
2014-08-04 17:28:59 -03:00
|
|
|
def test_prerequisites():
|
2011-11-07 05:12:51 -04:00
|
|
|
'''check we have the right directories and tools to run tests'''
|
2014-08-04 17:28:59 -03:00
|
|
|
print("Testing prerequisites")
|
2015-05-10 19:37:49 -03:00
|
|
|
util.mkdir_p(util.reltopdir('../buildlogs'))
|
2011-11-09 01:15:53 -04:00
|
|
|
return True
|
2011-11-12 19:11:25 -04:00
|
|
|
|
2012-06-15 03:52:55 -03:00
|
|
|
def alarm_handler(signum, frame):
|
|
|
|
'''handle test timeout'''
|
|
|
|
global results, opts
|
|
|
|
try:
|
|
|
|
results.add('TIMEOUT', '<span class="failed-text">FAILED</span>', opts.timeout)
|
2012-06-15 17:47:55 -03:00
|
|
|
util.pexpect_close_all()
|
2012-07-09 20:13:16 -03:00
|
|
|
convert_gpx()
|
2013-07-08 19:48:17 -03:00
|
|
|
write_fullresults()
|
2012-06-15 03:52:55 -03:00
|
|
|
os.killpg(0, signal.SIGKILL)
|
|
|
|
except Exception:
|
|
|
|
pass
|
|
|
|
sys.exit(1)
|
2011-10-30 23:50:34 -03:00
|
|
|
|
|
|
|
############## main program #############
|
|
|
|
parser = optparse.OptionParser("autotest")
|
|
|
|
parser.add_option("--skip", type='string', default='', help='list of steps to skip (comma separated)')
|
|
|
|
parser.add_option("--list", action='store_true', default=False, help='list the available steps')
|
2011-11-13 03:33:31 -04:00
|
|
|
parser.add_option("--viewerip", default=None, help='IP address to send MAVLink and fg packets to')
|
2013-05-02 07:03:36 -03:00
|
|
|
parser.add_option("--map", action='store_true', default=False, help='show map')
|
2011-11-13 06:20:29 -04:00
|
|
|
parser.add_option("--experimental", default=False, action='store_true', help='enable experimental tests')
|
2013-03-12 18:23:41 -03:00
|
|
|
parser.add_option("--timeout", default=3000, type='int', help='maximum runtime in seconds')
|
2016-04-11 05:05:39 -03:00
|
|
|
parser.add_option("--valgrind", default=False, action='store_true', help='run ArduPilot binaries under valgrind')
|
2016-06-26 23:05:16 -03:00
|
|
|
parser.add_option("--gdb", default=False, action='store_true', help='run ArduPilot binaries under gdb')
|
2016-05-21 12:19:50 -03:00
|
|
|
parser.add_option("--debug", default=False, action='store_true', help='make built binaries debug binaries')
|
|
|
|
parser.add_option("-j", default=None, type='int', help='build CPUs')
|
2011-10-30 23:50:34 -03:00
|
|
|
|
|
|
|
opts, args = parser.parse_args()
|
|
|
|
|
2016-01-09 01:27:03 -04:00
|
|
|
import arducopter, arduplane, apmrover2, quadplane
|
2012-04-27 00:32:22 -03:00
|
|
|
|
2011-10-30 23:50:34 -03:00
|
|
|
steps = [
|
2014-08-04 17:28:59 -03:00
|
|
|
'prerequisites',
|
2012-02-19 02:05:21 -04:00
|
|
|
'build.All',
|
2013-03-10 03:16:56 -03:00
|
|
|
'build.Binaries',
|
2015-04-30 01:09:59 -03:00
|
|
|
# 'build.DevRelease',
|
2012-11-24 06:12:05 -04:00
|
|
|
'build.Examples',
|
2013-05-21 04:01:59 -03:00
|
|
|
'build.Parameters',
|
2012-11-27 19:43:11 -04:00
|
|
|
|
2011-10-30 23:50:34 -03:00
|
|
|
'build.ArduPlane',
|
|
|
|
'defaults.ArduPlane',
|
2011-11-12 07:13:17 -04:00
|
|
|
'fly.ArduPlane',
|
2016-01-09 01:27:03 -04:00
|
|
|
'fly.QuadPlane',
|
2012-11-27 19:43:11 -04:00
|
|
|
|
|
|
|
'build.APMrover2',
|
|
|
|
'defaults.APMrover2',
|
|
|
|
'drive.APMrover2',
|
|
|
|
|
2011-11-07 07:55:21 -04:00
|
|
|
'build.ArduCopter',
|
2011-10-30 23:50:34 -03:00
|
|
|
'defaults.ArduCopter',
|
2011-11-07 07:55:21 -04:00
|
|
|
'fly.ArduCopter',
|
2015-05-27 05:13:55 -03:00
|
|
|
|
|
|
|
'build.Helicopter',
|
2013-05-29 02:33:32 -03:00
|
|
|
'fly.CopterAVC',
|
2012-11-27 19:43:11 -04:00
|
|
|
|
2015-09-15 19:02:51 -03:00
|
|
|
'build.AntennaTracker',
|
|
|
|
|
2011-11-09 05:27:00 -04:00
|
|
|
'convertgpx',
|
2011-10-30 23:50:34 -03:00
|
|
|
]
|
|
|
|
|
|
|
|
skipsteps = opts.skip.split(',')
|
|
|
|
|
2012-06-15 03:52:55 -03:00
|
|
|
# ensure we catch timeouts
|
|
|
|
signal.signal(signal.SIGALRM, alarm_handler)
|
|
|
|
signal.alarm(opts.timeout)
|
|
|
|
|
2012-12-21 23:50:32 -04:00
|
|
|
if opts.list:
|
|
|
|
for step in steps:
|
|
|
|
print(step)
|
|
|
|
sys.exit(0)
|
|
|
|
|
2011-10-30 23:50:34 -03:00
|
|
|
def skip_step(step):
|
|
|
|
'''see if a step should be skipped'''
|
|
|
|
for skip in skipsteps:
|
2012-11-29 03:09:44 -04:00
|
|
|
if fnmatch.fnmatch(step.lower(), skip.lower()):
|
2011-10-30 23:50:34 -03:00
|
|
|
return True
|
|
|
|
return False
|
|
|
|
|
2016-05-21 12:19:50 -03:00
|
|
|
def binary_path(step, debug=False):
|
|
|
|
if step.find("ArduCopter") != -1:
|
|
|
|
binary_name = "arducopter-quad"
|
|
|
|
elif step.find("ArduPlane") != -1:
|
|
|
|
binary_name = "arduplane"
|
|
|
|
elif step.find("APMrover2") != -1:
|
|
|
|
binary_name = "ardurover"
|
|
|
|
elif step.find("AntennaTracker") != -1:
|
|
|
|
binary_name = "antennatracker"
|
|
|
|
elif step.find("CopterAVC") != -1:
|
|
|
|
binary_name = "arducopter-heli"
|
|
|
|
elif step.find("QuadPlane") != -1:
|
|
|
|
binary_name = "arduplane"
|
|
|
|
else:
|
2016-05-27 18:29:23 -03:00
|
|
|
# cope with builds that don't have a specific binary
|
|
|
|
return None
|
2016-05-21 12:19:50 -03:00
|
|
|
|
|
|
|
if debug:
|
|
|
|
binary_basedir = "sitl-debug"
|
|
|
|
else:
|
|
|
|
binary_basedir = "sitl"
|
|
|
|
|
|
|
|
binary = util.reltopdir(os.path.join('build', binary_basedir, 'bin', binary_name))
|
|
|
|
if not os.path.exists(binary):
|
|
|
|
if os.path.exists(binary + ".exe"):
|
|
|
|
binary_path += ".exe"
|
|
|
|
else:
|
|
|
|
raise ValueError("Binary (%s) does not exist" % (binary,))
|
|
|
|
|
|
|
|
return binary
|
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
def run_step(step):
|
|
|
|
'''run one step'''
|
2014-11-13 01:31:26 -04:00
|
|
|
|
|
|
|
# remove old logs
|
2014-11-13 06:52:48 -04:00
|
|
|
util.run_cmd('/bin/rm -f logs/*.BIN logs/LASTLOG.TXT')
|
2014-11-13 01:31:26 -04:00
|
|
|
|
2014-08-04 17:28:59 -03:00
|
|
|
if step == "prerequisites":
|
|
|
|
return test_prerequisites()
|
2011-11-09 01:15:53 -04:00
|
|
|
|
|
|
|
if step == 'build.ArduPlane':
|
2016-05-21 12:19:50 -03:00
|
|
|
return util.build_SIL('bin/arduplane', j=opts.j, debug=opts.debug)
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2012-11-27 19:43:11 -04:00
|
|
|
if step == 'build.APMrover2':
|
2016-05-21 12:19:50 -03:00
|
|
|
return util.build_SIL('bin/ardurover', j=opts.j, debug=opts.debug)
|
2012-11-27 19:43:11 -04:00
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
if step == 'build.ArduCopter':
|
2016-05-21 12:19:50 -03:00
|
|
|
return util.build_SIL('bin/arducopter-quad', j=opts.j, debug=opts.debug)
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2015-09-15 19:02:51 -03:00
|
|
|
if step == 'build.AntennaTracker':
|
2016-05-21 12:19:50 -03:00
|
|
|
return util.build_SIL('bin/antennatracker', j=opts.j, debug=opts.debug)
|
2015-09-15 19:02:51 -03:00
|
|
|
|
2015-05-27 05:13:55 -03:00
|
|
|
if step == 'build.Helicopter':
|
2016-05-21 12:19:50 -03:00
|
|
|
return util.build_SIL('bin/arducopter-heli', j=opts.j, debug=opts.debug)
|
|
|
|
|
|
|
|
binary = binary_path(step, debug=opts.debug)
|
2015-05-27 05:13:55 -03:00
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
if step == 'defaults.ArduPlane':
|
2016-05-21 12:19:50 -03:00
|
|
|
return get_default_params('ArduPlane', binary)
|
2011-11-09 01:15:53 -04:00
|
|
|
|
|
|
|
if step == 'defaults.ArduCopter':
|
2016-05-21 12:19:50 -03:00
|
|
|
return get_default_params('ArduCopter', binary)
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2012-11-27 19:43:11 -04:00
|
|
|
if step == 'defaults.APMrover2':
|
2016-05-21 12:19:50 -03:00
|
|
|
return get_default_params('APMrover2', binary)
|
2012-11-27 19:43:11 -04:00
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
if step == 'fly.ArduCopter':
|
2016-06-26 23:05:16 -03:00
|
|
|
return arducopter.fly_ArduCopter(binary, viewerip=opts.viewerip, map=opts.map, valgrind=opts.valgrind, gdb=opts.gdb)
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2013-05-29 02:33:32 -03:00
|
|
|
if step == 'fly.CopterAVC':
|
2016-06-26 23:05:16 -03:00
|
|
|
return arducopter.fly_CopterAVC(binary, viewerip=opts.viewerip, map=opts.map, valgrind=opts.valgrind, gdb=opts.gdb)
|
2013-05-29 02:33:32 -03:00
|
|
|
|
2011-11-12 07:13:17 -04:00
|
|
|
if step == 'fly.ArduPlane':
|
2016-06-26 23:05:16 -03:00
|
|
|
return arduplane.fly_ArduPlane(binary, viewerip=opts.viewerip, map=opts.map, valgrind=opts.valgrind, gdb=opts.gdb)
|
2011-11-12 07:13:17 -04:00
|
|
|
|
2016-01-09 01:27:03 -04:00
|
|
|
if step == 'fly.QuadPlane':
|
2016-06-26 23:05:16 -03:00
|
|
|
return quadplane.fly_QuadPlane(binary, viewerip=opts.viewerip, map=opts.map, valgrind=opts.valgrind, gdb=opts.gdb)
|
2016-01-09 01:27:03 -04:00
|
|
|
|
2012-11-27 19:43:11 -04:00
|
|
|
if step == 'drive.APMrover2':
|
2016-06-26 23:05:16 -03:00
|
|
|
return apmrover2.drive_APMrover2(binary, viewerip=opts.viewerip, map=opts.map, valgrind=opts.valgrind, gdb=opts.gdb)
|
2012-11-27 19:43:11 -04:00
|
|
|
|
2012-02-19 02:05:21 -04:00
|
|
|
if step == 'build.All':
|
|
|
|
return build_all()
|
|
|
|
|
2013-03-10 03:16:56 -03:00
|
|
|
if step == 'build.Binaries':
|
|
|
|
return build_binaries()
|
|
|
|
|
2014-10-29 21:12:17 -03:00
|
|
|
if step == 'build.DevRelease':
|
|
|
|
return build_devrelease()
|
|
|
|
|
2012-11-24 06:12:05 -04:00
|
|
|
if step == 'build.Examples':
|
|
|
|
return build_examples()
|
|
|
|
|
2013-05-21 04:01:59 -03:00
|
|
|
if step == 'build.Parameters':
|
|
|
|
return build_parameters()
|
|
|
|
|
2011-11-09 05:27:00 -04:00
|
|
|
if step == 'convertgpx':
|
|
|
|
return convert_gpx()
|
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
raise RuntimeError("Unknown step %s" % step)
|
|
|
|
|
2011-11-09 08:25:08 -04:00
|
|
|
class TestResult(object):
|
|
|
|
'''test result class'''
|
|
|
|
def __init__(self, name, result, elapsed):
|
|
|
|
self.name = name
|
|
|
|
self.result = result
|
|
|
|
self.elapsed = "%.1f" % elapsed
|
|
|
|
|
|
|
|
class TestFile(object):
|
|
|
|
'''test result file'''
|
|
|
|
def __init__(self, name, fname):
|
|
|
|
self.name = name
|
|
|
|
self.fname = fname
|
|
|
|
|
|
|
|
class TestResults(object):
|
|
|
|
'''test results class'''
|
|
|
|
def __init__(self):
|
|
|
|
self.date = time.asctime()
|
2012-02-13 18:06:24 -04:00
|
|
|
self.githash = util.run_cmd('git rev-parse HEAD', output=True, dir=util.reltopdir('.')).strip()
|
2011-11-09 08:25:08 -04:00
|
|
|
self.tests = []
|
|
|
|
self.files = []
|
2013-05-05 23:32:42 -03:00
|
|
|
self.images = []
|
2011-11-09 08:25:08 -04:00
|
|
|
|
|
|
|
def add(self, name, result, elapsed):
|
|
|
|
'''add a result'''
|
|
|
|
self.tests.append(TestResult(name, result, elapsed))
|
|
|
|
|
|
|
|
def addfile(self, name, fname):
|
|
|
|
'''add a result file'''
|
|
|
|
self.files.append(TestFile(name, fname))
|
|
|
|
|
2013-05-05 23:32:42 -03:00
|
|
|
def addimage(self, name, fname):
|
|
|
|
'''add a result image'''
|
|
|
|
self.images.append(TestFile(name, fname))
|
|
|
|
|
2011-11-09 08:25:08 -04:00
|
|
|
def addglob(self, name, pattern):
|
|
|
|
'''add a set of files'''
|
|
|
|
import glob
|
2015-05-10 19:37:49 -03:00
|
|
|
for f in glob.glob(util.reltopdir('../buildlogs/%s' % pattern)):
|
2011-11-09 08:25:08 -04:00
|
|
|
self.addfile(name, os.path.basename(f))
|
|
|
|
|
2013-05-05 23:32:42 -03:00
|
|
|
def addglobimage(self, name, pattern):
|
|
|
|
'''add a set of images'''
|
|
|
|
import glob
|
2015-05-10 19:37:49 -03:00
|
|
|
for f in glob.glob(util.reltopdir('../buildlogs/%s' % pattern)):
|
2013-05-05 23:32:42 -03:00
|
|
|
self.addimage(name, os.path.basename(f))
|
|
|
|
|
2011-11-09 08:25:08 -04:00
|
|
|
|
|
|
|
|
|
|
|
def write_webresults(results):
|
|
|
|
'''write webpage results'''
|
2013-08-29 01:20:16 -03:00
|
|
|
from pymavlink.generator import mavtemplate
|
2011-11-09 08:25:08 -04:00
|
|
|
t = mavtemplate.MAVTemplate()
|
2011-11-09 09:23:46 -04:00
|
|
|
for h in glob.glob(util.reltopdir('Tools/autotest/web/*.html')):
|
|
|
|
html = util.loadfile(h)
|
2015-05-10 19:37:49 -03:00
|
|
|
f = open(util.reltopdir("../buildlogs/%s" % os.path.basename(h)), mode='w')
|
2011-11-09 09:23:46 -04:00
|
|
|
t.write(f, html, results)
|
|
|
|
f.close()
|
2011-11-09 09:31:50 -04:00
|
|
|
for f in glob.glob(util.reltopdir('Tools/autotest/web/*.png')):
|
2015-05-10 19:37:49 -03:00
|
|
|
shutil.copy(f, util.reltopdir('../buildlogs/%s' % os.path.basename(f)))
|
2011-11-09 08:25:08 -04:00
|
|
|
|
2013-07-08 19:48:17 -03:00
|
|
|
def write_fullresults():
|
|
|
|
'''write out full results set'''
|
|
|
|
global results
|
|
|
|
results.addglob("Google Earth track", '*.kmz')
|
|
|
|
results.addfile('Full Logs', 'autotest-output.txt')
|
2013-12-28 06:47:12 -04:00
|
|
|
results.addglob('DataFlash Log', '*-log.bin')
|
2013-07-08 19:48:17 -03:00
|
|
|
results.addglob("MAVLink log", '*.tlog')
|
|
|
|
results.addglob("GPX track", '*.gpx')
|
|
|
|
results.addfile('ArduPlane build log', 'ArduPlane.txt')
|
|
|
|
results.addfile('ArduPlane code size', 'ArduPlane.sizes.txt')
|
|
|
|
results.addfile('ArduPlane stack sizes', 'ArduPlane.framesizes.txt')
|
2013-09-22 19:48:01 -03:00
|
|
|
results.addfile('ArduPlane defaults', 'ArduPlane-defaults.parm')
|
2014-11-13 01:31:26 -04:00
|
|
|
results.addglob("ArduPlane log", 'ArduPlane-*.BIN')
|
2014-11-13 02:27:02 -04:00
|
|
|
results.addglob("ArduPlane core", 'ArduPlane.core')
|
|
|
|
results.addglob("ArduPlane ELF", 'ArduPlane.elf')
|
2013-07-08 19:48:17 -03:00
|
|
|
results.addfile('ArduCopter build log', 'ArduCopter.txt')
|
|
|
|
results.addfile('ArduCopter code size', 'ArduCopter.sizes.txt')
|
|
|
|
results.addfile('ArduCopter stack sizes', 'ArduCopter.framesizes.txt')
|
2013-09-22 19:48:01 -03:00
|
|
|
results.addfile('ArduCopter defaults', 'ArduCopter-defaults.parm')
|
2014-11-13 01:31:26 -04:00
|
|
|
results.addglob("ArduCopter log", 'ArduCopter-*.BIN')
|
2014-11-13 02:27:02 -04:00
|
|
|
results.addglob("ArduCopter core", 'ArduCopter.core')
|
|
|
|
results.addglob("ArduCopter elf", 'ArduCopter.elf')
|
2014-11-13 01:31:26 -04:00
|
|
|
results.addglob("CopterAVC log", 'CopterAVC-*.BIN')
|
2014-11-13 02:27:02 -04:00
|
|
|
results.addglob("CopterAVC core", 'CopterAVC.core')
|
2013-07-08 19:48:17 -03:00
|
|
|
results.addfile('APMrover2 build log', 'APMrover2.txt')
|
|
|
|
results.addfile('APMrover2 code size', 'APMrover2.sizes.txt')
|
|
|
|
results.addfile('APMrover2 stack sizes', 'APMrover2.framesizes.txt')
|
2013-09-22 19:48:01 -03:00
|
|
|
results.addfile('APMrover2 defaults', 'APMrover2-defaults.parm')
|
2014-11-13 01:31:26 -04:00
|
|
|
results.addglob("APMrover2 log", 'APMrover2-*.BIN')
|
2014-11-13 02:27:02 -04:00
|
|
|
results.addglob("APMrover2 core", 'APMrover2.core')
|
|
|
|
results.addglob("APMrover2 ELF", 'APMrover2.elf')
|
2015-09-15 19:02:51 -03:00
|
|
|
results.addfile('AntennaTracker build log', 'AntennaTracker.txt')
|
|
|
|
results.addfile('AntennaTracker code size', 'AntennaTracker.sizes.txt')
|
|
|
|
results.addfile('AntennaTracker stack sizes', 'AntennaTracker.framesizes.txt')
|
|
|
|
results.addglob("AntennaTracker ELF", 'AntennaTracker.elf')
|
2013-08-14 20:08:08 -03:00
|
|
|
results.addglob('APM:Libraries documentation', 'docs/libraries/index.html')
|
|
|
|
results.addglob('APM:Plane documentation', 'docs/ArduPlane/index.html')
|
|
|
|
results.addglob('APM:Copter documentation', 'docs/ArduCopter/index.html')
|
|
|
|
results.addglob('APM:Rover documentation', 'docs/APMrover2/index.html')
|
2013-07-08 19:48:17 -03:00
|
|
|
results.addglobimage("Flight Track", '*.png')
|
|
|
|
|
|
|
|
write_webresults(results)
|
|
|
|
|
2011-11-09 08:25:08 -04:00
|
|
|
|
2012-06-15 03:52:55 -03:00
|
|
|
results = TestResults()
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2014-11-13 01:31:26 -04:00
|
|
|
def check_logs(step):
|
|
|
|
'''check for log files from a step'''
|
|
|
|
print("check step: ", step)
|
|
|
|
if step.startswith('fly.'):
|
|
|
|
vehicle = step[4:]
|
|
|
|
elif step.startswith('drive.'):
|
|
|
|
vehicle = step[6:]
|
|
|
|
else:
|
|
|
|
return
|
2014-11-13 06:52:48 -04:00
|
|
|
logs = glob.glob("logs/*.BIN")
|
2014-11-13 01:31:26 -04:00
|
|
|
for log in logs:
|
|
|
|
bname = os.path.basename(log)
|
2015-05-10 19:37:49 -03:00
|
|
|
newname = util.reltopdir("../buildlogs/%s-%s" % (vehicle, bname))
|
2014-11-13 01:31:26 -04:00
|
|
|
print("Renaming %s to %s" % (log, newname))
|
|
|
|
os.rename(log, newname)
|
|
|
|
|
2014-11-13 06:52:48 -04:00
|
|
|
corefile = "core"
|
2014-11-13 02:27:02 -04:00
|
|
|
if os.path.exists(corefile):
|
2015-05-10 19:37:49 -03:00
|
|
|
newname = util.reltopdir("../buildlogs/%s.core" % vehicle)
|
2014-11-13 02:27:02 -04:00
|
|
|
print("Renaming %s to %s" % (corefile, newname))
|
|
|
|
os.rename(corefile, newname)
|
2014-11-13 06:52:48 -04:00
|
|
|
util.run_cmd('/bin/cp A*/A*.elf ../buildlogs', dir=util.reltopdir('.'))
|
2014-11-13 02:27:02 -04:00
|
|
|
|
2011-11-09 00:45:18 -04:00
|
|
|
def run_tests(steps):
|
|
|
|
'''run a list of steps'''
|
2012-06-15 03:52:55 -03:00
|
|
|
global results
|
2011-11-09 08:25:08 -04:00
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
passed = True
|
2011-11-09 02:16:20 -04:00
|
|
|
failed = []
|
2011-11-09 00:45:18 -04:00
|
|
|
for step in steps:
|
2011-12-02 00:21:15 -04:00
|
|
|
util.pexpect_close_all()
|
2011-11-09 00:45:18 -04:00
|
|
|
if skip_step(step):
|
|
|
|
continue
|
2011-11-09 01:15:53 -04:00
|
|
|
|
2011-11-09 08:25:08 -04:00
|
|
|
t1 = time.time()
|
2011-11-09 01:15:53 -04:00
|
|
|
print(">>>> RUNNING STEP: %s at %s" % (step, time.asctime()))
|
|
|
|
try:
|
|
|
|
if not run_step(step):
|
|
|
|
print(">>>> FAILED STEP: %s at %s" % (step, time.asctime()))
|
|
|
|
passed = False
|
2011-11-09 02:16:20 -04:00
|
|
|
failed.append(step)
|
2011-11-09 23:37:52 -04:00
|
|
|
results.add(step, '<span class="failed-text">FAILED</span>', time.time() - t1)
|
2011-11-09 01:15:53 -04:00
|
|
|
continue
|
|
|
|
except Exception, msg:
|
|
|
|
passed = False
|
2011-11-09 02:16:20 -04:00
|
|
|
failed.append(step)
|
2011-11-09 01:15:53 -04:00
|
|
|
print(">>>> FAILED STEP: %s at %s (%s)" % (step, time.asctime(), msg))
|
2011-11-09 08:43:25 -04:00
|
|
|
traceback.print_exc(file=sys.stdout)
|
2011-11-09 23:37:52 -04:00
|
|
|
results.add(step, '<span class="failed-text">FAILED</span>', time.time() - t1)
|
2014-11-13 01:31:26 -04:00
|
|
|
check_logs(step)
|
2011-11-25 23:44:07 -04:00
|
|
|
continue
|
2011-11-09 23:37:52 -04:00
|
|
|
results.add(step, '<span class="passed-text">PASSED</span>', time.time() - t1)
|
2011-11-09 01:15:53 -04:00
|
|
|
print(">>>> PASSED STEP: %s at %s" % (step, time.asctime()))
|
2014-11-13 01:31:26 -04:00
|
|
|
check_logs(step)
|
2011-11-09 02:16:20 -04:00
|
|
|
if not passed:
|
|
|
|
print("FAILED %u tests: %s" % (len(failed), failed))
|
2011-11-09 08:25:08 -04:00
|
|
|
|
2011-12-02 00:21:15 -04:00
|
|
|
util.pexpect_close_all()
|
|
|
|
|
2013-07-08 19:48:17 -03:00
|
|
|
write_fullresults()
|
2011-11-09 08:25:08 -04:00
|
|
|
|
2011-11-09 01:15:53 -04:00
|
|
|
return passed
|
2011-11-09 00:45:18 -04:00
|
|
|
|
2011-11-09 08:53:09 -04:00
|
|
|
|
2015-05-10 19:37:49 -03:00
|
|
|
util.mkdir_p(util.reltopdir('../buildlogs'))
|
2013-04-14 04:16:30 -03:00
|
|
|
|
2015-05-10 19:37:49 -03:00
|
|
|
lck = util.lock_file(util.reltopdir('../buildlogs/autotest.lck'))
|
2011-11-09 08:53:09 -04:00
|
|
|
if lck is None:
|
|
|
|
print("autotest is locked - exiting")
|
|
|
|
sys.exit(0)
|
|
|
|
|
2011-12-02 00:21:15 -04:00
|
|
|
atexit.register(util.pexpect_close_all)
|
|
|
|
|
2012-11-29 03:09:44 -04:00
|
|
|
if len(args) > 0:
|
|
|
|
# allow a wildcard list of steps
|
|
|
|
matched = []
|
|
|
|
for a in args:
|
2016-06-19 22:48:07 -03:00
|
|
|
arg_matched = False
|
2012-11-29 03:09:44 -04:00
|
|
|
for s in steps:
|
|
|
|
if fnmatch.fnmatch(s.lower(), a.lower()):
|
|
|
|
matched.append(s)
|
2016-06-19 22:48:07 -03:00
|
|
|
arg_matched = True
|
|
|
|
if not arg_matched:
|
|
|
|
print("No steps matched argument ({})".format(a))
|
|
|
|
sys.exit(1)
|
|
|
|
|
2012-11-29 03:09:44 -04:00
|
|
|
steps = matched
|
|
|
|
|
2011-11-09 00:45:18 -04:00
|
|
|
try:
|
2011-11-09 01:15:53 -04:00
|
|
|
if not run_tests(steps):
|
|
|
|
sys.exit(1)
|
2011-11-09 00:45:18 -04:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
util.pexpect_close_all()
|
2011-11-09 01:15:53 -04:00
|
|
|
sys.exit(1)
|
2011-11-09 00:45:18 -04:00
|
|
|
except Exception:
|
|
|
|
# make sure we kill off any children
|
|
|
|
util.pexpect_close_all()
|
|
|
|
raise
|