From 6fbdb1e90fa1549360cc66b9357bb6dff728c4be Mon Sep 17 00:00:00 2001 From: Davide Angelocola Date: Sun, 19 Jul 2026 09:13:27 +0200 Subject: [PATCH] test: tag Raincloud corpus tests @Tag("raincloud"), excluded by default MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A plain `./mvnw verify` silently ran the full real-world Raincloud corpus whenever a developer had hydrated it locally (via hydrate-raincloud-corpus.sh): the two Raincloud tests only gated real work behind `assumeTrue(Files.exists(manifestPath()))`, which is a no-op skip on CI (corpus never hydrated) but a surprise on a dev machine. In particular RaincloudSizeComparisonIntegrationTest — documented as purely informational — does a full Parquet->Vortex re-encode (FSST training, etc.) per slug, costing a release preflight 15+ minutes of unexpected CPU-heavy work. Make the exclusion explicit and controllable with JUnit 5 `@Tag`: - Tag both classes `@Tag("raincloud")`. - Failsafe `excludedGroups` (integration/pom.xml), bound to a new `vortex.it.excludedGroups` property defaulting to `raincloud`, so a routine build excludes them from test discovery entirely (stronger than assumeTrue's skip) yet the CLI can opt back in. Verified against a locally hydrated 10-slug corpus: - `./mvnw verify -pl integration -am` no longer discovers/runs either class. - Failsafe 3.5.6 applies `excludedGroups` even to an explicitly named `-Dit.test=Raincloud...` class, and a literal pom value cannot be cleared from the CLI — hence the property indirection. Opting in requires `-Dvortex.it.excludedGroups=` in addition to `-Dit.test`. The full conformance run (11 tests) passes end-to-end with that flag. Updated the documented invocations to include the flag: CLAUDE.md Commands section and the hydrate script's usage/output hints. No CHANGELOG entry: test/tooling-only churn, no change to shipped artifacts. Co-Authored-By: Claude Sonnet 5 --- .github/workflows/raincloud-conformance.yml | 2 +- CLAUDE.md | 11 +++++++++-- docs/compatibility.md | 2 +- integration/pom.xml | 15 +++++++++++++++ .../RaincloudConformanceIntegrationTest.java | 9 +++++++++ .../RaincloudSizeComparisonIntegrationTest.java | 9 +++++++++ scripts/hydrate-raincloud-corpus.sh | 7 +++++++ 7 files changed, 51 insertions(+), 4 deletions(-) diff --git a/.github/workflows/raincloud-conformance.yml b/.github/workflows/raincloud-conformance.yml index 1acdea37..d6f711af 100644 --- a/.github/workflows/raincloud-conformance.yml +++ b/.github/workflows/raincloud-conformance.yml @@ -51,7 +51,7 @@ jobs: run: scripts/hydrate-raincloud-corpus.sh --max-mb "${{ github.event.inputs.max-mb || '200' }}" - name: Run conformance suite - run: ./mvnw verify -pl integration -am -Dit.test=RaincloudConformanceIntegrationTest + run: ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test=RaincloudConformanceIntegrationTest - name: Publish per-slug results to job summary if: always() diff --git a/CLAUDE.md b/CLAUDE.md index 9aa6cf27..566f3148 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -63,10 +63,17 @@ Trunk-based. PRs fine but always squash or rebase — no merge commits. Keep com ./mvnw verify -pl integration -am # integration (failsafe, NOT surefire) ./mvnw verify -pl integration -am -Dit.test="RustWritesJavaReadsIntegrationTest#method" ./bench JavaVsJniReadBenchmark.javaReadVolume # benchmark — always ClassName.methodName filter -scripts/hydrate-raincloud-corpus.sh --max-mb 200 # hydrate real-world conformance corpus (#205), - # then verify -Dit.test=RaincloudConformanceIntegrationTest +scripts/hydrate-raincloud-corpus.sh --max-mb 200 # hydrate real-world conformance corpus (#205), then: +./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test="RaincloudConformanceIntegrationTest" ``` +The Raincloud corpus tests (`RaincloudConformanceIntegrationTest`, +`RaincloudSizeComparisonIntegrationTest`) are `@Tag("raincloud")` and excluded from a routine +`./mvnw verify` (failsafe `excludedGroups`, default `raincloud`) so a plain build never runs the +real corpus — even on a machine that has hydrated it locally. Opt in with +`-Dvortex.it.excludedGroups=` (clears the exclusion); this is required *in addition to* `-Dit.test`, +since the tag filter applies even to an explicitly named class. + Regenerate after editing `.fbs`/`.proto` (both generators are in-house, no external tools): ```bash diff --git a/docs/compatibility.md b/docs/compatibility.md index dcea9742..3858ec06 100644 --- a/docs/compatibility.md +++ b/docs/compatibility.md @@ -55,7 +55,7 @@ oracle) — a zero-diff proves every value survived the Python-write / Java-read ```bash scripts/hydrate-raincloud-corpus.sh --max-mb 200 # cache → mirror → local build -./mvnw verify -pl integration -am -Dit.test=RaincloudConformanceIntegrationTest +./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= -Dit.test=RaincloudConformanceIntegrationTest ``` Per-slug status lives in `integration/src/test/resources/raincloud/expected-status.csv` diff --git a/integration/pom.xml b/integration/pom.xml index 4721d649..c41726bc 100644 --- a/integration/pom.xml +++ b/integration/pom.xml @@ -14,6 +14,11 @@ true + + raincloud @@ -203,6 +208,16 @@ **/*IntegrationTest.java + + ${vortex.it.excludedGroups} @{argLine} --add-opens java.base/java.nio=ALL-UNNAMED diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java index 222b5dd9..62051c16 100644 --- a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java +++ b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudConformanceIntegrationTest.java @@ -12,6 +12,7 @@ import io.github.dfa1.vortex.csv.CsvExporter; import io.github.dfa1.vortex.csv.ExportOptions; import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.parallel.Execution; @@ -55,6 +56,14 @@ /// Expected per-slug status lives in `src/test/resources/raincloud/expected-status.csv`. /// Known gaps assert that the failure still occurs, so fixing the reader forces the /// matrix entry to flip to `ok` in the same change. +/// +/// Tagged `raincloud` and excluded from the default `./mvnw verify` (via the failsafe +/// `excludedGroups` configuration) so a routine build never runs the real corpus even on +/// a developer machine that has hydrated it locally. The exclusion applies even to an +/// explicit `-Dit.test=RaincloudConformanceIntegrationTest` selection, so running it +/// requires clearing the tag filter first: `-Dvortex.it.excludedGroups= +/// -Dit.test=RaincloudConformanceIntegrationTest`. +@Tag("raincloud") class RaincloudConformanceIntegrationTest { private static final Path DEFAULT_MANIFEST = diff --git a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java index 4269d494..c53a7c5f 100644 --- a/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java +++ b/integration/src/test/java/io/github/dfa1/vortex/integration/RaincloudSizeComparisonIntegrationTest.java @@ -2,6 +2,7 @@ import io.github.dfa1.vortex.parquet.ParquetImporter; import org.junit.jupiter.api.DynamicTest; +import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestFactory; import org.junit.jupiter.api.parallel.Execution; @@ -25,6 +26,14 @@ /// Skipped (visibly) when the corpus is not hydrated — run /// `scripts/hydrate-raincloud-corpus.sh` first, or point `RAINCLOUD_CORPUS_MANIFEST` /// at a manifest TSV (`slugvortex-pathparquet-path` per line). +/// +/// Tagged `raincloud` and excluded from the default `./mvnw verify` (via the failsafe +/// `excludedGroups` configuration): this purely-informational, CPU-heavy re-encode never +/// gates a routine build, even on a developer machine that has hydrated the corpus locally. +/// The exclusion applies even to an explicit `-Dit.test=RaincloudSizeComparisonIntegrationTest` +/// selection, so running it requires clearing the tag filter first: +/// `-Dvortex.it.excludedGroups= -Dit.test=RaincloudSizeComparisonIntegrationTest`. +@Tag("raincloud") class RaincloudSizeComparisonIntegrationTest { private static final Path DEFAULT_MANIFEST = diff --git a/scripts/hydrate-raincloud-corpus.sh b/scripts/hydrate-raincloud-corpus.sh index 6520585b..1b4f4261 100755 --- a/scripts/hydrate-raincloud-corpus.sh +++ b/scripts/hydrate-raincloud-corpus.sh @@ -10,6 +10,11 @@ # Usage: # scripts/hydrate-raincloud-corpus.sh [--max-mb N] [slug ...] # +# The conformance test is @Tag("raincloud") and excluded from a routine `./mvnw verify`, +# so after hydrating run it explicitly with the tag exclusion cleared: +# ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= \ +# -Dit.test=RaincloudConformanceIntegrationTest +# # With no slugs, hydrates every entry of the conformance matrix # (integration/src/test/resources/raincloud/expected-status.csv) whose combined # artifact size fits --max-mb (default 200; use --max-mb 0 for no size cap — the @@ -115,4 +120,6 @@ with open(os.environ["MANIFEST"], "w") as manifest: hydrated += 1 print(f"ok {slug}") print(f"\nhydrated={hydrated} skipped={skipped} manifest={os.environ['MANIFEST']}") +print("run: ./mvnw verify -pl integration -am -Dvortex.it.excludedGroups= " + "-Dit.test=RaincloudConformanceIntegrationTest") PY