Skip to content

Commit c3e05a2

Browse files
committed
Fix test seeding on 1.11+
1 parent 84d80d0 commit c3e05a2

File tree

2 files changed

+42
-33
lines changed

2 files changed

+42
-33
lines changed

src/ReTest.jl

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,10 @@ const ArgType = Union{Module,PatternX,AbstractString,AbstractArray,Tuple,Symbol,
575575
Pair{Module,
576576
<:Union{PatternX,AbstractString,AbstractArray,Tuple}}}
577577

578+
# Holds the seed to set before each testset. This is not thread-safe, but it's
579+
# not normal/intended to call retest() concurrently anyway.
580+
const test_seed = Ref{Any}(false)
581+
578582
const retest_defaults = (
579583
dry = false,
580584
stats = false,
@@ -1089,22 +1093,12 @@ function retest(@nospecialize(args::ArgType...);
10891093
end
10901094

10911095
if seed !== false
1092-
let seedstr =
1093-
if seed === true
1094-
# seed!(nothing) doesn't work on old Julia, so we can't just set
1095-
# `seed = nothing` and interpolate `seed` directly in includestr
1096-
""
1097-
else
1098-
string(seed)
1099-
end,
1100-
includestr = """
1101-
using Random
1102-
Random.seed!($seedstr)
1103-
nothing
1104-
"""
1105-
# can't use `@everywhere using Random`, as here is not toplevel
1106-
@everywhere Base.include_string(Main, $includestr)
1107-
end
1096+
includestr = """
1097+
import ReTest
1098+
ReTest.test_seed[] = $seed
1099+
"""
1100+
1101+
@everywhere Base.include_string(Main, $includestr)
11081102
end
11091103

11101104
@sync for wrkr in workers()

src/testset.jl

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ using Distributed: myid, nworkers
1414

1515
import InlineTest: @testset
1616

17+
import ..ReTest
1718
using ..ReTest: Pattern, Marks, matches, setresult!
1819

1920
# mostly copied from Test stdlib
@@ -514,17 +515,19 @@ function testset_beginend(mod::Module, isfinal::Bool, pat::Pattern, id::Int64, d
514515
put!($(chan.preview), ($id, $desc))
515516
end
516517
push_testset(ts)
518+
517519
# we reproduce the logic of guardseed, but this function
518520
# cannot be used as it changes slightly the semantic of @testset,
519521
# by wrapping the body in a function
520-
local RNG = default_rng()
521-
local oldrng = copy(RNG)
522+
local default_rng_orig = copy(default_rng())
523+
@static if VERSION >= v"1.11"
524+
local tls_seed_orig = copy(Random.get_tls_seed())
525+
end
526+
522527
try
523-
# RNG is re-seeded with its own seed to ease reproduce a failed test
524-
if VERSION >= v"1.7.0-DEV.1225"
525-
Random.seed!(Random.GLOBAL_SEED)
526-
else
527-
Random.seed!(RNG.seed)
528+
# RNG is re-seeded with the desired seed for the test
529+
if ReTest.test_seed[] !== false
530+
Random.seed!(ReTest.test_seed[])
528531
end
529532
let
530533
ts.timed = @stats $stats $(esc(tests))
@@ -536,14 +539,19 @@ function testset_beginend(mod::Module, isfinal::Bool, pat::Pattern, id::Int64, d
536539
record(ts, Error(:nontest_error, Expr(:tuple), err,
537540
current_exceptions(), $(QuoteNode(source))))
538541
finally
539-
copy!(RNG, oldrng)
542+
copy!(default_rng(), default_rng_orig)
543+
@static if VERSION >= v"1.11"
544+
copy!(Random.get_tls_seed(), tls_seed_orig)
545+
end
546+
540547
setresult!($marks, ts.subject, !anyfailed(ts))
541548
pop_testset()
542549
ret = finish(ts, $chan)
543550
end
544551
ret
545552
end
546553
end
554+
547555
# preserve outer location if possible
548556
if tests isa Expr && tests.head === :block &&
549557
!isempty(tests.args) && tests.args[1] isa LineNumberNode
@@ -578,7 +586,7 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
578586
break
579587
end
580588
# it's 1000 times faster to copy from tmprng rather than calling Random.seed!
581-
copy!(RNG, tmprng)
589+
copy!(default_rng(), tmprng)
582590
end
583591
ts = ts0
584592
if nworkers() == 1 && get_testset_depth() == 0 && $(chan.preview) !== nothing
@@ -600,19 +608,22 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
600608
end
601609
end
602610
end
611+
603612
quote
604613
local arr = Vector{Any}()
605614
local first_iteration = true
606615
local iter = 0
607616
local ts
608-
local RNG = default_rng()
609-
local oldrng = copy(RNG)
610-
if VERSION >= v"1.7.0-DEV.1225"
611-
Random.seed!(Random.GLOBAL_SEED)
612-
else
613-
Random.seed!(RNG.seed)
617+
618+
local default_rng_orig = copy(default_rng())
619+
@static if VERSION >= v"1.11"
620+
local tls_seed_orig = copy(Random.get_tls_seed())
621+
end
622+
623+
local tmprng = copy(default_rng())
624+
if ReTest.test_seed[] !== false
625+
tmprng = copy(Random.seed!(ReTest.test_seed[]))
614626
end
615-
local tmprng = copy(RNG)
616627
try
617628
let
618629
$(Expr(:for, Expr(:block, [esc(v) for v in loops]...), blk))
@@ -623,7 +634,11 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
623634
pop_testset()
624635
push!(arr, finish(ts, $chan))
625636
end
626-
copy!(RNG, oldrng)
637+
638+
copy!(default_rng(), default_rng_orig)
639+
@static if VERSION >= v"1.11"
640+
copy!(Random.get_tls_seed(), tls_seed_orig)
641+
end
627642
end
628643
arr
629644
end

0 commit comments

Comments
 (0)