Skip to content

Commit db6cd4f

Browse files
committed
use awaitility to avoid flakyness
Signed-off-by: Jay DeLuca <jaydeluca4@gmail.com>
1 parent 1f3865f commit db6cd4f

File tree

3 files changed

+55
-5
lines changed

3 files changed

+55
-5
lines changed

prometheus-metrics-core/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,11 @@
5151
<version>3.6.1</version>
5252
<scope>test</scope>
5353
</dependency>
54+
<dependency>
55+
<groupId>org.awaitility</groupId>
56+
<artifactId>awaitility</artifactId>
57+
<version>4.3.0</version>
58+
<scope>test</scope>
59+
</dependency>
5460
</dependencies>
5561
</project>

prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/HistogramTest.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package io.prometheus.metrics.core.metrics;
22

33
import static io.prometheus.metrics.core.metrics.TestUtil.assertExemplarEquals;
4+
import static java.util.concurrent.TimeUnit.SECONDS;
45
import static org.assertj.core.api.Assertions.assertThat;
56
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
67
import static org.assertj.core.data.Offset.offset;
8+
import static org.awaitility.Awaitility.await;
79

810
import io.prometheus.metrics.config.EscapingScheme;
911
import io.prometheus.metrics.config.MetricsProperties;
@@ -1020,10 +1022,17 @@ 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+
getExemplar(histogram.collect(), Double.POSITIVE_INFINITY, "path", "/hello") != null
1034+
&& getExemplar(histogram.collect(), Double.POSITIVE_INFINITY, "path", "/world")
1035+
!= null);
10271036
snapshot = histogram.collect();
10281037
assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello"));
10291038
assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world"));
@@ -1036,16 +1045,28 @@ public void markCurrentSpanAsExemplar() {}
10361045
assertExemplarEquals(ex2a, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/hello"));
10371046
assertExemplarEquals(ex2b, getExemplar(snapshot, Double.POSITIVE_INFINITY, "path", "/world"));
10381047

1039-
Thread.sleep(sampleIntervalMillis + 1);
1048+
waitForSampleInterval(sampleIntervalMillis);
10401049
histogram.labelValues("/hello").observe(1.5);
10411050
histogram.labelValues("/world").observe(1.5);
1042-
Thread.sleep(sampleIntervalMillis + 1);
1051+
waitForSampleInterval(sampleIntervalMillis);
10431052
histogram.labelValues("/hello").observe(2.5);
10441053
histogram.labelValues("/world").observe(2.5);
1045-
Thread.sleep(sampleIntervalMillis + 1);
1054+
waitForSampleInterval(sampleIntervalMillis);
10461055
histogram.labelValues("/hello").observe(3.5);
10471056
histogram.labelValues("/world").observe(3.5);
10481057

1058+
await()
1059+
.atMost(2, SECONDS)
1060+
.until(
1061+
() -> {
1062+
HistogramSnapshot s = histogram.collect();
1063+
return getExemplar(s, 2.0, "path", "/hello") != null
1064+
&& getExemplar(s, 2.0, "path", "/world") != null
1065+
&& getExemplar(s, 3.0, "path", "/hello") != null
1066+
&& getExemplar(s, 3.0, "path", "/world") != null
1067+
&& getExemplar(s, 4.0, "path", "/hello") != null
1068+
&& getExemplar(s, 4.0, "path", "/world") != null;
1069+
});
10491070
snapshot = histogram.collect();
10501071
assertExemplarEquals(ex1a, getExemplar(snapshot, 1.0, "path", "/hello"));
10511072
assertExemplarEquals(ex1b, getExemplar(snapshot, 1.0, "path", "/world"));
@@ -1072,15 +1093,35 @@ public void markCurrentSpanAsExemplar() {}
10721093
"span_id",
10731094
"spanId-11"))
10741095
.build();
1075-
Thread.sleep(sampleIntervalMillis + 1);
1096+
waitForSampleInterval(sampleIntervalMillis);
10761097
histogram
10771098
.labelValues("/hello")
10781099
.observeWithExemplar(3.4, Labels.of("key1", "value1", "key2", "value2"));
1100+
await()
1101+
.atMost(2, SECONDS)
1102+
.until(
1103+
() -> {
1104+
Exemplar actual = getExemplar(histogram.collect(), 4.0, "path", "/hello");
1105+
return actual != null && Math.abs(actual.getValue() - 3.4) < 0.0001;
1106+
});
10791107
snapshot = histogram.collect();
10801108
// custom exemplars have preference, so the automatic exemplar is replaced
10811109
assertExemplarEquals(custom, getExemplar(snapshot, 4.0, "path", "/hello"));
10821110
}
10831111

1112+
/**
1113+
* Waits for the exemplar sampler's rate limit window so the next observation is accepted. Uses a
1114+
* deterministic delay (2x sample interval) so the scheduler is ready.
1115+
*/
1116+
private static void waitForSampleInterval(long sampleIntervalMillis) {
1117+
try {
1118+
Thread.sleep(2 * sampleIntervalMillis);
1119+
} catch (InterruptedException e) {
1120+
Thread.currentThread().interrupt();
1121+
throw new AssertionError("Interrupted while waiting for sample interval", e);
1122+
}
1123+
}
1124+
10841125
private Exemplar getExemplar(HistogramSnapshot snapshot, double le, String... labels) {
10851126
HistogramSnapshot.HistogramDataPointSnapshot data =
10861127
snapshot.getDataPoints().stream()

prometheus-metrics-core/src/test/java/io/prometheus/metrics/core/metrics/TestUtil.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
public class TestUtil {
1010

1111
public static void assertExemplarEquals(Exemplar expected, Exemplar actual) {
12+
assertThat(actual)
13+
.as("Expected exemplar to be present (rate-limited sampler may not have accepted yet)")
14+
.isNotNull();
1215
// ignore timestamp
1316
assertThat(actual.getValue()).isCloseTo(expected.getValue(), offset(0.00001));
1417
assertThat((Iterable<? extends Label>) actual.getLabels()).isEqualTo(expected.getLabels());

0 commit comments

Comments
 (0)