import importlib.util import json import os import unittest import osbuild 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.""" cases = [ {}, {"assembler": None}, {"stages": []}, {"build": {}}, {"build": None} ] for pipeline in cases: with self.subTest(pipeline): self.assertEqual(osbuild.load(pipeline, {}).description(), {}) def test_stage(self): name = "org.osbuild.test" options = {"one": 1} cases = [ (osbuild.Stage(name, {}, None, None, {}), {"name": name}), (osbuild.Stage(name, {}, None, None, None), {"name": name}), (osbuild.Stage(name, {}, None, None, options), {"name": name, "options": options}), ] for stage, description in cases: with self.subTest(description): self.assertEqual(stage.description(), description) def test_assembler(self): name = "org.osbuild.test" options = {"one": 1} cases = [ (osbuild.Assembler(name, None, None, {}), {"name": name}), (osbuild.Assembler(name, None, None, None), {"name": name}), (osbuild.Assembler(name, None, None, options), {"name": name, "options": options}), ] for assembler, description in cases: with self.subTest(description): self.assertEqual(assembler.description(), description) def test_pipeline(self): build = osbuild.Pipeline("org.osbuild.test") build.add_stage("org.osbuild.test", {}, {"one": 1}) pipeline = osbuild.Pipeline("org.osbuild.test", build) pipeline.add_stage("org.osbuild.test", {}, {"one": 2}) pipeline.set_assembler("org.osbuild.test") self.assertEqual(pipeline.description(), { "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.test" } }) def test_stageinfo(self): def list_stages(base): return [(base, f) for f in os.listdir(base) if f.startswith("org.osbuild")] def load_module(base, name): loader = importlib.machinery.SourceFileLoader(name, f"{base}/{name}") spec = importlib.util.spec_from_loader(loader.name, loader) mod = importlib.util.module_from_spec(spec) loader.exec_module(mod) return mod stages = list_stages("stages") stages += list_stages("assemblers") for stage in stages: base, name = stage m = load_module(base, name) try: json.loads("{" + m.STAGE_OPTS + "}") except json.decoder.JSONDecodeError as e: msg = f"Stage '{base}/{name}' has invalid STAGE_OPTS\n\t" + str(e) self.fail(msg) if __name__ == "__main__": unittest.main()