mirror of
https://github.com/ArduPilot/ardupilot.git
synced 2026-10-02 10:23:25 +08:00
autotest: skip MAVFTPCrcCompareMAVProxy only where crccmp is missing
The test drives "ftp crclocal" and "ftp crccmp". MAVProxy grew those in 328d7de20 (2026-07-27) and has not cut a release since - the newest tag, v1.8.74, is from 2025-08-02 and contains neither - so on a released MAVProxy "ftp crclocal" falls through to the usage print and the test waits out its 60s pexpect timeout. Skipping it unconditionally would cost real coverage: build_ci.sh installs MAVProxy by cloning master, which does have both commands, so the test runs and passes in CI today. A version gate would not work either, because MAVProxy master still calls itself 1.8.74 - the same version the release reports - so any mavproxy_version_gt() test would disable the test in CI as well. Ask the ftp module whether it implements the command instead, and skip only where it does not. Nothing has to be un-done later: the skip stops applying by itself once the local MAVProxy has crccmp. Keeping this in disabled_tests() rather than returning early inside the test means the skip is still reported in the run summary and the JUnit report. Ask the MAVProxy we are actually going to run, not the one this process could import. MAVPROXY_CMD can name a MAVProxy in another virtualenv, which is the whole point of the variable, and an in-process "import MAVProxy" would then answer for the wrong install - saying the command is present when the MAVProxy under test lacks it, which is exactly the 60s timeout this is meant to avoid. Take the interpreter out of the mavproxy script's shebang and put the question to that, keeping the lookup next to mavproxy_cmd() in util.py where MAVPROXY_CMD is read. Verified four ways: with crccmp present the entry is absent and test.Plane.MAVFTPCrcCompareMAVProxy passes; with MAVPROXY_CMD pointing at a stub install whose ftp module has no crccmp the probe reports False and the entry appears, while an in-process import in that same run still says True; and with MAVPROXY_CMD naming a path that does not exist the probe returns "don't know" and the test is left enabled. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
Andrew Tridgell
co-authored by
Claude Opus 5
parent
9189701872
commit
cd8a2df5fa
@@ -9790,7 +9790,7 @@ class AutoTestPlane(vehicle_test_suite.TestSuite):
|
||||
]
|
||||
|
||||
def disabled_tests(self):
|
||||
return {
|
||||
ret = {
|
||||
"LandingDrift": "Flapping test. See https://github.com/ArduPilot/ardupilot/issues/20054",
|
||||
"TerrainRally": "Passes vacuously due to helper alt-frame bugs. See https://github.com/ArduPilot/ardupilot/issues/33740", # noqa
|
||||
"InteractTest": "requires user interaction",
|
||||
@@ -9800,6 +9800,12 @@ class AutoTestPlane(vehicle_test_suite.TestSuite):
|
||||
"MAVFTPListDirectoryInterleavedGet": "needs a MAVProxy which does not continue a listing by mutating the last op sent; see https://github.com/ArduPilot/MAVProxy", # noqa:E501
|
||||
"MAVFTPListDirectoryTabInNameMAVProxy": "needs a MAVProxy which takes the size from the end of a listing entry; see https://github.com/ArduPilot/MAVProxy", # noqa:E501
|
||||
}
|
||||
if not self.mavproxy_ftp_module_has_command("crccmp"):
|
||||
# added to MAVProxy in 328d7de20 (2026-07-27) and not in any
|
||||
# release up to v1.8.74; skipped only where it is missing, so
|
||||
# CI - which installs MAVProxy from git master - still runs it
|
||||
ret["MAVFTPCrcCompareMAVProxy"] = "needs a MAVProxy which has the ftp crclocal and crccmp commands; see https://github.com/ArduPilot/MAVProxy" # noqa:E501
|
||||
return ret
|
||||
|
||||
|
||||
class AutoTestPlaneTests1a(AutoTestPlane):
|
||||
|
||||
@@ -9,6 +9,7 @@ import math
|
||||
import os
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import signal
|
||||
import socket
|
||||
import subprocess
|
||||
@@ -835,6 +836,57 @@ def MAVProxy_version():
|
||||
return int(match.group(1)), int(match.group(2)), int(match.group(3))
|
||||
|
||||
|
||||
def mavproxy_python():
|
||||
"""return the interpreter which runs mavproxy_cmd(), as an argv list.
|
||||
|
||||
MAVPROXY_CMD can name a MAVProxy installed somewhere other than the
|
||||
interpreter running the test suite - a virtualenv, say - so
|
||||
importing MAVProxy here would answer questions about the wrong
|
||||
MAVProxy. Take the interpreter out of the script's shebang line
|
||||
instead. Returns None if it can't be worked out.
|
||||
"""
|
||||
path = shutil.which(mavproxy_cmd())
|
||||
if path is None:
|
||||
return None
|
||||
try:
|
||||
with open(path, "rb") as f:
|
||||
first_line = f.readline()
|
||||
except OSError:
|
||||
return None
|
||||
if not first_line.startswith(b"#!"):
|
||||
# not a script at all; a compiled wrapper, perhaps
|
||||
return None
|
||||
return shlex.split(first_line[2:].strip().decode("utf-8"))
|
||||
|
||||
|
||||
def MAVProxy_ftp_module_has_command(command):
|
||||
"""return True if MAVProxy's ftp module implements "ftp <command>".
|
||||
|
||||
Asks the MAVProxy which mavproxy_cmd() will run, not the one this
|
||||
process happens to be able to import. Returns None if that can't be
|
||||
asked.
|
||||
"""
|
||||
python = mavproxy_python()
|
||||
if python is None:
|
||||
return None
|
||||
program = (
|
||||
"from MAVProxy.modules import mavproxy_ftp;"
|
||||
"print(hasattr(mavproxy_ftp.FTPModule, %s))" % repr("cmd_%s" % command)
|
||||
)
|
||||
try:
|
||||
completed = subprocess.run(
|
||||
python + ["-c", program],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
timeout=60,
|
||||
)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return None
|
||||
if completed.returncode != 0:
|
||||
return None
|
||||
return completed.stdout.decode("ascii").strip() == "True"
|
||||
|
||||
|
||||
def start_MAVProxy_SITL(atype,
|
||||
aircraft=None,
|
||||
setup=False,
|
||||
|
||||
@@ -2289,6 +2289,24 @@ class TestSuite(abc.ABC):
|
||||
'''return the current version of mavproxy as a tuple e.g. (1,8,8)'''
|
||||
return util.MAVProxy_version()
|
||||
|
||||
def mavproxy_ftp_module_has_command(self, command):
|
||||
'''return True if MAVProxy's ftp module implements "ftp <command>".
|
||||
|
||||
MAVProxy's version is no use for this: master and the newest
|
||||
release both call themselves 1.8.74, so a version gate would
|
||||
disable the test everywhere, including CI - which installs
|
||||
MAVProxy from git master and so does have these commands. Ask
|
||||
the module what it can do instead; the answer changes by itself
|
||||
when the local MAVProxy is updated.
|
||||
'''
|
||||
ret = util.MAVProxy_ftp_module_has_command(command)
|
||||
if ret is None:
|
||||
# couldn't ask the MAVProxy we will be running. Assume the
|
||||
# command is there and let the test run rather than silently
|
||||
# dropping coverage:
|
||||
return True
|
||||
return ret
|
||||
|
||||
def mavproxy_version_gt(self, major, minor, point):
|
||||
if os.getenv("AUTOTEST_FORCE_MAVPROXY_VERSION", None) is not None:
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user