Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/UnitTests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,5 @@ jobs:
arch: ${{ matrix.julia-arch }}
- uses: julia-actions/cache@v3
- uses: julia-actions/julia-runtest@v1
env:
JULIA_NUM_THREADS: "auto"
9 changes: 8 additions & 1 deletion src/ParallelTestRunner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1189,10 +1189,12 @@ function _runtests(mod::Module, args::ParsedArgs;
#

tests_to_start = Threads.Atomic{Int}(length(tests))
next_test = Threads.Atomic{Int}(1)
try
@sync for test in tests
@sync for _ in 1:length(tests)
push!(worker_tasks, Threads.@spawn begin
local p = nothing
local test
acquired = false
try
Base.acquire(sem)
Expand All @@ -1202,6 +1204,11 @@ function _runtests(mod::Module, args::ParsedArgs;

done && return

# with multiple threads, tasks reach this point in arbitrary order,
# so pick the next test to run only now, rather than at spawn time,
# to preserve the sorted test order (issue #139)
test = tests[Threads.atomic_add!(next_test, 1)]

test_t0 = @lock running_tests begin
test_t0 = time()
running_tests[][test] = test_t0
Expand Down
30 changes: 30 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,36 @@ end
@test contains(str, "SUCCESS")
end

@testset "test start order" begin
# Tests must start in the given order, regardless of the
# number of threads of the host Julia process (issue #139).
testsuite = Dict(
"sort$(n)" => :(@test true)
for n in 1:5
)
tests = ["sort$(n)" for n in 1:length(testsuite)]

io = IOBuffer()
# with a single job, tests start strictly in acquisition order
ParallelTestRunner._runtests(
ParallelTestRunner, parse_args(["--jobs=1", "--verbose"]);
testsuite,
tests,
historical_durations=Dict{String, Float64}(),
stdout=io,
stderr=io,
)

str = String(take!(io))
@test contains(str, "SUCCESS")
started_at = map(tests) do name
m = match(Regex("$(name) .+ started at"), str)
@test m !== nothing
m === nothing ? typemax(Int) : m.offset
end
@test issorted(started_at)
end

@testset "init code" begin
init_code = quote
using Test
Expand Down