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

CI: param check for redefinition #231

Merged
Merged
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
44 changes: 38 additions & 6 deletions Tools/Carbonix_scripts/param_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import re
import glob
import subprocess
from fnmatch import fnmatch
from argparse import ArgumentParser


Expand All @@ -46,6 +47,7 @@ def parse_arguments():

# Add flags for enabling/disabling checks
parser.add_argument('--no-missing', action='store_true', help='Disable missing check')
parser.add_argument('--no-redefinition', action='store_true', help='Disable redefinition check')
parser.add_argument('--no-readonly', action='store_true', help='Disable read-only check')
parser.add_argument('--no-bitmask', action='store_true', help='Disable bitmask check')
parser.add_argument('--no-range', action='store_true', help='Disable range check')
Expand Down Expand Up @@ -115,7 +117,7 @@ def check_file(file, metadata, args=None):
Returns:
list: A list of error messages if any parameters are invalid.
"""
params, msgs = load_params(file)
params, msgs = load_params(file, args)

skip_missing = args.no_missing if args else False

Expand Down Expand Up @@ -279,16 +281,22 @@ def check_values(name, value, metadata):
return None


def load_params(file):
def load_params(file, args=None, depth=0):
"""Loads a parameter file and returns parameters and errors.

Reads the specified parameter file, stripping out comments and skipping
over directives like @include or @delete. It checks the comments for a
DISABLE_CHECKS flag. It builds a dictionary of parameters and their
values/disabled checks, and returns it along with any errors encountered.
Reads the specified parameter file, stripping out comments. It checks the
comments for a DISABLE_CHECKS flag. It builds a dictionary of parameters
and their values/disabled checks, and returns it along with any errors
encountered.

It will also check for redefinition of parameters within a file, including
handling @include and @delete directives, and log an error unless
args.no_redefinition is set.

Args:
file (str): The path to the parameter file to be loaded.
args (Namespace): An optional namespace containing flags to skip checks.
depth (int): The depth of the recursive call to prevent infinite loops.

Returns:
tuple: (params, errors)
Expand All @@ -298,12 +306,31 @@ def load_params(file):
- errors (list): A list of error messages encountered during
parsing.
"""
if depth > 10:
raise ValueError("Too many levels of @include")

params = {}
errors = []

skip_redefinition = args.no_redefinition if args else False

with open(file, 'r') as file_object:
lines = file_object.readlines()

# Build up seen parameters to check for redefinition
seen_params = set()
for line in lines:
if line.startswith('@include'):
rel_path = line.split(maxsplit=1)[1].strip()
path = os.path.join(os.path.dirname(file), rel_path)
params2, _ = load_params(path, args, depth + 1)
seen_params.update(params2.keys())
elif line.startswith('@delete'):
pattern = line.split(maxsplit=1)[1].strip()
seen_params = {
p for p in seen_params if not fnmatch(p, pattern)
}

for i, line in enumerate(lines):
# Strip whitespace
processed_line = line.strip()
Expand Down Expand Up @@ -343,6 +370,11 @@ def load_params(file):
# Split on , or any whitespace
parts = re.split(r'[,\s]+', processed_line, 1)

# Check for redefinition
if parts[0] in seen_params and not skip_redefinition:
errors.append(f'{parts[0]} redefined')
seen_params.add(parts[0])

# Try to convert the value string to a float
try:
value = parts[1]
Expand Down
23 changes: 19 additions & 4 deletions Tools/Carbonix_scripts/param_check_unittests.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ def test_load_params(self):

# Bad parameter lines that should fail to parse and exit the program
bad_lines = [
'PARAM4 1 2\n',
'PARAM4\n',
'P#ARAM4 1\n',
'PARAM4, 0x10.0\n',
'PARAM5 1 2\n',
'PARAM5\n',
'P#ARAM5 1\n',
'PARAM5, 0x10.0\n',
]
for line in bad_lines:
content = mock_file_content + line
Expand Down Expand Up @@ -168,6 +168,7 @@ def test_check_param(self):
def test_check_file(self, mock_check_param):
mock_args = type('', (), {})() # Creating a simple object to simulate args
mock_args.no_missing = False
mock_args.no_redefinition = False

# Case 1: All parameters pass their checks
mock_file_content = "PARAM1, 10\nPARAM2, 20\n"
Expand Down Expand Up @@ -219,6 +220,20 @@ def test_check_file(self, mock_check_param):
# Check that no error messages are returned because DISABLE_CHECKS is valid
self.assertEqual(msgs, [])

# Case 6: Redefined parameter
mock_file_content = "PARAM1, 10\nPARAM1, 20\n"
with patch('builtins.open', mock_open(read_data=mock_file_content)):
msgs = check_file('fake_file.parm', mock_metadata, mock_args)
# Check that a redefined parameter error is reported
self.assertEqual(msgs, ['PARAM1 redefined'])

# Case 7: Redefined parameter but with no-redefinition flag
mock_args.no_redefinition = True
with patch('builtins.open', mock_open(read_data=mock_file_content)):
msgs = check_file('fake_file.parm', mock_metadata, mock_args)
# Check that no error messages are returned when no-redefinition is enabled
self.assertEqual(msgs, [])

@patch('param_check.parse_arguments')
@patch('param_check.generate_metadata')
@patch('param_check.check_file')
Expand Down
32 changes: 0 additions & 32 deletions libraries/AP_HAL_ChibiOS/hwdef/CarbonixCommon/defaults.parm
Original file line number Diff line number Diff line change
Expand Up @@ -121,47 +121,15 @@ SCR_ENABLE,1
SCR_HEAP_SIZE,200000
SCR_VM_I_COUNT,100000
SERVO1_FUNCTION,33 # Motor 1
SERVO1_MAX,2000 # Setting all servos to 2000/1000, overriding in platforms if needed
SERVO1_MIN,1000
SERVO10_FUNCTION,4 # Aileron
SERVO10_MAX,2000
SERVO10_MIN,1000
SERVO11_FUNCTION,21 # Rudder
SERVO11_MAX,2000
SERVO11_MIN,1000
SERVO12_MAX,2000
SERVO12_MIN,1000
SERVO13_MAX,2000
SERVO13_MIN,1000
SERVO14_FUNCTION,0 # PLB Servo/GPIO
SERVO14_MAX,2000
SERVO14_MIN,1000
SERVO15_MAX,2000
SERVO15_MIN,1000
SERVO16_MAX,2000
SERVO16_MIN,1000
SERVO2_FUNCTION,34 # Motor 2
SERVO2_MAX,2000
SERVO2_MIN,1000
SERVO3_FUNCTION,35 # Motor 3
SERVO3_MAX,2000
SERVO3_MIN,1000
SERVO4_FUNCTION,36 # Motor 4
SERVO4_MAX,2000
SERVO4_MIN,1000
SERVO5_FUNCTION,70 # Pusher throttle
SERVO5_MAX,2000
SERVO5_MIN,1000
SERVO6_FUNCTION,19 # Elevator
SERVO6_MAX,2000
SERVO6_MIN,1000
SERVO7_FUNCTION,0 # PLB Servo/GPIO
SERVO7_MAX,2000
SERVO7_MIN,1000
SERVO8_FUNCTION,-1 # IGN relay GPIO
SERVO8_MAX,2000
SERVO8_MIN,1000
SERVO9_FUNCTION,94 # Scripting function for LEDs
SERVO9_MAX,2000
SERVO9_MIN,1000
TERRAIN_FOLLOW,72 # Enabled Auto and Guided (the command being executed must have the terrain frame though)
35 changes: 33 additions & 2 deletions libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Ottano/defaults.parm
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,39 @@ SERIAL4_PROTOCOL,2
SERIAL5_PROTOCOL,28
SERIAL6_BAUD,115
SERIAL6_PROTOCOL,2
SERVO5_MAX,1950
SERVO5_MIN,980
# Defaulting servos to 1000-2000us except throttle
SERVO1_MAX,2000
SERVO1_MIN,1000
SERVO10_MAX,2000
SERVO10_MIN,1000
SERVO11_MAX,2000
SERVO11_MIN,1000
SERVO12_MAX,2000
SERVO12_MIN,1000
SERVO13_MAX,2000
SERVO13_MIN,1000
SERVO14_MAX,2000
SERVO14_MIN,1000
SERVO15_MAX,2000
SERVO15_MIN,1000
SERVO16_MAX,2000
SERVO16_MIN,1000
SERVO2_MAX,2000
SERVO2_MIN,1000
SERVO3_MAX,2000
SERVO3_MIN,1000
SERVO4_MAX,2000
SERVO4_MIN,1000
SERVO5_MAX,1950 # Throttle servo endpoints
SERVO5_MIN,980 # Throttle servo endpoints
SERVO6_MAX,2000
SERVO6_MIN,1000
SERVO7_MAX,2000
SERVO7_MIN,1000
SERVO8_MAX,2000
SERVO8_MIN,1000
SERVO9_MAX,2000
SERVO9_MIN,1000
TECS_CLMB_MAX,4
TECS_INTEG_GAIN,0.15
TECS_LAND_ARSPD,24
Expand Down
33 changes: 33 additions & 0 deletions libraries/AP_HAL_ChibiOS/hwdef/CubeOrange-Volanti/defaults.parm
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,39 @@ SERIAL5_BAUD,115
SERIAL5_PROTOCOL,2
SERIAL6_BAUD,115
SERIAL6_PROTOCOL,2
# Defaulting servos to 1000-2000us
SERVO1_MAX,2000
SERVO1_MIN,1000
SERVO10_MAX,2000
SERVO10_MIN,1000
SERVO11_MAX,2000
SERVO11_MIN,1000
SERVO12_MAX,2000
SERVO12_MIN,1000
SERVO13_MAX,2000
SERVO13_MIN,1000
SERVO14_MAX,2000
SERVO14_MIN,1000
SERVO15_MAX,2000
SERVO15_MIN,1000
SERVO16_MAX,2000
SERVO16_MIN,1000
SERVO2_MAX,2000
SERVO2_MIN,1000
SERVO3_MAX,2000
SERVO3_MIN,1000
SERVO4_MAX,2000
SERVO4_MIN,1000
SERVO5_MAX,2000
SERVO5_MIN,1000
SERVO6_MAX,2000
SERVO6_MIN,1000
SERVO7_MAX,2000
SERVO7_MIN,1000
SERVO8_MAX,2000
SERVO8_MIN,1000
SERVO9_MAX,2000
SERVO9_MIN,1000
TECS_CLMB_MAX,3.1
TECS_PITCH_MAX,10
TECS_PITCH_MIN,-10
Expand Down
Loading