Skip to content

Commit b6d0dac

Browse files
authored
Merge pull request #654 from DataDog/ark/java9-logmanager-fix
Workaround LogManager startup issue and add springboot test
2 parents 4a6bd7a + 9d1dd4e commit b6d0dac

File tree

13 files changed

+153
-40
lines changed

13 files changed

+153
-40
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,13 @@ public static ResettableClassFileTransformer installBytebuddyAgent(
8080
named("java.net.URL")
8181
.or(named("java.net.HttpURLConnection"))
8282
.or(nameStartsWith("java.util.concurrent."))
83-
.or(nameStartsWith("java.util.logging.")))))
83+
.or(
84+
nameStartsWith("java.util.logging.")
85+
// Concurrent instrumentation modifies the strucutre of
86+
// Cleaner class incompaibly with java9+ modules.
87+
// Working around until a long-term fix for modules can be
88+
// put in place.
89+
.and(not(named("java.util.logging.LogManager$Cleaner")))))))
8490
.or(nameStartsWith("com.sun.").and(not(nameStartsWith("com.sun.messaging."))))
8591
.or(
8692
nameStartsWith("sun.")

dd-smoke-tests/README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Datadog Smoke Tests
2+
Assert that various application servers will start up with the Datadog JavaAgent without any obvious ill effects.
3+
4+
Each subproject underneath `dd-smoke-tests` is a single smoke test. Each test does the following
5+
* Launch the app server with stdout and stderr logged to `$buildDir/reports/server.log`
6+
* Run a spock test which does 200 requests to an endpoint on the server and asserts on an expected response.
7+
8+
Note that there is nothing special about doing 200 requests. 200 is simply an arbitrarily large number to exercise the server.

dd-smoke-tests/dd-smoke-tests.gradle

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1 @@
1-
// Set properties before any plugins get loaded
2-
project.ext {
3-
// Execute tests on all JVMs, even rare and outdated ones
4-
integrationTests = true
5-
}
6-
7-
apply from: "${rootDir}/gradle/java.gradle"
8-
91
description = 'dd-smoke-tests'

dd-smoke-tests/play/play.gradle

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -69,21 +69,8 @@ dependencies {
6969
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
7070
}
7171

72-
/** Open up a random, reusable port. */
73-
def randomOpenPort() {
74-
final ServerSocket socket
75-
try {
76-
socket = new ServerSocket(0)
77-
socket.setReuseAddress(true)
78-
socket.close()
79-
return socket.getLocalPort()
80-
} catch (final IOException ioe) {
81-
ioe.printStackTrace()
82-
return -1
83-
}
84-
}
85-
8672
task startServer(type: com.github.psxpaul.task.ExecFork) {
73+
dependsOn project(':dd-java-agent').shadowJar
8774
playHttpPort = randomOpenPort()
8875

8976
if (playHttpPort == -1) {
@@ -93,6 +80,7 @@ task startServer(type: com.github.psxpaul.task.ExecFork) {
9380
workingDir = "${buildDir}/stage/playBinary"
9481
commandLine = "${workingDir}/bin/playBinary"
9582
stopAfter = test
83+
standardOutput "${buildDir}/reports/server.log"
9684
// these params tells the ExecFork plugin to block on startServer task until the port is opened or the string is seen in the ouput
9785
waitForPort = playHttpPort
9886
waitForOutput = "Listening for HTTP on /127.0.0.1:${playHttpPort}"
@@ -120,7 +108,7 @@ tasks.withType(Test) {
120108
events "started"
121109
}
122110

123-
dependsOn project(':dd-java-agent').shadowJar, startServer
111+
dependsOn startServer
124112
}
125113

126114
// clean up the PID file from the server
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
plugins {
2+
id "com.github.johnrengelman.shadow" version "4.0.1"
3+
id 'com.github.psxpaul.execfork' version '0.1.8'
4+
}
5+
apply from: "${rootDir}/gradle/java.gradle"
6+
description = 'SpringBoot Smoke Tests.'
7+
8+
9+
ext {
10+
springbootHttpPort = 8080
11+
}
12+
13+
// The standard spring-boot plugin doesn't play nice with our project
14+
// so we'll build a fat jar instead
15+
jar {
16+
manifest {
17+
attributes(
18+
'Main-Class': 'datadog.smoketest.springboot.SpringbootApplication'
19+
)
20+
}
21+
}
22+
23+
dependencies {
24+
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.18.RELEASE'
25+
26+
testCompile project(':dd-trace-api')
27+
testCompile project(':dd-trace-ot')
28+
testCompile project(':dd-java-agent:testing')
29+
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
30+
}
31+
32+
task startServer(type: com.github.psxpaul.task.ExecFork) {
33+
springbootHttpPort = randomOpenPort()
34+
dependsOn project(':dd-java-agent').shadowJar, shadowJar
35+
36+
if (springbootHttpPort == -1) {
37+
throw new GradleException("Failed to get random port to start springboot")
38+
}
39+
workingDir = "${buildDir}"
40+
commandLine = "java"
41+
args = ["-javaagent:${project(':dd-java-agent').tasks.shadowJar.archivePath}",
42+
"-Ddd.writer.type=LoggingWriter",
43+
"-Ddd.service.name=java-app",
44+
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=debug",
45+
"-jar",
46+
"${tasks.shadowJar.archivePath}",
47+
"--server.port=$springbootHttpPort"]
48+
standardOutput "${buildDir}/reports/server.log"
49+
waitForPort = springbootHttpPort
50+
waitForOutput = "datadog.smoketest.springboot.SpringbootApplication - Started SpringbootApplication"
51+
stopAfter = test
52+
}
53+
54+
tasks.withType(Test) {
55+
jvmArgs "-Ddatadog.smoketest.server.port=${springbootHttpPort}"
56+
57+
dependsOn startServer
58+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package datadog.smoketest.springboot;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class SpringbootApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(SpringbootApplication.class, args);
11+
}
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package datadog.smoketest.springboot.controller;
2+
3+
import org.springframework.web.bind.annotation.RequestMapping;
4+
import org.springframework.web.bind.annotation.RestController;
5+
6+
@RestController
7+
public class WebController {
8+
@RequestMapping("/greeting")
9+
public String greeting() {
10+
return "Sup Dawg";
11+
}
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
logging.level.root=WARN
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package datadog.trace.agent
2+
3+
import datadog.trace.agent.test.utils.OkHttpUtils
4+
import okhttp3.OkHttpClient
5+
import okhttp3.Request
6+
import spock.lang.Specification
7+
8+
class SpringBootSmokeTest extends Specification {
9+
10+
private OkHttpClient client = OkHttpUtils.client()
11+
private int port = Integer.parseInt(System.getProperty("datadog.smoketest.server.port", "8080"))
12+
13+
def "default home page #n th time"() {
14+
setup:
15+
String url = "http://localhost:$port/greeting"
16+
def request = new Request.Builder().url(url).get().build()
17+
18+
when:
19+
def response = client.newCall(request).execute()
20+
21+
then:
22+
def responseBodyStr = response.body().string()
23+
responseBodyStr != null
24+
responseBodyStr.contains("Sup Dawg")
25+
response.body().contentType().toString().contains("text/plain")
26+
response.code() == 200
27+
28+
where:
29+
n << (1..200)
30+
}
31+
}

dd-smoke-tests/wildfly/wildfly.gradle

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,6 @@ dependencies {
3636
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
3737
}
3838

39-
/** Open up a random, reusable port. */
40-
def randomOpenPort() {
41-
final ServerSocket socket
42-
try {
43-
socket = new ServerSocket(0)
44-
socket.setReuseAddress(true)
45-
socket.close()
46-
return socket.getLocalPort()
47-
} catch (final IOException ioe) {
48-
ioe.printStackTrace()
49-
return -1
50-
}
51-
}
52-
5339
task unzip(type: Copy) {
5440
def zipFileNamePrefix = "servlet"
5541
def zipPath = project.configurations.compile.find {
@@ -67,6 +53,8 @@ task unzip(type: Copy) {
6753
}
6854

6955
task startServer(type: com.github.psxpaul.task.ExecFork) {
56+
dependsOn project(':dd-java-agent').shadowJar
57+
7058
wildflyHttpPort = randomOpenPort()
7159
// not used, but to ensure https default port 8443 won't clash
7260
int httpsPort = randomOpenPort()
@@ -80,6 +68,7 @@ task startServer(type: com.github.psxpaul.task.ExecFork) {
8068
commandLine = "${workingDir}/bin/standalone.sh"
8169
// ideally this should be good enough to use to stop wildfly, but wildfly needs to gracefully shutdown from jboss-cli.sh
8270
// stopAfter = test
71+
standardOutput "${buildDir}/reports/server.log"
8372
// these params tells the ExecFork plugin to block on startServer task until the port is opened or the string is seen in the ouput
8473
waitForPort = wildflyHttpPort
8574
waitForOutput = "Undertow HTTP listener default listening on 127.0.0.1:${wildflyHttpPort}"
@@ -112,7 +101,7 @@ tasks.withType(Test) {
112101
events "started"
113102
}
114103

115-
dependsOn project(':dd-java-agent').shadowJar, startServer
104+
dependsOn startServer
116105
}
117106

118107
// ensure that the wildfly server gets shutdown

dd-trace-java.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ allprojects {
2222
}
2323

2424
apply from: "${rootDir}/gradle/dependencies.gradle"
25+
apply from: "${rootDir}/gradle/util.gradle"
2526
}
2627

2728
repositories {

gradle/util.gradle

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,17 @@ task artifacts {
1111
}
1212
}
1313
}
14+
15+
/** Find a random, reusable port. */
16+
ext.randomOpenPort = { ->
17+
final ServerSocket socket
18+
try {
19+
socket = new ServerSocket(0)
20+
socket.setReuseAddress(true)
21+
socket.close()
22+
return socket.getLocalPort()
23+
} catch (final IOException ioe) {
24+
ioe.printStackTrace()
25+
return -1
26+
}
27+
}

settings.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ include ':dd-java-agent:agent-jmxfetch'
1818
include ':dd-java-agent:testing'
1919

2020
// smoke tests
21-
include ':dd-smoke-tests:wildfly'
2221
include ':dd-smoke-tests:play'
22+
include ':dd-smoke-tests:springboot'
23+
include ':dd-smoke-tests:wildfly'
2324

2425
// instrumentation:
2526
include ':dd-java-agent:instrumentation:akka-http-10.0'

0 commit comments

Comments
 (0)