From 1430657692c98db1ecf288eabc5a628b5412f1ad Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 3 Sep 2024 13:48:35 -0700 Subject: [PATCH 1/7] rebasing --- sdk/testing/build.gradle.kts | 1 + .../testing/assertj/LogRecordDataAssert.java | 103 ++++++++++++++++++ .../testing/assertj/LogAssertionsTest.java | 41 +++++++ 3 files changed, 145 insertions(+) diff --git a/sdk/testing/build.gradle.kts b/sdk/testing/build.gradle.kts index a9f2534aafd..4d3f3aa4ec8 100644 --- a/sdk/testing/build.gradle.kts +++ b/sdk/testing/build.gradle.kts @@ -8,6 +8,7 @@ otelJava.moduleName.set("io.opentelemetry.sdk.testing") dependencies { api(project(":api:all")) + api(project(":api:incubator")) api(project(":sdk:all")) compileOnly("org.assertj:assertj-core") diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index 11031aa9ef4..a2714183379 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -6,17 +6,22 @@ package io.opentelemetry.sdk.testing.assertj; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import static java.util.stream.Collectors.toList; +import static org.junit.Assert.assertNotNull; import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.resources.Resource; +import java.util.ArrayList; import java.util.Arrays; +import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Consumer; @@ -167,6 +172,104 @@ public LogRecordDataAssert hasBody(@Nullable Value body) { return this; } + // @SuppressWarnings({"MethodCanBeStatic"}) + // private void bodyIsAnyValue() { + // // Actually, we can't do these two checks because the body is still STRING type + // assertThat(actual.getBodyValue().getType()).isNotSameAs(ValueType.EMPTY); + // assertThat(actual.getBodyValue().getType()).isNotSameAs(ValueType.STRING); + // // TODO: breedx-splk simplify this when ANY_VALUE is promoted with stability + // } + + public LogRecordDataAssert hasBodyField(String key, String value) { + return hasBodyField(key, Value.of(value)); + } + + public LogRecordDataAssert hasBodyField(String key, long value) { + return hasBodyField(key, Value.of(value)); + } + + public LogRecordDataAssert hasBodyField(String key, double value) { + return hasBodyField(key, Value.of(value)); + } + + public LogRecordDataAssert hasBodyField(String key, boolean value) { + return hasBodyField(key, Value.of(value)); + } + + public LogRecordDataAssert hasBodyField(String key, String... value) { + List> values = new ArrayList<>(value.length); + for (String val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + public LogRecordDataAssert hasBodyField(String key, long... value) { + List> values = new ArrayList<>(value.length); + for (long val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + public LogRecordDataAssert hasBodyField(String key, double... value) { + List> values = new ArrayList<>(value.length); + for (double val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + public LogRecordDataAssert hasBodyField(String key, boolean... value) { + List> values = new ArrayList<>(value.length); + for (boolean val : value) { + values.add(Value.of(val)); + } + return hasBodyField(key, Value.of(values)); + } + + @SuppressWarnings({"unchecked"}) + public LogRecordDataAssert hasBodyField(String key, Value value) { + isNotNull(); + Value bodyValue = actual.getBodyValue(); + assertNotNull(bodyValue); // Can't use assertj or nullaway complains + Value> body = (Value>) bodyValue; + List payload = body.getValue(); + KeyValue expected = KeyValue.of(key, value); + assertThat(payload).contains(expected); + return this; + } + + @SuppressWarnings({"unchecked"}) + public LogRecordDataAssert hasBodyField(AttributeKey key, T value) { + switch (key.getType()) { + case STRING: + return hasBodyField(key.getKey(), (String) value); + case BOOLEAN: + return hasBodyField(key.getKey(), (boolean) value); + case LONG: + return hasBodyField(key.getKey(), (long) value); + case DOUBLE: + return hasBodyField(key.getKey(), (double) value); + case STRING_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case BOOLEAN_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case LONG_ARRAY: + return hasBodyField( + key.getKey(), Value.of(((List) value).stream().map(Value::of).collect(toList()))); + case DOUBLE_ARRAY: + return hasBodyField( + key.getKey(), + Value.of(((List) value).stream().map(Value::of).collect(toList()))); + } + return this; + } + /** Asserts the log has the given attributes. */ public LogRecordDataAssert hasAttributes(Attributes attributes) { isNotNull(); diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java index 15da07a5214..2f589ac8ca5 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -13,15 +13,22 @@ import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.incubator.events.EventLogger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.api.trace.TraceFlags; import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; +import io.opentelemetry.sdk.logs.SdkLoggerProvider; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter; import io.opentelemetry.sdk.testing.logs.TestLogRecordData; import java.util.Arrays; +import java.util.List; import java.util.concurrent.TimeUnit; import org.junit.jupiter.api.Test; @@ -276,4 +283,38 @@ void failure() { assertThatThrownBy(() -> assertThat(LOG_DATA).hasTotalAttributeCount(11)) .isInstanceOf(AssertionError.class); } + + @Test + void eventBodyAssertions() { + InMemoryLogRecordExporter exporter = InMemoryLogRecordExporter.create(); + SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .addLogRecordProcessor(SimpleLogRecordProcessor.create(exporter)) + .build(); + EventLogger eventLogger = SdkEventLoggerProvider.create(loggerProvider).get("test.test"); + eventLogger + .builder("foo") + .put("foostr", "bar") + .put("foobool", true) + .put("foolong", 12) + .put("foodbl", 12.0) + .put("foostra", "bar", "baz", "buzz") + .put("foolonga", 9, 0, 2, 1, 0) + .put("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) + .put("fooboola", true, true, true, false) + .put("fooany", Value.of("grim")) + .emit(); + List logs = exporter.getFinishedLogRecordItems(); + assertThat(logs).hasSize(1); + assertThat(logs.get(0)) + .hasBodyField("foostr", "bar") + .hasBodyField("foobool", true) + .hasBodyField("foolong", 12) + .hasBodyField("foodbl", 12.0) + .hasBodyField("foostra", "bar", "baz", "buzz") + .hasBodyField("foolonga", 9, 0, 2, 1, 0) + .hasBodyField("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) + .hasBodyField("fooboola", true, true, true, false) + .hasBodyField("fooany", Value.of("grim")); + } } From 2d1ccb03ab1ab131fa163f5b93a2b7cde62d59c6 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Mon, 17 Jun 2024 10:57:47 -0700 Subject: [PATCH 2/7] remove AnyValue from public api --- .../sdk/testing/assertj/LogRecordDataAssert.java | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index a2714183379..335e7df23dc 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -172,14 +172,6 @@ public LogRecordDataAssert hasBody(@Nullable Value body) { return this; } - // @SuppressWarnings({"MethodCanBeStatic"}) - // private void bodyIsAnyValue() { - // // Actually, we can't do these two checks because the body is still STRING type - // assertThat(actual.getBodyValue().getType()).isNotSameAs(ValueType.EMPTY); - // assertThat(actual.getBodyValue().getType()).isNotSameAs(ValueType.STRING); - // // TODO: breedx-splk simplify this when ANY_VALUE is promoted with stability - // } - public LogRecordDataAssert hasBodyField(String key, String value) { return hasBodyField(key, Value.of(value)); } @@ -228,8 +220,9 @@ public LogRecordDataAssert hasBodyField(String key, boolean... value) { return hasBodyField(key, Value.of(values)); } + // TODO: Make this public once AnyValue is no longer incubating @SuppressWarnings({"unchecked"}) - public LogRecordDataAssert hasBodyField(String key, Value value) { + LogRecordDataAssert hasBodyField(String key, Value value) { isNotNull(); Value bodyValue = actual.getBodyValue(); assertNotNull(bodyValue); // Can't use assertj or nullaway complains From 1f9550f378a48c01043ef3aa1c2a2a2a3a8c65a9 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Mon, 10 Jun 2024 08:30:59 -0700 Subject: [PATCH 3/7] boos test coverage --- .../testing/assertj/LogAssertionsTest.java | 64 ++++++++++++------- 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java index 2f589ac8ca5..849ba25b90f 100644 --- a/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java +++ b/sdk/testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -5,6 +5,14 @@ package io.opentelemetry.sdk.testing.assertj; +import static io.opentelemetry.api.common.AttributeKey.booleanArrayKey; +import static io.opentelemetry.api.common.AttributeKey.booleanKey; +import static io.opentelemetry.api.common.AttributeKey.doubleArrayKey; +import static io.opentelemetry.api.common.AttributeKey.doubleKey; +import static io.opentelemetry.api.common.AttributeKey.longArrayKey; +import static io.opentelemetry.api.common.AttributeKey.longKey; +import static io.opentelemetry.api.common.AttributeKey.stringArrayKey; +import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.attributeEntry; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.equalTo; @@ -40,7 +48,7 @@ public class LogAssertionsTest { private static final String TRACE_ID = "00000000000000010000000000000002"; private static final String SPAN_ID = "0000000000000003"; - private static final AttributeKey DOG = AttributeKey.stringKey("dog"); + private static final AttributeKey DOG = stringKey("dog"); private static final Attributes ATTRIBUTES = Attributes.builder() .put("bear", "mya") @@ -86,7 +94,7 @@ void passing() { attributes -> assertThat(attributes) .hasSize(2) - .containsEntry(AttributeKey.stringKey("dog"), "bark") + .containsEntry(stringKey("dog"), "bark") .hasEntrySatisfying(DOG, value -> assertThat(value).hasSize(4)) .hasEntrySatisfying( AttributeKey.booleanKey("dog is cute"), @@ -125,14 +133,13 @@ void passing() { attributes -> OpenTelemetryAssertions.assertThat(attributes) .hasSize(8) - .containsEntry(AttributeKey.stringKey("bear"), "mya") - .hasEntrySatisfying( - AttributeKey.stringKey("bear"), value -> assertThat(value).hasSize(3)) + .containsEntry(stringKey("bear"), "mya") + .hasEntrySatisfying(stringKey("bear"), value -> assertThat(value).hasSize(3)) .containsEntry("bear", "mya") .containsEntry("warm", true) .containsEntry("temperature", 30) - .containsEntry(AttributeKey.longKey("temperature"), 30L) - .containsEntry(AttributeKey.longKey("temperature"), 30) + .containsEntry(longKey("temperature"), 30L) + .containsEntry(longKey("temperature"), 30) .containsEntry("length", 1.2) .containsEntry("colors", "red", "blue") .containsEntryWithStringValuesOf("colors", Arrays.asList("red", "blue")) @@ -142,7 +149,7 @@ void passing() { .containsEntryWithLongValuesOf("scores", Arrays.asList(0L, 1L)) .containsEntry("coins", 0.01, 0.05, 0.1) .containsEntryWithDoubleValuesOf("coins", Arrays.asList(0.01, 0.05, 0.1)) - .containsKey(AttributeKey.stringKey("bear")) + .containsKey(stringKey("bear")) .containsKey("bear") .containsOnly( attributeEntry("bear", "mya"), @@ -154,12 +161,12 @@ void passing() { attributeEntry("scores", 0L, 1L), attributeEntry("coins", 0.01, 0.05, 0.1))) .hasAttributesSatisfying( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanArrayKey("conditions"), Arrays.asList(false, true))) .hasAttributesSatisfyingExactly( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanKey("warm"), true), - equalTo(AttributeKey.longKey("temperature"), 30L), + equalTo(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)), @@ -235,7 +242,7 @@ void failure() { .hasAttributesSatisfying( attributes -> OpenTelemetryAssertions.assertThat(attributes) - .containsKey(AttributeKey.stringKey("cat")))) + .containsKey(stringKey("cat")))) .isInstanceOf(AssertionError.class); assertThatThrownBy( () -> @@ -263,21 +270,18 @@ void failure() { attributes -> OpenTelemetryAssertions.assertThat(attributes) .hasEntrySatisfying( - AttributeKey.stringKey("bear"), - value -> assertThat(value).hasSize(2)))) + stringKey("bear"), value -> assertThat(value).hasSize(2)))) .isInstanceOf(AssertionError.class); assertThatThrownBy( - () -> - assertThat(LOG_DATA) - .hasAttributesSatisfying(equalTo(AttributeKey.stringKey("bear"), "moo"))) + () -> assertThat(LOG_DATA).hasAttributesSatisfying(equalTo(stringKey("bear"), "moo"))) .isInstanceOf(AssertionError.class); assertThatThrownBy( () -> assertThat(LOG_DATA) .hasAttributesSatisfyingExactly( - equalTo(AttributeKey.stringKey("bear"), "mya"), + equalTo(stringKey("bear"), "mya"), equalTo(AttributeKey.booleanKey("warm"), true), - equalTo(AttributeKey.longKey("temperature"), 30L), + equalTo(longKey("temperature"), 30L), equalTo(AttributeKey.doubleKey("length"), 1.2))) .isInstanceOf(AssertionError.class); assertThatThrownBy(() -> assertThat(LOG_DATA).hasTotalAttributeCount(11)) @@ -296,25 +300,41 @@ void eventBodyAssertions() { .builder("foo") .put("foostr", "bar") .put("foobool", true) - .put("foolong", 12) + .put("foolong", 12L) .put("foodbl", 12.0) .put("foostra", "bar", "baz", "buzz") .put("foolonga", 9, 0, 2, 1, 0) .put("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) .put("fooboola", true, true, true, false) .put("fooany", Value.of("grim")) + .put(stringKey("ak_str"), "bar") + .put(booleanKey("ak_bool"), true) + .put(longKey("ak_long"), 12L) + .put(doubleKey("ak_dbl"), 12.0) + .put(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) + .put(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) + .put(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) + .put(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)) .emit(); List logs = exporter.getFinishedLogRecordItems(); assertThat(logs).hasSize(1); assertThat(logs.get(0)) .hasBodyField("foostr", "bar") .hasBodyField("foobool", true) - .hasBodyField("foolong", 12) + .hasBodyField("foolong", 12L) .hasBodyField("foodbl", 12.0) .hasBodyField("foostra", "bar", "baz", "buzz") .hasBodyField("foolonga", 9, 0, 2, 1, 0) .hasBodyField("foodbla", 9.1, 0.2, 2.3, 1.4, 0.5) .hasBodyField("fooboola", true, true, true, false) - .hasBodyField("fooany", Value.of("grim")); + .hasBodyField("fooany", Value.of("grim")) + .hasBodyField(stringKey("ak_str"), "bar") + .hasBodyField(booleanKey("ak_bool"), true) + .hasBodyField(longKey("ak_long"), 12L) + .hasBodyField(doubleKey("ak_dbl"), 12.0) + .hasBodyField(stringArrayKey("ak_stra"), Arrays.asList("bar", "baz", "buzz")) + .hasBodyField(longArrayKey("ak_longa"), Arrays.asList(9L, 0L, 2L, 1L, 0L)) + .hasBodyField(doubleArrayKey("ak_dbla"), Arrays.asList(9.1, 0.2, 2.3, 1.4, 0.5)) + .hasBodyField(booleanArrayKey("ak_boola"), Arrays.asList(true, true, true, false)); } } From 2a896616108ce4198eddca9e7fb25278a82d6049 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Tue, 3 Sep 2024 13:59:10 -0700 Subject: [PATCH 4/7] jApiCmp --- .../current_vs_latest/opentelemetry-sdk-testing.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 988fe184f0f..589c621082d 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -2,6 +2,16 @@ Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar *** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBody(io.opentelemetry.api.common.Value) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, java.lang.String[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(io.opentelemetry.api.common.AttributeKey, java.lang.Object) + GENERIC TEMPLATES: +++ T:java.lang.Object **** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable) === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.logs.data.Body getBody() From 9eef3b64392646c24c8a39c916dc4f58c2a83889 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Wed, 4 Sep 2024 12:50:09 -0700 Subject: [PATCH 5/7] code review comments --- .../testing/assertj/LogRecordDataAssert.java | 44 ++++++++++++++++++- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index 335e7df23dc..de00a505cf1 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -14,6 +14,7 @@ import io.opentelemetry.api.common.AttributesBuilder; import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; +import io.opentelemetry.api.common.ValueType; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.sdk.common.InstrumentationScopeInfo; @@ -172,22 +173,42 @@ public LogRecordDataAssert hasBody(@Nullable Value body) { return this; } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and String {@code value}. + */ public LogRecordDataAssert hasBodyField(String key, String value) { return hasBodyField(key, Value.of(value)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and long {@code value}. + */ public LogRecordDataAssert hasBodyField(String key, long value) { return hasBodyField(key, Value.of(value)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and double {@code value}. + */ public LogRecordDataAssert hasBodyField(String key, double value) { return hasBodyField(key, Value.of(value)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and boolean {@code value}. + */ public LogRecordDataAssert hasBodyField(String key, boolean value) { return hasBodyField(key, Value.of(value)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of String {@code value}s. + */ public LogRecordDataAssert hasBodyField(String key, String... value) { List> values = new ArrayList<>(value.length); for (String val : value) { @@ -196,6 +217,10 @@ public LogRecordDataAssert hasBodyField(String key, String... value) { return hasBodyField(key, Value.of(values)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of long {@code value}s. + */ public LogRecordDataAssert hasBodyField(String key, long... value) { List> values = new ArrayList<>(value.length); for (long val : value) { @@ -204,6 +229,10 @@ public LogRecordDataAssert hasBodyField(String key, long... value) { return hasBodyField(key, Value.of(values)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of double {@code value}s. + */ public LogRecordDataAssert hasBodyField(String key, double... value) { List> values = new ArrayList<>(value.length); for (double val : value) { @@ -212,6 +241,10 @@ public LogRecordDataAssert hasBodyField(String key, double... value) { return hasBodyField(key, Value.of(values)); } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and list of boolean {@code value}s. + */ public LogRecordDataAssert hasBodyField(String key, boolean... value) { List> values = new ArrayList<>(value.length); for (boolean val : value) { @@ -220,9 +253,12 @@ public LogRecordDataAssert hasBodyField(String key, boolean... value) { return hasBodyField(key, Value.of(values)); } - // TODO: Make this public once AnyValue is no longer incubating + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given {@code key} and {@code value}. + */ @SuppressWarnings({"unchecked"}) - LogRecordDataAssert hasBodyField(String key, Value value) { + public LogRecordDataAssert hasBodyField(String key, Value value) { isNotNull(); Value bodyValue = actual.getBodyValue(); assertNotNull(bodyValue); // Can't use assertj or nullaway complains @@ -233,6 +269,10 @@ LogRecordDataAssert hasBodyField(String key, Value value) { return this; } + /** + * Asserts the log has a body of type {@link ValueType#KEY_VALUE_LIST}, containing a field with + * the given attribute {@code key} and {@code value}. + */ @SuppressWarnings({"unchecked"}) public LogRecordDataAssert hasBodyField(AttributeKey key, T value) { switch (key.getType()) { From 51fa4ea99eb857e8cfda2ca9b28411ed9b03a0f4 Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Wed, 4 Sep 2024 12:53:34 -0700 Subject: [PATCH 6/7] add message and explicit type assertion --- .../sdk/testing/assertj/LogRecordDataAssert.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java index de00a505cf1..b717ecedad9 100644 --- a/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java +++ b/sdk/testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogRecordDataAssert.java @@ -5,6 +5,7 @@ package io.opentelemetry.sdk.testing.assertj; +import static io.opentelemetry.api.common.ValueType.KEY_VALUE_LIST; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertNotNull; @@ -261,7 +262,9 @@ public LogRecordDataAssert hasBodyField(String key, boolean... value) { public LogRecordDataAssert hasBodyField(String key, Value value) { isNotNull(); Value bodyValue = actual.getBodyValue(); - assertNotNull(bodyValue); // Can't use assertj or nullaway complains + assertNotNull( + "Body was not expected to be null.", bodyValue); // Can't use assertj or nullaway complains + assertThat(bodyValue.getType()).isEqualTo(KEY_VALUE_LIST); Value> body = (Value>) bodyValue; List payload = body.getValue(); KeyValue expected = KeyValue.of(key, value); From 16bd9d21868bab9dec88196ee7b9aee99f3c14db Mon Sep 17 00:00:00 2001 From: Jason Plumb Date: Thu, 5 Sep 2024 09:05:36 -0700 Subject: [PATCH 7/7] jApiCmp --- docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt index 589c621082d..4d359472772 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-sdk-testing.txt @@ -10,6 +10,7 @@ Comparing source compatibility of opentelemetry-sdk-testing-1.42.0-SNAPSHOT.jar +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, long[]) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, double[]) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, boolean[]) + +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(java.lang.String, io.opentelemetry.api.common.Value) +++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.testing.assertj.LogRecordDataAssert hasBodyField(io.opentelemetry.api.common.AttributeKey, java.lang.Object) GENERIC TEMPLATES: +++ T:java.lang.Object **** MODIFIED CLASS: PUBLIC ABSTRACT io.opentelemetry.sdk.testing.logs.TestLogRecordData (not serializable)