Skip to content

Commit

Permalink
Improve FakeDeliveryService to better differentiate sessions and back…
Browse files Browse the repository at this point in the history
…ground activities
  • Loading branch information
bidetofevil committed May 16, 2024
1 parent 248a719 commit 6f043d8
Show file tree
Hide file tree
Showing 13 changed files with 76 additions and 71 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import io.embrace.android.embracesdk.internal.utils.Provider
import io.embrace.android.embracesdk.logging.InternalErrorService
import io.embrace.android.embracesdk.payload.EventMessage
import io.embrace.android.embracesdk.payload.SessionMessage
import java.io.IOException
import org.json.JSONObject
import org.junit.Assert
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.robolectric.Robolectric
import java.io.IOException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
import org.json.JSONObject
import org.junit.Assert

/*** Extension functions that are syntactic sugar for retrieving information from the SDK. ***/

Expand Down Expand Up @@ -98,29 +98,29 @@ internal fun IntegrationTestRule.Harness.getLastSentLogMessage(expectedSize: Int
/**
* Returns a list of [SessionMessage] that were sent by the SDK since startup.
*/
internal fun IntegrationTestRule.Harness.getSentSessionMessages(): List<SessionMessage> {
return overriddenDeliveryModule.deliveryService.lastSentSessions.map { it.first }.filter { it.session.appState == "foreground" }
internal fun IntegrationTestRule.Harness.getSentSessions(): List<SessionMessage> {
return overriddenDeliveryModule.deliveryService.getSentSessions()
}

/**
* Returns a list of [BackgroundActivityMessage] that were sent by the SDK since startup.
*/
internal fun IntegrationTestRule.Harness.getSentBackgroundActivities(): List<SessionMessage> {
return overriddenDeliveryModule.deliveryService.lastSentSessions.map { it.first }.filter { it.session.appState == "background" }
return overriddenDeliveryModule.deliveryService.getSentBackgroundActivities()
}

/**
* Returns the last [SessionMessage] that was saved by the SDK.
*/
internal fun IntegrationTestRule.Harness.getLastSavedSessionMessage(): SessionMessage? {
return overriddenDeliveryModule.deliveryService.lastSavedSession
internal fun IntegrationTestRule.Harness.getLastSavedSession(): SessionMessage? {
return overriddenDeliveryModule.deliveryService.getLastSavedSession()
}

/**
* Returns the last [SessionMessage] that was sent by the SDK.
*/
internal fun IntegrationTestRule.Harness.getLastSentSessionMessage(): SessionMessage? {
return getSentSessionMessages().lastOrNull()
internal fun IntegrationTestRule.Harness.getLastSentSession(): SessionMessage? {
return getSentSessions().lastOrNull()
}

/**
Expand Down Expand Up @@ -155,7 +155,7 @@ internal fun IntegrationTestRule.Harness.recordSession(
activityController?.pause()
activityController?.stop()
activityService.onBackground()
return getLastSentSessionMessage()
return getLastSentSession()
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.config.remote.SessionRemoteConfig
import io.embrace.android.embracesdk.fakes.fakeSessionBehavior
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.getSentSessions
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifySessionHappened
import org.junit.Assert.assertEquals
Expand All @@ -27,7 +27,7 @@ internal class ManualSessionTest {

@Before
fun setUp() {
assertTrue(testRule.harness.getSentSessionMessages().isEmpty())
assertTrue(testRule.harness.getSentSessions().isEmpty())
}

@Test
Expand All @@ -37,7 +37,7 @@ internal class ManualSessionTest {
harness.overriddenClock.tick(10000) // enough to trigger new session
embrace.endSession()
}
val messages = harness.getSentSessionMessages()
val messages = harness.getSentSessions()
assertEquals(2, messages.size)
val stateSession = messages[0] // started via state, ended manually
val manualSession = messages[1] // started manually, ended via state
Expand All @@ -58,7 +58,7 @@ internal class ManualSessionTest {
harness.overriddenClock.tick(10000)
embrace.endSession()
}
val messages = harness.getSentSessionMessages()
val messages = harness.getSentSessions()
assertEquals(1, messages.size)
verifySessionHappened(messages[0])
}
Expand All @@ -74,7 +74,7 @@ internal class ManualSessionTest {
harness.overriddenClock.tick(1000) // not enough to trigger new session
embrace.endSession()
}
val message = harness.getSentSessionMessages().single()
val message = harness.getSentSessions().single()
verifySessionHappened(message)
assertEquals(1, message.session.number)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import io.embrace.android.embracesdk.findSessionSpan
import io.embrace.android.embracesdk.gating.EmbraceGatingService
import io.embrace.android.embracesdk.gating.GatingService
import io.embrace.android.embracesdk.gating.SessionGatingKeys
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.getSentSessions
import io.embrace.android.embracesdk.hasEventOfType
import io.embrace.android.embracesdk.hasSpanOfType
import io.embrace.android.embracesdk.logging.EmbLoggerImpl
Expand Down Expand Up @@ -67,7 +67,7 @@ internal class OtelSessionGatingTest {

@Before
fun setUp() {
assertTrue(testRule.harness.getSentSessionMessages().isEmpty())
assertTrue(testRule.harness.getSentSessions().isEmpty())
}

@Test
Expand All @@ -76,7 +76,7 @@ internal class OtelSessionGatingTest {

with(testRule) {
simulateSession()
val payload = harness.getSentSessionMessages().single()
val payload = harness.getSentSessions().single()
verifySessionHappened(payload)
assertSessionGating(payload, gated = false)
}
Expand All @@ -94,7 +94,7 @@ internal class OtelSessionGatingTest {

with(testRule) {
simulateSession()
val payload = harness.getSentSessionMessages().single()
val payload = harness.getSentSessions().single()
verifySessionHappened(payload)
assertSessionGating(payload, gated = true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.fakes.FakeClock
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.fakes.injection.FakeWorkerThreadModule
import io.embrace.android.embracesdk.getLastSavedSessionMessage
import io.embrace.android.embracesdk.getLastSentSessionMessage
import io.embrace.android.embracesdk.getLastSavedSession
import io.embrace.android.embracesdk.getLastSentSession
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.worker.WorkerName.PERIODIC_CACHE
import org.junit.Assert.assertEquals
Expand Down Expand Up @@ -42,22 +42,22 @@ internal class PeriodicSessionCacheTest {
executor.runCurrentlyBlocked()
embrace.addSessionProperty("Test", "Test", true)

var endMessage = checkNotNull(harness.getLastSavedSessionMessage())
var endMessage = checkNotNull(harness.getLastSavedSession())
assertEquals("en", endMessage.session.messageType)
assertEquals(false, endMessage.session.isEndedCleanly)
assertEquals(true, endMessage.session.isReceivedTermination)
assertEquals(0, endMessage.session.properties?.size)

// trigger another periodic cache
executor.moveForwardAndRunBlocked(2000)
endMessage = checkNotNull(harness.getLastSavedSessionMessage())
endMessage = checkNotNull(harness.getLastSavedSession())
assertEquals("en", endMessage.session.messageType)
assertEquals(false, endMessage.session.isEndedCleanly)
assertEquals(true, endMessage.session.isReceivedTermination)
assertEquals("Test", checkNotNull(endMessage.session.properties)["Test"])
}

val endMessage = checkNotNull(harness.getLastSentSessionMessage())
val endMessage = checkNotNull(harness.getLastSentSession())
assertEquals("en", endMessage.session.messageType)
assertEquals(true, endMessage.session.isEndedCleanly)
assertNull(endMessage.session.isReceivedTermination)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@ package io.embrace.android.embracesdk.session

import androidx.test.ext.junit.runners.AndroidJUnit4
import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.fakes.fakeDataCaptureEventBehavior
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.internal.MessageType
import io.embrace.android.embracesdk.recordSession
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.embrace.android.embracesdk.session

import androidx.test.ext.junit.runners.AndroidJUnit4
import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.getSentSessions
import io.embrace.android.embracesdk.payload.Session.LifeEventType
import io.embrace.android.embracesdk.recordSession
import io.embrace.android.embracesdk.verifySessionHappened
Expand All @@ -26,7 +26,7 @@ internal class StatefulSessionTest {

@Before
fun setUp() {
assertTrue(testRule.harness.getSentSessionMessages().isEmpty())
assertTrue(testRule.harness.getSentSessions().isEmpty())
}

@Test
Expand All @@ -40,7 +40,7 @@ internal class StatefulSessionTest {
harness.recordSession { }

// verify first session
val messages = testRule.harness.getSentSessionMessages()
val messages = testRule.harness.getSentSessions()
val first = messages[0]
verifySessionHappened(first)
assertEquals(LifeEventType.STATE, first.session.startType)
Expand All @@ -59,7 +59,7 @@ internal class StatefulSessionTest {
harness.recordSession {
harness.recordSession()
}
val messages = testRule.harness.getSentSessionMessages()
val messages = testRule.harness.getSentSessions()

// TODO: future the logic seems wrong here - nested calls should probably be ignored
// and should not drop a session. However, it's an unlikely scenario (if we trust)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.fakes.fakeOTelBehavior
import io.embrace.android.embracesdk.findLogAttribute
import io.embrace.android.embracesdk.getLastSentLog
import io.embrace.android.embracesdk.getLastSentSessionMessage
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.getLastSentSession
import io.embrace.android.embracesdk.getSentSessions
import io.embrace.android.embracesdk.internal.serialization.EmbraceSerializer
import io.embrace.android.embracesdk.internal.utils.getSafeStackTrace
import io.embrace.android.embracesdk.payload.LegacyExceptionInfo
Expand All @@ -36,7 +36,7 @@ internal class CrashTest {

@Before
fun setup() {
assertTrue(testRule.harness.getSentSessionMessages().isEmpty())
assertTrue(testRule.harness.getSentSessions().isEmpty())
testRule.harness.overriddenConfigService.oTelBehavior = fakeOTelBehavior {
RemoteConfig(oTelConfig = OTelRemoteConfig(isBetaEnabled = true))
}
Expand Down Expand Up @@ -68,7 +68,7 @@ internal class CrashTest {
assertEquals(expectedExceptionCause, log?.findLogAttribute("emb.android.crash.exception_cause"))
assertNotNull(log?.findLogAttribute("emb.android.threads"))

val message = checkNotNull(testRule.harness.getLastSentSessionMessage())
val message = checkNotNull(testRule.harness.getLastSentSession())
verifySessionHappened(message)
assertNotNull(message.session.crashReportId)
assertEquals(message.session.crashReportId, log?.findLogAttribute("log.record.uid"))
Expand Down Expand Up @@ -111,7 +111,7 @@ internal class CrashTest {
assertEquals(expectedExceptionCause, log?.findLogAttribute("emb.android.crash.exception_cause"))
assertNotNull(log?.findLogAttribute("emb.android.threads"))

val message = checkNotNull(testRule.harness.getLastSentSessionMessage())
val message = checkNotNull(testRule.harness.getLastSentSession())
verifySessionHappened(message)
assertNotNull(message.session.crashReportId)
assertEquals(message.session.crashReportId, log?.findLogAttribute("log.record.uid"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package io.embrace.android.embracesdk.testcases
import android.os.Build
import androidx.test.ext.junit.runners.AndroidJUnit4
import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.getLastSentSessionMessage
import io.embrace.android.embracesdk.getLastSentSession
import io.embrace.android.embracesdk.internal.clock.millisToNanos
import io.embrace.android.embracesdk.internal.network.http.NetworkCaptureData
import io.embrace.android.embracesdk.internal.spans.EmbraceSpanData
Expand Down Expand Up @@ -226,7 +226,7 @@ internal class NetworkRequestApiTest {
embrace.recordNetworkRequest(request)
}

val session = checkNotNull(testRule.harness.getLastSentSessionMessage())
val session = checkNotNull(testRule.harness.getLastSentSession())

val spans = checkNotNull(session.spans?.filter { it.attributes.containsKey("http.request.method") })
assertEquals(
Expand Down Expand Up @@ -275,7 +275,7 @@ internal class NetworkRequestApiTest {
}

private fun validateAndReturnExpectedNetworkSpan(): EmbraceSpanData {
val session = checkNotNull(testRule.harness.getLastSentSessionMessage())
val session = checkNotNull(testRule.harness.getLastSentSession())

val spans = checkNotNull(session.spans?.filter { it.attributes.containsKey("http.request.method") })
assertEquals(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import io.embrace.android.embracesdk.config.local.SdkLocalConfig
import io.embrace.android.embracesdk.fakes.fakeBreadcrumbBehavior
import io.embrace.android.embracesdk.findEventOfType
import io.embrace.android.embracesdk.findSessionSpan
import io.embrace.android.embracesdk.getSentSessionMessages
import io.embrace.android.embracesdk.getSentSessions
import io.embrace.android.embracesdk.recordSession
import org.junit.Assert
import org.junit.Rule
Expand Down Expand Up @@ -80,7 +80,7 @@ internal class PushNotificationTest {
}

private fun IntegrationTestRule.assertNotification(type: String) {
val payload = harness.getSentSessionMessages().single()
val payload = harness.getSentSessions().single()
val sessionSpan = payload.findSessionSpan()
Assert.assertNotNull(sessionSpan)
val event = sessionSpan.findEventOfType(EmbType.System.PushNotification)
Expand Down Expand Up @@ -112,7 +112,7 @@ internal class PushNotificationTest {
embrace.logPushNotification("title", "body", "from", "id", 1, 2, true, true)
}

val payload = harness.getSentSessionMessages().single()
val payload = harness.getSentSessions().single()
val sessionSpan = payload.findSessionSpan()
Assert.assertNotNull(sessionSpan)
val event = sessionSpan.findEventOfType(EmbType.System.PushNotification)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,22 @@ import io.embrace.android.embracesdk.session.orchestrator.SessionSnapshotType
internal open class FakeDeliveryService : DeliveryService {
var lastSentNetworkCall: NetworkEvent? = null
var lastSentCrash: EventMessage? = null
var lastSentEvent: EventMessage? = null
val lastSentLogs: MutableList<EventMessage> = mutableListOf()
val lastSentLogPayloads: MutableList<Envelope<LogPayload>> = mutableListOf()
val lastSavedLogPayloads: MutableList<Envelope<LogPayload>> = mutableListOf()
val sentMoments: MutableList<EventMessage> = mutableListOf()
var sendBackgroundActivitiesInvokedCount: Int = 0
var lastSentBackgroundActivities: MutableList<SessionMessage> = mutableListOf()
var saveBackgroundActivityInvokedCount: Int = 0
var lastSavedBackgroundActivities: MutableList<SessionMessage> = mutableListOf()
var lastEventSentAsync: EventMessage? = null
var eventSentAsyncInvokedCount: Int = 0
var lastSavedCrash: EventMessage? = null
var lastSentCachedSession: String? = null
var lastSavedSession: SessionMessage? = null
var lastSnapshotType: SessionSnapshotType? = null
val lastSentSessions: MutableList<Pair<SessionMessage, SessionSnapshotType>> = mutableListOf()
val sentSessionMessages: MutableList<Pair<SessionMessage, SessionSnapshotType>> = mutableListOf()
val lastSavedSessionMessages: MutableList<Pair<SessionMessage, SessionSnapshotType>> = mutableListOf()

override fun sendSession(sessionMessage: SessionMessage, snapshotType: SessionSnapshotType) {
if (snapshotType != SessionSnapshotType.PERIODIC_CACHE) {
lastSentSessions.add(sessionMessage to snapshotType)
sentSessionMessages.add(sessionMessage to snapshotType)
}
lastSavedSession = sessionMessage
lastSnapshotType = snapshotType
lastSavedSessionMessages.add(sessionMessage to snapshotType)
}

override fun sendCachedSessions(
Expand Down Expand Up @@ -76,4 +69,20 @@ internal open class FakeDeliveryService : DeliveryService {
lastSavedCrash = crash
lastSentCrash = crash
}

fun getSentSessions(): List<SessionMessage> {
return sentSessionMessages.map { it.first }.filter { it.session.appState == "foreground" }
}

fun getSentBackgroundActivities(): List<SessionMessage> {
return sentSessionMessages.map { it.first }.filter { it.session.appState == "background" }
}

fun getLastSavedSession(): SessionMessage? {
return lastSavedSessionMessages.map { it.first }.lastOrNull { it.session.appState == "foreground" }
}

fun getLastSentSession(): SessionMessage? {
return getSentSessions().lastOrNull()
}
}

0 comments on commit 6f043d8

Please sign in to comment.