Merge pull request #273 from DataDog/tyler/agent-integ-test
Add tests against an actual trace agent.
This commit is contained in:
commit
cb604a0932
|
@ -84,6 +84,38 @@ jobs:
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/openjdk:9-jdk
|
- image: circleci/openjdk:9-jdk
|
||||||
|
|
||||||
|
agent_integration_tests:
|
||||||
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/openjdk:8-jdk
|
||||||
|
- image: datadog/docker-dd-agent
|
||||||
|
env:
|
||||||
|
- DD_APM_ENABLED=true
|
||||||
|
- DD_BIND_HOST=0.0.0.0
|
||||||
|
- DD_API_KEY=invalid_key_but_this_is_fine
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
|
||||||
|
- restore_cache:
|
||||||
|
# Reset the cache approx every release
|
||||||
|
keys:
|
||||||
|
- dd-trace-java-{{ checksum "dd-trace-java.gradle" }}-{{ .Branch }}-{{ .Revision }}
|
||||||
|
- dd-trace-java-{{ checksum "dd-trace-java.gradle" }}-{{ .Branch }}
|
||||||
|
- dd-trace-java-{{ checksum "dd-trace-java.gradle" }}
|
||||||
|
- dd-trace-java
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Run Trace Agent Tests
|
||||||
|
command: ./gradlew traceAgentTest --parallel --stacktrace --no-daemon
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Save Artifacts to (project-root)/build
|
||||||
|
when: always
|
||||||
|
command: .circleci/save_artifacts.sh
|
||||||
|
|
||||||
|
- store_test_results:
|
||||||
|
path: build/test-results
|
||||||
|
|
||||||
scan_versions:
|
scan_versions:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
steps:
|
steps:
|
||||||
|
@ -170,6 +202,13 @@ workflows:
|
||||||
tags:
|
tags:
|
||||||
only: /.*/
|
only: /.*/
|
||||||
|
|
||||||
|
- agent_integration_tests:
|
||||||
|
requires:
|
||||||
|
- build
|
||||||
|
filters:
|
||||||
|
tags:
|
||||||
|
only: /.*/
|
||||||
|
|
||||||
- scan_versions:
|
- scan_versions:
|
||||||
requires:
|
requires:
|
||||||
- build
|
- build
|
||||||
|
@ -182,6 +221,7 @@ workflows:
|
||||||
- test_7
|
- test_7
|
||||||
- test_8
|
- test_8
|
||||||
- test_9
|
- test_9
|
||||||
|
- agent_integration_tests
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
only: master
|
only: master
|
||||||
|
@ -193,6 +233,7 @@ workflows:
|
||||||
- test_7
|
- test_7
|
||||||
- test_8
|
- test_8
|
||||||
- test_9
|
- test_9
|
||||||
|
- agent_integration_tests
|
||||||
filters:
|
filters:
|
||||||
branches:
|
branches:
|
||||||
ignore: /.*/
|
ignore: /.*/
|
||||||
|
|
|
@ -27,6 +27,8 @@ repositories {
|
||||||
|
|
||||||
description = 'dd-trace-java'
|
description = 'dd-trace-java'
|
||||||
|
|
||||||
|
task traceAgentTest {}
|
||||||
|
|
||||||
// Applied here to allow publishing of artifactory build info
|
// Applied here to allow publishing of artifactory build info
|
||||||
apply from: "${rootDir}/gradle/publish.gradle"
|
apply from: "${rootDir}/gradle/publish.gradle"
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
plugins {
|
plugins {
|
||||||
id "me.champeau.gradle.jmh" version "0.4.4"
|
id "me.champeau.gradle.jmh" version "0.4.4"
|
||||||
|
id 'org.unbroken-dome.test-sets' version '1.4.4'
|
||||||
}
|
}
|
||||||
|
|
||||||
description = 'dd-trace-ot'
|
description = 'dd-trace-ot'
|
||||||
|
@ -29,6 +30,10 @@ if (JavaVersion.current() != JavaVersion.VERSION_1_8) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testSets {
|
||||||
|
traceAgentTest
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile project(':dd-trace-api')
|
compile project(':dd-trace-api')
|
||||||
compile deps.opentracing
|
compile deps.opentracing
|
||||||
|
|
|
@ -37,11 +37,18 @@ public class DDApi {
|
||||||
private final RateLimiter loggingRateLimiter =
|
private final RateLimiter loggingRateLimiter =
|
||||||
RateLimiter.create(1.0 / SECONDS_BETWEEN_ERROR_LOG);
|
RateLimiter.create(1.0 / SECONDS_BETWEEN_ERROR_LOG);
|
||||||
|
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
|
private static final ObjectMapper objectMapper = new ObjectMapper(new MessagePackFactory());
|
||||||
|
|
||||||
public DDApi(final String host, final int port) {
|
public DDApi(final String host, final int port) {
|
||||||
if (traceEndpointAvailable("http://" + host + ":" + port + TRACES_ENDPOINT_V4)
|
this(
|
||||||
&& serviceEndpointAvailable("http://" + host + ":" + port + SERVICES_ENDPOINT_V4)) {
|
host,
|
||||||
|
port,
|
||||||
|
traceEndpointAvailable("http://" + host + ":" + port + TRACES_ENDPOINT_V4)
|
||||||
|
&& serviceEndpointAvailable("http://" + host + ":" + port + SERVICES_ENDPOINT_V4));
|
||||||
|
}
|
||||||
|
|
||||||
|
DDApi(final String host, final int port, final boolean v4EndpointsAvailable) {
|
||||||
|
if (v4EndpointsAvailable) {
|
||||||
this.tracesEndpoint = "http://" + host + ":" + port + TRACES_ENDPOINT_V4;
|
this.tracesEndpoint = "http://" + host + ":" + port + TRACES_ENDPOINT_V4;
|
||||||
this.servicesEndpoint = "http://" + host + ":" + port + SERVICES_ENDPOINT_V4;
|
this.servicesEndpoint = "http://" + host + ":" + port + SERVICES_ENDPOINT_V4;
|
||||||
} else {
|
} else {
|
||||||
|
@ -163,15 +170,16 @@ public class DDApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean traceEndpointAvailable(final String endpoint) {
|
private static boolean traceEndpointAvailable(final String endpoint) {
|
||||||
return endpointAvailable(endpoint, Collections.emptyList(), true);
|
return endpointAvailable(endpoint, Collections.emptyList(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean serviceEndpointAvailable(final String endpoint) {
|
private static boolean serviceEndpointAvailable(final String endpoint) {
|
||||||
return endpointAvailable(endpoint, Collections.emptyMap(), true);
|
return endpointAvailable(endpoint, Collections.emptyMap(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean endpointAvailable(final String endpoint, final Object data, final boolean retry) {
|
private static boolean endpointAvailable(
|
||||||
|
final String endpoint, final Object data, final boolean retry) {
|
||||||
try {
|
try {
|
||||||
final HttpURLConnection httpCon = getHttpURLConnection(endpoint);
|
final HttpURLConnection httpCon = getHttpURLConnection(endpoint);
|
||||||
|
|
||||||
|
@ -192,7 +200,7 @@ public class DDApi {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private HttpURLConnection getHttpURLConnection(final String endpoint) throws IOException {
|
private static HttpURLConnection getHttpURLConnection(final String endpoint) throws IOException {
|
||||||
final HttpURLConnection httpCon;
|
final HttpURLConnection httpCon;
|
||||||
final URL url = new URL(endpoint);
|
final URL url = new URL(endpoint);
|
||||||
httpCon = (HttpURLConnection) url.openConnection();
|
httpCon = (HttpURLConnection) url.openConnection();
|
||||||
|
|
|
@ -241,11 +241,8 @@ class DDApiTest extends Specification {
|
||||||
def "Api ResponseListeners see 200 responses"() {
|
def "Api ResponseListeners see 200 responses"() {
|
||||||
setup:
|
setup:
|
||||||
def agentResponse = new AtomicReference<String>(null)
|
def agentResponse = new AtomicReference<String>(null)
|
||||||
ResponseListener responseListener = new ResponseListener() {
|
ResponseListener responseListener = { String endpoint, JsonNode responseJson ->
|
||||||
@Override
|
agentResponse.set(responseJson.toString())
|
||||||
void onResponse(String endpoint, JsonNode responseJson) {
|
|
||||||
agentResponse.set(responseJson.toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
boolean servicesAvailable = true
|
boolean servicesAvailable = true
|
||||||
def agent = ratpack {
|
def agent = ratpack {
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode
|
||||||
|
import datadog.opentracing.DDSpan
|
||||||
|
import datadog.opentracing.DDSpanContext
|
||||||
|
import datadog.opentracing.DDTracer
|
||||||
|
import datadog.opentracing.PendingTrace
|
||||||
|
import datadog.trace.common.Service
|
||||||
|
import datadog.trace.common.sampling.PrioritySampling
|
||||||
|
import datadog.trace.common.writer.DDAgentWriter
|
||||||
|
import datadog.trace.common.writer.DDApi
|
||||||
|
import datadog.trace.common.writer.ListWriter
|
||||||
|
import spock.lang.Specification
|
||||||
|
import spock.lang.Unroll
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
import java.util.concurrent.atomic.AtomicReference
|
||||||
|
|
||||||
|
class DDApiIntegrationTest {
|
||||||
|
static class DDApiIntegrationV4Test extends Specification {
|
||||||
|
static final WRITER = new ListWriter()
|
||||||
|
static final TRACER = new DDTracer(WRITER)
|
||||||
|
static final CONTEXT = new DDSpanContext(
|
||||||
|
1L,
|
||||||
|
1L,
|
||||||
|
0L,
|
||||||
|
"fakeService",
|
||||||
|
"fakeOperation",
|
||||||
|
"fakeResource",
|
||||||
|
PrioritySampling.UNSET,
|
||||||
|
Collections.emptyMap(),
|
||||||
|
false,
|
||||||
|
"fakeType",
|
||||||
|
Collections.emptyMap(),
|
||||||
|
new PendingTrace(TRACER, 1L),
|
||||||
|
TRACER)
|
||||||
|
|
||||||
|
def api = new DDApi(DDAgentWriter.DEFAULT_HOSTNAME, DDAgentWriter.DEFAULT_PORT, v4())
|
||||||
|
|
||||||
|
def endpoint = new AtomicReference<String>(null)
|
||||||
|
def agentResponse = new AtomicReference<String>(null)
|
||||||
|
|
||||||
|
DDApi.ResponseListener responseListener = { String receivedEndpoint, JsonNode responseJson ->
|
||||||
|
endpoint.set(receivedEndpoint)
|
||||||
|
agentResponse.set(responseJson.toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
def setup() {
|
||||||
|
api.addResponseListener(responseListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean v4() {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "Sending traces succeeds (test #test)"() {
|
||||||
|
expect:
|
||||||
|
api.sendTraces(traces)
|
||||||
|
if (v4()) {
|
||||||
|
endpoint.get() == "http://localhost:8126/v0.4/traces"
|
||||||
|
agentResponse.get() == '{"rate_by_service":{"service:,env:":1}}'
|
||||||
|
}
|
||||||
|
|
||||||
|
where:
|
||||||
|
traces | test
|
||||||
|
[] | 1
|
||||||
|
[[], []] | 2
|
||||||
|
[[new DDSpan(1, CONTEXT)]] | 3
|
||||||
|
[[new DDSpan(TimeUnit.MILLISECONDS.toMicros(System.currentTimeMillis()), CONTEXT)]] | 4
|
||||||
|
}
|
||||||
|
|
||||||
|
def "Sending services succeeds"() {
|
||||||
|
expect:
|
||||||
|
api.sendServices(services)
|
||||||
|
endpoint.get() == null
|
||||||
|
agentResponse.get() == null
|
||||||
|
|
||||||
|
where:
|
||||||
|
services | _
|
||||||
|
[:] | _
|
||||||
|
['app': new Service("name", "appName", Service.AppType.WEB)] | _
|
||||||
|
}
|
||||||
|
|
||||||
|
@Unroll
|
||||||
|
def "Sending bad trace fails (test #test)"() {
|
||||||
|
expect:
|
||||||
|
api.sendTraces(traces) == false
|
||||||
|
|
||||||
|
where:
|
||||||
|
traces | test
|
||||||
|
[""] | 1
|
||||||
|
["", 123] | 2
|
||||||
|
[[:]] | 3
|
||||||
|
[new Object()] | 4
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DDApiIntegrationV3Test extends DDApiIntegrationV4Test {
|
||||||
|
boolean v4() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
def cleanup() {
|
||||||
|
assert endpoint.get() == null
|
||||||
|
assert agentResponse.get() == null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue