From 2a5d36ac529f6f4dd48e8223fb7e9c291374ac82 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Mon, 6 Jul 2026 14:00:43 +0200 Subject: [PATCH] faster ci (#25966) --- koch.nim | 13 +++++-- testament/categories.nim | 66 +++++++++++++++----------------- testament/testament.nim | 7 +++- tests/async/t14820.nim | 4 +- tests/async/tasyncclosestall.nim | 2 +- 5 files changed, 50 insertions(+), 42 deletions(-) diff --git a/koch.nim b/koch.nim index 4a3f4ae9ae..4364cfa254 100644 --- a/koch.nim +++ b/koch.nim @@ -669,7 +669,16 @@ proc runCI(cmd: string) = # boot without -d:nimHasLibFFI to make sure this still works # `--lib:lib` is needed for bootstrap on openbsd, for reasons described in # https://github.com/nim-lang/Nim/pull/14291 (`getAppFilename` bugsfor older nim on openbsd). - kochExecFold("Boot Nim ORC", "boot -d:release -d:nimStrictMode --lib:lib") + # + # Bootstrap exactly once per platform. The refc-mm bootstrap is a + # platform-independent compiler-correctness check, so Linux uses it as its sole + # boot (and then runs the whole suite against the refc-built compiler), while + # the other platforms cover the default ORC bootstrap. `koch` is rebuilt + # per-runner, so `when defined(linux)` selects the Linux job at compile time. + when defined(linux): + kochExecFold("Boot Nim refc", "boot -d:release --mm:refc -d:nimStrictMode --lib:lib") + else: + kochExecFold("Boot Nim ORC", "boot -d:release -d:nimStrictMode --lib:lib") when false: # debugging: when you need to run only 1 test in CI, use something like this: execFold("debugging test", "nim r tests/stdlib/tosproc.nim") @@ -723,8 +732,6 @@ proc runCI(cmd: string) = execFold("build nimsuggest_testing", "nim c -o:bin/nimsuggest_testing -d:release nimsuggest/nimsuggest") execFold("Run nimsuggest tests", "nim r nimsuggest/tester") - kochExecFold("Testing booting in refc", "boot -d:release --mm:refc -d:nimStrictMode --lib:lib") - proc testUnixInstall(cmdLineRest: string) = csource("-d:danger" & cmdLineRest) diff --git a/testament/categories.nim b/testament/categories.nim index d6abb6691e..17e9a48a86 100644 --- a/testament/categories.nim +++ b/testament/categories.nim @@ -116,56 +116,52 @@ proc dllTests(r: var TResults, cat: Category, options: string) = # ------------------------------ GC tests ------------------------------------- proc gcTests(r: var TResults, cat: Category, options: string) = - template testWithoutMs(filename: untyped) = - testSpec r, makeTest("tests/gc" / filename, options & "--mm:refc", cat) - testSpec r, makeTest("tests/gc" / filename, options & - " -d:release -d:useRealtimeGC --mm:refc", cat) - when filename != "gctest": - testSpec r, makeTest("tests/gc" / filename, options & - " --gc:orc", cat) - testSpec r, makeTest("tests/gc" / filename, options & - " --gc:orc -d:release", cat) - - template testWithoutBoehm(filename: untyped) = - testWithoutMs filename - testSpec r, makeTest("tests/gc" / filename, options & - " --gc:markAndSweep", cat) - testSpec r, makeTest("tests/gc" / filename, options & - " -d:release --gc:markAndSweep", cat) + template run(filename, extraOptions: untyped) = + testSpec r, makeTest("tests/gc" / filename, options & extraOptions, cat) + # The matrix every gc test file goes through: refc (debug + realtime-release) + # and orc (debug + release). This is the coverage we actually rely on today. template test(filename: untyped) = - testWithoutBoehm filename - when not defined(windows) and not defined(android) and not defined(osx): - # boehm library linking broken on macos 13 - # AR: cannot find any boehm.dll on the net, right now, so disabled - # for windows: - testSpec r, makeTest("tests/gc" / filename, options & - " --gc:boehm", cat) - testSpec r, makeTest("tests/gc" / filename, options & - " -d:release --gc:boehm", cat) + run filename, " --mm:refc" + run filename, " -d:release -d:useRealtimeGC --mm:refc" + run filename, " --gc:orc" + run filename, " --gc:orc -d:release" - testWithoutBoehm "foreign_thr" + # markAndSweep and boehm are legacy collectors. Exercising them for every gc + # test file tripled this category's CI cost for little added signal, so only + # `gctest` keeps them alive. `gctest` does not build under orc. + template testLegacyGc(filename: untyped) = + run filename, " --mm:refc" + run filename, " -d:release -d:useRealtimeGC --mm:refc" + run filename, " --gc:markAndSweep" + run filename, " -d:release --gc:markAndSweep" + when not defined(windows) and not defined(android) and not defined(osx): + # boehm linking is broken on macOS 13 and there is no usable boehm.dll for + # Windows, so those platforms skip it. + run filename, " --gc:boehm" + run filename, " -d:release --gc:boehm" + + testLegacyGc "gctest" + + test "foreign_thr" test "gcemscripten" test "growobjcrash" test "gcbench" test "gcleak" test "gcleak2" - testWithoutBoehm "gctest" test "gcleak3" test "gcleak4" # Disabled because it works and takes too long to run: #test "gcleak5" - testWithoutBoehm "weakrefs" + test "weakrefs" test "cycleleak" - testWithoutBoehm "closureleak" - testWithoutMs "refarrayleak" - - testWithoutBoehm "tlists" - testWithoutBoehm "thavlak" - + test "closureleak" + test "refarrayleak" + test "tlists" + test "thavlak" test "stackrefleak" test "cyclecollector" - testWithoutBoehm "trace_globals" + test "trace_globals" test "tfinalizers" # ------------------------- threading tests ----------------------------------- diff --git a/testament/testament.nim b/testament/testament.nim index a0e1f910ed..73af243c57 100644 --- a/testament/testament.nim +++ b/testament/testament.nim @@ -777,7 +777,12 @@ proc main() = if kind == pcDir and cat notin ["testdata", "nimcache"]: cats.add cat if isNimRepoTests(): - cats.add AdditionalCategories + # `ic` and `navigator` are real `tests/` dirs (already collected above) *and* + # listed in AdditionalCategories; without this guard they'd run twice, which + # doubled the (expensive) `ic` category on every `all` run. `debugger`, + # `examples` and `lib` have no matching `tests/` dir, so they are still added. + for cat in AdditionalCategories: + if cat notin cats: cats.add cat if useMegatest: cats.add MegaTestCat var cmds: seq[string] = @[] diff --git a/tests/async/t14820.nim b/tests/async/t14820.nim index 359884468e..2161a4b6d3 100644 --- a/tests/async/t14820.nim +++ b/tests/async/t14820.nim @@ -13,7 +13,7 @@ import asyncdispatch, times var done = false proc somethingAsync() {.async.} = - yield sleepAsync 5000 + yield sleepAsync 1000 echo "async done" done = true @@ -21,5 +21,5 @@ asyncCheck somethingAsync() var count = 0 while not done: count += 1 - drain 1000 + drain 200 echo "iteration: ", count diff --git a/tests/async/tasyncclosestall.nim b/tests/async/tasyncclosestall.nim index 566523a726..05348587c1 100644 --- a/tests/async/tasyncclosestall.nim +++ b/tests/async/tasyncclosestall.nim @@ -13,7 +13,7 @@ else: # This reproduces a case where a socket remains stuck waiting for writes # even when the socket is closed. const - timeout = 8000 + timeout = 2000 var port = Port(0) var sent = 0