Skip to content

Commit 735e827

Browse files
committed
fix span ordering in tests
1 parent 835133e commit 735e827

File tree

2 files changed

+80
-51
lines changed

2 files changed

+80
-51
lines changed

dd-java-agent/instrumentation/mule-4/src/main/java/datadog/trace/instrumentation/mule4/EventContextCreationAdvice.java

-2
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ public static void onExit(
4242
if (parentState != null) {
4343
spanState = new SpanState(parentState.getEventContextSpan(), null);
4444
}
45-
// TODO: remove me
46-
System.err.println("CHILD CREATED " + " " + activeSpan() + " " + spanState);
4745
}
4846

4947
contextStore.put(zis, spanState);

dd-java-agent/instrumentation/mule-4/src/test/groovy/mule4/MuleForkedTest.groovy

+80-49
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ class MuleForkedTest extends WithHttpServer<MuleTestContainer> {
127127
"$Tags.HTTP_STATUS" 200
128128
"$Tags.HTTP_URL" "${requestServer.address.resolve("/remote-client-request")}"
129129
"$Tags.PEER_HOSTNAME" "localhost"
130-
"$Tags.PEER_PORT" { true } // is this really the best way to ignore tags?
130+
"$Tags.PEER_PORT" { Integer }
131131
defaultTags()
132132
}
133133
}
@@ -153,62 +153,93 @@ class MuleForkedTest extends WithHttpServer<MuleTestContainer> {
153153
jsonAdapter.fromJson(response.body().string()) == output
154154

155155
assertTraces(1) {
156-
trace(4 + 3 * names.size(), new Comparator<DDSpan>() {
157-
@Override
158-
int compare(DDSpan o1, DDSpan o2) {
159-
def ret = o1.parentId <=> o2.parentId
160-
if (ret != 0) {
161-
return ret
162-
}
163-
return o1.spanId <=> o2.spanId
156+
trace(4 + 3 * names.size(), new TreeComparator(trace(0))) { traceAssert ->
157+
for (int i = 0; i < (4 + 3 * names.size()); i++) {
158+
System.err.println(span(i))
159+
}
160+
span {
161+
operationName operation()
162+
resourceName "PUT /pfe-request"
163+
spanType DDSpanTypes.HTTP_SERVER
164+
tags {
165+
"$Tags.COMPONENT" "grizzly-filterchain-server"
166+
"$Tags.SPAN_KIND" "server"
167+
"$Tags.HTTP_METHOD" "PUT"
168+
"$Tags.HTTP_STATUS" 200
169+
"$Tags.HTTP_URL" "${address.resolve("/pfe-request")}"
170+
"$Tags.HTTP_HOSTNAME" address.host
171+
"$Tags.HTTP_USER_AGENT" String
172+
"$Tags.PEER_HOST_IPV4" "127.0.0.1"
173+
"$Tags.HTTP_CLIENT_IP" "127.0.0.1"
174+
"$Tags.PEER_PORT" { Integer }
175+
defaultTags()
164176
}
165-
}) { traceAssert ->
166-
167-
span {
168-
operationName operation()
169-
resourceName "PUT /pfe-request"
170-
spanType DDSpanTypes.HTTP_SERVER
177+
}
178+
def flowParent = muleSpan(traceAssert, "mule:flow", "MulePFETestFlow")
179+
def foreachParent = muleSpan(traceAssert, "mule:parallel-foreach", "PFE", flowParent)
180+
muleSpan(traceAssert, "mule:set-payload", "PFE Set Payload", flowParent)
181+
def iterationParents = []
182+
for (def pos = 1; pos <= names.size(); pos++) {
183+
iterationParents += muleSpan(traceAssert, "mule:parallel-foreach:iteration", "PFE", foreachParent)
184+
}
185+
def requestParents =[]
186+
iterationParents.each { parent ->
187+
requestParents += muleSpan(traceAssert, "http:request", "PFE Request", parent)
188+
}
189+
requestParents.each {parent ->
190+
traceAssert.span {
191+
childOf parent
192+
operationName "http.request"
193+
resourceName "GET /remote-pfe-request"
194+
spanType DDSpanTypes.HTTP_CLIENT
171195
tags {
172-
"$Tags.COMPONENT" "grizzly-filterchain-server"
173-
"$Tags.SPAN_KIND" "server"
174-
"$Tags.HTTP_METHOD" "PUT"
196+
"$Tags.COMPONENT" "grizzly-http-async-client"
197+
"$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT
198+
"$Tags.HTTP_METHOD" "GET"
175199
"$Tags.HTTP_STATUS" 200
176-
"$Tags.HTTP_URL" "${address.resolve("/pfe-request")}"
177-
"$Tags.HTTP_HOSTNAME" address.host
178-
"$Tags.HTTP_USER_AGENT" String
179-
"$Tags.PEER_HOST_IPV4" "127.0.0.1"
180-
"$Tags.HTTP_CLIENT_IP" "127.0.0.1"
200+
"$Tags.PEER_HOSTNAME" "localhost"
181201
"$Tags.PEER_PORT" { true } // is this really the best way to ignore tags?
202+
urlTags("${requestServer.address.resolve("/remote-pfe-request")}", ExpectedQueryParams.getExpectedQueryParams("Mule"))
182203
defaultTags()
183204
}
184205
}
185-
def flowParent = muleSpan(traceAssert, "mule:flow", "MulePFETestFlow")
186-
def foreachParent = muleSpan(traceAssert, "mule:parallel-foreach", "PFE", flowParent)
187-
muleSpan(traceAssert, "mule:set-payload", "PFE Set Payload", flowParent)
188-
def iterationParents = []
189-
for (def pos = 1; pos <= names.size(); pos++) {
190-
iterationParents += muleSpan(traceAssert, "mule:parallel-foreach:iteration", "PFE", foreachParent)
191-
}
192-
iterationParents.each { parent ->
193-
muleSpan(traceAssert, "http:request", "PFE Request", parent)
194-
traceAssert.span {
195-
childOfPrevious()
196-
operationName "http.request"
197-
resourceName "GET /remote-pfe-request"
198-
spanType DDSpanTypes.HTTP_CLIENT
199-
tags {
200-
"$Tags.COMPONENT" "grizzly-http-async-client"
201-
"$Tags.SPAN_KIND" Tags.SPAN_KIND_CLIENT
202-
"$Tags.HTTP_METHOD" "GET"
203-
"$Tags.HTTP_STATUS" 200
204-
"$Tags.PEER_HOSTNAME" "localhost"
205-
"$Tags.PEER_PORT" { true } // is this really the best way to ignore tags?
206-
urlTags("${requestServer.address.resolve("/remote-pfe-request")}", ExpectedQueryParams.getExpectedQueryParams("Mule"))
207-
defaultTags()
208-
}
209-
}
210-
}
211206
}
207+
}
208+
}
209+
}
210+
211+
/**
212+
* Sorts the spans by level in the trace (how many parents).
213+
* If in the same level, the one with lower parent it will come first.
214+
*/
215+
private static class TreeComparator implements Comparator<DDSpan> {
216+
private final Map<DDSpan, Long> levels
217+
218+
TreeComparator(List<DDSpan> trace) {
219+
final Map<Long, DDSpan> traceMap = trace.collectEntries { [(it.spanId): it] }
220+
levels = trace.collectEntries({
221+
[(it): walkUp(traceMap, it, 0)]
222+
})
223+
}
224+
225+
@Override
226+
int compare(DDSpan o1, DDSpan o2) {
227+
def len = levels[o1] <=> levels[o2]
228+
// if they are not on the same tree level, take the one with shortest path to the root
229+
if (len != 0) {
230+
return len
231+
}
232+
if (o1.parentId == o2.parentId) {
233+
return o1.spanId <=> o2.spanId
234+
}
235+
return o1.parentId <=> o2.parentId
236+
}
237+
238+
def walkUp(Map<Long, DDSpan> traceMap, DDSpan span, int size) {
239+
if (span.parentId == 0) {
240+
return size
241+
}
242+
return walkUp(traceMap, traceMap.get(span.parentId), size + 1)
212243
}
213244
}
214245

0 commit comments

Comments
 (0)