Skip to content

Commit

Permalink
Changes for the 6.9.2 patch (#1173)
Browse files Browse the repository at this point in the history
  • Loading branch information
bidetofevil authored Aug 1, 2024
1 parent ae04cd4 commit d3441ae
Show file tree
Hide file tree
Showing 9 changed files with 134 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.embrace.android.embracesdk.session

import androidx.test.ext.junit.runners.AndroidJUnit4
import io.embrace.android.embracesdk.IntegrationTestRule
import io.embrace.android.embracesdk.recordSession
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@RunWith(AndroidJUnit4::class)
internal class SessionSpanTest {

@Rule
@JvmField
val testRule: IntegrationTestRule = IntegrationTestRule {
IntegrationTestRule.Harness(startImmediately = false)
}

@Test
fun `there is always a valid session when background activity is enabled`() {
with(testRule) {
harness.overriddenConfigService.backgroundActivityCaptureEnabled = true
startSdk()
checkNotNull(harness.recordSession {
assertFalse(embrace.currentSessionId.isNullOrBlank())
})
assertFalse(embrace.currentSessionId.isNullOrBlank())
checkNotNull(harness.recordSession {
assertFalse(embrace.currentSessionId.isNullOrBlank())
})
}
}

@Test
fun `no valid session when bg activity not enabled after backgrounding`() {
with(testRule) {
harness.overriddenConfigService.backgroundActivityCaptureEnabled = false
startSdk()
checkNotNull(harness.recordSession {
assertFalse(embrace.currentSessionId.isNullOrBlank())
})
assertTrue(embrace.currentSessionId.isNullOrBlank())
checkNotNull(harness.recordSession {
assertFalse(embrace.currentSessionId.isNullOrBlank())
})
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ import io.embrace.android.embracesdk.spans.EmbraceSpan
* Abstraction of the current session span
*/
internal interface CurrentSessionSpan : Initializable, SessionSpanWriter {
/**
* Ensure there exists a session span that is ready to take in data, and create one if it's possible.
* Returns true if an active session span exists at the time the method returns.
*/
fun readySession(): Boolean

/**
* End the current session span and start a new one if the app is not terminating
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,18 @@ internal class CurrentSessionSpanImpl(
return sessionSpan.get()?.getSystemAttribute(embSessionId) ?: ""
}

override fun readySession(): Boolean {
if (sessionSpan.get() == null) {
synchronized(sessionSpan) {
if (sessionSpan.get() == null) {
sessionSpan.set(startSessionSpan(openTelemetryClock.now().nanosToMillis()))
return sessionSpanReady()
}
}
}
return sessionSpanReady()
}

override fun endSession(startNewSession: Boolean, appTerminationCause: AppTerminationCause?): List<EmbraceSpanData> {
synchronized(sessionSpan) {
val endingSessionSpan = sessionSpan.get()
Expand Down Expand Up @@ -161,4 +173,6 @@ internal class CurrentSessionSpanImpl(
setSystemAttribute(embSessionId, Uuid.getEmbUuid())
}
}

private fun sessionSpanReady() = sessionSpan.get()?.isRecording ?: false
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ internal class PayloadFactoryImpl(
initial = initial,
endType = SessionSnapshotType.NORMAL_END,
logger = logger,
backgroundActivityEnabled = isBackgroundActivityEnabled(),
backgroundActivityEnabled = true,
)
)
}
Expand Down Expand Up @@ -135,7 +135,7 @@ internal class PayloadFactoryImpl(
initial = initial,
endType = SessionSnapshotType.JVM_CRASH,
logger = logger,
backgroundActivityEnabled = isBackgroundActivityEnabled(),
backgroundActivityEnabled = true,
crashId = crashId
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ internal class PayloadMessageCollatorImpl(
) : PayloadMessageCollator {

override fun buildInitialSession(params: InitialEnvelopeParams) = with(params) {
currentSessionSpan.readySession()
SessionZygote(
sessionId = currentSessionSpan.getSessionId(),
startTime = startTime,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ internal class FakeCurrentSessionSpan(
return true
}

override fun readySession(): Boolean {
sessionSpan = newSessionSpan(clock.now())
return true
}

override fun endSession(startNewSession: Boolean, appTerminationCause: AppTerminationCause?): List<EmbraceSpanData> {
val endingSessionSpan = checkNotNull(sessionSpan)
endingSessionSpan.endTimeNanos = clock.nowInNanos()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,14 @@ import io.embrace.android.embracesdk.session.orchestrator.SessionSnapshotType
internal class FakeSessionPayloadSource : SessionPayloadSource {

var sessionPayload: SessionPayload = SessionPayload()
override fun getSessionPayload(endType: SessionSnapshotType, startNewSession: Boolean, crashId: String?) = sessionPayload
var lastStartNewSession: Boolean? = null

override fun getSessionPayload(
endType: SessionSnapshotType,
startNewSession: Boolean,
crashId: String?
): SessionPayload {
lastStartNewSession = startNewSession
return SessionPayload()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,35 @@ import io.embrace.android.embracesdk.fakes.FakeGatingService
import io.embrace.android.embracesdk.fakes.FakePreferenceService
import io.embrace.android.embracesdk.fakes.FakeSessionPayloadSource
import io.embrace.android.embracesdk.fakes.injection.FakeInitModule
import io.embrace.android.embracesdk.session.lifecycle.ProcessState
import io.embrace.android.embracesdk.session.lifecycle.ProcessState.BACKGROUND
import io.embrace.android.embracesdk.session.lifecycle.ProcessState.FOREGROUND
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Test

internal class PayloadFactoryImplTest {

private lateinit var configService: FakeConfigService
private lateinit var sessionPayloadSource: FakeSessionPayloadSource
private lateinit var factory: PayloadFactoryImpl

@Before
fun setUp() {
val configService = FakeConfigService()
val initModule = FakeInitModule()
configService = FakeConfigService()
sessionPayloadSource = FakeSessionPayloadSource()
val collator = PayloadMessageCollatorImpl(
gatingService = FakeGatingService(),
preferencesService = FakePreferenceService(),
currentSessionSpan = initModule.openTelemetryModule.currentSessionSpan,
sessionEnvelopeSource = SessionEnvelopeSourceImpl(
FakeEnvelopeMetadataSource(),
FakeEnvelopeResourceSource(),
FakeSessionPayloadSource()
sessionPayloadSource
)
)
factory = PayloadFactoryImpl(
Expand All @@ -42,4 +51,38 @@ internal class PayloadFactoryImplTest {
val session = checkNotNull(factory.startPayloadWithState(FOREGROUND, 0, false))
checkNotNull(factory.endPayloadWithState(FOREGROUND, 0, session))
}

@Test
fun `verify expected payloads with ba enabled`() {
configService.backgroundActivityCaptureEnabled = true
verifyPayloadWithState(state = FOREGROUND, zygoteCreated = true, startNewSession = true)
verifyPayloadWithState(state = BACKGROUND, zygoteCreated = true, startNewSession = true)
verifyPayloadWithManual()
}

@Test
fun `verify expected payloads with ba disabled`() {
configService.backgroundActivityCaptureEnabled = false
verifyPayloadWithState(state = FOREGROUND, zygoteCreated = true, startNewSession = false)
verifyPayloadWithState(state = BACKGROUND, zygoteCreated = false, startNewSession = false)
verifyPayloadWithManual()
}

private fun verifyPayloadWithState(state: ProcessState, zygoteCreated: Boolean, startNewSession: Boolean) {
val zygote = factory.startPayloadWithState(state, 0, false)
if (zygoteCreated) {
assertTrue(checkNotNull(zygote).sessionId.isNotBlank())
assertNotNull(factory.endPayloadWithState(state, 0, zygote))
assertEquals(startNewSession, sessionPayloadSource.lastStartNewSession)
} else {
assertNull(zygote)
}
}

private fun verifyPayloadWithManual() {
val zygote = factory.startSessionWithManual(0)
assertTrue(zygote.sessionId.isNotBlank())
assertNotNull(factory.endSessionWithManual(0, zygote))
assertEquals(true, sessionPayloadSource.lastStartNewSession)
}
}
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
org.gradle.parallel=true
version = 6.9.1
version = 6.9.2
android.useAndroidX=true
# Enable adding baseline-prof.txt files to AAR artifacts.
android.experimental.enableArtProfiles=true
Expand Down

0 comments on commit d3441ae

Please sign in to comment.