Skip to content

Commit 6acf73d

Browse files
ChrisRackauckas-ClaudeChrisRackauckasclaude
authored
Fix CI: gate MATLAB-runtime tests on engine availability; raise MATLAB floor to 0.8.1 (#83)
The Core and Downgrade jobs have been red because the MATLAB runtime is not available on CI runners: - Core (julia 1 / lts): matlab_runtime_tests.jl calls solve(prob, ode45()), which opens a MATLAB MSession. On any runner without a usable MATLAB engine (all GitHub-hosted runners, and self-hosted runners without a licensed engine) MSession throws UndefRefError, erroring the test. The interface and JET tests, which exercise this package's own logic without an engine, pass. Gate the engine-dependent solve calls on an actual capability probe (MATLAB.libmx_size > 0 plus a real MSession(0) attempt): run them where a working MATLAB engine exists (and assert they succeed), skip with an @info notice where it does not. The package logic tests still run unconditionally. - Downgrade (lts): the MATLAB compat floor "0.8" resolves MATLAB v0.8.0, whose __init__ unconditionally runs `which matlab` and errors when MATLAB is absent, so MATLABDiffEq cannot even precompile. v0.8.1 introduced the deps.jl / check_deps build mechanism with a CI fallback (libmx_size = 0) that loads gracefully without MATLAB. Raise the floor to "0.8.1" (drops only the broken v0.8.0 patch) so Downgrade resolves to a loadable MATLAB. Verified locally on Julia 1.12 (the "julia 1" channel) with CI=true and no MATLAB present: Core tests pass (interface 40/40, jet 34/34, runtime tests skipped with the @info notice). MATLAB v0.8.1 confirmed to load gracefully (libmx_size == 0) on Julia 1.10 with CI=true and no MATLAB installed. Co-authored-by: ChrisRackauckas-Claude <accounts@chrisrackauckas.com> Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b1cc7a7 commit 6acf73d

2 files changed

Lines changed: 61 additions & 34 deletions

File tree

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "MATLABDiffEq"
22
uuid = "e2752cbe-bcf4-5895-8727-84ebc14a76bd"
3-
version = "1.5.0"
3+
version = "1.5.1"
44

55
[deps]
66
DiffEqBase = "2b5f629d-d688-5b77-993f-72d75c75574e"
@@ -11,7 +11,7 @@ Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1111

1212
[compat]
1313
DiffEqBase = "6.122, 7"
14-
MATLAB = "0.8, 0.9, 0.10"
14+
MATLAB = "0.8.1, 0.9, 0.10"
1515
ModelingToolkit = "8, 9, 10, 11"
1616
ParameterizedFunctions = "5"
1717
PrecompileTools = "1.1"

test/matlab_runtime_tests.jl

Lines changed: 59 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,37 +1,64 @@
1-
# These tests require MATLAB runtime to be available.
2-
# They test the actual ODE solving functionality.
3-
using DiffEqBase, MATLABDiffEq, ParameterizedFunctions
1+
# These tests exercise the actual ODE solving functionality, which requires a
2+
# usable MATLAB engine. They are gated on the engine being startable: on CI
3+
# runners (and any machine without a licensed/working MATLAB) starting an
4+
# MSession is impossible, so the engine-dependent smoke tests are skipped with a
5+
# notice rather than failing. Where a working MATLAB engine is present the full
6+
# solve path runs and must succeed.
7+
using DiffEqBase, MATLABDiffEq, ParameterizedFunctions, MATLAB, Test
48

5-
f = @ode_def_bare LotkaVolterra begin
6-
dx = a * x - b * x * y
7-
dy = -c * y + d * x * y
8-
end a b c d
9-
p = [1.5, 1, 3, 1]
10-
tspan = (0.0, 10.0)
11-
u0 = [1.0, 1.0]
12-
prob = ODEProblem(f, u0, tspan, p)
13-
sol = solve(prob, MATLABDiffEq.ode45())
14-
15-
function lorenz(du, u, p, t)
16-
du[1] = 10.0(u[2] - u[1])
17-
du[2] = u[1] * (28.0 - u[3]) - u[2]
18-
return du[3] = u[1] * u[2] - (8 / 3) * u[3]
9+
# `libmx_size == 0` means MATLAB.jl was built without a MATLAB installation
10+
# (the build-time CI fallback), so the engine libraries were never loaded.
11+
# Even when libraries are present, starting an MSession can still fail (no
12+
# license, no display), so probe an actual session before running the solves.
13+
function matlab_engine_available()
14+
MATLAB.libmx_size > 0 || return false
15+
return try
16+
MATLAB.MSession(0)
17+
true
18+
catch
19+
false
20+
end
1921
end
20-
u0 = [1.0; 0.0; 0.0]
21-
tspan = (0.0, 100.0)
22-
prob = ODEProblem(lorenz, u0, tspan)
23-
sol = solve(prob, MATLABDiffEq.ode45())
2422

25-
algs = [
26-
MATLABDiffEq.ode23
27-
MATLABDiffEq.ode45
28-
MATLABDiffEq.ode113
29-
MATLABDiffEq.ode23s
30-
MATLABDiffEq.ode23t
31-
MATLABDiffEq.ode23tb
32-
MATLABDiffEq.ode15s
33-
]
23+
@testset "MATLAB runtime solve" begin
24+
if !matlab_engine_available()
25+
@info "MATLAB engine not available on this machine; skipping engine-dependent solve tests."
26+
else
27+
f = @ode_def_bare LotkaVolterra begin
28+
dx = a * x - b * x * y
29+
dy = -c * y + d * x * y
30+
end a b c d
31+
p = [1.5, 1, 3, 1]
32+
tspan = (0.0, 10.0)
33+
u0 = [1.0, 1.0]
34+
prob = ODEProblem(f, u0, tspan, p)
35+
sol = solve(prob, MATLABDiffEq.ode45())
36+
@test length(sol.t) > 0
37+
38+
function lorenz(du, u, p, t)
39+
du[1] = 10.0(u[2] - u[1])
40+
du[2] = u[1] * (28.0 - u[3]) - u[2]
41+
return du[3] = u[1] * u[2] - (8 / 3) * u[3]
42+
end
43+
u0 = [1.0; 0.0; 0.0]
44+
tspan = (0.0, 100.0)
45+
prob = ODEProblem(lorenz, u0, tspan)
46+
sol = solve(prob, MATLABDiffEq.ode45())
47+
@test length(sol.t) > 0
48+
49+
algs = [
50+
MATLABDiffEq.ode23
51+
MATLABDiffEq.ode45
52+
MATLABDiffEq.ode113
53+
MATLABDiffEq.ode23s
54+
MATLABDiffEq.ode23t
55+
MATLABDiffEq.ode23tb
56+
MATLABDiffEq.ode15s
57+
]
3458

35-
for alg in algs
36-
sol = solve(prob, alg())
59+
for alg in algs
60+
sol = solve(prob, alg())
61+
@test length(sol.t) > 0
62+
end
63+
end
3764
end

0 commit comments

Comments
 (0)