diff --git a/awx/main/scheduler/__init__.py b/awx/main/scheduler/__init__.py index 8569fb5cfc..5221f340a6 100644 --- a/awx/main/scheduler/__init__.py +++ b/awx/main/scheduler/__init__.py @@ -240,6 +240,9 @@ class TaskManager(): dependencies.append(project_task) # Inventory created 2 seconds behind job + ''' + Inventory may have already been synced from a provision callback. + ''' inventory_sources_already_updated = task.get_inventory_sources_already_updated() for inventory_source_task in self.graph.get_inventory_sources(task['inventory_id']): diff --git a/awx/main/scheduler/dependency_graph.py b/awx/main/scheduler/dependency_graph.py index 7b66a8fe1b..846a194b27 100644 --- a/awx/main/scheduler/dependency_graph.py +++ b/awx/main/scheduler/dependency_graph.py @@ -117,10 +117,6 @@ class DependencyGraph(object): if not latest_inventory_update: return True - # TODO: Other finished, failed cases? i.e. error ? - if latest_inventory_update['status'] in ['failed', 'canceled']: - return True - ''' This is a bit of fuzzy logic. If the latest inventory update has a created time == job_created_time-2 @@ -138,7 +134,11 @@ class DependencyGraph(object): timeout_seconds = timedelta(seconds=latest_inventory_update['inventory_source__update_cache_timeout']) if (latest_inventory_update['finished'] + timeout_seconds) < now: return True - + + if latest_inventory_update['inventory_source__update_on_launch'] is True and \ + latest_inventory_update['status'] in ['failed', 'canceled', 'error']: + return True + return False def mark_system_job(self): diff --git a/awx/main/scheduler/partial.py b/awx/main/scheduler/partial.py index d16634f369..18c5c63d46 100644 --- a/awx/main/scheduler/partial.py +++ b/awx/main/scheduler/partial.py @@ -151,6 +151,7 @@ class InventoryUpdateLatestDict(InventoryUpdateDict): FIELDS = ( 'id', 'status', 'created', 'celery_task_id', 'inventory_source_id', 'finished', 'inventory_source__update_cache_timeout', 'launch_type', + 'inventory_source__update_on_launch', ) model = InventoryUpdate diff --git a/awx/main/tests/unit/scheduler/test_scheduler_inventory_update.py b/awx/main/tests/unit/scheduler/test_scheduler_inventory_update.py index 5e49eec729..eeace8243d 100644 --- a/awx/main/tests/unit/scheduler/test_scheduler_inventory_update.py +++ b/awx/main/tests/unit/scheduler/test_scheduler_inventory_update.py @@ -26,6 +26,22 @@ def successful_inventory_update_latest_cache_expired(inventory_update_latest_fac return iu +@pytest.fixture +def failed_inventory_update_latest_cache_zero(failed_inventory_update_latest): + iu = failed_inventory_update_latest + iu['inventory_source__update_cache_timeout'] = 0 + iu['inventory_source__update_on_launch'] = True + iu['finished'] = iu['created'] + timedelta(seconds=2) + iu['status'] = 'failed' + return iu + + +@pytest.fixture +def failed_inventory_update_latest_cache_non_zero(failed_inventory_update_latest_cache_zero): + failed_inventory_update_latest_cache_zero['inventory_source__update_cache_timeout'] = 10000000 + return failed_inventory_update_latest_cache_zero + + class TestStartInventoryUpdate(): def test_pending(self, scheduler_factory, pending_inventory_update): scheduler = scheduler_factory(tasks=[pending_inventory_update]) @@ -79,9 +95,18 @@ class TestCreateDependentInventoryUpdate(): scheduler.start_task.assert_called_with(waiting_inventory_update, [pending_job]) - def test_last_update_failed(self, scheduler_factory, pending_job, failed_inventory_update, failed_inventory_update_latest, waiting_inventory_update, inventory_id_sources): + def test_last_update_timeout_zero_failed(self, scheduler_factory, pending_job, failed_inventory_update, failed_inventory_update_latest_cache_zero, waiting_inventory_update, inventory_id_sources): scheduler = scheduler_factory(tasks=[failed_inventory_update, pending_job], - latest_inventory_updates=[failed_inventory_update_latest], + latest_inventory_updates=[failed_inventory_update_latest_cache_zero], + create_inventory_update=waiting_inventory_update, + inventory_sources=inventory_id_sources) + scheduler._schedule() + + scheduler.start_task.assert_called_with(waiting_inventory_update, [pending_job]) + + def test_last_update_timeout_non_zero_failed(self, scheduler_factory, pending_job, failed_inventory_update, failed_inventory_update_latest_cache_non_zero, waiting_inventory_update, inventory_id_sources): + scheduler = scheduler_factory(tasks=[failed_inventory_update, pending_job], + latest_inventory_updates=[failed_inventory_update_latest_cache_non_zero], create_inventory_update=waiting_inventory_update, inventory_sources=inventory_id_sources) scheduler._schedule()