Skip to content

[REFACTOR] Reduce Complexity of Radio Schema Validation #284

@Mikefly123

Description

@Mikefly123

Story

  • As a developer
  • I want to be able to easily understand the radio schema validation
  • So that I can implement it without mistakes

Acceptance Criteria

  • Refactored Radio Config Validation passes SonarQube Complexity Check

Technical Details

We have a codebase issue identified by the SonarQube code quality checker. Specifically it relates to the overly complex radio config validation. This code is used to check and ensure that the radio config, defined in config.json is validated and will not throw any errors when used to initialize a radio manager.

Right now there are too many nested if statements, and figuring out a way to split a few out and simplify the logic would make things much more understandable!

Relevant Code

        self.RADIO_SCHEMA = {
            "license": {"type": str},
            "modulation": {"type": str, "allowed_values": ["LoRa", "FSK"]},
            "start_time": {"type": int, "min": 0, "max": 80000},
            "transmit_frequency": {
                "type": (int, float),
                "min0": 435,
                "max0": 438.0,
                "min1": 915.0,
                "max1": 915.0,
            },
        }

    def validate(self, key: str, value) -> None:
        """
        Validates a radio configuration value against its schema.

        Args:
            key (str): The configuration key to validate.
            value: The value to validate.

        Raises:
            KeyError: If the key is not found in any schema.
            TypeError: If the value is not of the expected type or not allowed.
            ValueError: If the value is out of the allowed range.
        """

        if key in self.RADIO_SCHEMA:
            schema = self.RADIO_SCHEMA[key]
        elif key in self.fsk.FSK_SCHEMA:
            schema = self.fsk.FSK_SCHEMA[key]
        elif key in self.lora.LORA_SCHEMA:
            schema = self.lora.LORA_SCHEMA[key]
        else:
            raise KeyError

        if "allowed_values" in schema:
            if value not in schema["allowed_values"]:
                raise TypeError

        expected_type = schema["type"]

        # checks value is of same type; also covers bools
        if not isinstance(value, expected_type):
            raise TypeError

        # checks int, float, and bytes range
        if isinstance(value, (int, float, bytes)):
            if "min" in schema and value < schema["min"]:
                raise ValueError
            if "max" in schema and value > schema["max"]:
                raise ValueError

            # specific to transmit_frequency
            if key == "transmit_frequency":
                if "min0" in schema and value < schema["min0"]:
                    raise ValueError
                if "max1" in schema and value > schema["max1"]:
                    raise ValueError
                if (
                    "max0" in schema
                    and value > schema["max0"]
                    and "min1" in schema
                    and value < schema["min1"]
                ):
                    raise ValueError

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions