示例#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 test_static() -> None:
    downloaded_file = FirmwareDownloader._download(
        FirmwareDownloader._manifest_remote)
    assert downloaded_file, "Failed to download file."
    assert downloaded_file.exists(), "Download file does not exist."

    smaller_valid_size_bytes = 180 * 1024
    assert downloaded_file.stat(
    ).st_size > smaller_valid_size_bytes, "Download file size is not big enough."
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"))
def test_firmware_download() -> None:
    firmware_download = FirmwareDownloader()
    assert firmware_download.download_manifest(
    ), "Failed to download/validate manifest file."

    versions = firmware_download._find_version_item(
        vehicletype="Sub",
        format="apj",
        mav_firmware_version_type="STABLE-4.0.1",
        platform=Platform.Pixhawk1)
    assert len(versions) == 1, "Failed to find a single firmware."

    versions = firmware_download._find_version_item(
        vehicletype="Sub",
        mav_firmware_version_type="STABLE-4.0.1",
        platform=Platform.Pixhawk1)
    assert len(versions) == 3, "Failed to find multiple versions."

    available_versions = firmware_download.get_available_versions(
        Vehicle.Sub, Platform.Pixhawk1)
    assert len(available_versions) == len(
        set(available_versions)), "Available versions are not unique."

    test_available_versions = [
        "STABLE-4.0.1", "STABLE-4.0.0", "OFFICIAL", "DEV", "BETA"
    ]
    assert len(set(available_versions)) >= len(
        set(test_available_versions
            )), "Available versions are missing know versions."

    assert firmware_download.download(
        Vehicle.Sub, Platform.Pixhawk1,
        "STABLE-4.0.1"), "Failed to download a valid firmware file."

    assert firmware_download.download(
        Vehicle.Sub,
        Platform.Pixhawk1), "Failed to download latest valid firmware file."

    assert firmware_download.download(
        Vehicle.Sub,
        Platform.Pixhawk4), "Failed to download latest valid firmware file."

    assert firmware_download.download(
        Vehicle.Sub, Platform.SITL), "Failed to download SITL."

    # It'll fail if running in an arch different of ARM
    if "x86" in os.uname().machine:
        assert firmware_download.download(
            Vehicle.Sub,
            Platform.Navigator), "Failed to download navigator binary."
    else:
        with pytest.raises(Exception):
            firmware_download.download(Vehicle.Sub, Platform.Navigator)
 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()
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)