Skip to content

Populate sampling rate in session event #4891

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

Merged
merged 4 commits into from
Apr 14, 2023
Merged
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 @@ -60,7 +60,7 @@ internal constructor(

private fun initiateSessionStart() {
val sessionDetails = sessionGenerator.generateNewSession()
val sessionEvent = SessionEvents.startSession(firebaseApp, sessionDetails)
val sessionEvent = SessionEvents.startSession(firebaseApp, sessionDetails, sessionSettings)

if (sessionDetails.collectEvents) {
sessionCoordinator.attemptLoggingSessionEvent(sessionEvent)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.google.firebase.encoders.DataEncoder
import com.google.firebase.encoders.FieldDescriptor
import com.google.firebase.encoders.ObjectEncoderContext
import com.google.firebase.encoders.json.JsonDataEncoderBuilder
import com.google.firebase.sessions.settings.SessionsSettings

/**
* Contains functions for [SessionEvent]s.
Expand Down Expand Up @@ -103,7 +104,8 @@ internal object SessionEvents {
fun startSession(
firebaseApp: FirebaseApp,
sessionDetails: SessionDetails,
currentTimeUs: Long = WallClock.currentTimeUs(),
sessionsSettings: SessionsSettings,
currentTimeUs: Long = WallClock.currentTimeUs()
) =
SessionEvent(
eventType = EventType.SESSION_START,
Expand All @@ -113,6 +115,7 @@ internal object SessionEvents {
sessionDetails.firstSessionId,
sessionDetails.sessionIndex,
currentTimeUs,
DataCollectionStatus(sessionSamplingRate = sessionsSettings.samplingRate),
),
applicationInfo = getApplicationInfo(firebaseApp)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class ApplicationInfoTest {

@Test
fun applicationInfo_populatesInfoCorrectly() {
val applicationInfo = SessionEvents.getApplicationInfo(FakeFirebaseApp.fakeFirebaseApp())
val applicationInfo = SessionEvents.getApplicationInfo(FakeFirebaseApp().firebaseApp)
assertThat(applicationInfo)
.isEqualTo(
ApplicationInfo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import com.google.android.datatransport.Event
import com.google.android.datatransport.TransportFactory
import com.google.common.truth.Truth.assertThat
import com.google.firebase.FirebaseApp
import com.google.firebase.sessions.settings.SessionsSettings
import com.google.firebase.sessions.testing.FakeFirebaseApp
import com.google.firebase.sessions.testing.FakeProvider
import com.google.firebase.sessions.testing.FakeTransportFactory
Expand All @@ -35,10 +36,12 @@ class EventGDTLoggerTest {

@Test
fun event_logsToGoogleDataTransport() {
val fakeFirebaseApp = FakeFirebaseApp()
val sessionEvent =
SessionEvents.startSession(
FakeFirebaseApp.fakeFirebaseApp(),
fakeFirebaseApp.firebaseApp,
TestSessionEventData.TEST_SESSION_DETAILS,
SessionsSettings(fakeFirebaseApp.firebaseApp.applicationContext),
TestSessionEventData.TEST_SESSION_TIMESTAMP_US,
)
val fakeTransportFactory = FakeTransportFactory()
Expand All @@ -50,7 +53,7 @@ class EventGDTLoggerTest {
assertThat(fakeTransportFactory.name).isEqualTo("FIREBASE_APPQUALITY_SESSION")
assertThat(fakeTransportFactory.payloadEncoding).isEqualTo(Encoding.of("json"))
assertThat(fakeTransportFactory.fakeTransport!!.sentEvent)
.isEqualTo(Event.ofData(TestSessionEventData.EXPECTED_DEFAULT_SESSION_EVENT))
.isEqualTo(Event.ofData(TestSessionEventData.TEST_SESSION_EVENT))
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class LocalOverrideSettingsTest {

@Test
fun localOverrides_returnsNullByDefault() {
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext

val localSettings = LocalOverrideSettings(context)
assertThat(localSettings.sessionEnabled).isNull()
Expand All @@ -46,7 +46,7 @@ class LocalOverrideSettingsTest {
metadata.putBoolean("firebase_sessions_enabled", false)
metadata.putDouble("firebase_sessions_sampling_rate", 0.5)
metadata.putInt("firebase_sessions_sessions_restart_timeout", 180)
val context = FakeFirebaseApp.fakeFirebaseApp(metadata).applicationContext
val context = FakeFirebaseApp(metadata).firebaseApp.applicationContext

val localSettings = LocalOverrideSettings(context)
assertThat(localSettings.sessionEnabled).isFalse()
Expand All @@ -59,7 +59,7 @@ class LocalOverrideSettingsTest {
val metadata = Bundle()
metadata.putBoolean("firebase_sessions_enabled", false)
metadata.putInt("firebase_sessions_sessions_restart_timeout", 180)
val context = FakeFirebaseApp.fakeFirebaseApp(metadata).applicationContext
val context = FakeFirebaseApp(metadata).firebaseApp.applicationContext

val localSettings = LocalOverrideSettings(context)
assertThat(localSettings.sessionEnabled).isFalse()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package com.google.firebase.sessions

import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.google.firebase.sessions.settings.SessionsSettings
import com.google.firebase.sessions.testing.FakeEventGDTLogger
import com.google.firebase.sessions.testing.FakeFirebaseApp
import com.google.firebase.sessions.testing.FakeFirebaseInstallations
Expand All @@ -43,10 +44,12 @@ class SessionCoordinatorTest {
)

// Construct an event with no fid set.
val fakeFirebaseApp = FakeFirebaseApp()
val sessionEvent =
SessionEvents.startSession(
FakeFirebaseApp.fakeFirebaseApp(),
fakeFirebaseApp.firebaseApp,
TestSessionEventData.TEST_SESSION_DETAILS,
SessionsSettings(fakeFirebaseApp.firebaseApp.applicationContext),
TestSessionEventData.TEST_SESSION_TIMESTAMP_US,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.google.common.truth.Truth.assertThat
import com.google.firebase.FirebaseApp
import com.google.firebase.sessions.SessionEvents.SESSION_EVENT_ENCODER
import com.google.firebase.sessions.settings.SessionsSettings
import com.google.firebase.sessions.testing.FakeFirebaseApp
import com.google.firebase.sessions.testing.TestSessionEventData
import org.junit.After
Expand All @@ -36,10 +37,12 @@ class SessionEventEncoderTest {

@Test
fun sessionEvent_encodesToJson() {
val fakeFirebaseApp = FakeFirebaseApp()
val sessionEvent =
SessionEvents.startSession(
FakeFirebaseApp.fakeFirebaseApp(),
fakeFirebaseApp.firebaseApp,
TestSessionEventData.TEST_SESSION_DETAILS,
SessionsSettings(fakeFirebaseApp.firebaseApp.applicationContext),
TestSessionEventData.TEST_SESSION_TIMESTAMP_US,
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,16 @@

package com.google.firebase.sessions

import android.os.Bundle
import com.google.common.truth.Truth.assertThat
import com.google.firebase.FirebaseApp
import com.google.firebase.sessions.settings.SessionsSettings
import com.google.firebase.sessions.testing.FakeFirebaseApp
import com.google.firebase.sessions.testing.TestSessionEventData
import com.google.firebase.sessions.testing.TestSessionEventData.TEST_DATA_COLLECTION_STATUS
import com.google.firebase.sessions.testing.TestSessionEventData.TEST_SESSION_DATA
import com.google.firebase.sessions.testing.TestSessionEventData.TEST_SESSION_DETAILS
import com.google.firebase.sessions.testing.TestSessionEventData.TEST_SESSION_EVENT
import com.google.firebase.sessions.testing.TestSessionEventData.TEST_SESSION_TIMESTAMP_US
import org.junit.After
import org.junit.Test
import org.junit.runner.RunWith
Expand All @@ -29,14 +35,41 @@ import org.robolectric.RobolectricTestRunner
class SessionEventTest {
@Test
fun sessionStart_populatesSessionDetailsCorrectly() {
val fakeFirebaseApp = FakeFirebaseApp()
val sessionEvent =
SessionEvents.startSession(
FakeFirebaseApp.fakeFirebaseApp(),
TestSessionEventData.TEST_SESSION_DETAILS,
TestSessionEventData.TEST_SESSION_TIMESTAMP_US,
fakeFirebaseApp.firebaseApp,
TEST_SESSION_DETAILS,
SessionsSettings(fakeFirebaseApp.firebaseApp.applicationContext),
TEST_SESSION_TIMESTAMP_US,
)

assertThat(sessionEvent).isEqualTo(TestSessionEventData.EXPECTED_DEFAULT_SESSION_EVENT)
assertThat(sessionEvent).isEqualTo(TEST_SESSION_EVENT)
}

@Test
fun sessionStart_samplingRate() {
val metadata = Bundle()
metadata.putDouble("firebase_sessions_sampling_rate", 0.5)
val fakeFirebaseApp = FakeFirebaseApp(metadata)

val sessionEvent =
SessionEvents.startSession(
fakeFirebaseApp.firebaseApp,
TEST_SESSION_DETAILS,
SessionsSettings(fakeFirebaseApp.firebaseApp.applicationContext),
TEST_SESSION_TIMESTAMP_US,
)

assertThat(sessionEvent)
.isEqualTo(
TEST_SESSION_EVENT.copy(
sessionData =
TEST_SESSION_DATA.copy(
dataCollectionStatus = TEST_DATA_COLLECTION_STATUS.copy(sessionSamplingRate = 0.5)
)
)
)
}

@After
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class SessionInitiatorTest {
@Test
fun coldStart_initiatesSession() {
val sessionStartCounter = SessionStartCounter()
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext
val settings = SessionsSettings(context)

// Simulate a cold start by simply constructing the SessionInitiator object
Expand All @@ -63,7 +63,7 @@ class SessionInitiatorTest {
fun appForegrounded_largeInterval_initiatesSession() {
val fakeClock = FakeClock()
val sessionStartCounter = SessionStartCounter()
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext
val settings = SessionsSettings(context)

val sessionInitiator =
Expand All @@ -84,7 +84,7 @@ class SessionInitiatorTest {
fun appForegrounded_smallInterval_doesNotInitiatesSession() {
val fakeClock = FakeClock()
val sessionStartCounter = SessionStartCounter()
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext
val settings = SessionsSettings(context)

val sessionInitiator =
Expand All @@ -105,7 +105,7 @@ class SessionInitiatorTest {
fun appForegrounded_background_foreground_largeIntervals_initiatesSessions() {
val fakeClock = FakeClock()
val sessionStartCounter = SessionStartCounter()
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext
val settings = SessionsSettings(context)

val sessionInitiator =
Expand All @@ -129,7 +129,7 @@ class SessionInitiatorTest {
fun appForegrounded_background_foreground_smallIntervals_doesNotInitiateNewSessions() {
val fakeClock = FakeClock()
val sessionStartCounter = SessionStartCounter()
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext
val settings = SessionsSettings(context)

val sessionInitiator =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class SessionsSettingsTest {

@Test
fun sessionSettings_fetchDefaults() {
val context = FakeFirebaseApp.fakeFirebaseApp().applicationContext
val context = FakeFirebaseApp().firebaseApp.applicationContext

val sessionsSettings = SessionsSettings(context)
assertThat(sessionsSettings.sessionsEnabled).isTrue()
Expand All @@ -46,7 +46,7 @@ class SessionsSettingsTest {
metadata.putBoolean("firebase_sessions_enabled", false)
metadata.putDouble("firebase_sessions_sampling_rate", 0.5)
metadata.putInt("firebase_sessions_sessions_restart_timeout", 180)
val context = FakeFirebaseApp.fakeFirebaseApp(metadata).applicationContext
val context = FakeFirebaseApp(metadata).firebaseApp.applicationContext

val sessionsSettings = SessionsSettings(context)
assertThat(sessionsSettings.sessionsEnabled).isFalse()
Expand All @@ -59,7 +59,7 @@ class SessionsSettingsTest {
val metadata = Bundle()
metadata.putBoolean("firebase_sessions_enabled", false)
metadata.putDouble("firebase_sessions_sampling_rate", 0.5)
val context = FakeFirebaseApp.fakeFirebaseApp(metadata).applicationContext
val context = FakeFirebaseApp(metadata).firebaseApp.applicationContext

val sessionsSettings = SessionsSettings(context)
assertThat(sessionsSettings.sessionsEnabled).isFalse()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,10 @@ import com.google.firebase.ktx.Firebase
import com.google.firebase.ktx.initialize
import org.robolectric.Shadows

object FakeFirebaseApp {
internal val MOCK_PROJECT_ID = "project"
internal val MOCK_APP_ID = "1:12345:android:app"
internal val MOCK_API_KEY = "RANDOM_APIKEY_FOR_TESTING"
internal val MOCK_APP_VERSION = "1.0.0"
internal class FakeFirebaseApp(metadata: Bundle? = null) {
val firebaseApp: FirebaseApp

fun fakeFirebaseApp(): FirebaseApp {
return fakeFirebaseApp(null)
}

fun fakeFirebaseApp(metadata: Bundle?): FirebaseApp {
init {
val shadowPackageManager =
Shadows.shadowOf(ApplicationProvider.getApplicationContext<Context>().packageManager)
val packageInfo =
Expand All @@ -45,12 +38,10 @@ object FakeFirebaseApp {
.build()
packageInfo.versionName = MOCK_APP_VERSION

if (metadata != null) {
packageInfo.applicationInfo.metaData = metadata
}
metadata?.let { packageInfo.applicationInfo.metaData = it }
shadowPackageManager.installPackage(packageInfo)

val firebaseApp =
firebaseApp =
Firebase.initialize(
ApplicationProvider.getApplicationContext(),
FirebaseOptions.Builder()
Expand All @@ -59,6 +50,12 @@ object FakeFirebaseApp {
.setProjectId(MOCK_PROJECT_ID)
.build()
)
return firebaseApp
}

companion object {
internal const val MOCK_PROJECT_ID = "project"
internal const val MOCK_APP_ID = "1:12345:android:app"
internal const val MOCK_API_KEY = "RANDOM_APIKEY_FOR_TESTING"
internal const val MOCK_APP_VERSION = "1.0.0"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,27 @@ internal object TestSessionEventData {

const val TEST_SESSION_TIMESTAMP_US: Long = 12340000

val EXPECTED_DEFAULT_SESSION_EVENT =
val TEST_DATA_COLLECTION_STATUS =
DataCollectionStatus(
performance = DataCollectionState.COLLECTION_ENABLED,
crashlytics = DataCollectionState.COLLECTION_ENABLED,
sessionSamplingRate = 1.0
)

val TEST_SESSION_DATA =
SessionInfo(
sessionId = "a1b2c3",
firstSessionId = "a1a1a1",
sessionIndex = 3,
eventTimestampUs = TEST_SESSION_TIMESTAMP_US,
dataCollectionStatus = TEST_DATA_COLLECTION_STATUS,
firebaseInstallationId = "",
)

val TEST_SESSION_EVENT =
SessionEvent(
eventType = EventType.SESSION_START,
sessionData =
SessionInfo(
sessionId = "a1b2c3",
firstSessionId = "a1a1a1",
sessionIndex = 3,
firebaseInstallationId = "",
eventTimestampUs = TestSessionEventData.TEST_SESSION_TIMESTAMP_US,
),
sessionData = TEST_SESSION_DATA,
applicationInfo =
ApplicationInfo(
appId = FakeFirebaseApp.MOCK_APP_ID,
Expand Down