Skip to content

Commit 7426235

Browse files
amarzialidevflow.devflow-routing-intake
andauthored
Add smoke test for websphere-jmx (#11077)
Add smoke test for websphere-jmx avoid udp listener hangs on cleanup Co-authored-by: devflow.devflow-routing-intake <devflow.devflow-routing-intake@kubernetes.us1.ddbuild.io>
1 parent 067d0d2 commit 7426235

File tree

5 files changed

+141
-1
lines changed

5 files changed

+141
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ abstract class ProcessManager extends Specification {
5050

5151
// Here for backwards compatibility with single process case
5252
@Shared
53-
def logFilePath = logFilePaths[0]
53+
def logFilePath = logFilePaths.length > 0 ? logFilePaths[0] : null
5454

5555
def setup() {
5656
testedProcesses.each {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apply from: "$rootDir/gradle/java.gradle"
2+
3+
dependencies {
4+
testImplementation project(':dd-smoke-tests')
5+
testImplementation libs.testcontainers
6+
}
7+
8+
testJvmConstraints {
9+
// there is no need to run it multiple times since it runs on a container
10+
maxJavaVersion = JavaVersion.VERSION_1_8
11+
}
12+
13+
tasks.withType(Test).configureEach {
14+
usesService(testcontainersLimit)
15+
}
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
package datadog.smoketest
2+
3+
4+
import java.time.Duration
5+
import java.util.concurrent.ArrayBlockingQueue
6+
import java.util.concurrent.BlockingQueue
7+
import java.util.concurrent.TimeUnit
8+
import org.slf4j.Logger
9+
import org.slf4j.LoggerFactory
10+
import org.testcontainers.containers.GenericContainer
11+
import org.testcontainers.containers.output.Slf4jLogConsumer
12+
import org.testcontainers.containers.wait.strategy.Wait
13+
import org.testcontainers.utility.MountableFile
14+
import spock.lang.Shared
15+
16+
/**
17+
* Smoke test for the websphere-jmx instrumentation.
18+
*
19+
* Builds and starts a WebSphere traditional (tWAS) container with the dd-java-agent baked in
20+
* via jvm-config.props, then verifies that jmxfetch reports WebSphere thread pool metrics
21+
* via statsd UDP.
22+
*
23+
* Note that the websphere related metrics will only arrive if our instrumentation is applied.
24+
*/
25+
class WebSphereJmxSmokeTest extends AbstractSmokeTest {
26+
27+
private static final Logger LOG = LoggerFactory.getLogger(WebSphereJmxSmokeTest)
28+
29+
@Override
30+
protected int numberOfProcesses() {
31+
return 0
32+
}
33+
34+
@Shared
35+
DatagramSocket statsdSocket
36+
37+
@Shared
38+
int statsdPort
39+
40+
@Shared
41+
BlockingQueue<String> statsdMessages = new ArrayBlockingQueue<>(256)
42+
43+
@Shared
44+
Thread listenerThread
45+
46+
@Shared
47+
GenericContainer websphere
48+
49+
def setupSpec() {
50+
statsdSocket = new DatagramSocket()
51+
statsdPort = statsdSocket.getLocalPort()
52+
LOG.info("StatsDServer listening on UDP port {}", statsdPort)
53+
54+
listenerThread = Thread.start {
55+
byte[] buf = new byte[2048]
56+
while (!Thread.currentThread().interrupted()) {
57+
try {
58+
DatagramPacket packet = new DatagramPacket(buf, buf.length)
59+
statsdSocket.receive(packet)
60+
String msg = new String(packet.getData(), 0, packet.getLength())
61+
LOG.debug("Received statsd: {}", msg)
62+
statsdMessages.offer(msg, 1, TimeUnit.SECONDS)
63+
} catch (Exception ignored) {
64+
break
65+
}
66+
}
67+
}
68+
69+
websphere = new GenericContainer("icr.io/appcafe/websphere-traditional:latest")
70+
// inject wished jvm props for the server we are running
71+
.withCopyFileToContainer(MountableFile.forClasspathResource("jvm-config.props"), "/work/config/")
72+
// copy the agent jar
73+
.withCopyFileToContainer(MountableFile.forHostPath(shadowJarPath), "/opt/dd-java-agent.jar")
74+
// let it run on a macos for dev
75+
.withCreateContainerCmdModifier { it.withPlatform('linux/amd64') }
76+
// this is required to send back udp datagrams to us
77+
.withExtraHost('host.docker.internal', 'host-gateway')
78+
// set jmxfetch props
79+
.withEnv('DD_JMXFETCH_STATSD_HOST', 'host.docker.internal')
80+
.withEnv('DD_JMXFETCH_STATSD_PORT', String.valueOf(statsdPort))
81+
.withLogConsumer(new Slf4jLogConsumer(LOG).withPrefix('websphere'))
82+
// the server will restart 2 times. First to update the jvm props
83+
.waitingFor(Wait.forLogMessage('.*open for e-business.*', 2))
84+
// it can be long
85+
.withStartupTimeout(Duration.ofMinutes(8))
86+
// override the command (by default it's /work/start_server.sh)
87+
.withCommand("bash", "-c", "/work/configure.sh && /work/start_server.sh")
88+
89+
websphere.start()
90+
LOG.info("WebSphere container started")
91+
}
92+
93+
def cleanupSpec() {
94+
websphere?.stop()
95+
statsdSocket?.close()
96+
listenerThread?.join()
97+
}
98+
99+
def "jmxfetch reports WebSphere thread pool metrics via statsd"() {
100+
when: "waiting for websphere.thread_pool metrics"
101+
String metric = waitForMetric('websphere.thread_pool', Duration.ofMinutes(3))
102+
103+
then: "at least one thread pool metric arrives"
104+
metric != null
105+
metric.contains('websphere.thread_pool')
106+
}
107+
108+
def waitForMetric(String prefix, Duration timeout) {
109+
long deadline = System.currentTimeMillis() + timeout.toMillis()
110+
while (System.currentTimeMillis() < deadline) {
111+
String msg = statsdMessages.poll(5, TimeUnit.SECONDS)
112+
if (msg?.contains(prefix)) {
113+
return msg
114+
}
115+
}
116+
return null
117+
}
118+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
ResourceType=JavaVirtualMachine
2+
ImplementingResourceType=Server
3+
ResourceId=Cell=!{cellName}:Node=!{nodeName}:Server=!{serverName}:JavaProcessDef=:JavaVirtualMachine=
4+
AttributeInfo=jvmEntries
5+
6+
genericJvmArguments=-javaagent:/opt/dd-java-agent.jar -Ddd.trace.debug=true -Ddd.jmxfetch.websphere.enabled=true

settings.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ include(
248248
":dd-smoke-tests:vertx-3.9",
249249
":dd-smoke-tests:vertx-3.9-resteasy",
250250
":dd-smoke-tests:vertx-4.2",
251+
":dd-smoke-tests:websphere-jmx",
251252
":dd-smoke-tests:wildfly",
252253
":dd-smoke-tests:appsec",
253254
":dd-smoke-tests:appsec:spring-tomcat7",

0 commit comments

Comments
 (0)