From acb0579a76ec7c1303a484d8be9969eed888337f Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Tue, 9 Jun 2026 18:10:30 -0400 Subject: [PATCH 1/4] Canonical CI: grouped-tests.yml + root test/test_groups.toml Convert the root test workflow (CI.yml) to the canonical thin caller of SciML/.github/.github/workflows/grouped-tests.yml@v1, declaring its group x version matrix once in test/test_groups.toml. - CI.yml: replace the hand-maintained group x version matrix job with the reusable grouped-tests.yml caller (coverage:false; on:/triggers preserved verbatim). Linux-only (no os axis). - test/test_groups.toml: [Core] on [lts,1,pre] (reproduces the old matrix exactly) + newly-wired [QA] on [lts,1]. - runtests.jl: add GROUP dispatch (existing suite is Core/All; GROUP==QA runs the isolated QA env). - test/qa/{Project.toml,qa.jl}: isolated Aqua + JET environment running Aqua.test_all(FEniCS) and JET.test_package(FEniCS; target_defined_modules=true). - Project.toml: raise [compat] julia 1.6 -> 1.10 (LTS floor); add Test = "1" compat for the test-only extra (benign metadata fixes). Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/CI.yml | 28 +++++----------------------- Project.toml | 3 ++- test/qa/Project.toml | 14 ++++++++++++++ test/qa/qa.jl | 9 +++++++++ test/runtests.jl | 12 +++++++++++- test/test_groups.toml | 5 +++++ 6 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 test/qa/Project.toml create mode 100644 test/qa/qa.jl create mode 100644 test/test_groups.toml diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 8fedc89..1942eaf 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -11,26 +11,8 @@ on: paths-ignore: - 'docs/**' jobs: - test: - runs-on: ubuntu-latest - container: - image: cmhyett/julia-fenics:latest - - strategy: - fail-fast: false - matrix: - group: - - Core - version: - - 'lts' - - '1' - - 'pre' - steps: - - uses: actions/checkout@v6 - - - uses: julia-actions/setup-julia@v3 - with: - version: ${{ matrix.version }} - - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 + tests: + uses: "SciML/.github/.github/workflows/grouped-tests.yml@v1" + with: + coverage: false + secrets: "inherit" diff --git a/Project.toml b/Project.toml index b13eb0c..30cc190 100644 --- a/Project.toml +++ b/Project.toml @@ -18,7 +18,8 @@ ProgressMeter = "1.2" PyCall = "1.90" Requires = "0.5, 1.0" SpecialFunctions = "0.8, 0.9, 1.2, 2" -julia = "1.6" +Test = "1" +julia = "1.10" [extras] ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" diff --git a/test/qa/Project.toml b/test/qa/Project.toml new file mode 100644 index 0000000..d68cc46 --- /dev/null +++ b/test/qa/Project.toml @@ -0,0 +1,14 @@ +[deps] +Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" +FEniCS = "186dfeec-b415-5c13-8e76-5fbf19f56f9b" +JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" + +[sources] +FEniCS = {path = "../.."} + +[compat] +Aqua = "0.8" +JET = "0.9,0.10,0.11" +Test = "1" +julia = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl new file mode 100644 index 0000000..3cd50d1 --- /dev/null +++ b/test/qa/qa.jl @@ -0,0 +1,9 @@ +using FEniCS, Aqua, JET, Test + +@testset "Aqua" begin + Aqua.test_all(FEniCS) +end + +@testset "JET" begin + JET.test_package(FEniCS; target_defined_modules = true) +end diff --git a/test/runtests.jl b/test/runtests.jl index 4691c1f..2462c36 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,16 @@ -using FEniCS using Test +const GROUP = get(ENV, "GROUP", "All") + +if GROUP == "QA" + @testset "Quality Assurance" begin + include(joinpath(@__DIR__, "qa", "qa.jl")) + end + exit() +end + +using FEniCS + FEniCS.set_log_level(FEniCS.WARNING) @testset "Explicit Imports" begin diff --git a/test/test_groups.toml b/test/test_groups.toml new file mode 100644 index 0000000..1fe84cd --- /dev/null +++ b/test/test_groups.toml @@ -0,0 +1,5 @@ +[Core] +versions = ["lts", "1", "pre"] + +[QA] +versions = ["lts", "1"] From 5ec5475ae2b77d449924473e4045e853c7a343d8 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Wed, 10 Jun 2026 06:27:29 -0400 Subject: [PATCH 2/4] Restore FEniCS container (cmhyett/julia-fenics:latest) in grouped-tests caller The grouped-tests conversion dropped the Docker container the pre-conversion CI ran in, so every Core job failed with the FEniCS Python stack missing. Pass it through the new container input of grouped-tests.yml. Depends on SciML/.github#86 merging and a v1 retag. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/CI.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 1942eaf..37f9e8a 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -15,4 +15,5 @@ jobs: uses: "SciML/.github/.github/workflows/grouped-tests.yml@v1" with: coverage: false + container: "cmhyett/julia-fenics:latest" secrets: "inherit" From 2ccaa9462ecb500092afca99bb16999711de8699 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sat, 13 Jun 2026 06:36:26 -0400 Subject: [PATCH 3/4] ci: re-trigger grouped-tests after SciML/.github@v1 gained container input The grouped-tests caller passes container: cmhyett/julia-fenics:latest, which was unsupported by SciML/.github grouped-tests.yml@v1 at the time of the last run (startup_failure on 2026-06-10). v1 now resolves to v1.13.0, which adds the container input, so re-run CI to validate. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) From aa098cd79d29445a795b0d9ef6ae455ce68dd3ce Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Sun, 14 Jun 2026 19:57:11 -0400 Subject: [PATCH 4/4] Adopt SciMLTesting v1.2 folder-based run_tests (on top of grouped-tests conversion) Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- Project.toml | 6 +++- test/core.jl | 53 +++++++++++++++++++++++++++++ test/qa/Project.toml | 4 +++ test/runtests.jl | 80 ++++++++++---------------------------------- 4 files changed, 79 insertions(+), 64 deletions(-) create mode 100644 test/core.jl diff --git a/Project.toml b/Project.toml index 30cc190..5ecd8e7 100644 --- a/Project.toml +++ b/Project.toml @@ -17,6 +17,8 @@ OrdinaryDiffEqSDIRK = "1, 2" ProgressMeter = "1.2" PyCall = "1.90" Requires = "0.5, 1.0" +SafeTestsets = "0.1, 1" +SciMLTesting = "1" SpecialFunctions = "0.8, 0.9, 1.2, 2" Test = "1" julia = "1.10" @@ -26,7 +28,9 @@ ADTypes = "47edcb42-4c32-4615-8424-f2b9edc5f35b" ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed" OrdinaryDiffEqSDIRK = "2d112036-d095-4a1e-ab9a-08536f3ecdbf" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["ADTypes", "ExplicitImports", "Test", "OrdinaryDiffEq", "OrdinaryDiffEqSDIRK"] +test = ["ADTypes", "ExplicitImports", "Test", "OrdinaryDiffEq", "OrdinaryDiffEqSDIRK", "SafeTestsets", "SciMLTesting"] diff --git a/test/core.jl b/test/core.jl new file mode 100644 index 0000000..a77d777 --- /dev/null +++ b/test/core.jl @@ -0,0 +1,53 @@ +using FEniCS +using Test + +FEniCS.set_log_level(FEniCS.WARNING) + +@testset "Explicit Imports" begin + include("explicit_imports.jl") +end + +examples_dir = joinpath(@__DIR__, "..", "examples") +@assert ispath(examples_dir) +example_filenames = readdir(examples_dir) +@assert "tutorial1.jl" in example_filenames + +@testset "Example $(filename)" for filename in example_filenames + path = joinpath(examples_dir, filename) + @test (include(path); true) + # Test that PyCall is not used in the example. + # Use of PyCall indicates, that we did not wrap enough + # functionality + s = read(path, String) + @test !occursin("PyCall", s) +end + +@testset "Creation" begin + @test include("test_create.jl") + @test include("test_pycreate.jl") + @test include("test_jfem.jl") +end + +@testset "assign" begin + mesh = UnitIntervalMesh(10) + V = FunctionSpace(mesh, "P", 1) + u = interpolate(Expression("x[0]", degree = 1), V) + arr1 = get_array(u) + arr2 = randn(size(arr1)) + assign(u, arr2) + @test get_array(u) == arr2 + assign(u, arr1) + @test get_array(u) == arr1 +end + +#tests relating to interface.jl file +@testset "Interface" begin + global mesh = UnitSquareMesh(2, 2) + dbc(x, y) = 1 + global u = feMesh(mesh, dbc) + @test (u.n_nodes == 9) + @test (u.n_elements == 8) + @test (u.n_internal_nodes == 1) + @test (u.n_boundary_nodes == 8) + @test (u.node_vals == [1, 1, 1, 1, 0, 1, 1, 1, 1]) +end diff --git a/test/qa/Project.toml b/test/qa/Project.toml index d68cc46..55d7844 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -2,6 +2,8 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" FEniCS = "186dfeec-b415-5c13-8e76-5fbf19f56f9b" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" +SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" +SciMLTesting = "09d9d899-5365-40a9-917a-5f67fddea283" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [sources] @@ -10,5 +12,7 @@ FEniCS = {path = "../.."} [compat] Aqua = "0.8" JET = "0.9,0.10,0.11" +SafeTestsets = "0.1, 1" +SciMLTesting = "1" Test = "1" julia = "1.10" diff --git a/test/runtests.jl b/test/runtests.jl index 2462c36..b5c4068 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,63 +1,17 @@ -using Test - -const GROUP = get(ENV, "GROUP", "All") - -if GROUP == "QA" - @testset "Quality Assurance" begin - include(joinpath(@__DIR__, "qa", "qa.jl")) - end - exit() -end - -using FEniCS - -FEniCS.set_log_level(FEniCS.WARNING) - -@testset "Explicit Imports" begin - include("explicit_imports.jl") -end - -examples_dir = joinpath(@__DIR__, "..", "examples") -@assert ispath(examples_dir) -example_filenames = readdir(examples_dir) -@assert "tutorial1.jl" in example_filenames - -@testset "Example $(filename)" for filename in example_filenames - path = joinpath(examples_dir, filename) - @test (include(path); true) - # Test that PyCall is not used in the example. - # Use of PyCall indicates, that we did not wrap enough - # functionality - s = read(path, String) - @test !occursin("PyCall", s) -end - -@testset "Creation" begin - @test include("test_create.jl") - @test include("test_pycreate.jl") - @test include("test_jfem.jl") -end; - -@testset "assign" begin - mesh = UnitIntervalMesh(10) - V = FunctionSpace(mesh, "P", 1) - u = interpolate(Expression("x[0]", degree = 1), V) - arr1 = get_array(u) - arr2 = randn(size(arr1)) - assign(u, arr2) - @test get_array(u) == arr2 - assign(u, arr1) - @test get_array(u) == arr1 -end - -#tests relating to interface.jl file -@testset "Interface" begin - global mesh = UnitSquareMesh(2, 2) - dbc(x, y) = 1 - global u = feMesh(mesh, dbc) - @test (u.n_nodes == 9) - @test (u.n_elements == 8) - @test (u.n_internal_nodes == 1) - @test (u.n_boundary_nodes == 8) - @test (u.node_vals == [1, 1, 1, 1, 0, 1, 1, 1, 1]) -end; +using SciMLTesting + +run_tests(; + # Core orchestrates the example sweep and inline FEniCS testsets in a single + # body (core.jl) rather than as independent per-file groups, so it is passed + # explicitly instead of being discovered as a folder. + core = joinpath(@__DIR__, "core.jl"), + groups = Dict( + "QA" => (; + env = joinpath(@__DIR__, "qa"), + body = joinpath(@__DIR__, "qa", "qa.jl"), + ), + ), + # The original ran only the Core body for the default GROUP="All"; QA ran only + # when explicitly selected (it exited early before loading FEniCS). + all = ["Core"], +)