Refactor test_install to mock multiple Qts

This will allow testing multiple qt installations, as required by the
feature that installs the default desktop qt where required

Add autodesktop test for ios
This commit is contained in:
Dave Dalcino
2022-07-30 10:49:40 -07:00
parent 703f2d2fe3
commit bcd4e03838
2 changed files with 422 additions and 281 deletions

View File

@@ -2,7 +2,7 @@ import re
import sys import sys
from pathlib import Path from pathlib import Path
from tempfile import TemporaryDirectory from tempfile import TemporaryDirectory
from typing import List, Optional from typing import Dict, List, Optional
import pytest import pytest
@@ -378,28 +378,73 @@ def test_cli_choose_archive_dest(
@pytest.mark.parametrize( @pytest.mark.parametrize(
"host, is_auto, mocked_mingw, existing_arch_dirs, expect_arch", "host, is_auto, mocked_mingw, existing_arch_dirs, expect",
( (
("windows", False, "win64_mingw99", ["not_mingw"], "win64_mingw99"), # not installed ( # not installed
("windows", False, "win64_mingw99", ["mingw128_32"], "mingw128_32"), # Alt Desktop Qt already installed "windows",
("linux", False, None, ["gcc_32"], "gcc_64"), # not installed False,
("linux", False, None, ["gcc_64"], "gcc_64"), # Desktop Qt already installed "win64_mingw99",
("windows", True, "win64_mingw99", ["not_mingw"], "win64_mingw99"), # not installed ["not_mingw"],
("windows", True, "win64_mingw99", ["mingw128_32"], "mingw128_32"), # Alt Desktop Qt already installed {"install": None, "instruct": "win64_mingw99", "use_dir": "mingw99_64"},
("linux", True, None, ["gcc_32"], "gcc_64"), # not installed ),
("linux", True, None, ["gcc_64"], "gcc_64"), # Desktop Qt already installed ( # Alt Desktop Qt already installed
"windows",
False,
"win64_mingw99",
["mingw128_32"],
{"install": None, "instruct": None, "use_dir": "mingw128_32"},
),
# not installed
("linux", False, None, ["gcc_32"], {"install": None, "instruct": "gcc_64", "use_dir": "gcc_64"}),
( # Desktop Qt already installed
"linux",
False,
None,
["gcc_64"],
{"install": None, "instruct": None, "use_dir": "gcc_64"},
),
( # not installed
"windows",
True,
"win64_mingw99",
["not_mingw"],
{"install": "win64_mingw99", "instruct": None, "use_dir": "mingw99_64"},
),
( # Alt Desktop Qt already installed
"windows",
True,
"win64_mingw99",
["mingw128_32"],
{"install": None, "instruct": None, "use_dir": "mingw128_32"},
),
# not installed
("linux", True, None, ["gcc_32"], {"install": "gcc_64", "instruct": None, "use_dir": "gcc_64"}),
( # Desktop Qt already installed
"linux",
True,
None,
["gcc_64"],
{"install": None, "instruct": None, "use_dir": "gcc_64"},
),
), ),
) )
@pytest.mark.skip def test_get_autodesktop_dir_and_arch(
def test_cli_handle_missing_desktop_qt( monkeypatch, capsys, host: str, is_auto: bool, mocked_mingw: str, existing_arch_dirs: List[str], expect: Dict[str, str]
monkeypatch, mocker, capsys, host, is_auto, mocked_mingw, existing_arch_dirs: List[str], expect_arch: str
): ):
"""
:is_auto: Simulates passing `--autodesktop` to aqt
:mocked_mingw: When we ask MetadataFactory for a list of available architectures, we return this value
:existing_arch_dirs: Directories that contain an existing file at `arch_dir/bin/qmake`
:expect[install]: The archdir we expect aqt to install
:expect[instruct]: The architecture we expect aqt to ask the user to install
:expect[use_dir]: The directory that includes `bin/qmake`; we will patch files in the mobile installation
with this value
"""
monkeypatch.setattr(MetadataFactory, "fetch_arches", lambda *args: [mocked_mingw]) monkeypatch.setattr(MetadataFactory, "fetch_arches", lambda *args: [mocked_mingw])
monkeypatch.setattr(Cli, "run", lambda *args: 0) monkeypatch.setattr(Cli, "run", lambda *args: 0)
target = "android" target = "android"
version = "6.2.3" version = "6.2.3"
spy = mocker.spy(Cli, "run")
cli = Cli() cli = Cli()
cli._setup_settings() cli._setup_settings()
@@ -414,19 +459,19 @@ def test_cli_handle_missing_desktop_qt(
qmake = base_dir / version / arch_dir / f"bin/qmake{'.exe' if host == 'windows' else ''}" qmake = base_dir / version / arch_dir / f"bin/qmake{'.exe' if host == 'windows' else ''}"
qmake.parent.mkdir(parents=True) qmake.parent.mkdir(parents=True)
qmake.write_text("exe file") qmake.write_text("exe file")
cli._install_desktop_qt(host, target, Version(version), base_dir, should_warn=not is_auto) autodesktop_arch_dir, autodesktop_arch_to_install = cli._get_autodesktop_dir_and_arch(
out, err = capsys.readouterr() is_auto, host, target, base_dir, Version(version)
if is_auto:
if expect_arch not in existing_arch_dirs:
assert err.strip() == f"INFO : {expect_msg_prefix} Now installing Qt: desktop {version} {expect_arch}"
spy.assert_called_once_with(cli, ["install-qt", host, "desktop", version, expect_arch])
else:
expect_msg = (
""
if expect_arch in existing_arch_dirs
else f"WARNING : {expect_msg_prefix} You can install it with the following command:\n"
f" `aqt install-qt {host} desktop {version} {expect_arch}`"
) )
assert err.strip() == expect_msg # It should choose the correct desktop arch directory for updates
assert spy.call_count == 0 assert autodesktop_arch_dir == expect["use_dir"]
out, err = capsys.readouterr()
if expect["install"]:
assert err.strip() == f"INFO : {expect_msg_prefix} Now installing Qt: desktop {version} {expect['install']}"
elif expect["instruct"]:
assert (
err.strip() == f"WARNING : {expect_msg_prefix} You can install it with the following command:\n"
f" `aqt install-qt {host} desktop {version} {expect['instruct']}`"
)
else:
assert err.strip() == f"INFO : Found installed {host}-desktop Qt at {temp_dir}/{version}/{expect['use_dir']}"

View File

@@ -1,6 +1,7 @@
import hashlib import hashlib
import logging import logging
import os import os
import posixpath
import re import re
import subprocess import subprocess
import sys import sys
@@ -124,34 +125,49 @@ class MockArchive:
def make_mock_geturl_download_archive( def make_mock_geturl_download_archive(
archives: Iterable[MockArchive], *,
arch: str, standard_archives: List[MockArchive],
os_name: str, desktop_archives: Optional[List[MockArchive]] = None,
updates_url: str, standard_updates_url: str,
desktop_updates_url: str = "",
) -> Tuple[GET_URL_TYPE, DOWNLOAD_ARCHIVE_TYPE]: ) -> Tuple[GET_URL_TYPE, DOWNLOAD_ARCHIVE_TYPE]:
""" """
Returns a mock 'getUrl' and a mock 'downloadArchive' function. Returns a mock 'getUrl' and a mock 'downloadArchive' function.
""" """
for _arc in archives: if desktop_archives is None:
assert _arc.filename_7z.endswith(".7z") desktop_archives = []
for _archive in [*standard_archives, *desktop_archives]:
assert _archive.filename_7z.endswith(".7z")
xml = "<Updates>\n{}\n</Updates>".format("\n".join([archive.xml_package_update() for archive in archives])) standard_xml = "<Updates>\n{}\n</Updates>".format(
"\n".join([archive.xml_package_update() for archive in standard_archives])
)
desktop_xml = "<Updates>\n{}\n</Updates>".format(
"\n".join([archive.xml_package_update() for archive in desktop_archives])
)
def mock_getUrl(url: str, *args, **kwargs) -> str: def mock_getUrl(url: str, *args, **kwargs) -> str:
if url.endswith(updates_url): for xml, updates_url in (
(standard_xml, standard_updates_url),
(desktop_xml, desktop_updates_url),
):
basename = posixpath.dirname(updates_url)
if not updates_url:
continue
elif url.endswith(updates_url):
return xml return xml
elif url.endswith(".sha256"): elif basename in url and url.endswith(".sha256"):
filename = url.split("/")[-1][: -len(".sha256")] filename = url.split("/")[-1][: -len(".sha256")]
return f"{hashlib.sha256(bytes(xml, 'utf-8')).hexdigest()} {filename}" return f"{hashlib.sha256(bytes(xml, 'utf-8')).hexdigest()} {filename}"
assert False assert False, f"No mocked url available for '{url}'"
def mock_download_archive(url: str, out: str, *args): def mock_download_archive(url: str, out: str, *args):
"""Make a mocked 7z archive at out_filename""" """Make a mocked 7z archive at out_filename"""
def locate_archive() -> MockArchive: def locate_archive() -> MockArchive:
for arc in archives: for archive in [*standard_archives, *desktop_archives]:
if Path(out).name == arc.filename_7z: if Path(out).name == archive.filename_7z:
return arc return archive
assert False, "Requested an archive that was not mocked" assert False, "Requested an archive that was not mocked"
locate_archive().write_compressed_archive(Path(out).parent) locate_archive().write_compressed_archive(Path(out).parent)
@@ -237,9 +253,9 @@ def qtpositioning_module(ver: str, arch: str) -> MockArchive:
) )
def plain_qtbase_archive(update_xml_name: str, arch: str, should_install: bool = True) -> MockArchive: def plain_qtbase_archive(update_xml_name: str, arch: str, host: str = "windows", should_install: bool = True) -> MockArchive:
return MockArchive( return MockArchive(
filename_7z=f"qtbase-windows-{arch}.7z", filename_7z=f"qtbase-{host}-{arch}.7z",
update_xml_name=update_xml_name, update_xml_name=update_xml_name,
contents=( contents=(
PatchedFile( PatchedFile(
@@ -282,12 +298,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"linux", "linux",
"desktop", "desktop",
"1.2.3-0-197001020304", "1.2.3-0-197001020304",
"", {"std": ""},
"", {"std": ""},
"linux_x64/desktop/tools_qtcreator/Updates.xml", {"std": "linux_x64/desktop/tools_qtcreator/Updates.xml"},
[ {"std": [tool_archive("linux", "tools_qtcreator", "qt.tools.qtcreator")]},
tool_archive("linux", "tools_qtcreator", "qt.tools.qtcreator"),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qt.tools.qtcreator...\n" r"INFO : Downloading qt.tools.qtcreator...\n"
@@ -301,12 +315,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"linux", "linux",
"desktop", "desktop",
"1.2.3", "1.2.3",
"", {"std": ""},
"", {"std": ""},
"linux_x64/desktop/tools_qtcreator/Updates.xml", {"std": "linux_x64/desktop/tools_qtcreator/Updates.xml"},
[ {"std": [tool_archive("linux", "tools_qtcreator", "qt.tools.qtcreator", datetime(1970, 1, 2, 3, 4, 5, 6))]},
tool_archive("linux", "tools_qtcreator", "qt.tools.qtcreator", datetime(1970, 1, 2, 3, 4, 5, 6)),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"WARNING : The command 'tool' is deprecated and marked for removal in a future version of aqt.\n" r"WARNING : The command 'tool' is deprecated and marked for removal in a future version of aqt.\n"
@@ -322,12 +334,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.14.0", "5.14.0",
"win32_mingw73", {"std": "win32_mingw73"},
"mingw73_32", {"std": "mingw73_32"},
"windows_x86/desktop/qt5_5140/Updates.xml", {"std": "windows_x86/desktop/qt5_5140/Updates.xml"},
[ {"std": [plain_qtbase_archive("qt.qt5.5140.win32_mingw73", "win32_mingw73")]},
plain_qtbase_archive("qt.qt5.5140.win32_mingw73", "win32_mingw73"),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"WARNING : The command 'install' is deprecated" r"WARNING : The command 'install' is deprecated"
@@ -344,10 +354,11 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.14.2", "5.14.2",
"", {"std": ""},
"", {"std": ""},
"windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml", {"std": "windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml"},
[ {
"std": [
MockArchive( MockArchive(
filename_7z="qtbase-everywhere-src-5.14.2.7z", filename_7z="qtbase-everywhere-src-5.14.2.7z",
update_xml_name="qt.qt5.5142.src", update_xml_name="qt.qt5.5142.src",
@@ -360,7 +371,8 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
), ),
), ),
), ),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"WARNING : The parameter 'target' with value 'desktop' is deprecated " r"WARNING : The parameter 'target' with value 'desktop' is deprecated "
@@ -377,10 +389,11 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.14.2", "5.14.2",
"", {"std": ""},
"", {"std": ""},
"windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml", {"std": "windows_x86/desktop/qt5_5142_src_doc_examples/Updates.xml"},
[ {
"std": [
MockArchive( MockArchive(
filename_7z="qtbase-everywhere-src-5.14.2.7z", filename_7z="qtbase-everywhere-src-5.14.2.7z",
update_xml_name="qt.qt5.5142.src", update_xml_name="qt.qt5.5142.src",
@@ -392,8 +405,9 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
patched_content=None, # not patched patched_content=None, # not patched
), ),
), ),
), )
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase\.\.\.\n" r"INFO : Downloading qtbase\.\.\.\n"
@@ -407,12 +421,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.9.0", "5.9.0",
"win32_mingw53", {"std": "win32_mingw53"},
"mingw53_32", {"std": "mingw53_32"},
"windows_x86/desktop/qt5_59/Updates.xml", {"std": "windows_x86/desktop/qt5_59/Updates.xml"},
[ {"std": [plain_qtbase_archive("qt.59.win32_mingw53", "win32_mingw53")]},
plain_qtbase_archive("qt.59.win32_mingw53", "win32_mingw53"),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"WARNING : The command 'install' is deprecated" r"WARNING : The command 'install' is deprecated"
@@ -429,12 +441,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.9.0", "5.9.0",
"win32_mingw53", {"std": "win32_mingw53"},
"mingw53_32", {"std": "mingw53_32"},
"windows_x86/desktop/qt5_59/Updates.xml", {"std": "windows_x86/desktop/qt5_59/Updates.xml"},
[ {"std": [plain_qtbase_archive("qt.59.win32_mingw53", "win32_mingw53")]},
plain_qtbase_archive("qt.59.win32_mingw53", "win32_mingw53"),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n" r"INFO : Downloading qtbase...\n"
@@ -448,12 +458,10 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.14.0", "5.14.0",
"win32_mingw73", {"std": "win32_mingw73"},
"mingw73_32", {"std": "mingw73_32"},
"windows_x86/desktop/qt5_5140/Updates.xml", {"std": "windows_x86/desktop/qt5_5140/Updates.xml"},
[ {"std": [plain_qtbase_archive("qt.qt5.5140.win32_mingw73", "win32_mingw73")]},
plain_qtbase_archive("qt.qt5.5140.win32_mingw73", "win32_mingw73"),
],
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n" r"INFO : Downloading qtbase...\n"
@@ -467,13 +475,15 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"5.14.0", "5.14.0",
"win64_mingw73", {"std": "win64_mingw73"},
"mingw73_64", {"std": "mingw73_64"},
"windows_x86/desktop/qt5_5140/Updates.xml", {"std": "windows_x86/desktop/qt5_5140/Updates.xml"},
[ {
"std": [
plain_qtbase_archive("qt.qt5.5140.win64_mingw73", "win64_mingw73"), plain_qtbase_archive("qt.qt5.5140.win64_mingw73", "win64_mingw73"),
qtcharts_module("5.14.0", "win64_mingw73"), qtcharts_module("5.14.0", "win64_mingw73"),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n" r"INFO : Downloading qtbase...\n"
@@ -489,13 +499,15 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"6.2.0", "6.2.0",
"win64_mingw73", {"std": "win64_mingw73"},
"mingw73_64", {"std": "mingw73_64"},
"windows_x86/desktop/qt6_620/Updates.xml", {"std": "windows_x86/desktop/qt6_620/Updates.xml"},
[ {
"std": [
plain_qtbase_archive("qt.qt6.620.win64_mingw73", "win64_mingw73", should_install=False), plain_qtbase_archive("qt.qt6.620.win64_mingw73", "win64_mingw73", should_install=False),
qtpositioning_module("6.2.0", "win64_mingw73"), qtpositioning_module("6.2.0", "win64_mingw73"),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtlocation...\n" r"INFO : Downloading qtlocation...\n"
@@ -509,13 +521,15 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"desktop", "desktop",
"6.1.0", "6.1.0",
"win64_mingw81", {"std": "win64_mingw81"},
"mingw81_64", {"std": "mingw81_64"},
"windows_x86/desktop/qt6_610/Updates.xml", {"std": "windows_x86/desktop/qt6_610/Updates.xml"},
[ {
"std": [
plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81"), plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81"),
qtcharts_module("6.1.0", "win64_mingw81"), qtcharts_module("6.1.0", "win64_mingw81"),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n" r"INFO : Downloading qtbase...\n"
@@ -531,10 +545,11 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"windows", "windows",
"android", "android",
"6.1.0", "6.1.0",
"android_armv7", {"std": "android_armv7"},
"android_armv7", {"std": "android_armv7"},
"windows_x86/android/qt6_610_armv7/Updates.xml", {"std": "windows_x86/android/qt6_610_armv7/Updates.xml"},
[ {
"std": [
MockArchive( MockArchive(
filename_7z="qtbase-windows-android_armv7.7z", filename_7z="qtbase-windows-android_armv7.7z",
update_xml_name="qt.qt6.610.android_armv7", update_xml_name="qt.qt6.610.android_armv7",
@@ -571,14 +586,15 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
), ),
), ),
), ),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-windows-android_armv7.7z in .*\n"
r"WARNING : You are installing the android version of Qt, which requires that the desktop version of " r"WARNING : You are installing the android version of Qt, which requires that the desktop version of "
r"Qt is also installed. You can install it with the following command:\n" r"Qt is also installed. You can install it with the following command:\n"
r" `aqt install-qt windows desktop 6.1.0 win64_mingw1234`\n" r" `aqt install-qt windows desktop 6.1.0 win64_mingw1234`\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-windows-android_armv7.7z in .*\n"
r"INFO : Patching .*6\.1\.0[/\\]android_armv7[/\\]bin[/\\]qmake.bat\n" r"INFO : Patching .*6\.1\.0[/\\]android_armv7[/\\]bin[/\\]qmake.bat\n"
r"INFO : Finished installation\n" r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second" r"INFO : Time elapsed: .* second"
@@ -589,10 +605,11 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"linux", "linux",
"android", "android",
"6.3.0", "6.3.0",
"android_arm64_v8a", {"std": "android_arm64_v8a"},
"android_arm64_v8a", {"std": "android_arm64_v8a"},
"linux_x64/android/qt6_630_arm64_v8a/Updates.xml", {"std": "linux_x64/android/qt6_630_arm64_v8a/Updates.xml"},
[ {
"std": [
MockArchive( MockArchive(
filename_7z="qtbase-linux-android_arm64_v8a.7z", filename_7z="qtbase-linux-android_arm64_v8a.7z",
update_xml_name="qt.qt6.630.android_arm64_v8a", update_xml_name="qt.qt6.630.android_arm64_v8a",
@@ -629,14 +646,15 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
), ),
), ),
), ),
], ]
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-linux-android_arm64_v8a.7z in .*\n"
r"WARNING : You are installing the android version of Qt, which requires that the desktop version of " r"WARNING : You are installing the android version of Qt, which requires that the desktop version of "
r"Qt is also installed. You can install it with the following command:\n" r"Qt is also installed. You can install it with the following command:\n"
r" `aqt install-qt linux desktop 6\.3\.0 gcc_64`\n" r" `aqt install-qt linux desktop 6\.3\.0 gcc_64`\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-linux-android_arm64_v8a.7z in .*\n"
r"INFO : Patching .*6\.3\.0[/\\]android_arm64_v8a[/\\]bin[/\\]qmake\n" r"INFO : Patching .*6\.3\.0[/\\]android_arm64_v8a[/\\]bin[/\\]qmake\n"
r"INFO : Finished installation\n" r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second" r"INFO : Time elapsed: .* second"
@@ -647,10 +665,71 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
"mac", "mac",
"ios", "ios",
"6.1.2", "6.1.2",
{"std": "ios"},
{"std": "ios"},
{"std": "mac_x64/ios/qt6_612/Updates.xml"},
{
"std": [
MockArchive(
filename_7z="qtbase-mac-ios.7z",
update_xml_name="qt.qt6.612.ios",
contents=(
# Qt 6 non-desktop should patch qconfig.pri, qmake script and target_qt.conf
PatchedFile(
filename="mkspecs/qconfig.pri",
unpatched_content="... blah blah blah ...\n"
"QT_EDITION = Not OpenSource\n"
"QT_LICHECK = Not Empty\n"
"... blah blah blah ...\n",
patched_content="... blah blah blah ...\n"
"QT_EDITION = OpenSource\n"
"QT_LICHECK =\n"
"... blah blah blah ...\n",
),
PatchedFile(
filename="bin/target_qt.conf",
unpatched_content="Prefix=/Users/qt/work/install/target\n"
"HostPrefix=../../\n"
"HostData=target\n",
patched_content="Prefix={base_dir}{sep}6.1.2{sep}ios{sep}target\n"
"HostPrefix=../../macos\n"
"HostData=../ios\n",
),
PatchedFile(
filename="bin/qmake",
unpatched_content="... blah blah blah ...\n"
"/Users/qt/work/install/bin\n"
"... blah blah blah ...\n",
patched_content="... blah blah blah ...\n"
"{base_dir}/6.1.2/macos/bin\n"
"... blah blah blah ...\n",
),
),
),
]
},
re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"WARNING : You are installing the ios version of Qt, which requires that the desktop version of Qt is "
r"also installed. You can install it with the following command:\n"
r" `aqt install-qt mac desktop 6\.1\.2 clang_64`\n"
r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-mac-ios.7z in .*\n"
r"INFO : Patching .*6\.1\.2[/\\]ios[/\\]bin[/\\]qmake\n"
r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second"
),
),
(
"install-qt mac ios 6.1.2 --autodesktop".split(),
"mac",
"ios", "ios",
"ios", "6.1.2",
"mac_x64/ios/qt6_612/Updates.xml", {"std": "ios", "desk": "clang_64"},
[ {"std": "ios", "desk": "macos"},
{"std": "mac_x64/ios/qt6_612/Updates.xml", "desk": "mac_x64/desktop/qt6_612/Updates.xml"},
{
"std": [
MockArchive( MockArchive(
filename_7z="qtbase-mac-ios.7z", filename_7z="qtbase-mac-ios.7z",
update_xml_name="qt.qt6.612.ios", update_xml_name="qt.qt6.612.ios",
@@ -688,13 +767,16 @@ def tool_archive(host: str, tool_name: str, variant: str, date: datetime = datet
), ),
), ),
], ],
"desk": [plain_qtbase_archive("qt.qt6.612.clang_64", "clang_64", host="mac")],
},
re.compile( re.compile(
r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n" r"^INFO : aqtinstall\(aqt\) v.* on Python 3.*\n"
r"INFO : You are installing the ios version of Qt, which requires that the desktop version of "
r"Qt is also installed. Now installing Qt: desktop 6\.1\.2 clang_64\n"
r"INFO : Downloading qtbase...\n" r"INFO : Downloading qtbase...\n"
r"Finished installation of qtbase-mac-ios.7z in .*\n" r"Finished installation of qtbase-mac-ios.7z in .*\n"
r"WARNING : You are installing the ios version of Qt, which requires that the desktop version of Qt is " r"INFO : Downloading qtbase...\n"
r"also installed. You can install it with the following command:\n" r"Finished installation of qtbase-mac-clang_64.7z in .*\n"
r" `aqt install-qt mac desktop 6\.1\.2 clang_64`\n"
r"INFO : Patching .*6\.1\.2[/\\]ios[/\\]bin[/\\]qmake\n" r"INFO : Patching .*6\.1\.2[/\\]ios[/\\]bin[/\\]qmake\n"
r"INFO : Finished installation\n" r"INFO : Finished installation\n"
r"INFO : Time elapsed: .* second" r"INFO : Time elapsed: .* second"
@@ -709,19 +791,28 @@ def test_install(
host: str, host: str,
target: str, target: str,
version: str, version: str,
arch: str, arch: Dict[str, str],
arch_dir: str, arch_dir: Dict[str, str],
updates_url: str, updates_url: Dict[str, str],
archives: List[MockArchive], archives: Dict[str, List[MockArchive]],
expect_out, # type: re.Pattern expect_out, # type: re.Pattern
): ):
# For convenience, fill in version and arch dir: prevents repetitive data declarations # For convenience, fill in version and arch dir: prevents repetitive data declarations
for i in range(len(archives)): std_archives = archives["std"]
archives[i].version = version for i in range(len(std_archives)):
archives[i].arch_dir = arch_dir std_archives[i].version = version
std_archives[i].arch_dir = arch_dir["std"]
desktop_archives = archives.get("desk", [])
for i in range(len(desktop_archives)):
desktop_archives[i].version = version
desktop_archives[i].arch_dir = arch_dir["desk"]
mock_get_url, mock_download_archive = make_mock_geturl_download_archive(archives, arch, host, updates_url) mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
standard_archives=std_archives,
desktop_archives=desktop_archives,
standard_updates_url=updates_url.get("std", None),
desktop_updates_url=updates_url.get("desk", None),
)
monkeypatch.setattr("aqt.archives.getUrl", mock_get_url) monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
monkeypatch.setattr("aqt.helper.getUrl", mock_get_url) monkeypatch.setattr("aqt.helper.getUrl", mock_get_url)
monkeypatch.setattr("aqt.installer.downloadBinaryFile", mock_download_archive) monkeypatch.setattr("aqt.installer.downloadBinaryFile", mock_download_archive)
@@ -742,11 +833,12 @@ def test_install(
assert expect_out.match(err) assert expect_out.match(err)
installed_path = Path(output_dir) / version / arch_dir for key in arch_dir.keys():
installed_path = Path(output_dir) / version / arch_dir[key]
if version == "5.9.0": if version == "5.9.0":
installed_path = Path(output_dir) / "5.9" / arch_dir installed_path = Path(output_dir) / "5.9" / arch_dir[key]
assert installed_path.is_dir() assert installed_path.is_dir()
for archive in archives: for archive in archives[key]:
if not archive.should_install: if not archive.should_install:
continue continue
for patched_file in archive.contents: for patched_file in archive.contents:
@@ -915,7 +1007,9 @@ def test_install_pool_exception(monkeypatch, capsys, exception_class, settings_f
archives = [plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81")] archives = [plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81")]
cmd = ["install-qt", host, target, ver, arch] cmd = ["install-qt", host, target, ver, arch]
mock_get_url, mock_download_archive = make_mock_geturl_download_archive(archives, arch, host, updates_url) mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
standard_archives=archives, standard_updates_url=updates_url
)
monkeypatch.setattr("aqt.archives.getUrl", mock_get_url) monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
monkeypatch.setattr("aqt.helper.getUrl", mock_get_url) monkeypatch.setattr("aqt.helper.getUrl", mock_get_url)
monkeypatch.setattr("aqt.installer.installer", mock_installer_func) monkeypatch.setattr("aqt.installer.installer", mock_installer_func)
@@ -1016,7 +1110,9 @@ def test_installer_passes_base_to_metadatafactory(
archives[i].version = version archives[i].version = version
archives[i].arch_dir = arch_dir archives[i].arch_dir = arch_dir
basic_mock_get_url, mock_download_archive = make_mock_geturl_download_archive(archives, arch, host, updates_url) basic_mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
standard_archives=archives, standard_updates_url=updates_url
)
def mock_get_url(url: str, *args, **kwargs) -> str: def mock_get_url(url: str, *args, **kwargs) -> str:
# If we are fetching an index.html file, get it from tests/data/ # If we are fetching an index.html file, get it from tests/data/