diff --git a/sdk/logs-testing/README.md b/sdk/logs-testing/README.md new file mode 100644 index 00000000000..8f6c8ec7c8c --- /dev/null +++ b/sdk/logs-testing/README.md @@ -0,0 +1,6 @@ +# OpenTelemetry Logs SDK Testing + +[![Javadocs][javadoc-image]][javadoc-url] + +[javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-sdk-logs-testing.svg +[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-sdk-logs-testing diff --git a/sdk/logs-testing/build.gradle.kts b/sdk/logs-testing/build.gradle.kts new file mode 100644 index 00000000000..f7fcce0c487 --- /dev/null +++ b/sdk/logs-testing/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + id("otel.java-conventions") + id("otel.publish-conventions") +} + +description = "OpenTelemetry Logs SDK Testing utilities" +otelJava.moduleName.set("io.opentelemetry.sdk.logs.testing") + +dependencies { + api(project(":api:all")) + api(project(":sdk:all")) + api(project(":sdk:logs")) + api(project(":sdk:testing")) + + compileOnly("org.assertj:assertj-core") + compileOnly("junit:junit") + compileOnly("org.junit.jupiter:junit-jupiter-api") + + annotationProcessor("com.google.auto.value:auto-value") + + testImplementation("junit:junit") +} diff --git a/sdk/logs-testing/gradle.properties b/sdk/logs-testing/gradle.properties new file mode 100644 index 00000000000..4476ae57e31 --- /dev/null +++ b/sdk/logs-testing/gradle.properties @@ -0,0 +1 @@ +otel.release=alpha diff --git a/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogAssertions.java b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogAssertions.java new file mode 100644 index 00000000000..b4400ce9a68 --- /dev/null +++ b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogAssertions.java @@ -0,0 +1,20 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.assertj; + +import io.opentelemetry.sdk.logs.data.LogData; +import org.assertj.core.api.Assertions; + +/** Test assertions for data heading to exporters within the Metrics SDK. */ +public final class LogAssertions extends Assertions { + + /** Returns an assertion for {@link io.opentelemetry.sdk.logs.data.LogData}. */ + public static LogDataAssert assertThat(LogData log) { + return new LogDataAssert(log); + } + + private LogAssertions() {} +} diff --git a/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogDataAssert.java b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogDataAssert.java new file mode 100644 index 00000000000..69765e96012 --- /dev/null +++ b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/LogDataAssert.java @@ -0,0 +1,183 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.assertj; + +import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.AttributesBuilder; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; +import io.opentelemetry.sdk.logs.data.LogData; +import io.opentelemetry.sdk.logs.data.Severity; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Map; +import java.util.function.Consumer; +import org.assertj.core.api.AbstractAssert; + +/** Test assertions for {@link LogData}. */ +public class LogDataAssert extends AbstractAssert { + protected LogDataAssert(LogData actual) { + super(actual, LogDataAssert.class); + } + + /** Asserts the {@link Resource} associated with a log matches the expected value. */ + public LogDataAssert hasResource(Resource resource) { + isNotNull(); + if (!actual.getResource().equals(resource)) { + failWithActualExpectedAndMessage( + actual, + "resource: " + resource, + "Expected log to have resource <%s> but found <%s>", + resource, + actual.getResource()); + } + return this; + } + + /** + * Asserts the {@link InstrumentationLibraryInfo} associated with a log matches the expected + * value. + */ + public LogDataAssert hasInstrumentationLibrary( + InstrumentationLibraryInfo instrumentationLibrary) { + isNotNull(); + if (!actual.getInstrumentationLibraryInfo().equals(instrumentationLibrary)) { + failWithActualExpectedAndMessage( + actual, + "instrumentation library: " + instrumentationLibrary, + "Expected log to have resource <%s> but found <%s>", + instrumentationLibrary, + actual.getInstrumentationLibraryInfo()); + } + return this; + } + + /** Asserts the log has the given epoch timestamp. */ + public LogDataAssert hasEpochNanos(long epochNanos) { + isNotNull(); + if (actual.getEpochNanos() != epochNanos) { + failWithActualExpectedAndMessage( + actual.getEpochNanos(), + epochNanos, + "Expected log to have epoch <%s> nanos but was <%s>", + epochNanos, + actual.getEpochNanos()); + } + return this; + } + + /** Asserts the log has the given span context. */ + public LogDataAssert hasSpanContext(SpanContext spanContext) { + isNotNull(); + if (!actual.getSpanContext().equals(spanContext)) { + failWithActualExpectedAndMessage( + actual.getSpanContext(), + spanContext, + "Expected log to have span context <%s> nanos but was <%s>", + spanContext, + actual.getSpanContext()); + } + return this; + } + + /** Asserts the log has the given severity. */ + public LogDataAssert hasSeverity(Severity severity) { + isNotNull(); + if (actual.getSeverity() != severity) { + failWithActualExpectedAndMessage( + actual.getSeverity(), + severity, + "Expected log to have severity <%s> but was <%s>", + severity, + actual.getSeverity()); + } + return this; + } + + /** Asserts the log has the given severity text. */ + public LogDataAssert hasSeverityText(String severityText) { + isNotNull(); + if (!severityText.equals(actual.getSeverityText())) { + failWithActualExpectedAndMessage( + actual.getSeverityText(), + severityText, + "Expected log to have severity text <%s> but was <%s>", + severityText, + actual.getSeverityText()); + } + return this; + } + + /** Asserts the log has the given name. */ + public LogDataAssert hasName(String name) { + isNotNull(); + if (!name.equals(actual.getName())) { + failWithActualExpectedAndMessage( + actual.getName(), + name, + "Expected log to have name <%s> but was <%s>", + name, + actual.getName()); + } + return this; + } + + /** Asserts the log has the given body. */ + public LogDataAssert hasBody(String body) { + isNotNull(); + if (!actual.getBody().asString().equals(body)) { + failWithActualExpectedAndMessage( + actual.getBody(), + body, + "Expected log to have body <%s> but was <%s>", + body, + actual.getBody().asString()); + } + return this; + } + + /** Asserts the log has the given attributes. */ + public LogDataAssert hasAttributes(Attributes attributes) { + isNotNull(); + if (!attributesAreEqual(attributes)) { + failWithActualExpectedAndMessage( + actual.getAttributes(), + attributes, + "Expected log to have attributes <%s> but was <%s>", + actual.getName(), + attributes, + actual.getAttributes()); + } + return this; + } + + /** Asserts the log has the given attributes. */ + @SuppressWarnings({"rawtypes", "unchecked"}) + @SafeVarargs + public final LogDataAssert hasAttributes(Map.Entry, ?>... entries) { + AttributesBuilder attributesBuilder = Attributes.builder(); + for (Map.Entry, ?> attr : entries) { + attributesBuilder.put((AttributeKey) attr.getKey(), attr.getValue()); + } + Attributes attributes = attributesBuilder.build(); + return hasAttributes(attributes); + } + + /** Asserts the log has attributes satisfying the given condition. */ + public LogDataAssert hasAttributesSatisfying(Consumer attributes) { + isNotNull(); + assertThat(actual.getAttributes()).as("attributes").satisfies(attributes); + return this; + } + + private boolean attributesAreEqual(Attributes attributes) { + // compare as maps, since implementations do not have equals that work correctly across + // implementations. + return actual.getAttributes().asMap().equals(attributes.asMap()); + } +} diff --git a/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/package-info.java b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/package-info.java new file mode 100644 index 00000000000..c2388a7b6f5 --- /dev/null +++ b/sdk/logs-testing/src/main/java/io/opentelemetry/sdk/testing/assertj/package-info.java @@ -0,0 +1,9 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +@ParametersAreNonnullByDefault +package io.opentelemetry.sdk.testing.assertj; + +import javax.annotation.ParametersAreNonnullByDefault; diff --git a/sdk/logs-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java b/sdk/logs-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java new file mode 100644 index 00000000000..48c91d777e7 --- /dev/null +++ b/sdk/logs-testing/src/test/java/io/opentelemetry/sdk/testing/assertj/LogAssertionsTest.java @@ -0,0 +1,184 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.testing.assertj; + +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 org.assertj.core.api.Assertions.assertThatThrownBy; + +import io.opentelemetry.api.common.AttributeKey; +import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.trace.SpanContext; +import io.opentelemetry.api.trace.TraceFlags; +import io.opentelemetry.api.trace.TraceState; +import io.opentelemetry.sdk.common.InstrumentationLibraryInfo; +import io.opentelemetry.sdk.logs.data.LogData; +import io.opentelemetry.sdk.logs.data.LogDataBuilder; +import io.opentelemetry.sdk.logs.data.Severity; +import io.opentelemetry.sdk.resources.Resource; +import java.util.Arrays; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.Test; + +public class LogAssertionsTest { + private static final Resource RESOURCE = + Resource.create(Attributes.of(stringKey("resource_key"), "resource_value")); + private static final InstrumentationLibraryInfo INSTRUMENTATION_LIBRARY_INFO = + InstrumentationLibraryInfo.create("instrumentation_library", null); + private static final String TRACE_ID = "00000000000000010000000000000002"; + private static final String SPAN_ID = "0000000000000003"; + private static final Attributes ATTRIBUTES = + Attributes.builder() + .put("bear", "mya") + .put("warm", true) + .put("temperature", 30) + .put("length", 1.2) + .put("colors", "red", "blue") + .put("conditions", false, true) + .put("scores", 0L, 1L) + .put("coins", 0.01, 0.05, 0.1) + .build(); + + private static final LogData LOG_DATA = + LogDataBuilder.create(RESOURCE, INSTRUMENTATION_LIBRARY_INFO) + .setEpoch(100, TimeUnit.NANOSECONDS) + .setSpanContext( + SpanContext.create( + TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault())) + .setSeverity(Severity.INFO) + .setSeverityText("info") + .setName("name") + .setBody("message") + .setAttributes(ATTRIBUTES) + .build(); + + @Test + void passing() { + assertThat(LOG_DATA) + .hasResource(RESOURCE) + .hasInstrumentationLibrary(INSTRUMENTATION_LIBRARY_INFO) + .hasEpochNanos(100) + .hasSpanContext( + SpanContext.create(TRACE_ID, SPAN_ID, TraceFlags.getDefault(), TraceState.getDefault())) + .hasSeverity(Severity.INFO) + .hasSeverityText("info") + .hasName("name") + .hasBody("message") + .hasAttributes(ATTRIBUTES) + .hasAttributes( + attributeEntry("bear", "mya"), + attributeEntry("warm", true), + attributeEntry("temperature", 30), + attributeEntry("length", 1.2), + attributeEntry("colors", "red", "blue"), + attributeEntry("conditions", false, true), + attributeEntry("scores", 0L, 1L), + attributeEntry("coins", 0.01, 0.05, 0.1)) + .hasAttributesSatisfying( + attributes -> + OpenTelemetryAssertions.assertThat(attributes) + .hasSize(8) + .containsEntry(AttributeKey.stringKey("bear"), "mya") + .hasEntrySatisfying( + AttributeKey.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("length", 1.2) + .containsEntry("colors", "red", "blue") + .containsEntryWithStringValuesOf("colors", Arrays.asList("red", "blue")) + .containsEntry("conditions", false, true) + .containsEntryWithBooleanValuesOf("conditions", Arrays.asList(false, true)) + .containsEntry("scores", 0L, 1L) + .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("bear") + .containsOnly( + attributeEntry("bear", "mya"), + attributeEntry("warm", true), + attributeEntry("temperature", 30), + attributeEntry("length", 1.2), + attributeEntry("colors", "red", "blue"), + attributeEntry("conditions", false, true), + attributeEntry("scores", 0L, 1L), + attributeEntry("coins", 0.01, 0.05, 0.1))); + } + + @Test + void failure() { + assertThatThrownBy(() -> assertThat(LOG_DATA).hasResource(Resource.empty())); + assertThatThrownBy( + () -> assertThat(LOG_DATA).hasInstrumentationLibrary(InstrumentationLibraryInfo.empty())); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasEpochNanos(200)); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasSpanContext( + SpanContext.create( + TRACE_ID, + "0000000000000004", + TraceFlags.getDefault(), + TraceState.getDefault()))); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasSeverity(Severity.DEBUG)); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasSeverityText("warning")); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasName("foo")); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasBody("bar")); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasAttributes(Attributes.empty())) + .isInstanceOf(AssertionError.class); + assertThatThrownBy(() -> assertThat(LOG_DATA).hasAttributes(attributeEntry("food", "burger"))) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> + OpenTelemetryAssertions.assertThat(attributes) + .containsEntry("cat", "bark"))) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> + OpenTelemetryAssertions.assertThat(attributes) + .containsKey(AttributeKey.stringKey("cat")))) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> + OpenTelemetryAssertions.assertThat(attributes).containsKey("cat"))) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> OpenTelemetryAssertions.assertThat(attributes).isEmpty())) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> OpenTelemetryAssertions.assertThat(attributes).hasSize(33))) + .isInstanceOf(AssertionError.class); + assertThatThrownBy( + () -> + assertThat(LOG_DATA) + .hasAttributesSatisfying( + attributes -> + OpenTelemetryAssertions.assertThat(attributes) + .hasEntrySatisfying( + AttributeKey.stringKey("bear"), + value -> assertThat(value).hasSize(2)))) + .isInstanceOf(AssertionError.class); + } +} diff --git a/sdk/logs/build.gradle.kts b/sdk/logs/build.gradle.kts index 279f091c29d..5773999a8d4 100644 --- a/sdk/logs/build.gradle.kts +++ b/sdk/logs/build.gradle.kts @@ -11,6 +11,8 @@ otelJava.moduleName.set("io.opentelemetry.sdk.extension.logging") dependencies { api(project(":sdk:common")) + testImplementation(project(":sdk:logs-testing")) + testImplementation("org.awaitility:awaitility") annotationProcessor("com.google.auto.value:auto-value") diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterProviderBuilderTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterProviderBuilderTest.java index c957c203e33..bf75bff77a1 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterProviderBuilderTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterProviderBuilderTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.logs; -import static org.assertj.core.api.AssertionsForClassTypes.assertThat; +import static io.opentelemetry.sdk.testing.assertj.LogAssertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -14,6 +14,7 @@ import io.opentelemetry.sdk.resources.Resource; import java.util.LinkedList; import java.util.List; +import org.assertj.core.api.AssertionsForClassTypes; import org.junit.jupiter.api.Test; class SdkLogEmitterProviderBuilderTest { @@ -35,7 +36,7 @@ void canSetClock() { SdkLogEmitterProvider provider = builder.build(); provider.logEmitterBuilder("inst").build().logBuilder().emit(); - assertThat(seenLogs.size()).isEqualTo(1); - assertThat(seenLogs.get(0).getEpochNanos()).isEqualTo(13L); + AssertionsForClassTypes.assertThat(seenLogs.size()).isEqualTo(1); + assertThat(seenLogs.get(0)).hasEpochNanos(13L); } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterTest.java index a287f1d5f7b..ec202c97958 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/SdkLogEmitterTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.logs; -import static org.assertj.core.api.Assertions.assertThat; +import static io.opentelemetry.sdk.testing.assertj.LogAssertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -36,6 +36,6 @@ void logBuilder() { // Have to test through the builder logBuilder.emit(); - assertThat(seenLog.get().getBody().asString()).isEqualTo("foo"); + assertThat(seenLog.get()).hasBody("foo"); } } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogProcessorTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogProcessorTest.java index dd0e8f94c3e..c2df4eae0f0 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogProcessorTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/BatchLogProcessorTest.java @@ -5,7 +5,7 @@ package io.opentelemetry.sdk.logs.export; -import static org.assertj.core.api.Assertions.assertThat; +import static io.opentelemetry.sdk.testing.assertj.LogAssertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode; import static org.awaitility.Awaitility.await; @@ -19,6 +19,7 @@ import io.opentelemetry.sdk.common.CompletableResultCode; import io.opentelemetry.sdk.logs.SdkLogEmitterProvider; import io.opentelemetry.sdk.logs.data.LogData; +import io.opentelemetry.sdk.testing.assertj.LogAssertions; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -121,8 +122,8 @@ void emitMultipleLogs() { List exported = waitingLogExporter.waitForExport(); assertThat(exported) .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_1), - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + logData -> assertThat(logData).hasBody(LOG_MESSAGE_1), + logData -> assertThat(logData).hasBody(LOG_MESSAGE_2)); } @Test @@ -153,9 +154,7 @@ void emitMoreLogsThanBufferSize() { () -> assertThat(logExporter.getExported()) .hasSize(6) - .allSatisfy( - logData -> - assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_1))); + .allSatisfy(logData -> assertThat(logData).hasBody(LOG_MESSAGE_1))); } @Test @@ -216,13 +215,13 @@ void emitLogsToMultipleExporters() { assertThat(exported1) .hasSize(2) .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_1), - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + logData -> assertThat(logData).hasBody(LOG_MESSAGE_1), + logData -> assertThat(logData).hasBody(LOG_MESSAGE_2)); assertThat(exported2) .hasSize(2) .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_1), - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + logData -> assertThat(logData).hasBody(LOG_MESSAGE_1), + logData -> assertThat(logData).hasBody(LOG_MESSAGE_2)); } @Test @@ -311,16 +310,12 @@ void exporterThrowsException() { emitLog(sdkLogEmitterProvider, LOG_MESSAGE_1); List exported = waitingLogExporter.waitForExport(); - assertThat(exported) - .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_1)); + assertThat(exported).satisfiesExactly(logData -> assertThat(logData).hasBody(LOG_MESSAGE_1)); waitingLogExporter.reset(); // Continue to export after the exception was received. emitLog(sdkLogEmitterProvider, LOG_MESSAGE_2); exported = waitingLogExporter.waitForExport(); - assertThat(exported) - .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + assertThat(exported).satisfiesExactly(logData -> assertThat(logData).hasBody(LOG_MESSAGE_2)); } @Test @@ -342,8 +337,7 @@ public void continuesIfExporterTimesOut() throws InterruptedException { argThat( logs -> { assertThat(logs) - .anySatisfy( - log -> assertThat(log.getBody().asString()).isEqualTo(LOG_MESSAGE_1)); + .anySatisfy(log -> LogAssertions.assertThat(log).hasBody(LOG_MESSAGE_1)); exported.countDown(); return true; }))) @@ -361,8 +355,7 @@ public void continuesIfExporterTimesOut() throws InterruptedException { argThat( logs -> { assertThat(logs) - .anySatisfy( - log -> assertThat(log.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + .anySatisfy(log -> LogAssertions.assertThat(log).hasBody(LOG_MESSAGE_2)); exportedAgain.countDown(); return true; }))) @@ -393,9 +386,8 @@ void shutdownFlushes() { sdkLogEmitterProvider.shutdown().join(10, TimeUnit.SECONDS); List exported = waitingLogExporter.getExported(); - assertThat(exported) - .satisfiesExactly( - logData -> assertThat(logData.getBody().asString()).isEqualTo(LOG_MESSAGE_2)); + assertThat(exported).satisfiesExactly(logData -> assertThat(logData).hasBody(LOG_MESSAGE_2)); + ; assertThat(waitingLogExporter.shutDownCalled.get()).isTrue(); } diff --git a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/InMemoryLogExporterTest.java b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/InMemoryLogExporterTest.java index 15644382fba..fcb1b546b9a 100644 --- a/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/InMemoryLogExporterTest.java +++ b/sdk/logs/src/test/java/io/opentelemetry/sdk/logs/export/InMemoryLogExporterTest.java @@ -12,6 +12,7 @@ import io.opentelemetry.sdk.logs.LogEmitter; import io.opentelemetry.sdk.logs.SdkLogEmitterProvider; import io.opentelemetry.sdk.logs.data.LogData; +import io.opentelemetry.sdk.testing.assertj.LogAssertions; import java.util.Collections; import java.util.List; import org.junit.jupiter.api.AfterEach; @@ -48,9 +49,9 @@ void getFinishedLogItems() { List logItems = exporter.getFinishedLogItems(); assertThat(logItems).isNotNull(); assertThat(logItems.size()).isEqualTo(3); - assertThat(logItems.get(0).getBody().asString()).isEqualTo("message 1"); - assertThat(logItems.get(1).getBody().asString()).isEqualTo("message 2"); - assertThat(logItems.get(2).getBody().asString()).isEqualTo("message 3"); + LogAssertions.assertThat(logItems.get(0)).hasBody("message 1"); + LogAssertions.assertThat(logItems.get(1)).hasBody("message 2"); + LogAssertions.assertThat(logItems.get(2)).hasBody("message 3"); } @Test diff --git a/settings.gradle.kts b/settings.gradle.kts index aeeedefe8d0..06d86ae83ba 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -60,6 +60,7 @@ include(":perf-harness") include(":sdk:all") include(":sdk:common") include(":sdk:logs") +include(":sdk:logs-testing") include(":sdk:metrics") include(":sdk:metrics-testing") include(":sdk:testing")