Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adjustment of behaviour of hasXAttributesSatisfying and hasXAttribute… #4882

Merged
merged 5 commits into from Nov 29, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
23 changes: 22 additions & 1 deletion docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt
@@ -1,2 +1,23 @@
Comparing source compatibility of against
No changes.
*** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.assertj.AbstractPointAssert (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.AbstractPointAssert hasAttributesSatisfyingExactly(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) FINAL(+) io.opentelemetry.sdk.testing.assertj.AbstractPointAssert hasAttributesSatisfyingExactly(java.lang.Iterable)
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.DoubleExemplarAssert (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.DoubleExemplarAssert hasFilteredAttributesSatisfyingExactly(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.DoubleExemplarAssert hasFilteredAttributesSatisfyingExactly(java.lang.Iterable)
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.EventDataAssert (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.EventDataAssert hasAttributesSatisfying(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.EventDataAssert hasAttributesSatisfying(java.lang.Iterable)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.EventDataAssert hasAttributesSatisfyingExactly(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.EventDataAssert hasAttributesSatisfyingExactly(java.lang.Iterable)
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LongExemplarAssert (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LongExemplarAssert hasFilteredAttributesSatisfyingExactly(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LongExemplarAssert hasFilteredAttributesSatisfyingExactly(java.lang.Iterable)
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.SpanDataAssert (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.SpanDataAssert hasAttributesSatisfying(io.opentelemetry.sdk.testing.assertj.AttributeAssertion[])
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.SpanDataAssert hasAttributesSatisfying(java.lang.Iterable)
Expand Up @@ -15,6 +15,7 @@
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Arrays;
import java.util.Map;
import java.util.function.Consumer;
import org.assertj.core.api.AbstractAssert;
Expand Down Expand Up @@ -160,6 +161,37 @@ public LogRecordDataAssert hasAttributesSatisfying(Consumer<Attributes> attribut
return this;
}

/** Asserts the log has attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public LogRecordDataAssert hasAttributesSatisfying(AttributeAssertion... assertions) {
return hasAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the log has attributes matching all {@code assertions}. Assertions can be created using
* methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public LogRecordDataAssert hasAttributesSatisfying(Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getAttributes(), assertions);
return myself;
}

/** Asserts the log has attributes matching all {@code assertions} and no more. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public LogRecordDataAssert hasAttributesSatisfyingExactly(AttributeAssertion... assertions) {
return hasAttributesSatisfyingExactly(Arrays.asList(assertions));
}

/**
* Asserts the log has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public LogRecordDataAssert hasAttributesSatisfyingExactly(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributesExactly(actual.getAttributes(), assertions);
return myself;
}

private boolean attributesAreEqual(Attributes attributes) {
// compare as maps, since implementations do not have equals that work correctly across
// implementations.
Expand Down
Expand Up @@ -8,6 +8,7 @@
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static io.opentelemetry.sdk.testing.assertj.LogAssertions.assertThat;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

import io.opentelemetry.api.common.AttributeKey;
Expand Down Expand Up @@ -111,6 +112,18 @@ void passing() {
attributeEntry("conditions", false, true),
attributeEntry("scores", 0L, 1L),
attributeEntry("coins", 0.01, 0.05, 0.1)))
.hasAttributesSatisfying(
equalTo(AttributeKey.stringKey("bear"), "mya"),
equalTo(AttributeKey.booleanArrayKey("conditions"), Arrays.asList(false, true)))
.hasAttributesSatisfyingExactly(
equalTo(AttributeKey.stringKey("bear"), "mya"),
equalTo(AttributeKey.booleanKey("warm"), true),
equalTo(AttributeKey.longKey("temperature"), 30L),
equalTo(AttributeKey.doubleKey("length"), 1.2),
equalTo(AttributeKey.stringArrayKey("colors"), Arrays.asList("red", "blue")),
equalTo(AttributeKey.booleanArrayKey("conditions"), Arrays.asList(false, true)),
equalTo(AttributeKey.longArrayKey("scores"), Arrays.asList(0L, 1L)),
equalTo(AttributeKey.doubleArrayKey("coins"), Arrays.asList(0.01, 0.05, 0.1)))
.hasTotalAttributeCount(999);
}

Expand Down Expand Up @@ -181,6 +194,20 @@ void failure() {
AttributeKey.stringKey("bear"),
value -> assertThat(value).hasSize(2))))
.isInstanceOf(AssertionError.class);
assertThatThrownBy(
() ->
assertThat(LOG_DATA)
.hasAttributesSatisfying(equalTo(AttributeKey.stringKey("bear"), "moo")))
.isInstanceOf(AssertionError.class);
assertThatThrownBy(
() ->
assertThat(LOG_DATA)
.hasAttributesSatisfyingExactly(
equalTo(AttributeKey.stringKey("bear"), "mya"),
equalTo(AttributeKey.booleanKey("warm"), true),
equalTo(AttributeKey.longKey("temperature"), 30L),
equalTo(AttributeKey.doubleKey("length"), 1.2)))
.isInstanceOf(AssertionError.class);
assertThatThrownBy(() -> assertThat(LOG_DATA).hasTotalAttributeCount(11))
.isInstanceOf(AssertionError.class);
}
Expand Down
Expand Up @@ -93,21 +93,41 @@ public final PointAssertT hasAttributes(Map.Entry<? extends AttributeKey<?>, ?>.
}

/**
* Asserts the point has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* Asserts the point has attributes matching all {@code assertions}. Assertions can be created
* using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public final PointAssertT hasAttributesSatisfying(AttributeAssertion... assertions) {
return hasAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the point has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* Asserts the point has attributes matching all {@code assertions}. Assertions can be created
* using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public final PointAssertT hasAttributesSatisfying(Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getAttributes(), assertions);
return myself;
}

/**
* Asserts the point has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public final PointAssertT hasAttributesSatisfyingExactly(AttributeAssertion... assertions) {
return hasAttributesSatisfyingExactly(Arrays.asList(assertions));
}

/**
* Asserts the point has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public final PointAssertT hasAttributesSatisfyingExactly(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributesExactly(actual.getAttributes(), assertions);
return myself;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add coverage for the new code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I'll try to finish this one tomorrow :)

}
}
Expand Up @@ -34,6 +34,32 @@ static <T, U extends AbstractAssert<U, T>> Consumer<T>[] toConsumers(
}

static void assertAttributes(Attributes actual, Iterable<AttributeAssertion> assertions) {
assertAttributes(actual, assertions, "attribute keys");
}

static void assertAttributes(
Attributes actual, Iterable<AttributeAssertion> assertions, String name) {
Set<AttributeKey<?>> actualKeys = actual.asMap().keySet();
Set<AttributeKey<?>> checkedKeys = new HashSet<>();
for (AttributeAssertion attributeAssertion : assertions) {
AttributeKey<?> key = attributeAssertion.getKey();
Object value = actual.get(key);
if (value != null) {
checkedKeys.add(key);
}
AbstractAssert<?, ?> assertion = AttributeAssertion.attributeValueAssertion(key, value);
attributeAssertion.getAssertion().accept(assertion);
}

assertThat(actualKeys).as(name).containsAll(checkedKeys);
}

static void assertAttributesExactly(Attributes actual, Iterable<AttributeAssertion> assertions) {
mateuszrzeszutek marked this conversation as resolved.
Show resolved Hide resolved
assertAttributesExactly(actual, assertions, "attribute keys");
}

static void assertAttributesExactly(
Attributes actual, Iterable<AttributeAssertion> assertions, String name) {
Set<AttributeKey<?>> actualKeys = actual.asMap().keySet();
Set<AttributeKey<?>> checkedKeys = new HashSet<>();
for (AttributeAssertion attributeAssertion : assertions) {
Expand All @@ -46,7 +72,7 @@ static void assertAttributes(Attributes actual, Iterable<AttributeAssertion> ass
attributeAssertion.getAssertion().accept(assertion);
}

assertThat(actualKeys).as("attribute keys").containsExactlyInAnyOrderElementsOf(checkedKeys);
assertThat(actualKeys).as(name).containsExactlyInAnyOrderElementsOf(checkedKeys);
}

/**
Expand Down
Expand Up @@ -97,19 +97,36 @@ public final DoubleExemplarAssert hasFilteredAttributes(
return hasFilteredAttributes(attributes);
}

/** Asserts the exemplar has filtered attributes matching all {@code assertions} and no more. */
/** Asserts the exemplar has filtered attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public DoubleExemplarAssert hasFilteredAttributesSatisfying(AttributeAssertion... assertions) {
return hasFilteredAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the exemplar has filtered attributes matching all {@code assertions}. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public DoubleExemplarAssert hasFilteredAttributesSatisfying(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getFilteredAttributes(), assertions);
return myself;
}

/** Asserts the exemplar has filtered attributes matching all {@code assertions} and no more. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public DoubleExemplarAssert hasFilteredAttributesSatisfyingExactly(
AttributeAssertion... assertions) {
return hasFilteredAttributesSatisfyingExactly(Arrays.asList(assertions));
}

/**
* Asserts the exemplar has filtered attributes matching all {@code assertions} and no more.
* Assertions can be created using methods like {@link
* OpenTelemetryAssertions#satisfies(AttributeKey, OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public DoubleExemplarAssert hasFilteredAttributesSatisfying(
public DoubleExemplarAssert hasFilteredAttributesSatisfyingExactly(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getFilteredAttributes(), assertions);
AssertUtil.assertAttributesExactly(actual.getFilteredAttributes(), assertions);
return myself;
}
}
Expand Up @@ -7,9 +7,11 @@

import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.trace.data.EventData;
import java.time.Instant;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -82,4 +84,34 @@ public EventDataAssert hasAttributesSatisfying(Consumer<Attributes> attributes)
assertThat(actual.getAttributes()).as("attributes").satisfies(attributes);
return this;
}

/** Asserts the event has attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public EventDataAssert hasAttributesSatisfying(AttributeAssertion... assertions) {
return hasAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the event has attributes matching all {@code assertions}. Assertions can be created
* using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public EventDataAssert hasAttributesSatisfying(Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getAttributes(), assertions);
return this;
}

/** Asserts the event has attributes matching all {@code assertions} and no more. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public EventDataAssert hasAttributesSatisfyingExactly(AttributeAssertion... assertions) {
return hasAttributesSatisfyingExactly(Arrays.asList(assertions));
}

/**
* Asserts the event has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public EventDataAssert hasAttributesSatisfyingExactly(Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributesExactly(actual.getAttributes(), assertions);
return this;
}
}
Expand Up @@ -96,19 +96,36 @@ public final LongExemplarAssert hasFilteredAttributes(
return hasFilteredAttributes(attributes);
}

/** Asserts the exemplar has filtered attributes matching all {@code assertions} and no more. */
/** Asserts the exemplar has filtered attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public LongExemplarAssert hasFilteredAttributesSatisfying(AttributeAssertion... assertions) {
return hasFilteredAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the exemplar has filtered attributes matching all {@code assertions}. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public LongExemplarAssert hasFilteredAttributesSatisfying(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getFilteredAttributes(), assertions);
return myself;
}

/** Asserts the exemplar has filtered attributes matching all {@code assertions} and no more. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public LongExemplarAssert hasFilteredAttributesSatisfyingExactly(
AttributeAssertion... assertions) {
return hasFilteredAttributesSatisfying(Arrays.asList(assertions));
}

/**
* Asserts the exemplar has filtered attributes matching all {@code assertions} and no more.
* Assertions can be created using methods like {@link
* OpenTelemetryAssertions#satisfies(AttributeKey, OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public LongExemplarAssert hasFilteredAttributesSatisfying(
public LongExemplarAssert hasFilteredAttributesSatisfyingExactly(
Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(actual.getFilteredAttributes(), assertions);
AssertUtil.assertAttributesExactly(actual.getFilteredAttributes(), assertions);
return myself;
}
}
Expand Up @@ -22,7 +22,6 @@
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.time.Instant;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
Expand Down Expand Up @@ -307,7 +306,25 @@ public SpanDataAssert hasAttributesSatisfying(Consumer<Attributes> attributes) {
return this;
}

/** Asserts the span has attributes matching all {@code assertions} and no more. */
/** Asserts the span has attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public SpanDataAssert hasAttributesSatisfying(AttributeAssertion... assertions) {
return hasAttributesSatisfying(Arrays.asList(assertions));
}

/** Asserts the span has attributes matching all {@code assertions}. */
lmonkiewicz marked this conversation as resolved.
Show resolved Hide resolved
public SpanDataAssert hasAttributesSatisfying(Iterable<AttributeAssertion> assertions) {
AssertUtil.assertAttributes(
actual.getAttributes(),
assertions,
String.format("span [%s] attribute keys", actual.getName()));
return this;
}

/**
* Asserts the span has attributes matching all {@code assertions} and no more. Assertions can be
* created using methods like {@link OpenTelemetryAssertions#satisfies(AttributeKey,
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public SpanDataAssert hasAttributesSatisfyingExactly(AttributeAssertion... assertions) {
return hasAttributesSatisfyingExactly(Arrays.asList(assertions));
}
Expand All @@ -318,22 +335,10 @@ public SpanDataAssert hasAttributesSatisfyingExactly(AttributeAssertion... asser
* OpenTelemetryAssertions.LongAssertConsumer)}.
*/
public SpanDataAssert hasAttributesSatisfyingExactly(Iterable<AttributeAssertion> assertions) {
Set<AttributeKey<?>> actualKeys = actual.getAttributes().asMap().keySet();
Set<AttributeKey<?>> checkedKeys = new HashSet<>();
for (AttributeAssertion attributeAssertion : assertions) {
AttributeKey<?> key = attributeAssertion.getKey();
Object value = actual.getAttributes().get(key);
if (value != null) {
checkedKeys.add(key);
}
AbstractAssert<?, ?> assertion = AttributeAssertion.attributeValueAssertion(key, value);
attributeAssertion.getAssertion().accept(assertion);
}

assertThat(actualKeys)
.as("span [%s] attribute keys", actual.getName())
.containsExactlyInAnyOrderElementsOf(checkedKeys);

AssertUtil.assertAttributesExactly(
actual.getAttributes(),
assertions,
String.format("span [%s] attribute keys", actual.getName()));
return this;
}

Expand Down