Skip to content

Commit ac3c5a6

Browse files
ChrisRackauckas-ClaudeChrisRackauckasclaude
authored
Use SciMLTesting v1.2 folder-based run_tests (#521)
Replace the hand-written GROUP dispatch in test/runtests.jl with the SciMLTesting v1.2 folder-discovery entry point (`using SciMLTesting; run_tests()`), restructuring the suite into group folders: * Core = top-level test/*.jl @safetestset wrappers (each includes its self-contained body from test/bodies/, which in turn includes the shared preamble test/shared/test_setup.jl). benchmarks_valid.jl is a new Core wrapper reproducing the master "Benchmarks are valid" testset (it includes the package's benchmarking/benchmarks.jl). * ModelingToolkitSIExt = test/ModelingToolkitSIExt/ with its own sub-env Project.toml declaring the extension trigger weakdeps (ModelingToolkitBase, SymbolicUtils, Symbolics) plus Nemo/ SpecialFunctions/TestSetExtensions, replacing the dynamic Pkg.add("ModelingToolkit") the old runtests did for this group. * QA = test/qa/qa.jl, run in the main test env (Aqua stays in root [extras], as on master — no qa sub-env is invented). * test/shared/test_setup.jl and test/bodies/ are non-group folders, never auto-discovered. The exact set of tests run under each GROUP value (All, Core, QA, ModelingToolkitSIExt) is unchanged from master: Core runs the 44 non-QA top-level test files plus the benchmarks testset; QA runs qa.jl; All adds the ModelingToolkit extension test; ModelingToolkitSIExt runs that test. Add SciMLTesting (+ SafeTestsets) to the root test deps and the ext sub-env; drop Pkg from the root test deps (the harness owns all Pkg operations now). test/test_groups.toml is unchanged. Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 69d0c3b commit ac3c5a6

97 files changed

Lines changed: 4697 additions & 4487 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Project.toml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,12 @@ MacroTools = "0.5"
4444
ModelingToolkitBase = "1.12"
4545
Nemo = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55"
4646
ParamPunPam = "0.5.5"
47-
Pkg = "1.10, 1.11"
4847
PrecompileTools = "1.2"
4948
Primes = "0.5"
5049
Random = "1.10, 1.11"
5150
RationalFunctionFields = "0.3.1"
51+
SafeTestsets = "0.0.1, 0.1"
52+
SciMLTesting = "1"
5253
SpecialFunctions = "2"
5354
SymbolicUtils = "4"
5455
Symbolics = "7"
@@ -61,12 +62,13 @@ julia = "1.10.4, 1.11.2"
6162
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
6263
CPUSummary = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9"
6364
ModelingToolkitBase = "7771a370-6774-4173-bd38-47e70ca0b839"
64-
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
65+
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
66+
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
6567
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
6668
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
6769
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
6870
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6971
TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04"
7072

7173
[targets]
72-
test = ["Aqua", "CPUSummary", "Pkg", "SpecialFunctions", "Test", "TestSetExtensions"]
74+
test = ["Aqua", "CPUSummary", "SafeTestsets", "SciMLTesting", "SpecialFunctions", "Test", "TestSetExtensions"]
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
[deps]
2+
ModelingToolkitBase = "7771a370-6774-4173-bd38-47e70ca0b839"
3+
Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a"
4+
SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f"
5+
SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283"
6+
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
7+
StructuralIdentifiability = "220ca800-aa68-49bb-acd8-6037fa93a544"
8+
SymbolicUtils = "d1185830-fcd6-423d-90d6-eec64667417b"
9+
Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7"
10+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
11+
TestSetExtensions = "98d24dd4-01ad-11ea-1b02-c9a08f80db04"
12+
13+
[sources]
14+
StructuralIdentifiability = { path = "../.." }
15+
16+
[compat]
17+
ModelingToolkitBase = "1.12"
18+
Nemo = "0.46, 0.47, 0.48, 0.49, 0.50, 0.51, 0.52, 0.53, 0.54, 0.55"
19+
SafeTestsets = "0.0.1, 0.1"
20+
SciMLTesting = "1"
21+
SpecialFunctions = "2"
22+
SymbolicUtils = "4"
23+
Symbolics = "7"
24+
Test = "1"
25+
TestSetExtensions = "2, 3, 4"
26+
julia = "1.10.4, 1.11.2"
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@safetestset "ModelingToolkit interface" begin
2+
include(joinpath(@__DIR__, "..", "bodies", "extensions", "modelingtoolkit.jl"))
3+
end

test/benchmarks_valid.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@safetestset "Benchmarks are valid" begin
2+
include(joinpath(@__DIR__, "bodies", "benchmarks_valid.jl"))
3+
end

test/bodies/benchmarks_valid.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
@testset "Benchmarks are valid" verbose = true begin
4+
# https://github.com/pogudingleb/RationalFunctionFields.jl uses this
5+
include(joinpath(dirname(dirname(pathof(StructuralIdentifiability))), "benchmarking", "benchmarks.jl"))
6+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
if GROUP == "All" || GROUP == "Core"
4+
@testset "Primality check (zerodim subroutine)" begin
5+
R, (x, y) = Nemo.polynomial_ring(Nemo.QQ, ["x", "y"])
6+
7+
@test check_primality_zerodim([x^2 - 1, y^2 - 4]) == false
8+
9+
@test check_primality_zerodim([(x + 5) * (x^3 - 7), y - 3]) == false
10+
11+
@test check_primality_zerodim([x^3 - 5, y - 1]) == true
12+
13+
@test check_primality_zerodim([x^2 + 1, y^3 - 3 * x + x + 5]) == true
14+
15+
# not prime over any modulous but prime over Q
16+
@test check_primality_zerodim([x, y^4 + 1]) == true
17+
end
18+
end

test/bodies/common_ring.jl

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
if GROUP == "All" || GROUP == "Core"
4+
@testset "Computing common ring for the PB-reduction" begin
5+
ode = @ODEmodel(x1'(t) = x2(t), x2'(t) = a * x1(t), y(t) = x1(t))
6+
ioeqs = find_ioequations(ode)
7+
pbr = PBRepresentation(ode, ioeqs)
8+
R, (y_2, y_5, c) = Nemo.polynomial_ring(Nemo.QQ, ["y(t)_2", "y(t)_5", "c"])
9+
p = y_2^2 + c * y_5
10+
(r, der) = common_ring(p, pbr)
11+
@test Set(map(var_to_str, gens(r))) ==
12+
Set(["y(t)_0", "y(t)_1", "y(t)_2", "y(t)_3", "y(t)_4", "y(t)_5", "c", "a"])
13+
14+
ode = @ODEmodel(
15+
x1'(t) = x3(t),
16+
x2'(t) = a * x2(t),
17+
x3'(t) = x1(t),
18+
y1(t) = x1(t),
19+
y2(t) = x2(t) + u(t)
20+
)
21+
ioeqs = find_ioequations(ode)
22+
pbr = PBRepresentation(ode, ioeqs)
23+
R, (y1_0, y2_3, u_3) =
24+
Nemo.polynomial_ring(Nemo.QQ, ["y1(t)_0", "y2(t)_3", "u(t)_3"])
25+
p = y1_0 + y2_3 + u_3
26+
(r, der) = common_ring(p, pbr)
27+
@test Set([var_to_str(v) for v in gens(r)]) == Set(
28+
[
29+
"y1(t)_0",
30+
"y1(t)_1",
31+
"y1(t)_2",
32+
"y1(t)_3",
33+
"y1(t)_4",
34+
"y2(t)_0",
35+
"y2(t)_1",
36+
"y2(t)_2",
37+
"y2(t)_3",
38+
"u(t)_0",
39+
"u(t)_1",
40+
"u(t)_2",
41+
"u(t)_3",
42+
"a",
43+
]
44+
)
45+
end
46+
end
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
if GROUP == "All" || GROUP == "Core"
4+
@testset "Decomposing derivative" begin
5+
cases = [
6+
["yy_11", ["y", "yy", "yy_"], ("yy", 11)],
7+
["xx_xx_xx_0", ["xx", "x", "xx_xx_xx"], ("xx_xx_xx", 0)],
8+
["abc154f", ["ab", "abc"], nothing],
9+
["c_1542673", ["a", "b", "c"], ("c", 1542673)],
10+
["a", ["a"], nothing],
11+
]
12+
for c in cases
13+
@test decompose_derivative(c[1], c[2]) == c[3]
14+
end
15+
end
16+
end

test/bodies/det_minor_expansion.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
if GROUP == "All" || GROUP == "Core"
4+
@testset "Determinant by minor expansion" begin
5+
for d in 1:5
6+
for testcase in 1:10
7+
mat_space = Nemo.matrix_space(Nemo.QQ, d, d)
8+
rnd_matrix = mat_space([mod(rand(Int), 1000) for i in 1:d, j in 1:d])
9+
@test det(rnd_matrix) == det_minor_expansion(rnd_matrix)
10+
end
11+
end
12+
end
13+
end
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
include(joinpath(@__DIR__, "..", "shared", "test_setup.jl"))
2+
3+
if GROUP == "All" || GROUP == "Core"
4+
@testset "Computing variations around a sequence solution" begin
5+
# Computing sensitivities directly be explicitly writing down Lie derivatives
6+
function use_lie_derivatives(
7+
dds::StructuralIdentifiability.DDS{P},
8+
params::Dict{P, T},
9+
ic::Dict{P, T},
10+
input_values::Dict{P, Array{T, 1}},
11+
num_terms::Int,
12+
) where {T <: Generic.FieldElem, P <: MPolyRingElem{T}}
13+
newvars = [var_to_str(v) for v in gens(parent(dds))]
14+
append!(
15+
newvars,
16+
[var_to_str(v) * "$i" for v in inputs(dds) for i in 1:num_terms],
17+
)
18+
R, _ = StructuralIdentifiability.Nemo.polynomial_ring(
19+
base_ring(parent(dds)),
20+
newvars,
21+
)
22+
explicit_sol = merge(
23+
Dict(
24+
parent_ring_change(x, R) => Vector{Any}([parent_ring_change(x, R)])
25+
for (x, eq) in x_equations(dds)
26+
),
27+
Dict(
28+
parent_ring_change(y, R) =>
29+
Vector{Any}([parent_ring_change(eq, R)]) for
30+
(y, eq) in y_equations(dds)
31+
),
32+
)
33+
time_step = merge(
34+
Dict(
35+
parent_ring_change(x, R) => parent_ring_change(eq, R) for
36+
(x, eq) in x_equations(dds)
37+
),
38+
Dict(
39+
parent_ring_change(p, R) => parent_ring_change(p, R) for
40+
p in StructuralIdentifiability.parameters(dds)
41+
),
42+
Dict(
43+
parent_ring_change(u, R) => str_to_var(var_to_str(u) * "1", R) for
44+
u in inputs(dds)
45+
),
46+
Dict(
47+
str_to_var(s * "$i", R) => str_to_var(s * "$(i + 1)", R) for
48+
s in map(var_to_str, inputs(dds)) for i in 1:(num_terms - 1)
49+
),
50+
)
51+
eval_dict = merge(
52+
Dict(parent_ring_change(p, R) => v for (p, v) in params),
53+
Dict(parent_ring_change(x, R) => v for (x, v) in ic),
54+
Dict(parent_ring_change(u, R) => val[1] for (u, val) in input_values),
55+
Dict(
56+
str_to_var(var_to_str(u) * "$i", R) => input_values[u][i + 1] for
57+
u in inputs(dds) for i in 1:(num_terms - 1)
58+
),
59+
)
60+
generalized_parameters = [
61+
parent_ring_change(p, R) for
62+
p in vcat(x_vars(dds), StructuralIdentifiability.parameters(dds))
63+
]
64+
for i in 2:num_terms
65+
for (k, v) in explicit_sol
66+
push!(explicit_sol[k], eval_at_dict(v[end], time_step))
67+
end
68+
end
69+
part_diffs = Dict(
70+
(f, p) => [] for f in keys(explicit_sol) for p in generalized_parameters
71+
)
72+
for i in 1:num_terms
73+
for (f, ders) in explicit_sol
74+
for p in generalized_parameters
75+
push!(
76+
part_diffs[(f, p)],
77+
eval_at_dict(derivative(ders[i], p), eval_dict),
78+
)
79+
end
80+
end
81+
end
82+
return Dict(
83+
(
84+
parent_ring_change(k[1], parent(dds)),
85+
parent_ring_change(k[2], parent(dds)),
86+
) => res for (k, res) in part_diffs
87+
)
88+
end
89+
90+
locQQ = StructuralIdentifiability.Nemo.QQ
91+
92+
dds = @DDSmodel(a(t + 1) = a(t)^2 + b, y(t) = 1 / (a(t) * c(t)))
93+
params = Dict(b => locQQ(1))
94+
ic = Dict(a => locQQ(2))
95+
input_values = Dict(c => [locQQ(1), locQQ(-2), locQQ(3), locQQ(-4), locQQ(5)])
96+
seq_sol, diff_sol =
97+
differentiate_sequence_solution(dds, params, ic, input_values, 4)
98+
diff_y = differentiate_sequence_output(dds, params, ic, input_values, 4)
99+
lie_ders_sol = use_lie_derivatives(dds, params, ic, input_values, 4)
100+
merged = merge(diff_sol, diff_y)
101+
@test merged == lie_ders_sol
102+
103+
dds = @DDSmodel(
104+
a(t + 1) =
105+
(23 * k1 * a(t) - 7 * b(t)^3) // (a(t)^2 + b(t)^2) - c(t)^3 * k1 * b(t),
106+
b(t + 1) = a(t) + 17 * (b(t) - c(t))^2 + 1 // (a(t) + b(t) - k2),
107+
y(t) = (a(t) + b(t) - c(t)) // (a(t)^2 + k2)
108+
)
109+
params = Dict(k1 => locQQ(1), k2 => locQQ(2))
110+
ic = Dict(a => locQQ(3), b => locQQ(-4))
111+
input_values = Dict(c => [locQQ(5), locQQ(-6), locQQ(7), locQQ(-8)])
112+
seq_sol, diff_sol =
113+
differentiate_sequence_solution(dds, params, ic, input_values, 2)
114+
diff_y = differentiate_sequence_output(dds, params, ic, input_values, 2)
115+
lie_ders_sol = use_lie_derivatives(dds, params, ic, input_values, 2)
116+
merged = merge(diff_sol, diff_y)
117+
@test merged == lie_ders_sol
118+
end
119+
end

0 commit comments

Comments
 (0)