Skip to content

Commit

Permalink
Merge pull request #654 from DataDog/ark/java9-logmanager-fix
Browse files Browse the repository at this point in the history
Workaround LogManager startup issue and add springboot test
  • Loading branch information
realark committed Jan 10, 2019
2 parents 4a6bd7a + 9d1dd4e commit b6d0dac
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,13 @@ public static ResettableClassFileTransformer installBytebuddyAgent(
named("java.net.URL")
.or(named("java.net.HttpURLConnection"))
.or(nameStartsWith("java.util.concurrent."))
.or(nameStartsWith("java.util.logging.")))))
.or(
nameStartsWith("java.util.logging.")
// Concurrent instrumentation modifies the strucutre of
// Cleaner class incompaibly with java9+ modules.
// Working around until a long-term fix for modules can be
// put in place.
.and(not(named("java.util.logging.LogManager$Cleaner")))))))
.or(nameStartsWith("com.sun.").and(not(nameStartsWith("com.sun.messaging."))))
.or(
nameStartsWith("sun.")
Expand Down
8 changes: 8 additions & 0 deletions dd-smoke-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Datadog Smoke Tests
Assert that various application servers will start up with the Datadog JavaAgent without any obvious ill effects.

Each subproject underneath `dd-smoke-tests` is a single smoke test. Each test does the following
* Launch the app server with stdout and stderr logged to `$buildDir/reports/server.log`
* Run a spock test which does 200 requests to an endpoint on the server and asserts on an expected response.

Note that there is nothing special about doing 200 requests. 200 is simply an arbitrarily large number to exercise the server.
8 changes: 0 additions & 8 deletions dd-smoke-tests/dd-smoke-tests.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1 @@
// Set properties before any plugins get loaded
project.ext {
// Execute tests on all JVMs, even rare and outdated ones
integrationTests = true
}

apply from: "${rootDir}/gradle/java.gradle"

description = 'dd-smoke-tests'
18 changes: 3 additions & 15 deletions dd-smoke-tests/play/play.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -69,21 +69,8 @@ dependencies {
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
}

/** Open up a random, reusable port. */
def randomOpenPort() {
final ServerSocket socket
try {
socket = new ServerSocket(0)
socket.setReuseAddress(true)
socket.close()
return socket.getLocalPort()
} catch (final IOException ioe) {
ioe.printStackTrace()
return -1
}
}

task startServer(type: com.github.psxpaul.task.ExecFork) {
dependsOn project(':dd-java-agent').shadowJar
playHttpPort = randomOpenPort()

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

dependsOn project(':dd-java-agent').shadowJar, startServer
dependsOn startServer
}

// clean up the PID file from the server
Expand Down
58 changes: 58 additions & 0 deletions dd-smoke-tests/springboot/springboot.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
plugins {
id "com.github.johnrengelman.shadow" version "4.0.1"
id 'com.github.psxpaul.execfork' version '0.1.8'
}
apply from: "${rootDir}/gradle/java.gradle"
description = 'SpringBoot Smoke Tests.'


ext {
springbootHttpPort = 8080
}

// The standard spring-boot plugin doesn't play nice with our project
// so we'll build a fat jar instead
jar {
manifest {
attributes(
'Main-Class': 'datadog.smoketest.springboot.SpringbootApplication'
)
}
}

dependencies {
compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.18.RELEASE'

testCompile project(':dd-trace-api')
testCompile project(':dd-trace-ot')
testCompile project(':dd-java-agent:testing')
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
}

task startServer(type: com.github.psxpaul.task.ExecFork) {
springbootHttpPort = randomOpenPort()
dependsOn project(':dd-java-agent').shadowJar, shadowJar

if (springbootHttpPort == -1) {
throw new GradleException("Failed to get random port to start springboot")
}
workingDir = "${buildDir}"
commandLine = "java"
args = ["-javaagent:${project(':dd-java-agent').tasks.shadowJar.archivePath}",
"-Ddd.writer.type=LoggingWriter",
"-Ddd.service.name=java-app",
"-Ddatadog.slf4j.simpleLogger.defaultLogLevel=debug",
"-jar",
"${tasks.shadowJar.archivePath}",
"--server.port=$springbootHttpPort"]
standardOutput "${buildDir}/reports/server.log"
waitForPort = springbootHttpPort
waitForOutput = "datadog.smoketest.springboot.SpringbootApplication - Started SpringbootApplication"
stopAfter = test
}

tasks.withType(Test) {
jvmArgs "-Ddatadog.smoketest.server.port=${springbootHttpPort}"

dependsOn startServer
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package datadog.smoketest.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootApplication {

public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package datadog.smoketest.springboot.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class WebController {
@RequestMapping("/greeting")
public String greeting() {
return "Sup Dawg";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
logging.level.root=WARN
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package datadog.trace.agent

import datadog.trace.agent.test.utils.OkHttpUtils
import okhttp3.OkHttpClient
import okhttp3.Request
import spock.lang.Specification

class SpringBootSmokeTest extends Specification {

private OkHttpClient client = OkHttpUtils.client()
private int port = Integer.parseInt(System.getProperty("datadog.smoketest.server.port", "8080"))

def "default home page #n th time"() {
setup:
String url = "http://localhost:$port/greeting"
def request = new Request.Builder().url(url).get().build()

when:
def response = client.newCall(request).execute()

then:
def responseBodyStr = response.body().string()
responseBodyStr != null
responseBodyStr.contains("Sup Dawg")
response.body().contentType().toString().contains("text/plain")
response.code() == 200

where:
n << (1..200)
}
}
19 changes: 4 additions & 15 deletions dd-smoke-tests/wildfly/wildfly.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,6 @@ dependencies {
testCompile group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.6.0'
}

/** Open up a random, reusable port. */
def randomOpenPort() {
final ServerSocket socket
try {
socket = new ServerSocket(0)
socket.setReuseAddress(true)
socket.close()
return socket.getLocalPort()
} catch (final IOException ioe) {
ioe.printStackTrace()
return -1
}
}

task unzip(type: Copy) {
def zipFileNamePrefix = "servlet"
def zipPath = project.configurations.compile.find {
Expand All @@ -67,6 +53,8 @@ task unzip(type: Copy) {
}

task startServer(type: com.github.psxpaul.task.ExecFork) {
dependsOn project(':dd-java-agent').shadowJar

wildflyHttpPort = randomOpenPort()
// not used, but to ensure https default port 8443 won't clash
int httpsPort = randomOpenPort()
Expand All @@ -80,6 +68,7 @@ task startServer(type: com.github.psxpaul.task.ExecFork) {
commandLine = "${workingDir}/bin/standalone.sh"
// ideally this should be good enough to use to stop wildfly, but wildfly needs to gracefully shutdown from jboss-cli.sh
// stopAfter = test
standardOutput "${buildDir}/reports/server.log"
// these params tells the ExecFork plugin to block on startServer task until the port is opened or the string is seen in the ouput
waitForPort = wildflyHttpPort
waitForOutput = "Undertow HTTP listener default listening on 127.0.0.1:${wildflyHttpPort}"
Expand Down Expand Up @@ -112,7 +101,7 @@ tasks.withType(Test) {
events "started"
}

dependsOn project(':dd-java-agent').shadowJar, startServer
dependsOn startServer
}

// ensure that the wildfly server gets shutdown
Expand Down
1 change: 1 addition & 0 deletions dd-trace-java.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ allprojects {
}

apply from: "${rootDir}/gradle/dependencies.gradle"
apply from: "${rootDir}/gradle/util.gradle"
}

repositories {
Expand Down
14 changes: 14 additions & 0 deletions gradle/util.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,17 @@ task artifacts {
}
}
}

/** Find a random, reusable port. */
ext.randomOpenPort = { ->
final ServerSocket socket
try {
socket = new ServerSocket(0)
socket.setReuseAddress(true)
socket.close()
return socket.getLocalPort()
} catch (final IOException ioe) {
ioe.printStackTrace()
return -1
}
}
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ include ':dd-java-agent:agent-jmxfetch'
include ':dd-java-agent:testing'

// smoke tests
include ':dd-smoke-tests:wildfly'
include ':dd-smoke-tests:play'
include ':dd-smoke-tests:springboot'
include ':dd-smoke-tests:wildfly'

// instrumentation:
include ':dd-java-agent:instrumentation:akka-http-10.0'
Expand Down

0 comments on commit b6d0dac

Please sign in to comment.