JIRA: RHELCMP-12388
Signed-off-by: Aditya Bisoi <abisoi@redhat.com>
(cherry picked from commit b513c8cd00)
		
	
			
		
			
				
	
	
		
			529 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			529 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| 
 | |
| try:
 | |
|     import unittest2 as unittest
 | |
| except ImportError:
 | |
|     import unittest
 | |
| 
 | |
| import six
 | |
| from unittest import mock
 | |
| 
 | |
| from pungi import checks
 | |
| from tests.helpers import load_config, PKGSET_REPOS
 | |
| 
 | |
| 
 | |
| class ConfigTestCase(unittest.TestCase):
 | |
|     def assertValidation(self, cfg, errors=[], warnings=[]):
 | |
|         actual_errors, actual_warnings = checks.validate(cfg)
 | |
|         six.assertCountEqual(self, errors, actual_errors)
 | |
|         self.assertEqual(warnings, actual_warnings)
 | |
| 
 | |
| 
 | |
| class PkgsetConfigTestCase(ConfigTestCase):
 | |
|     def test_validate_minimal_pkgset_koji(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_validate_minimal_pkgset_repos(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="repos",
 | |
|             pkgset_repos={"x86_64": "/first", "ppc64": "/second"},
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_pkgset_mismatch_repos(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="repos",
 | |
|             pkgset_koji_tag="f25",
 | |
|             pkgset_koji_inherit=False,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 checks.REQUIRES.format("pkgset_source", "repos", "pkgset_repos"),
 | |
|                 checks.CONFLICTS.format("pkgset_source", "repos", "pkgset_koji_tag"),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "pkgset_source", "repos", "pkgset_koji_inherit"
 | |
|                 ),
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_pkgset_mismatch_koji(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_repos={"whatever": "/foo"},
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg, [checks.CONFLICTS.format("pkgset_source", "koji", "pkgset_repos")]
 | |
|         )
 | |
| 
 | |
|     def test_pkgset_multiple_koji_tags(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_koji_tag=["f25", "f25-extra"],
 | |
|             pkgset_koji_inherit=False,
 | |
|         )
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
| 
 | |
| class ReleaseConfigTestCase(ConfigTestCase):
 | |
|     def test_set_release_is_layered(self):
 | |
|         cfg = load_config(PKGSET_REPOS, release_is_layered=True)
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             warnings=[
 | |
|                 "WARNING: Config option release_is_layered was removed and has no effect; remove it. It's layered if there's configuration for base product."  # noqa: E501
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_only_config_base_product_name(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             base_product_name="Prod",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 checks.REQUIRES.format(
 | |
|                     "base_product_name", "Prod", "base_product_short"
 | |
|                 ),
 | |
|                 checks.REQUIRES.format(
 | |
|                     "base_product_name", "Prod", "base_product_version"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_short", None, "base_product_name"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_version", None, "base_product_name"
 | |
|                 ),
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_only_config_base_product_short(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             base_product_short="bp",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 checks.REQUIRES.format("base_product_short", "bp", "base_product_name"),
 | |
|                 checks.REQUIRES.format(
 | |
|                     "base_product_short", "bp", "base_product_version"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_name", None, "base_product_short"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_version", None, "base_product_short"
 | |
|                 ),
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_only_config_base_product_version(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             base_product_version="1.0",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 checks.REQUIRES.format(
 | |
|                     "base_product_version", "1.0", "base_product_name"
 | |
|                 ),
 | |
|                 checks.REQUIRES.format(
 | |
|                     "base_product_version", "1.0", "base_product_short"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_name", None, "base_product_version"
 | |
|                 ),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "base_product_short", None, "base_product_version"
 | |
|                 ),
 | |
|             ],
 | |
|         )
 | |
| 
 | |
| 
 | |
| class ImageNameConfigTestCase(ConfigTestCase):
 | |
|     def test_image_name_simple_string(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             image_name_format="foobar",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg, [])
 | |
| 
 | |
|     def test_image_name_variant_mapping(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             image_name_format={"^Server$": "foobar"},
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg, [])
 | |
| 
 | |
| 
 | |
| class RunrootConfigTestCase(ConfigTestCase):
 | |
|     def test_set_runroot_true(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             runroot=True,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             warnings=[
 | |
|                 "WARNING: Config option runroot was removed and has no effect; remove it. Please specify 'runroot_method' if you want to enable runroot, otherwise run things locally."  # noqa: E501
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_set_runroot_false(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             runroot=False,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             warnings=[
 | |
|                 "WARNING: Config option runroot was removed and has no effect; remove it. Please specify 'runroot_method' if you want to enable runroot, otherwise run things locally."  # noqa: E501
 | |
|             ],
 | |
|         )
 | |
| 
 | |
| 
 | |
| class BuildinstallConfigTestCase(ConfigTestCase):
 | |
|     def test_bootable_deprecated(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             bootable=True,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             warnings=[
 | |
|                 "WARNING: Config option bootable was removed and has no effect; remove it. Setting buildinstall_method option if you want a bootable installer."  # noqa: E501
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|     def test_buildinstall_method_without_bootable(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             buildinstall_method="lorax",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg, [])
 | |
| 
 | |
|     def test_lorax_with_lorax_options(self):
 | |
|         cfg = load_config(PKGSET_REPOS, buildinstall_method="lorax", lorax_options=[])
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_lorax_options_without_bootable_and_method(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             lorax_options=[("^Server$", {})],
 | |
|             buildinstall_kickstart="foo",
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 checks.CONFLICTS.format("buildinstall_method", "None", "lorax_options"),
 | |
|                 checks.CONFLICTS.format(
 | |
|                     "buildinstall_method", "None", "buildinstall_kickstart"
 | |
|                 ),
 | |
|             ],
 | |
|         )
 | |
| 
 | |
| 
 | |
| class CreaterepoConfigTestCase(ConfigTestCase):
 | |
|     def test_validate_minimal_pkgset_koji(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_koji_tag="f25",
 | |
|             product_id_allow_missing=True,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [checks.CONFLICTS.format("product_id", "None", "product_id_allow_missing")],
 | |
|         )
 | |
| 
 | |
| 
 | |
| class GatherConfigTestCase(ConfigTestCase):
 | |
|     def test_dnf_backend_is_default_on_py3(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_koji_tag="f27",
 | |
|         )
 | |
| 
 | |
|         with mock.patch("six.PY2", new=False):
 | |
|             self.assertValidation(cfg, [])
 | |
|         self.assertEqual(cfg["gather_backend"], "dnf")
 | |
| 
 | |
|     def test_yum_backend_is_default_on_py2(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_koji_tag="f27",
 | |
|         )
 | |
| 
 | |
|         with mock.patch("six.PY2", new=True):
 | |
|             self.assertValidation(cfg, [])
 | |
|         self.assertEqual(cfg["gather_backend"], "yum")
 | |
| 
 | |
|     def test_yum_backend_is_rejected_on_py3(self):
 | |
|         cfg = load_config(
 | |
|             pkgset_source="koji",
 | |
|             pkgset_koji_tag="f27",
 | |
|             gather_backend="yum",
 | |
|         )
 | |
| 
 | |
|         with mock.patch("six.PY2", new=False):
 | |
|             self.assertValidation(
 | |
|                 cfg,
 | |
|                 ["Failed validation in gather_backend: 'yum' is not one of ['dnf']"],
 | |
|             )
 | |
| 
 | |
| 
 | |
| class OSBSConfigTestCase(ConfigTestCase):
 | |
|     def test_validate(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             osbs={
 | |
|                 "^Server$": {
 | |
|                     "url": "http://example.com",
 | |
|                     "target": "f25-build",
 | |
|                     "git_branch": "f25",
 | |
|                 }
 | |
|             },
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_validate_bad_conf(self):
 | |
|         cfg = load_config(PKGSET_REPOS, osbs="yes please")
 | |
| 
 | |
|         self.assertNotEqual(checks.validate(cfg), ([], []))
 | |
| 
 | |
| 
 | |
| class OstreeConfigTestCase(ConfigTestCase):
 | |
|     def test_validate(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             ostree=[
 | |
|                 (
 | |
|                     "^Atomic$",
 | |
|                     {
 | |
|                         "x86_64": {
 | |
|                             "treefile": "fedora-atomic-docker-host.json",
 | |
|                             "config_url": "https://git.fedorahosted.org/git/fedora-atomic.git",  # noqa: E501
 | |
|                             "repo": "Everything",
 | |
|                             "ostree_repo": "/mnt/koji/compose/atomic/Rawhide/",
 | |
|                             "version": "!OSTREE_VERSION_FROM_LABEL_DATE_TYPE_RESPIN",
 | |
|                         }
 | |
|                     },
 | |
|                 )
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_validate_bad_conf(self):
 | |
|         cfg = load_config(PKGSET_REPOS, ostree="yes please")
 | |
| 
 | |
|         self.assertNotEqual(checks.validate(cfg), ([], []))
 | |
| 
 | |
| 
 | |
| class OstreeInstallerConfigTestCase(ConfigTestCase):
 | |
|     def test_validate(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             ostree_installer=[
 | |
|                 (
 | |
|                     "^Atomic$",
 | |
|                     {
 | |
|                         "x86_64": {
 | |
|                             "repo": "Everything",
 | |
|                             "release": None,
 | |
|                             "installpkgs": ["fedora-productimg-atomic"],
 | |
|                             "add_template": [
 | |
|                                 "/spin-kickstarts/atomic-installer/lorax-configure-repo.tmpl"  # noqa: E501
 | |
|                             ],
 | |
|                             "add_template_var": [
 | |
|                                 "ostree_osname=fedora-atomic",
 | |
|                                 "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
 | |
|                             ],
 | |
|                             "add_arch_template": [
 | |
|                                 "/spin-kickstarts/atomic-installer/lorax-embed-repo.tmpl"  # noqa: E501
 | |
|                             ],
 | |
|                             "rootfs_size": "3",
 | |
|                             "add_arch_template_var": [
 | |
|                                 "ostree_repo=https://kojipkgs.fedoraproject.org/compose/atomic/Rawhide/",  # noqa: E501
 | |
|                                 "ostree_osname=fedora-atomic",
 | |
|                                 "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
 | |
|                             ],
 | |
|                         }
 | |
|                     },
 | |
|                 )
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_validate_bad_conf(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             ostree_installer=[
 | |
|                 (
 | |
|                     "^Atomic$",
 | |
|                     {
 | |
|                         "x86_64": {
 | |
|                             "repo": "Everything",
 | |
|                             "release": None,
 | |
|                             "installpkgs": ["fedora-productimg-atomic"],
 | |
|                             "add_template": [
 | |
|                                 "/spin-kickstarts/atomic-installer/lorax-configure-repo.tmpl"  # noqa: E501
 | |
|                             ],
 | |
|                             "add_template_var": [
 | |
|                                 "ostree_osname=fedora-atomic",
 | |
|                                 "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
 | |
|                             ],
 | |
|                             "add_arch_template": 15,
 | |
|                             "add_arch_template_var": [
 | |
|                                 "ostree_repo=https://kojipkgs.fedoraproject.org/compose/atomic/Rawhide/",  # noqa: E501
 | |
|                                 "ostree_osname=fedora-atomic",
 | |
|                                 "ostree_ref=fedora-atomic/Rawhide/x86_64/docker-host",
 | |
|                             ],
 | |
|                         }
 | |
|                     },
 | |
|                 )
 | |
|             ],
 | |
|         )
 | |
| 
 | |
|         self.assertNotEqual(checks.validate(cfg), ([], []))
 | |
| 
 | |
| 
 | |
| class LiveMediaConfigTestCase(ConfigTestCase):
 | |
|     @mock.patch("pungi.util.resolve_git_url")
 | |
|     def test_global_config_validation(self, resolve_git_url):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             live_media_ksurl="git://example.com/repo.git#HEAD",
 | |
|             live_media_target="f24",
 | |
|             live_media_release="RRR",
 | |
|             live_media_version="Rawhide",
 | |
|         )
 | |
| 
 | |
|         resolve_git_url.side_effect = lambda x, _helper: x.replace("HEAD", "CAFE")
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
|         self.assertEqual(cfg["live_media_ksurl"], "git://example.com/repo.git#CAFE")
 | |
| 
 | |
|     def test_global_config_null_release(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             live_media_release=None,
 | |
|         )
 | |
| 
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
| 
 | |
| class TestSuggestions(ConfigTestCase):
 | |
|     def test_with_a_typo(self):
 | |
|         cfg = load_config(PKGSET_REPOS, product_pid=None)
 | |
| 
 | |
|         self.assertValidation(
 | |
|             cfg, [], [checks.UNKNOWN_SUGGEST.format("product_pid", "product_id")]
 | |
|         )
 | |
| 
 | |
| 
 | |
| class TestRegexValidation(ConfigTestCase):
 | |
|     def test_incorrect_regular_expression(self):
 | |
|         cfg = load_config(PKGSET_REPOS, multilib=[("^*$", {"*": []})])
 | |
| 
 | |
|         msg = "Failed validation in multilib.0.0: incorrect regular expression: nothing to repeat"  # noqa: E501
 | |
|         if six.PY3:
 | |
|             msg += " at position 1"
 | |
|         self.assertValidation(cfg, [msg], [])
 | |
| 
 | |
| 
 | |
| class RepoclosureTestCase(ConfigTestCase):
 | |
|     def test_invalid_backend(self):
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             repoclosure_backend="fnd",  # Intentionally with a typo
 | |
|         )
 | |
| 
 | |
|         options = ["yum", "dnf"] if six.PY2 else ["dnf"]
 | |
|         self.assertValidation(
 | |
|             cfg,
 | |
|             [
 | |
|                 "Failed validation in repoclosure_backend: 'fnd' is not one of %s"
 | |
|                 % options
 | |
|             ],
 | |
|         )
 | |
| 
 | |
| 
 | |
| class VariantAsLookasideTestCase(ConfigTestCase):
 | |
|     def test_empty(self):
 | |
|         variant_as_lookaside = []
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             variant_as_lookaside=variant_as_lookaside,
 | |
|         )
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_basic(self):
 | |
|         variant_as_lookaside = [
 | |
|             ("Client", "Base"),
 | |
|             ("Server", "Client"),
 | |
|             ("Everything", "Spin"),
 | |
|         ]
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             variant_as_lookaside=variant_as_lookaside,
 | |
|         )
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
| 
 | |
| class SkipPhasesTestCase(ConfigTestCase):
 | |
|     def test_empty(self):
 | |
|         skip_phases = []
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             skip_phases=skip_phases,
 | |
|         )
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_basic(self):
 | |
|         skip_phases = [
 | |
|             "buildinstall",
 | |
|             "gather",
 | |
|         ]
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             skip_phases=skip_phases,
 | |
|         )
 | |
|         self.assertValidation(cfg)
 | |
| 
 | |
|     def test_bad_phase_name(self):
 | |
|         skip_phases = [
 | |
|             "gather",
 | |
|             "non-existing-phase_name",
 | |
|         ]
 | |
|         cfg = load_config(
 | |
|             PKGSET_REPOS,
 | |
|             skip_phases=skip_phases,
 | |
|         )
 | |
|         self.assertNotEqual(checks.validate(cfg), ([], []))
 |