AAP-45541 Add test to recreate jobs/4075584/job_events/children_summary/ error (#16163)

* Add test to recreate the error

* Also begin to add detection for empty event

* Remove breakpoint

* fix: ignore events with missing event types

* run linter and apply changes

---------

Co-authored-by: AlanCoding <arominge@redhat.com>
Co-authored-by: Peter Braun <pbraun@redhat.com>
This commit is contained in:
Chris Meyers 2025-12-17 15:34:53 -05:00 committed by GitHub
parent d7eb714859
commit 41f1ffc1dd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 51 additions and 1 deletions

View File

@ -3943,6 +3943,10 @@ class JobJobEventsChildrenSummary(APIView):
prev_non_meta_event = events[0]
for i, e in enumerate(events):
if not e['event']:
logging.warning(f'event type missing for event {e}')
continue
if not e['event'] in JobJobEventsChildrenSummary.meta_events:
prev_non_meta_event = e
if not e['uuid']:
@ -3980,9 +3984,11 @@ class JobJobEventsChildrenSummary(APIView):
z = i
next_non_meta_event = events[-1]
while z < len(events):
if events[z]['event'] not in JobJobEventsChildrenSummary.meta_events:
if events[z]['event'] not in JobJobEventsChildrenSummary.meta_events + ('',):
next_non_meta_event = events[z]
break
elif not events[z]['event']:
logging.warning(f"JobEventChildrenSummary: job event 'event' field is unexpectedly empty for job {job.id}")
z += 1
event_level_after = models.JobEvent.LEVEL_FOR_EVENT[next_non_meta_event['event']]
if event_level_after and event_level_after > event_level_before:

View File

@ -73,6 +73,7 @@ def test_job_job_events_children_summary(get, organization_factory, job_template
job_id=job.pk, uuid='uuid3', parent_uuid='uuid2', event="playbook_on_task_start", counter=3, stdout='a' * 1024, job_created=job.created
).save()
JobEvent.create_from_data(job_id=job.pk, uuid='uuid4', parent_uuid='', event='verbose', counter=4, stdout='a' * 1024, job_created=job.created).save()
JobEvent.create_from_data(
job_id=job.pk, uuid='uuid5', parent_uuid='uuid1', event="playbook_on_play_start", counter=5, stdout='a' * 1024, job_created=job.created
).save()
@ -131,3 +132,46 @@ def test_job_job_events_children_summary_is_tree(get, organization_factory, job_
assert response.data["meta_event_nested_uuid"] == {}
assert response.data["event_processing_finished"] == True
assert response.data["is_tree"] == False
@pytest.mark.django_db
def test_job_job_events_children_summary_empty_event(get, organization_factory, job_template_factory):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization, inventory='test_inv', project='test_proj').job_template
job = jt.create_unified_job()
url = reverse('api:job_job_events_children_summary', kwargs={'pk': job.pk})
response = get(url, user=objs.superusers.admin, expect=200)
assert response.data["event_processing_finished"] == False
'''
E1
E2
E3
E4 (verbose)
E5
'''
JobEvent.create_from_data(
job_id=job.pk, uuid='uuid1', parent_uuid='', event="playbook_on_start", counter=1, stdout='a' * 1024, job_created=job.created
).save()
JobEvent.create_from_data(
job_id=job.pk, uuid='uuid2', parent_uuid='uuid1', event="playbook_on_play_start", counter=2, stdout='a' * 1024, job_created=job.created
).save()
JobEvent.create_from_data(
job_id=job.pk, uuid='uuid3', parent_uuid='uuid2', event="playbook_on_task_start", counter=3, stdout='a' * 1024, job_created=job.created
).save()
JobEvent.create_from_data(job_id=job.pk, uuid='uuid4', parent_uuid='', event='verbose', counter=4, stdout='a' * 1024, job_created=job.created).save()
JobEvent.create_from_data(job_id=job.pk, uuid='uuid4', parent_uuid='', event='', counter=5, stdout='a' * 1024, job_created=job.created).save()
JobEvent.create_from_data(
job_id=job.pk, uuid='uuid5', parent_uuid='uuid1', event="playbook_on_play_start", counter=6, stdout='a' * 1024, job_created=job.created
).save()
job.emitted_events = job.get_event_queryset().count()
job.status = "successful"
job.save()
url = reverse('api:job_job_events_children_summary', kwargs={'pk': job.pk})
response = get(url, user=objs.superusers.admin, expect=200)
assert response.data["children_summary"] == {1: {"rowNumber": 0, "numChildren": 4}, 2: {"rowNumber": 1, "numChildren": 2}}
assert response.data["meta_event_nested_uuid"] == {4: "uuid2"}
assert response.data["event_processing_finished"] == True
assert response.data["is_tree"] == True