Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-enable examples in CI #29236

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test_unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ jobs:
]
config: [
unit-tests,
examples,
sitl
# examples,
]
steps:
# git checkout the PR
Expand Down
2 changes: 1 addition & 1 deletion Tools/autotest/autotest.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ def build_binaries():

def build_examples(**kwargs):
"""Build examples."""
for target in 'Pixhawk1', 'navio', 'linux':
for target in 'Pixhawk1', 'navio', 'linux', 'sitl':
print("Running build.examples for %s" % target)
try:
util.build_examples(target, **kwargs)
Expand Down
100 changes: 78 additions & 22 deletions Tools/autotest/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,36 +12,60 @@
import signal
import subprocess
import time
import traceback

from pysim import util


def run_example(filepath, valgrind=False, gdb=False):
def run_example(name, filepath, valgrind=False, gdb=False):
cmd = []
if valgrind:
cmd.append("valgrind")
if gdb:
cmd.append("gdb")
cmd.append(filepath)
print("Running: (%s)" % str(cmd))
bob = subprocess.Popen(cmd, stdin=None, close_fds=True)
retcode = bob.poll()
time.sleep(10)
print("pre-kill retcode: %s" % str(retcode))
if retcode is not None:
raise ValueError("Process exited before I could kill it (%s)" % str(retcode))
bob.send_signal(signal.SIGTERM)
time.sleep(1)
retcode = bob.poll()
print("retcode: %s" % str(retcode))
if retcode is None:
# if we get this far then we're not going to get a gcda file
# out of this process for coverage analysis; it has to exit
# normally, and it hasn't responded to a TERM.
bob.kill()
retcode2 = bob.wait()
print("retcode2: %s" % str(retcode2))
elif retcode == -15:
devnull = open("/dev/null", "w")
bob = subprocess.Popen(cmd, stdin=devnull, stdout=devnull, stderr=devnull, close_fds=True)

expect_exit = False
timeout = 10
if name in [
'RCProtocolTest',
'Scheduler_test',
'TransferFunctionCheck',
'XPlane',
]:
expect_exit = True

tstart = time.time()
while True:
if time.time() - tstart > timeout:
break
if not expect_exit:
retcode = bob.poll()
if retcode is not None:
raise ValueError("Process exited before I could kill it (%s)" % str(retcode))

if expect_exit:
retcode = bob.wait()
if retcode is None:
raise ValueError("Expected example to exit, it did not")
else:
bob.send_signal(signal.SIGTERM)
time.sleep(1)
retcode = bob.poll()
print("retcode: %s" % str(retcode))
if retcode is None:
# if we get this far then we're not going to get a gcda file
# out of this process for coverage analysis; it has to exit
# normally, and it hasn't responded to a TERM.
bob.kill()
retcode2 = bob.wait()
print("retcode2: %s" % str(retcode2))
return

if retcode == -15:
print("process exited with -15, indicating it didn't catch the TERM signal and exit properly")
elif retcode != 0:
# note that process could exit with code 0 and we couldn't tell...
Expand All @@ -50,6 +74,13 @@ def run_example(filepath, valgrind=False, gdb=False):
print("Ran: (%s)" % str(cmd))


def print_exception_stacktrace(e):
print(f"{e}\n")
print(''.join(traceback.format_exception(type(e),
e,
tb=e.__traceback__)))


def run_examples(debug=False, valgrind=False, gdb=False):
dirpath = util.reltopdir(os.path.join('build', 'sitl', 'examples'))

Expand All @@ -69,19 +100,44 @@ def run_examples(debug=False, valgrind=False, gdb=False):
if ex is not None:
raise ex

# note that some of the comments on examples here are incorrect -
# since we are running on SITL it's not a matter of not having the
# hardware, rather the simulation hasn't been set up
# appropriately. We run with a model of "NoVehicle", which
# doesn't update the Aircraft base class.
skip = {
"AHRS_Test": "segfault as AP_Logger not instantiated",
"AP_FW_Controller_test": "exits with a status code of 1 (failure) for some reason",
"BARO_generic": "Most linux computers don't have baros...",
"RCProtocolDecoder": "This assumes specific hardware is connected",
"DSP_test": "exits with an arithmetic exception",
"FlashTest": "https://github.com/ArduPilot/ardupilot/issues/14168",
"INS_generic": "SITL is not available, segfaults",
"ModuleTest": "test aborts",
"NMEA_Output": "segfault as AP_Logger not instantiated",
"RCProtocolDecoder": "This assumes specific hardware is connected",
"SlewLimiter": "exits with a status code of 1 (failure) for some reason",
"UART_chargen": "This nuke the term",
}
for afile in os.listdir(dirpath):

failures = []
for afile in sorted(os.listdir(dirpath)):
if afile in skip:
print("Skipping %s: %s" % (afile, skip[afile]))
continue
filepath = os.path.join(dirpath, afile)
if not os.path.isfile(filepath):
continue
run_example(filepath, valgrind=valgrind, gdb=gdb)
try:
run_example(afile, filepath, valgrind=valgrind, gdb=gdb)
except Exception as e:
print("Example failed with exception")
print_exception_stacktrace(e)
failures.append(afile)

if len(failures):
print("Failed examples:")
for failure in failures:
print(f" {failure}")
return False

return True
Loading