Skip to content

Commit 2b7fe75

Browse files
authored
Add resource assertion methods to SpanDataAssert and MetricAssert (#5160)
* Fix nullable warning in AttributeAssertion * Fix warnings in assertion tests * Add missing test for MetricAssert.hasSummarySatisfying() type check failure * Add hasResourceSatisfying() method to SpanDataAssert and MetricAssert
1 parent 43c88b9 commit 2b7fe75

File tree

7 files changed

+412
-7
lines changed

7 files changed

+412
-7
lines changed

docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt

+17
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,23 @@ Comparing source compatibility of against
2929
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.MetricAssert (not serializable)
3030
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
3131
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.MetricAssert hasExponentialHistogramSatisfying(java.util.function.Consumer)
32+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.MetricAssert hasResourceSatisfying(java.util.function.Consumer)
33+
+++ NEW CLASS: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert (not serializable)
34+
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
35+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttribute(io.opentelemetry.api.common.AttributeKey, java.lang.Object)
36+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttribute(io.opentelemetry.sdk.testing.assertj.AttributeAssertion)
37+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributes(io.opentelemetry.api.common.Attributes)
38+
+++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributes(java.util.Map$Entry[])
39+
+++ NEW ANNOTATION: java.lang.SafeVarargs
40+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributesSatisfying(java.util.function.Consumer)
41+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributesSatisfying(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
42+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributesSatisfying(java.lang.Iterable)
43+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributesSatisfyingExactly(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
44+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasAttributesSatisfyingExactly(java.lang.Iterable)
45+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.ResourceAssert hasSchemaUrl(java.lang.String)
46+
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.SpanDataAssert (not serializable)
47+
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
48+
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.SpanDataAssert hasResourceSatisfying(java.util.function.Consumer)
3249
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.TracesAssert (not serializable)
3350
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
3451
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.testing.assertj.TracesAssert assertThat(java.util.List)

sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/AttributeAssertion.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ static AttributeAssertion create(
4343
}
4444

4545
private static AbstractAssert<? extends AbstractAssert<?, ?>, ?> makeAssertion(
46-
AttributeKey<?> key, Object value) {
46+
AttributeKey<?> key, @Nullable Object value) {
4747
switch (key.getType()) {
4848
case STRING:
4949
return assertThat((String) value);

sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/MetricAssert.java

+12
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,18 @@ public MetricAssert hasResource(Resource resource) {
3737
return this;
3838
}
3939

40+
/**
41+
* Asserts the metric has a resource satisfying the given condition.
42+
*
43+
* @since 1.23.0
44+
*/
45+
public MetricAssert hasResourceSatisfying(Consumer<ResourceAssert> resource) {
46+
isNotNull();
47+
resource.accept(
48+
new ResourceAssert(actual.getResource(), String.format("metric [%s]", actual.getName())));
49+
return this;
50+
}
51+
4052
/** Asserts the metric has the given the {@link InstrumentationScopeInfo}. */
4153
public MetricAssert hasInstrumentationScope(InstrumentationScopeInfo instrumentationScopeInfo) {
4254
isNotNull();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.testing.assertj;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import io.opentelemetry.api.common.AttributeKey;
11+
import io.opentelemetry.api.common.Attributes;
12+
import io.opentelemetry.api.common.AttributesBuilder;
13+
import io.opentelemetry.sdk.resources.Resource;
14+
import java.util.Arrays;
15+
import java.util.Map;
16+
import java.util.Set;
17+
import java.util.function.Consumer;
18+
import javax.annotation.Nullable;
19+
import org.assertj.core.api.AbstractAssert;
20+
21+
/**
22+
* Assertions for {@link Resource}.
23+
*
24+
* @since 1.23.0
25+
*/
26+
public final class ResourceAssert extends AbstractAssert<ResourceAssert, Resource> {
27+
28+
private final String label;
29+
30+
ResourceAssert(Resource resource, String label) {
31+
super(resource, ResourceAssert.class);
32+
this.label = label;
33+
}
34+
35+
/** Asserts the resource has a schemaUrl satisfying the given condition. */
36+
// Workaround "passing @Nullable parameter 'schemaUrl' where @NonNull is required", Nullaway
37+
// seems to think assertThat is supposed to be passed NonNull even though we know that can't be
38+
// true for assertions.
39+
@SuppressWarnings("NullAway")
40+
public ResourceAssert hasSchemaUrl(@Nullable String schemaUrl) {
41+
isNotNull();
42+
assertThat(actual.getSchemaUrl()).as("resource schema URL of %s", label).isEqualTo(schemaUrl);
43+
return this;
44+
}
45+
46+
/** Asserts the resource has the given attribute. */
47+
public <T> ResourceAssert hasAttribute(AttributeKey<T> key, T value) {
48+
return hasAttribute(OpenTelemetryAssertions.equalTo(key, value));
49+
}
50+
51+
/** Asserts the resource has an attribute matching the {@code attributeAssertion}. */
52+
public ResourceAssert hasAttribute(AttributeAssertion attributeAssertion) {
53+
isNotNull();
54+
55+
Set<AttributeKey<?>> actualKeys = actual.getAttributes().asMap().keySet();
56+
AttributeKey<?> key = attributeAssertion.getKey();
57+
58+
assertThat(actualKeys).as("resource attribute keys of %s", label).contains(key);
59+
60+
Object value = actual.getAttributes().get(key);
61+
AbstractAssert<?, ?> assertion = AttributeAssertion.attributeValueAssertion(key, value);
62+
attributeAssertion.getAssertion().accept(assertion);
63+
64+
return this;
65+
}
66+
67+
/** Asserts the resource has the given attributes. */
68+
public ResourceAssert hasAttributes(Attributes attributes) {
69+
isNotNull();
70+
if (!AssertUtil.attributesAreEqual(actual.getAttributes(), attributes)) {
71+
failWithActualExpectedAndMessage(
72+
actual.getAttributes(),
73+
attributes,
74+
"Expected resource of <%s> to have attributes <%s> but was <%s>",
75+
label,
76+
attributes,
77+
actual.getAttributes());
78+
}
79+
return this;
80+
}
81+
82+
/** Asserts the resource has the given attributes. */
83+
@SuppressWarnings({"rawtypes", "unchecked"})
84+
@SafeVarargs
85+
public final ResourceAssert hasAttributes(Map.Entry<? extends AttributeKey<?>, ?>... entries) {
86+
AttributesBuilder attributesBuilder = Attributes.builder();
87+
for (Map.Entry<? extends AttributeKey<?>, ?> attr : entries) {
88+
attributesBuilder.put((AttributeKey) attr.getKey(), attr.getValue());
89+
}
90+
Attributes attributes = attributesBuilder.build();
91+
return hasAttributes(attributes);
92+
}
93+
94+
/** Asserts the resource has attributes satisfying the given condition. */
95+
public ResourceAssert hasAttributesSatisfying(Consumer<Attributes> attributes) {
96+
isNotNull();
97+
OpenTelemetryAssertions.assertThat(actual.getAttributes())
98+
.as("resource attributes of %s", label)
99+
.satisfies(attributes);
100+
return this;
101+
}
102+
103+
/**
104+
* Asserts the event has attributes matching all {@code assertions}. Assertions can be created
105+
* using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
106+
* OpenTelemetryAssertions.LongAssertConsumer)}.
107+
*/
108+
public ResourceAssert hasAttributesSatisfying(AttributeAssertion... assertions) {
109+
return hasAttributesSatisfying(Arrays.asList(assertions));
110+
}
111+
112+
/**
113+
* Asserts the event has attributes matching all {@code assertions}. Assertions can be created
114+
* using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
115+
* OpenTelemetryAssertions.LongAssertConsumer)}.
116+
*/
117+
public ResourceAssert hasAttributesSatisfying(Iterable<AttributeAssertion> assertions) {
118+
AssertUtil.assertAttributes(
119+
actual.getAttributes(), assertions, String.format("resource of %s attribute keys", label));
120+
return this;
121+
}
122+
123+
/**
124+
* Asserts the resource has attributes matching all {@code assertions} and no more. Assertions can
125+
* be created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
126+
* OpenTelemetryAssertions.LongAssertConsumer)}.
127+
*/
128+
public ResourceAssert hasAttributesSatisfyingExactly(AttributeAssertion... assertions) {
129+
return hasAttributesSatisfyingExactly(Arrays.asList(assertions));
130+
}
131+
132+
/**
133+
* Asserts the resource has attributes matching all {@code assertions} and no more. Assertions can
134+
* be created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
135+
* OpenTelemetryAssertions.LongAssertConsumer)}.
136+
*/
137+
public ResourceAssert hasAttributesSatisfyingExactly(Iterable<AttributeAssertion> assertions) {
138+
AssertUtil.assertAttributesExactly(
139+
actual.getAttributes(), assertions, String.format("resource of %s attribute keys", label));
140+
return this;
141+
}
142+
}

sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/SpanDataAssert.java

+12
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,18 @@ public SpanDataAssert hasResource(Resource resource) {
159159
return this;
160160
}
161161

162+
/**
163+
* Asserts the span has a resource satisfying the given condition.
164+
*
165+
* @since 1.23.0
166+
*/
167+
public SpanDataAssert hasResourceSatisfying(Consumer<ResourceAssert> resource) {
168+
isNotNull();
169+
resource.accept(
170+
new ResourceAssert(actual.getResource(), String.format("span [%s]", actual.getName())));
171+
return this;
172+
}
173+
162174
/**
163175
* Asserts the span has the given {@link io.opentelemetry.sdk.common.InstrumentationLibraryInfo}.
164176
*

0 commit comments

Comments
 (0)