From 081904345a10a1d60024d338bf6340497a5d0a16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=ABl?= Date: Thu, 6 Aug 2026 10:15:50 +0200 Subject: [PATCH] ci: give each screenshot test class its own JVM There are five screenshot test classes (PreviewShard1..4Test plus PreviewA11yTest) and each shard renders roughly 770 previews in a single process. Gradle reuses a forked JVM for the next test class once maxParallelForks is exhausted, so on the current six-core runners (forks = 3) two classes run second, inside a process that has already rendered a full shard. That matches the observed failure exactly: PreviewShard2Test and PreviewShard4Test fail 100% while shards 1 and 3 pass 100%, and the split holds even for byte-identical preview states. The previous eight-core runners computed forks = 4, reused only one JVM, and were green on this same tree. forkEvery = 1 restarts the JVM after every test class. It costs five JVM startups and no extra peak memory, unlike raising maxParallelForks to 5, which would need 10 GB of test heap on a 19 GiB runner with no swap. Claude-Session: https://claude.ai/code/session_01MQbp1EPM4TSXq8P8Pyq44F --- build.gradle.kts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/build.gradle.kts b/build.gradle.kts index 0e0df9dbc6..2ea2561289 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -156,6 +156,17 @@ allprojects { if (isScreenshotTest) { // Increase heap size for screenshot tests maxHeapSize = "2g" + // Give every screenshot test class its own JVM. + // + // There are 5 screenshot classes (PreviewShard1..4Test + PreviewA11yTest) and each + // shard renders ~770 previews in a single process. Gradle reuses a forked JVM for the + // next class once maxParallelForks is exhausted, so on a 6-core runner (forks = 3) two + // classes run second, in a process that has already rendered a full shard — and they + // render differently from how the goldens were recorded. That is exactly the observed + // failure: shards 2 and 4 fail 100% while 1 and 3 pass 100%, deterministically, for + // byte-identical states. The 8-core runner (forks = 4) reused only one JVM and was green + // on the same tree. Restarting per class costs 5 JVM startups and no extra peak memory. + forkEvery = 1L // Record all the languages? if (project.hasProperty("allLanguagesNoEnglish")) { // Do not record English language