@@ -300,7 +300,6 @@ func (runner *TestFileRunner) Test(file *moduletest.File) {
300300// walkGraph goes through the graph and execute each run it finds.
301301func (runner * TestFileRunner ) walkGraph (g * terraform.Graph , file * moduletest.File ) tfdiags.Diagnostics {
302302 sem := runner .Suite .semaphore
303- collectRunStatus , updateFileStatus := runner .trackRunStatuses (file )
304303
305304 // Walk the graph.
306305 walkFn := func (v dag.Vertex ) (diags tfdiags.Diagnostics ) {
@@ -377,13 +376,9 @@ func (runner *TestFileRunner) walkGraph(g *terraform.Graph, file *moduletest.Fil
377376 }
378377
379378 startTime := time .Now ().UTC ()
380- deferFileStatus := runner .run (run , file , startTime )
379+ runner .run (run , file , startTime )
381380 runner .Suite .View .Run (run , file , moduletest .Complete , 0 )
382- // If the run block is done, but it was due to an expected failure, we
383- // don't want to update the file status immediately. We'll collect the
384- // status of this run block and update the file status at the end of the
385- // file execution.
386- collectRunStatus (run , deferFileStatus )
381+ file .UpdateStatus (run .Status )
387382 case graph.GraphNodeExecutable :
388383 diags = v .Execute (runner .EvalContext )
389384 return diags
@@ -394,12 +389,10 @@ func (runner *TestFileRunner) walkGraph(g *terraform.Graph, file *moduletest.Fil
394389 return
395390 }
396391
397- diags := g .AcyclicGraph .Walk (walkFn )
398- updateFileStatus ()
399- return diags
392+ return g .AcyclicGraph .Walk (walkFn )
400393}
401394
402- func (runner * TestFileRunner ) run (run * moduletest.Run , file * moduletest.File , startTime time.Time ) ( deferFileStatus bool ) {
395+ func (runner * TestFileRunner ) run (run * moduletest.Run , file * moduletest.File , startTime time.Time ) {
403396 log .Printf ("[TRACE] TestFileRunner: executing run block %s/%s" , file .Name , run .Name )
404397 defer func () {
405398 // If we got far enough to actually execute the run then we'll give
@@ -491,9 +484,9 @@ func (runner *TestFileRunner) run(run *moduletest.Run, file *moduletest.File, st
491484
492485 planScope , plan , planDiags := runner .plan (tfCtx , config , state , run , file , setVariables , references , start )
493486 if run .Config .Command == configs .PlanTestCommand {
487+ // Then we want to assess our conditions and diagnostics differently.
494488 planDiags = run .ValidateExpectedFailures (planDiags )
495489 run .Diagnostics = run .Diagnostics .Append (planDiags )
496- // Then we want to assess our conditions and diagnostics differently.
497490 if planDiags .HasErrors () {
498491 run .Status = moduletest .Error
499492 return
@@ -540,21 +533,12 @@ func (runner *TestFileRunner) run(run *moduletest.Run, file *moduletest.File, st
540533 return
541534 }
542535
543- // Otherwise any error (expected or unexpected) during the planning prevents our apply from
536+ // Otherwise any error during the planning prevents our apply from
544537 // continuing which is an error.
545538 planDiags = run .ExplainExpectedFailures (planDiags )
546539 run .Diagnostics = run .Diagnostics .Append (planDiags )
547540 if planDiags .HasErrors () {
548541 run .Status = moduletest .Error
549- // If the plan failed, but all the failures were expected, then we don't
550- // want to mark the overall file as a failure, so that subsequent runs can
551- // still be executed.
552- // We will collect the status of this run instead of updating the file status.
553- // At the end of the file execution, we will update the file status based on the
554- // statuses of all the runs.
555- if ! run .ValidateExpectedFailures (planDiags ).HasErrors () {
556- deferFileStatus = true
557- }
558542 return
559543 }
560544
@@ -575,11 +559,9 @@ func (runner *TestFileRunner) run(run *moduletest.Run, file *moduletest.File, st
575559 applyScope , updated , applyDiags := runner .apply (tfCtx , plan , state , run , file , moduletest .Running , start , variables )
576560
577561 // Remove expected diagnostics, and add diagnostics in case anything that should have failed didn't.
578- applyDiags = run .ValidateExpectedFailures (applyDiags )
579-
580- run .Diagnostics = run .Diagnostics .Append (applyDiags )
581- if applyDiags .HasErrors () {
582- run .Status = moduletest .Error
562+ // We'll also update the run status based on the presence of errors or missing expected failures.
563+ failOrErr := runner .checkForMissingExpectedFailures (run , applyDiags )
564+ if failOrErr {
583565 // Even though the apply operation failed, the graph may have done
584566 // partial updates and the returned state should reflect this.
585567 runner .EvalContext .SetFileState (key , & graph.TestFileState {
@@ -639,6 +621,38 @@ func (runner *TestFileRunner) run(run *moduletest.Run, file *moduletest.File, st
639621 return
640622}
641623
624+ // checkForMissingExpectedFailures checks for missing expected failures in the diagnostics.
625+ // It updates the run status based on the presence of errors or missing expected failures.
626+ func (runner * TestFileRunner ) checkForMissingExpectedFailures (run * moduletest.Run , diags tfdiags.Diagnostics ) (failOrErr bool ) {
627+ // If there are errors in the diagnostics, update the run status to error.
628+ if diags .HasErrors () {
629+ run .Status = moduletest .Error
630+ }
631+
632+ // Retrieve diagnostics that are either unrelated to expected failures or report missing expected failures.
633+ unexpectedDiags := run .ValidateExpectedFailures (diags )
634+ var nonFailureDiags tfdiags.Diagnostics
635+ for _ , diag := range unexpectedDiags {
636+ switch {
637+ // If any diagnostic indicates a missing expected failure, update the run status to fail.
638+ case diag .Description ().Summary == moduletest .MissingFailureSummary :
639+ diag .ExtraInfo ()
640+ run .Status = moduletest .Fail
641+ default :
642+ // Append other diagnostics.
643+ nonFailureDiags = nonFailureDiags .Append (diag )
644+ }
645+ }
646+ // If there are other errors, update the run status to error.
647+ if nonFailureDiags .HasErrors () {
648+ run .Status = moduletest .Error
649+ }
650+
651+ // Append all diagnostics that are not expected failures to the run diagnostics.
652+ run .Diagnostics = run .Diagnostics .Append (unexpectedDiags )
653+ return run .Status > moduletest .Pass
654+ }
655+
642656func (runner * TestFileRunner ) validate (run * moduletest.Run , file * moduletest.File , start int64 ) tfdiags.Diagnostics {
643657 log .Printf ("[TRACE] TestFileRunner: called validate for %s/%s" , file .Name , run .Name )
644658
0 commit comments