|
5 | 5 |
|
6 | 6 | package io.opentelemetry.contrib.jmxscraper.assertions; |
7 | 7 |
|
8 | | -import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attribute; |
| 8 | +import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeSet; |
9 | 9 |
|
10 | 10 | import com.google.errorprone.annotations.CanIgnoreReturnValue; |
11 | 11 | import io.opentelemetry.proto.common.v1.KeyValue; |
12 | 12 | import io.opentelemetry.proto.metrics.v1.Metric; |
13 | 13 | import io.opentelemetry.proto.metrics.v1.NumberDataPoint; |
14 | 14 | import java.util.Arrays; |
15 | 15 | import java.util.Collection; |
16 | | -import java.util.Collections; |
17 | 16 | import java.util.HashSet; |
18 | 17 | import java.util.List; |
| 18 | +import java.util.Map; |
19 | 19 | import java.util.Set; |
20 | 20 | import java.util.function.Consumer; |
21 | 21 | import java.util.stream.Collectors; |
@@ -234,64 +234,78 @@ private void dataPointsCommonCheck(List<NumberDataPoint> dataPoints) { |
234 | 234 | } |
235 | 235 |
|
236 | 236 | /** |
237 | | - * Verifies that all data points have the same expected one attribute |
| 237 | + * Verifies that all metric data points have the same expected one attribute |
238 | 238 | * |
239 | | - * @param expectedAttribute expected attribute |
| 239 | + * @param expectedAttribute attribute matcher to validate data points attributes |
240 | 240 | * @return this |
241 | 241 | */ |
242 | 242 | @CanIgnoreReturnValue |
243 | 243 | public final MetricAssert hasDataPointsWithOneAttribute(AttributeMatcher expectedAttribute) { |
244 | | - return hasDataPointsWithAttributes(Collections.singleton(expectedAttribute)); |
| 244 | + return hasDataPointsWithAttributes(attributeSet(expectedAttribute)); |
245 | 245 | } |
246 | 246 |
|
247 | 247 | /** |
248 | | - * Verifies that every provided attribute matcher set matches attributes of at least one metric |
249 | | - * data point. Attribute matcher set is considered matching data point attributes if each matcher |
250 | | - * matches exactly one data point attribute |
| 248 | + * Verifies that every data point attributes set is matched by one of matcher sets provided. Data |
| 249 | + * point attributes set is matched by matcher set if each attribute is matched by one matcher and |
| 250 | + * matcher count is equal to attribute count. |
251 | 251 | * |
252 | | - * @param attributeSets array of attribute matcher sets |
| 252 | + * @param attributeMatchers array of attribute matcher sets |
253 | 253 | * @return this |
254 | 254 | */ |
255 | 255 | @SafeVarargs |
256 | 256 | @CanIgnoreReturnValue |
257 | 257 | @SuppressWarnings("varargs") // required to avoid warning |
258 | | - public final MetricAssert hasDataPointsWithAttributes(Set<AttributeMatcher>... attributeSets) { |
| 258 | + public final MetricAssert hasDataPointsWithAttributes( |
| 259 | + Set<AttributeMatcher>... attributeMatchers) { |
259 | 260 | return checkDataPoints( |
260 | 261 | dataPoints -> { |
261 | 262 | dataPointsCommonCheck(dataPoints); |
262 | 263 |
|
263 | | - boolean[] matchedSets = new boolean[attributeSets.length]; |
| 264 | + boolean[] matchedSets = new boolean[attributeMatchers.length]; |
264 | 265 |
|
265 | 266 | // validate each datapoint attributes match exactly one of the provided attributes sets |
266 | 267 | for (NumberDataPoint dataPoint : dataPoints) { |
267 | | - Set<AttributeMatcher> dataPointAttributes = toSet(dataPoint.getAttributesList()); |
| 268 | + Map<String, String> dataPointAttributes = toMap(dataPoint.getAttributesList()); |
268 | 269 | int matchCount = 0; |
269 | | - for (int i = 0; i < attributeSets.length; i++) { |
270 | | - if (attributeSets[i].equals(dataPointAttributes)) { |
| 270 | + for (int i = 0; i < attributeMatchers.length; i++) { |
| 271 | + if (matchAttributes(attributeMatchers[i], dataPointAttributes)) { |
271 | 272 | matchedSets[i] = true; |
272 | 273 | matchCount++; |
273 | 274 | } |
274 | 275 | } |
275 | 276 |
|
276 | 277 | info.description( |
277 | 278 | "data point attributes '%s' for metric '%s' must match exactly one of the attribute sets '%s'", |
278 | | - dataPointAttributes, actual.getName(), Arrays.asList(attributeSets)); |
| 279 | + dataPointAttributes, actual.getName(), Arrays.asList(attributeMatchers)); |
279 | 280 | integers.assertEqual(info, matchCount, 1); |
280 | 281 | } |
281 | 282 |
|
282 | 283 | // check that all attribute sets matched at least once |
283 | 284 | for (int i = 0; i < matchedSets.length; i++) { |
284 | 285 | info.description( |
285 | 286 | "no data point matched attribute set '%s' for metric '%s'", |
286 | | - attributeSets[i], actual.getName()); |
| 287 | + attributeMatchers[i], actual.getName()); |
287 | 288 | objects.assertEqual(info, matchedSets[i], true); |
288 | 289 | } |
289 | 290 | }); |
290 | 291 | } |
291 | 292 |
|
292 | | - private static Set<AttributeMatcher> toSet(List<KeyValue> list) { |
| 293 | + private static boolean matchAttributes( |
| 294 | + Set<AttributeMatcher> attributeMatchers, Map<String, String> dataPointAttributes) { |
| 295 | + if (attributeMatchers.size() != dataPointAttributes.size()) { |
| 296 | + return false; |
| 297 | + } |
| 298 | + for (AttributeMatcher matcher : attributeMatchers) { |
| 299 | + String attributeValue = dataPointAttributes.get(matcher.getAttributeName()); |
| 300 | + if (!matcher.matchesValue(attributeValue)) { |
| 301 | + return false; |
| 302 | + } |
| 303 | + } |
| 304 | + return true; |
| 305 | + } |
| 306 | + |
| 307 | + private static Map<String, String> toMap(List<KeyValue> list) { |
293 | 308 | return list.stream() |
294 | | - .map(entry -> attribute(entry.getKey(), entry.getValue().getStringValue())) |
295 | | - .collect(Collectors.toSet()); |
| 309 | + .collect(Collectors.toMap(KeyValue::getKey, kv -> kv.getValue().getStringValue())); |
296 | 310 | } |
297 | 311 | } |
0 commit comments