56
56
57
57
import java .net .InetSocketAddress ;
58
58
import java .net .UnknownHostException ;
59
+ import java .time .Instant ;
59
60
import java .util .ArrayList ;
60
61
import java .util .Arrays ;
61
62
import java .util .Collection ;
68
69
import java .util .Set ;
69
70
import java .util .concurrent .CountDownLatch ;
70
71
import java .util .concurrent .TimeUnit ;
72
+ import java .util .concurrent .atomic .AtomicReference ;
71
73
72
74
import static java .net .InetAddress .getByName ;
73
75
import static java .util .Arrays .asList ;
82
84
import static org .hamcrest .Matchers .containsInAnyOrder ;
83
85
import static org .hamcrest .Matchers .containsString ;
84
86
import static org .hamcrest .Matchers .equalTo ;
87
+ import static org .hamcrest .Matchers .greaterThanOrEqualTo ;
85
88
import static org .hamcrest .Matchers .hasSize ;
86
89
import static org .hamcrest .Matchers .instanceOf ;
87
90
import static org .hamcrest .Matchers .is ;
91
+ import static org .hamcrest .Matchers .lessThanOrEqualTo ;
88
92
import static org .hamcrest .Matchers .notNullValue ;
89
93
import static org .hamcrest .Matchers .nullValue ;
90
94
import static org .mockito .Mockito .mock ;
@@ -324,6 +328,7 @@ protected void populatePerRequestThreadContext(RestRequest restRequest, ThreadCo
324
328
*/
325
329
public void testTraceParentAndTraceId () {
326
330
final String traceParentValue = "00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01" ;
331
+ final AtomicReference <Instant > traceStartTimeRef = new AtomicReference <>();
327
332
final HttpServerTransport .Dispatcher dispatcher = new HttpServerTransport .Dispatcher () {
328
333
329
334
@ Override
@@ -332,7 +337,8 @@ public void dispatchRequest(final RestRequest request, final RestChannel channel
332
337
assertThat (threadContext .getHeader (Task .TRACE_PARENT_HTTP_HEADER ), nullValue ());
333
338
assertThat (threadContext .getTransient ("parent_" + Task .TRACE_PARENT_HTTP_HEADER ), equalTo (traceParentValue ));
334
339
// request trace start time is also set
335
- assertThat (threadContext .getTransient (Task .TRACE_START_TIME ), notNullValue ());
340
+ assertTrue (traceStartTimeRef .compareAndSet (null , threadContext .getTransient (Task .TRACE_START_TIME )));
341
+ assertNotNull (traceStartTimeRef .get ());
336
342
}
337
343
338
344
@ Override
@@ -371,14 +377,10 @@ protected HttpServerChannel bind(InetSocketAddress hostAddress) {
371
377
}
372
378
373
379
@ Override
374
- protected void doStart () {
375
-
376
- }
380
+ protected void doStart () {}
377
381
378
382
@ Override
379
- protected void stopInternal () {
380
-
381
- }
383
+ protected void stopInternal () {}
382
384
383
385
@ Override
384
386
public HttpStats stats () {
@@ -391,11 +393,20 @@ protected void populatePerRequestThreadContext(RestRequest restRequest, ThreadCo
391
393
}
392
394
}
393
395
) {
396
+ final var systemTimeBeforeRequest = System .currentTimeMillis ();
394
397
transport .dispatchRequest (fakeRequest , channel , null );
398
+ final var systemTimeAfterRequest = System .currentTimeMillis ();
395
399
// headers are "null" here, aka not present, because the thread context changes containing them is to be confined to the request
396
400
assertThat (threadPool .getThreadContext ().getHeader (Task .TRACE_ID ), nullValue ());
397
401
assertThat (threadPool .getThreadContext ().getHeader (Task .TRACE_PARENT_HTTP_HEADER ), nullValue ());
398
402
assertThat (threadPool .getThreadContext ().getTransient ("parent_" + Task .TRACE_PARENT_HTTP_HEADER ), nullValue ());
403
+
404
+ // system clock is not _technically_ monotonic but in practice it's very unlikely to see a discontinuity here
405
+ assertThat (
406
+ traceStartTimeRef .get ().toEpochMilli (),
407
+ allOf (greaterThanOrEqualTo (systemTimeBeforeRequest ), lessThanOrEqualTo (systemTimeAfterRequest ))
408
+ );
409
+
399
410
transport .dispatchRequest (null , null , new Exception ());
400
411
// headers are "null" here, aka not present, because the thread context changes containing them is to be confined to the request
401
412
assertThat (threadPool .getThreadContext ().getHeader (Task .TRACE_ID ), nullValue ());
0 commit comments