From 5a66b7be4ee5fd5285e7a5c3a9ba317c2bf3c8d2 Mon Sep 17 00:00:00 2001 From: bidetofevil Date: Thu, 2 Jan 2025 16:27:13 -0800 Subject: [PATCH] Restructure assertions to remove magic numbers --- .../testcases/features/UiLoadTest.kt | 50 ++++++++++++------- .../actions/EmbraceActionInterface.kt | 29 ++++++----- 2 files changed, 49 insertions(+), 30 deletions(-) diff --git a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/UiLoadTest.kt b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/UiLoadTest.kt index e76204c21..badffa55b 100644 --- a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/UiLoadTest.kt +++ b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testcases/features/UiLoadTest.kt @@ -17,6 +17,10 @@ import io.embrace.android.embracesdk.internal.payload.ApplicationState import io.embrace.android.embracesdk.internal.payload.Span import io.embrace.android.embracesdk.spans.ErrorCode import io.embrace.android.embracesdk.testframework.IntegrationTestRule +import io.embrace.android.embracesdk.testframework.actions.EmbraceActionInterface.Companion.ACTIVITY_GAP +import io.embrace.android.embracesdk.testframework.actions.EmbraceActionInterface.Companion.LIFECYCLE_EVENT_GAP +import io.embrace.android.embracesdk.testframework.actions.EmbraceActionInterface.Companion.POST_ACTIVITY_ACTION_DWELL +import io.embrace.android.embracesdk.testframework.actions.EmbraceActionInterface.Companion.STARTUP_BACKGROUND_TIME import io.opentelemetry.api.trace.SpanId import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue @@ -108,11 +112,11 @@ internal class UiLoadTest { val trace = findSpansOfType(EmbType.Performance.UiLoad).single() assertEquals("emb-$MANUAL_STOP_ACTIVITY_NAME-cold-time-to-initial-display", trace.name) - val expectedTraceStartTime = preLaunchTimeMs + 50 + val expectedTraceStartTime = preLaunchTimeMs + calculateTotalTime(activityGaps = 1) assertEmbraceSpanData( span = trace, expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 400, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 4), expectedParentId = SpanId.getInvalid(), ) } @@ -147,11 +151,11 @@ internal class UiLoadTest { val trace = findSpansOfType(EmbType.Performance.UiLoad).single() assertEquals("emb-$MANUAL_STOP_ACTIVITY_NAME-cold-time-to-initial-display", trace.name) - val expectedTraceStartTime = preLaunchTimeMs + 50 + val expectedTraceStartTime = preLaunchTimeMs + ACTIVITY_GAP assertEmbraceSpanData( span = trace, expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 20301, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 3, activitiesFullyLoaded = 1), expectedParentId = SpanId.getInvalid(), expectedStatus = Span.Status.ERROR, expectedErrorCode = ErrorCode.USER_ABANDON, @@ -212,25 +216,27 @@ internal class UiLoadTest { val rootSpanId = checkNotNull(trace.spanId) assertEquals("emb-$ACTIVITY2_NAME-cold-time-to-initial-display", trace.name) - val expectedTraceStartTime = preLaunchTimeMs + 20351 + val expectedTraceStartTime = preLaunchTimeMs + + calculateTotalTime(lifecycleStages = 3, activitiesFullyLoaded = 1, activityGaps = 1) + assertEmbraceSpanData( span = trace, expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 200, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 2), expectedParentId = SpanId.getInvalid(), ) assertEmbraceSpanData( span = payload.findSpansByName("emb-${LifecycleStage.CREATE.spanName(ACTIVITY2_NAME)}").single(), expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 100, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), expectedParentId = rootSpanId, ) assertEmbraceSpanData( span = payload.findSpansByName("emb-${LifecycleStage.START.spanName(ACTIVITY2_NAME)}").single(), - expectedStartTimeMs = expectedTraceStartTime + 100, - expectedEndTimeMs = expectedTraceStartTime + 200, + expectedStartTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 2), expectedParentId = rootSpanId, ) } @@ -264,11 +270,11 @@ internal class UiLoadTest { assertEquals("emb-$ACTIVITY1_NAME-cold-time-to-initial-display", trace.name) val rootSpanId = checkNotNull(trace.spanId) - val expectedTraceStartTime = preLaunchTimeMs + 10000 + val expectedTraceStartTime = preLaunchTimeMs + calculateTotalTime(fromBackground = true) assertEmbraceSpanData( span = trace, expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 200, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 2), expectedParentId = SpanId.getInvalid(), ) @@ -278,14 +284,14 @@ internal class UiLoadTest { .findSpansByName("emb-${LifecycleStage.CREATE.spanName(ACTIVITY1_NAME)}") .single(), expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 100, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), expectedParentId = rootSpanId, ) assertEmbraceSpanData( span = payload.findSpansByName("emb-${LifecycleStage.START.spanName(ACTIVITY1_NAME)}").single(), - expectedStartTimeMs = expectedTraceStartTime + 100, - expectedEndTimeMs = expectedTraceStartTime + 200, + expectedStartTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 2), expectedParentId = rootSpanId, ) } @@ -319,18 +325,18 @@ internal class UiLoadTest { assertEquals("emb-$ACTIVITY1_NAME-hot-time-to-initial-display", trace.name) val rootSpanId = checkNotNull(trace.spanId) - val expectedTraceStartTime = preLaunchTimeMs + 10000 + val expectedTraceStartTime = preLaunchTimeMs + calculateTotalTime(fromBackground = true) assertEmbraceSpanData( span = trace, expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 100, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), expectedParentId = SpanId.getInvalid(), ) assertEmbraceSpanData( span = payload.findSpansByName("emb-${LifecycleStage.START.spanName(ACTIVITY1_NAME)}").single(), expectedStartTimeMs = expectedTraceStartTime, - expectedEndTimeMs = expectedTraceStartTime + 100, + expectedEndTimeMs = expectedTraceStartTime + calculateTotalTime(lifecycleStages = 1), expectedParentId = rootSpanId, ) } @@ -353,5 +359,15 @@ internal class UiLoadTest { val ACTIVITY1_NAME = Robolectric.buildActivity(Activity1::class.java).get().localClassName val ACTIVITY2_NAME = Robolectric.buildActivity(Activity2::class.java).get().localClassName val MANUAL_STOP_ACTIVITY_NAME = Robolectric.buildActivity(ManualStopActivity::class.java).get().localClassName + + fun calculateTotalTime( + lifecycleStages: Int = 0, + activitiesFullyLoaded: Int = 0, + activityGaps: Int = 0, + fromBackground: Boolean = false, + ): Long = lifecycleStages * LIFECYCLE_EVENT_GAP + + activitiesFullyLoaded * POST_ACTIVITY_ACTION_DWELL + + activityGaps * ACTIVITY_GAP + + if (fromBackground) STARTUP_BACKGROUND_TIME else 0 } } diff --git a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testframework/actions/EmbraceActionInterface.kt b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testframework/actions/EmbraceActionInterface.kt index 5fcb56164..2a221f23b 100644 --- a/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testframework/actions/EmbraceActionInterface.kt +++ b/embrace-android-sdk/src/integrationTest/kotlin/io/embrace/android/embracesdk/testframework/actions/EmbraceActionInterface.kt @@ -40,7 +40,7 @@ internal class EmbraceActionInterface( onForeground() // perform a custom action during the session boundary, e.g. adding a breadcrumb. - action() + this.action() // end session 30s later by entering background setup.overriddenClock.tick(30000) @@ -66,9 +66,6 @@ internal class EmbraceActionInterface( createFirstActivity: Boolean = true, invokeManualEnd: Boolean = false, activitiesAndActions: List, () -> Unit>> = listOf(), - lifecycleEventGap: Long = 100L, - postActionDwell: Long = 20000L, - activityGap: Long = 50L, ) { var lastActivity: ActivityController<*>? = if (addStartupActivity) { Robolectric.buildActivity(Activity::class.java) @@ -83,35 +80,34 @@ internal class EmbraceActionInterface( if (startInBackground) { stop() onBackground() - setup.overriddenClock.tick(10000L) + setup.overriddenClock.tick(STARTUP_BACKGROUND_TIME) } else { - setup.overriddenClock.tick(activityGap) + setup.overriddenClock.tick(ACTIVITY_GAP) } } activitiesAndActions.forEachIndexed { index, (activityController, action) -> if (index != 0 || createFirstActivity) { activityController.create() - setup.overriddenClock.tick(lifecycleEventGap) + setup.overriddenClock.tick(LIFECYCLE_EVENT_GAP) } activityController.start() - setup.overriddenClock.tick(lifecycleEventGap) + setup.overriddenClock.tick(LIFECYCLE_EVENT_GAP) if (index == 0 && startInBackground) { onForeground() } activityController.resume() - setup.overriddenClock.tick(lifecycleEventGap) + setup.overriddenClock.tick(LIFECYCLE_EVENT_GAP) if (invokeManualEnd) { - setup.overriddenClock.tick(lifecycleEventGap) + setup.overriddenClock.tick(LIFECYCLE_EVENT_GAP) embrace.activityLoaded(activityController.get()) } lastActivity?.stop() - setup.overriddenClock.tick() action() - setup.overriddenClock.tick(postActionDwell) + setup.overriddenClock.tick(POST_ACTIVITY_ACTION_DWELL) activityController.pause() - setup.overriddenClock.tick(activityGap) + setup.overriddenClock.tick(ACTIVITY_GAP) lastActivity = activityController } lastActivity?.stop() @@ -150,4 +146,11 @@ internal class EmbraceActionInterface( val dataSource = checkNotNull(bootstrapper.featureModule.thermalStateDataSource.dataSource) dataSource.handleThermalStateChange(thermalState) } + + companion object { + const val LIFECYCLE_EVENT_GAP: Long = 10L + const val ACTIVITY_GAP: Long = 100L + const val STARTUP_BACKGROUND_TIME: Long = 1000L + const val POST_ACTIVITY_ACTION_DWELL: Long = 10000L + } }