|
3 | 3 | import static io.prometheus.metrics.model.snapshots.SnapshotEscaper.escapeMetricSnapshot; |
4 | 4 | import static io.prometheus.metrics.model.snapshots.SnapshotEscaper.escapeName; |
5 | 5 | import static io.prometheus.metrics.model.snapshots.SnapshotEscaper.getSnapshotLabelName; |
6 | | -import static io.prometheus.metrics.model.snapshots.SnapshotEscaper.unescapeName; |
7 | 6 | import static org.assertj.core.api.Assertions.assertThat; |
8 | 7 |
|
9 | 8 | import java.util.stream.Stream; |
10 | 9 | import org.junit.jupiter.api.Test; |
11 | 10 | import org.junit.jupiter.params.ParameterizedTest; |
12 | 11 | import org.junit.jupiter.params.provider.Arguments; |
13 | | -import org.junit.jupiter.params.provider.CsvSource; |
14 | 12 | import org.junit.jupiter.params.provider.MethodSource; |
15 | 13 |
|
16 | 14 | class SnapshotEscaperTest { |
17 | 15 |
|
18 | 16 | @ParameterizedTest |
19 | 17 | @MethodSource("escapeNameLegacyTestCases") |
20 | | - public void testEscapeNameLegacy( |
21 | | - String input, EscapingScheme escapingScheme, String expected, String unescapeExpected) { |
22 | | - assertEscape(input, escapingScheme, expected, unescapeExpected); |
23 | | - } |
24 | | - |
25 | | - @ParameterizedTest |
26 | | - @MethodSource("escapeNameUtf8TestCases") |
27 | | - public void testEscapeNameUtf8( |
28 | | - String input, EscapingScheme escapingScheme, String expected, String unescapeExpected) { |
29 | | - assertEscape(input, escapingScheme, expected, unescapeExpected); |
30 | | - } |
31 | | - |
32 | | - private static void assertEscape( |
33 | | - String input, EscapingScheme escapingScheme, String expected, String unescapeExpected) { |
34 | | - String escaped = escapeName(input, escapingScheme); |
35 | | - assertThat(escaped).isEqualTo(expected); |
36 | | - assertThat(unescapeName(escaped, escapingScheme)).isEqualTo(unescapeExpected); |
| 18 | + public void testEscapeName(String input, EscapingScheme escapingScheme, String expected) { |
| 19 | + assertThat(escapeName(input, escapingScheme)).isEqualTo(expected); |
37 | 20 | } |
38 | 21 |
|
39 | 22 | static Stream<Arguments> escapeNameLegacyTestCases() { |
40 | 23 | return Stream.of( |
41 | | - Arguments.of("", EscapingScheme.UNDERSCORE_ESCAPING, "", ""), |
42 | | - Arguments.of("", EscapingScheme.DOTS_ESCAPING, "", ""), |
43 | | - Arguments.of("", EscapingScheme.VALUE_ENCODING_ESCAPING, "", ""), |
| 24 | + Arguments.of("", EscapingScheme.UNDERSCORE_ESCAPING, ""), |
| 25 | + Arguments.of("", EscapingScheme.DOTS_ESCAPING, ""), |
| 26 | + Arguments.of("", EscapingScheme.VALUE_ENCODING_ESCAPING, ""), |
44 | 27 | Arguments.of( |
45 | | - "no:escaping_required", |
46 | | - EscapingScheme.UNDERSCORE_ESCAPING, |
47 | | - "no:escaping_required", |
48 | | - "no:escaping_required"), |
| 28 | + "no:escaping_required", EscapingScheme.UNDERSCORE_ESCAPING, "no:escaping_required"), |
49 | 29 | // Dots escaping will escape underscores even though it's not strictly |
50 | 30 | // necessary for compatibility. |
| 31 | + Arguments.of("no:escaping_required", EscapingScheme.DOTS_ESCAPING, "no:escaping__required"), |
51 | 32 | Arguments.of( |
52 | | - "no:escaping_required", |
53 | | - EscapingScheme.DOTS_ESCAPING, |
54 | | - "no:escaping__required", |
55 | | - "no:escaping_required"), |
56 | | - Arguments.of( |
57 | | - "no:escaping_required", |
58 | | - EscapingScheme.VALUE_ENCODING_ESCAPING, |
59 | | - "no:escaping_required", |
60 | | - "no:escaping_required"), |
| 33 | + "no:escaping_required", EscapingScheme.VALUE_ENCODING_ESCAPING, "no:escaping_required"), |
61 | 34 | Arguments.of( |
62 | | - "no:escaping_required", |
63 | | - EscapingScheme.UNDERSCORE_ESCAPING, |
64 | | - "no:escaping_required", |
65 | | - "no:escaping_required"), |
| 35 | + "no:escaping_required", EscapingScheme.UNDERSCORE_ESCAPING, "no:escaping_required"), |
66 | 36 | Arguments.of( |
67 | 37 | "mysystem.prod.west.cpu.load", |
68 | 38 | EscapingScheme.DOTS_ESCAPING, |
69 | | - "mysystem_dot_prod_dot_west_dot_cpu_dot_load", |
70 | | - "mysystem.prod.west.cpu.load"), |
| 39 | + "mysystem_dot_prod_dot_west_dot_cpu_dot_load"), |
71 | 40 | Arguments.of( |
72 | 41 | "mysystem.prod.west.cpu.load_total", |
73 | 42 | EscapingScheme.DOTS_ESCAPING, |
74 | | - "mysystem_dot_prod_dot_west_dot_cpu_dot_load__total", |
75 | | - "mysystem.prod.west.cpu.load_total"), |
76 | | - Arguments.of( |
77 | | - "http.status:sum", |
78 | | - EscapingScheme.DOTS_ESCAPING, |
79 | | - "http_dot_status:sum", |
80 | | - "http.status:sum"), |
81 | | - Arguments.of( |
82 | | - "label with 😱", EscapingScheme.UNDERSCORE_ESCAPING, "label_with__", "label_with__"), |
83 | | - Arguments.of( |
84 | | - "label with 😱", EscapingScheme.DOTS_ESCAPING, "label__with____", "label_with__"), |
| 43 | + "mysystem_dot_prod_dot_west_dot_cpu_dot_load__total"), |
| 44 | + Arguments.of("http.status:sum", EscapingScheme.DOTS_ESCAPING, "http_dot_status:sum"), |
| 45 | + Arguments.of("label with 😱", EscapingScheme.UNDERSCORE_ESCAPING, "label_with__"), |
| 46 | + Arguments.of("label with 😱", EscapingScheme.DOTS_ESCAPING, "label__with____"), |
85 | 47 | Arguments.of( |
86 | | - "label with 😱", |
87 | | - EscapingScheme.VALUE_ENCODING_ESCAPING, |
88 | | - "U__label_20_with_20__1f631_", |
89 | | - "label with 😱"), |
| 48 | + "label with 😱", EscapingScheme.VALUE_ENCODING_ESCAPING, "U__label_20_with_20__1f631_"), |
90 | 49 | // name with unicode characters > 0x100 |
91 | | - Arguments.of("花火", EscapingScheme.UNDERSCORE_ESCAPING, "__", "__"), |
| 50 | + Arguments.of("花火", EscapingScheme.UNDERSCORE_ESCAPING, "__"), |
92 | 51 | // Dots-replacement does not know the difference between two replaced |
93 | | - Arguments.of("花火", EscapingScheme.DOTS_ESCAPING, "____", "__"), |
94 | | - Arguments.of("花火", EscapingScheme.VALUE_ENCODING_ESCAPING, "U___82b1__706b_", "花火"), |
| 52 | + Arguments.of("花火", EscapingScheme.DOTS_ESCAPING, "____"), |
| 53 | + Arguments.of("花火", EscapingScheme.VALUE_ENCODING_ESCAPING, "U___82b1__706b_"), |
95 | 54 | // name with spaces and edge-case value |
| 55 | + Arguments.of("label with Ā", EscapingScheme.UNDERSCORE_ESCAPING, "label_with__"), |
| 56 | + Arguments.of("label with Ā", EscapingScheme.DOTS_ESCAPING, "label__with____"), |
96 | 57 | Arguments.of( |
97 | | - "label with Ā", EscapingScheme.UNDERSCORE_ESCAPING, "label_with__", "label_with__"), |
98 | | - Arguments.of( |
99 | | - "label with Ā", EscapingScheme.DOTS_ESCAPING, "label__with____", "label_with__"), |
100 | | - Arguments.of( |
101 | | - "label with Ā", |
102 | | - EscapingScheme.VALUE_ENCODING_ESCAPING, |
103 | | - "U__label_20_with_20__100_", |
104 | | - "label with Ā")); |
105 | | - } |
106 | | - |
107 | | - static Stream<Arguments> escapeNameUtf8TestCases() { |
108 | | - return Stream.of( |
| 58 | + "label with Ā", EscapingScheme.VALUE_ENCODING_ESCAPING, "U__label_20_with_20__100_"), |
109 | 59 | // name with dots - needs UTF-8 validation for escaping to occur |
110 | 60 | Arguments.of( |
111 | 61 | "mysystem.prod.west.cpu.load", |
112 | 62 | EscapingScheme.UNDERSCORE_ESCAPING, |
113 | | - "mysystem_prod_west_cpu_load", |
114 | 63 | "mysystem_prod_west_cpu_load"), |
115 | 64 | Arguments.of( |
116 | 65 | "mysystem.prod.west.cpu.load", |
117 | 66 | EscapingScheme.VALUE_ENCODING_ESCAPING, |
118 | | - "U__mysystem_2e_prod_2e_west_2e_cpu_2e_load", |
119 | | - "mysystem.prod.west.cpu.load"), |
| 67 | + "U__mysystem_2e_prod_2e_west_2e_cpu_2e_load"), |
120 | 68 | Arguments.of( |
121 | 69 | "mysystem.prod.west.cpu.load_total", |
122 | 70 | EscapingScheme.UNDERSCORE_ESCAPING, |
123 | | - "mysystem_prod_west_cpu_load_total", |
124 | 71 | "mysystem_prod_west_cpu_load_total"), |
125 | 72 | Arguments.of( |
126 | 73 | "mysystem.prod.west.cpu.load_total", |
127 | 74 | EscapingScheme.VALUE_ENCODING_ESCAPING, |
128 | | - "U__mysystem_2e_prod_2e_west_2e_cpu_2e_load__total", |
129 | | - "mysystem.prod.west.cpu.load_total"), |
| 75 | + "U__mysystem_2e_prod_2e_west_2e_cpu_2e_load__total"), |
| 76 | + Arguments.of("http.status:sum", EscapingScheme.UNDERSCORE_ESCAPING, "http_status:sum"), |
130 | 77 | Arguments.of( |
131 | | - "http.status:sum", |
132 | | - EscapingScheme.UNDERSCORE_ESCAPING, |
133 | | - "http_status:sum", |
134 | | - "http_status:sum"), |
135 | | - Arguments.of( |
136 | | - "http.status:sum", |
137 | | - EscapingScheme.VALUE_ENCODING_ESCAPING, |
138 | | - "U__http_2e_status:sum", |
139 | | - "http.status:sum")); |
140 | | - } |
141 | | - |
142 | | - @ParameterizedTest |
143 | | - @CsvSource( |
144 | | - value = { |
145 | | - // empty string |
146 | | - "'',''", |
147 | | - // basic case, no error |
148 | | - "U__no:unescapingrequired,no:unescapingrequired", |
149 | | - // capitals ok, no error |
150 | | - "U__capitals_2E_ok,capitals.ok", |
151 | | - // underscores, no error |
152 | | - "U__underscores__doubled__,underscores_doubled_", |
153 | | - // invalid single underscore |
154 | | - "U__underscores_doubled_,U__underscores_doubled_", |
155 | | - // invalid single underscore, 2 |
156 | | - "U__underscores__doubled_,U__underscores__doubled_", |
157 | | - // giant fake UTF-8 code |
158 | | - "U__my__hack_2e_attempt_872348732fabdabbab_,U__my__hack_2e_attempt_872348732fabdabbab_", |
159 | | - // trailing UTF-8 |
160 | | - "U__my__hack_2e,U__my__hack_2e", |
161 | | - // invalid UTF-8 value |
162 | | - "U__bad__utf_2eg_,U__bad__utf_2eg_", |
163 | | - // surrogate UTF-8 value |
164 | | - "U__bad__utf_D900_,U__bad__utf_D900_", |
165 | | - }) |
166 | | - public void testValueUnescapeErrors(String escapedName, String expectedUnescapedName) { |
167 | | - assertThat(unescapeName(escapedName, EscapingScheme.VALUE_ENCODING_ESCAPING)) |
168 | | - .isEqualTo(expectedUnescapedName); |
| 78 | + "http.status:sum", EscapingScheme.VALUE_ENCODING_ESCAPING, "U__http_2e_status:sum")); |
169 | 79 | } |
170 | 80 |
|
171 | 81 | @Test |
|
0 commit comments