Skip to content

Commit 9581afa

Browse files
committed
Improve module sandboxing and allow init code customization.
1 parent ed0f74f commit 9581afa

File tree

5 files changed

+24
-27
lines changed

5 files changed

+24
-27
lines changed

src/ParallelTestRunner.jl

Lines changed: 14 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ end
134134

135135
## entry point
136136

137-
function runtest(::Type{TestRecord}, f, name)
137+
function runtest(::Type{TestRecord}, f, name, init_code)
138138
function inner()
139139
# generate a temporary module to execute the tests in
140140
mod_name = Symbol("Test", rand(1:100), "Main_", replace(name, '/' => '_'))
@@ -146,16 +146,16 @@ function runtest(::Type{TestRecord}, f, name)
146146
wait(@spawnat 1 print_testworker_started(name, id))
147147
end
148148

149-
ex = quote
149+
data = @eval mod begin
150150
GC.gc(true)
151151
Random.seed!(1)
152+
$init_code
152153

153154
res = @timed @testset $name begin
154-
$f()
155+
$f
155156
end
156157
(res...,)
157158
end
158-
data = Core.eval(mod, ex)
159159

160160
#data[1] is the testset
161161

@@ -227,8 +227,9 @@ Several keyword arguments are also supported:
227227
228228
- `testfilter`: Optional function to filter which tests to run (default: run all tests)
229229
- `RecordType`: Type of test record to use for tracking test results (default: `TestRecord`)
230-
- `custom_tests`: Optional dictionary of custom tests, mapping test names to a zero-argument
231-
function
230+
- `custom_tests`: Optional dictionary of custom tests, mapping test names to expressions.
231+
- `init_code`: Code use to initialize each test's sandbox module (e.g., import auxiliary
232+
packages, define constants, etc).
232233
233234
## Command Line Options
234235
@@ -241,8 +242,7 @@ Several keyword arguments are also supported:
241242
242243
## Behavior
243244
244-
- Automatically discovers all `.jl` files in the test directory (excluding `setup.jl` and
245-
`runtests.jl`)
245+
- Automatically discovers all `.jl` files in the test directory (excluding `runtests.jl`)
246246
- Sorts tests by file size (largest first) for load balancing
247247
- Launches worker processes with appropriate Julia flags for testing
248248
- Monitors memory usage and recycles workers that exceed memory limits
@@ -272,7 +272,7 @@ Workers are automatically recycled when they exceed memory limits to prevent out
272272
issues during long test runs. The memory limit is set based on system architecture.
273273
"""
274274
function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
275-
custom_tests::Dict{String}=Dict{String}())
275+
custom_tests::Dict{String}=Dict{String}(), init_code = :())
276276
do_help, _ = extract_flag!(ARGS, "--help")
277277
if do_help
278278
println(
@@ -313,7 +313,7 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
313313
for (rootpath, dirs, files) in walkdir(WORKDIR)
314314
# find Julia files
315315
filter!(files) do file
316-
endswith(file, ".jl") && file !== "setup.jl" && file !== "runtests.jl"
316+
endswith(file, ".jl") && file !== "runtests.jl"
317317
end
318318
isempty(files) && continue
319319

@@ -337,7 +337,9 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
337337

338338
append!(tests, files)
339339
for file in files
340-
test_runners[file] = ()->Main.include(joinpath(WORKDIR, file * ".jl"))
340+
test_runners[file] = quote
341+
include($(joinpath(WORKDIR, file * ".jl")))
342+
end
341343
end
342344
end
343345
sort!(tests; by = (file) -> stat(joinpath(WORKDIR, file * ".jl")).size, rev = true)
@@ -387,14 +389,8 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
387389
Distributed.remotecall_eval(
388390
Main, procs, quote
389391
import ParallelTestRunner
390-
# TODO: Should we import Test for the user here?
391-
import ParallelTestRunner: Test
392-
using .Test
393392
end
394393
)
395-
if ispath(joinpath(WORKDIR, "setup.jl"))
396-
@everywhere procs include($(joinpath(WORKDIR, "setup.jl")))
397-
end
398394
procs
399395
end
400396
end
@@ -507,7 +503,7 @@ function runtests(ARGS; testfilter = Returns(true), RecordType = TestRecord,
507503
# run the test
508504
running_tests[test] = now()
509505
try
510-
resp = remotecall_fetch(runtest, wrkr, RecordType, test_runners[test], test)
506+
resp = remotecall_fetch(runtest, wrkr, RecordType, test_runners[test], test, init_code)
511507
catch e
512508
isa(e, InterruptException) && return
513509
resp = Any[e]

test/init.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
@test should_be_defined()

test/runtests.jl

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,15 @@ using ParallelTestRunner
22

33
pushfirst!(ARGS, "--verbose")
44

5+
init_code = quote
6+
using Test
7+
should_be_defined() = true
8+
end
9+
510
custom_tests = Dict(
6-
"whatever" => Returns(nothing)
11+
"custom" => quote
12+
@test should_be_defined()
13+
end
714
)
815

9-
runtests(ARGS; custom_tests)
16+
runtests(ARGS; init_code, custom_tests)

test/setup.jl

Lines changed: 0 additions & 5 deletions
This file was deleted.

test/test_setup.jl

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)