Skip to content

Commit

Permalink
Merge pull request #58 from JuliaTesting/precompile
Browse files Browse the repository at this point in the history
Add a precompilation workload
  • Loading branch information
JamesWrigley authored Jan 23, 2025
2 parents 69f2e7d + c398a56 commit 52b8ad1
Show file tree
Hide file tree
Showing 9 changed files with 137 additions and 76 deletions.
28 changes: 8 additions & 20 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ on:
tags: '*'
pull_request:

permissions:
contents: read
actions: write

jobs:
test:
name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }}
Expand All @@ -15,37 +19,21 @@ jobs:
fail-fast: false
matrix:
include:
- { os: ubuntu-latest, version: '1.0', arch: x64}
- { os: ubuntu-latest, version: '1.1', arch: x64}
- { os: ubuntu-latest, version: '1.2', arch: x64}
- { os: ubuntu-latest, version: '1.3', arch: x64}
- { os: ubuntu-latest, version: '1.4', arch: x64}
- { os: ubuntu-latest, version: '1.5', arch: x64}
- { os: ubuntu-latest, version: '1.6', arch: x64}
- { os: ubuntu-latest, version: '^1.7.0-0', arch: x64}
- { os: ubuntu-latest, version: '1.10', arch: x64}
- { os: ubuntu-latest, version: 'nightly', arch: x64}
- { os: ubuntu-latest, version: '1', arch: x86 }
- { os: windows-latest, version: '1', arch: x64}
- { os: macOS-latest, version: '1', arch: x64}

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4

- uses: julia-actions/setup-julia@v1
- uses: julia-actions/setup-julia@v2
with:
version: ${{ matrix.version }}
arch: ${{ matrix.arch }}

- uses: actions/cache@v1
env:
cache-name: cache-artifacts
with:
path: ~/.julia/artifacts
key: ${{ runner.os }}-test-${{ env.cache-name }}-${{ hashFiles('**/Project.toml') }}
restore-keys: |
${{ runner.os }}-test-${{ env.cache-name }}-
${{ runner.os }}-test-
${{ runner.os }}-
- uses: julia-actions/cache@v2

- run: |
git config --global user.name Tester
Expand Down
9 changes: 2 additions & 7 deletions .github/workflows/Documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,10 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: julia-actions/setup-julia@latest
with:
version: '1'
- uses: julia-actions/cache@v2
- name: Install dependencies
run: |
julia --project=docs/ -e '
using Pkg
Pkg.develop([PackageSpec(path=joinpath(pwd(), "InlineTest")),
PackageSpec(path=pwd())])
Pkg.instantiate()'
julia --project=docs/ -e 'using Pkg; Pkg.instantiate()'
- name: Build and deploy
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
Expand Down
6 changes: 4 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
name = "ReTest"
uuid = "e0db7c4e-2690-44b9-bad6-7687da720f89"
authors = ["Rafael Fourquet <[email protected]>"]
version = "0.3.3"
version = "0.3.4"

[deps]
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
InlineTest = "bd334432-b1e7-49c7-a2dc-dd9149e4ebd6"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Sockets = "6462fe0b-24de-5631-8697-dd941f90decc"
Expand All @@ -14,7 +15,8 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
[compat]
InlineTest = "=0.2.0"
Revise = "3.1"
julia = "1"
PrecompileTools = "1.2.1"
julia = "1.10"

[extras]
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
Expand Down
4 changes: 4 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ ReTest = "e0db7c4e-2690-44b9-bad6-7687da720f89"

[compat]
Documenter = "1"

[sources]
ReTest = { path = ".." }
InlineTest = { path = "../InlineTest" }
5 changes: 3 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using Documenter, ReTest

makedocs(sitename = "ReTest.jl",
modules = [ReTest, ReTest.InlineTest])
makedocs(; sitename = "ReTest.jl",
modules = [ReTest, ReTest.InlineTest],
warnonly=[:missing_docs])


deploydocs(
Expand Down
33 changes: 17 additions & 16 deletions src/ReTest.jl
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,10 @@ const ArgType = Union{Module,PatternX,AbstractString,AbstractArray,Tuple,Symbol,
Pair{Module,
<:Union{PatternX,AbstractString,AbstractArray,Tuple}}}

# Holds the seed to set before each testset. This is not thread-safe, but it's
# not normal/intended to call retest() concurrently anyway.
const test_seed = Ref{Any}(false)

const retest_defaults = (
dry = false,
stats = false,
Expand Down Expand Up @@ -1089,22 +1093,12 @@ function retest(@nospecialize(args::ArgType...);
end

if seed !== false
let seedstr =
if seed === true
# seed!(nothing) doesn't work on old Julia, so we can't just set
# `seed = nothing` and interpolate `seed` directly in includestr
""
else
string(seed)
end,
includestr = """
using Random
Random.seed!($seedstr)
nothing
"""
# can't use `@everywhere using Random`, as here is not toplevel
@everywhere Base.include_string(Main, $includestr)
end
includestr = """
import ReTest
ReTest.test_seed[] = $seed
"""

@everywhere Base.include_string(Main, $includestr)
end

@sync for wrkr in workers()
Expand Down Expand Up @@ -1413,6 +1407,11 @@ function process_args(@nospecialize(args);
# tests is passed to retest in order to run tests in its submodules
filter!(m -> isdefined(m, INLINE_TEST), modules)

# Remove the precompilation module if we're not precompiling
if ccall(:jl_generating_output, Cint, ()) == 0
filter!(m -> nameof(m) !== :_ReTestPrecompileTests, modules)
end

shuffle && shuffle!(modules)

########## process verbose
Expand Down Expand Up @@ -1749,4 +1748,6 @@ function runtests(tests::String="")
Pkg.test("ReTest", test_args=Vector{String}(split(tests)))
end

include("precompile.jl")

end # module ReTest
50 changes: 50 additions & 0 deletions src/precompile.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import PrecompileTools: @setup_workload, @compile_workload

module _ReTestPrecompile
const x = 1
end

module _ReTestPrecompileTests
import .._ReTestPrecompile
using ..ReTest

@testset "precompilation workload" begin
@test _ReTestPrecompile.x == 1
@test false
end

end # _ReTestPrecompileTestsModule


@setup_workload begin
stderr_pipe = Pipe()
stdout_pipe = Pipe()

@compile_workload begin
try
redirect_stdio(; stderr=stderr_pipe, stdout=stdout_pipe) do
retest(_ReTestPrecompile, _ReTestPrecompileTests; recursive=false, stats=true, spin=true)
end
catch ex
close(stderr_pipe.in)
close(stdout_pipe.in)

if !(ex isa Test.TestSetException)
stdout_str = read(stdout_pipe, String)
stderr_str = read(stderr_pipe, String)

@error "Precompilation failed, this is the captured stdout ($(length(stdout_str)) chars):"
println(stdout_str)

@error "And this is the captured stderr ($(length(stderr_str)) chars):"
println(stderr_str)

rethrow()
end
finally
empty!(ReTest.TESTED_MODULES)
close(stderr_pipe)
close(stdout_pipe)
end
end
end
49 changes: 32 additions & 17 deletions src/testset.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ using Distributed: myid, nworkers

import InlineTest: @testset

import ..ReTest
using ..ReTest: Pattern, Marks, matches, setresult!

# mostly copied from Test stdlib
Expand Down Expand Up @@ -514,17 +515,19 @@ function testset_beginend(mod::Module, isfinal::Bool, pat::Pattern, id::Int64, d
put!($(chan.preview), ($id, $desc))
end
push_testset(ts)

# we reproduce the logic of guardseed, but this function
# cannot be used as it changes slightly the semantic of @testset,
# by wrapping the body in a function
local RNG = default_rng()
local oldrng = copy(RNG)
local default_rng_orig = copy(default_rng())
@static if VERSION >= v"1.11"
local tls_seed_orig = copy(Random.get_tls_seed())
end

try
# RNG is re-seeded with its own seed to ease reproduce a failed test
if VERSION >= v"1.7.0-DEV.1225"
Random.seed!(Random.GLOBAL_SEED)
else
Random.seed!(RNG.seed)
# RNG is re-seeded with the desired seed for the test
if ReTest.test_seed[] !== false
Random.seed!(ReTest.test_seed[])
end
let
ts.timed = @stats $stats $(esc(tests))
Expand All @@ -536,14 +539,19 @@ function testset_beginend(mod::Module, isfinal::Bool, pat::Pattern, id::Int64, d
record(ts, Error(:nontest_error, Expr(:tuple), err,
current_exceptions(), $(QuoteNode(source))))
finally
copy!(RNG, oldrng)
copy!(default_rng(), default_rng_orig)
@static if VERSION >= v"1.11"
copy!(Random.get_tls_seed(), tls_seed_orig)
end

setresult!($marks, ts.subject, !anyfailed(ts))
pop_testset()
ret = finish(ts, $chan)
end
ret
end
end

# preserve outer location if possible
if tests isa Expr && tests.head === :block &&
!isempty(tests.args) && tests.args[1] isa LineNumberNode
Expand Down Expand Up @@ -578,7 +586,7 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
break
end
# it's 1000 times faster to copy from tmprng rather than calling Random.seed!
copy!(RNG, tmprng)
copy!(default_rng(), tmprng)
end
ts = ts0
if nworkers() == 1 && get_testset_depth() == 0 && $(chan.preview) !== nothing
Expand All @@ -600,19 +608,22 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
end
end
end

quote
local arr = Vector{Any}()
local first_iteration = true
local iter = 0
local ts
local RNG = default_rng()
local oldrng = copy(RNG)
if VERSION >= v"1.7.0-DEV.1225"
Random.seed!(Random.GLOBAL_SEED)
else
Random.seed!(RNG.seed)

local default_rng_orig = copy(default_rng())
@static if VERSION >= v"1.11"
local tls_seed_orig = copy(Random.get_tls_seed())
end

local tmprng = copy(default_rng())
if ReTest.test_seed[] !== false
tmprng = copy(Random.seed!(ReTest.test_seed[]))
end
local tmprng = copy(RNG)
try
let
$(Expr(:for, Expr(:block, [esc(v) for v in loops]...), blk))
Expand All @@ -623,7 +634,11 @@ function testset_forloop(mod::Module, isfinal::Bool, pat::Pattern, id::Int64,
pop_testset()
push!(arr, finish(ts, $chan))
end
copy!(RNG, oldrng)

copy!(default_rng(), default_rng_orig)
@static if VERSION >= v"1.11"
copy!(Random.get_tls_seed(), tls_seed_orig)
end
end
arr
end
Expand Down
29 changes: 17 additions & 12 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function check(rx, list; implicit=false)
if implicit
expected = "Main.M\n" * expected
end
actual = readchomp(io)
actual = strip(readchomp(io))
if isempty(expected)
@test startswith(actual, "No matching tests for module")
else
Expand Down Expand Up @@ -1836,17 +1836,22 @@ end
restore_file!(load_path_file)
end

# test lazy=true
empty!(Hijack.RUN)
ReTest.hijack("./Hijack/test/lazy.jl", :HijackLazy, lazy=true)
retest(HijackLazy)
@test Hijack.RUN == [1, 3]

# test lazy=:brutal
empty!(Hijack.RUN)
ReTest.hijack("./Hijack/test/lazy.jl", :HijackBrutal, lazy=:brutal)
retest(HijackBrutal)
@test Hijack.RUN == [3]
# These two tests currently just spin forever
if false
@warn "Skipping some hijack tests because they cause Revise to get into an infinite loop"

# test lazy=true
empty!(Hijack.RUN)
ReTest.hijack("./Hijack/test/lazy.jl", :HijackLazy, lazy=true)
retest(HijackLazy)
@test Hijack.RUN == [1, 3]

# test lazy=:brutal
empty!(Hijack.RUN)
ReTest.hijack("./Hijack/test/lazy.jl", :HijackBrutal, lazy=:brutal)
retest(HijackBrutal)
@test Hijack.RUN == [3]
end

# test lazy=:wrong
empty!(Hijack.RUN)
Expand Down

2 comments on commit 52b8ad1

@JamesWrigley
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/123826

Tip: Release Notes

Did you know you can add release notes too? Just add markdown formatted text underneath the comment after the text
"Release notes:" and it will be added to the registry PR, and if TagBot is installed it will also be added to the
release that TagBot creates. i.e.

@JuliaRegistrator register

Release notes:

## Breaking changes

- blah

To add them here just re-invoke and the PR will be updated.

Tagging

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.3.4 -m "<description of version>" 52b8ad18cc2cdc420b03a1f43c07c4d2ec6a0769
git push origin v0.3.4

Please sign in to comment.