From 99160dd0a077270770d922a7b77fcc5486b0d4da Mon Sep 17 00:00:00 2001 From: Erwan Rouchet <rouchet@teklia.com> Date: Tue, 10 Jan 2023 10:14:13 +0100 Subject: [PATCH] Check that artifact IDs are UUIDs in recipes --- ponos/recipe.py | 5 +++++ tests/server/test_recipe.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 tests/server/test_recipe.py diff --git a/ponos/recipe.py b/ponos/recipe.py index 42ef5b282b..0daeff5391 100644 --- a/ponos/recipe.py +++ b/ponos/recipe.py @@ -1,5 +1,6 @@ import re from collections import namedtuple +from uuid import UUID import yaml from django.core.validators import URLValidator @@ -56,6 +57,10 @@ def validate_task(task, top_env): if "artifact" in task: assert isinstance(task["artifact"], str), "Task artifact should be a string" + try: + UUID(task["artifact"]) + except (TypeError, ValueError): + raise AssertionError("Task artifact should be a valid UUID string") if "requires_gpu" in task: assert isinstance( diff --git a/tests/server/test_recipe.py b/tests/server/test_recipe.py new file mode 100644 index 0000000000..18ef2dbe9a --- /dev/null +++ b/tests/server/test_recipe.py @@ -0,0 +1,42 @@ +from textwrap import dedent + +from django.test import TestCase + +from ponos.recipe import parse_recipe + +# List of (broken recipe, expected AssertionError message) tuples +ERROR_CASES = [ + ("[]", "Recipe should be a dict"), + ("tasks: {}", "No tasks"), + ("tasks: [{image: lol}]", "Tasks should be a dict"), + ("tasks: {a: {}, '': {}}", "Tasks should have non-blank slugs"), + ("tasks: {a: []}", "Task should be a dict"), + ("tasks: {a: {}}", "Missing image"), + ( + """ + tasks: + lol: + image: blah + artifact: 42 + """, + "Task artifact should be a string", + ), + ( + """ + tasks: + lol: + image: blah + artifact: philosophers_stone + """, + "Task artifact should be a valid UUID string", + ), +] + + +class TestRecipe(TestCase): + def test_recipe_errors(self): + for recipe, expected_message in ERROR_CASES: + with self.subTest(recipe=recipe), self.assertRaisesMessage( + AssertionError, expected_message + ): + parse_recipe(dedent(recipe)) -- GitLab