mirror of
https://github.com/ansible/awx.git
synced 2026-06-24 16:17:51 -02:30
Record whether a file was written for fact cache (#16361)
This commit is contained in:
@@ -73,17 +73,21 @@ class TestFinishFactCacheScoping:
|
||||
class TestFinishFactCacheConcurrentProtection:
|
||||
"""finish_fact_cache must not clear facts that a concurrent job updated."""
|
||||
|
||||
def test_skip_clear_when_facts_modified_after_job_created(self, organization, artifacts_dir):
|
||||
"""If a host's facts were updated after the job was created, do not clear them.
|
||||
def test_no_clear_when_no_file_was_written(self, organization, artifacts_dir):
|
||||
"""Host with no prior facts should not have facts cleared when file is missing.
|
||||
|
||||
Generated by Claude Opus 4.6 (claude-opus-4-6).
|
||||
|
||||
start_fact_cache records hosts_cached[host] = False for hosts with no
|
||||
prior facts (no file written). finish_fact_cache should skip the clear
|
||||
for these hosts because the missing file is expected, not a clear signal.
|
||||
"""
|
||||
inv = Inventory.objects.create(organization=organization, name='concurrent-inv')
|
||||
host = inv.hosts.create(name='target')
|
||||
|
||||
job_created = now() - timedelta(minutes=5)
|
||||
|
||||
# start_fact_cache writes a reference file (host has no facts yet → no file written)
|
||||
# start_fact_cache records host with False (no facts → no file written)
|
||||
start_fact_cache(inv.hosts.all(), artifacts_dir=artifacts_dir, timeout=0, inventory_id=inv.id)
|
||||
|
||||
# Simulate a concurrent job updating this host's facts AFTER our job was created
|
||||
@@ -91,12 +95,43 @@ class TestFinishFactCacheConcurrentProtection:
|
||||
host.ansible_facts_modified = now()
|
||||
host.save(update_fields=['ansible_facts', 'ansible_facts_modified'])
|
||||
|
||||
# The fact file is missing (our job's ansible didn't target this host),
|
||||
# which would normally trigger a clear. But the concurrent protection
|
||||
# should skip it because ansible_facts_modified > job_created.
|
||||
fact_file = os.path.join(artifacts_dir, 'fact_cache', host.name)
|
||||
if os.path.exists(fact_file):
|
||||
os.remove(fact_file)
|
||||
# The fact file is missing because start_fact_cache never wrote one.
|
||||
# finish_fact_cache should skip this host entirely.
|
||||
finish_fact_cache(
|
||||
inv.hosts,
|
||||
artifacts_dir=artifacts_dir,
|
||||
inventory_id=inv.id,
|
||||
job_created=job_created,
|
||||
)
|
||||
|
||||
host.refresh_from_db()
|
||||
assert host.ansible_facts == {'from_concurrent_job': True}, 'Facts were cleared for a host that never had a fact file written'
|
||||
|
||||
def test_skip_clear_when_facts_modified_after_job_created(self, organization, artifacts_dir):
|
||||
"""If a file was written and then deleted, but facts were concurrently updated, skip clear.
|
||||
|
||||
Generated by Claude Opus 4.6 (claude-opus-4-6).
|
||||
"""
|
||||
inv = Inventory.objects.create(organization=organization, name='concurrent-written-inv')
|
||||
host = inv.hosts.create(name='target')
|
||||
|
||||
old_time = now() - timedelta(hours=1)
|
||||
host.ansible_facts = {'original': True}
|
||||
host.ansible_facts_modified = old_time
|
||||
host.save(update_fields=['ansible_facts', 'ansible_facts_modified'])
|
||||
|
||||
job_created = now() - timedelta(minutes=5)
|
||||
|
||||
# start_fact_cache writes a file (host has facts → True in map)
|
||||
start_fact_cache(inv.hosts.all(), artifacts_dir=artifacts_dir, timeout=0, inventory_id=inv.id)
|
||||
|
||||
# Remove the fact file (ansible didn't target this host via --limit)
|
||||
os.remove(os.path.join(artifacts_dir, 'fact_cache', host.name))
|
||||
|
||||
# Simulate a concurrent job updating this host's facts AFTER our job was created
|
||||
host.ansible_facts = {'from_concurrent_job': True}
|
||||
host.ansible_facts_modified = now()
|
||||
host.save(update_fields=['ansible_facts', 'ansible_facts_modified'])
|
||||
|
||||
finish_fact_cache(
|
||||
inv.hosts,
|
||||
|
||||
Reference in New Issue
Block a user