From 2bba3d7ceb6200ee5dbf6d4044eb0915d5d65fc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar?= <56847527+LikeTheSalad@users.noreply.github.com> Date: Mon, 29 Jul 2024 15:09:02 +0200 Subject: [PATCH] Instrumentation API part 9 (#486) * Moving InitializationEvents to the common api * Adding auto service dependency * Making SdkInitializationEvents a service * Moving InitializationEvents to the agent * Connecting StartupInstrumentation with SdkInitializationEvents * Adding tests * Adding tests * Making InitializationEvents internal * Removing autoService from java lib conventions --- android-agent/build.gradle.kts | 2 +- .../android/OpenTelemetryRumBuilder.java | 28 ++----- .../initialization/InitializationEvents.kt | 80 +++++++++++++++++++ .../android/OpenTelemetryRumBuilderTest.java | 16 ++-- .../InitializationEventsTest.kt | 32 ++++++++ .../TestInitializationEvents.kt | 35 ++++++++ ...ternal.initialization.InitializationEvents | 1 + ...tel.android-library-conventions.gradle.kts | 3 + gradle/libs.versions.toml | 3 + instrumentation/startup/build.gradle.kts | 2 +- .../startup/InitializationEvents.kt | 48 ----------- .../startup/SdkInitializationEvents.kt | 25 +++--- .../startup/StartupInstrumentation.kt | 23 ++++++ .../startup/SdkInitializationEventsTest.kt | 12 +-- .../startup/StartupInstrumentationTest.kt | 63 +++++++++++++++ 15 files changed, 267 insertions(+), 106 deletions(-) create mode 100644 android-agent/src/main/java/io/opentelemetry/android/internal/initialization/InitializationEvents.kt create mode 100644 android-agent/src/test/java/io/opentelemetry/android/internal/initialization/InitializationEventsTest.kt create mode 100644 android-agent/src/test/java/io/opentelemetry/android/internal/initialization/TestInitializationEvents.kt create mode 100644 android-agent/src/test/resources/META-INF/services/io.opentelemetry.android.internal.initialization.InitializationEvents delete mode 100644 instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.kt create mode 100644 instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentation.kt create mode 100644 instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentationTest.kt diff --git a/android-agent/build.gradle.kts b/android-agent/build.gradle.kts index a7c4d81e3..b46831d87 100644 --- a/android-agent/build.gradle.kts +++ b/android-agent/build.gradle.kts @@ -63,7 +63,7 @@ android { dependencies { implementation(project(":common")) - implementation(project(":instrumentation:startup")) // todo remove during the initializationevents adaptation work. + implementation(project(":instrumentation:common-api")) implementation(libs.androidx.core) implementation(libs.androidx.navigation.fragment) implementation(libs.androidx.lifecycle.process) diff --git a/android-agent/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java b/android-agent/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java index e45a08d66..05b272d5e 100644 --- a/android-agent/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java +++ b/android-agent/src/main/java/io/opentelemetry/android/OpenTelemetryRumBuilder.java @@ -15,11 +15,10 @@ import io.opentelemetry.android.features.diskbuffering.SignalFromDiskExporter; import io.opentelemetry.android.features.diskbuffering.scheduler.ExportScheduleHandler; import io.opentelemetry.android.instrumentation.common.InstrumentedApplication; -import io.opentelemetry.android.instrumentation.startup.InitializationEvents; -import io.opentelemetry.android.instrumentation.startup.SdkInitializationEvents; import io.opentelemetry.android.internal.features.networkattrs.NetworkAttributesSpanAppender; import io.opentelemetry.android.internal.features.persistence.DiskManager; import io.opentelemetry.android.internal.features.persistence.SimpleTemporaryFileProvider; +import io.opentelemetry.android.internal.initialization.InitializationEvents; import io.opentelemetry.android.internal.processors.GlobalAttributesLogRecordAppender; import io.opentelemetry.android.internal.services.CacheStorage; import io.opentelemetry.android.internal.services.Preferences; @@ -51,9 +50,7 @@ import io.opentelemetry.sdk.trace.export.SpanExporter; import java.io.IOException; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.Function; @@ -89,7 +86,6 @@ public final class OpenTelemetryRumBuilder { (a) -> a; private Resource resource; - private InitializationEvents initializationEvents = InitializationEvents.NO_OP; private static TextMapPropagator buildDefaultPropagator() { return TextMapPropagator.composite( @@ -277,7 +273,8 @@ public OpenTelemetryRum build() { } OpenTelemetryRum build(ServiceManager serviceManager) { - applyConfiguration(serviceManager); + InitializationEvents initializationEvents = InitializationEvents.get(); + applyConfiguration(serviceManager, initializationEvents); DiskBufferingConfiguration diskBufferingConfiguration = config.getDiskBufferingConfiguration(); @@ -374,18 +371,10 @@ public OpenTelemetryRumBuilder addOtelSdkReadyListener(Consumer configMap = new HashMap<>(); - // TODO: Convert config to map - // breedx-splk: Left incomplete for now, because I think Cesar is making changes around - // this - initializationEvents.recordConfiguration(configMap); + initializationEvents.recordConfiguration(config); } initializationEvents.sdkInitializationStarted(); @@ -485,9 +474,4 @@ private ContextPropagators buildFinalPropagators() { TextMapPropagator defaultPropagator = buildDefaultPropagator(); return ContextPropagators.create(propagatorCustomizer.apply(defaultPropagator)); } - - OpenTelemetryRumBuilder setInitializationEvents(InitializationEvents initializationEvents) { - this.initializationEvents = initializationEvents; - return this; - } } diff --git a/android-agent/src/main/java/io/opentelemetry/android/internal/initialization/InitializationEvents.kt b/android-agent/src/main/java/io/opentelemetry/android/internal/initialization/InitializationEvents.kt new file mode 100644 index 000000000..2d94abfdd --- /dev/null +++ b/android-agent/src/main/java/io/opentelemetry/android/internal/initialization/InitializationEvents.kt @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.initialization + +import io.opentelemetry.android.config.OtelRumConfig +import io.opentelemetry.sdk.trace.export.SpanExporter +import java.util.ServiceLoader.load + +/** + * This class is internal and not for public use. Its APIs are unstable and can change at any time. + */ +interface InitializationEvents { + fun sdkInitializationStarted() + + fun recordConfiguration(config: OtelRumConfig) + + fun currentNetworkProviderInitialized() + + fun networkMonitorInitialized() + + fun anrMonitorInitialized() + + fun slowRenderingDetectorInitialized() + + fun crashReportingInitialized() + + fun spanExporterInitialized(spanExporter: SpanExporter) + + companion object { + private var instance: InitializationEvents? = null + + @JvmStatic + fun get(): InitializationEvents { + if (instance == null) { + val initializationEvents = load(InitializationEvents::class.java).firstOrNull() + if (initializationEvents != null) { + set(initializationEvents) + } else { + set(NO_OP) + } + } + + return instance!! + } + + @JvmStatic + fun set(initializationEvents: InitializationEvents) { + if (instance == null) { + instance = initializationEvents + } + } + + @JvmStatic + fun resetForTest() { + instance = null + } + + val NO_OP: InitializationEvents = + object : InitializationEvents { + override fun sdkInitializationStarted() {} + + override fun recordConfiguration(config: OtelRumConfig) {} + + override fun currentNetworkProviderInitialized() {} + + override fun networkMonitorInitialized() {} + + override fun anrMonitorInitialized() {} + + override fun slowRenderingDetectorInitialized() {} + + override fun crashReportingInitialized() {} + + override fun spanExporterInitialized(spanExporter: SpanExporter) {} + } + } +} diff --git a/android-agent/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java b/android-agent/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java index 9b3faa164..fb95f78b2 100644 --- a/android-agent/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java +++ b/android-agent/src/test/java/io/opentelemetry/android/OpenTelemetryRumBuilderTest.java @@ -30,7 +30,7 @@ import io.opentelemetry.android.features.diskbuffering.DiskBufferingConfiguration; import io.opentelemetry.android.features.diskbuffering.SignalFromDiskExporter; import io.opentelemetry.android.features.diskbuffering.scheduler.ExportScheduleHandler; -import io.opentelemetry.android.instrumentation.startup.InitializationEvents; +import io.opentelemetry.android.internal.initialization.InitializationEvents; import io.opentelemetry.android.internal.services.CacheStorage; import io.opentelemetry.android.internal.services.Preferences; import io.opentelemetry.android.internal.services.ServiceManager; @@ -105,12 +105,14 @@ public void setup() { mocks = MockitoAnnotations.openMocks(this); when(application.getApplicationContext()).thenReturn(applicationContext); when(application.getMainLooper()).thenReturn(looper); + InitializationEvents.set(initializationEvents); } @After public void tearDown() throws Exception { SignalFromDiskExporter.resetForTesting(); mocks.close(); + InitializationEvents.resetForTest(); } @Test @@ -302,9 +304,7 @@ public void diskBufferingEnabled() { .build()); ArgumentCaptor exporterCaptor = ArgumentCaptor.forClass(SpanExporter.class); - OpenTelemetryRum.builder(application, config) - .setInitializationEvents(initializationEvents) - .build(serviceManager); + OpenTelemetryRum.builder(application, config).build(serviceManager); assertThat(SignalFromDiskExporter.get()).isNotNull(); verify(scheduleHandler).enable(); @@ -333,9 +333,7 @@ public void diskBufferingEnabled_when_exception_thrown() { .setExportScheduleHandler(scheduleHandler) .build()); - OpenTelemetryRum.builder(application, config) - .setInitializationEvents(initializationEvents) - .build(serviceManager); + OpenTelemetryRum.builder(application, config).build(serviceManager); verify(initializationEvents).spanExporterInitialized(exporterCaptor.capture()); verify(scheduleHandler, never()).enable(); @@ -366,9 +364,7 @@ public void diskBufferingDisabled() { .setExportScheduleHandler(scheduleHandler) .build()); - OpenTelemetryRum.builder(application, config) - .setInitializationEvents(initializationEvents) - .build(); + OpenTelemetryRum.builder(application, config).build(); verify(initializationEvents).spanExporterInitialized(exporterCaptor.capture()); verify(scheduleHandler, never()).enable(); diff --git a/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/InitializationEventsTest.kt b/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/InitializationEventsTest.kt new file mode 100644 index 000000000..04e273552 --- /dev/null +++ b/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/InitializationEventsTest.kt @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.initialization + +import io.mockk.mockk +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.Test + +class InitializationEventsTest { + @AfterEach + fun tearDown() { + InitializationEvents.resetForTest() + } + + @Test + fun `Verify service loading`() { + val initializationEvents = InitializationEvents.get() + assertThat(initializationEvents).isInstanceOf(TestInitializationEvents::class.java) + } + + @Test + fun `Verify setting instance once`() { + val initializationEvents = mockk() + InitializationEvents.set(initializationEvents) + + assertThat(InitializationEvents.get()).isEqualTo(initializationEvents) + } +} diff --git a/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/TestInitializationEvents.kt b/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/TestInitializationEvents.kt new file mode 100644 index 000000000..93fdda9bd --- /dev/null +++ b/android-agent/src/test/java/io/opentelemetry/android/internal/initialization/TestInitializationEvents.kt @@ -0,0 +1,35 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.internal.initialization + +import io.opentelemetry.android.config.OtelRumConfig +import io.opentelemetry.sdk.trace.export.SpanExporter + +class TestInitializationEvents : InitializationEvents { + override fun sdkInitializationStarted() { + } + + override fun recordConfiguration(config: OtelRumConfig) { + } + + override fun currentNetworkProviderInitialized() { + } + + override fun networkMonitorInitialized() { + } + + override fun anrMonitorInitialized() { + } + + override fun slowRenderingDetectorInitialized() { + } + + override fun crashReportingInitialized() { + } + + override fun spanExporterInitialized(spanExporter: SpanExporter) { + } +} diff --git a/android-agent/src/test/resources/META-INF/services/io.opentelemetry.android.internal.initialization.InitializationEvents b/android-agent/src/test/resources/META-INF/services/io.opentelemetry.android.internal.initialization.InitializationEvents new file mode 100644 index 000000000..8842b0e2b --- /dev/null +++ b/android-agent/src/test/resources/META-INF/services/io.opentelemetry.android.internal.initialization.InitializationEvents @@ -0,0 +1 @@ +io.opentelemetry.android.internal.initialization.TestInitializationEvents \ No newline at end of file diff --git a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts index 8cd367678..d1d2a91a0 100644 --- a/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/otel.android-library-conventions.gradle.kts @@ -4,6 +4,7 @@ plugins { id("com.android.library") id("org.jetbrains.kotlin.android") id("otel.errorprone-conventions") + id("kotlin-kapt") } val javaVersion = rootProject.extra["java_version"] as JavaVersion @@ -44,6 +45,8 @@ tasks.withType { val libs = extensions.getByType().named("libs") dependencies { implementation(libs.findLibrary("findbugs-jsr305").get()) + compileOnly(libs.findLibrary("auto-service-annotations").get()) + kapt(libs.findLibrary("auto-service-processor").get()) testImplementation(libs.findLibrary("assertj-core").get()) testImplementation(libs.findBundle("mocking").get()) testImplementation(libs.findBundle("junit").get()) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9bac48ba2..554a753a7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,6 +13,7 @@ spotless = "6.25.0" kotlin = "2.0.0" androidPlugin = "8.5.1" junitKtx = "1.2.1" +autoService = "1.1.1" [libraries] opentelemetry-platform = { module = "io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom", version.ref = "opentelemetry-instrumentation" } @@ -36,6 +37,8 @@ opentelemetry-exporter-logging = { module = "io.opentelemetry:opentelemetry-expo opentelemetry-diskBuffering = { module = "io.opentelemetry.contrib:opentelemetry-disk-buffering", version.ref = "opentelemetry-contrib" } opentelemetry-exporter-otlp = { module = "io.opentelemetry:opentelemetry-exporter-otlp", version.ref = "opentelemetry" } volley = "com.android.volley:volley:1.2.1" +auto-service-annotations = { module = "com.google.auto.service:auto-service-annotations", version.ref = "autoService" } +auto-service-processor = { module = "com.google.auto.service:auto-service", version.ref = "autoService" } #Test tools opentelemetry-sdk-testing = { module = "io.opentelemetry:opentelemetry-sdk-testing", version.ref = "opentelemetry" } diff --git a/instrumentation/startup/build.gradle.kts b/instrumentation/startup/build.gradle.kts index 06e98f8d6..f679f2ac9 100644 --- a/instrumentation/startup/build.gradle.kts +++ b/instrumentation/startup/build.gradle.kts @@ -16,8 +16,8 @@ android { dependencies { api(platform(libs.opentelemetry.platform)) api(libs.opentelemetry.api) + api(project(":android-agent")) api(project(":common")) - api(project(":instrumentation:common-api")) implementation(libs.androidx.core) implementation(libs.opentelemetry.semconv) implementation(libs.opentelemetry.sdk) diff --git a/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.kt b/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.kt deleted file mode 100644 index c0e00104b..000000000 --- a/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/InitializationEvents.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.android.instrumentation.startup - -import io.opentelemetry.sdk.trace.export.SpanExporter - -interface InitializationEvents { - fun sdkInitializationStarted() - - fun recordConfiguration(config: Map) - - fun currentNetworkProviderInitialized() - - fun networkMonitorInitialized() - - fun anrMonitorInitialized() - - fun slowRenderingDetectorInitialized() - - fun crashReportingInitialized() - - fun spanExporterInitialized(spanExporter: SpanExporter) - - companion object { - @JvmField - val NO_OP: InitializationEvents = - object : InitializationEvents { - override fun sdkInitializationStarted() {} - - override fun recordConfiguration(config: Map) {} - - override fun currentNetworkProviderInitialized() {} - - override fun networkMonitorInitialized() {} - - override fun anrMonitorInitialized() {} - - override fun slowRenderingDetectorInitialized() {} - - override fun crashReportingInitialized() {} - - override fun spanExporterInitialized(spanExporter: SpanExporter) {} - } - } -} diff --git a/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.kt b/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.kt index 00de72f6a..67a374659 100644 --- a/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.kt +++ b/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEvents.kt @@ -5,33 +5,30 @@ package io.opentelemetry.android.instrumentation.startup +import com.google.auto.service.AutoService import io.opentelemetry.android.common.RumConstants +import io.opentelemetry.android.config.OtelRumConfig +import io.opentelemetry.android.internal.initialization.InitializationEvents +import io.opentelemetry.api.OpenTelemetry import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.incubator.logs.AnyValue -import io.opentelemetry.sdk.OpenTelemetrySdk import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider import io.opentelemetry.sdk.trace.export.SpanExporter import java.time.Instant -import java.util.function.Consumer import java.util.function.Supplier -class SdkInitializationEvents(private val clock: Supplier = Supplier { Instant.now() }) : InitializationEvents { +@AutoService(InitializationEvents::class) +class SdkInitializationEvents(private val clock: Supplier = Supplier { Instant.now() }) : + InitializationEvents { private val events = mutableListOf() override fun sdkInitializationStarted() { addEvent(RumConstants.Events.INIT_EVENT_STARTED) } - override fun recordConfiguration(config: Map) { - val map = mutableMapOf>() - config.entries.forEach( - Consumer { e: Map.Entry -> - map[e.key] = AnyValue.of(e.value) - }, - ) - val body = AnyValue.of(map) - addEvent(RumConstants.Events.INIT_EVENT_CONFIG, body = body) + override fun recordConfiguration(config: OtelRumConfig) { + // TODO convert config to AnyValue and add an event for it named RumConstants.Events.INIT_EVENT_CONFIG } override fun currentNetworkProviderInitialized() { @@ -60,8 +57,8 @@ class SdkInitializationEvents(private val clock: Supplier = Supplier { addEvent(RumConstants.Events.INIT_EVENT_SPAN_EXPORTER, attr = attributes) } - fun finish(sdk: OpenTelemetrySdk) { - val loggerProvider = sdk.sdkLoggerProvider + internal fun finish(openTelemetry: OpenTelemetry) { + val loggerProvider = openTelemetry.logsBridge val eventLogger = SdkEventLoggerProvider.create(loggerProvider).get("otel.initialization.events") events.forEach { event: Event -> diff --git a/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentation.kt b/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentation.kt new file mode 100644 index 000000000..fab5df2d6 --- /dev/null +++ b/instrumentation/startup/src/main/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentation.kt @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.instrumentation.startup + +import android.app.Application +import io.opentelemetry.android.OpenTelemetryRum +import io.opentelemetry.android.instrumentation.AndroidInstrumentation +import io.opentelemetry.android.internal.initialization.InitializationEvents + +class StartupInstrumentation : AndroidInstrumentation { + override fun install( + application: Application, + openTelemetryRum: OpenTelemetryRum, + ) { + val events = InitializationEvents.get() + if (events is SdkInitializationEvents) { + events.finish(openTelemetryRum.openTelemetry) + } + } +} diff --git a/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEventsTest.kt b/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEventsTest.kt index 68473f4d0..4fb8eeb19 100644 --- a/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEventsTest.kt +++ b/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/SdkInitializationEventsTest.kt @@ -12,13 +12,11 @@ import io.mockk.verify import io.opentelemetry.android.common.RumConstants import io.opentelemetry.api.common.AttributeKey.stringKey import io.opentelemetry.api.common.Attributes -import io.opentelemetry.api.incubator.logs.AnyValue import io.opentelemetry.sdk.OpenTelemetrySdk import io.opentelemetry.sdk.logs.LogRecordProcessor import io.opentelemetry.sdk.logs.ReadWriteLogRecord import io.opentelemetry.sdk.logs.SdkLoggerProvider import io.opentelemetry.sdk.logs.data.Body -import io.opentelemetry.sdk.logs.internal.AnyValueBody import io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat import io.opentelemetry.sdk.trace.export.SpanExporter import org.junit.jupiter.api.Test @@ -37,11 +35,7 @@ class SdkInitializationEventsTest { Supplier { Instant.ofEpochMilli(fakeTime.getAndAdd(50)) } - val config = mapOf(Pair("foo", "bar"), Pair("bar", "baz")) val seen: MutableList = ArrayList() - val expectedConfig = - AnyValueBody.create(AnyValue.of(config.mapValues { AnyValue.of(it.value) })) - val exporter = mockk() val processor = mockk() val loggerProvider = @@ -64,7 +58,6 @@ class SdkInitializationEventsTest { events.crashReportingInitialized() events.currentNetworkProviderInitialized() events.networkMonitorInitialized() - events.recordConfiguration(config) events.slowRenderingDetectorInitialized() events.spanExporterInitialized(exporter) @@ -79,9 +72,8 @@ class SdkInitializationEventsTest { time(now + 100).named(RumConstants.Events.INIT_EVENT_CRASH_REPORTER), time(now + 150).named(RumConstants.Events.INIT_EVENT_NET_PROVIDER), time(now + 200).named(RumConstants.Events.INIT_EVENT_NET_MONITOR), - time(now + 250).named(RumConstants.Events.INIT_EVENT_CONFIG).withBody(expectedConfig), - time(now + 300).named(RumConstants.Events.INIT_EVENT_JANK_MONITOR), - time(now + 350).named(RumConstants.Events.INIT_EVENT_SPAN_EXPORTER).withAttributes( + time(now + 250).named(RumConstants.Events.INIT_EVENT_JANK_MONITOR), + time(now + 300).named(RumConstants.Events.INIT_EVENT_SPAN_EXPORTER).withAttributes( "span.exporter", "com.cool.Exporter", ), diff --git a/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentationTest.kt b/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentationTest.kt new file mode 100644 index 000000000..bfb08daad --- /dev/null +++ b/instrumentation/startup/src/test/java/io/opentelemetry/android/instrumentation/startup/StartupInstrumentationTest.kt @@ -0,0 +1,63 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.android.instrumentation.startup + +import io.mockk.Called +import io.mockk.Runs +import io.mockk.every +import io.mockk.just +import io.mockk.mockk +import io.mockk.verify +import io.opentelemetry.android.OpenTelemetryRum +import io.opentelemetry.android.internal.initialization.InitializationEvents +import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension +import org.junit.jupiter.api.AfterEach +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.extension.RegisterExtension + +class StartupInstrumentationTest { + @JvmField + @RegisterExtension + val otelTesting = OpenTelemetryExtension.create() + private lateinit var instrumentation: StartupInstrumentation + + @BeforeEach + fun setUp() { + instrumentation = StartupInstrumentation() + } + + @AfterEach + fun tearDown() { + InitializationEvents.resetForTest() + } + + @Test + fun `Call finish on SdkInitializationEvents`() { + val sdkInitializationEvents = mockk() + val openTelemetryRum = mockk() + every { openTelemetryRum.openTelemetry }.returns(otelTesting.openTelemetry) + every { sdkInitializationEvents.finish(any()) } just Runs + InitializationEvents.set(sdkInitializationEvents) + + instrumentation.install(mockk(), openTelemetryRum) + + verify { + sdkInitializationEvents.finish(otelTesting.openTelemetry) + } + } + + @Test + fun `No action when the InitializationEvents instance is not SdkInitializationEvents`() { + val initializationEvents = mockk() + val openTelemetryRum = mockk() + InitializationEvents.set(initializationEvents) + + instrumentation.install(mockk(), openTelemetryRum) + + verify { initializationEvents wasNot Called } + } +}