There are many types of archives that the tests deal with. Provide a generalized 'archive_extract' that can detect the format and delegate to the appropriate helper for extraction. This ensures that all archive extraction code follows the same design pattern.
Signed-off-by: Daniel P. Berrangé <berra...@redhat.com> --- tests/functional/qemu_test/__init__.py | 1 + tests/functional/qemu_test/archive.py | 58 ++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py index fe6cbe3a8a..665c482d13 100644 --- a/tests/functional/qemu_test/__init__.py +++ b/tests/functional/qemu_test/__init__.py @@ -16,3 +16,4 @@ from .decorators import skipIfMissingCommands, skipIfNotMachine, \ skipFlakyTest, skipUntrustedTest, skipBigDataTest, \ skipIfMissingImports +from .archive import archive_extract diff --git a/tests/functional/qemu_test/archive.py b/tests/functional/qemu_test/archive.py index bc448dee4a..c439d9413a 100644 --- a/tests/functional/qemu_test/archive.py +++ b/tests/functional/qemu_test/archive.py @@ -10,8 +10,10 @@ import os from subprocess import check_call, run, DEVNULL import tarfile +from urllib.parse import urlparse import zipfile +from .asset import Asset from .cmd import run_cmd @@ -56,3 +58,59 @@ def deb_extract(archive, dest_dir, member=None): tar_extract(file_path, dest_dir, member) finally: os.chdir(cwd) + +''' +@params archive: filename, Asset, or file-like object to extract +@params dest_dir: target directory to extract into +@params member: optional member file to limit extraction to + +Extracts @archive into @dest_dir. All files are extracted +unless @member specifies a limit. + +If @format is None, heuristics will be applied to guess the format +from the filename or Asset URL. @format must be non-None if @archive +is a file-like object. +''' +def archive_extract(archive, dest_dir, format=None, member=None): + if format is None: + format = guess_archive_format(archive) + if type(archive) == Asset: + archive = str(archive) + + if format == "tar": + tar_extract(archive, dest_dir, member) + elif format == "zip": + zip_extract(archive, dest_dir, member) + elif format == "cpio": + if member is not None: + raise Exception("Unable to filter cpio extraction") + cpio_extract(archive, dest_dir) + elif format == "deb": + if type(archive) != str: + raise Exception("Unable to use file-like object with deb archives") + deb_extract(archive, dest_dir, "./" + member) + else: + raise Exception(f"Unknown archive format {format}") + +''' +@params archive: filename, or Asset to guess + +Guess the format of @compressed, raising an exception if +no format can be determined +''' +def guess_archive_format(archive): + if type(archive) == Asset: + archive = urlparse(archive.url).path + elif type(archive) != str: + raise Exception(f"Unable to guess archive format for {archive}") + + if ".tar." in archive or archive.endswith("tgz"): + return "tar" + elif archive.endswith(".zip"): + return "zip" + elif archive.endswith(".cpio"): + return "cpio" + elif archive.endswith(".deb") or archive.endswith(".udeb"): + return "deb" + else: + raise Exception(f"Unknown archive format for {archive}") -- 2.46.0