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

@bric3 bric3 commented May 21, 2026

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.

bric3 and 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>
@bric3 bric3 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 owner May 21, 2026 14:48
@bric3 bric3 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.

@bric3 bric3 requested review from daniel-mohedano and jpbempel May 21, 2026 14:49
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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".

Comment thread dd-smoke-tests/gradle/src/test/java/datadog/smoketest/AbstractGradleTest.java Outdated
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 bric3 force-pushed the bdu/civis-groovy-to-java branch from f8d3d7b to 75b54e7 Compare May 21, 2026 15:19
@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - sbt-scalatest

Job Status: success

Scenario Overhead (%)
agent 54.31
agentEvpProxy 54.98

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - nebula-release-plugin

Job Status: success

Scenario Overhead (%)
agent 38.35
agentless 36.72
agentlessCodeCoverage 45.47
agentlessLineCoverage 76.27

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - netflix-zuul

Job Status: success

Scenario Overhead (%)
agent 87.61
agentless 80.94
agentlessCodeCoverage 96.04
agentlessLineCoverage 112.61

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - pass4s

Job Status: success

Scenario Overhead (%)
agent -0.27
agentless -1.49
agentlessCodeCoverage 6.55

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - reactive-streams-jvm

Job Status: success

Scenario Overhead (%)
agent 24.11
agentless 18.43
agentlessCodeCoverage 20.07
agentlessLineCoverage 30.65

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - sonar-kotlin

Job Status: success

Scenario Overhead (%)
agent 12.69
agentless 10.61
agentlessCodeCoverage 14.87
agentlessLineCoverage 18.62

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - jolokia

Job Status: success

Scenario Overhead (%)
agent 92.69
agentless 90.50
agentlessCodeCoverage 99.11
agentlessLineCoverage 99.93

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - okhttp

Job Status: success

Scenario Overhead (%)
agent 17.89
agentless 17.07
agentlessCodeCoverage 22.17
agentlessLineCoverage 44.82

@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - spring_boot

Job Status: success

Scenario Overhead (%)
agent 15.76
agentless 9.63
agentlessCodeCoverage 13.92
agentlessLineCoverage 32.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 bric3 force-pushed the bdu/civis-groovy-to-java branch from 3d74b53 to e7b65b2 Compare May 21, 2026 16:09
@cit-pr-commenter-54b7da
Copy link
Copy Markdown

cit-pr-commenter-54b7da Bot commented May 21, 2026

Test Environment - sonar-java

Job Status: success

Scenario Overhead (%)
agent 17.22
agentless -15.25
agentlessCodeCoverage 48.43
agentlessLineCoverage 96.62

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

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

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".

bric3 and 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 bric3 force-pushed the bdu/civis-groovy-to-java branch from ad8dcc4 to 7d4c6e4 Compare May 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
Contributor Author

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!

Copy link
Copy Markdown
Contributor

@daniel-mohedano daniel-mohedano left a comment

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;
}
Copy link
Copy Markdown
Contributor

@daniel-mohedano daniel-mohedano May 22, 2026

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
Contributor Author

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-cf854d Bot merged commit 4bc4b92 into master May 22, 2026
568 checks passed
@gh-worker-dd-mergequeue-cf854d gh-worker-dd-mergequeue-cf854d Bot deleted the bdu/civis-groovy-to-java branch May 22, 2026 14:12
@github-actions github-actions Bot added this to the 1.63.0 milestone May 22, 2026
@bric3 bric3 mentioned this pull request May 22, 2026
15 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp: ci visibility Continuous Integration Visibility tag: ai generated Largely based on code generated by an AI or LLM tag: no release notes Changes to exclude from release notes type: refactoring

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants