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

enhance test_install to exercise extensions #871

Merged
merged 1 commit into from
Jan 4, 2025
Merged
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
178 changes: 164 additions & 14 deletions tests/test_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,36 @@ class MockArchive:
version: str = ""
arch_dir: str = ""
should_install: bool = True
extract_target: Optional[str] = None
date: datetime = datetime.now()

def xml_package_update(self) -> str:
return textwrap.dedent(
f"""\
<PackageUpdate>
<Name>{self.update_xml_name}</Name>
<Version>{self.version}-0-{self.date.strftime("%Y%m%d%H%M")}</Version>
<Description>none</Description>
<DownloadableArchives>{self.filename_7z}</DownloadableArchives>
</PackageUpdate>"""
)
if self.extract_target:
return textwrap.dedent(
f"""\
<PackageUpdate>
<Name>{self.update_xml_name}</Name>
<Version>{self.version}-0-{self.date.strftime("%Y%m%d%H%M")}</Version>
<Description>none</Description>
<DownloadableArchives>{self.filename_7z}</DownloadableArchives>
<Operations>
<Operation name="Extract">
<Argument>{self.extract_target}</Argument>
<Argument>{self.filename_7z}</Argument>
</Operation>
</Operations>
</PackageUpdate>"""
)
else:
return textwrap.dedent(
f"""\
<PackageUpdate>
<Name>{self.update_xml_name}</Name>
<Version>{self.version}-0-{self.date.strftime("%Y%m%d%H%M")}</Version>
<Description>none</Description>
<DownloadableArchives>{self.filename_7z}</DownloadableArchives>
</PackageUpdate>"""
)

def write_compressed_archive(self, dest: Path) -> None:
def open_writable_archive():
Expand All @@ -128,35 +146,50 @@ def write_to_archive(arc, src, arcname):
# shutil.make_archive(str(dest / self.filename_7z), "zip", src)

with TemporaryDirectory() as temp_dir, open_writable_archive() as archive:
# if the Updates.xml file uses Operations/Operation[@name='Extract'] elements then the names
# of archive members do not include the version and arch_dir path segments, instead they are
# supplied by an Argument element which is used when the archive is extracted.
temp_path = Path(temp_dir)
arch_dir = self.arch_dir if not self.extract_target else ""

for folder in ("bin", "lib", "mkspecs"):
(temp_path / self.arch_dir / folder).mkdir(parents=True, exist_ok=True)
(temp_path / arch_dir / folder).mkdir(parents=True, exist_ok=True)

# Use `self.contents` to write qmake binary, qmake script, QtCore binaries, etc
for patched_file in self.contents:
full_path = temp_path / self.arch_dir / patched_file.filename
full_path = temp_path / arch_dir / patched_file.filename
if not full_path.parent.exists():
full_path.parent.mkdir(parents=True)
full_path.write_text(patched_file.unpatched_content, "utf_8")

archive_name = "5.9" if self.version == "5.9.0" else self.version
if self.extract_target:
archive_name = "."
else:
archive_name = "5.9" if self.version == "5.9.0" else self.version
write_to_archive(archive, temp_path, arcname=archive_name)


def make_mock_geturl_download_archive(
*,
standard_archives: List[MockArchive],
desktop_archives: Optional[List[MockArchive]] = None,
extpdf_archives: Optional[List[MockArchive]] = None,
extweb_archives: Optional[List[MockArchive]] = None,
standard_updates_url: str,
desktop_updates_url: str = "",
extpdf_updates_url: str = "",
extweb_updates_url: str = "",
) -> Tuple[GET_URL_TYPE, DOWNLOAD_ARCHIVE_TYPE]:
"""
Returns a mock 'getUrl' and a mock 'downloadArchive' function.
"""
if desktop_archives is None:
desktop_archives = []
for _archive in [*standard_archives, *desktop_archives]:
if extpdf_archives is None:
extpdf_archives = []
if extweb_archives is None:
extweb_archives = []
for _archive in [*standard_archives, *desktop_archives, *extpdf_archives, *extweb_archives]:
assert re.match(r".*\.(7z|tar\.xz)$", _archive.filename_7z), "Unsupported file type"

standard_xml = "<Updates>\n{}\n</Updates>".format(
Expand All @@ -165,6 +198,8 @@ def make_mock_geturl_download_archive(
desktop_xml = "<Updates>\n{}\n</Updates>".format(
"\n".join([archive.xml_package_update() for archive in desktop_archives])
)
extpdf_xml = "<Updates>\n{}\n</Updates>".format("\n".join([archive.xml_package_update() for archive in extpdf_archives]))
extweb_xml = "<Updates>\n{}\n</Updates>".format("\n".join([archive.xml_package_update() for archive in extweb_archives]))
merged_xml = "<Updates>\n{}{}\n</Updates>".format(
"\n".join([archive.xml_package_update() for archive in standard_archives]),
"\n".join([archive.xml_package_update() for archive in desktop_archives]),
Expand All @@ -177,6 +212,8 @@ def mock_getUrl(url: str, *args, **kwargs) -> str:
for xml, updates_url in (
(standard_xml, standard_updates_url),
(desktop_xml, desktop_updates_url),
(extpdf_xml, extpdf_updates_url),
(extweb_xml, extweb_updates_url),
):
basename = posixpath.dirname(updates_url)
if not updates_url:
Expand All @@ -186,13 +223,18 @@ def mock_getUrl(url: str, *args, **kwargs) -> str:
elif basename in url and url.endswith(".sha256"):
filename = url.split("/")[-1][: -len(".sha256")]
return f"{hashlib.sha256(bytes(xml, 'utf-8')).hexdigest()} {filename}"
"""
extensions urls may or may not exist.
"""
if "/extensions/" in url:
raise ArchiveDownloadError(f"Failed to retrieve file at {url}\nServer response code: 404, reason: Not Found")
assert False, f"No mocked url available for '{url}'"

def mock_download_archive(url: str, out: str, *args):
"""Make a mocked 7z archive at out_filename"""

def locate_archive() -> MockArchive:
for archive in [*standard_archives, *desktop_archives]:
for archive in [*standard_archives, *desktop_archives, *extpdf_archives, *extweb_archives]:
if Path(out).name == archive.filename_7z:
return archive
assert False, "Requested an archive that was not mocked"
Expand Down Expand Up @@ -1121,6 +1163,102 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
r"INFO : Time elapsed: .* second"
),
),
( # extensions availability: qtpdf and qtwebengine
"install-qt windows desktop 6.8.1 win64_msvc2022_64 -m qtwebengine".split(),
"windows",
"desktop",
"6.8.1",
{"std": "win64_msvc2022_64", "extpdf": "win64_msvc2022_64", "extweb": "win64_msvc2022_64"},
{"std": "msvc2022_64", "extpdf": "msvc2022_64", "extweb": "msvc2022_64"},
{
"std": "windows_x86/desktop/qt6_681/qt6_681/Updates.xml",
"extpdf": "windows_x86/extensions/qtpdf/681/msvc2022_64/Updates.xml",
"extweb": "windows_x86/extensions/qtwebengine/681/msvc2022_64/Updates.xml",
},
{
"std": [
plain_qtbase_archive(
"qt.qt6.681.win64_msvc2022_64",
"Windows-Windows_11_23H2-X86_64",
host="Windows-Windows_11_23H2-MSVC2022",
)
],
"extpdf": [
MockArchive(
filename_7z="qtpdf-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z",
update_xml_name="extensions.qtpdf.681.win64_msvc2022_64",
contents=(),
should_install=False,
extract_target="@TargetDir@/6.8.1/msvc2022_64",
),
],
"extweb": [
MockArchive(
filename_7z="qtwebengine-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z",
update_xml_name="extensions.qtwebengine.681.win64_msvc2022_64",
contents=(
PatchedFile(filename="lib/Qt6WebEngineCore.prl", unpatched_content="... qtwebengine ...\n"),
),
should_install=False,
extract_target="@TargetDir@/6.8.1/msvc2022_64",
),
],
},
re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Found extension qtwebengine\n"
r"INFO : Found extension qtpdf\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of "
r"qtbase-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z in .*\n"
r"INFO : Downloading qtwebengine...\n"
r"Finished installation of "
r"qtwebengine-Windows-Windows_11_23H2-MSVC2022-Windows-Windows_11_23H2-X86_64.7z in .*\n"
r"INFO : Patching .*/6.8.1/msvc2022_64/lib/Qt6WebEngineCore.prl\n"
r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second"
),
),
( # extension availability: qtpdf only
"install-qt windows desktop 6.8.1 win64_mingw -m qtpdf".split(),
"windows",
"desktop",
"6.8.1",
{"std": "win64_mingw", "extpdf": "win64_mingw"},
{"std": "mingw_64", "extpdf": "mingw_64"},
{
"std": "windows_x86/desktop/qt6_681/qt6_681/Updates.xml",
"extpdf": "windows_x86/extensions/qtpdf/681/mingw/Updates.xml",
},
{
"std": [
plain_qtbase_archive(
"qt.qt6.681.win64_mingw",
"Windows-Windows_10_22H2-X86_64",
host="Windows-Windows_10_22H2-Mingw",
)
],
"extpdf": [
MockArchive(
filename_7z="qtpdf-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z",
update_xml_name="extensions.qtpdf.681.win64_mingw",
contents=(),
should_install=False,
extract_target="@TargetDir@/6.8.1/mingw_64",
),
],
},
re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Found extension qtpdf\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z in .*\n"
r"INFO : Downloading qtpdf...\n"
r"Finished installation of qtpdf-Windows-Windows_10_22H2-Mingw-Windows-Windows_10_22H2-X86_64.7z in .*\n"
r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second"
),
),
),
)
def test_install(
Expand All @@ -1145,12 +1283,24 @@ def test_install(
for i in range(len(desktop_archives)):
desktop_archives[i].version = version
desktop_archives[i].arch_dir = arch_dir["desk"]
extpdf_archives = archives.get("extpdf", [])
for i in range(len(extpdf_archives)):
extpdf_archives[i].version = version
extpdf_archives[i].arch_dir = arch_dir["extpdf"]
extweb_archives = archives.get("extweb", [])
for i in range(len(extweb_archives)):
extweb_archives[i].version = version
extweb_archives[i].arch_dir = arch_dir["extweb"]

mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
standard_archives=std_archives,
desktop_archives=desktop_archives,
extpdf_archives=extpdf_archives,
extweb_archives=extweb_archives,
standard_updates_url=updates_url.get("std", ""),
desktop_updates_url=updates_url.get("desk", ""),
extpdf_updates_url=updates_url.get("extpdf", ""),
extweb_updates_url=updates_url.get("extweb", ""),
)
monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
monkeypatch.setattr("aqt.helper.getUrl", mock_get_url)
Expand Down
Loading