Exemple #1
0
def test_cli_invalid_version(capsys, invalid_version):
    """Checks that invalid version strings are handled properly"""

    # Ensure that invalid_version cannot be a semantic_version.Version
    with pytest.raises(ValueError):
        Version(invalid_version)

    cli = Cli()
    cli._setup_settings()

    matcher = re.compile(r"^INFO    : aqtinstall\(aqt\) v.* on Python 3.*\n"
                         r"(.*\n)*"
                         r"ERROR   :.*Invalid version: '" + invalid_version +
                         r"'! Please use the form '5\.X\.Y'\.\n.*")

    for cmd in (
        ("install", invalid_version, "mac", "desktop"),
        ("doc", invalid_version, "mac", "desktop"),
        ("list-qt", "mac", "desktop", "--arch", invalid_version),
    ):
        cli = Cli()
        assert cli.run(cmd) == 1
        out, err = capsys.readouterr()
        sys.stdout.write(out)
        sys.stderr.write(err)
        assert matcher.match(err)
Exemple #2
0
def test_list_archives(monkeypatch, capsys, version: str, arch: str,
                       modules_to_query: List[str],
                       modules_failed_query: List[str]):
    archive_id = ArchiveId("qt", "windows", "desktop")
    in_file = f"{archive_id.host}-{version.replace('.', '')}-update.xml"
    expect_out_file = f"{archive_id.host}-{version.replace('.', '')}-expect.json"
    _xml = (Path(__file__).parent / "data" / in_file).read_text("utf-8")
    monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: _xml)
    expect = json.loads(
        (Path(__file__).parent / "data" / expect_out_file).read_text("utf-8"))

    if not modules_to_query:
        expected_qt_archives = expect["qt_base_pkgs_by_arch"][arch][
            "DownloadableArchives"]
        expected = set([arc.split("-")[0] for arc in expected_qt_archives])
    else:
        expected_mod_metadata = expect["modules_metadata_by_arch"][arch]
        if "all" not in modules_to_query:
            expected_mod_metadata = filter(
                lambda mod: mod["Name"].split(".")[-2] in modules_to_query,
                expected_mod_metadata)
        expected = set([
            arc.split("-")[0] for mod in expected_mod_metadata
            for arc in mod["DownloadableArchives"]
        ])

    archives_query = [version, arch, *modules_to_query]
    cli_args = ["list-qt", "windows", "desktop", "--archives", *archives_query]
    if not modules_failed_query:
        meta = set(
            MetadataFactory(archive_id,
                            archives_query=archives_query).getList())
        assert meta == expected

        cli = Cli()
        assert 0 == cli.run(cli_args)
        out, err = capsys.readouterr()
        assert out.rstrip() == " ".join(sorted(expected))
        return

    expected_err_msg = f"The requested modules were not located: {sorted(modules_failed_query)}"
    with pytest.raises(CliInputError) as err:
        MetadataFactory(archive_id, archives_query=archives_query).getList()
    assert err.type == CliInputError
    assert format(err.value).startswith(expected_err_msg)

    cli = Cli()
    assert 1 == cli.run(cli_args)
    out, err = capsys.readouterr()
    assert expected_err_msg in err
Exemple #3
0
def test_cli_determine_qt_version(monkeypatch, host, target, arch,
                                  version_or_spec: str,
                                  expected_version: Version,
                                  is_bad_spec: bool):
    _html = (Path(__file__).parent / "data" /
             f"{host}-{target}.html").read_text("utf-8")
    monkeypatch.setattr(MetadataFactory, "fetch_http",
                        lambda *args, **kwargs: _html)
    cli = Cli()
    cli._setup_settings()

    if is_bad_spec:
        with pytest.raises(CliInputError) as e:
            Cli._determine_qt_version(version_or_spec, host, target, arch)
        assert e.type == CliInputError
        assert format(
            e.value
        ) == f"Invalid version or SimpleSpec: '{version_or_spec}'\n" + SimpleSpec.usage(
        )
    elif not expected_version:
        with pytest.raises(CliInputError) as e:
            Cli._determine_qt_version(version_or_spec, host, target, arch)
        assert e.type == CliInputError
        expect_msg = f"No versions of Qt exist for spec={version_or_spec} with host={host}, target={target}, arch={arch}"
        actual_msg = format(e.value)
        assert actual_msg == expect_msg
    else:
        ver = Cli._determine_qt_version(version_or_spec, host, target, arch)
        assert ver == expected_version
Exemple #4
0
def test_cli_set_7zip(monkeypatch):
    cli = Cli()
    cli._setup_settings()
    with pytest.raises(CliInputError) as err:
        cli._set_sevenzip("some_nonexistent_binary")
    assert err.type == CliInputError
    assert format(err.value) == "Specified 7zip command executable does not exist: 'some_nonexistent_binary'"
Exemple #5
0
def test_cli_check_module():
    cli = Cli()
    cli._setup_settings()
    assert cli._check_modules_arg("5.11.3", ["qtcharts", "qtwebengine"])
    assert not cli._check_modules_arg("5.7", ["not_exist"])
    assert cli._check_modules_arg("5.14.0", None)
    assert not cli._check_modules_arg("5.15.0", ["Unknown"])
Exemple #6
0
def test_install_nonexistent_archives(monkeypatch, capsys, cmd,
                                      xml_file: Optional[str], expected):
    xml = (Path(__file__).parent / "data" /
           xml_file).read_text("utf-8") if xml_file else ""

    def mock_get_url(url, *args, **kwargs):
        if not xml_file:
            raise ArchiveDownloadError(
                f"Failed to retrieve file at {url}\nServer response code: 404, reason: Not Found"
            )
        return xml

    monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
    monkeypatch.setattr(
        "aqt.archives.get_hash", lambda *args, **kwargs: hashlib.sha256(
            bytes(xml, "utf-8")).hexdigest())
    monkeypatch.setattr(
        "aqt.metadata.get_hash", lambda *args, **kwargs: hashlib.sha256(
            bytes(xml, "utf-8")).hexdigest())
    monkeypatch.setattr("aqt.metadata.getUrl", mock_get_url)

    cli = Cli()
    cli._setup_settings()
    assert cli.run(cmd.split()) == 1

    out, err = capsys.readouterr()
    actual = err[err.index("\n") + 1:]
    assert actual == expected, "{0} != {1}".format(actual, expected)
Exemple #7
0
def test_cli_check_mirror():
    cli = Cli()
    cli._setup_settings()
    assert cli._check_mirror(None)
    arg = ["install-qt", "linux", "desktop", "5.11.3", "-b", "https://download.qt.io/"]
    args = cli.parser.parse_args(arg)
    assert args.base == "https://download.qt.io/"
    assert cli._check_mirror(args.base)
Exemple #8
0
def test_list_wrong_target(capsys, cmd: str, host: str, target: str):
    expect = f"ERROR   : '{target}' is not a valid target for host '{host}'"

    cli = Cli()
    return_code = cli.run([cmd, host, target])
    out, err = capsys.readouterr()
    assert return_code == 1
    assert err.strip() == expect
Exemple #9
0
def test_invalid_spec(capsys, cmd: str, spec: str):
    expect_prefix = f"ERROR   : Invalid version specification: '{spec}'"
    host, target = "linux", "desktop"
    cli = Cli()
    return_code = cli.run([cmd, host, target, "--spec", spec])
    out, err = capsys.readouterr()
    assert return_code == 1
    assert err.strip().startswith(expect_prefix)
Exemple #10
0
def test_cli_legacy_commands_with_correct_syntax(monkeypatch, cmd):
    # Pretend to install correctly when any command is run
    for func in ("run_install_qt", "run_install_src", "run_install_doc", "run_install_example", "run_install_tool"):
        monkeypatch.setattr(Cli, func, lambda *args, **kwargs: 0)

    cli = Cli()
    cli._setup_settings()
    assert 0 == cli.run(cmd.split())
Exemple #11
0
def test_cli_check_combination():
    cli = Cli()
    cli._setup_settings()
    assert cli._check_qt_arg_combination("5.11.3", "linux", "desktop",
                                         "gcc_64")
    assert cli._check_qt_arg_combination("5.11.3", "mac", "desktop",
                                         "clang_64")
    assert not cli._check_qt_arg_combination("5.14.0", "android", "desktop",
                                             "clang_64")
Exemple #12
0
def test_list_invalid_extensions(capsys, monkeypatch, target, ext, version,
                                 expected_msg):
    host = "windows"
    extension_params = ["--extension", ext] if ext else []
    cli = Cli()
    cli.run(["list-qt", host, target, *extension_params, "--arch", version])
    out, err = capsys.readouterr()
    sys.stdout.write(out)
    sys.stderr.write(err)
    assert expected_msg in err
Exemple #13
0
def test_cli_input_errors(capsys, cmd, expect_msg, should_show_help):
    cli = Cli()
    cli._setup_settings()
    assert 1 == cli.run(cmd.split())
    out, err = capsys.readouterr()
    if should_show_help:
        assert expected_help(out)
    else:
        assert out == ""
    assert err.rstrip().endswith(expect_msg)
Exemple #14
0
def test_list_src_doc_examples_cli(monkeypatch, capsys, win_5152_sde_xml_file,
                                   command: str, expected: Set[str]):
    monkeypatch.setattr(MetadataFactory, "fetch_http",
                        lambda self, _: win_5152_sde_xml_file)

    cli = Cli()
    assert 0 == cli.run(command.split())
    out, err = capsys.readouterr()
    assert not err
    out_set = set(out.strip().split())
    assert out_set == expected
Exemple #15
0
def test_install(
        monkeypatch,
        capsys,
        cmd: List[str],
        host: str,
        target: str,
        version: str,
        arch: str,
        arch_dir: str,
        updates_url: str,
        archives: List[MockArchive],
        expect_out,  # type: re.Pattern
):

    # For convenience, fill in version and arch dir: prevents repetitive data declarations
    for i in range(len(archives)):
        archives[i].version = version
        archives[i].arch_dir = arch_dir

    mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
        archives, arch, host, updates_url)
    monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
    monkeypatch.setattr("aqt.installer.getUrl", mock_get_url)
    monkeypatch.setattr("aqt.installer.downloadBinaryFile",
                        mock_download_archive)

    with TemporaryDirectory() as output_dir:
        cli = Cli()
        cli._setup_settings()

        assert 0 == cli.run(cmd + ["--outputdir", output_dir])

        out, err = capsys.readouterr()
        sys.stdout.write(out)
        sys.stderr.write(err)

        assert expect_out.match(err)

        installed_path = Path(output_dir) / version / arch_dir
        if version == "5.9.0":
            installed_path = Path(output_dir) / "5.9" / arch_dir
        assert installed_path.is_dir()
        for archive in archives:
            if not archive.should_install:
                continue
            for patched_file in archive.contents:
                file_path = installed_path / patched_file.filename
                assert file_path.is_file()

                expect_content = patched_file.expected_content(
                    base_dir=output_dir, sep=os.sep)
                actual_content = file_path.read_text(encoding="utf_8")
                assert actual_content == expect_content
Exemple #16
0
def test_list_tool_cli(monkeypatch, capsys, host: str, target: str,
                       tool_name: str):
    html_file = f"{host}-{target}.html"
    xml_file = f"{host}-{target}-{tool_name}-update.xml"
    html_expect = f"{host}-{target}-expect.json"
    xml_expect = f"{host}-{target}-{tool_name}-expect.json"
    htmltext, xmltext, htmljson, xmljson = [
        (Path(__file__).parent / "data" / filename).read_text("utf-8")
        for filename in (html_file, xml_file, html_expect, xml_expect)
    ]
    expected_tools = set(json.loads(htmljson)["tools"])
    xml_data = json.loads(xmljson)
    expected_tool_modules = set(xml_data["modules"])

    def _mock_fetch_http(_, rest_of_url, *args, **kwargs: str) -> str:
        if not rest_of_url.endswith("Updates.xml"):
            return htmltext
        folder = urlparse(rest_of_url).path.split("/")[-2]
        assert folder.startswith("tools_")
        return xmltext

    monkeypatch.setattr(MetadataFactory, "fetch_http", _mock_fetch_http)

    cli = Cli()
    cli.run(["list-tool", host, target])
    out, err = capsys.readouterr()
    output_set = set(out.strip().split())
    assert output_set == expected_tools

    cli.run(["list-tool", host, target, tool_name])
    out, err = capsys.readouterr()
    output_set = set(out.strip().split())
    assert output_set == expected_tool_modules

    # Test abbreviated tool name: "aqt list-tool mac desktop ifw"
    assert tool_name.startswith("tools_")
    short_tool_name = tool_name[6:]
    cli.run(["list-tool", host, target, short_tool_name])
    out, err = capsys.readouterr()
    output_set = set(out.strip().split())
    assert output_set == expected_tool_modules

    cli.run(["list-tool", host, target, tool_name, "-l"])
    out, err = capsys.readouterr()

    expected_tooldata = format(fetch_expected_tooldata(xml_expect))
    assert out.strip() == expected_tooldata
Exemple #17
0
def test_cli_unexpected_error(monkeypatch, capsys):
    def _mocked_run(*args):
        raise RuntimeError("Some unexpected error")

    monkeypatch.setattr("aqt.installer.Cli.run_install_qt", _mocked_run)

    cli = Cli()
    cli._setup_settings()
    assert Cli.UNHANDLED_EXCEPTION_CODE == cli.run(["install-qt", "mac", "ios", "6.2.0"])
    out, err = capsys.readouterr()
    assert err.startswith("Some unexpected error")
    assert err.rstrip().endswith(
        "===========================PLEASE FILE A BUG REPORT===========================\n"
        "You have discovered a bug in aqt.\n"
        "Please file a bug report at https://github.com/miurahr/aqtinstall/issues.\n"
        "Please remember to include a copy of this program's output in your report."
    )
Exemple #18
0
def test_cli_legacy_tool_new_syntax(monkeypatch, capsys, cmd):
    # These incorrect commands cannot be filtered out directly by argparse because
    # they have the correct number of arguments.
    command = cmd.split()

    expected = (
        "WARNING : The command 'tool' is deprecated and marked for removal in a future version of aqt.\n"
        "In the future, please use the command 'install-tool' instead.\n"
        "ERROR   : Invalid version: 'tools_ifw'! Please use the form '5.X.Y'.\n"
    )

    cli = Cli()
    cli._setup_settings()
    assert 1 == cli.run(command)
    out, err = capsys.readouterr()
    actual = err[err.index("\n") + 1:]
    assert actual == expected
Exemple #19
0
def test_list_qt_cli(
    monkeypatch,
    capsys,
    expected_windows_desktop_5140: Dict[str, Set[str]],
    args: str,
    expect: Union[Set[str], List[str]],
):
    htmlfile, xmlfile = "windows-desktop.html", "windows-5140-update.xml"
    version_string_to_replace = "qt5.5140"
    if isinstance(expect, list):
        # In this case, 'expect' is a list of keys to follow to the expected values.
        expected_dict = expected_windows_desktop_5140
        for key in expect:  # Follow the chain of keys to the list of values.
            expected_dict = expected_dict[key]
        assert isinstance(expected_dict, list)
        expect_set = set(expected_dict)
    else:
        expect_set = expect
    assert isinstance(expect_set, set)

    def _mock_fetch_http(_, rest_of_url, *args, **kwargs: str) -> str:
        htmltext = (Path(__file__).parent / "data" /
                    htmlfile).read_text("utf-8")
        if not rest_of_url.endswith("Updates.xml"):
            return htmltext

        xmltext = (Path(__file__).parent / "data" / xmlfile).read_text("utf-8")
        # If we are serving an Updates.xml, `aqt list` will look for a Qt version number.
        # We will replace the version numbers in the file with the requested version.
        match = re.search(r"qt(\d)_(\d+)", rest_of_url)
        assert match
        major, version_nodot = match.groups()
        desired_version_string = f"qt{major}.{version_nodot}"
        return xmltext.replace(version_string_to_replace,
                               desired_version_string)

    monkeypatch.setattr(MetadataFactory, "fetch_http", _mock_fetch_http)

    cli = Cli()
    cli.run(["list-qt", "windows", "desktop", *args.split()])
    out, err = capsys.readouterr()
    output_set = set(out.strip().split())
    assert output_set == expect_set
Exemple #20
0
def test_install_pool_exception(monkeypatch, capsys, make_exception,
                                settings_file, expect_end_msg, expect_return):
    def mock_installer_func(*args):
        raise eval(make_exception)

    host, target, ver, arch = "windows", "desktop", "6.1.0", "win64_mingw81"
    updates_url = "windows_x86/desktop/qt6_610/Updates.xml"
    archives = [
        plain_qtbase_archive("qt.qt6.610.win64_mingw81", "win64_mingw81")
    ]

    cmd = ["install-qt", host, target, ver, arch]
    mock_get_url, mock_download_archive = make_mock_geturl_download_archive(
        archives, arch, host, updates_url)
    monkeypatch.setattr("aqt.archives.getUrl", mock_get_url)
    monkeypatch.setattr("aqt.installer.getUrl", mock_get_url)
    monkeypatch.setattr("aqt.installer.installer", mock_installer_func)

    Settings.load_settings(str(Path(__file__).parent / settings_file))
    cli = Cli()
    assert expect_return == cli.run(cmd)
    out, err = capsys.readouterr()
    assert err.rstrip().endswith(expect_end_msg)
Exemple #21
0
def test_list_targets(capsys, cmd: str, host: str, expect: Set[str]):
    cli = Cli()
    cli.run([cmd, host])
    out, err = capsys.readouterr()
    output_set = set(out.strip().split())
    assert output_set == expect
Exemple #22
0
def test_list_archives_insufficient_args(capsys):
    cli = Cli()
    assert 1 == cli.run("list-qt mac desktop --archives 5.14.0".split())
    out, err = capsys.readouterr()
    assert err.strip(
    ) == "ERROR   : The '--archives' flag requires a 'QT_VERSION' and an 'ARCHITECTURE' parameter."
Exemple #23
0
def test_cli_legacy_commands_with_wrong_syntax(cmd):
    cli = Cli()
    cli._setup_settings()
    with pytest.raises(SystemExit) as e:
        cli.run(cmd.split())
    assert e.type == SystemExit
Exemple #24
0
def main():
    # For Windows standalone binaries, this is a noop on all other environments.
    freeze_support()
    cli = Cli()
    return cli.run()
Exemple #25
0
def test_cli_help(capsys):
    cli = Cli()
    cli.run(["help"])
    out, err = capsys.readouterr()
    assert expected_help(out)
Exemple #26
0
def main():
    cli = Cli()
    return cli.run()
Exemple #27
0
def test_cli_check_version():
    cli = Cli()
    cli._setup_settings()
    assert cli._check_qt_arg_versions("5.12.0")
    assert not cli._check_qt_arg_versions("5.12")