Skip to content

Commit b1bfb13

Browse files
authored
feat(smoke-tests): Adding crash tracking (#7855)
* Excluding J9 * Improving PortUtils to exitCode when process ends abnormally * Improving error reporting when process fails to start Wrapped PortUtils.waitForPortToOpen with exception handling, when exception is raised log file indicating error is added to exception message * Suppressed FileNotException in cleanUpSpec, when process exits abormally since no file is expected and it creates noise * Clarifying exception message * Refining exception suppression, some tests clean-up with test processes still running? * Adding ability to selectively suppress crash tracking * Adding some sanity checks that test processes are up and running as expected * Reworking exception handling logic around verifyLog * Modifying exception handling logic around verifyLog in response to review feedback * When process is alive or exited normally, the exception flows through as is * When process exited abnormally, the exception is wrapped in another exception that indicates the abnormal termination
1 parent a62e471 commit b1bfb13

File tree

4 files changed

+63
-4
lines changed

4 files changed

+63
-4
lines changed

dd-java-agent/testing/src/main/groovy/datadog/trace/agent/test/utils/PortUtils.java

+11-1
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,17 @@ public static void waitForPortToOpen(
115115
}
116116

117117
if (!process.isAlive()) {
118-
throw new RuntimeException("Process died before port " + port + " was opened");
118+
int exitCode = process.exitValue();
119+
if (exitCode != 0) {
120+
throw new RuntimeException(
121+
"Process exited abnormally exitCode="
122+
+ exitCode
123+
+ " before port="
124+
+ port
125+
+ " was opened");
126+
} else {
127+
throw new RuntimeException("Process finished before port=" + port + " was opened");
128+
}
119129
}
120130

121131
if (isPortOpen(port)) {

dd-smoke-tests/src/main/groovy/datadog/smoketest/AbstractServerSmokeTest.groovy

+23-2
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,12 @@ abstract class AbstractServerSmokeTest extends AbstractSmokeTest {
6767
(0..<numberOfProcesses).each { idx ->
6868
def port = httpPorts[idx]
6969
def process = testedProcesses[idx]
70-
PortUtils.waitForPortToOpen(port, 240, TimeUnit.SECONDS, process)
70+
71+
try {
72+
PortUtils.waitForPortToOpen(port, 240, TimeUnit.SECONDS, process)
73+
} catch ( Exception e ) {
74+
throw new RuntimeException(e.getMessage() + " - log file " + logFilePaths[idx], e)
75+
}
7176
}
7277
}
7378

@@ -77,7 +82,23 @@ abstract class AbstractServerSmokeTest extends AbstractSmokeTest {
7782
if (null != (outputFile = outputs[idx])) {
7883
// check the structures written out to the log,
7984
// and fail the run if anything unexpected was recorded
80-
verifyLog(idx, outputFile)
85+
try {
86+
verifyLog(idx, outputFile)
87+
} catch (FileNotFoundException e) {
88+
if (testedProcesses[idx].isAlive()) {
89+
throw e
90+
}
91+
def exitCode = testedProcesses[idx].exitValue()
92+
if (exitCode == 0) {
93+
throw e
94+
} else {
95+
def logFile = logFilePaths[idx]
96+
// highlight when process exited abnormally, since that may have contributed
97+
// to the log verification failure
98+
throw new RuntimeException(
99+
"Server process exited abnormally - exit code: ${exitCode}; check log file: ${logFile}", e)
100+
}
101+
}
81102
}
82103
}
83104
}

dd-smoke-tests/src/main/groovy/datadog/smoketest/AbstractSmokeTest.groovy

+17-1
Original file line numberDiff line numberDiff line change
@@ -164,13 +164,18 @@ abstract class AbstractSmokeTest extends ProcessManager {
164164
"-Ddd.version=${VERSION}"
165165
]
166166

167+
def testCrashTracking() {
168+
return true
169+
}
167170

168171
def javaProperties() {
172+
def tmpDir = "/tmp"
173+
169174
def ret = [
170175
"${getMaxMemoryArgumentForFork()}",
171176
"${getMinMemoryArgumentForFork()}",
172177
"-javaagent:${shadowJarPath}",
173-
isIBM ? "-Xdump:directory=/tmp" : "-XX:ErrorFile=/tmp/hs_err_pid%p.log",
178+
isIBM ? "-Xdump:directory=${tmpDir}" : "-XX:ErrorFile=${tmpDir}/hs_err_pid%p.log",
174179
"-Ddd.trace.agent.port=${server.address.port}",
175180
"-Ddd.env=${ENV}",
176181
"-Ddd.version=${VERSION}",
@@ -190,9 +195,20 @@ abstract class AbstractSmokeTest extends ProcessManager {
190195
if (testTelemetry()) {
191196
ret += "-Ddd.telemetry.heartbeat.interval=5"
192197
}
198+
// DQH - Nov 2024 - skipping for J9 which doesn't have full crash tracking support
199+
if (testCrashTracking() && !Platform.isJ9()) {
200+
def extension = getScriptExtension()
201+
ret += "-XX:OnError=\"${tmpDir}/dd_crash_uploader.${extension} %p\""
202+
// Unlike crash tracking smoke test, keep the default delay; otherwise, otherwise other tests will fail
203+
// ret += "-Ddd.dogstatsd.start-delay=0"
204+
}
193205
ret as String[]
194206
}
195207

208+
static String getScriptExtension() {
209+
return Platform.isWindows() ? "bat" : "sh"
210+
}
211+
196212
def inferServiceName() {
197213
true
198214
}

dd-smoke-tests/src/main/groovy/datadog/smoketest/ProcessManager.groovy

+12
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,18 @@ abstract class ProcessManager extends Specification {
196196
outputThreads.captureOutput(p, new File(logFilePaths[idx]))
197197
}
198198
testedProcess = numberOfProcesses == 1 ? testedProcesses[0] : null
199+
200+
201+
(0..<numberOfProcesses).each { idx ->
202+
def curProc = testedProcesses[idx]
203+
204+
if ( !curProc.isAlive() && curProc.exitValue() != 0 ) {
205+
def exitCode = curProc.exitValue()
206+
def logFile = logFilePaths[idx]
207+
208+
throw new RuntimeException("Process exited abormally - exitCode:${exitCode}; logFile=${logFile}")
209+
}
210+
}
199211
}
200212

201213
String javaPath() {

0 commit comments

Comments
 (0)