11package io .prometheus .metrics .core .metrics ;
22
33import static io .prometheus .metrics .core .metrics .TestUtil .assertExemplarEquals ;
4+ import static java .util .concurrent .TimeUnit .SECONDS ;
45import static org .assertj .core .api .Assertions .assertThat ;
56import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
67import static org .assertj .core .data .Offset .offset ;
8+ import static org .awaitility .Awaitility .await ;
79
810import io .prometheus .metrics .config .EscapingScheme ;
911import io .prometheus .metrics .config .MetricsProperties ;
@@ -1020,10 +1022,18 @@ public void markCurrentSpanAsExemplar() {}
10201022 assertThat (getExemplar (snapshot , Double .POSITIVE_INFINITY , "path" , "/hello" )).isNull ();
10211023 assertThat (getExemplar (snapshot , Double .POSITIVE_INFINITY , "path" , "/world" )).isNull ();
10221024
1023- Thread . sleep (sampleIntervalMillis + 1 );
1025+ waitForSampleInterval (sampleIntervalMillis );
10241026 histogram .labelValues ("/hello" ).observe (4.5 );
10251027 histogram .labelValues ("/world" ).observe (4.5 );
10261028
1029+ await ()
1030+ .atMost (2 , SECONDS )
1031+ .until (
1032+ () -> {
1033+ HistogramSnapshot s = histogram .collect ();
1034+ return getExemplar (s , Double .POSITIVE_INFINITY , "path" , "/hello" ) != null
1035+ && getExemplar (s , Double .POSITIVE_INFINITY , "path" , "/world" ) != null ;
1036+ });
10271037 snapshot = histogram .collect ();
10281038 assertExemplarEquals (ex1a , getExemplar (snapshot , 1.0 , "path" , "/hello" ));
10291039 assertExemplarEquals (ex1b , getExemplar (snapshot , 1.0 , "path" , "/world" ));
@@ -1036,16 +1046,28 @@ public void markCurrentSpanAsExemplar() {}
10361046 assertExemplarEquals (ex2a , getExemplar (snapshot , Double .POSITIVE_INFINITY , "path" , "/hello" ));
10371047 assertExemplarEquals (ex2b , getExemplar (snapshot , Double .POSITIVE_INFINITY , "path" , "/world" ));
10381048
1039- Thread . sleep (sampleIntervalMillis + 1 );
1049+ waitForSampleInterval (sampleIntervalMillis );
10401050 histogram .labelValues ("/hello" ).observe (1.5 );
10411051 histogram .labelValues ("/world" ).observe (1.5 );
1042- Thread . sleep (sampleIntervalMillis + 1 );
1052+ waitForSampleInterval (sampleIntervalMillis );
10431053 histogram .labelValues ("/hello" ).observe (2.5 );
10441054 histogram .labelValues ("/world" ).observe (2.5 );
1045- Thread . sleep (sampleIntervalMillis + 1 );
1055+ waitForSampleInterval (sampleIntervalMillis );
10461056 histogram .labelValues ("/hello" ).observe (3.5 );
10471057 histogram .labelValues ("/world" ).observe (3.5 );
10481058
1059+ await ()
1060+ .atMost (2 , SECONDS )
1061+ .until (
1062+ () -> {
1063+ HistogramSnapshot s = histogram .collect ();
1064+ return getExemplar (s , 2.0 , "path" , "/hello" ) != null
1065+ && getExemplar (s , 2.0 , "path" , "/world" ) != null
1066+ && getExemplar (s , 3.0 , "path" , "/hello" ) != null
1067+ && getExemplar (s , 3.0 , "path" , "/world" ) != null
1068+ && getExemplar (s , 4.0 , "path" , "/hello" ) != null
1069+ && getExemplar (s , 4.0 , "path" , "/world" ) != null ;
1070+ });
10491071 snapshot = histogram .collect ();
10501072 assertExemplarEquals (ex1a , getExemplar (snapshot , 1.0 , "path" , "/hello" ));
10511073 assertExemplarEquals (ex1b , getExemplar (snapshot , 1.0 , "path" , "/world" ));
@@ -1072,15 +1094,32 @@ public void markCurrentSpanAsExemplar() {}
10721094 "span_id" ,
10731095 "spanId-11" ))
10741096 .build ();
1075- Thread . sleep (sampleIntervalMillis + 1 );
1097+ waitForSampleInterval (sampleIntervalMillis );
10761098 histogram
10771099 .labelValues ("/hello" )
10781100 .observeWithExemplar (3.4 , Labels .of ("key1" , "value1" , "key2" , "value2" ));
1101+ await ()
1102+ .atMost (2 , SECONDS )
1103+ .until (
1104+ () -> {
1105+ Exemplar actual = getExemplar (histogram .collect (), 4.0 , "path" , "/hello" );
1106+ return actual != null && Math .abs (actual .getValue () - 3.4 ) < 0.00001 ;
1107+ });
10791108 snapshot = histogram .collect ();
10801109 // custom exemplars have preference, so the automatic exemplar is replaced
10811110 assertExemplarEquals (custom , getExemplar (snapshot , 4.0 , "path" , "/hello" ));
10821111 }
10831112
1113+ /** Waits for the exemplar sampler's rate limit window so the next observation is accepted. */
1114+ private static void waitForSampleInterval (long sampleIntervalMillis ) {
1115+ try {
1116+ Thread .sleep (2 * sampleIntervalMillis );
1117+ } catch (InterruptedException e ) {
1118+ Thread .currentThread ().interrupt ();
1119+ throw new AssertionError ("Interrupted while waiting for sample interval" , e );
1120+ }
1121+ }
1122+
10841123 private Exemplar getExemplar (HistogramSnapshot snapshot , double le , String ... labels ) {
10851124 HistogramSnapshot .HistogramDataPointSnapshot data =
10861125 snapshot .getDataPoints ().stream ()
0 commit comments