def test_list_versions_tools(monkeypatch, spec_regex, os_name, target, in_file, expect_out_file): _html = (Path(__file__).parent / "data" / in_file).read_text("utf-8") monkeypatch.setattr(MetadataFactory, "fetch_http", lambda *args, **kwargs: _html) expected = json.loads( (Path(__file__).parent / "data" / expect_out_file).read_text("utf-8")) # Test 'aqt list-tool' tools = MetadataFactory(ArchiveId("tools", os_name, target)).getList() assert tools == expected["tools"] for ext, expected_output in expected["qt"].items(): # Test 'aqt list-qt' archive_id = ArchiveId("qt", os_name, target, ext if ext != "qt" else "") all_versions = MetadataFactory(archive_id).getList() if len(expected_output) == 0: assert not all_versions else: assert f"{all_versions}" == "\n".join(expected_output) # Filter for the latest version only latest_ver = MetadataFactory(archive_id, is_latest_version=True).getList() if len(expected_output) == 0: assert not latest_ver else: assert f"{latest_ver}" == expected_output[-1].split(" ")[-1] for row in expected_output: spec_str = spec_regex.search(row).group(1) spec = SimpleSpec(spec_str) if not ext.endswith( "preview") else SimpleSpec(spec_str + ".0-preview") # Find the latest version for a particular spec latest_ver_for_spec = MetadataFactory( archive_id, spec=spec, is_latest_version=True, ).getList() assert f"{latest_ver_for_spec}" == row.split(" ")[-1] # Find all versions for a particular spec all_ver_for_spec = MetadataFactory( archive_id, spec=spec, ).getList() assert f"{all_ver_for_spec}" == row
def opt_version_for_spec(ext: str, _spec: SimpleSpec) -> Optional[Version]: try: return MetadataFactory(ArchiveId("qt", host, target, ext), spec=_spec).getList().latest() except AqtException: return None
def test_show_list_empty(monkeypatch, capsys): monkeypatch.setattr(MetadataFactory, "getList", lambda self: []) meta = MetadataFactory(ArchiveId("tools", "mac", "desktop")) with pytest.raises(EmptyMetadata) as error: show_list(meta) assert error.type == EmptyMetadata assert format(error.value) == "No tools available for this request."
def list_qt_versions(host: str = "linux", target: str = "desktop") -> List[str]: all_versions = list() versions: Versions = MetadataFactory(ArchiveId("qt", host, target)).getList() for minor_group in versions: all_versions.extend([str(ver) for ver in minor_group]) return all_versions
def iter_qt_minor_groups( host: str = "linux", target: str = "desktop") -> Generator[Tuple[int, int], None, None]: versions: Versions = MetadataFactory(ArchiveId("qt", host, target)).getList() for minor_group in versions: v = minor_group[0] yield v.major, v.minor
def test_list_src_doc_examples_modules(monkeypatch, win_5152_sde_xml_file, cmd_type: str, host: str, version: str, expected: Set[str]): monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: win_5152_sde_xml_file) archive_id = ArchiveId("qt", host, "desktop", "src_doc_examples") modules = set( MetadataFactory(archive_id).fetch_modules_sde(cmd_type, Version(version))) assert modules == expected
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
def iter_modules_for_qt_minor_groups( host: str = "linux", target: str = "desktop", arch: str = "gcc_64") -> Generator[Dict, None, None]: logger.info("Fetching qt modules for {}/{}".format(host, target)) for major, minor in tqdm(list(iter_qt_minor_groups(host, target))): yield { "qt_version": f"{major}.{minor}", "modules": MetadataFactory(ArchiveId("qt", host, target), modules_query=(f"{major}.{minor}.0", arch)).getList(), }
def test_list_archives_bad_xml(monkeypatch): archive_id = ArchiveId("qt", "windows", "desktop") archives_query = ["5.15.2", "win32_mingw81", "qtcharts"] xml_no_name = "<Updates><PackageUpdate><badname></badname></PackageUpdate></Updates>" xml_empty_name = "<Updates><PackageUpdate><Name></Name></PackageUpdate></Updates>" xml_broken = "<Updates></PackageUpdate><PackageUpdate></Updates><Name></Name>" for _xml in (xml_no_name, xml_empty_name, xml_broken): monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: _xml) with pytest.raises(ArchiveListError) as e: MetadataFactory(archive_id, archives_query=archives_query).getList() assert e.type == ArchiveListError
def test_show_list_tools(monkeypatch, capsys): page = (Path(__file__).parent / "data" / "mac-desktop.html").read_text("utf-8") monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: page) expect_file = Path(__file__).parent / "data" / "mac-desktop-expect.json" expect = "\n".join(json.loads( expect_file.read_text("utf-8"))["tools"]) + "\n" meta = MetadataFactory(ArchiveId("tools", "mac", "desktop")) show_list(meta) out, err = capsys.readouterr() sys.stdout.write(out) sys.stderr.write(err) assert out == expect
def test_list_fetch_tool_by_simple_spec(monkeypatch): update_xml = ( Path(__file__).parent / "data" / "windows-desktop-tools_vcredist-update.xml").read_text("utf-8") monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: update_xml) expect_json = ( Path(__file__).parent / "data" / "windows-desktop-tools_vcredist-expect.json").read_text("utf-8") expected = json.loads(expect_json)["modules_data"] def check(actual, expect): for key in ( "Description", "DisplayName", "DownloadableArchives", "ReleaseDate", "SHA1", "Version", "Virtual", ): assert actual[key] == expect[key] meta = MetadataFactory(ArchiveId("tools", "windows", "desktop")) check( meta.fetch_tool_by_simple_spec(tool_name="tools_vcredist", simple_spec=SimpleSpec("2011")), expected["qt.tools.vcredist"], ) check( meta.fetch_tool_by_simple_spec(tool_name="tools_vcredist", simple_spec=SimpleSpec("2014")), expected["qt.tools.vcredist_msvc2013_x86"], ) nonexistent = meta.fetch_tool_by_simple_spec( tool_name="tools_vcredist", simple_spec=SimpleSpec("1970")) assert nonexistent is None # Simulate a broken Updates.xml file, with invalid versions highest_module_info = MetadataFactory.choose_highest_version_in_spec( all_tools_data={"some_module": { "Version": "not_a_version" }}, simple_spec=SimpleSpec("*"), ) assert highest_module_info is None
def test_list_architectures_and_modules(monkeypatch, version: str, extension: str, in_file: str, expect_out_file: str): archive_id = ArchiveId("qt", "windows", "desktop", extension) _xml = (Path(__file__).parent / "data" / in_file).read_text("utf-8") expect = json.loads( (Path(__file__).parent / "data" / expect_out_file).read_text("utf-8")) monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: _xml) for arch in expect["architectures"]: modules = MetadataFactory(archive_id).fetch_modules( Version(version), arch) assert modules == sorted(expect["modules_by_arch"][arch]) arches = MetadataFactory(archive_id).fetch_arches(Version(version)) assert arches == expect["architectures"]
def test_tool_modules(monkeypatch, host: str, target: str, tool_name: str): archive_id = ArchiveId("tools", host, target) in_file = "{}-{}-{}-update.xml".format(host, target, tool_name) expect_out_file = "{}-{}-{}-expect.json".format(host, target, tool_name) _xml = (Path(__file__).parent / "data" / in_file).read_text("utf-8") expect = json.loads( (Path(__file__).parent / "data" / expect_out_file).read_text("utf-8")) monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: _xml) modules = MetadataFactory(archive_id, tool_name=tool_name).getList() assert modules == expect["modules"] table = MetadataFactory(archive_id, tool_name=tool_name, is_long_listing=True).getList() assert table._rows() == expect["long_listing"]
def run_list_tool(self, args: argparse.ArgumentParser): """Print tools""" if not args.target: print(" ".join(ArchiveId.TARGETS_FOR_HOST[args.host])) return if args.target not in ArchiveId.TARGETS_FOR_HOST[args.host]: raise CliInputError( "'{0.target}' is not a valid target for host '{0.host}'". format(args)) meta = MetadataFactory( archive_id=ArchiveId("tools", args.host, args.target), tool_name=args.tool_name, is_long_listing=args.long, ) show_list(meta)
def run_list_qt(self, args: argparse.ArgumentParser): """Print versions of Qt, extensions, modules, architectures""" if not args.target: print(" ".join(ArchiveId.TARGETS_FOR_HOST[args.host])) return if args.target not in ArchiveId.TARGETS_FOR_HOST[args.host]: raise CliInputError( "'{0.target}' is not a valid target for host '{0.host}'". format(args)) if args.modules: modules_ver, modules_query = args.modules[0], tuple(args.modules) else: modules_ver, modules_query = None, None for version_str in (modules_ver, args.extensions, args.arch, args.archives[0] if args.archives else None): Cli._validate_version_str(version_str, allow_latest=True, allow_empty=True) spec = None try: if args.spec is not None: spec = SimpleSpec(args.spec) except ValueError as e: raise CliInputError( f"Invalid version specification: '{args.spec}'.\n" + SimpleSpec.usage()) from e meta = MetadataFactory( archive_id=ArchiveId( "qt", args.host, args.target, args.extension if args.extension else "", ), spec=spec, is_latest_version=args.latest_version, modules_query=modules_query, extensions_ver=args.extensions, architectures_ver=args.arch, archives_query=args.archives, ) show_list(meta)
def test_show_list_tools_long_ifw(capsys, monkeypatch, columns, expect): update_xml = (Path(__file__).parent / "data" / "mac-desktop-tools_ifw-update.xml").read_text("utf-8") monkeypatch.setattr(MetadataFactory, "fetch_http", lambda self, _: update_xml) monkeypatch.setattr(shutil, "get_terminal_size", lambda fallback: os.terminal_size((columns, 24))) meta = MetadataFactory( ArchiveId("tools", "mac", "desktop"), tool_name="tools_ifw", is_long_listing=True, ) show_list(meta) out, err = capsys.readouterr() sys.stdout.write(out) sys.stderr.write(err) assert out == expect
def iter_archive_ids( *, category: str, hosts: Iterator[str] = ArchiveId.HOSTS, targets: Optional[Iterator[str]] = None, add_extensions: bool = False, ) -> Generator[ArchiveId, None, None]: def iter_extensions() -> Generator[str, None, None]: if add_extensions and category == "qt": if target == "android": yield from ("", "x86_64", "x86", "armv7", "arm64_v8a") return elif target == "desktop": yield from ("wasm", "") return yield "" for host in sorted(hosts): use_targets = targets if use_targets is None: use_targets = ArchiveId.TARGETS_FOR_HOST[host] for target in use_targets: for ext in iter_extensions(): yield ArchiveId(category, host, target, ext)
def run_install_tool(self, args): """Run tool subcommand""" start_time = time.perf_counter() self.show_aqt_version() if args.is_legacy: self._warn_on_deprecated_command("tool", "install-tool") tool_name = args.tool_name # such as tools_openssl_x64 os_name = args.host # windows, linux and mac target = "desktop" if args.is_legacy else args.target # desktop, android and ios output_dir = args.outputdir if output_dir is None: base_dir = os.getcwd() else: base_dir = output_dir sevenzip = self._set_sevenzip(args.external) if EXT7Z and sevenzip is None: # override when py7zr is not exist sevenzip = self._set_sevenzip(Settings.zipcmd) version = getattr(args, "version", None) # for legacy aqt tool keep = args.keep if args.base is not None: base = args.base else: base = Settings.baseurl if args.timeout is not None: timeout = (args.timeout, args.timeout) else: timeout = (Settings.connection_timeout, Settings.response_timeout) if args.tool_variant is None: archive_id = ArchiveId("tools", os_name, target, "") meta = MetadataFactory(archive_id, is_latest_version=True, tool_name=tool_name) try: archs = meta.getList() except ArchiveDownloadError as e: msg = f"Failed to locate XML data for the tool '{tool_name}'." raise ArchiveListError( msg, suggested_action=suggested_follow_up(meta)) from e else: archs = [args.tool_variant] for arch in archs: if not self._check_tools_arg_combination(os_name, tool_name, arch): self.logger.warning( "Specified target combination is not valid: {} {} {}". format(os_name, tool_name, arch)) tool_archives: ToolArchives = self.retry_on_bad_connection( lambda base_url: ToolArchives( os_name=os_name, tool_name=tool_name, target=target, base=base_url, version_str=version, arch=arch, timeout=timeout, ), base, ) run_installer(tool_archives.get_packages(), base_dir, sevenzip, keep) self.logger.info("Finished installation") self.logger.info("Time elapsed: {time:.8f} second".format( time=time.perf_counter() - start_time))
("android", "wasm", "6.1.9", qt6_android_requires_ext_msg), ), ) 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 mac_qt = ArchiveId("qt", "mac", "desktop") mac_wasm = ArchiveId("qt", "mac", "desktop", "wasm") wrong_tool_name_msg = "Please use 'aqt list-tool mac desktop' to check what tools are available." wrong_qt_version_msg = "Please use 'aqt list-qt mac desktop' to show versions of Qt available." wrong_ext_msg = "Please use 'aqt list-qt mac desktop --extensions <QT_VERSION>' to list valid extensions." wrong_arch_msg = "Please use 'aqt list-qt mac desktop --arch <QT_VERSION>' to list valid architectures." @pytest.mark.parametrize( "meta, expected_message", ( (MetadataFactory(mac_qt), []), ( MetadataFactory(mac_qt, spec=SimpleSpec("5.0")), [ "Please use 'aqt list-qt mac desktop' to check that versions of qt exist within the spec '5.0'."