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)
+
+
+(a)pytest.fixture
+def config():
+ with patch.object(config, "__init__", Config_init_mock):
+ return lcitool.Config()
+
+
+(a)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"}
+}
+
+
+(a)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