Esempio n. 1
0
def test_firmware_validation() -> None:
    downloader = FirmwareDownloader()
    installer = FirmwareInstaller()

    # Pixhawk1 and Pixhawk4 APJ firmwares should always work
    temporary_file = downloader.download(Vehicle.Sub, Platform.Pixhawk1)
    installer.validate_firmware(temporary_file, Platform.Pixhawk1)

    temporary_file = downloader.download(Vehicle.Sub, Platform.Pixhawk4)
    installer.validate_firmware(temporary_file, Platform.Pixhawk4)

    # New SITL firmwares should always work
    temporary_file = downloader.download(Vehicle.Sub,
                                         Platform.SITL,
                                         version="DEV")
    installer.validate_firmware(temporary_file, Platform.SITL)

    # Raise when validating Navigator firmwares (as test platform is x86)
    temporary_file = downloader.download(Vehicle.Sub, Platform.Navigator)
    with pytest.raises(InvalidFirmwareFile):
        installer.validate_firmware(temporary_file, Platform.Navigator)

    # Install SITL firmware
    temporary_file = downloader.download(Vehicle.Sub,
                                         Platform.SITL,
                                         version="DEV")
    board = FlightController(name="SITL",
                             manufacturer="ArduPilot Team",
                             platform=Platform.SITL)
    installer.install_firmware(temporary_file, board,
                               pathlib.Path(f"{temporary_file}_dest"))
 def __init__(self, firmware_folder: pathlib.Path,
              defaults_folder: pathlib.Path) -> None:
     self.firmware_folder = firmware_folder
     self.defaults_folder = defaults_folder
     self.firmware_download = FirmwareDownloader()
     self.firmware_installer = FirmwareInstaller()
 def validate_firmware(firmware_path: pathlib.Path,
                       platform: Platform) -> None:
     FirmwareInstaller.validate_firmware(firmware_path, platform)
class FirmwareManager:
    def __init__(self, firmware_folder: pathlib.Path,
                 defaults_folder: pathlib.Path) -> None:
        self.firmware_folder = firmware_folder
        self.defaults_folder = defaults_folder
        self.firmware_download = FirmwareDownloader()
        self.firmware_installer = FirmwareInstaller()

    @staticmethod
    def firmware_name(platform: Platform) -> str:
        """Get consistent firmware name for given platform."""
        return f"ardupilot_{platform.value.lower()}"

    def firmware_path(self, platform: Platform) -> pathlib.Path:
        """Get firmware's path for given platform. This is the path where we expect to find
        a valid Ardupilot binary for Linux boards."""
        return pathlib.Path.joinpath(self.firmware_folder,
                                     self.firmware_name(platform))

    def default_firmware_path(self, platform: Platform) -> pathlib.Path:
        """Get path of default firmware for given platform."""
        return pathlib.Path.joinpath(self.defaults_folder,
                                     self.firmware_name(platform))

    def is_default_firmware_available(self, platform: Platform) -> bool:
        return pathlib.Path.is_file(self.default_firmware_path(platform))

    def is_firmware_installed(self, board: FlightController) -> bool:
        """Check if firmware for given platform is installed."""
        if board.type == PlatformType.Serial:
            # Assumes for now that a serial board always has a firmware installed, which is true most of the time
            # TODO: Validate if properly. The uploader tool seems capable of doing this.
            return True

        firmware_format = FirmwareDownloader._supported_firmware_formats[
            board.platform.type]
        if firmware_format == FirmwareFormat.ELF:
            return pathlib.Path.is_file(self.firmware_path(board.platform))

        raise UnsupportedPlatform(
            "Install check is not implemented for this platform.")

    def get_available_firmwares(self, vehicle: Vehicle,
                                platform: Platform) -> List[Firmware]:
        firmwares = []
        versions = self.firmware_download.get_available_versions(
            vehicle, platform)
        if not versions:
            raise NoVersionAvailable(
                f"Failed to find any version for vehicle {vehicle}.")
        for version in versions:
            try:
                url = self.firmware_download.get_download_url(
                    vehicle, platform, version)
                firmware = Firmware(name=version, url=url)
                firmwares.append(firmware)
            except Exception as error:
                logger.debug(
                    f"Error fetching URL for version {version} on vehicle {vehicle}: {error}"
                )
        if not firmwares:
            raise NoVersionAvailable(
                f"Failed do get any valid URL for vehicle {vehicle}.")
        return firmwares

    def install_firmware_from_file(self, new_firmware_path: pathlib.Path,
                                   board: FlightController) -> None:
        try:
            if board.type == PlatformType.Serial:
                self.firmware_installer.install_firmware(
                    new_firmware_path, board)
            else:
                self.firmware_installer.install_firmware(
                    new_firmware_path, board,
                    self.firmware_path(board.platform))
            logger.info(f"Succefully installed firmware for {board.name}.")
        except Exception as error:
            raise FirmwareInstallFail("Could not install firmware.") from error

    def install_firmware_from_url(self, url: str,
                                  board: FlightController) -> None:
        temporary_file = self.firmware_download._download(url.strip())
        self.install_firmware_from_file(temporary_file, board)

    def install_firmware_from_params(self,
                                     vehicle: Vehicle,
                                     board: FlightController,
                                     version: str = "") -> None:
        url = self.firmware_download.get_download_url(vehicle, board.platform,
                                                      version)
        self.install_firmware_from_url(url, board)

    def restore_default_firmware(self, board: FlightController) -> None:
        if not self.is_default_firmware_available(board.platform):
            raise NoDefaultFirmwareAvailable(
                f"Default firmware not available for '{board.name}'.")

        self.install_firmware_from_file(
            self.default_firmware_path(board.platform), board)

    @staticmethod
    def validate_firmware(firmware_path: pathlib.Path,
                          platform: Platform) -> None:
        FirmwareInstaller.validate_firmware(firmware_path, platform)
def test_firmware_validation() -> None:
    downloader = FirmwareDownloader()
    installer = FirmwareInstaller()

    # Pixhawk1 APJ firmwares should always work
    temporary_file = downloader.download(Vehicle.Sub, Platform.Pixhawk1)
    installer.validate_firmware(temporary_file, Platform.Pixhawk1)

    # New SITL firmwares should always work
    temporary_file = downloader.download(Vehicle.Sub,
                                         Platform.SITL,
                                         version="DEV")
    installer.validate_firmware(temporary_file, Platform.SITL)

    # Raise when validating for Undefined platform
    with pytest.raises(UndefinedPlatform):
        installer.validate_firmware(pathlib.Path(""), Platform.Undefined)

    # Raise when validating Navigator firmwares (as test platform is x86)
    temporary_file = downloader.download(Vehicle.Sub, Platform.NavigatorR5)
    with pytest.raises(InvalidFirmwareFile):
        installer.validate_firmware(temporary_file, Platform.NavigatorR5)

    # Install SITL firmware
    temporary_file = downloader.download(Vehicle.Sub,
                                         Platform.SITL,
                                         version="DEV")
    installer.install_firmware(temporary_file, Platform.SITL,
                               pathlib.Path(f"{temporary_file}_dest"))