From b26b8e709781a425b67bf85554e1a72dfd872a0c Mon Sep 17 00:00:00 2001 From: Seth Foster Date: Mon, 16 Dec 2019 15:15:23 -0500 Subject: [PATCH] Prevent running jobs from blocking inventory updates A running job that has an inventory source will block that inventory update from running. This fix removes the block. The test creates a job in running state, and an inventory update in pending state. The test asserts that the task manager and dependency graph .is_job_blocked method returns False for the inventory update (i.e. update can run). issue #4809 --- awx/main/scheduler/dependency_graph.py | 7 +---- .../task_management/test_scheduler.py | 30 +++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/awx/main/scheduler/dependency_graph.py b/awx/main/scheduler/dependency_graph.py index 2d180bbced..6f1eb79e3e 100644 --- a/awx/main/scheduler/dependency_graph.py +++ b/awx/main/scheduler/dependency_graph.py @@ -15,7 +15,6 @@ class DependencyGraph(object): INVENTORY_UPDATES = 'inventory_updates' JOB_TEMPLATE_JOBS = 'job_template_jobs' - JOB_INVENTORY_IDS = 'job_inventory_ids' SYSTEM_JOB = 'system_job' INVENTORY_SOURCE_UPDATES = 'inventory_source_updates' @@ -40,8 +39,6 @@ class DependencyGraph(object): Track runnable job related project and inventory to ensure updates don't run while a job needing those resources is running. ''' - # inventory_id -> True / False - self.data[self.JOB_INVENTORY_IDS] = {} # inventory_source_id -> True / False self.data[self.INVENTORY_SOURCE_UPDATES] = {} @@ -77,7 +74,6 @@ class DependencyGraph(object): self.data[self.INVENTORY_SOURCE_UPDATES][inventory_source_id] = False def mark_job_template_job(self, job): - self.data[self.JOB_INVENTORY_IDS][job.inventory_id] = False self.data[self.JOB_TEMPLATE_JOBS][job.job_template_id] = False def mark_workflow_job(self, job): @@ -87,8 +83,7 @@ class DependencyGraph(object): return self.data[self.PROJECT_UPDATES].get(job.project_id, True) def can_inventory_update_run(self, job): - return self.data[self.JOB_INVENTORY_IDS].get(job.inventory_source.inventory_id, True) and \ - self.data[self.INVENTORY_SOURCE_UPDATES].get(job.inventory_source_id, True) + return self.data[self.INVENTORY_SOURCE_UPDATES].get(job.inventory_source_id, True) def can_job_run(self, job): if self.data[self.PROJECT_UPDATES].get(job.project_id, True) is True and \ diff --git a/awx/main/tests/functional/task_management/test_scheduler.py b/awx/main/tests/functional/task_management/test_scheduler.py index f76e998355..1ad3d7e035 100644 --- a/awx/main/tests/functional/task_management/test_scheduler.py +++ b/awx/main/tests/functional/task_management/test_scheduler.py @@ -353,3 +353,33 @@ def test_job_not_blocking_project_update(default_instance_group, job_template_fa dependency_graph = DependencyGraph(None) dependency_graph.add_job(job) assert not dependency_graph.is_job_blocked(project_update) + + +@pytest.mark.django_db +def test_job_not_blocking_inventory_update(default_instance_group, job_template_factory, inventory_source_factory): + objects = job_template_factory('jt', organization='org1', project='proj', + inventory='inv', credential='cred', + jobs=["job"]) + job = objects.jobs["job"] + job.instance_group = default_instance_group + job.status = "running" + job.save() + + with mock.patch("awx.main.scheduler.TaskManager.start_task"): + task_manager = TaskManager() + task_manager._schedule() + + inv = objects.inventory + inv_source = inventory_source_factory("ec2") + inv_source.source = "ec2" + inv.inventory_sources.add(inv_source) + inventory_update = inv_source.create_inventory_update() + inventory_update.instance_group = default_instance_group + inventory_update.status = "pending" + inventory_update.save() + + assert not task_manager.is_job_blocked(inventory_update) + + dependency_graph = DependencyGraph(None) + dependency_graph.add_job(job) + assert not dependency_graph.is_job_blocked(inventory_update)