mirror of
https://github.com/ArduPilot/ardupilot
synced 2025-01-05 07:28:29 -04:00
autotest: comprehensive dataflash test
This commit is contained in:
parent
ccb583d092
commit
6ebc7622fe
@ -5476,6 +5476,14 @@ class AutoTestCopter(AutoTest):
|
|||||||
"Test that Alt Estimation is mandatory for ALT_HOLD",
|
"Test that Alt Estimation is mandatory for ALT_HOLD",
|
||||||
self.test_alt_estimate_prearm),
|
self.test_alt_estimate_prearm),
|
||||||
|
|
||||||
|
("DataFlash",
|
||||||
|
"Test DataFlash Block backend",
|
||||||
|
self.test_dataflash_sitl),
|
||||||
|
|
||||||
|
("DataFlashErase",
|
||||||
|
"Test DataFlash Block backend erase",
|
||||||
|
self.test_dataflash_erase),
|
||||||
|
|
||||||
("LogUpload",
|
("LogUpload",
|
||||||
"Log upload",
|
"Log upload",
|
||||||
self.log_upload),
|
self.log_upload),
|
||||||
|
@ -26,6 +26,7 @@ from pymavlink import mavextra
|
|||||||
from pymavlink import mavparm
|
from pymavlink import mavparm
|
||||||
|
|
||||||
from pysim import util, vehicleinfo
|
from pysim import util, vehicleinfo
|
||||||
|
from io import StringIO
|
||||||
|
|
||||||
# a list of pexpect objects to read while waiting for
|
# a list of pexpect objects to read while waiting for
|
||||||
# messages. This keeps the output to stdout flowing
|
# messages. This keeps the output to stdout flowing
|
||||||
@ -5319,20 +5320,57 @@ Also, ignores heartbeats not from our target system'''
|
|||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
def test_dataflash_sitl(self):
|
def test_dataflash_sitl(self):
|
||||||
|
"""Test the basic functionality of block logging"""
|
||||||
self.context_push()
|
self.context_push()
|
||||||
ex = None
|
ex = None
|
||||||
try:
|
try:
|
||||||
self.set_parameter("LOG_BACKEND_TYPE", 5)
|
self.set_parameter("LOG_BACKEND_TYPE", 4)
|
||||||
|
self.set_parameter("LOG_FILE_DSRMROT", 1)
|
||||||
self.reboot_sitl()
|
self.reboot_sitl()
|
||||||
self.drain_mav() # hopefully draining COMMAND_ACK from that failed arm
|
# First log created here, but we are in chip erase so ignored
|
||||||
self.mavproxy.send("module load log\n")
|
self.mavproxy.send("module load log\n")
|
||||||
# self.mavproxy.expect("Loaded module log\n")
|
|
||||||
self.mavproxy.send("log erase\n")
|
self.mavproxy.send("log erase\n")
|
||||||
|
self.mavproxy.expect("Chip erase complete")
|
||||||
|
|
||||||
|
self.wait_ready_to_arm()
|
||||||
|
if self.is_copter() or self.is_plane():
|
||||||
|
self.set_autodisarm_delay(0)
|
||||||
|
self.arm_vehicle()
|
||||||
|
self.delay_sim_time(5)
|
||||||
|
self.disarm_vehicle()
|
||||||
|
# First log created here
|
||||||
|
self.delay_sim_time(2)
|
||||||
|
self.arm_vehicle()
|
||||||
|
self.delay_sim_time(5)
|
||||||
|
self.disarm_vehicle()
|
||||||
|
# Second log created here
|
||||||
|
self.delay_sim_time(2)
|
||||||
self.mavproxy.send("log list\n")
|
self.mavproxy.send("log list\n")
|
||||||
self.mavproxy.expect("Log 1 numLogs 1 lastLog 1 size")
|
self.mavproxy.expect("Log ([0-9]+) numLogs ([0-9]+) lastLog ([0-9]+) size ([0-9]+)", timeout=120)
|
||||||
|
log_num = int(self.mavproxy.match.group(1))
|
||||||
|
numlogs = int(self.mavproxy.match.group(2))
|
||||||
|
lastlog = int(self.mavproxy.match.group(3))
|
||||||
|
size = int(self.mavproxy.match.group(4))
|
||||||
|
if numlogs != 2 or log_num != 1 or size <= 0:
|
||||||
|
raise NotAchievedException("Unexpected log information %d %d %d" % (log_num, numlogs, lastlog))
|
||||||
|
self.progress("Log size: %d" % size)
|
||||||
self.reboot_sitl()
|
self.reboot_sitl()
|
||||||
|
# This starts a new log with a time of 0, wait for arm so that we can insert the correct time
|
||||||
|
self.wait_ready_to_arm()
|
||||||
|
# Third log created here
|
||||||
self.mavproxy.send("log list\n")
|
self.mavproxy.send("log list\n")
|
||||||
self.mavproxy.expect("Log 1 numLogs 2 lastLog 2 size")
|
self.mavproxy.expect("Log 1 numLogs 3 lastLog 3 size")
|
||||||
|
|
||||||
|
# Download second and third logs
|
||||||
|
self.mavproxy.send("log download 2 logs/dataflash-log-002.BIN\n")
|
||||||
|
self.mavproxy.expect("Finished downloading", timeout=120)
|
||||||
|
self.mavproxy.send("log download 3 logs/dataflash-log-003.BIN\n")
|
||||||
|
self.mavproxy.expect("Finished downloading", timeout=120)
|
||||||
|
|
||||||
|
# Erase the logs
|
||||||
|
self.mavproxy.send("log erase\n")
|
||||||
|
self.mavproxy.expect("Chip erase complete")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.progress("Exception (%s) caught" % str(e))
|
self.progress("Exception (%s) caught" % str(e))
|
||||||
ex = e
|
ex = e
|
||||||
@ -5342,6 +5380,107 @@ Also, ignores heartbeats not from our target system'''
|
|||||||
if ex is not None:
|
if ex is not None:
|
||||||
raise ex
|
raise ex
|
||||||
|
|
||||||
|
def validate_log_file(self, logname, header_errors=0):
|
||||||
|
"""Validate the contents of a log file"""
|
||||||
|
# read the downloaded log - it must parse without error
|
||||||
|
class Capturing(list):
|
||||||
|
def __enter__(self):
|
||||||
|
self._stderr = sys.stderr
|
||||||
|
sys.stderr = self._stringio = StringIO()
|
||||||
|
return self
|
||||||
|
def __exit__(self, *args):
|
||||||
|
self.extend(self._stringio.getvalue().splitlines())
|
||||||
|
del self._stringio # free up some memory
|
||||||
|
sys.stderr = self._stderr
|
||||||
|
|
||||||
|
with Capturing() as df_output:
|
||||||
|
try:
|
||||||
|
mlog = mavutil.mavlink_connection(logname)
|
||||||
|
while True:
|
||||||
|
m = mlog.recv_match()
|
||||||
|
if m is None:
|
||||||
|
break
|
||||||
|
except Exception as e:
|
||||||
|
raise NotAchievedException("Error reading log file %s: %s" % (logname, str(e)))
|
||||||
|
|
||||||
|
herrors = 0
|
||||||
|
|
||||||
|
for msg in df_output:
|
||||||
|
if msg.startswith("bad header") or msg.startswith("unknown msg type"):
|
||||||
|
herrors = herrors + 1
|
||||||
|
|
||||||
|
if herrors > header_errors:
|
||||||
|
raise NotAchievedException("Error parsing log file %s, %d header errors" % (logname, herrors))
|
||||||
|
|
||||||
|
def test_dataflash_erase(self):
|
||||||
|
"""Test that erasing the dataflash chip and creating a new log is error free"""
|
||||||
|
ex = None
|
||||||
|
self.context_push()
|
||||||
|
try:
|
||||||
|
self.set_parameter("LOG_BACKEND_TYPE", 4)
|
||||||
|
self.reboot_sitl()
|
||||||
|
self.mavproxy.send("module load log\n")
|
||||||
|
self.mavproxy.send("log erase\n")
|
||||||
|
self.mavproxy.expect("Chip erase complete")
|
||||||
|
self.set_parameter("LOG_DISARMED", 1)
|
||||||
|
self.delay_sim_time(3)
|
||||||
|
self.set_parameter("LOG_DISARMED", 0)
|
||||||
|
self.mavproxy.send("log download 1 logs/dataflash-log-erase.BIN\n")
|
||||||
|
self.mavproxy.expect("Finished downloading", timeout=120)
|
||||||
|
# read the downloaded log - it must parse without error
|
||||||
|
self.validate_log_file("logs/dataflash-log-erase.BIN")
|
||||||
|
|
||||||
|
self.start_subtest("Test file wrapping results in a valid file")
|
||||||
|
# roughly 4mb
|
||||||
|
self.set_parameter("LOG_FILE_DSRMROT", 1)
|
||||||
|
self.set_parameter("LOG_BITMASK", 131071)
|
||||||
|
self.wait_ready_to_arm()
|
||||||
|
if self.is_copter() or self.is_plane():
|
||||||
|
self.set_autodisarm_delay(0)
|
||||||
|
self.arm_vehicle()
|
||||||
|
self.delay_sim_time(30)
|
||||||
|
self.disarm_vehicle()
|
||||||
|
# roughly 4mb
|
||||||
|
self.arm_vehicle()
|
||||||
|
self.delay_sim_time(30)
|
||||||
|
self.disarm_vehicle()
|
||||||
|
# roughly 9mb, should wrap around
|
||||||
|
self.arm_vehicle()
|
||||||
|
self.delay_sim_time(50)
|
||||||
|
self.disarm_vehicle()
|
||||||
|
# make sure we have finished logging
|
||||||
|
self.delay_sim_time(15)
|
||||||
|
self.mavproxy.send("log list\n")
|
||||||
|
self.mavproxy.expect("Log ([0-9]+) numLogs ([0-9]+) lastLog ([0-9]+) size ([0-9]+)", timeout=120)
|
||||||
|
if int(self.mavproxy.match.group(2)) != 2:
|
||||||
|
raise NotAchievedException("Expected 2 logs")
|
||||||
|
|
||||||
|
self.mavproxy.send("log download 1 logs/dataflash-log-erase2.BIN\n")
|
||||||
|
self.mavproxy.expect("Finished downloading", timeout=120)
|
||||||
|
self.validate_log_file("logs/dataflash-log-erase2.BIN", 1)
|
||||||
|
|
||||||
|
self.mavproxy.send("log download latest logs/dataflash-log-erase3.BIN\n")
|
||||||
|
self.mavproxy.expect("Finished downloading", timeout=120)
|
||||||
|
self.validate_log_file("logs/dataflash-log-erase3.BIN", 1)
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
self.mavproxy.send("log erase\n")
|
||||||
|
self.mavproxy.expect("Chip erase complete")
|
||||||
|
|
||||||
|
# clean up
|
||||||
|
self.mavproxy.send("log erase\n")
|
||||||
|
self.mavproxy.expect("Chip erase complete")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.progress("Exception (%s) caught" % str(e))
|
||||||
|
ex = e
|
||||||
|
|
||||||
|
self.mavproxy.send("module unload log\n")
|
||||||
|
self.context_pop()
|
||||||
|
self.reboot_sitl()
|
||||||
|
if ex is not None:
|
||||||
|
raise ex
|
||||||
|
|
||||||
def test_arm_feature(self):
|
def test_arm_feature(self):
|
||||||
"""Common feature to test."""
|
"""Common feature to test."""
|
||||||
# TEST ARMING/DISARM
|
# TEST ARMING/DISARM
|
||||||
|
Loading…
Reference in New Issue
Block a user