From 2d7d15af491425cf06774c05377eb9678c130fd5 Mon Sep 17 00:00:00 2001 From: David Moreau Simard Date: Wed, 14 Nov 2018 14:40:44 -0500 Subject: [PATCH] model: change task.completed to task.status We want a bit more granularity regarding the status of the tasks, "completed" is not enough. In 0.x, the status was inferred at runtime. We'll set it so we don't need to compute it every time. Change-Id: Idf2dbe9cde1b0cc8da1cbb7fe94894f1a06ea9cd --- ara/api/migrations/0001_initial.py | 4 ++-- ara/api/models.py | 9 ++++++++- ara/api/tests/factories.py | 2 +- ara/api/tests/tests_task.py | 15 ++++++++++++--- 4 files changed, 23 insertions(+), 7 deletions(-) diff --git a/ara/api/migrations/0001_initial.py b/ara/api/migrations/0001_initial.py index bb2b456..6fac4d0 100644 --- a/ara/api/migrations/0001_initial.py +++ b/ara/api/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 2.1.3 on 2018-11-14 19:34 +# Generated by Django 2.1.3 on 2018-11-14 19:40 from django.db import migrations, models import django.db.models.deletion @@ -164,7 +164,7 @@ class Migration(migrations.Migration): ('lineno', models.IntegerField()), ('tags', models.BinaryField(max_length=4294967295)), ('handler', models.BooleanField()), - ('completed', models.BooleanField(default=False)), + ('status', models.CharField(choices=[('unknown', 'unknown'), ('running', 'running'), ('completed', 'completed')], default='unknown', max_length=25)), ('file', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='api.File')), ('play', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='api.Play')), ('playbook', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tasks', to='api.Playbook')), diff --git a/ara/api/models.py b/ara/api/models.py index 3af1f37..7289242 100644 --- a/ara/api/models.py +++ b/ara/api/models.py @@ -177,12 +177,19 @@ class Task(Duration): class Meta: db_table = "tasks" + # A task in ARA can be running (in progress) or completed (regardless of success or failure) + # Actual task statuses (such as failed, skipped, etc.) are actually in the Results table. + UNKNOWN = "unknown" + RUNNING = "running" + COMPLETED = "completed" + STATUS = ((UNKNOWN, "unknown"), (RUNNING, "running"), (COMPLETED, "completed")) + name = models.TextField(blank=True, null=True) action = models.TextField() lineno = models.IntegerField() tags = models.BinaryField(max_length=(2 ** 32) - 1) handler = models.BooleanField() - completed = models.BooleanField(default=False) + status = models.CharField(max_length=25, choices=STATUS, default=UNKNOWN) play = models.ForeignKey(Play, on_delete=models.CASCADE, related_name="tasks") file = models.ForeignKey(File, on_delete=models.CASCADE, related_name="tasks") diff --git a/ara/api/tests/factories.py b/ara/api/tests/factories.py index 92e0fc2..3361653 100644 --- a/ara/api/tests/factories.py +++ b/ara/api/tests/factories.py @@ -79,7 +79,7 @@ class TaskFactory(factory.DjangoModelFactory): model = models.Task name = "test task" - completed = True + status = "running" action = "setup" lineno = 2 handler = False diff --git a/ara/api/tests/tests_task.py b/ara/api/tests/tests_task.py index 3bc84db..bb0c1c2 100644 --- a/ara/api/tests/tests_task.py +++ b/ara/api/tests/tests_task.py @@ -37,7 +37,7 @@ class TaskTestCase(APITestCase): "name": "serializer", "action": "test", "lineno": 2, - "completed": True, + "status": "completed", "handler": False, "play": play.id, "file": file.id, @@ -48,6 +48,7 @@ class TaskTestCase(APITestCase): task = serializer.save() task.refresh_from_db() self.assertEqual(task.name, "serializer") + self.assertEqual(task.status, "completed") def test_task_serializer_compress_tags(self): play = factories.PlayFactory() @@ -57,7 +58,7 @@ class TaskTestCase(APITestCase): "name": "compress", "action": "test", "lineno": 2, - "completed": True, + "status": "running", "handler": False, "play": play.id, "file": file.id, @@ -103,7 +104,7 @@ class TaskTestCase(APITestCase): "action": "test", "lineno": 2, "handler": False, - "completed": True, + "status": "running", "play": play.id, "file": file.id, "playbook": play.playbook.id, @@ -140,3 +141,11 @@ class TaskTestCase(APITestCase): task = factories.TaskFactory(started=started, ended=ended) request = self.client.get("/api/v1/tasks/%s" % task.id) self.assertEqual(request.data["duration"], datetime.timedelta(0, 3600)) + + def test_update_wrong_task_status(self): + task = factories.TaskFactory() + self.assertNotEqual("wrong", task.status) + request = self.client.patch("/api/v1/tasks/%s" % task.id, {"status": "wrong"}) + self.assertEqual(400, request.status_code) + task_updated = models.Task.objects.get(id=task.id) + self.assertNotEqual("wrong", task_updated.status)