diff options
Diffstat (limited to 'tests/unittests/config/test_cc_zypper_add_repo.py')
-rw-r--r-- | tests/unittests/config/test_cc_zypper_add_repo.py | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/tests/unittests/config/test_cc_zypper_add_repo.py b/tests/unittests/config/test_cc_zypper_add_repo.py new file mode 100644 index 00000000..4304fee1 --- /dev/null +++ b/tests/unittests/config/test_cc_zypper_add_repo.py @@ -0,0 +1,223 @@ +# This file is part of cloud-init. See LICENSE file for license information. + +import configparser +import glob +import logging +import os + +from cloudinit import util +from cloudinit.config import cc_zypper_add_repo +from tests.unittests import helpers +from tests.unittests.helpers import mock + +LOG = logging.getLogger(__name__) + + +class TestConfig(helpers.FilesystemMockingTestCase): + def setUp(self): + super(TestConfig, self).setUp() + self.tmp = self.tmp_dir() + self.zypp_conf = "etc/zypp/zypp.conf" + + def test_bad_repo_config(self): + """Config has no baseurl, no file should be written""" + cfg = { + "repos": [ + {"id": "foo", "name": "suse-test", "enabled": "1"}, + ] + } + self.patchUtils(self.tmp) + cc_zypper_add_repo._write_repos(cfg["repos"], "/etc/zypp/repos.d") + self.assertRaises( + IOError, util.load_file, "/etc/zypp/repos.d/foo.repo" + ) + + def test_write_repos(self): + """Verify valid repos get written""" + cfg = self._get_base_config_repos() + root_d = self.tmp_dir() + cc_zypper_add_repo._write_repos(cfg["zypper"]["repos"], root_d) + repos = glob.glob("%s/*.repo" % root_d) + expected_repos = ["testing-foo.repo", "testing-bar.repo"] + if len(repos) != 2: + assert 'Number of repos written is "%d" expected 2' % len(repos) + for repo in repos: + repo_name = os.path.basename(repo) + if repo_name not in expected_repos: + assert 'Found repo with name "%s"; unexpected' % repo_name + # Validation that the content gets properly written is in another test + + def test_write_repo(self): + """Verify the content of a repo file""" + cfg = { + "repos": [ + { + "baseurl": "http://foo", + "name": "test-foo", + "id": "testing-foo", + }, + ] + } + root_d = self.tmp_dir() + cc_zypper_add_repo._write_repos(cfg["repos"], root_d) + contents = util.load_file("%s/testing-foo.repo" % root_d) + parser = configparser.ConfigParser() + parser.read_string(contents) + expected = { + "testing-foo": { + "name": "test-foo", + "baseurl": "http://foo", + "enabled": "1", + "autorefresh": "1", + } + } + for section in expected: + self.assertTrue( + parser.has_section(section), + "Contains section {0}".format(section), + ) + for k, v in expected[section].items(): + self.assertEqual(parser.get(section, k), v) + + def test_config_write(self): + """Write valid configuration data""" + cfg = {"config": {"download.deltarpm": "False", "reposdir": "foo"}} + root_d = self.tmp_dir() + helpers.populate_dir(root_d, {self.zypp_conf: "# Zypp config\n"}) + self.reRoot(root_d) + cc_zypper_add_repo._write_zypp_config(cfg["config"]) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + expected = [ + "# Zypp config", + "# Added via cloud.cfg", + "download.deltarpm=False", + "reposdir=foo", + ] + for item in contents.split("\n"): + if item not in expected: + self.assertIsNone(item) + + @mock.patch("cloudinit.log.logging") + def test_config_write_skip_configdir(self, mock_logging): + """Write configuration but skip writing 'configdir' setting""" + cfg = { + "config": { + "download.deltarpm": "False", + "reposdir": "foo", + "configdir": "bar", + } + } + root_d = self.tmp_dir() + helpers.populate_dir(root_d, {self.zypp_conf: "# Zypp config\n"}) + self.reRoot(root_d) + cc_zypper_add_repo._write_zypp_config(cfg["config"]) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + expected = [ + "# Zypp config", + "# Added via cloud.cfg", + "download.deltarpm=False", + "reposdir=foo", + ] + for item in contents.split("\n"): + if item not in expected: + self.assertIsNone(item) + # Not finding teh right path for mocking :( + # assert mock_logging.warning.called + + def test_empty_config_section_no_new_data(self): + """When the config section is empty no new data should be written to + zypp.conf""" + cfg = self._get_base_config_repos() + cfg["zypper"]["config"] = None + root_d = self.tmp_dir() + helpers.populate_dir(root_d, {self.zypp_conf: "# No data"}) + self.reRoot(root_d) + cc_zypper_add_repo._write_zypp_config(cfg.get("config", {})) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + self.assertEqual(contents, "# No data") + + def test_empty_config_value_no_new_data(self): + """When the config section is not empty but there are no values + no new data should be written to zypp.conf""" + cfg = self._get_base_config_repos() + cfg["zypper"]["config"] = {"download.deltarpm": None} + root_d = self.tmp_dir() + helpers.populate_dir(root_d, {self.zypp_conf: "# No data"}) + self.reRoot(root_d) + cc_zypper_add_repo._write_zypp_config(cfg.get("config", {})) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + self.assertEqual(contents, "# No data") + + def test_handler_full_setup(self): + """Test that the handler ends up calling the renderers""" + cfg = self._get_base_config_repos() + cfg["zypper"]["config"] = { + "download.deltarpm": "False", + } + root_d = self.tmp_dir() + os.makedirs("%s/etc/zypp/repos.d" % root_d) + helpers.populate_dir(root_d, {self.zypp_conf: "# Zypp config\n"}) + self.reRoot(root_d) + cc_zypper_add_repo.handle("zypper_add_repo", cfg, None, LOG, []) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + expected = [ + "# Zypp config", + "# Added via cloud.cfg", + "download.deltarpm=False", + ] + for item in contents.split("\n"): + if item not in expected: + self.assertIsNone(item) + repos = glob.glob("%s/etc/zypp/repos.d/*.repo" % root_d) + expected_repos = ["testing-foo.repo", "testing-bar.repo"] + if len(repos) != 2: + assert 'Number of repos written is "%d" expected 2' % len(repos) + for repo in repos: + repo_name = os.path.basename(repo) + if repo_name not in expected_repos: + assert 'Found repo with name "%s"; unexpected' % repo_name + + def test_no_config_section_no_new_data(self): + """When there is no config section no new data should be written to + zypp.conf""" + cfg = self._get_base_config_repos() + root_d = self.tmp_dir() + helpers.populate_dir(root_d, {self.zypp_conf: "# No data"}) + self.reRoot(root_d) + cc_zypper_add_repo._write_zypp_config(cfg.get("config", {})) + cfg_out = os.path.join(root_d, self.zypp_conf) + contents = util.load_file(cfg_out) + self.assertEqual(contents, "# No data") + + def test_no_repo_data(self): + """When there is no repo data nothing should happen""" + root_d = self.tmp_dir() + self.reRoot(root_d) + cc_zypper_add_repo._write_repos(None, root_d) + content = glob.glob("%s/*" % root_d) + self.assertEqual(len(content), 0) + + def _get_base_config_repos(self): + """Basic valid repo configuration""" + cfg = { + "zypper": { + "repos": [ + { + "baseurl": "http://foo", + "name": "test-foo", + "id": "testing-foo", + }, + { + "baseurl": "http://bar", + "name": "test-bar", + "id": "testing-bar", + }, + ] + } + } + return cfg |