Skip to content

Commit 717dbfb

Browse files
committed
use parameterized tests
Signed-off-by: Gregor Zeitlinger <[email protected]>
1 parent 3418c7e commit 717dbfb

File tree

2 files changed

+80
-57
lines changed

2 files changed

+80
-57
lines changed

prometheus-metrics-model/src/main/java/io/prometheus/metrics/model/snapshots/PrometheusNaming.java

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
package io.prometheus.metrics.model.snapshots;
22

3-
import static java.lang.Character.MAX_CODE_POINT;
4-
import static java.lang.Character.MAX_LOW_SURROGATE;
5-
import static java.lang.Character.MIN_HIGH_SURROGATE;
6-
73
import io.prometheus.metrics.config.PrometheusProperties;
4+
import io.prometheus.metrics.config.PrometheusPropertiesLoader;
5+
86
import java.nio.charset.StandardCharsets;
97
import java.util.ArrayList;
108
import java.util.List;
119
import java.util.regex.Matcher;
1210
import java.util.regex.Pattern;
1311

12+
import static java.lang.Character.MAX_CODE_POINT;
13+
import static java.lang.Character.MAX_LOW_SURROGATE;
14+
import static java.lang.Character.MIN_HIGH_SURROGATE;
15+
1416
/**
1517
* Utility for Prometheus Metric and Label naming.
1618
*
@@ -26,7 +28,8 @@ public class PrometheusNaming {
2628
* components that don't support UTF-8 may result in bugs or other undefined behavior. This value
2729
* is intended to be set by UTF-8-aware binaries as part of their startup via a properties file.
2830
*/
29-
public static final ValidationScheme nameValidationScheme = initValidationScheme();
31+
public static ValidationScheme nameValidationScheme =
32+
initValidationScheme(PrometheusProperties.get());
3033

3134
/** Default escaping scheme for names when not specified. */
3235
public static final EscapingScheme DEFAULT_ESCAPING_SCHEME =
@@ -75,16 +78,19 @@ public class PrometheusNaming {
7578
".total", ".created", ".bucket", ".info"
7679
};
7780

78-
static ValidationScheme initValidationScheme() {
79-
String validationScheme =
80-
PrometheusProperties.get().getNamingProperties().getValidationScheme();
81-
if (validationScheme != null && validationScheme.equals("utf-8")) {
81+
static ValidationScheme initValidationScheme(PrometheusProperties properties) {
82+
if ("utf-8".equals(properties.getNamingProperties().getValidationScheme())) {
8283
return ValidationScheme.UTF_8_VALIDATION;
8384
}
8485

8586
return ValidationScheme.LEGACY_VALIDATION;
8687
}
8788

89+
// VisibleForTesting
90+
public static void resetForTest() {
91+
nameValidationScheme = initValidationScheme(PrometheusPropertiesLoader.load());
92+
}
93+
8894
/**
8995
* Get the current validation scheme. This method exists primarily to enable testing different
9096
* validation behaviors while keeping the validation scheme field final and immutable.

prometheus-metrics-model/src/test/java/io/prometheus/metrics/model/snapshots/PrometheusNamingTest.java

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,37 @@
11
package io.prometheus.metrics.model.snapshots;
22

3-
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.*;
3+
import org.junit.jupiter.api.AfterEach;
4+
import org.junit.jupiter.api.Test;
5+
import org.junit.jupiter.params.ParameterizedTest;
6+
import org.junit.jupiter.params.provider.Arguments;
7+
import org.junit.jupiter.params.provider.MethodSource;
8+
import org.junitpioneer.jupiter.SetSystemProperty;
9+
import org.mockito.MockedStatic;
10+
11+
import java.util.stream.Stream;
12+
13+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.escapeMetricSnapshot;
14+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.escapeName;
15+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.isValidLabelName;
16+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.prometheusName;
17+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeLabelName;
18+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeMetricName;
19+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.sanitizeUnitName;
20+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.unescapeName;
21+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.validateMetricName;
22+
import static io.prometheus.metrics.model.snapshots.PrometheusNaming.validateUnitName;
423
import static org.assertj.core.api.Assertions.assertThat;
524
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
625
import static org.mockito.Mockito.CALLS_REAL_METHODS;
726
import static org.mockito.Mockito.mockStatic;
827

9-
import org.junit.jupiter.api.Test;
10-
import org.mockito.MockedStatic;
11-
1228
class PrometheusNamingTest {
1329

30+
@AfterEach
31+
void tearDown() {
32+
PrometheusNaming.resetForTest();
33+
}
34+
1435
@Test
1536
public void testSanitizeMetricName() {
1637
assertThat(prometheusName(sanitizeMetricName("0abc.def"))).isEqualTo("_abc_def");
@@ -27,7 +48,6 @@ public void testSanitizeMetricName() {
2748

2849
@Test
2950
public void testSanitizeMetricNameWithUnit() {
30-
3151
assertThat(prometheusName(sanitizeMetricName("0abc.def", Unit.RATIO)))
3252
.isEqualTo("_abc_def_" + Unit.RATIO);
3353
assertThat(prometheusName(sanitizeMetricName("___ab.:c0", Unit.RATIO)))
@@ -46,7 +66,6 @@ public void testSanitizeMetricNameWithUnit() {
4666

4767
@Test
4868
public void testSanitizeLabelName() {
49-
5069
assertThat(prometheusName(sanitizeLabelName("0abc.def"))).isEqualTo("_abc_def");
5170
assertThat(prometheusName(sanitizeLabelName("_abc"))).isEqualTo("_abc");
5271
assertThat(prometheusName(sanitizeLabelName("__abc"))).isEqualTo("_abc");
@@ -102,52 +121,50 @@ public void testEmptyUnitName() {
102121
.isThrownBy(() -> sanitizeUnitName(""));
103122
}
104123

105-
@Test
106-
public void testMetricNameIsValid() {
107-
assertThat(validateMetricName("Avalid_23name")).isNull();
108-
assertThat(validateMetricName("_Avalid_23name")).isNull();
109-
assertThat(validateMetricName("1valid_23name"))
110-
.isEqualTo("The metric name contains unsupported characters");
111-
assertThat(validateMetricName("avalid_23name")).isNull();
112-
assertThat(validateMetricName("Ava:lid_23name")).isNull();
113-
assertThat(validateMetricName("a lid_23name"))
114-
.isEqualTo("The metric name contains unsupported characters");
115-
assertThat(validateMetricName(":leading_colon")).isNull();
116-
assertThat(validateMetricName("colon:in:the:middle")).isNull();
117-
assertThat(validateMetricName("")).isEqualTo("The metric name contains unsupported characters");
118-
assertThat(validateMetricName("a\ud800z"))
119-
.isEqualTo("The metric name contains unsupported characters");
124+
@SuppressWarnings("unused")
125+
@SetSystemProperty(key = "io.prometheus.naming.validationScheme", value = "utf-8")
126+
@ParameterizedTest
127+
@MethodSource("testLabelNameIsValid")
128+
public void testLabelNameIsValidUtf8(
129+
String labelName, boolean legacyValid, boolean utf8Valid, boolean legacyCharsetValid) {
130+
PrometheusNaming.resetForTest();
131+
assertMetricName(labelName, utf8Valid);
132+
// for some reason, an empty label name is considered valid in UTF-8 validation
133+
assertLabelName(labelName, utf8Valid || labelName.isEmpty());
120134
}
121135

122-
@Test
123-
public void testLabelNameIsValid() {
124-
try (MockedStatic<PrometheusNaming> mock =
125-
mockStatic(PrometheusNaming.class, CALLS_REAL_METHODS)) {
126-
// Mock the validation scheme to use UTF-8 validation for this test
127-
mock.when(PrometheusNaming::getValidationScheme)
128-
.thenReturn(ValidationScheme.UTF_8_VALIDATION);
136+
@SuppressWarnings("unused")
137+
@ParameterizedTest
138+
@MethodSource("testLabelNameIsValid")
139+
public void testLabelNameIsValidLegacy(
140+
String labelName, boolean legacyValid, boolean utf8Valid, boolean legacyCharsetValid) {
141+
assertMetricName(labelName, legacyCharsetValid);
142+
assertLabelName(labelName, legacyValid);
143+
}
129144

130-
// These assertions now use UTF-8 validation behavior
131-
assertThat(isValidLabelName("Avalid_23name")).isTrue();
132-
assertThat(isValidLabelName("_Avalid_23name")).isTrue();
133-
assertThat(isValidLabelName("1valid_23name")).isTrue();
134-
assertThat(isValidLabelName("avalid_23name")).isTrue();
135-
assertThat(isValidLabelName("Ava:lid_23name")).isTrue();
136-
assertThat(isValidLabelName("a lid_23name")).isTrue();
137-
assertThat(isValidLabelName(":leading_colon")).isTrue();
138-
assertThat(isValidLabelName("colon:in:the:middle")).isTrue();
139-
assertThat(isValidLabelName("a\ud800z")).isFalse();
140-
}
145+
private static void assertLabelName(String labelName, boolean legacyValid) {
146+
assertThat(isValidLabelName(labelName)).describedAs("isValidLabelName(%s)", labelName)
147+
.isEqualTo(legacyValid);
148+
}
149+
150+
private static void assertMetricName(String labelName, boolean valid) {
151+
assertThat(validateMetricName(labelName)).describedAs("validateMetricName(%s)", labelName)
152+
.isEqualTo(valid ? null : "The metric name contains unsupported characters");
153+
}
141154

142-
assertThat(isValidLabelName("Avalid_23name")).isTrue();
143-
assertThat(isValidLabelName("_Avalid_23name")).isTrue();
144-
assertThat(isValidLabelName("1valid_23name")).isFalse();
145-
assertThat(isValidLabelName("avalid_23name")).isTrue();
146-
assertThat(isValidLabelName("Ava:lid_23name")).isFalse();
147-
assertThat(isValidLabelName("a lid_23name")).isFalse();
148-
assertThat(isValidLabelName(":leading_colon")).isFalse();
149-
assertThat(isValidLabelName("colon:in:the:middle")).isFalse();
150-
assertThat(isValidLabelName("a\ud800z")).isFalse();
155+
static Stream<Arguments> testLabelNameIsValid() {
156+
return Stream.of(
157+
Arguments.of("", false, false, false),
158+
Arguments.of("Avalid_23name", true, true, true),
159+
Arguments.of("_Avalid_23name", true, true, true),
160+
Arguments.of("1valid_23name", false, true, false),
161+
Arguments.of("avalid_23name", true, true, true),
162+
Arguments.of("Ava:lid_23name", false, true, true),
163+
Arguments.of("a lid_23name", false, true, false),
164+
Arguments.of(":leading_colon", false, true, true),
165+
Arguments.of("colon:in:the:middle", false, true, true),
166+
Arguments.of("aΩz", false, true, false),
167+
Arguments.of("a\ud800z", false, false, false));
151168
}
152169

153170
@Test

0 commit comments

Comments
 (0)