Skip to content

Commit dfe3af3

Browse files
authored
Merge pull request #6 from SylvainJuge/assertions-refactoring
Assertions refactoring
2 parents 6431feb + 5e69a82 commit dfe3af3

File tree

8 files changed

+126
-113
lines changed

8 files changed

+126
-113
lines changed

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/assertions/AttributeMatcher.java

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package io.opentelemetry.contrib.jmxscraper.assertions;
77

8-
import java.util.Objects;
98
import javax.annotation.Nullable;
109

1110
/** Implements functionality of matching data point attributes. */
@@ -42,25 +41,6 @@ public String getAttributeName() {
4241
return attributeName;
4342
}
4443

45-
@Override
46-
public boolean equals(Object o) {
47-
if (this == o) {
48-
return true;
49-
}
50-
if (!(o instanceof AttributeMatcher)) {
51-
return false;
52-
}
53-
AttributeMatcher other = (AttributeMatcher) o;
54-
// Do not attributeValue into account so AttributeMatcher instances can be stored in collections
55-
// with guarantee of uniqueness per attribute
56-
return Objects.equals(attributeName, other.attributeName);
57-
}
58-
59-
@Override
60-
public int hashCode() {
61-
return Objects.hash(attributeName);
62-
}
63-
6444
@Override
6545
public String toString() {
6646
return attributeValue == null
@@ -76,6 +56,6 @@ public String toString() {
7656
* @return true if this matcher is matching provided value, false otherwise.
7757
*/
7858
boolean matchesValue(String value) {
79-
return (attributeValue == null) || Objects.equals(attributeValue, value);
59+
return attributeValue == null || attributeValue.equals(value);
8060
}
8161
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.jmxscraper.assertions;
7+
8+
import java.util.Collection;
9+
import java.util.Map;
10+
import java.util.stream.Collectors;
11+
12+
/** Group of attribute matchers */
13+
public class AttributeMatcherGroup {
14+
15+
// stored as a Map for easy lookup by name
16+
private final Map<String, AttributeMatcher> matchers;
17+
18+
/**
19+
* Constructor for a set of attribute matchers
20+
*
21+
* @param matchers collection of matchers to build a group from
22+
* @throws IllegalStateException if there is any duplicate key
23+
*/
24+
AttributeMatcherGroup(Collection<AttributeMatcher> matchers) {
25+
this.matchers =
26+
matchers.stream().collect(Collectors.toMap(AttributeMatcher::getAttributeName, m -> m));
27+
}
28+
29+
/**
30+
* Checks if attributes match this attribute matcher group
31+
*
32+
* @param attributes attributes to check as map
33+
* @return {@literal true} when the attributes match all attributes from this group
34+
*/
35+
public boolean matches(Map<String, String> attributes) {
36+
if (attributes.size() != matchers.size()) {
37+
return false;
38+
}
39+
40+
for (Map.Entry<String, String> entry : attributes.entrySet()) {
41+
AttributeMatcher matcher = matchers.get(entry.getKey());
42+
if (matcher == null) {
43+
// no matcher for this key: unexpected key
44+
return false;
45+
}
46+
47+
if (!matcher.matchesValue(entry.getValue())) {
48+
// value does not match: unexpected value
49+
return false;
50+
}
51+
}
52+
53+
return true;
54+
}
55+
56+
@Override
57+
public String toString() {
58+
return matchers.values().toString();
59+
}
60+
}

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/assertions/DataPointAttributes.java

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
package io.opentelemetry.contrib.jmxscraper.assertions;
77

88
import java.util.Arrays;
9-
import java.util.Set;
10-
import java.util.stream.Collectors;
119

1210
/**
1311
* Utility class implementing convenience static methods to construct data point attribute matchers
@@ -40,21 +38,16 @@ public static AttributeMatcher attributeWithAnyValue(String name) {
4038
}
4139

4240
/**
43-
* Create a set of attribute matchers that should be used to verify set of data point attributes.
41+
* Creates a group of attribute matchers that should be used to verify data point attributes.
4442
*
45-
* @param attributes list of matchers to create set. It must contain matchers with unique names.
46-
* @return set of unique attribute matchers
43+
* @param attributes list of matchers to create group. It must contain matchers with unique names.
44+
* @return group of attribute matchers
4745
* @throws IllegalArgumentException if provided list contains two or more matchers with the same
48-
* name.
49-
* @see MetricAssert#hasDataPointsWithAttributes(Set[]) for detailed description of the algorithm
50-
* used for matching
46+
* attribute name
47+
* @see MetricAssert#hasDataPointsWithAttributes(AttributeMatcherGroup...) for detailed
48+
* description off the algorithm used for matching
5149
*/
52-
public static Set<AttributeMatcher> attributeSet(AttributeMatcher... attributes) {
53-
Set<AttributeMatcher> matcherSet = Arrays.stream(attributes).collect(Collectors.toSet());
54-
if (matcherSet.size() < attributes.length) {
55-
throw new IllegalArgumentException(
56-
"Duplicated matchers found in " + Arrays.toString(attributes));
57-
}
58-
return matcherSet;
50+
public static AttributeMatcherGroup attributeGroup(AttributeMatcher... attributes) {
51+
return new AttributeMatcherGroup(Arrays.asList(attributes));
5952
}
6053
}

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/assertions/MetricAssert.java

Lines changed: 18 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
package io.opentelemetry.contrib.jmxscraper.assertions;
77

8-
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeSet;
8+
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeGroup;
99

1010
import com.google.errorprone.annotations.CanIgnoreReturnValue;
1111
import io.opentelemetry.proto.common.v1.KeyValue;
@@ -241,73 +241,54 @@ private void dataPointsCommonCheck(List<NumberDataPoint> dataPoints) {
241241
*/
242242
@CanIgnoreReturnValue
243243
public final MetricAssert hasDataPointsWithOneAttribute(AttributeMatcher expectedAttribute) {
244-
return hasDataPointsWithAttributes(attributeSet(expectedAttribute));
244+
return hasDataPointsWithAttributes(attributeGroup(expectedAttribute));
245245
}
246246

247247
/**
248-
* Verifies that every data point attributes set is matched exactly by one of the matcher sets
249-
* provided. Also, each matcher set must match at least one data point attributes set. Data point
250-
* attributes set is matched by matcher set if each attribute is matched by one matcher and each
251-
* matcher matches one attribute. In other words: number of attributes is the same as number of
252-
* matchers and there is 1:1 matching between them.
248+
* Verifies that every data point attributes is matched exactly by one of the matcher groups
249+
* provided. Also, each matcher group must match at least one data point attributes set. Data
250+
* point attributes are matched by matcher group if each attribute is matched by one matcher and
251+
* each matcher matches one attribute. In other words: number of attributes is the same as number
252+
* of matchers and there is 1:1 matching between them.
253253
*
254-
* @param attributeMatchers array of attribute matcher sets
254+
* @param matcherGroups array of attribute matcher groups
255255
* @return this
256256
*/
257-
@SafeVarargs
258257
@CanIgnoreReturnValue
259-
@SuppressWarnings("varargs") // required to avoid warning
260-
public final MetricAssert hasDataPointsWithAttributes(
261-
Set<AttributeMatcher>... attributeMatchers) {
258+
public final MetricAssert hasDataPointsWithAttributes(AttributeMatcherGroup... matcherGroups) {
262259
return checkDataPoints(
263260
dataPoints -> {
264261
dataPointsCommonCheck(dataPoints);
265262

266-
boolean[] matchedSets = new boolean[attributeMatchers.length];
263+
boolean[] matchedSets = new boolean[matcherGroups.length];
267264

268265
// validate each datapoint attributes match exactly one of the provided attributes sets
269266
for (NumberDataPoint dataPoint : dataPoints) {
270-
Map<String, String> dataPointAttributes = toMap(dataPoint.getAttributesList());
267+
Map<String, String> dataPointAttributes =
268+
dataPoint.getAttributesList().stream()
269+
.collect(
270+
Collectors.toMap(KeyValue::getKey, kv -> kv.getValue().getStringValue()));
271271
int matchCount = 0;
272-
for (int i = 0; i < attributeMatchers.length; i++) {
273-
if (matchAttributes(attributeMatchers[i], dataPointAttributes)) {
272+
for (int i = 0; i < matcherGroups.length; i++) {
273+
if (matcherGroups[i].matches(dataPointAttributes)) {
274274
matchedSets[i] = true;
275275
matchCount++;
276276
}
277277
}
278278

279279
info.description(
280280
"data point attributes '%s' for metric '%s' must match exactly one of the attribute sets '%s'",
281-
dataPointAttributes, actual.getName(), Arrays.asList(attributeMatchers));
281+
dataPointAttributes, actual.getName(), Arrays.asList(matcherGroups));
282282
integers.assertEqual(info, matchCount, 1);
283283
}
284284

285285
// check that all attribute sets matched at least once
286286
for (int i = 0; i < matchedSets.length; i++) {
287287
info.description(
288288
"no data point matched attribute set '%s' for metric '%s'",
289-
attributeMatchers[i], actual.getName());
289+
matcherGroups[i], actual.getName());
290290
objects.assertEqual(info, matchedSets[i], true);
291291
}
292292
});
293293
}
294-
295-
private static boolean matchAttributes(
296-
Set<AttributeMatcher> attributeMatchers, Map<String, String> dataPointAttributes) {
297-
if (attributeMatchers.size() != dataPointAttributes.size()) {
298-
return false;
299-
}
300-
for (AttributeMatcher matcher : attributeMatchers) {
301-
String attributeValue = dataPointAttributes.get(matcher.getAttributeName());
302-
if (!matcher.matchesValue(attributeValue)) {
303-
return false;
304-
}
305-
}
306-
return true;
307-
}
308-
309-
private static Map<String, String> toMap(List<KeyValue> list) {
310-
return list.stream()
311-
.collect(Collectors.toMap(KeyValue::getKey, kv -> kv.getValue().getStringValue()));
312-
}
313294
}

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/ActiveMqIntegrationTest.java

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
package io.opentelemetry.contrib.jmxscraper.target_systems;
77

88
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attribute;
9-
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeSet;
9+
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeGroup;
1010

1111
import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer;
1212
import java.nio.file.Path;
@@ -48,7 +48,7 @@ protected MetricsVerifier createMetricsVerifier() {
4848
.hasUnit("{consumer}")
4949
.isUpDownCounter()
5050
.hasDataPointsWithAttributes(
51-
attributeSet(
51+
attributeGroup(
5252
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
5353
attribute("broker", "localhost"))))
5454
.add(
@@ -59,7 +59,7 @@ protected MetricsVerifier createMetricsVerifier() {
5959
.hasUnit("{producer}")
6060
.isUpDownCounter()
6161
.hasDataPointsWithAttributes(
62-
attributeSet(
62+
attributeGroup(
6363
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
6464
attribute("broker", "localhost"))))
6565
.add(
@@ -78,7 +78,7 @@ protected MetricsVerifier createMetricsVerifier() {
7878
.hasUnit("%")
7979
.isGauge()
8080
.hasDataPointsWithAttributes(
81-
attributeSet(
81+
attributeGroup(
8282
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
8383
attribute("broker", "localhost"))))
8484
.add(
@@ -107,7 +107,7 @@ protected MetricsVerifier createMetricsVerifier() {
107107
.hasUnit("{message}")
108108
.isUpDownCounter()
109109
.hasDataPointsWithAttributes(
110-
attributeSet(
110+
attributeGroup(
111111
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
112112
attribute("broker", "localhost"))))
113113
.add(
@@ -119,7 +119,7 @@ protected MetricsVerifier createMetricsVerifier() {
119119
.hasUnit("{message}")
120120
.isCounter()
121121
.hasDataPointsWithAttributes(
122-
attributeSet(
122+
attributeGroup(
123123
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
124124
attribute("broker", "localhost"))))
125125
.add(
@@ -130,7 +130,7 @@ protected MetricsVerifier createMetricsVerifier() {
130130
.hasUnit("{message}")
131131
.isCounter()
132132
.hasDataPointsWithAttributes(
133-
attributeSet(
133+
attributeGroup(
134134
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
135135
attribute("broker", "localhost"))))
136136
.add(
@@ -141,7 +141,7 @@ protected MetricsVerifier createMetricsVerifier() {
141141
.hasUnit("{message}")
142142
.isCounter()
143143
.hasDataPointsWithAttributes(
144-
attributeSet(
144+
attributeGroup(
145145
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
146146
attribute("broker", "localhost"))))
147147
.add(
@@ -152,7 +152,7 @@ protected MetricsVerifier createMetricsVerifier() {
152152
.hasUnit("ms")
153153
.isGauge()
154154
.hasDataPointsWithAttributes(
155-
attributeSet(
155+
attributeGroup(
156156
attribute("destination", "ActiveMQ.Advisory.MasterBroker"),
157157
attribute("broker", "localhost"))));
158158
}

jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/target_systems/CassandraIntegrationTest.java

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,12 @@
66
package io.opentelemetry.contrib.jmxscraper.target_systems;
77

88
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attribute;
9-
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeSet;
9+
import static io.opentelemetry.contrib.jmxscraper.assertions.DataPointAttributes.attributeGroup;
1010

1111
import io.opentelemetry.contrib.jmxscraper.JmxScraperContainer;
12-
import io.opentelemetry.contrib.jmxscraper.assertions.AttributeMatcher;
12+
import io.opentelemetry.contrib.jmxscraper.assertions.AttributeMatcherGroup;
1313
import java.nio.file.Path;
1414
import java.time.Duration;
15-
import java.util.Set;
1615
import org.testcontainers.containers.GenericContainer;
1716
import org.testcontainers.containers.wait.strategy.Wait;
1817

@@ -162,9 +161,9 @@ protected MetricsVerifier createMetricsVerifier() {
162161
.hasUnit("1")
163162
.isCounter()
164163
.hasDataPointsWithAttributes(
165-
attributeSet(attribute("operation", "RangeSlice")),
166-
attributeSet(attribute("operation", "Read")),
167-
attributeSet(attribute("operation", "Write"))))
164+
attributeGroup(attribute("operation", "RangeSlice")),
165+
attributeGroup(attribute("operation", "Read")),
166+
attributeGroup(attribute("operation", "Write"))))
168167
.add(
169168
"cassandra.client.request.error.count",
170169
metric ->
@@ -184,7 +183,7 @@ protected MetricsVerifier createMetricsVerifier() {
184183
errorCountAttributes("Write", "Unavailable")));
185184
}
186185

187-
private static Set<AttributeMatcher> errorCountAttributes(String operation, String status) {
188-
return attributeSet(attribute("operation", operation), attribute("status", status));
186+
private static AttributeMatcherGroup errorCountAttributes(String operation, String status) {
187+
return attributeGroup(attribute("operation", operation), attribute("status", status));
189188
}
190189
}

0 commit comments

Comments
 (0)