This patch exercises the functionality added to the Config class by defining a couple of pytest unit tests. The pytest script imports lcitool as a local module (which is far from ideal), but in order to do that, lcitool has to adopt the .py extension otherwise python refuses to import it, but then again, this patch is just to showcase the functionality. --- guests/{lcitool => lcitool.py} | 0 guests/requirements.txt | 2 + guests/test_config.py | 165 +++++++++++++++++++++++++++++++++ 3 files changed, 167 insertions(+) rename guests/{lcitool => lcitool.py} (100%) create mode 100644 guests/test_config.py diff --git a/guests/lcitool b/guests/lcitool.py similarity index 100% rename from guests/lcitool rename to guests/lcitool.py diff --git a/guests/requirements.txt b/guests/requirements.txt index 900cfd6..c2b8f2c 100644 --- a/guests/requirements.txt +++ b/guests/requirements.txt @@ -1,2 +1,4 @@ ansible jenkins-job-builder +pytest +mock diff --git a/guests/test_config.py b/guests/test_config.py new file mode 100644 index 0000000..09343cc --- /dev/null +++ b/guests/test_config.py @@ -0,0 +1,165 @@ +import os +import pytest +import yaml +from mock import patch +import lcitool + +empty_config = "" + +missing_mandatory_key = \ + """ + install: + flavor: test + """ + +empty_mandatory_key = \ + """ + install: + flavor: test + root_password: + """ + +empty_optional_key = \ + """ + install: + flavor: + root_password: foo + """ + +extra_key = \ + """ + install: + root_password: foo + bar: baz + """ + +empty_flavor = \ + """ + install: + root_password: foo + """ + +invalid_flavor = \ + """ + install: + flavor: bar + root_password: foo + """ + +invalid_value_type = \ + """ + install: + flavor: bar + root_password: + - let + - me + - in + """ + + +def Config_init_mock(self): + # load only the default config template here + base = lcitool.Util.get_base() + with open(os.path.join(base, "config.yaml"), "r") as fp: + self.values = yaml.safe_load(fp) + + +@pytest.fixture +def config(): + with patch.object(config, "__init__", Config_init_mock): + return lcitool.Config() + + +@pytest.mark.parametrize("yamlstr,_pass", [ + (empty_config, False), + (missing_mandatory_key, False), + (empty_mandatory_key, False), + (empty_optional_key, False), + (invalid_flavor, False), + (invalid_value_type, False), + (extra_key, True), + (empty_flavor, True), +]) +def test_config_validate(config, yamlstr, _pass): + user_config = yaml.safe_load(yamlstr) + + if _pass: + config._validate(user_config) + else: + with pytest.raises(Exception): + config._validate(user_config) + + +yaml_in1 = \ + """ + install: + root_password: foo + vcpus: 4 + """ + +dict_out1 = { + "install": { + "flavor": "test", + "root_password": "foo", + "virt_type": "kvm", + "arch": "x86_64", + "machine": "pc", + "cpu_model": "host-passthrough", + "vcpus": 4, + "memory_size": 2, + "disk_size": 15, + "storage_pool": "default", + "network": "default"}, + "gitlab": { + "url": "https://gitlab.com", + "runner_secret": None} +} + +yaml_in2 = \ + """ + install: + flavor: gitlab + root_password: foo + virt_type: qemu + arch: aarch64 + machine: q35 + cpu_model: host-passthrough + vcpus: 4 + memory_size: 4 + disk_size: 8 + storage_pool: foo + network: bar + gitlab: + url: https://example.com + runner_secret: foobar + """ + +dict_out2 = { + "install": { + "flavor": "gitlab", + "root_password": "foo", + "virt_type": "qemu", + "arch": "aarch64", + "machine": "q35", + "cpu_model": "host-passthrough", + "vcpus": 4, + "memory_size": 4, + "disk_size": 8, + "storage_pool": "foo", + "network": "bar"}, + "gitlab": { + "url": "https://example.com", + "runner_secret": "foobar"} +} + + +@pytest.mark.parametrize("yaml_in, dict_out", [ + (yaml_in1, dict_out1), + (yaml_in2, dict_out2) +]) +def test_compare_config_contents(config, yaml_in, dict_out): + parsed = yaml.safe_load(yaml_in) + + # fill in the default values + config._update(parsed) + assert config.values == dict_out -- 2.25.3