def test_keep_n_latest_modules():
    """Test keeping only the latest version of modulemd"""
    unit_1 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=100,
                     context="abcd",
                     arch="x86_64"),
        None,
    )

    unit_2 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=101,
                     context="abcd",
                     arch="x86_64"),
        None,
    )

    matcher = ModularMatcher(None, None)
    modules = [unit_1, unit_2]
    matcher._keep_n_latest_modules(modules)

    # there should only one modulemd
    assert len(modules) == 1
    # with the highest number of version
    assert modules.pop().version == 101
def test_get_modular_srpms_criteria(ubi_config):
    """Testing creation of criteria for srpms query"""
    matcher = ModularMatcher(None, ubi_config.modules)
    unit_1 = UbiUnit(
        RpmUnit(
            name="test",
            version="1.0",
            release="1",
            arch="x86_64",
            sourcerpm="test.x86_64.src.rpm",
        ),
        None,
    )
    unit_2 = UbiUnit(
        RpmUnit(
            name="test-debug",
            version="1.0",
            release="1",
            arch="i386",
            sourcerpm="test-debug.i386.src.rpm",
        ),
        None,
    )

    # we need to set up binary and debug rpms
    # the criteria are based on sourcerpm attr of those units
    matcher.binary_rpms = f_proxy(f_return(set([unit_1])))
    matcher.debug_rpms = f_proxy(f_return(set([unit_2])))

    criteria = matcher._get_srpms_criteria()
    # there should be 1 criteria created
    assert len(criteria) == 2
    # it should be instance of Criteria
    for crit in criteria:
        assert isinstance(crit, Criteria)
def test_vercmp_sort():
    """Tests all comparison methods for vercmp sort used for RPM packages comparison"""
    vercmp_klass = vercmp_sort()

    unit_1 = vercmp_klass(
        UbiUnit(
            RpmUnit(
                name="test",
                version="10",
                release="20",
                epoch="1",
                arch="x86_64",
            ),
            None,
        ))

    unit_2 = vercmp_klass(
        UbiUnit(
            RpmUnit(
                name="test",
                version="10",
                release="200",
                epoch="1",
                arch="x86_64",
            ),
            None,
        ))

    assert (unit_1 < unit_2) is True
    assert (unit_1 <= unit_2) is True
    assert (unit_1 == unit_2) is False
    assert (unit_1 >= unit_2) is False
    assert (unit_1 > unit_2) is False
    assert (unit_1 != unit_2) is True
def test_keep_n_latest_rpms():
    """Test keeping only the latest version of rpm"""
    unit_1 = UbiUnit(
        RpmUnit(
            name="test",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )

    unit_2 = UbiUnit(
        RpmUnit(
            name="test",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )

    matcher = RpmMatcher(None, None)
    rpms = [unit_1, unit_2]
    rpms.sort(key=vercmp_sort())
    matcher._keep_n_latest_rpms(rpms)

    # there should only one rpm
    assert len(rpms) == 1
    # with the highest number of version
    assert rpms[0].version == "11"
def test_keep_n_latest_rpms_multiple_arches():
    """Test keeping only the latest version of rpm for multiple arches"""

    unit_1 = UbiUnit(
        RpmUnit(
            name="test",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    unit_2 = UbiUnit(
        RpmUnit(
            name="test",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    unit_3 = UbiUnit(
        RpmUnit(
            name="test",
            version="10",
            release="20",
            arch="i686",
        ),
        None,
    )
    unit_4 = UbiUnit(
        RpmUnit(
            name="test",
            version="9",
            release="20",
            arch="i686",
        ),
        None,
    )

    matcher = RpmMatcher(None, None)
    rpms = [unit_1, unit_2, unit_3, unit_4]
    rpms.sort(key=vercmp_sort())
    matcher._keep_n_latest_rpms(rpms)

    # sort by version, the order after _keep_n_latest_rpms() is not guaranteed in this case
    rpms.sort(key=lambda x: x.version)

    # there should be 2 rpms
    assert len(rpms) == 2

    # i686 rpm goes with its highest version
    assert rpms[0].version == "10"
    assert rpms[0].arch == "i686"

    # x86_64 rpm goes with its highest version
    assert rpms[1].version == "11"
    assert rpms[1].arch == "x86_64"
def test_get_modular_rpms_criteria(ubi_config):
    """Test creation of criteria for rpms query"""
    matcher = ModularMatcher(None, ubi_config.modules)
    unit = UbiUnit(
        ModulemdUnit(
            name="test",
            stream="10",
            version=100,
            context="abcd",
            arch="x86_64",
            artifacts=[
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.src",
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
            ],
        ),
        None,
    )
    matcher.modules = f_proxy(f_return(set([unit])))
    criteria = matcher._get_modular_rpms_criteria()

    # there should be 1 criterium created - srpm is skipped
    assert len(criteria) == 1
    # it should be instance of Criteria
    for crit in criteria:
        assert isinstance(crit, Criteria)
def test_modular_rpms_filenames_per_profiles_missing_profile(ubi_config):
    """Test getting filename from module artifacts, request for non-existing profile in modulemd"""
    matcher = ModularMatcher(None, ubi_config.modules)
    unit = UbiUnit(
        ModulemdUnit(
            name="fake_name",
            stream="fake_stream",
            version=100,
            context="abcd",
            arch="x86_64",
            artifacts=[
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.src",
                "perl-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
                "bash-7:10.5-el6.x86_64",
                "bash-devel-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
            ],
            profiles={"another": ["bash"]},
        ),
        None,
    )
    modules = f_proxy(f_return(set([unit])))
    filenames = matcher._modular_rpms_filenames(modules)

    # all non-src pkgs are in result
    # this result is driven by ubi_config that force to use only profile called "test"
    # but we don't have this profile in the testing modulemd, so we take all non-src artifacts
    assert len(filenames) == 3
    assert filenames == set([
        "bash-10.5-el6.x86_64.rpm",
        "bash-devel-0.99.24-441.module+el8.3.0+6718+7f269185.x86_64.rpm",
        "perl-0.99.24-441.module+el8.3.0+6718+7f269185.x86_64.rpm",
    ])
def test_modular_rpms_filenames_per_profiles(ubi_config):
    """Test getting filename from module artifacts, limited by profiles"""
    matcher = ModularMatcher(None, ubi_config.modules)
    unit = UbiUnit(
        ModulemdUnit(
            name="fake_name",
            stream="fake_stream",
            version=100,
            context="abcd",
            arch="x86_64",
            artifacts=[
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.src",
                "perl-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
                "bash-7:10.5-el6.x86_64",
                "bash-devel-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
            ],
            profiles={
                "test": ["perl", "bash"],
                "another": ["bash"]
            },
        ),
        None,
    )
    modules = f_proxy(f_return(set([unit])))
    filenames = matcher._modular_rpms_filenames(modules)

    # only pkgs from test profile perl+bash should be in result
    # this result is driven also by ubi_config that force to use only profile called "test"
    assert len(filenames) == 2
    assert filenames == set([
        "bash-10.5-el6.x86_64.rpm",
        "perl-0.99.24-441.module+el8.3.0+6718+7f269185.x86_64.rpm",
    ])
def test_modular_rpms_filenames(ubi_config):
    """Test getting filename from module artifacts, srpms are skipped."""
    matcher = ModularMatcher(None, ubi_config.modules)
    unit = UbiUnit(
        ModulemdUnit(
            name="test",
            stream="10",
            version=100,
            context="abcd",
            arch="x86_64",
            artifacts=[
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.src",
                "perl-version-7:0.99.24-441.module+el8.3.0+6718+7f269185.x86_64",
            ],
        ),
        None,
    )

    modules = f_proxy(f_return(set([unit])))
    filenames = matcher._modular_rpms_filenames(modules)

    # there should be only 1 filename because srpms are skipped
    assert len(filenames) == 1
    assert (filenames.pop() ==
            "perl-version-0.99.24-441.module+el8.3.0+6718+7f269185.x86_64.rpm")
def test_keep_n_latest_modules_different_context():
    """Test keeping only the latest version of modulemds with the different context"""
    unit_1 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=100,
                     context="abcd",
                     arch="x86_64"),
        None,
    )

    unit_2 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=100,
                     context="xyz",
                     arch="x86_64"),
        None,
    )
    unit_3 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=99,
                     context="xyz",
                     arch="x86_64"),
        None,
    )

    matcher = ModularMatcher(None, None)
    modules = [unit_1, unit_2, unit_3]
    matcher._keep_n_latest_modules(modules)
    expected_contexts = ["abcd", "xyz"]

    # both of modulemd should be in result
    assert len(modules) == 2
    actual_contexts = []
    versions = set()
    for module in modules:
        actual_contexts.append(module.context)
        versions.add(module.version)
    # the should have different contexts
    assert sorted(actual_contexts) == expected_contexts
    # but only modules with the highest version are kept
    assert len(versions) == 1
    assert versions.pop() == 100
def test_get_modulemd_output_set():
    """Test creation of modulemd output set for ubipop"""
    unit_1 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=100,
                     context="abcd",
                     arch="x86_64"),
        None,
    )

    unit_2 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=101,
                     context="xyz",
                     arch="x86_64"),
        None,
    )

    unit_3 = UbiUnit(
        ModulemdUnit(name="test",
                     stream="20",
                     version=100,
                     context="xyz",
                     arch="x86_64"),
        None,
    )

    matcher = ModularMatcher(None, None)
    output_set = matcher._get_modulemd_output_set([unit_1, unit_2, unit_3])

    assert isinstance(output_set, list)
    # In output_set, we should have only the latest version of modulemds
    # of the same name and stream
    assert sorted(output_set, key=attrgetter("_unit")) == [unit_2, unit_3]
def test_ubi_unit():
    """Test proper wrapping *Unit classes of pulplib and access of their attrs"""
    unit = RpmUnit(name="test", version="1.0", release="1", arch="x86_64")

    repo_id = "test_repo_id"
    ubi_unit = UbiUnit(unit, repo_id)

    # we can directly access attrs of RpmUnit
    assert ubi_unit.name == "test"
    assert ubi_unit.version == "1.0"
    assert ubi_unit.release == "1"
    assert ubi_unit.arch == "x86_64"
    assert ubi_unit.associate_source_repo_id == repo_id

    # non-existing attr will raise an error
    with pytest.raises(AttributeError):
        _ = ubi_unit.non_existing_attr
def test_flatten_md_defaults_name_profiles():
    unit = UbiUnit(
        ModulemdDefaultsUnit(
            name="test",
            stream="foo",
            profiles={
                "rhel": ["common", "uncommon"],
                "fedora": ["super", "ultra"]
            },
            repo_id="foo-repo",
        ),
        "foo-repo",
    )

    out = flatten_md_defaults_name_profiles(unit)

    assert out == "test:[fedora:super,ultra]:[rhel:common,uncommon]"
def test_get_modulemd_defaults_criteria():
    """Test proper creation of criteria for modulemd_defaults query"""
    matcher = ModularMatcher(None, None)
    unit = UbiUnit(
        ModulemdUnit(name="test",
                     stream="10",
                     version=100,
                     context="abcd",
                     arch="x86_64"),
        None,
    )
    matcher.modules = [unit]
    criteria = matcher._get_modulemd_defaults_criteria()
    # there should be 1 criterium created based on modules list of Matcher obj.
    assert len(criteria) == 1
    # it should be instance of Criteria
    for crit in criteria:
        assert isinstance(crit, Criteria)
def _get_test_unit(klass, **kwargs):
    repo_id = kwargs.pop("src_repo_id")
    return UbiUnit(klass(**kwargs), repo_id)
def test_get_rpm_output_set_include_modular_and_all_versions(ubi_config):
    """tests getting rpm output set from RpmMatcher, modular packages included
    as well as all version of given package, only blacklist is applied"""
    matcher = RpmMatcher(None, ubi_config)
    # This unit will be in the output set - we allow all versions
    unit_1 = UbiUnit(
        RpmUnit(
            name="test",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one will be excluded using blacklist
    unit_2 = UbiUnit(
        RpmUnit(
            name="excluded_with_globbing123456789",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one will be excluded using blacklist
    unit_3 = UbiUnit(
        RpmUnit(
            name="excluded_package",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this is another unit that will be in the output set
    unit_4 = UbiUnit(
        RpmUnit(
            name="test",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one is included, we don't exclude modular packages this time
    unit_5 = UbiUnit(
        RpmUnit(
            name="modular_package",
            version="12",
            release="20",
            arch="x86_64",
            filename="modular_package.rpm",
        ),
        None,
    )

    rpms = [unit_1, unit_2, unit_3, unit_4, unit_5]
    output = matcher._get_rpm_output_set(rpms,
                                         modular_rpm_filenames=None,
                                         keep_all_versions=True)

    # in the output set there should be three units
    assert len(output) == 3
    # let's sort the output, order is not guranteed
    output.sort(key=lambda x: x.version)

    assert output[0].name == "test"
    assert output[0].version == "10"

    assert output[1].name == "test"
    assert output[1].version == "11"

    assert output[2].name == "modular_package"
    assert output[2].version == "12"
def test_get_rpm_output_set(ubi_config):
    """tests getting rpm output set from RpmMatcher"""
    matcher = RpmMatcher(None, ubi_config)
    # this unit won't be in output set, there is a newver one - unit_4 with higher version
    unit_1 = UbiUnit(
        RpmUnit(
            name="test",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one will be excluded using blacklist
    unit_2 = UbiUnit(
        RpmUnit(
            name="excluded_with_globbing123456789",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one will be excluded using blacklist
    unit_3 = UbiUnit(
        RpmUnit(
            name="excluded_package",
            version="10",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this it the only one that will in output set
    unit_4 = UbiUnit(
        RpmUnit(
            name="test",
            version="11",
            release="20",
            arch="x86_64",
        ),
        None,
    )
    # this one is excluded because it's a modular package
    unit_5 = UbiUnit(
        RpmUnit(
            name="modular_package",
            version="10",
            release="20",
            arch="x86_64",
            filename="modular_package.rpm",
        ),
        None,
    )

    modular_pkgs_filenames = f_proxy(f_return(set(["modular_package.rpm"])))
    rpms = [unit_1, unit_2, unit_3, unit_4, unit_5]
    output = matcher._get_rpm_output_set(rpms, modular_pkgs_filenames)

    # in the output set there is only one unit, according to the rules
    assert len(output) == 1
    assert output[0].name == "test"
    assert output[0].version == "11"