55
66package io .opentelemetry .contrib .jmxscraper .assertions ;
77
8+ import static io .opentelemetry .contrib .jmxscraper .assertions .DataPointAttributes .attribute ;
9+
810import com .google .errorprone .annotations .CanIgnoreReturnValue ;
911import io .opentelemetry .proto .common .v1 .KeyValue ;
1012import io .opentelemetry .proto .metrics .v1 .Metric ;
1113import io .opentelemetry .proto .metrics .v1 .NumberDataPoint ;
1214import java .util .Arrays ;
1315import java .util .Collection ;
14- import java .util .HashMap ;
16+ import java .util .Collections ;
1517import java .util .HashSet ;
1618import java .util .List ;
17- import java .util .Map ;
1819import java .util .Set ;
1920import java .util .function .Consumer ;
2021import java .util .stream .Collectors ;
2122import org .assertj .core .api .AbstractAssert ;
2223import org .assertj .core .internal .Integers ;
2324import org .assertj .core .internal .Iterables ;
24- import org .assertj .core .internal .Maps ;
2525import org .assertj .core .internal .Objects ;
2626
2727public class MetricAssert extends AbstractAssert <MetricAssert , Metric > {
2828
2929 private static final Objects objects = Objects .instance ();
3030 private static final Iterables iterables = Iterables .instance ();
3131 private static final Integers integers = Integers .instance ();
32- private static final Maps maps = Maps .instance ();
3332
3433 private boolean strict ;
3534
@@ -59,7 +58,7 @@ private void strictCheck(
5958 if (!strict ) {
6059 return ;
6160 }
62- String failMsgPrefix = expectedCheckStatus ? "duplicate " : "missing " ;
61+ String failMsgPrefix = expectedCheckStatus ? "Missing " : "Duplicate " ;
6362 info .description (
6463 "%s assertion on %s for metric '%s'" , failMsgPrefix , metricProperty , actual .getName ());
6564 objects .assertEqual (info , actualCheckStatus , expectedCheckStatus );
@@ -122,8 +121,8 @@ private MetricAssert hasSum(boolean monotonic) {
122121 info .description ("sum expected for metric '%s'" , actual .getName ());
123122 objects .assertEqual (info , actual .hasSum (), true );
124123
125- String prefix = monotonic ? "monotonic" : "non-monotonic" ;
126- info .description (prefix + " sum expected for metric '%s'" , actual .getName ());
124+ String sumType = monotonic ? "monotonic" : "non-monotonic" ;
125+ info .description (" sum for metric '%s' is expected to be %s " , actual .getName (), sumType );
127126 objects .assertEqual (info , actual .getSum ().getIsMonotonic (), monotonic );
128127 return this ;
129128 }
@@ -156,6 +155,11 @@ public MetricAssert isUpDownCounter() {
156155 return this ;
157156 }
158157
158+ /**
159+ * Verifies that there is no attribute in any of data points.
160+ *
161+ * @return this
162+ */
159163 @ CanIgnoreReturnValue
160164 public MetricAssert hasDataPointsWithoutAttributes () {
161165 isNotNull ();
@@ -195,6 +199,7 @@ private MetricAssert checkDataPoints(Consumer<List<NumberDataPoint>> listConsume
195199 return this ;
196200 }
197201
202+ // TODO: To be removed and calls will be replaced with hasDataPointsWithAttributes()
198203 @ CanIgnoreReturnValue
199204 public MetricAssert hasTypedDataPoints (Collection <String > types ) {
200205 return checkDataPoints (
@@ -229,66 +234,48 @@ private void dataPointsCommonCheck(List<NumberDataPoint> dataPoints) {
229234 }
230235
231236 /**
232- * Verifies that all data points have all the expected attributes
237+ * Verifies that all data points have the same expected one attribute
233238 *
234- * @param attributes expected attributes
239+ * @param expectedAttribute expected attribute
235240 * @return this
236241 */
237- @ SafeVarargs
238242 @ CanIgnoreReturnValue
239- public final MetricAssert hasDataPointsAttributes (Map .Entry <String , String >... attributes ) {
240- return checkDataPoints (
241- dataPoints -> {
242- dataPointsCommonCheck (dataPoints );
243-
244- Map <String , String > attributesMap = new HashMap <>();
245- for (Map .Entry <String , String > attributeEntry : attributes ) {
246- attributesMap .put (attributeEntry .getKey (), attributeEntry .getValue ());
247- }
248- for (NumberDataPoint dataPoint : dataPoints ) {
249- Map <String , String > dataPointAttributes = toMap (dataPoint .getAttributesList ());
250-
251- // all attributes must match
252- info .description (
253- "missing/unexpected data points attributes for metric '%s'" , actual .getName ());
254- containsExactly (dataPointAttributes , attributes );
255- maps .assertContainsAllEntriesOf (info , dataPointAttributes , attributesMap );
256- }
257- });
243+ public final MetricAssert hasDataPointsWithOneAttribute (AttributeMatcher expectedAttribute ) {
244+ return hasDataPointsWithAttributes (Collections .singleton (expectedAttribute ));
258245 }
259246
260247 /**
261- * Verifies that all data points have their attributes match one of the attributes set and that
262- * all provided attributes sets matched at least once.
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
263251 *
264- * @param attributeSets sets of attributes as maps
252+ * @param attributeSets array of attribute matcher sets
265253 * @return this
266254 */
267255 @ SafeVarargs
268256 @ CanIgnoreReturnValue
269257 @ SuppressWarnings ("varargs" ) // required to avoid warning
270- public final MetricAssert hasDataPointsAttributes ( Map < String , String >... attributeSets ) {
258+ public final MetricAssert hasDataPointsWithAttributes ( Set < AttributeMatcher >... attributeSets ) {
271259 return checkDataPoints (
272260 dataPoints -> {
273261 dataPointsCommonCheck (dataPoints );
274262
275263 boolean [] matchedSets = new boolean [attributeSets .length ];
276264
277- // validate each datapoint attributes match exactly one of the provided attributes set
265+ // validate each datapoint attributes match exactly one of the provided attributes sets
278266 for (NumberDataPoint dataPoint : dataPoints ) {
279- Map <String , String > map = toMap (dataPoint .getAttributesList ());
280-
267+ Set <AttributeMatcher > dataPointAttributes = toSet (dataPoint .getAttributesList ());
281268 int matchCount = 0 ;
282269 for (int i = 0 ; i < attributeSets .length ; i ++) {
283- if (mapEquals ( map , attributeSets [i ])) {
270+ if (attributeSets [i ]. equals ( dataPointAttributes )) {
284271 matchedSets [i ] = true ;
285272 matchCount ++;
286273 }
287274 }
288275
289276 info .description (
290277 "data point attributes '%s' for metric '%s' must match exactly one of the attribute sets '%s'" ,
291- map , actual .getName (), Arrays .asList (attributeSets ));
278+ dataPointAttributes , actual .getName (), Arrays .asList (attributeSets ));
292279 integers .assertEqual (info , matchCount , 1 );
293280 }
294281
@@ -302,29 +289,9 @@ public final MetricAssert hasDataPointsAttributes(Map<String, String>... attribu
302289 });
303290 }
304291
305- /**
306- * Map equality utility
307- *
308- * @param m1 first map
309- * @param m2 second map
310- * @return true if the maps have exactly the same keys and values
311- */
312- private static boolean mapEquals (Map <String , String > m1 , Map <String , String > m2 ) {
313- if (m1 .size () != m2 .size ()) {
314- return false ;
315- }
316- return m1 .entrySet ().stream ().allMatch (e -> e .getValue ().equals (m2 .get (e .getKey ())));
317- }
318-
319- @ SafeVarargs
320- @ SuppressWarnings ("varargs" ) // required to avoid warning
321- private final void containsExactly (
322- Map <String , String > map , Map .Entry <String , String >... entries ) {
323- maps .assertContainsExactly (info , map , entries );
324- }
325-
326- private static Map <String , String > toMap (List <KeyValue > list ) {
292+ private static Set <AttributeMatcher > toSet (List <KeyValue > list ) {
327293 return list .stream ()
328- .collect (Collectors .toMap (KeyValue ::getKey , kv -> kv .getValue ().getStringValue ()));
294+ .map (entry -> attribute (entry .getKey (), entry .getValue ().getStringValue ()))
295+ .collect (Collectors .toSet ());
329296 }
330297}
0 commit comments