summaryrefslogtreecommitdiffstats
path: root/tests/test_packager_provided_files.py
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-26 06:32:43 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-26 06:32:43 +0000
commiteb24e936acc4949d79f6c25fabb138eaed87d8af (patch)
treea496d901f1bc835285ac9d1561b1afbfbd3fab38 /tests/test_packager_provided_files.py
parentAdding debian version 0.1.37. (diff)
downloaddebputy-eb24e936acc4949d79f6c25fabb138eaed87d8af.tar.xz
debputy-eb24e936acc4949d79f6c25fabb138eaed87d8af.zip
Merging upstream version 0.1.38.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/test_packager_provided_files.py')
-rw-r--r--tests/test_packager_provided_files.py416
1 files changed, 415 insertions, 1 deletions
diff --git a/tests/test_packager_provided_files.py b/tests/test_packager_provided_files.py
index b0e075f..caf4bd1 100644
--- a/tests/test_packager_provided_files.py
+++ b/tests/test_packager_provided_files.py
@@ -1,11 +1,17 @@
+import os
import random
-from typing import cast, TYPE_CHECKING
+from typing import cast, TYPE_CHECKING, Sequence, Optional, Mapping
import pytest
from debputy.packager_provided_files import detect_all_packager_provided_files
from debputy.plugin.api import DebputyPluginInitializer
from debputy.plugin.api.feature_set import PluginProvidedFeatureSet
+from debputy.plugin.api.impl import plugin_metadata_for_debputys_own_plugin
+from debputy.plugin.api.impl_types import (
+ PackagerProvidedFileClassSpec,
+ DebputyPluginMetadata,
+)
from debputy.plugin.api.test_api import (
InitializedPluginUnderTest,
build_virtual_file_system,
@@ -13,6 +19,7 @@ from debputy.plugin.api.test_api import (
from debputy.plugin.api.test_api.test_impl import (
initialize_plugin_under_test_preloaded,
)
+from lint_tests.lint_tutil import requires_levenshtein
from tutil import faked_binary_package, binary_package_table
if TYPE_CHECKING:
@@ -210,9 +217,416 @@ def test_packager_provided_files_priority(
assert expected_basename == matched.path.name
+@pytest.mark.parametrize(
+ "main_package,secondary_package",
+ [
+ ("foo", "foo-doc"),
+ ("foo.bar", "foo.bar-doc"),
+ ],
+)
+def test_detect_ppf_simple(main_package: str, secondary_package: str) -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package(main_package, is_main_package=True),
+ faked_binary_package(secondary_package),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "install",
+ f"{secondary_package}.install",
+ f"{main_package}.docs",
+ f"{secondary_package}.docs",
+ "copyright",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "install",
+ ),
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "docs",
+ ),
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "copyright",
+ packageless_is_fallback_for_all_packages=True,
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ )
+ assert main_package in results
+ main_matches = results[main_package].auto_installable
+ assert {m.path.name for m in main_matches} == {
+ "install",
+ f"{main_package}.docs",
+ "copyright",
+ }
+
+ assert secondary_package in results
+ sec_matches = results[secondary_package].auto_installable
+ expected = {
+ f"{secondary_package}.install",
+ f"{secondary_package}.docs",
+ "copyright",
+ }
+ assert {m.path.name for m in sec_matches} == expected
+
+
+def test_detect_ppf_name_segment() -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package("foo", is_main_package=True),
+ faked_binary_package("bar"),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "fuu.install",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "install",
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {
+ "fuu.install",
+ }
+ foo_install = foo_matches[0]
+ assert foo_install.name_segment == "fuu"
+ assert foo_install.package_name == "foo"
+ assert foo_install.architecture_restriction is None
+ assert not foo_install.fuzzy_match
+
+ assert "bar" in results
+ assert not results["bar"].auto_installable
+
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "install",
+ allow_name_segment=False,
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ allow_fuzzy_matches=True,
+ )
+
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"fuu.install"}
+ foo_install = foo_matches[0]
+ assert foo_install.name_segment == "fuu"
+ assert foo_install.package_name == "foo"
+ assert foo_install.architecture_restriction is None
+
+ assert "bar" in results
+ assert not results["bar"].auto_installable
+
+
+def test_detect_ppf_fuzzy_match_bug_950723() -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package("foo", is_main_package=True),
+ faked_binary_package("bar"),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "bar.service",
+ "foo@.service",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "service",
+ bug_950723=True,
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"foo@.service"}
+ foo_at_service = foo_matches[0]
+ # Without bug#950723 AND fuzzy_match, it counts a name segment for the main package.
+ assert foo_at_service.name_segment == "foo@"
+ assert foo_at_service.package_name == "foo"
+ assert foo_at_service.architecture_restriction is None
+ assert not foo_at_service.fuzzy_match
+
+ assert "bar" in results
+ bar_matches = results["bar"].auto_installable
+ assert {m.path.name for m in bar_matches} == {"bar.service"}
+ bar_service = bar_matches[0]
+ assert bar_service.name_segment is None
+ assert bar_service.package_name == "bar"
+ assert bar_service.architecture_restriction is None
+ assert not bar_service.fuzzy_match
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ allow_fuzzy_matches=True,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"foo@.service"}
+ foo_at_service = foo_matches[0]
+ assert foo_at_service.name_segment is None
+ assert foo_at_service.package_name == "foo"
+ assert foo_at_service.architecture_restriction is None
+
+ assert "bar" in results
+ bar_matches = results["bar"].auto_installable
+ assert {m.path.name for m in bar_matches} == {"bar.service"}
+ bar_service = bar_matches[0]
+ assert bar_service.name_segment is None
+ assert bar_service.package_name == "bar"
+ assert bar_service.architecture_restriction is None
+ assert not bar_service.fuzzy_match
+
+
+@requires_levenshtein
+def test_detect_ppf_typo() -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package("foo", is_main_package=True),
+ faked_binary_package("bar"),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "fuu.install",
+ "bar.intsall",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "install",
+ ),
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "logcheck.violations.d",
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ detect_typos=True,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"fuu.install"}
+ foo_logcheck = foo_matches[0]
+ # Not a typo due to how name segments works with debhelper compat <= 13
+ # (but should probably have been one.
+ assert foo_logcheck.name_segment == "fuu"
+ assert foo_logcheck.package_name == "foo"
+ assert foo_logcheck.architecture_restriction is None
+
+ assert "bar" in results
+ bar_matches = results["bar"].auto_installable
+ assert {m.path.name for m in bar_matches} == {"bar.intsall"}
+ bar_logcheck = bar_matches[0]
+ assert os.path.basename(bar_logcheck.expected_path) == "bar.install"
+ assert bar_logcheck.name_segment is None
+ assert bar_logcheck.package_name == "bar"
+ assert bar_logcheck.architecture_restriction is None
+
+ debian_dir = build_virtual_file_system(
+ [
+ # Typo'ed by intention
+ "logchcek.violations.d",
+ "bar.logchcek.violations.d",
+ ]
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ detect_typos=True,
+ )
+
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"logchcek.violations.d"}
+ foo_logcheck = foo_matches[0]
+ assert foo_logcheck.name_segment is None
+ assert foo_logcheck.package_name == "foo"
+ assert foo_logcheck.architecture_restriction is None
+ assert os.path.basename(foo_logcheck.expected_path) == "logcheck.violations.d"
+
+ assert "bar" in results
+ bar_matches = results["bar"].auto_installable
+ assert {m.path.name for m in bar_matches} == {
+ "bar.logchcek.violations.d",
+ }
+ bar_logcheck = bar_matches[0]
+ assert bar_logcheck.name_segment is None
+ assert bar_logcheck.package_name == "bar"
+ assert bar_logcheck.architecture_restriction is None
+ assert os.path.basename(bar_logcheck.expected_path) == "bar.logcheck.violations.d"
+
+
+def test_debhelper_overlapping_stems() -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package("foo", is_main_package=True),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "foo.user.service",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "service",
+ ),
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "user.service",
+ ),
+ )
+
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {
+ "foo.user.service",
+ }
+ matched_file = foo_matches[0]
+ assert matched_file.definition.stem == "user.service"
+ assert matched_file.name_segment is None
+ assert matched_file.package_name == "foo"
+ assert matched_file.architecture_restriction is None
+
+ debian_dir = build_virtual_file_system(
+ [
+ "foo.named.service",
+ ]
+ )
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"foo.named.service"}
+ matched_file = foo_matches[0]
+ assert matched_file.definition.stem == "service"
+ assert matched_file.name_segment == "named"
+ assert matched_file.package_name == "foo"
+ assert matched_file.architecture_restriction is None
+
+
+@requires_levenshtein
+def test_debhelper_overlapping_stems_typo_check() -> None:
+ plugin_metadata = plugin_metadata_for_debputys_own_plugin()
+ binary_packages = binary_package_table(
+ faked_binary_package("foo", is_main_package=True),
+ )
+ debian_dir = build_virtual_file_system(
+ [
+ "foo.uxxr.service",
+ ]
+ )
+ ppf_defs = _ppfs(
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "service",
+ ),
+ _fake_PPFClassSpec(
+ plugin_metadata,
+ "user.service",
+ ),
+ )
+ results = detect_all_packager_provided_files(
+ ppf_defs,
+ debian_dir,
+ binary_packages,
+ detect_typos=True,
+ )
+ assert "foo" in results
+ foo_matches = results["foo"].auto_installable
+ assert {m.path.name for m in foo_matches} == {"foo.uxxr.service"}
+ foo_install = foo_matches[0]
+ # While it could just as well be a named segment, we assume it is a typo.
+ assert foo_install.definition.stem == "user.service"
+ assert foo_install.name_segment is None
+ assert foo_install.package_name == "foo"
+ assert foo_install.architecture_restriction is None
+ assert os.path.basename(foo_install.expected_path) == "foo.user.service"
+
+
def _fetch_debputy_plugin_feature_set(
plugin: InitializedPluginUnderTest,
) -> PluginProvidedFeatureSet:
# Very much not public API, but we need it to avoid testing on production data (also, it is hard to find
# relevant debputy files for all the cases we want to test).
return cast("InitializedPluginUnderTestImpl", plugin)._feature_set
+
+
+def _fake_PPFClassSpec(
+ debputy_plugin_metadata: DebputyPluginMetadata,
+ stem: str,
+ *,
+ default_priority: Optional[int] = None,
+ packageless_is_fallback_for_all_packages: bool = False,
+ bug_950723: bool = False,
+ has_active_command: bool = False,
+ allow_name_segment: bool = True,
+) -> PackagerProvidedFileClassSpec:
+ return PackagerProvidedFileClassSpec(
+ debputy_plugin_metadata,
+ stem,
+ "not-a-real-ppf",
+ allow_architecture_segment=True,
+ allow_name_segment=allow_name_segment,
+ default_priority=default_priority,
+ default_mode=0o644,
+ post_formatting_rewrite=None,
+ packageless_is_fallback_for_all_packages=packageless_is_fallback_for_all_packages,
+ reservation_only=False,
+ formatting_callback=None,
+ bug_950723=bug_950723,
+ has_active_command=has_active_command,
+ )
+
+
+def _ppfs(
+ *ppfs: PackagerProvidedFileClassSpec,
+) -> Mapping[str, PackagerProvidedFileClassSpec]:
+ return {ppf.stem: ppf for ppf in ppfs}