From 166b8cc88fe65f8824a1c428dd6e77e59ffbbcac Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 10 Jun 2025 10:56:03 -0400 Subject: [PATCH 1/2] Test: Fix failfast for for loops --- stdlib/Test/src/Test.jl | 4 +++- stdlib/Test/test/runtests.jl | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index f379c4dd15ac3..fe069101746f3 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1925,7 +1925,9 @@ function testset_forloop(args, testloop, source) # Something in the test block threw an error. Count that as an # error in this test set trigger_test_failure_break(err) - if !isa(err, FailFastError) + if err isa FailFastError + get_testset_depth() > 1 ? rethrow() : failfast_print() + else record(ts, Error(:nontest_error, Expr(:tuple), err, Base.current_exceptions(), $(QuoteNode(source)))) end end diff --git a/stdlib/Test/test/runtests.jl b/stdlib/Test/test/runtests.jl index cffaa778cf265..4a8a25f0089d4 100644 --- a/stdlib/Test/test/runtests.jl +++ b/stdlib/Test/test/runtests.jl @@ -1394,7 +1394,7 @@ end @test occursin(expected, result) end end - @testset "failfast" begin + @testset "failfast begin-end" begin expected = r""" Test Summary: \| Fail Total +Time Foo \| 1 1 \s*\d*\.\ds @@ -1419,6 +1419,32 @@ end @test occursin(expected, result) end end + @testset "failfast for-loop" begin + expected = r""" + Test Summary: \| Fail Total +Time + Foo \| 1 1 \s*\d*\.\ds + 1 \| 1 1 \s*\d*\.\ds + """ + mktemp() do f, _ + write(f, + """ + using Test + + @testset "Foo" failfast=true begin + @testset "\$x" for x in 1:2 + @test false + end + @testset "Bar" begin + @test false + @test true + end + end + """) + cmd = `$(Base.julia_cmd()) --startup-file=no --color=no $f` + result = read(pipeline(ignorestatus(cmd), stderr=devnull), String) + @test occursin(expected, result) + end + end @testset "failfast passes to child testsets" begin expected = r""" Test Summary: \| Fail Total +Time From f3dacf0f6d47b686e3e4c13e4a3d33a04cee315e Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Tue, 10 Jun 2025 12:21:43 -0400 Subject: [PATCH 2/2] fix failfast through include barrier --- stdlib/Test/src/Test.jl | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/stdlib/Test/src/Test.jl b/stdlib/Test/src/Test.jl index fe069101746f3..7ad1c35294be7 100644 --- a/stdlib/Test/src/Test.jl +++ b/stdlib/Test/src/Test.jl @@ -1726,6 +1726,10 @@ end trigger_test_failure_break(@nospecialize(err)) = ccall(:jl_test_failure_breakpoint, Cvoid, (Any,), err) +is_failfast_error(err::FailFastError) = true +is_failfast_error(err::LoadError) = is_failfast_error(err.error) # handle `include` barrier +is_failfast_error(err) = false + """ Generate the code for an `@testset` with a `let` argument. """ @@ -1837,7 +1841,7 @@ function testset_beginend_call(args, tests, source) # something in the test block threw an error. Count that as an # error in this test set trigger_test_failure_break(err) - if err isa FailFastError + if is_failfast_error(err) get_testset_depth() > 1 ? rethrow() : failfast_print() else record(ts, Error(:nontest_error, Expr(:tuple), err, Base.current_exceptions(), $(QuoteNode(source)))) @@ -1925,7 +1929,7 @@ function testset_forloop(args, testloop, source) # Something in the test block threw an error. Count that as an # error in this test set trigger_test_failure_break(err) - if err isa FailFastError + if is_failfast_error(err) get_testset_depth() > 1 ? rethrow() : failfast_print() else record(ts, Error(:nontest_error, Expr(:tuple), err, Base.current_exceptions(), $(QuoteNode(source))))