Skip to content

Commit 8829765

Browse files
authored
Merge branch 'master' into dougqh/collection-benchmarks
2 parents bd48676 + 4368dcf commit 8829765

20 files changed

Lines changed: 319 additions & 163 deletions

File tree

.claude/skills/migrate-groovy-to-java/SKILL.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
name: migrate-groovy-to-java
3-
description: migrate test groovy files to java
3+
description: >
4+
Converts Spock/Groovy test files in a Gradle module to equivalent JUnit 5 Java tests.
5+
Use when asked to "migrate groovy", "convert groovy to java", "g2j", or when a module
6+
has .groovy test files that need to be replaced with .java equivalents.
47
---
58

69
Migrate test Groovy files to Java using JUnit 5
@@ -18,6 +21,8 @@ When converting Groovy code to Java code, make sure that:
1821
- Ensure parameterized test names are human-readable (i.e. no hashcodes); instead add a description string as the first `Arguments.arguments(...)` value or index the test case
1922
- When converting tuples, create a light dedicated structure instead to keep the typing system
2023
- Instead of checking a state and throwing an exception, use JUnit asserts
24+
- Instead of using `assertTrue(a.equals(b))` or `assertFalse(a.equals(b))`, use `assertEquals(expected, actual)` and `assertNotEquals(unexpected, actual)`
25+
- Import frequently used types rather than using fully-qualified names inline, to improve readability
2126
- Do not wrap checked exceptions and throw a Runtime exception; prefer adding a throws clause at method declaration
2227
- Do not mark local variables `final`
2328
- Ensure variables are human-readable; avoid single-letter names and pre-define variables that are referenced multiple times
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
issuer: https://token.actions.githubusercontent.com
2+
3+
subject: repo:DataDog/dd-trace-java:ref:refs/heads/master
4+
5+
claim_pattern:
6+
event_name: (schedule|workflow_dispatch)
7+
ref: refs/heads/master
8+
ref_protected: "true"
9+
job_workflow_ref: DataDog/dd-trace-java/\.github/workflows/update-smoke-test-latest-versions\.yaml@refs/heads/master
10+
11+
permissions:
12+
contents: write
13+
pull_requests: write

.github/workflows/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,14 @@ _Action:_ Create a PR updating the Grade dependencies and their locking files.
171171

172172
_Recovery:_ Manually trigger the action again.
173173

174+
### update-smoke-test-latest-versions [🔗](update-smoke-test-latest-versions.yaml)
175+
176+
_Trigger:_ Every week or manually.
177+
178+
_Action:_ Create a PR updating the pinned "latest" tool versions (Gradle, Maven, Maven Surefire) used by CI Visibility smoke tests.
179+
180+
_Recovery:_ Manually trigger the action again.
181+
174182
### update-jmxfetch-submodule [🔗](update-jmxfetch-submodule.yaml)
175183

176184
_Trigger:_ Monthly or manually
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
name: Update smoke test latest versions
2+
on:
3+
schedule:
4+
- cron: "0 5 * * 0"
5+
workflow_dispatch:
6+
7+
jobs:
8+
update-smoke-test-latest-versions:
9+
runs-on: ubuntu-latest
10+
name: Update smoke test latest versions
11+
permissions:
12+
contents: read
13+
id-token: write # Required for OIDC token federation
14+
steps:
15+
- uses: DataDog/dd-octo-sts-action@acaa02eee7e3bb0839e4272dacb37b8f3b58ba80 # v1.0.3
16+
id: octo-sts
17+
with:
18+
scope: DataDog/dd-trace-java
19+
policy: self.update-smoke-test-latest-versions.create-pr
20+
21+
- name: Checkout repository
22+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 6.0.2
23+
24+
- name: Define branch name
25+
id: define-branch
26+
run: |
27+
DATE=$(date +'%Y%m%d')
28+
echo "branch=ci/update-smoke-test-latest-versions-${DATE}" >> "$GITHUB_OUTPUT"
29+
30+
- name: Fetch latest Gradle version
31+
id: gradle
32+
run: |
33+
VERSION=$(curl -sf https://services.gradle.org/versions/current | jq -r '.version')
34+
if [ -z "$VERSION" ] || [ "$VERSION" = "null" ]; then
35+
echo "::error::Failed to fetch latest Gradle version"
36+
exit 1
37+
fi
38+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
39+
echo "Latest Gradle version: $VERSION"
40+
41+
- name: Fetch latest stable Maven version
42+
id: maven
43+
run: |
44+
METADATA=$(curl -sf https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/maven-metadata.xml)
45+
# Get all versions, filter out alpha/beta/rc, take the latest
46+
VERSION=$(echo "$METADATA" \
47+
| xmllint --xpath '//versions/version/text()' - 2>/dev/null \
48+
| tr ' ' '\n' \
49+
| grep -v -E '(alpha|beta|rc)' \
50+
| sort -V \
51+
| tail -1)
52+
if [ -z "$VERSION" ]; then
53+
echo "::error::Failed to fetch latest stable Maven version"
54+
exit 1
55+
fi
56+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
57+
echo "Latest stable Maven version: $VERSION"
58+
59+
- name: Fetch latest stable Maven Surefire version
60+
id: surefire
61+
run: |
62+
METADATA=$(curl -sf https://repo.maven.apache.org/maven2/org/apache/maven/plugins/maven-surefire-plugin/maven-metadata.xml)
63+
# Get all versions, filter out alpha/beta, take the latest
64+
VERSION=$(echo "$METADATA" \
65+
| xmllint --xpath '//versions/version/text()' - 2>/dev/null \
66+
| tr ' ' '\n' \
67+
| grep -v -E '(alpha|beta)' \
68+
| sort -V \
69+
| tail -1)
70+
if [ -z "$VERSION" ]; then
71+
echo "::error::Failed to fetch latest stable Maven Surefire version"
72+
exit 1
73+
fi
74+
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
75+
echo "Latest stable Maven Surefire version: $VERSION"
76+
77+
- name: Update properties files
78+
env:
79+
GRADLE_VERSION: ${{ steps.gradle.outputs.version }}
80+
MAVEN_VERSION: ${{ steps.maven.outputs.version }}
81+
SUREFIRE_VERSION: ${{ steps.surefire.outputs.version }}
82+
run: |
83+
printf '%s\n' \
84+
"# Pinned \"latest\" versions for CI Visibility Gradle smoke tests." \
85+
"# Updated automatically by the update-smoke-test-latest-versions workflow." \
86+
"gradle.version=${GRADLE_VERSION}" \
87+
> dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties
88+
89+
printf '%s\n' \
90+
"# Pinned \"latest\" versions for CI Visibility Maven smoke tests." \
91+
"# Updated automatically by the update-smoke-test-latest-versions workflow." \
92+
"maven.version=${MAVEN_VERSION}" \
93+
"maven-surefire.version=${SUREFIRE_VERSION}" \
94+
> dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties
95+
96+
- name: Check for changes
97+
id: check-changes
98+
run: |
99+
if [[ -z "$(git status -s)" ]]; then
100+
echo "No changes to commit."
101+
echo "has_changes=false" >> "$GITHUB_OUTPUT"
102+
else
103+
echo "has_changes=true" >> "$GITHUB_OUTPUT"
104+
fi
105+
106+
- name: Configure git
107+
if: steps.check-changes.outputs.has_changes == 'true'
108+
run: |
109+
git config user.name "github-actions[bot]"
110+
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
111+
112+
- name: Create commit
113+
if: steps.check-changes.outputs.has_changes == 'true'
114+
id: create-commit
115+
run: |
116+
git add dd-smoke-tests/gradle/src/test/resources/latest-tool-versions.properties \
117+
dd-smoke-tests/maven/src/test/resources/latest-tool-versions.properties
118+
git commit -m "chore: Update smoke test latest tool versions"
119+
echo "commit=$(git rev-parse HEAD)" >> "$GITHUB_OUTPUT"
120+
121+
- name: Push changes
122+
if: steps.check-changes.outputs.has_changes == 'true'
123+
uses: DataDog/commit-headless@05d7b7ee023e2c7d01c47832d420c2503cd416f3 # action/v2.0.3
124+
with:
125+
token: "${{ steps.octo-sts.outputs.token }}"
126+
branch: "${{ steps.define-branch.outputs.branch }}"
127+
head-sha: "${{ github.sha }}"
128+
create-branch: true
129+
command: push
130+
commits: "${{ steps.create-commit.outputs.commit }}"
131+
132+
- name: Create pull request
133+
if: steps.check-changes.outputs.has_changes == 'true'
134+
env:
135+
GH_TOKEN: ${{ steps.octo-sts.outputs.token }}
136+
run: |
137+
gh pr create --title "Update smoke test latest tool versions" \
138+
--base master \
139+
--head ${{ steps.define-branch.outputs.branch }} \
140+
--label "tag: dependencies" \
141+
--label "tag: no release notes" \
142+
--body "$(cat <<'EOF'
143+
# What Does This Do
144+
145+
This PR updates the pinned "latest" tool versions used by CI Visibility smoke tests:
146+
- Gradle: ${{ steps.gradle.outputs.version }}
147+
- Maven: ${{ steps.maven.outputs.version }}
148+
- Maven Surefire: ${{ steps.surefire.outputs.version }}
149+
150+
# Motivation
151+
152+
Keep smoke tests running against the latest stable versions of build tools.
153+
154+
# Contributor Checklist
155+
156+
- [ ] Verify smoke tests pass with the new versions
157+
EOF
158+
)"

dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/OtelInstrumentationScope.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
package datadog.opentelemetry.shim;
22

3+
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
34
import java.util.Objects;
45
import javax.annotation.Nullable;
56

67
/** Instrumentation scopes have a mandatory name, optional version, and optional schema URL. */
78
public final class OtelInstrumentationScope {
89

9-
private final String scopeName;
10-
@Nullable private final String scopeVersion;
11-
@Nullable private final String schemaUrl;
10+
private final UTF8BytesString scopeName;
11+
@Nullable private final UTF8BytesString scopeVersion;
12+
@Nullable private final UTF8BytesString schemaUrl;
1213

1314
public OtelInstrumentationScope(
1415
String scopeName, @Nullable String scopeVersion, @Nullable String schemaUrl) {
15-
this.scopeName = scopeName;
16-
this.scopeVersion = scopeVersion;
17-
this.schemaUrl = schemaUrl;
16+
this.scopeName = UTF8BytesString.create(scopeName);
17+
this.scopeVersion = UTF8BytesString.create(scopeVersion);
18+
this.schemaUrl = UTF8BytesString.create(schemaUrl);
1819
}
1920

20-
public String getName() {
21+
public UTF8BytesString getName() {
2122
return scopeName;
2223
}
2324

2425
@Nullable
25-
public String getVersion() {
26+
public UTF8BytesString getVersion() {
2627
return scopeVersion;
2728
}
2829

2930
@Nullable
30-
public String getSchemaUrl() {
31+
public UTF8BytesString getSchemaUrl() {
3132
return schemaUrl;
3233
}
3334

dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelInstrumentDescriptor.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,32 @@
11
package datadog.opentelemetry.shim.metrics;
22

3+
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
34
import java.util.Locale;
45
import java.util.Objects;
56
import javax.annotation.Nullable;
67

78
/** Uniquely describes an instrument for the Meter that created it. */
89
public final class OtelInstrumentDescriptor {
9-
private final String instrumentName;
10+
private final UTF8BytesString instrumentName;
1011
private final OtelInstrumentType instrumentType;
1112
private final boolean longValues;
12-
@Nullable private final String description;
13-
@Nullable private final String unit;
13+
@Nullable private final UTF8BytesString description;
14+
@Nullable private final UTF8BytesString unit;
1415

1516
OtelInstrumentDescriptor(
1617
String instrumentName,
1718
OtelInstrumentType instrumentType,
1819
boolean longValues,
1920
@Nullable String description,
2021
@Nullable String unit) {
21-
this.instrumentName = instrumentName;
22+
this.instrumentName = UTF8BytesString.create(instrumentName);
2223
this.instrumentType = instrumentType;
2324
this.longValues = longValues;
24-
this.description = description;
25-
this.unit = unit;
25+
this.description = UTF8BytesString.create(description);
26+
this.unit = UTF8BytesString.create(unit);
2627
}
2728

28-
public String getName() {
29+
public UTF8BytesString getName() {
2930
return instrumentName;
3031
}
3132

@@ -38,12 +39,12 @@ public boolean hasLongValues() {
3839
}
3940

4041
@Nullable
41-
public String getDescription() {
42+
public UTF8BytesString getDescription() {
4243
return description;
4344
}
4445

4546
@Nullable
46-
public String getUnit() {
47+
public UTF8BytesString getUnit() {
4748
return unit;
4849
}
4950

@@ -54,7 +55,7 @@ public boolean equals(Object o) {
5455
}
5556

5657
OtelInstrumentDescriptor that = (OtelInstrumentDescriptor) o;
57-
return instrumentName.equalsIgnoreCase(that.instrumentName)
58+
return instrumentName.toString().equalsIgnoreCase(that.instrumentName.toString())
5859
&& instrumentType == that.instrumentType
5960
&& longValues == that.longValues
6061
&& Objects.equals(description, that.description)
@@ -63,7 +64,7 @@ public boolean equals(Object o) {
6364

6465
@Override
6566
public int hashCode() {
66-
int result = instrumentName.toLowerCase(Locale.ROOT).hashCode();
67+
int result = instrumentName.toString().toLowerCase(Locale.ROOT).hashCode();
6768
result = 31 * result + instrumentType.hashCode();
6869
result = 31 * result + Boolean.hashCode(longValues);
6970
result = 31 * result + Objects.hashCode(description);

dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/data/OtelMetricStorage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import datadog.opentelemetry.shim.metrics.export.OtelInstrumentVisitor;
66
import datadog.trace.api.Config;
77
import datadog.trace.api.config.OtlpConfig;
8+
import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString;
89
import datadog.trace.relocate.api.RatelimitedLogger;
910
import io.opentelemetry.api.common.Attributes;
1011
import java.util.List;
@@ -89,7 +90,7 @@ public static OtelMetricStorage newHistogramStorage(
8990
return new OtelMetricStorage(descriptor, () -> new OtelHistogramSketch(bucketBoundaries));
9091
}
9192

92-
public String getInstrumentName() {
93+
public UTF8BytesString getInstrumentName() {
9394
return descriptor.getName();
9495
}
9596

dd-smoke-tests/gradle/src/test/groovy/datadog/smoketest/AbstractGradleTest.groovy

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,9 @@
11
package datadog.smoketest
22

3-
import com.fasterxml.jackson.databind.JsonNode
4-
import com.fasterxml.jackson.databind.ObjectMapper
53
import datadog.environment.JavaVirtualMachine
64
import datadog.trace.civisibility.CiVisibilitySmokeTest
75
import datadog.trace.util.ComparableVersion
8-
import okhttp3.OkHttpClient
9-
import okhttp3.Request
10-
import okhttp3.Response
116
import org.gradle.internal.impldep.org.apache.commons.io.FileUtils
12-
import org.gradle.util.GradleVersion
137
import org.junit.jupiter.api.Assumptions
148
import spock.lang.AutoCleanup
159
import spock.lang.Shared
@@ -138,16 +132,12 @@ class AbstractGradleTest extends CiVisibilitySmokeTest {
138132
}
139133

140134
private static String getLatestGradleVersion() {
141-
OkHttpClient client = new OkHttpClient()
142-
Request request = new Request.Builder().url("https://services.gradle.org/versions/current").build()
143-
try (Response response = client.newCall(request).execute()) {
144-
if (!response.successful) {
145-
return GradleVersion.current().version
146-
}
147-
def responseBody = response.body().string()
148-
ObjectMapper mapper = new ObjectMapper()
149-
JsonNode root = mapper.readTree(responseBody)
150-
return root.get("version").asText()
135+
def properties = new Properties()
136+
def stream = AbstractGradleTest.classLoader.getResourceAsStream("latest-tool-versions.properties")
137+
if (stream == null) {
138+
throw new IllegalStateException("Could not find latest-tool-versions.properties on classpath")
151139
}
140+
stream.withCloseable { properties.load(it) }
141+
return properties.getProperty("gradle.version")
152142
}
153143
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Pinned "latest" versions for CI Visibility Gradle smoke tests.
2+
# Updated automatically by the update-smoke-test-latest-versions workflow.
3+
gradle.version=9.4.0

0 commit comments

Comments
 (0)