Skip to content

Commit

Permalink
Merge pull request #561 from embrace-io/switch-collator
Browse files Browse the repository at this point in the history
Switch payload message collator depending on config
  • Loading branch information
fractalwrench authored Mar 14, 2024
2 parents 3ad0571 + 5d911c5 commit 7c7954a
Show file tree
Hide file tree
Showing 2 changed files with 113 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,16 @@ import io.embrace.android.embracesdk.session.orchestrator.SessionSnapshotType

internal class PayloadFactoryImpl(
private val v1payloadMessageCollator: V1PayloadMessageCollator,
@Suppress("UnusedPrivateProperty") private val v2payloadMessageCollator: V2PayloadMessageCollator,
private val v2payloadMessageCollator: V2PayloadMessageCollator,
private val configService: ConfigService
) : PayloadFactory {

private val collator: PayloadMessageCollator
get() = when {
configService.sessionBehavior.useV2Payload() -> v2payloadMessageCollator
else -> v1payloadMessageCollator
}

override fun startPayloadWithState(state: ProcessState, timestamp: Long, coldStart: Boolean) =
when (state) {
ProcessState.FOREGROUND -> startSessionWithState(timestamp, coldStart)
Expand Down Expand Up @@ -42,7 +48,7 @@ internal class PayloadFactoryImpl(
}

override fun startSessionWithManual(timestamp: Long): Session {
return v1payloadMessageCollator.buildInitialSession(
return collator.buildInitialSession(
InitialEnvelopeParams.SessionParams(
false,
LifeEventType.MANUAL,
Expand All @@ -52,7 +58,7 @@ internal class PayloadFactoryImpl(
}

override fun endSessionWithManual(timestamp: Long, initial: Session): SessionMessage {
return v1payloadMessageCollator.buildFinalSessionMessage(
return collator.buildFinalSessionMessage(
FinalEnvelopeParams.SessionParams(
initial = initial,
endTime = timestamp,
Expand All @@ -63,7 +69,7 @@ internal class PayloadFactoryImpl(
}

private fun startSessionWithState(timestamp: Long, coldStart: Boolean): Session {
return v1payloadMessageCollator.buildInitialSession(
return collator.buildInitialSession(
InitialEnvelopeParams.SessionParams(
coldStart,
LifeEventType.STATE,
Expand All @@ -83,7 +89,7 @@ internal class PayloadFactoryImpl(
coldStart -> timestamp
else -> timestamp + 1
}
return v1payloadMessageCollator.buildInitialSession(
return collator.buildInitialSession(
InitialEnvelopeParams.BackgroundActivityParams(
coldStart = coldStart,
startType = LifeEventType.BKGND_STATE,
Expand All @@ -93,7 +99,7 @@ internal class PayloadFactoryImpl(
}

private fun endSessionWithState(initial: Session, timestamp: Long): SessionMessage {
return v1payloadMessageCollator.buildFinalSessionMessage(
return collator.buildFinalSessionMessage(
FinalEnvelopeParams.SessionParams(
initial = initial,
endTime = timestamp,
Expand All @@ -110,7 +116,7 @@ internal class PayloadFactoryImpl(

// kept for backwards compat. the backend expects the start time to be 1 ms greater
// than the adjacent session, and manually adjusts.
return v1payloadMessageCollator.buildFinalBackgroundActivityMessage(
return collator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp - 1,
Expand All @@ -125,7 +131,7 @@ internal class PayloadFactoryImpl(
timestamp: Long,
crashId: String
): SessionMessage {
return v1payloadMessageCollator.buildFinalSessionMessage(
return collator.buildFinalSessionMessage(
FinalEnvelopeParams.SessionParams(
initial = initial,
endTime = timestamp,
Expand All @@ -144,7 +150,7 @@ internal class PayloadFactoryImpl(
if (!configService.isBackgroundActivityCaptureEnabled()) {
return null
}
return v1payloadMessageCollator.buildFinalBackgroundActivityMessage(
return collator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp,
Expand All @@ -159,7 +165,7 @@ internal class PayloadFactoryImpl(
* Called when the session is persisted every 2s to cache its state.
*/
private fun snapshotSession(initial: Session, timestamp: Long): SessionMessage {
return v1payloadMessageCollator.buildFinalSessionMessage(
return collator.buildFinalSessionMessage(
FinalEnvelopeParams.SessionParams(
initial = initial,
endTime = timestamp,
Expand All @@ -173,7 +179,7 @@ internal class PayloadFactoryImpl(
if (!configService.isBackgroundActivityCaptureEnabled()) {
return null
}
return v1payloadMessageCollator.buildFinalBackgroundActivityMessage(
return collator.buildFinalBackgroundActivityMessage(
FinalEnvelopeParams.BackgroundActivityParams(
initial = initial,
endTime = timestamp,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package io.embrace.android.embracesdk.session.message

import io.embrace.android.embracesdk.FakeBreadcrumbService
import io.embrace.android.embracesdk.FakeSessionPropertiesService
import io.embrace.android.embracesdk.capture.envelope.SessionEnvelopeSource
import io.embrace.android.embracesdk.config.remote.RemoteConfig
import io.embrace.android.embracesdk.config.remote.SessionRemoteConfig
import io.embrace.android.embracesdk.fakes.FakeConfigService
import io.embrace.android.embracesdk.fakes.FakeEnvelopeMetadataSource
import io.embrace.android.embracesdk.fakes.FakeEnvelopeResourceSource
import io.embrace.android.embracesdk.fakes.FakeEventService
import io.embrace.android.embracesdk.fakes.FakeInternalErrorService
import io.embrace.android.embracesdk.fakes.FakeLogMessageService
import io.embrace.android.embracesdk.fakes.FakeMetadataService
import io.embrace.android.embracesdk.fakes.FakePerformanceInfoService
import io.embrace.android.embracesdk.fakes.FakePreferenceService
import io.embrace.android.embracesdk.fakes.FakeSessionPayloadSource
import io.embrace.android.embracesdk.fakes.FakeStartupService
import io.embrace.android.embracesdk.fakes.FakeThermalStatusService
import io.embrace.android.embracesdk.fakes.FakeUserService
import io.embrace.android.embracesdk.fakes.FakeWebViewService
import io.embrace.android.embracesdk.fakes.fakeSessionBehavior
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.payload.LegacyExceptionError
import io.embrace.android.embracesdk.payload.isV2Payload
import io.embrace.android.embracesdk.session.lifecycle.ProcessState.FOREGROUND
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

internal class PayloadFactoryImplTest {

private var sessionConfig = SessionRemoteConfig()
private lateinit var factory: PayloadFactoryImpl

@Before
fun setUp() {
val configService = FakeConfigService(
sessionBehavior = fakeSessionBehavior(
remoteCfg = {
RemoteConfig(sessionConfig = sessionConfig)
}
)
)
val initModule = FakeInitModule()
val v1Collator = V1PayloadMessageCollator(
configService = FakeConfigService(),
nativeThreadSamplerService = null,
thermalStatusService = FakeThermalStatusService(),
webViewService = FakeWebViewService(),
userService = FakeUserService(),
preferencesService = FakePreferenceService(),
eventService = FakeEventService(),
logMessageService = FakeLogMessageService(),
internalErrorService = FakeInternalErrorService().apply {
currentExceptionError = LegacyExceptionError()
},
breadcrumbService = FakeBreadcrumbService(),
metadataService = FakeMetadataService(),
performanceInfoService = FakePerformanceInfoService(),
spanSink = initModule.openTelemetryModule.spanSink,
currentSessionSpan = initModule.openTelemetryModule.currentSessionSpan,
sessionPropertiesService = FakeSessionPropertiesService(),
startupService = FakeStartupService()
)
val v2Collator = V2PayloadMessageCollator(
v1Collator,
SessionEnvelopeSource(
FakeEnvelopeMetadataSource(),
FakeEnvelopeResourceSource(),
FakeSessionPayloadSource()
)
)
factory = PayloadFactoryImpl(
v1payloadMessageCollator = v1Collator,
v2payloadMessageCollator = v2Collator,
configService = configService
)
}

@Test
fun `legacy payload generated`() {
val session = checkNotNull(factory.startPayloadWithState(FOREGROUND, 0, false))
val sessionMessage = checkNotNull(factory.endPayloadWithState(FOREGROUND, 0, session))
assertFalse(sessionMessage.isV2Payload())
}

@Test
fun `v2 payload generated`() {
sessionConfig = SessionRemoteConfig(useV2Payload = true)
val session = checkNotNull(factory.startPayloadWithState(FOREGROUND, 0, false))
val sessionMessage = checkNotNull(factory.endPayloadWithState(FOREGROUND, 0, session))
assertTrue(sessionMessage.isV2Payload())
}
}

0 comments on commit 7c7954a

Please sign in to comment.