Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix manual session control enablement #1408

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ interface SessionBehavior {
fun isGatingFeatureEnabled(): Boolean

/**
* Whether session control is enabled, meaning that features should be gated.
* Whether session control is disabled, meaning that can't end sessions manually.
*/
fun isSessionControlEnabled(): Boolean
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can keep this as enabled at this level (app usage) so it matches the other kill switches. It's at the Config level that we should make this be identify itself as disabled

fun isSessionControlDisabled(): Boolean

/**
* Returns the maximum number of properties that can be attached to a session
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class SessionBehaviorImpl(

override fun isGatingFeatureEnabled(): Boolean = getSessionComponents() != null

override fun isSessionControlEnabled(): Boolean = remote?.sessionConfig?.isEnabled ?: false
override fun isSessionControlDisabled(): Boolean = remote?.disableSessionControl ?: false

override fun getMaxSessionProperties(): Int = remote?.maxSessionProperties ?: SESSION_PROPERTY_LIMIT

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ internal fun shouldEndManualSession(
): Boolean {
if (state == ProcessState.BACKGROUND) {
logger.logWarning("Cannot manually end session while in background.")
return true
return false
}
if (configService.sessionBehavior.isSessionControlEnabled()) {
logger.logWarning("Cannot manually end session while session control is enabled.")
return true
if (configService.sessionBehavior.isSessionControlDisabled()) {
logger.logWarning("Cannot manually end session while session control is disabled.")
return false
}
val initial = activeSession ?: return true
val initial = activeSession ?: return false
val startTime = initial.startTime
val delta = clock.now() - startTime
if (delta < MIN_SESSION_MS) {
Expand All @@ -37,9 +37,9 @@ internal fun shouldEndManualSession(
"This protects against instrumentation unintentionally creating too" +
"many sessions"
)
return true
return false
}
return false
return true
}

internal fun shouldRunOnBackground(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ internal class SessionOrchestratorImpl(
payloadFactory.startSessionWithManual(timestamp)
},
earlyTerminationCondition = {
return@transitionState shouldEndManualSession(
return@transitionState !shouldEndManualSession(
Copy link
Contributor Author

@nelsitoPuglisi nelsitoPuglisi Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

earlyTerminationCondition collects functions that prevent the execution.

configService,
clock,
activeSession,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ internal class EmbraceApiServiceTest {

// verify a few fields were serialized correctly.
checkNotNull(remoteConfig)
assertTrue(checkNotNull(remoteConfig.sessionConfig?.isEnabled))
assertFalse(checkNotNull(remoteConfig.disableSessionControl))
assertEquals(100, remoteConfig.threshold)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import org.junit.Test
internal class SessionBehaviorImplImplTest {

private val remote = RemoteConfig(
disableSessionControl = true,
sessionConfig = SessionRemoteConfig(
isEnabled = true,
sessionComponents = setOf("test"),
fullSessionEvents = setOf("test2")
),
Expand All @@ -26,7 +26,7 @@ internal class SessionBehaviorImplImplTest {
assertEquals(emptySet<String>(), getFullSessionEvents())
assertNull(getSessionComponents())
assertFalse(isGatingFeatureEnabled())
assertFalse(isSessionControlEnabled())
assertFalse(isSessionControlDisabled())
assertEquals(10, getMaxSessionProperties())
}
}
Expand All @@ -35,7 +35,7 @@ internal class SessionBehaviorImplImplTest {
fun testRemoteAndLocal() {
with(createSessionBehavior(remoteCfg = { remote })) {
assertTrue(isGatingFeatureEnabled())
assertTrue(isSessionControlEnabled())
assertTrue(isSessionControlDisabled())
assertEquals(setOf("test"), getSessionComponents())
assertEquals(setOf("test2"), getFullSessionEvents())
assertEquals(57, getMaxSessionProperties())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ internal class EmbraceGatingServiceV2PayloadTest {

private fun buildCustomRemoteConfig(components: Set<String>?, fullSessionEvents: Set<String>?) =
RemoteConfig(
disableSessionControl = false,
sessionConfig = SessionRemoteConfig(
isEnabled = true,
sessionComponents = components,
fullSessionEvents = fullSessionEvents
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ internal class EmbraceLogServiceTest {
remoteCfg = {
RemoteConfig(
sessionConfig = SessionRemoteConfig(
isEnabled = true,
sessionComponents = emptySet() // empty set will gate everything
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ internal class SessionOrchestratorTest {
}

@Test
fun `test manual session end disabled for session gating`() {
fun `test manual session end disabled`() {
configService = FakeConfigService(
sessionBehavior = FakeSessionBehavior(sessionControlEnabled = true)
sessionBehavior = FakeSessionBehavior(sessionControlDisabled = true)
)
createOrchestrator(false)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
"event_limits": {},
"offset": 0,
"personas": [],
"disable_session_control": false,
"session_control": {
"enable": true,
"async_end": false
},
"threshold": 100,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,12 @@ data class RemoteConfig(
@Json(name = "session_control")
val sessionConfig: SessionRemoteConfig? = null,

/**
* Settings defining if session control is disabled or not
*/
@Json(name = "disable_session_control")
val disableSessionControl: Boolean? = null,

/**
* Settings defining the log configuration.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,6 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class SessionRemoteConfig(
@Json(name = "enable")
val isEnabled: Boolean? = null,

/**
* A list of session components (i.e. Breadcrumbs, Session properties, etc) that will be
* included in the session payload. If components list exists, the services should restrict
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ internal class ManualSessionTest {
}

@Test
fun `calling endSession when session control enabled does not end sessions`() {
fun `calling endSession when session control disabled does not end sessions`() {
with(testRule) {
harness.overriddenConfigService.sessionBehavior = FakeSessionBehavior(sessionControlEnabled = true)
harness.overriddenConfigService.sessionBehavior = FakeSessionBehavior(sessionControlDisabled = true)
harness.recordSession {
harness.overriddenClock.tick(10000)
embrace.endSession()
Expand All @@ -66,7 +66,7 @@ internal class ManualSessionTest {
@Test
fun `calling endSession when state session is below 5s has no effect`() {
with(testRule) {
harness.overriddenConfigService.sessionBehavior = FakeSessionBehavior(sessionControlEnabled = true)
harness.overriddenConfigService.sessionBehavior = FakeSessionBehavior(sessionControlDisabled = true)
harness.recordSession {
harness.overriddenClock.tick(1000) // not enough to trigger new session
embrace.endSession()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import io.embrace.android.embracesdk.internal.config.behavior.SessionBehavior

class FakeSessionBehavior(
private val maxSessionProperties: Int = 100,
private val sessionControlEnabled: Boolean = false
private val sessionControlDisabled: Boolean = false
) : SessionBehavior {

override fun getFullSessionEvents(): Set<String> = emptySet()
override fun getSessionComponents(): Set<String>? = null
override fun isGatingFeatureEnabled(): Boolean = false
override fun isSessionControlEnabled(): Boolean = sessionControlEnabled
override fun isSessionControlDisabled(): Boolean = sessionControlDisabled
override fun getMaxSessionProperties(): Int = maxSessionProperties
override fun shouldGateMoment(): Boolean = false
override fun shouldGateInfoLog(): Boolean = false
Expand Down