From fd3c61ce18d550b0e6f1880e196bc049882d1496 Mon Sep 17 00:00:00 2001 From: ChrisRackauckas-Claude Date: Thu, 25 Jun 2026 07:50:17 -0400 Subject: [PATCH] QA: run_qa v1.6 form + ExplicitImports Convert the hand-rolled test/qa Aqua + ExplicitImports + JET block onto the SciMLTesting 1.6 run_qa form with ExplicitImports enabled. - qa.jl: `run_qa(FindFirstFunctions; explicit_imports = true, ...)` folds the Aqua.test_all checks, the package-wide JET pass (JET.test_package via `using JET`), and all six ExplicitImports checks into one call. Aqua.test_all with defaults passes (11/11), including the ambiguities check the old block ran with recursive=false; JET.report_package returns 0 reports so the standard test_package mode is clean. No aqua_broken / jet_broken / ei_broken needed. - ExplicitImports: the only finding is all_qualified_accesses_are_public, six Base internals accessed by qualification (GC.@preserve, Base.@propagate_inbounds, Base.Order, Base.RefValue, Base.libllvm_version, Base.llvmcall). Not public API and no public replacement, so ignored via ei_kwargs (source pkg: Base). The other five EI checks pass clean. - static_analysis_tests.jl: the existing granular JET report_call hot-path type-stability checks and the AllocCheck zero-allocation assertions are kept (run_qa's package-wide JET pass does not cover specific call signatures or allocations). Still in the QA group folder, so run_tests runs them. - test/qa/Project.toml: drop ExplicitImports (transitive via SciMLTesting); keep Aqua (the ambiguities sub-check's child process needs Aqua a direct dep), JET, AllocCheck; bump SciMLTesting compat to 1.6; add Test compat. Verified locally vs released SciMLTesting 1.6.0 on Julia 1.10 (lts), 1.11, and 1.12: QA/qa.jl 18/18 + QA/static_analysis_tests.jl 34/34, 0 Fail/Error/Broken. Co-Authored-By: Chris Rackauckas Co-Authored-By: Claude Opus 4.8 (1M context) --- test/qa/Project.toml | 5 ++-- test/qa/qa.jl | 22 ++++++++++++++++ .../{qa_tests.jl => static_analysis_tests.jl} | 25 +++++-------------- 3 files changed, 30 insertions(+), 22 deletions(-) create mode 100644 test/qa/qa.jl rename test/qa/{qa_tests.jl => static_analysis_tests.jl} (85%) diff --git a/test/qa/Project.toml b/test/qa/Project.toml index f2a10e9..2045966 100644 --- a/test/qa/Project.toml +++ b/test/qa/Project.toml @@ -1,7 +1,6 @@ [deps] AllocCheck = "9b6a8646-10ed-4001-bbdc-1d2f46dfbb1a" Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" -ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7" FindFirstFunctions = "64ca27bc-2ba2-4a57-88aa-44e436879224" JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b" SafeTestsets = "1bc83da4-3b8d-516f-aca4-4fe02f6d838f" @@ -11,8 +10,8 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [compat] AllocCheck = "0.1, 0.2" Aqua = "0.8" -ExplicitImports = "1.14" FindFirstFunctions = "1, 2.1, 3" JET = "0.9, 0.10, 0.11" SafeTestsets = "0.0.1, 0.1" -SciMLTesting = "1" +SciMLTesting = "1.6" +Test = "1.10" diff --git a/test/qa/qa.jl b/test/qa/qa.jl new file mode 100644 index 0000000..3e47319 --- /dev/null +++ b/test/qa/qa.jl @@ -0,0 +1,22 @@ +using SciMLTesting, FindFirstFunctions, JET, Test + +run_qa( + FindFirstFunctions; + explicit_imports = true, + ei_kwargs = (; + # All six are Base internals accessed by qualification (GC.@preserve, + # Base.@propagate_inbounds, Base.Order, Base.RefValue, Base.libllvm_version, + # Base.llvmcall). They are not public API, so ExplicitImports flags the + # qualified accesses; there is no public replacement. Source pkg: Base. + all_qualified_accesses_are_public = (; + ignore = ( + Symbol("@preserve"), + Symbol("@propagate_inbounds"), + :Order, + :RefValue, + :libllvm_version, + :llvmcall, + ), + ), + ), +) diff --git a/test/qa/qa_tests.jl b/test/qa/static_analysis_tests.jl similarity index 85% rename from test/qa/qa_tests.jl rename to test/qa/static_analysis_tests.jl index 6261514..1829b9f 100644 --- a/test/qa/qa_tests.jl +++ b/test/qa/static_analysis_tests.jl @@ -1,23 +1,10 @@ -using FindFirstFunctions, Aqua, ExplicitImports, JET, AllocCheck, Test - -@testset "Aqua" begin - Aqua.find_persistent_tasks_deps(FindFirstFunctions) - Aqua.test_ambiguities(FindFirstFunctions, recursive = false) - Aqua.test_deps_compat(FindFirstFunctions) - Aqua.test_piracies(FindFirstFunctions) - Aqua.test_project_extras(FindFirstFunctions) - Aqua.test_stale_deps(FindFirstFunctions) - Aqua.test_unbound_args(FindFirstFunctions) - Aqua.test_undefined_exports(FindFirstFunctions) -end +using FindFirstFunctions, JET, AllocCheck, Test -@testset "ExplicitImports" begin - @test check_no_implicit_imports(FindFirstFunctions) === nothing - @test check_no_stale_explicit_imports(FindFirstFunctions) === nothing -end +# Beyond the package-wide JET pass in run_qa (qa.jl), assert type stability on the +# specific hot-path call signatures, and assert they allocate nothing — guarantees +# `JET.test_package` / `Aqua` do not make on their own. -@testset "JET static analysis" begin - vec_int64 = Int64[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +@testset "JET static analysis (hot-path signatures)" begin vec_float64 = Float64[1.0, 2.0, 3.0, 4.0, 5.0] # findfirstequal - fast SIMD-based search @@ -126,7 +113,7 @@ end end @testset "searchsorted_last via enum tag" begin - # Each kind on Int64 / Float64 dense vectors: no allocations. + # Each kind on Int64 dense vectors: no allocations. for kind in ( KIND_BINARY_BRACKET, KIND_LINEAR_SCAN, KIND_BRACKET_GALLOP, KIND_EXP_FROM_LEFT,