func()

in pkg/runner/job_status.go [122:193]


func (jr *JobRunner) buildTestStatus(ctx xcontext.Context, coordinates job.TestCoordinates, currentJob *job.Job) (*job.TestStatus, error) {

	var currentTest *test.Test
	// Identify the test within the Job for which we are asking to calculate the status
	for _, candidateTest := range currentJob.Tests {
		if candidateTest.Name == coordinates.TestName {
			currentTest = candidateTest
			break
		}
	}

	if currentTest == nil {
		return nil, fmt.Errorf("job with id %d does not include any test named %s", coordinates.JobID, coordinates.TestName)
	}
	testStatus := job.TestStatus{
		TestCoordinates:  coordinates,
		TestStepStatuses: make([]job.TestStepStatus, len(currentTest.TestStepsBundles)),
	}

	// Build a TestStepStatus object for each TestStep
	for index, bundle := range currentTest.TestStepsBundles {
		testStepCoordinates := job.TestStepCoordinates{
			TestCoordinates: coordinates,
			TestStepName:    bundle.TestStep.Name(),
			TestStepLabel:   bundle.TestStepLabel,
		}
		testStepStatus, err := jr.buildTestStepStatus(ctx, testStepCoordinates)
		if err != nil {
			return nil, fmt.Errorf("could not build TestStatus for test %s: %v", bundle.TestStep.Name(), err)
		}
		testStatus.TestStepStatuses[index] = *testStepStatus
	}

	// Calculate the overall status of the Targets which corresponds to the last TargetStatus
	// object recorded for each Target.

	// Fetch all events signaling that a Target has been acquired. This is the source of truth
	// indicating which Targets belong to a Test.
	targetAcquiredEvents, err := jr.testEvManager.Fetch(ctx,
		testevent.QueryJobID(coordinates.JobID),
		testevent.QueryRunID(coordinates.RunID),
		testevent.QueryTestName(coordinates.TestName),
		testevent.QueryEventName(target.EventTargetAcquired),
	)

	if err != nil {
		return nil, fmt.Errorf("could not fetch events associated to target acquisition")
	}

	var targetStatuses []job.TargetStatus

	// Keep track of the last TargetStatus seen for each Target
	targetMap := make(map[string]job.TargetStatus)
	for _, testStepStatus := range testStatus.TestStepStatuses {
		for _, targetStatus := range testStepStatus.TargetStatuses {
			targetMap[targetStatus.Target.ID] = targetStatus
		}
	}

	for _, targetEvent := range targetAcquiredEvents {
		t := *targetEvent.Data.Target
		if _, ok := targetMap[t.ID]; !ok {
			// This Target is not associated to any TargetStatus, we assume it has not
			// started the test
			targetMap[t.ID] = job.TargetStatus{}
		}
		targetStatuses = append(targetStatuses, targetMap[t.ID])
	}

	testStatus.TargetStatuses = targetStatuses
	return &testStatus, nil
}