Skip to content

Commit 1a4f401

Browse files
authored
Merge branch 'master' into mhlidd/add_integration_gradle_task
2 parents 244d3c3 + 3fb3733 commit 1a4f401

584 files changed

Lines changed: 12545 additions & 11345 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ When converting Groovy code to Java code, make sure that:
2020
- `@TableTest` and `@MethodSource` may be combined on the same `@ParameterizedTest` when most cases are tabular but a few cases require programmatic setup.
2121
- In combined mode, keep table-friendly cases in `@TableTest`, and put only non-tabular/complex cases in `@MethodSource`.
2222
- If `@TableTest` is not viable for the test at all, use `@MethodSource` only.
23+
- If `@TableTest` was successfully used and if the `@ParameterizedTest` is not used to specify the test name, `@ParameterizedTest` can then be removed as `@TableTest` replace it fully.
2324
- For `@MethodSource`, name the arguments method `<testMethodName>Arguments` (camelCase, e.g. `testMethodArguments`) and return `Stream<Arguments>` using `Stream.of(...)` and `arguments(...)` with static import.
2425
- 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
2526
- When converting tuples, create a light dedicated structure instead to keep the typing system

.github/CODEOWNERS

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,14 @@
4545
/internal-api/src/test/groovy/datadog/trace/api/sampling @DataDog/apm-sdk-capabilities-java
4646

4747
# @DataDog/apm-serverless
48-
/dd-trace-core/src/main/java/datadog/trace/lambda/ @DataDog/apm-serverless
49-
/dd-trace-core/src/test/groovy/datadog/trace/lambda/ @DataDog/apm-serverless
50-
**/InferredProxy*.java @DataDog/apm-serverless
51-
**/InferredProxy*.groovy @DataDog/apm-serverless
48+
/dd-java-agent/instrumentation/aws-java/aws-java-lambda-handler-1.2/ @DataDog/apm-serverless
49+
/dd-java-agent/instrumentation/azure-functions/ @DataDog/apm-serverless
50+
/dd-java-agent/instrumentation/azure-functions-1.2.2/ @DataDog/apm-serverless
51+
/dd-trace-core/src/main/java/datadog/trace/lambda/ @DataDog/apm-serverless
52+
/dd-trace-core/src/test/groovy/datadog/trace/lambda/ @DataDog/apm-serverless
53+
/utils/container-utils/ @DataDog/apm-serverless
54+
**/InferredProxy*.java @DataDog/apm-serverless
55+
**/InferredProxy*.groovy @DataDog/apm-serverless
5256

5357
# @DataDog/apm-lang-platform-java
5458
/.github/ @DataDog/apm-lang-platform-java

.gitlab-ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ variables:
4343
description: "Enable flaky tests"
4444
value: "false"
4545

46+
# One pipeline injection package size ratchet
47+
OCI_PACKAGE_MAX_SIZE_BYTES: 40_000_000
48+
LIB_INJECTION_IMAGE_MAX_SIZE_BYTES: 40_000_000
49+
4650
# trigger new commit cancel
4751
workflow:
4852
auto_cancel:
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import org.w3c.dom.Element;
2+
import javax.xml.XMLConstants;
3+
import javax.xml.parsers.DocumentBuilderFactory;
4+
import javax.xml.transform.OutputKeys;
5+
import javax.xml.transform.TransformerFactory;
6+
import javax.xml.transform.dom.DOMSource;
7+
import javax.xml.transform.stream.StreamResult;
8+
import java.io.File;
9+
import java.nio.file.Files;
10+
import java.util.ArrayList;
11+
import java.util.LinkedHashMap;
12+
import java.util.List;
13+
import java.util.Map;
14+
15+
/// Tags intermediate `initializationError` retries with `dd_tags[test.final_status]=skip`.
16+
///
17+
/// Gradle generates synthetic "initializationError" testcases in JUnit reports for setup methods.
18+
/// When a setup is retried and eventually succeeds, multiple testcases are created, with only the
19+
/// last one passing. All intermediate attempts are marked skip so Test Optimization is not misled.
20+
///
21+
/// For any suite with multiple `initializationError` test cases (when retries occurred), all entries
22+
/// but the last one are tagged by this script with `dd_tags[test.final_status]=skip`. The last
23+
/// entry is left unmodified, allowing **Test Optimization** to apply its default status inference based
24+
/// on the actual outcome. Files with only one (or zero) `initializationError` test cases are left unmodified.
25+
///
26+
/// Before:
27+
///
28+
/// ```
29+
/// <testcase name="initializationError" />
30+
/// ```
31+
///
32+
/// After:
33+
///
34+
/// ```
35+
/// <testcase name="initializationError">
36+
/// <properties>
37+
/// <property name="dd_tags[test.final_status]" value="skip" />
38+
/// </properties>
39+
/// </testcase>
40+
/// ```
41+
///
42+
/// Usage (Java 25): `java TagInitializationErrors.java junit-report.xml`
43+
44+
class TagInitializationErrors {
45+
public static void main(String[] args) throws Exception {
46+
if (args.length == 0) {
47+
System.err.println("Usage: java TagInitializationErrors.java <xml-file>");
48+
System.exit(1);
49+
}
50+
var xmlFile = new File(args[0]);
51+
if (!xmlFile.exists()) {
52+
System.err.println("File not found: " + xmlFile);
53+
System.exit(1);
54+
}
55+
var dbf = DocumentBuilderFactory.newInstance();
56+
dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);
57+
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
58+
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
59+
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
60+
dbf.setExpandEntityReferences(false);
61+
var doc = dbf.newDocumentBuilder().parse(xmlFile);
62+
var testcases = doc.getElementsByTagName("testcase");
63+
Map<String, List<Element>> byClassname = new LinkedHashMap<>();
64+
for (int i = 0; i < testcases.getLength(); i++) {
65+
var e = (Element) testcases.item(i);
66+
if ("initializationError".equals(e.getAttribute("name"))) {
67+
byClassname.computeIfAbsent(e.getAttribute("classname"), k -> new ArrayList<>()).add(e);
68+
}
69+
}
70+
boolean modified = false;
71+
for (var group : byClassname.values()) {
72+
if (group.size() <= 1) continue;
73+
for (int i = 0; i < group.size() - 1; i++) {
74+
var testcase = group.get(i);
75+
var existingProperties = testcase.getElementsByTagName("properties");
76+
if (existingProperties.getLength() > 0) {
77+
var props = (Element) existingProperties.item(0);
78+
var existingProps = props.getElementsByTagName("property");
79+
boolean alreadyTagged = false;
80+
for (int j = 0; j < existingProps.getLength(); j++) {
81+
if ("dd_tags[test.final_status]".equals(((Element) existingProps.item(j)).getAttribute("name"))) {
82+
alreadyTagged = true;
83+
break;
84+
}
85+
}
86+
if (alreadyTagged) continue;
87+
var property = doc.createElement("property");
88+
property.setAttribute("name", "dd_tags[test.final_status]");
89+
property.setAttribute("value", "skip");
90+
props.appendChild(property);
91+
} else {
92+
var properties = doc.createElement("properties");
93+
var property = doc.createElement("property");
94+
property.setAttribute("name", "dd_tags[test.final_status]");
95+
property.setAttribute("value", "skip");
96+
properties.appendChild(property);
97+
testcase.appendChild(properties);
98+
}
99+
modified = true;
100+
}
101+
}
102+
if (!modified) return;
103+
var tmpFile = File.createTempFile("TagInitializationErrors", ".xml", xmlFile.getParentFile());
104+
try {
105+
var transformer = TransformerFactory.newInstance().newTransformer();
106+
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
107+
transformer.transform(new DOMSource(doc), new StreamResult(tmpFile));
108+
Files.move(tmpFile.toPath(), xmlFile.toPath(), java.nio.file.StandardCopyOption.REPLACE_EXISTING);
109+
} catch (Exception e) {
110+
tmpFile.delete();
111+
throw e;
112+
}
113+
}
114+
}

.gitlab/collect_results.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,9 @@ do
9090
echo " (non-stable test names detected)"
9191
fi
9292

93+
echo "Add dd_tags[test.final_status] property on retried synthetics testcase initializationErrors"
94+
$JAVA_25_HOME/bin/java "$(dirname "$0")/TagInitializationErrors.java" "$TARGET_DIR/$AGGREGATED_FILE_NAME"
95+
9396
echo "Add dd_tags[test.final_status] property to each testcase on $TARGET_DIR/$AGGREGATED_FILE_NAME"
9497
xsl_file="$(dirname "$0")/add_final_status.xsl"
9598
tmp_file="$(mktemp)"

build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ plugins {
1313

1414
id("com.diffplug.spotless") version "8.4.0"
1515
id("me.champeau.gradle.japicmp") version "0.4.3"
16-
id("com.github.spotbugs") version "6.4.8"
16+
id("com.github.spotbugs") version "6.5.0"
1717
id("de.thetaphi.forbiddenapis") version "3.10"
1818
id("io.github.gradle-nexus.publish-plugin") version "2.0.0"
1919
id("com.gradleup.shadow") version "8.3.9" apply false

buildSrc/src/main/kotlin/datadog/gradle/plugin/ci/CIJobsExtensions.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ val Project.isInSelectedSlot: Provider<Boolean>
2222
return@map true
2323
}
2424

25+
// When CI_NODE_INDEX or CI_NODE_TOTAL is unset in non-parallel jobs, one part may be empty (e.g. slot="/1") — treat as no filtering
26+
if (parts[0].isBlank() || parts[1].isBlank()) {
27+
project.logger.info("Incomplete slot value '{}', CI_NODE_INDEX or CI_NODE_TOTAL not set. Treating all projects as selected.", slot)
28+
return@map true
29+
}
30+
2531
val selectedSlot = parts[0].toIntOrNull()
2632
val totalSlots = parts[1].toIntOrNull()
2733

communication/gradle.lockfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ com.thoughtworks.qdox:qdox:1.12.1=codenarc
3636
commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testRuntimeClasspath
3737
commons-io:commons-io:2.11.0=testCompileClasspath,testRuntimeClasspath
3838
commons-io:commons-io:2.20.0=spotbugs
39-
de.thetaphi:forbiddenapis:3.10=compileClasspath
39+
de.thetaphi:forbiddenapis:3.10=compileClasspath,testCompileClasspath,testRuntimeClasspath
4040
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
4141
jaxen:jaxen:2.0.0=spotbugs
4242
junit:junit:4.12=testCompileClasspath,testRuntimeClasspath

dd-java-agent/agent-aiguard/gradle.lockfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ com.vaadin.external.google:android-json:0.0.20131108.vaadin1=testCompileClasspat
3636
commons-fileupload:commons-fileupload:1.5=testCompileClasspath,testRuntimeClasspath
3737
commons-io:commons-io:2.11.0=testCompileClasspath,testRuntimeClasspath
3838
commons-io:commons-io:2.20.0=spotbugs
39-
de.thetaphi:forbiddenapis:3.10=compileClasspath
39+
de.thetaphi:forbiddenapis:3.10=compileClasspath,testCompileClasspath,testRuntimeClasspath
4040
io.leangen.geantyref:geantyref:1.3.16=testRuntimeClasspath
4141
jaxen:jaxen:2.0.0=spotbugs
4242
net.bytebuddy:byte-buddy-agent:1.18.3=testCompileClasspath,testRuntimeClasspath

dd-java-agent/agent-aiguard/src/main/java/com/datadog/aiguard/AIGuardInternal.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ public BadConfigurationException(final String message) {
6969
static final String ACTION_TAG = "ai_guard.action";
7070
static final String REASON_TAG = "ai_guard.reason";
7171
static final String BLOCKED_TAG = "ai_guard.blocked";
72+
static final String EVENT_TAG = "ai_guard.event";
7273
static final String META_STRUCT_TAG = "ai_guard";
7374
static final String META_STRUCT_MESSAGES = "messages";
7475
static final String META_STRUCT_CATEGORIES = "attack_categories";
@@ -227,6 +228,7 @@ public Evaluation evaluate(final List<Message> messages, final Options options)
227228
final AgentSpan localRootSpan = span.getLocalRootSpan();
228229
if (localRootSpan != null) {
229230
localRootSpan.setTag(Tags.AI_GUARD_KEEP, true);
231+
localRootSpan.setTag(EVENT_TAG, true);
230232
}
231233
try (final AgentScope scope = tracer.activateSpan(span)) {
232234
final Message last = messages.get(messages.size() - 1);

0 commit comments

Comments
 (0)