From 40b0b4e5c2927e002c5a3142f5283804036739c9 Mon Sep 17 00:00:00 2001 From: Christian Kellner Date: Tue, 19 Jan 2021 13:32:26 +0000 Subject: [PATCH] test: extract format specific tests Move the format specific tests, i.e. the ones that test the format description itself, to a new test_fmt_v1.py file. --- test/mod/test_fmt_v1.py | 180 +++++++++++++++++++++++++++++++++++++++ test/mod/test_osbuild.py | 166 ------------------------------------ 2 files changed, 180 insertions(+), 166 deletions(-) create mode 100644 test/mod/test_fmt_v1.py diff --git a/test/mod/test_fmt_v1.py b/test/mod/test_fmt_v1.py new file mode 100644 index 00000000..50b4b93a --- /dev/null +++ b/test/mod/test_fmt_v1.py @@ -0,0 +1,180 @@ +# +# Tests specific for version 1 of the format +# + +import os +import unittest + +import osbuild +import osbuild.meta +from osbuild.formats import v1 as fmt + + +class TestFormatV1(unittest.TestCase): + + def test_canonical(self): + """Degenerate case. Make sure we always return the same canonical + description when passing empty or null values.""" + + index = osbuild.meta.Index(os.curdir) + + cases = [ + {}, + {"assembler": None}, + {"stages": []}, + {"build": {}}, + {"build": None} + ] + + for pipeline in cases: + manifest = {"pipeline": pipeline} + with self.subTest(pipeline): + desc = fmt.describe(fmt.load(manifest, index)) + self.assertEqual(desc["pipeline"], {}) + + def test_pipeline(self): + index = osbuild.meta.Index(os.curdir) + + test_info = index.get_module_info("Stage", "org.osbuild.test") + build = osbuild.Pipeline("org.osbuild.test") + build.add_stage(test_info, {"one": 1}) + + pipeline = osbuild.Pipeline("org.osbuild.test", build.tree_id) + pipeline.add_stage(test_info, {"one": 2}) + info = index.get_module_info("Assembler", "org.osbuild.noop") + pipeline.set_assembler(info) + + manifest = osbuild.Manifest([build, pipeline], {}) + + self.assertEqual(fmt.describe(manifest), { + "pipeline": { + "build": { + "pipeline": { + "stages": [ + { + "name": "org.osbuild.test", + "options": {"one": 1} + } + ] + }, + "runner": "org.osbuild.test" + }, + "stages": [ + { + "name": "org.osbuild.test", + "options": {"one": 2} + } + ], + "assembler": { + "name": "org.osbuild.noop" + } + } + }) + + def test_validation(self): + index = osbuild.meta.Index(os.curdir) + + # an empty manifest is OK + res = fmt.validate({}, index) + self.assertEqual(res.valid, True) + + # something totally invalid (by Ondřej Budai) + totally_invalid = { + "osbuild": { + "state": "awesome", + "but": { + "input-validation": 1 + } + } + } + + res = fmt.validate(totally_invalid, index) + self.assertEqual(res.valid, False) + # The top-level 'osbuild' is an additional property + self.assertEqual(len(res), 1) + + # This is missing the runner + no_runner = { + "pipeline": { + "build": { + "pipeline": {} + } + } + } + + res = fmt.validate(no_runner, index) + self.assertEqual(res.valid, False) + self.assertEqual(len(res), 1) # missing runner + lst = res[".pipeline.build"] + self.assertEqual(len(lst), 1) + + # de-dup issues: the manifest checking will report + # the extra element and the recursive build pipeline + # check will also report that same error; make sure + # they get properly de-duplicated + no_runner_extra = { + "pipeline": { + "build": { # missing runner + "pipeline": { + "extra": True, # should not be there + "stages": [{ + "name": "org.osbuild.chrony", + "options": { + "timeservers": "string" # should be an array + } + }] + } + } + } + } + + res = fmt.validate(no_runner_extra, index) + self.assertEqual(res.valid, False) + self.assertEqual(len(res), 3) + lst = res[".pipeline.build.pipeline"] + self.assertEqual(len(lst), 1) # should only have one + lst = res[".pipeline.build.pipeline.stages[0].options.timeservers"] + self.assertEqual(len(lst), 1) # should only have one + + # stage issues + stage_check = { + "pipeline": { + "stages": [{ + "name": "org.osbuild.grub2", + "options": { + "uefi": { + "install": False, + # missing "vendor" + }, + # missing rootfs or root_fs_uuid + } + }] + } + } + + res = fmt.validate(stage_check, index) + self.assertEqual(res.valid, False) + self.assertEqual(len(res), 2) + lst = res[".pipeline.stages[0].options"] + self.assertEqual(len(lst), 1) # missing rootfs + lst = res[".pipeline.stages[0].options.uefi"] + self.assertEqual(len(lst), 1) # missing "osname" + + assembler_check = { + "pipeline": { + "assembler": { + "name": "org.osbuild.tar", + "options": { + "compression": "foobar" + } + } + } + } + + res = fmt.validate(assembler_check, index) + self.assertEqual(res.valid, False) + self.assertEqual(len(res), 2) + lst = res[".pipeline.assembler.options"] + self.assertEqual(len(lst), 1) # missing "filename" + lst = res[".pipeline.assembler.options.compression"] + self.assertEqual(len(lst), 1) # wrong compression method diff --git a/test/mod/test_osbuild.py b/test/mod/test_osbuild.py index b1db3757..6dc64427 100644 --- a/test/mod/test_osbuild.py +++ b/test/mod/test_osbuild.py @@ -11,7 +11,6 @@ import unittest import osbuild import osbuild.meta -from osbuild.formats import v1 as fmt from osbuild.monitor import NullMonitor from osbuild.objectstore import ObjectStore from osbuild.pipeline import detect_host_runner @@ -19,24 +18,6 @@ from .. import test class TestDescriptions(unittest.TestCase): - def test_canonical(self): - """Degenerate case. Make sure we always return the same canonical - description when passing empty or null values.""" - - index = osbuild.meta.Index(os.curdir) - - cases = [ - {}, - {"assembler": None}, - {"stages": []}, - {"build": {}}, - {"build": None} - ] - for pipeline in cases: - manifest = {"pipeline": pipeline} - with self.subTest(pipeline): - desc = fmt.describe(fmt.load(manifest, index)) - self.assertEqual(desc["pipeline"], {}) @unittest.skipUnless(test.TestBase.can_bind_mount(), "root-only") def test_stage_run(self): @@ -60,45 +41,6 @@ class TestDescriptions(unittest.TestCase): self.assertEqual(res.success, True) self.assertEqual(res.id, stage.id) - def test_pipeline(self): - index = osbuild.meta.Index(os.curdir) - - test_info = index.get_module_info("Stage", "org.osbuild.test") - build = osbuild.Pipeline("org.osbuild.test") - build.add_stage(test_info, {"one": 1}) - - pipeline = osbuild.Pipeline("org.osbuild.test", build.tree_id) - pipeline.add_stage(test_info, {"one": 2}) - info = index.get_module_info("Assembler", "org.osbuild.noop") - pipeline.set_assembler(info) - - manifest = osbuild.Manifest([build, pipeline], {}) - - self.assertEqual(fmt.describe(manifest), { - "pipeline": { - "build": { - "pipeline": { - "stages": [ - { - "name": "org.osbuild.test", - "options": {"one": 1} - } - ] - }, - "runner": "org.osbuild.test" - }, - "stages": [ - { - "name": "org.osbuild.test", - "options": {"one": 2} - } - ], - "assembler": { - "name": "org.osbuild.noop" - } - } - }) - def test_moduleinfo(self): index = osbuild.meta.Index(os.curdir) @@ -138,111 +80,3 @@ class TestDescriptions(unittest.TestCase): self.assertFalse(res) res = schema.validate([1, 2, 3]) self.assertTrue(res) - - def test_validation(self): - index = osbuild.meta.Index(os.curdir) - - # an empty manifest is OK - res = fmt.validate({}, index) - self.assertEqual(res.valid, True) - - # something totally invalid (by Ondřej Budai) - totally_invalid = { - "osbuild": { - "state": "awesome", - "but": { - "input-validation": 1 - } - } - } - - res = fmt.validate(totally_invalid, index) - self.assertEqual(res.valid, False) - # The top-level 'osbuild' is an additional property - self.assertEqual(len(res), 1) - - # This is missing the runner - no_runner = { - "pipeline": { - "build": { - "pipeline": {} - } - } - } - - res = fmt.validate(no_runner, index) - self.assertEqual(res.valid, False) - self.assertEqual(len(res), 1) # missing runner - lst = res[".pipeline.build"] - self.assertEqual(len(lst), 1) - - # de-dup issues: the manifest checking will report - # the extra element and the recursive build pipeline - # check will also report that same error; make sure - # they get properly de-duplicated - no_runner_extra = { - "pipeline": { - "build": { # missing runner - "pipeline": { - "extra": True, # should not be there - "stages": [{ - "name": "org.osbuild.chrony", - "options": { - "timeservers": "string" # should be an array - } - }] - } - } - } - } - - res = fmt.validate(no_runner_extra, index) - self.assertEqual(res.valid, False) - self.assertEqual(len(res), 3) - lst = res[".pipeline.build.pipeline"] - self.assertEqual(len(lst), 1) # should only have one - lst = res[".pipeline.build.pipeline.stages[0].options.timeservers"] - self.assertEqual(len(lst), 1) # should only have one - - # stage issues - stage_check = { - "pipeline": { - "stages": [{ - "name": "org.osbuild.grub2", - "options": { - "uefi": { - "install": False, - # missing "vendor" - }, - # missing rootfs or root_fs_uuid - } - }] - } - } - - res = fmt.validate(stage_check, index) - self.assertEqual(res.valid, False) - self.assertEqual(len(res), 2) - lst = res[".pipeline.stages[0].options"] - self.assertEqual(len(lst), 1) # missing rootfs - lst = res[".pipeline.stages[0].options.uefi"] - self.assertEqual(len(lst), 1) # missing "osname" - - assembler_check = { - "pipeline": { - "assembler": { - "name": "org.osbuild.tar", - "options": { - "compression": "foobar" - } - } - } - } - - res = fmt.validate(assembler_check, index) - self.assertEqual(res.valid, False) - self.assertEqual(len(res), 2) - lst = res[".pipeline.assembler.options"] - self.assertEqual(len(lst), 1) # missing "filename" - lst = res[".pipeline.assembler.options.compression"] - self.assertEqual(len(lst), 1) # wrong compression method