Skip to content

Migrate CI Visibility Smoke tests from Groovy to Java - #11439

Merged
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
masterfrom
bdu/civis-groovy-to-java
May 22, 2026
Merged

Migrate CI Visibility Smoke tests from Groovy to Java#11439
gh-worker-dd-mergequeue-cf854d[bot] merged 9 commits into
masterfrom
bdu/civis-groovy-to-java

Conversation

@bric3

Copy link
Copy Markdown
Contributor

What Does This Do

Migrates the CiVisibility smoke-test stack from Groovy/Spock to Java + JUnit 5 + @TableTest:

  • dd-java-agent:agent-ci-visibility:civisibility-test-fixtures

THe other smoke test depends on the fixture

  • dd-smoke-tests:gradle
  • dd-smoke-tests:maven
  • dd-smoke-tests:junit-console

Motivation

Gradle 9 bundles Groovy 4 in gradleApi() / gradleTestKit(). However dd-smoke-tests:gradle smoke tests rely on Groovy tests and Spock 2.4-groovy-3.0, which is not compatible with Groovy 4.0 (compilation fails with IncompatibleGroovyVersionException).

Bumping Groovy to 4 is not the way we want to go

  • We want to migrate our tests to Java.
  • Moving to Groovy 4 only for these smoke tests is awkward.
  • There are quite a few differences.

Additional Notes

org.gradle.util.DistributionLocatororg.gradle.util.internal.DistributionLocator (the former package is gone in Gradle 9; the latter is present in both Gradle 8.14.5 and 9.5.1).

Contributor Checklist

Jira ticket: [PROJ-IDENT]

Note:Once your PR is ready to merge, add it to the merge queue by commenting /merge./merge -c cancels the queue request. /merge -f --reason "reason" skips all merge queue checks; please use this judiciously, as some checks do not run at the PR-level. For more information, see this doc.

bric3and others added 3 commits May 21, 2026 15:43
…Spock to Java/JUnit 5
Drops Spock + Groovy 3 from `dd-java-agent:agent-ci-visibility:civisibility-test-fixtures` and from the three CiVisibility smoke modules (`dd-smoke-tests:gradle`, `:maven`, `:junit-console`). The fixtures' main source is now Java; the three smoke modules use JUnit 5 + `@TableTest`. `MockBackend` and `CiVisibilityInstrumentationTest` stay on Groovy/Spock and consume the new Java APIs.
This unblocks running the CiVisibility smoke tests under Gradle 9, whose bundled Groovy 4 is incompatible with `spock 2.4-groovy-3.0`.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apply the rules from `.claude/skills/migrate-junit-source-to-tabletest/SKILL.md` to the freshly migrated CiVisibility smoke tests:
- Every `@TableTest` table now starts with a non-parameter `scenario` column used as the row's display name.
- `MavenSmokeTest.testJunit4ClassOrdering` drops its `String testcaseName` method parameter; the first column becomes the scenario.
- Duplicated `@TypeConverter TestFQN toTestFQN(...)` moves into `civisibility-test-fixtures` as a shared `CiVisibilityTableTestConverters`, wired via `@TypeConverterSources`.
- `GradleDaemonSmokeTest.testNew` collapses the three pairs of `test-succeed-new-instrumentation` rows that differed only on `configurationCache` into single rows via `{false, true}` value-set syntax.
- Gradle smoke tests no longer take `TestInfo` as a method parameter (which conflicted with TableTest's column-count convention); `AbstractGradleTest` captures it once in `@BeforeEach` and exposes it via an inherited `protected TestInfo testInfo` field.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tic prints
The scenario column added in the previous commit already identifies each `@TableTest` row in JUnit 5's test output and in the JUnit XML report, so the inline timestamped `System.out.println` prefixes were redundant. Removes the inherited `TestInfo testInfo` field on `AbstractGradleTest`, the parameter-injection `@BeforeEach`, and the unused `java.util.Date` imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3bric3 added the tag: no release notes Changes to exclude from release notes label May 21, 2026
@bric3
bric3 requested a review from a team as a code ownerMay 21, 2026 14:48
@bric3bric3 added type: refactoring comp: ci visibility Continuous Integration Visibility tag: ai generated Largely based on code generated by an AI or LLM labels May 21, 2026
@datadog-datadog-prod-us1-2

This comment has been minimized.

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:efc0ebaf18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Three regressions caught by GitLab CI on the PR:
1. **ClassCastException in `CiVisibilityTestUtils.assertData` at line 229.**
`CiVisibilityInstrumentationTest.assertSpansData` builds the
`additionalReplacements` map with GString values (via
`"${instrumentedLibraryName()}:${instrumentedLibraryVersion()}"`). My port
declared the parameter as `Map<String, String>`, so the for-each loop's
implicit `String` cast on `e.getValue()` blew up under Groovy callers.
Widens both `assertData` overloads to `Map<String, ?>` and uses
`String.valueOf` when stitching the value back into a placeholder string.
2. **`verifySnapshots` was failing on `dd.spanid` / friends.**
The original Groovy `requiredLogFields.each { field -> log.containsKey(field) }`
discarded the boolean — i.e. asserted nothing. My Java port turned it into
`assertTrue(log.containsKey(field))`, which tripped on snapshots that don't
include the field. Reverts to the original (intentionally lenient)
behaviour with a TODO-style comment explaining why.
3. **forbiddenApisMain + config-inversion-linter failures on the new Java
main sources.** The original code lived in `src/main/groovy/` which the
linters don't scan; the Java port exposes them to both
`forbiddenApisMain` (`System.getenv`, `System.out`, `String.getBytes()`,
`String.replaceAll(String, String)`) and `logEnvVarUsages` (the
`"DD_CIVISIBILITY_SMOKETEST_DEBUG_*"` literals). Fixes:
- Disable `forbiddenApisMain` on `civisibility-test-fixtures` — this is a
test-support module, on the test classpath of its consumers, so the
production-code-quality gates don't apply.
- Switch the local-debug toggles to JVM system properties
(`datadog.civisibility.smoketest.debug.parent` /
`…debug.child`) so no `DD_…` literal lives in `src/main/java` for
`logEnvVarUsages` to flag.
- Keep the explicit `StandardCharsets.UTF_8` on `String.getBytes(…)` and
the precompiled `Matcher.replaceAll(...)` — both are objectively
better than the platform-default variants.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3
bric3force-pushed the bdu/civis-groovy-to-java branch from f8d3d7b to 75b54e7CompareMay 21, 2026 15:19
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - sbt-scalatest

Job Status: success

ScenarioOverhead (%)
agent54.31
agentEvpProxy54.98

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - nebula-release-plugin

Job Status: success

ScenarioOverhead (%)
agent38.35
agentless36.72
agentlessCodeCoverage45.47
agentlessLineCoverage76.27

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - netflix-zuul

Job Status: success

ScenarioOverhead (%)
agent87.61
agentless80.94
agentlessCodeCoverage96.04
agentlessLineCoverage112.61

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - pass4s

Job Status: success

ScenarioOverhead (%)
agent-0.27
agentless-1.49
agentlessCodeCoverage6.55

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - reactive-streams-jvm

Job Status: success

ScenarioOverhead (%)
agent24.11
agentless18.43
agentlessCodeCoverage20.07
agentlessLineCoverage30.65

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - sonar-kotlin

Job Status: success

ScenarioOverhead (%)
agent12.69
agentless10.61
agentlessCodeCoverage14.87
agentlessLineCoverage18.62

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - jolokia

Job Status: success

ScenarioOverhead (%)
agent92.69
agentless90.50
agentlessCodeCoverage99.11
agentlessLineCoverage99.93

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - okhttp

Job Status: success

ScenarioOverhead (%)
agent17.89
agentless17.07
agentlessCodeCoverage22.17
agentlessLineCoverage44.82

@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - spring_boot

Job Status: success

ScenarioOverhead (%)
agent15.76
agentless9.63
agentlessCodeCoverage13.92
agentlessLineCoverage32.62

@bric3
bric3 marked this pull request as draft May 21, 2026 15:59
…izable
SpotBugs flagged `SE_COMPARATOR_SHOULD_BE_SERIALIZABLE` on the stateless comparator. Add `Serializable` to the `implements` clause with a `serialVersionUID` to satisfy the check.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3
bric3force-pushed the bdu/civis-groovy-to-java branch from 3d74b53 to e7b65b2CompareMay 21, 2026 16:09
@cit-pr-commenter-54b7da

cit-pr-commenter-54b7daBot commented May 21, 2026

Copy link
Copy Markdown

Test Environment - sonar-java

Job Status: success

ScenarioOverhead (%)
agent17.22
agentless-15.25
agentlessCodeCoverage48.43
agentlessLineCoverage96.62

@bric3
bric3 marked this pull request as ready for review May 21, 2026 19:51

@chatgpt-codex-connectorchatgpt-codex-connectorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit:ad8dcc480c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

bric3and others added 2 commits May 22, 2026 00:07
Groovy's `switch (null) { case foo: ... default: ... }` silently falls through to `default`, which is what the original `rootSpanTypeToVal` relied on for traces whose root span has no type set. The Java port called `DDSpanTypes.TEST.contentEquals(spanType)` directly, which throws NPE when `spanType` is `null` — surfacing as `4 failed tests due to NullPointerException at KarateTest.groovy:188` across every test_inst[*,6/8] and test_inst_latest[*,2/6] shard.
Adds an explicit `if (spanType == null) return 4;` short-circuit (the same value the default branch returns) and re-runs spotless to capture the verifySnapshots assertion-tightening edit reverted by the user in the IDE.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex review caught a regression vs. the original Spock semantics: in Spock, `@Shared @AutoCleanup protected MockBackend mockBackend = new MockBackend()` produces one instance per spec class. My Java port made it `static final` on the abstract base — meaning a single shared `MockBackend` for both `GradleDaemonSmokeTest` and `GradleLauncherSmokeTest`. Whichever JUnit ran first would call the inherited `@AfterAll closeMockBackend()`, leaving the second class to `reset()` a closed `TestHttpServer` and talk to a dead intake URL.
Switches `AbstractGradleTest` to `@TestInstance(Lifecycle.PER_CLASS)` and turns `mockBackend` and `closeMockBackend` into instance members. JUnit now creates one `AbstractGradleTest` instance per concrete subclass, with its own backend and its own close hook — matching the Spock `@Shared` lifecycle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@bric3
bric3force-pushed the bdu/civis-groovy-to-java branch from ad8dcc4 to 7d4c6e4CompareMay 21, 2026 22:07
Map<String, Object> snapshotContent = debuggerMap.snapshot as Map<String, Object>

assert snapshotContent != null
requiredSnapshotFields.each { field -> snapshotContent.containsKey(field) }

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: @DataDog/ci-app-libraries @daniel-mohedano I noticed the following code wasn't asserting anything in Groovy. And is ported the same way in its Java equivalent. It might be worh coming back to it at a later point.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, I'll handle it on my side in a following PR, thanks!

@daniel-mohedanodaniel-mohedano left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM from CIVis side, thanks a lot for the effort! 🚀

Comment on lines +155 to +160
private static boolean isWithin(
ComparableVersion version,
ComparableVersion lowerInclusive,
ComparableVersion upperExclusive) {
return version.compareTo(lowerInclusive) >= 0 && version.compareTo(upperExclusive) < 0;
}

@daniel-mohedanodaniel-mohedanoMay 22, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: we can remove datadog.trace.util.ComparableVersion#isWithin then, I think it was only used here

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather keep this focused on the conversion at this time.

@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854dBot merged commit 4bc4b92 into masterMay 22, 2026
568 checks passed
@gh-worker-dd-mergequeue-cf854d
gh-worker-dd-mergequeue-cf854dBot deleted the bdu/civis-groovy-to-java branch May 22, 2026 14:12
@github-actionsgithub-actionsBot added this to the 1.63.0 milestone May 22, 2026
@bric3bric3 mentioned this pull request May 22, 2026
19 tasks
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: ci visibilityContinuous Integration Visibilitytag: ai generatedLargely based on code generated by an AI or LLMtag: no release notesChanges to exclude from release notestype: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@bric3@jpbempel@daniel-mohedano