diff --git a/firebase-perf/firebase-perf.gradle b/firebase-perf/firebase-perf.gradle index c0fd6df6056..48bc21c7ffb 100644 --- a/firebase-perf/firebase-perf.gradle +++ b/firebase-perf/firebase-perf.gradle @@ -70,6 +70,7 @@ android { buildConfigField("String", "TRANSPORT_LOG_SRC", "String.valueOf(\"FIREPERF\")") buildConfigField("Boolean", "ENFORCE_DEFAULT_LOG_SRC", "Boolean.valueOf(false)") buildConfigField("String", "FIREPERF_VERSION_NAME", "String.valueOf(\"" + property("version") + "\")") + buildConfigField("Boolean", "ENFORCE_LEGACY_SESSIONS", "Boolean.valueOf(false)") if (project.hasProperty("fireperfBuildForAutopush")) { // This allows the SDK to be built for "Autopush" env when the mentioned flag @@ -77,6 +78,7 @@ android { // SDK or the Test App). buildConfigField("String", "TRANSPORT_LOG_SRC", "String.valueOf(\"FIREPERF_AUTOPUSH\")") buildConfigField("Boolean", "ENFORCE_DEFAULT_LOG_SRC", "Boolean.valueOf(true)") + buildConfigField("Boolean", "ENFORCE_LEGACY_SESSIONS", "Boolean.valueOf(true)") } minSdkVersion project.minSdkVersion @@ -118,7 +120,7 @@ dependencies { api("com.google.firebase:firebase-components:18.0.0") api("com.google.firebase:firebase-config:21.5.0") api("com.google.firebase:firebase-installations:17.2.0") - api("com.google.firebase:firebase-sessions:2.0.7") { + api(project(":firebase-sessions")) { exclude group: 'com.google.firebase', module: 'firebase-common' exclude group: 'com.google.firebase', module: 'firebase-common-ktx' exclude group: 'com.google.firebase', module: 'firebase-components' diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java index 5b89deaad82..164fe46b502 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfEarly.java @@ -51,12 +51,8 @@ public FirebasePerfEarly( uiExecutor.execute(new AppStartTrace.StartFromBackgroundRunnable(appStartTrace)); } - // TODO: Bring back Firebase Sessions dependency to watch for updates to sessions. + // In the case of a cold start, we initialize gauge collection with a legacy PerfSession. - // In the case of cold start, we create a session and start collecting gauges as early as - // possible. - // There is code in SessionManager that prevents us from resetting the session twice in case - // of app cold start. SessionManager.getInstance().initializeGaugeCollection(); } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java index c01f035af1f..daffc2de81a 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerfRegistrar.java @@ -30,6 +30,8 @@ import com.google.firebase.perf.injection.modules.FirebasePerformanceModule; import com.google.firebase.platforminfo.LibraryVersionComponent; import com.google.firebase.remoteconfig.RemoteConfigComponent; +import com.google.firebase.sessions.api.FirebaseSessionsDependencies; +import com.google.firebase.sessions.api.SessionSubscriber; import java.util.Arrays; import java.util.List; import java.util.concurrent.Executor; @@ -47,6 +49,11 @@ public class FirebasePerfRegistrar implements ComponentRegistrar { private static final String LIBRARY_NAME = "fire-perf"; private static final String EARLY_LIBRARY_NAME = "fire-perf-early"; + static { + // Add Firebase Performance as a dependency of Sessions when this class is loaded into memory. + FirebaseSessionsDependencies.addDependency(SessionSubscriber.Name.PERFORMANCE); + } + @Override @Keep public List> getComponents() { diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java index 40468566225..cce0389039b 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/FirebasePerformance.java @@ -34,14 +34,18 @@ import com.google.firebase.perf.config.RemoteConfigManager; import com.google.firebase.perf.logging.AndroidLogger; import com.google.firebase.perf.logging.ConsoleUrlGenerator; +import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck; import com.google.firebase.perf.metrics.HttpMetric; import com.google.firebase.perf.metrics.Trace; +import com.google.firebase.perf.session.FirebasePerformanceSessionSubscriber; import com.google.firebase.perf.session.SessionManager; import com.google.firebase.perf.transport.TransportManager; import com.google.firebase.perf.util.Constants; import com.google.firebase.perf.util.ImmutableBundle; import com.google.firebase.perf.util.Timer; import com.google.firebase.remoteconfig.RemoteConfigComponent; +import com.google.firebase.sessions.api.FirebaseSessionsDependencies; +import com.google.firebase.sessions.api.SessionSubscriber; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.net.URL; @@ -92,6 +96,8 @@ public class FirebasePerformance implements FirebasePerformanceAttributable { // once during initialization and cache it. private final ImmutableBundle mMetadataBundle; + private final SessionSubscriber sessionSubscriber; + /** Valid HttpMethods for manual network APIs */ @StringDef({ HttpMethod.GET, @@ -136,11 +142,6 @@ public static FirebasePerformance getInstance() { // to false if it's been force disabled or it is set to null if neither. @Nullable private Boolean mPerformanceCollectionForceEnabledState = null; - private final FirebaseApp firebaseApp; - private final Provider firebaseRemoteConfigProvider; - private final FirebaseInstallationsApi firebaseInstallationsApi; - private final Provider transportFactoryProvider; - /** * Constructs the FirebasePerformance class and allows injecting dependencies. * @@ -166,23 +167,19 @@ public static FirebasePerformance getInstance() { ConfigResolver configResolver, SessionManager sessionManager) { - this.firebaseApp = firebaseApp; - this.firebaseRemoteConfigProvider = firebaseRemoteConfigProvider; - this.firebaseInstallationsApi = firebaseInstallationsApi; - this.transportFactoryProvider = transportFactoryProvider; - if (firebaseApp == null) { this.mPerformanceCollectionForceEnabledState = false; this.configResolver = configResolver; this.mMetadataBundle = new ImmutableBundle(new Bundle()); + this.sessionSubscriber = new FirebasePerformanceSessionSubscriber(false); return; } + FirebaseSessionsEnforcementCheck.setEnforcement(BuildConfig.ENFORCE_LEGACY_SESSIONS); TransportManager.getInstance() .initialize(firebaseApp, firebaseInstallationsApi, transportFactoryProvider); Context appContext = firebaseApp.getApplicationContext(); - // TODO(b/110178816): Explore moving off of main thread. mMetadataBundle = extractMetadata(appContext); remoteConfigManager.setFirebaseRemoteConfigProvider(firebaseRemoteConfigProvider); @@ -192,6 +189,9 @@ public static FirebasePerformance getInstance() { sessionManager.setApplicationContext(appContext); mPerformanceCollectionForceEnabledState = configResolver.getIsPerformanceCollectionEnabled(); + sessionSubscriber = new FirebasePerformanceSessionSubscriber(isPerformanceCollectionEnabled()); + FirebaseSessionsDependencies.register(sessionSubscriber); + if (logger.isLogcatEnabled() && isPerformanceCollectionEnabled()) { logger.info( String.format( @@ -282,7 +282,7 @@ public synchronized void setPerformanceCollectionEnabled(@Nullable Boolean enabl return; } - if (configResolver.getIsPerformanceCollectionDeactivated()) { + if (Boolean.TRUE.equals(configResolver.getIsPerformanceCollectionDeactivated())) { logger.info("Firebase Performance is permanently disabled"); return; } @@ -466,4 +466,9 @@ private static ImmutableBundle extractMetadata(Context appContext) { Boolean getPerformanceCollectionForceEnabledState() { return mPerformanceCollectionForceEnabledState; } + + @VisibleForTesting + SessionSubscriber getSessionSubscriber() { + return sessionSubscriber; + } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/logging/FirebaseSessionsEnforcementCheck.kt b/firebase-perf/src/main/java/com/google/firebase/perf/logging/FirebaseSessionsEnforcementCheck.kt new file mode 100644 index 00000000000..0abef6b0008 --- /dev/null +++ b/firebase-perf/src/main/java/com/google/firebase/perf/logging/FirebaseSessionsEnforcementCheck.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase.perf.logging + +import com.google.firebase.perf.session.PerfSession +import com.google.firebase.perf.session.isLegacy + +class FirebaseSessionsEnforcementCheck { + companion object { + /** When enabled, failed preconditions will cause assertion errors for debugging. */ + @JvmStatic var enforcement: Boolean = false + private var logger: AndroidLogger = AndroidLogger.getInstance() + + @JvmStatic + fun checkSession(session: PerfSession, failureMessage: String) { + if (session.isLegacy()) { + logger.debug("legacy session ${session.sessionId()}: $failureMessage") + assert(!enforcement) { failureMessage } + } + } + } +} diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt new file mode 100644 index 00000000000..b3fed660d9c --- /dev/null +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebasePerformanceSessionSubscriber.kt @@ -0,0 +1,46 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase.perf.session + +import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck +import com.google.firebase.perf.session.gauges.GaugeManager +import com.google.firebase.perf.v1.ApplicationProcessState +import com.google.firebase.sessions.api.SessionSubscriber + +class FirebasePerformanceSessionSubscriber(override val isDataCollectionEnabled: Boolean) : + SessionSubscriber { + + override val sessionSubscriberName: SessionSubscriber.Name = SessionSubscriber.Name.PERFORMANCE + + override fun onSessionChanged(sessionDetails: SessionSubscriber.SessionDetails) { + val currentPerfSession = SessionManager.getInstance().perfSession() + FirebaseSessionsEnforcementCheck.checkSession(currentPerfSession, "onSessionChanged") + + if (currentPerfSession.isLegacy() && currentPerfSession.isVerbose) { + GaugeManager.getInstance() + .logGaugeMetadata(sessionDetails.sessionId, ApplicationProcessState.FOREGROUND) + GaugeManager.getInstance() + .logExistingGaugeMetrics(sessionDetails.sessionId, ApplicationProcessState.FOREGROUND) + } + + val updatedSession = PerfSession.createWithId(sessionDetails.sessionId) + SessionManager.getInstance().updatePerfSession(updatedSession) + GaugeManager.getInstance() + .logGaugeMetadata(updatedSession.sessionId(), ApplicationProcessState.FOREGROUND) + SessionManager.getInstance().updateGaugeCollectionOnNewSession() + } +} diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebaseSessionsHelper.kt b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebaseSessionsHelper.kt new file mode 100644 index 00000000000..7ab9bbf6fee --- /dev/null +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/FirebaseSessionsHelper.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase.perf.session + +import com.google.firebase.perf.util.Constants +import java.util.UUID + +/** Identifies whether the [PerfSession] is legacy or not. */ +fun PerfSession.isLegacy(): Boolean { + return this.sessionId().isLegacy() +} + +/** Identifies whether the string is from a legacy [PerfSession]. */ +fun String.isLegacy(): Boolean { + return this.startsWith(Constants.UNDEFINED_AQS_ID_PREFIX) +} + +/** Creates a valid session ID for [PerfSession] that can be predictably identified as legacy. */ +fun createLegacySessionId(): String { + val uuid = UUID.randomUUID().toString().replace("-", "") + return uuid.replaceRange( + 0, + Constants.UNDEFINED_AQS_ID_PREFIX.length, + Constants.UNDEFINED_AQS_ID_PREFIX + ) +} diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java index 160a4507560..47a2a1af9eb 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/PerfSession.java @@ -28,20 +28,20 @@ /** Details of a session including a unique Id and related information. */ public class PerfSession implements Parcelable { - - private final String sessionId; private final Timer creationTime; - - private boolean isGaugeAndEventCollectionEnabled = false; + private final String sessionId; + private boolean isGaugeAndEventCollectionEnabled = true; /* * Creates a PerfSession object and decides what metrics to collect. */ - public static PerfSession createWithId(@NonNull String sessionId) { - String prunedSessionId = sessionId.replace("-", ""); - PerfSession session = new PerfSession(prunedSessionId, new Clock()); - session.setGaugeAndEventCollectionEnabled(shouldCollectGaugesAndEvents()); - + public static PerfSession createWithId(@Nullable String aqsSessionId) { + String sessionId = aqsSessionId; + if (sessionId == null) { + sessionId = FirebaseSessionsHelperKt.createLegacySessionId(); + } + PerfSession session = new PerfSession(sessionId, new Clock()); + session.setGaugeAndEventCollectionEnabled(session.shouldCollectGaugesAndEvents()); return session; } @@ -59,7 +59,8 @@ private PerfSession(@NonNull Parcel in) { creationTime = in.readParcelable(Timer.class.getClassLoader()); } - /** Returns the sessionId of the object. */ + /** Returns the sessionId for the given session. */ + @NonNull public String sessionId() { return sessionId; } @@ -90,18 +91,6 @@ public boolean isVerbose() { return isGaugeAndEventCollectionEnabled; } - /** Checks if the current {@link com.google.firebase.perf.v1.PerfSession} is verbose or not. */ - @VisibleForTesting - static boolean isVerbose(@NonNull com.google.firebase.perf.v1.PerfSession perfSession) { - for (SessionVerbosity sessionVerbosity : perfSession.getSessionVerbosityList()) { - if (sessionVerbosity == SessionVerbosity.GAUGES_AND_SYSTEM_EVENTS) { - return true; - } - } - - return false; - } - /** * Checks if it has been more than {@link ConfigResolver#getSessionsMaxDurationMinutes()} time * since the creation time of the current session. @@ -163,11 +152,11 @@ public static com.google.firebase.perf.v1.PerfSession[] buildAndSort( } /** If true, Session Gauge collection is enabled. */ - public static boolean shouldCollectGaugesAndEvents() { + public boolean shouldCollectGaugesAndEvents() { ConfigResolver configResolver = ConfigResolver.getInstance(); - return configResolver.isPerformanceMonitoringEnabled() - && Math.random() < configResolver.getSessionsSamplingRate(); + && (Math.abs(this.sessionId.hashCode() % 100) + < configResolver.getSessionsSamplingRate() * 100); } /** @@ -208,4 +197,16 @@ public PerfSession[] newArray(int size) { return new PerfSession[size]; } }; + + /** Checks if the current {@link com.google.firebase.perf.v1.PerfSession} is verbose or not. */ + @VisibleForTesting + static boolean isVerbose(@NonNull com.google.firebase.perf.v1.PerfSession perfSession) { + for (SessionVerbosity sessionVerbosity : perfSession.getSessionVerbosityList()) { + if (sessionVerbosity == SessionVerbosity.GAUGES_AND_SYSTEM_EVENTS) { + return true; + } + } + + return false; + } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java index 79d034b9b0b..5a8540a6ffb 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/SessionManager.java @@ -19,7 +19,7 @@ import androidx.annotation.Keep; import androidx.annotation.VisibleForTesting; import com.google.firebase.perf.application.AppStateMonitor; -import com.google.firebase.perf.application.AppStateUpdateHandler; +import com.google.firebase.perf.logging.FirebaseSessionsEnforcementCheck; import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.perf.v1.ApplicationProcessState; import com.google.firebase.perf.v1.GaugeMetadata; @@ -27,16 +27,12 @@ import java.lang.ref.WeakReference; import java.util.HashSet; import java.util.Iterator; +import java.util.Objects; import java.util.Set; -import java.util.UUID; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; /** Session manager to generate sessionIDs and broadcast to the application. */ @Keep // Needed because of b/117526359. -public class SessionManager extends AppStateUpdateHandler { - +public class SessionManager { @SuppressLint("StaticFieldLeak") private static final SessionManager instance = new SessionManager(); @@ -45,7 +41,6 @@ public class SessionManager extends AppStateUpdateHandler { private final Set> clients = new HashSet<>(); private PerfSession perfSession; - private Future syncInitFuture; /** Returns the singleton instance of SessionManager. */ public static SessionManager getInstance() { @@ -54,15 +49,15 @@ public static SessionManager getInstance() { /** Returns the currently active PerfSession. */ public final PerfSession perfSession() { + FirebaseSessionsEnforcementCheck.checkSession( + perfSession, "Access perf session from manger without aqs ready"); + return perfSession; } private SessionManager() { - // Generate a new sessionID for every cold start. - this( - GaugeManager.getInstance(), - PerfSession.createWithId(UUID.randomUUID().toString()), - AppStateMonitor.getInstance()); + // session should quickly updated by session subscriber. + this(GaugeManager.getInstance(), PerfSession.createWithId(null), AppStateMonitor.getInstance()); } @VisibleForTesting @@ -71,7 +66,6 @@ public SessionManager( this.gaugeManager = gaugeManager; this.perfSession = perfSession; this.appStateMonitor = appStateMonitor; - registerForAppState(); } /** @@ -79,49 +73,7 @@ public SessionManager( * (currently that is before onResume finishes) to ensure gauge collection starts on time. */ public void setApplicationContext(final Context appContext) { - // Get PerfSession in main thread first, because it is possible that app changes fg/bg state - // which creates a new perfSession, before the following is executed in background thread - final PerfSession appStartSession = perfSession; - // TODO(b/258263016): Migrate to go/firebase-android-executors - @SuppressLint("ThreadPoolCreation") - ExecutorService executorService = Executors.newSingleThreadExecutor(); - syncInitFuture = - executorService.submit( - () -> { - gaugeManager.initializeGaugeMetadataManager(appContext); - if (appStartSession.isGaugeAndEventCollectionEnabled()) { - gaugeManager.logGaugeMetadata( - appStartSession.sessionId(), ApplicationProcessState.FOREGROUND); - } - }); - } - - @Override - public void onUpdateAppState(ApplicationProcessState newAppState) { - super.onUpdateAppState(newAppState); - - if (appStateMonitor.isColdStart()) { - // We want the Session to remain unchanged if this is a cold start of the app since we already - // update the PerfSession in FirebasePerfProvider#onAttachInfo(). - return; - } - - if (newAppState == ApplicationProcessState.FOREGROUND) { - // A new foregrounding of app will force a new sessionID generation. - PerfSession session = PerfSession.createWithId(UUID.randomUUID().toString()); - updatePerfSession(session); - } else { - // If the session is running for too long, generate a new session and collect gauges as - // necessary. - if (perfSession.isSessionRunningTooLong()) { - PerfSession session = PerfSession.createWithId(UUID.randomUUID().toString()); - updatePerfSession(session); - } else { - // For any other state change of the application, modify gauge collection state as - // necessary. - startOrStopCollectingGauges(newAppState); - } - } + gaugeManager.initializeGaugeMetadataManager(appContext); } /** @@ -130,6 +82,10 @@ public void onUpdateAppState(ApplicationProcessState newAppState) { * @see PerfSession#isSessionRunningTooLong() */ public void stopGaugeCollectionIfSessionRunningTooLong() { + FirebaseSessionsEnforcementCheck.checkSession( + perfSession, + "Session is not ready while trying to stopGaugeCollectionIfSessionRunningTooLong"); + if (perfSession.isSessionRunningTooLong()) { gaugeManager.stopCollectingGauges(); } @@ -145,12 +101,14 @@ public void stopGaugeCollectionIfSessionRunningTooLong() { */ public void updatePerfSession(PerfSession perfSession) { // Do not update the perf session if it is the exact same sessionId. - if (perfSession.sessionId() == this.perfSession.sessionId()) { + if (Objects.equals(perfSession.sessionId(), this.perfSession.sessionId())) { return; } this.perfSession = perfSession; + // TODO(b/394127311): Update/verify behavior for Firebase Sessions. + synchronized (clients) { for (Iterator> i = clients.iterator(); i.hasNext(); ) { SessionAwareObject callback = i.next().get(); @@ -164,9 +122,6 @@ public void updatePerfSession(PerfSession perfSession) { } } - // Log the gauge metadata event if data collection is enabled. - logGaugeMetadataIfCollectionEnabled(appStateMonitor.getAppState()); - // Start of stop the gauge data collection. startOrStopCollectingGauges(appStateMonitor.getAppState()); } @@ -178,7 +133,6 @@ public void updatePerfSession(PerfSession perfSession) { * this does not reset the perfSession. */ public void initializeGaugeCollection() { - logGaugeMetadataIfCollectionEnabled(ApplicationProcessState.FOREGROUND); startOrStopCollectingGauges(ApplicationProcessState.FOREGROUND); } @@ -206,13 +160,10 @@ public void unregisterForSessionUpdates(WeakReference client } } - private void logGaugeMetadataIfCollectionEnabled(ApplicationProcessState appState) { - if (perfSession.isGaugeAndEventCollectionEnabled()) { - gaugeManager.logGaugeMetadata(perfSession.sessionId(), appState); - } - } - private void startOrStopCollectingGauges(ApplicationProcessState appState) { + FirebaseSessionsEnforcementCheck.checkSession( + perfSession, "Session is not ready while trying to startOrStopCollectingGauges"); + if (perfSession.isGaugeAndEventCollectionEnabled()) { gaugeManager.startCollectingGauges(perfSession, appState); } else { @@ -224,9 +175,4 @@ private void startOrStopCollectingGauges(ApplicationProcessState appState) { public void setPerfSession(PerfSession perfSession) { this.perfSession = perfSession; } - - @VisibleForTesting - public Future getSyncInitFuture() { - return this.syncInitFuture; - } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/CpuGaugeCollector.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/CpuGaugeCollector.java index e33d363c0aa..ceb636d56b3 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/CpuGaugeCollector.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/CpuGaugeCollector.java @@ -17,8 +17,6 @@ import static android.system.Os.sysconf; import android.annotation.SuppressLint; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import android.system.OsConstants; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; @@ -163,7 +161,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate( this.cpuMetricCollectionRateMs = cpuMetricCollectionRate; try { cpuMetricCollectorJob = - cpuMetricCollectorExecutor.scheduleAtFixedRate( + cpuMetricCollectorExecutor.scheduleWithFixedDelay( () -> { CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime); if (currCpuReading != null) { @@ -181,7 +179,7 @@ private synchronized void scheduleCpuMetricCollectionWithRate( private synchronized void scheduleCpuMetricCollectionOnce(Timer referenceTime) { try { @SuppressWarnings("FutureReturnValueIgnored") - ScheduledFuture unusedFuture = + ScheduledFuture unusedFuture = cpuMetricCollectorExecutor.schedule( () -> { CpuMetricReading currCpuReading = syncCollectCpuMetric(referenceTime); @@ -227,12 +225,7 @@ private CpuMetricReading syncCollectCpuMetric(Timer referenceTime) { } private long getClockTicksPerSecond() { - if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) { - return sysconf(OsConstants._SC_CLK_TCK); - } else { - // TODO(b/110779408): Figure out how to collect this info for Android API 20 and below. - return INVALID_SC_PER_CPU_CLOCK_TICK; - } + return sysconf(OsConstants._SC_CLK_TCK); } private long convertClockTicksToMicroseconds(long clockTicks) { diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeManager.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeManager.java index 7f6182a9c15..4b2623d4409 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeManager.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeManager.java @@ -59,8 +59,10 @@ public class GaugeManager { private final TransportManager transportManager; @Nullable private GaugeMetadataManager gaugeMetadataManager; - @Nullable private ScheduledFuture gaugeManagerDataCollectionJob = null; + @Nullable private ScheduledFuture gaugeManagerDataCollectionJob = null; @Nullable private String sessionId = null; + + private boolean isCollectingGauges = false; private ApplicationProcessState applicationProcessState = ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN; @@ -72,8 +74,8 @@ private GaugeManager() { TransportManager.getInstance(), ConfigResolver.getInstance(), null, - new Lazy<>(() -> new CpuGaugeCollector()), - new Lazy<>(() -> new MemoryGaugeCollector())); + new Lazy<>(CpuGaugeCollector::new), + new Lazy<>(MemoryGaugeCollector::new)); } @VisibleForTesting @@ -81,7 +83,7 @@ private GaugeManager() { Lazy gaugeManagerExecutor, TransportManager transportManager, ConfigResolver configResolver, - GaugeMetadataManager gaugeMetadataManager, + @Nullable GaugeMetadataManager gaugeMetadataManager, Lazy cpuGaugeCollector, Lazy memoryGaugeCollector) { @@ -103,6 +105,34 @@ public static synchronized GaugeManager getInstance() { return instance; } + public void updateGaugeLogging( + String sessionId, ApplicationProcessState applicationProcessState, long collectionFrequency) { + try { + gaugeManagerDataCollectionJob = + gaugeManagerExecutor + .get() + .scheduleWithFixedDelay( + () -> { + syncFlush(sessionId, applicationProcessState); + }, + /* initialDelay= */ collectionFrequency + * APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC, + /* period= */ collectionFrequency * APPROX_NUMBER_OF_DATA_POINTS_PER_GAUGE_METRIC, + TimeUnit.MILLISECONDS); + + } catch (RejectedExecutionException e) { + logger.warn("Unable to start collecting Gauges: " + e.getMessage()); + } + } + + public long updateGaugeCollection( + ApplicationProcessState applicationProcessState, Timer gaugeCollectionTimer) { + if (isCollectingGauges) { + stopCollectingGauges(); + } + return startCollectingGauges(applicationProcessState, gaugeCollectionTimer); + } + /** * Starts the collection of available gauges for the given {@code sessionId} and {@code * applicationProcessState}. The collected Gauge Metrics will be flushed at regular intervals. @@ -136,11 +166,12 @@ public void startCollectingGauges( final String sessionIdForScheduledTask = sessionId; final ApplicationProcessState applicationProcessStateForScheduledTask = applicationProcessState; + // TODO(b/394127311): Switch to using AQS. try { gaugeManagerDataCollectionJob = gaugeManagerExecutor .get() - .scheduleAtFixedRate( + .scheduleWithFixedDelay( () -> { syncFlush(sessionIdForScheduledTask, applicationProcessStateForScheduledTask); }, @@ -189,7 +220,7 @@ private long startCollectingGauges(ApplicationProcessState appState, Timer refer * this.stopCollectingGauges()} should always be called from the same thread. */ public void stopCollectingGauges() { - if (this.sessionId == null) { + if (!this.isCollectingGauges) { return; } @@ -204,6 +235,7 @@ public void stopCollectingGauges() { gaugeManagerDataCollectionJob.cancel(false); } + // TODO(b/394127311): Switch to using AQS. // Flush any data that was collected for this session one last time. @SuppressWarnings("FutureReturnValueIgnored") ScheduledFuture unusedFuture = @@ -217,6 +249,7 @@ public void stopCollectingGauges() { TimeUnit.MILLISECONDS); this.sessionId = null; + this.isCollectingGauges = false; this.applicationProcessState = ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN; } @@ -242,6 +275,7 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) { } // Adding Session ID info. + // TODO(b/394127311): Switch to using AQS. gaugeMetricBuilder.setSessionId(sessionId); transportManager.log(gaugeMetricBuilder.build(), appState); @@ -250,7 +284,7 @@ private void syncFlush(String sessionId, ApplicationProcessState appState) { /** * Log the Gauge Metadata information to the transport. * - * @param sessionId The {@link PerfSession#sessionId()} to which the collected Gauge Metrics + * @param sessionId The {@link PerfSession#sessionId()} ()} to which the collected Gauge Metrics * should be associated with. * @param appState The {@link ApplicationProcessState} for which these gauges are collected. * @return true if GaugeMetadata was logged, false otherwise. @@ -332,6 +366,22 @@ public void collectGaugeMetricOnce(Timer referenceTime) { collectGaugeMetricOnce(cpuGaugeCollector.get(), memoryGaugeCollector.get(), referenceTime); } + public void logExistingGaugeMetrics( + String sessionId, ApplicationProcessState applicationProcessState) { + // Flush any data that was collected and associate it with the given session ID and + // applicationProcessState. + @SuppressWarnings("FutureReturnValueIgnored") + ScheduledFuture unusedFuture = + gaugeManagerExecutor + .get() + .schedule( + () -> { + syncFlush(sessionId, applicationProcessState); + }, + TIME_TO_WAIT_BEFORE_FLUSHING_GAUGES_QUEUE_MS, + TimeUnit.MILLISECONDS); + } + private static void collectGaugeMetricOnce( CpuGaugeCollector cpuGaugeCollector, MemoryGaugeCollector memoryGaugeCollector, @@ -402,4 +452,10 @@ private long getMemoryGaugeCollectionFrequencyMs( return memoryGaugeCollectionFrequency; } } + + private long getGaugeLoggingFrequency(ApplicationProcessState applicationProcessState) { + return Math.min( + getMemoryGaugeCollectionFrequencyMs(applicationProcessState), + getCpuGaugeCollectionFrequencyMs(applicationProcessState)); + } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeMetadataManager.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeMetadataManager.java index 6b4466dfc35..ed38dd8f38d 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeMetadataManager.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/GaugeMetadataManager.java @@ -17,18 +17,11 @@ import android.app.ActivityManager; import android.app.ActivityManager.MemoryInfo; import android.content.Context; -import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import androidx.annotation.VisibleForTesting; import com.google.firebase.perf.logging.AndroidLogger; import com.google.firebase.perf.util.StorageUnit; import com.google.firebase.perf.util.Utils; import com.google.firebase.perf.v1.GaugeMetadata; -import java.io.BufferedReader; -import java.io.FileReader; -import java.io.IOException; -import java.util.regex.Matcher; -import java.util.regex.Pattern; /** * The {@code GaugeMetadataManager} class is responsible for collecting {@link GaugeMetadata} @@ -41,7 +34,6 @@ class GaugeMetadataManager { private final Runtime runtime; private final ActivityManager activityManager; private final MemoryInfo memoryInfo; - private final Context appContext; GaugeMetadataManager(Context appContext) { this(Runtime.getRuntime(), appContext); @@ -50,7 +42,6 @@ class GaugeMetadataManager { @VisibleForTesting GaugeMetadataManager(Runtime runtime, Context appContext) { this.runtime = runtime; - this.appContext = appContext; this.activityManager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE); memoryInfo = new ActivityManager.MemoryInfo(); activityManager.getMemoryInfo(memoryInfo); @@ -75,29 +66,6 @@ public int getMaxEncouragedAppJavaHeapMemoryKb() { /** Returns the total memory (in kilobytes) accessible by the kernel (called the RAM size). */ public int getDeviceRamSizeKb() { - if (VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN) { - return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem)); - } - - return readTotalRAM(/* procFileName= */ "/proc/meminfo"); - } - - /** Returns the total ram size of the device (in kilobytes) by reading the "proc/meminfo" file. */ - @VisibleForTesting - int readTotalRAM(String procFileName) { - try (BufferedReader br = new BufferedReader(new FileReader(procFileName))) { - for (String s = br.readLine(); s != null; s = br.readLine()) { - if (s.startsWith("MemTotal")) { - Matcher m = Pattern.compile("\\d+").matcher(s); - return m.find() ? Integer.parseInt(m.group()) : 0; - } - } - } catch (IOException ioe) { - logger.warn("Unable to read '" + procFileName + "' file: " + ioe.getMessage()); - } catch (NumberFormatException nfe) { - logger.warn("Unable to parse '" + procFileName + "' file: " + nfe.getMessage()); - } - - return 0; + return Utils.saturatedIntCast(StorageUnit.BYTES.toKilobytes(memoryInfo.totalMem)); } } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/MemoryGaugeCollector.java b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/MemoryGaugeCollector.java index eeaf4eb7c80..a7b4b40002a 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/MemoryGaugeCollector.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/session/gauges/MemoryGaugeCollector.java @@ -50,7 +50,7 @@ public class MemoryGaugeCollector { public final ConcurrentLinkedQueue memoryMetricReadings; private final Runtime runtime; - @Nullable private ScheduledFuture memoryMetricCollectorJob = null; + @Nullable private ScheduledFuture memoryMetricCollectorJob = null; private long memoryMetricCollectionRateMs = UNSET_MEMORY_METRIC_COLLECTION_RATE; // TODO(b/258263016): Migrate to go/firebase-android-executors @@ -124,7 +124,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate( try { memoryMetricCollectorJob = - memoryMetricCollectorExecutor.scheduleAtFixedRate( + memoryMetricCollectorExecutor.scheduleWithFixedDelay( () -> { AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime); if (memoryReading != null) { @@ -142,7 +142,7 @@ private synchronized void scheduleMemoryMetricCollectionWithRate( private synchronized void scheduleMemoryMetricCollectionOnce(Timer referenceTime) { try { @SuppressWarnings("FutureReturnValueIgnored") - ScheduledFuture unusedFuture = + ScheduledFuture unusedFuture = memoryMetricCollectorExecutor.schedule( () -> { AndroidMemoryReading memoryReading = syncCollectMemoryMetric(referenceTime); diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java b/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java index 9600b099a6d..159af53d3d3 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/transport/TransportManager.java @@ -354,6 +354,7 @@ public void log(final GaugeMetric gaugeMetric) { * {@link #isAllowedToDispatch(PerfMetric)}). */ public void log(final GaugeMetric gaugeMetric, final ApplicationProcessState appState) { + // TODO(b/394127311): This *might* potentially be the right place to get AQS. executorService.execute( () -> syncLog(PerfMetric.newBuilder().setGaugeMetric(gaugeMetric), appState)); } diff --git a/firebase-perf/src/main/java/com/google/firebase/perf/util/Constants.java b/firebase-perf/src/main/java/com/google/firebase/perf/util/Constants.java index f2704b903ce..42a126f014e 100644 --- a/firebase-perf/src/main/java/com/google/firebase/perf/util/Constants.java +++ b/firebase-perf/src/main/java/com/google/firebase/perf/util/Constants.java @@ -22,6 +22,10 @@ public class Constants { public static final String PREFS_NAME = "FirebasePerfSharedPrefs"; public static final String ENABLE_DISABLE = "isEnabled"; + // A non-hex character guarantees it isn't an AQS generated UUID. + // https://kotlinlang.org/api/core/kotlin-stdlib/kotlin.uuid/-uuid/ + public static final String UNDEFINED_AQS_ID_PREFIX = "z"; + public static final double MIN_SAMPLING_RATE = 0.0; public static final double MAX_SAMPLING_RATE = 1.0; diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java index 0b7d4bbfc17..f30ee5d73a0 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/application/AppStateMonitorTest.java @@ -39,6 +39,8 @@ import com.google.firebase.perf.config.DeviceCacheManager; import com.google.firebase.perf.metrics.NetworkRequestMetricBuilder; import com.google.firebase.perf.metrics.Trace; +import com.google.firebase.perf.session.PerfSession; +import com.google.firebase.perf.session.SessionManager; import com.google.firebase.perf.session.gauges.GaugeManager; import com.google.firebase.perf.transport.TransportManager; import com.google.firebase.perf.util.Clock; @@ -80,6 +82,7 @@ public class AppStateMonitorTest extends FirebasePerformanceTestBase { @Before public void setUp() { currentTime = 0; + SessionManager.getInstance().updatePerfSession(PerfSession.createWithId("sessionId")); initMocks(this); doAnswer((Answer) invocationOnMock -> new Timer(currentTime)).when(clock).getTime(); diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/FirebaseSessionsTestHelper.kt b/firebase-perf/src/test/java/com/google/firebase/perf/session/FirebaseSessionsTestHelper.kt new file mode 100644 index 00000000000..a617af94a58 --- /dev/null +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/FirebaseSessionsTestHelper.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.google.firebase.perf.session + +import com.google.firebase.perf.util.Clock + +fun createTestSession(suffix: Int): PerfSession { + // TODO(b/394127311): Add a method to verify legacy behavior. + // only hex characters and so it's AQS. + return PerfSession(testSessionId(suffix), Clock()) +} + +fun testSessionId(suffix: Int): String = "abc$suffix" diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/PerfSessionTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/session/PerfSessionTest.java index 43257987b0f..6fe8e1a959c 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/session/PerfSessionTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/PerfSessionTest.java @@ -15,6 +15,8 @@ package com.google.firebase.perf.session; import static com.google.common.truth.Truth.assertThat; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.createTestSession; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.testSessionId; import static com.google.firebase.perf.util.Constants.PREFS_NAME; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -62,12 +64,24 @@ public void setUp() { @Test public void instanceCreation() { - PerfSession session = new PerfSession("sessionId", mockClock); + PerfSession session = PerfSession.createWithId("sessionId"); assertThat(session).isNotNull(); session.setGaugeAndEventCollectionEnabled(true); - Assert.assertTrue(session.isGaugeAndEventCollectionEnabled()); + assertThat(session.isVerbose()).isTrue(); session.setGaugeAndEventCollectionEnabled(false); - Assert.assertFalse(session.isGaugeAndEventCollectionEnabled()); + assertThat(session.isVerbose()).isFalse(); + assertThat(FirebaseSessionsHelperKt.isLegacy(session)).isFalse(); + } + + @Test + public void legacyInstanceCreation() { + PerfSession perfSession = PerfSession.createWithId(null); + assertThat(perfSession).isNotNull(); + perfSession.setGaugeAndEventCollectionEnabled(true); + assertThat(perfSession.isVerbose()).isTrue(); + perfSession.setGaugeAndEventCollectionEnabled(false); + assertThat(perfSession.isVerbose()).isFalse(); + assertThat(FirebaseSessionsHelperKt.isLegacy(perfSession)).isTrue(); } @Test @@ -76,19 +90,20 @@ public void shouldCollectGaugesAndEvents_perfMonDisabledAtRuntime_sessionNotVerb Bundle bundle = new Bundle(); bundle.putFloat("sessions_sampling_percentage", 100); configResolver.setMetadataBundle(new ImmutableBundle(bundle)); + PerfSession testSession = PerfSession.createWithId("aqsSessionId"); // By default, session is verbose if developer has set 100% of session verbosity. - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isTrue(); // Case #1: developer has disabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(false); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); // Case #2: developer has enabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(true); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isTrue(); } @Test @@ -99,20 +114,21 @@ public void shouldCollectGaugesAndEvents_perfMonDisabledAtBuildtime_verbosityDep bundle.putFloat("sessions_sampling_percentage", 100); bundle.putBoolean("firebase_performance_collection_enabled", false); configResolver.setMetadataBundle(new ImmutableBundle(bundle)); + PerfSession testSession = PerfSession.createWithId("aqsSessionId"); // By default, session is not verbose if developer disabled performance monitoring at build // time. - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); // Case #1: developer has enabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(true); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isTrue(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isTrue(); // Case #2: developer has disabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(false); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); } @Test @@ -122,24 +138,25 @@ public void shouldCollectGaugesAndEvents_perfMonDeactivated_sessionNotVerbose() bundle.putFloat("sessions_sampling_percentage", 100); bundle.putBoolean("firebase_performance_collection_deactivated", true); configResolver.setMetadataBundle(new ImmutableBundle(bundle)); + PerfSession testSession = PerfSession.createWithId("aqsSessionId"); // Session will never be verbose if developer deactivated performance monitoring at build time. - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); // Case #1: developer has enabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(true); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); // Case #2: developer has disabled Performance Monitoring during runtime. configResolver.setIsPerformanceCollectionEnabled(false); - assertThat(PerfSession.shouldCollectGaugesAndEvents()).isFalse(); + assertThat(testSession.shouldCollectGaugesAndEvents()).isFalse(); } @Test public void testPerfSessionConversion() { - PerfSession session1 = new PerfSession("sessionId", mockClock); + PerfSession session1 = createTestSession(1); session1.setGaugeAndEventCollectionEnabled(true); com.google.firebase.perf.v1.PerfSession perfSession = session1.build(); @@ -150,7 +167,7 @@ public void testPerfSessionConversion() { @Test public void testPerfSessionConversionWithoutVerbosity() { - PerfSession session1 = new PerfSession("sessionId", mockClock); + PerfSession session1 = createTestSession(1); com.google.firebase.perf.v1.PerfSession perfSession = session1.build(); Assert.assertEquals(session1.sessionId(), perfSession.getSessionId()); @@ -160,21 +177,21 @@ public void testPerfSessionConversionWithoutVerbosity() { @Test public void testPerfSessionsCreateDisabledGaugeCollectionWhenVerboseSessionForceDisabled() { forceNonVerboseSession(); - PerfSession testPerfSession = PerfSession.createWithId("sessionId"); + PerfSession testPerfSession = createTestSession(1); assertThat(testPerfSession.isGaugeAndEventCollectionEnabled()).isFalse(); } @Test public void testPerfSessionsCreateDisabledGaugeCollectionWhenSessionsFeatureDisabled() { forceSessionsFeatureDisabled(); - PerfSession testPerfSession = PerfSession.createWithId("sessionId"); + PerfSession testPerfSession = createTestSession(1); assertThat(testPerfSession.isGaugeAndEventCollectionEnabled()).isFalse(); } @Test public void testPerfSessionsCreateEnablesGaugeCollectionWhenVerboseSessionForceEnabled() { forceVerboseSession(); - PerfSession testPerfSession = PerfSession.createWithId("sessionId"); + PerfSession testPerfSession = PerfSession.createWithId(testSessionId(1)); assertThat(testPerfSession.isGaugeAndEventCollectionEnabled()).isTrue(); } @@ -185,16 +202,16 @@ public void testBuildAndSortMovesTheVerboseSessionToTop() { // Next, create 3 non-verbose sessions List sessions = new ArrayList<>(); - sessions.add(PerfSession.createWithId("sessionId1")); - sessions.add(PerfSession.createWithId("sessionId2")); - sessions.add(PerfSession.createWithId("sessionId3")); + sessions.add(PerfSession.createWithId(testSessionId(1))); + sessions.add(PerfSession.createWithId(testSessionId(2))); + sessions.add(PerfSession.createWithId(testSessionId(3))); // Force all the sessions from now onwards to be verbose forceVerboseSession(); // Next, create 2 verbose sessions - sessions.add(PerfSession.createWithId("sessionId4")); - sessions.add(PerfSession.createWithId("sessionId5")); + sessions.add(PerfSession.createWithId(testSessionId(4))); + sessions.add(PerfSession.createWithId(testSessionId(5))); // Verify that the first session in the list of sessions was not verbose assertThat(sessions.get(0).isVerbose()).isFalse(); @@ -216,7 +233,7 @@ public void testIsExpiredReturnsFalseWhenCurrentSessionLengthIsLessThanMaxSessio - TimeUnit.MINUTES.toMicros(1)); // Default Max Session Length is 4 hours when(mockClock.getTime()).thenReturn(mockTimer); - PerfSession session = new PerfSession("sessionId", mockClock); + PerfSession session = new PerfSession(testSessionId(1), mockClock); assertThat(session.isSessionRunningTooLong()).isFalse(); } @@ -227,7 +244,7 @@ public void testIsExpiredReturnsFalseWhenCurrentSessionLengthIsEqualToMaxSession .thenReturn(TimeUnit.HOURS.toMicros(4)); // Default Max Session Length is 4 hours when(mockClock.getTime()).thenReturn(mockTimer); - PerfSession session = new PerfSession("sessionId", mockClock); + PerfSession session = new PerfSession(testSessionId(1), mockClock); assertThat(session.isSessionRunningTooLong()).isFalse(); } @@ -238,7 +255,7 @@ public void testIsExpiredReturnsTrueWhenCurrentSessionLengthIsGreaterThanMaxSess .thenReturn(TimeUnit.HOURS.toMicros(5)); // Default Max Session Length is 4 hours when(mockClock.getTime()).thenReturn(mockTimer); - PerfSession session = new PerfSession("sessionId", mockClock); + PerfSession session = new PerfSession(testSessionId(1), mockClock); assertThat(session.isSessionRunningTooLong()).isTrue(); } } diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java index f3e3795f3f8..618dff747ff 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/SessionManagerTest.java @@ -15,10 +15,9 @@ package com.google.firebase.perf.session; import static com.google.common.truth.Truth.assertThat; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.createTestSession; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.testSessionId; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; @@ -40,7 +39,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.AdditionalMatchers; import org.mockito.ArgumentMatchers; import org.mockito.InOrder; import org.mockito.Mock; @@ -61,7 +59,7 @@ public class SessionManagerTest extends FirebasePerformanceTestBase { @Before public void setUp() { initMocks(this); - when(mockPerfSession.sessionId()).thenReturn("sessionId"); + when(mockPerfSession.sessionId()).thenReturn(testSessionId(5)); when(mockAppStateMonitor.isColdStart()).thenReturn(false); AppStateMonitor.getInstance().setIsColdStart(false); } @@ -70,11 +68,10 @@ public void setUp() { public void testInstanceCreation() { assertThat(SessionManager.getInstance()).isNotNull(); assertThat(SessionManager.getInstance()).isEqualTo(SessionManager.getInstance()); - assertThat(SessionManager.getInstance().perfSession().sessionId()).isNotNull(); } @Test - public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsInitialized() + public void setApplicationContext_initializeGaugeMetadataManager() throws ExecutionException, InterruptedException { when(mockPerfSession.isGaugeAndEventCollectionEnabled()).thenReturn(true); InOrder inOrder = Mockito.inOrder(mockGaugeManager); @@ -82,127 +79,7 @@ public void setApplicationContext_logGaugeMetadata_afterGaugeMetadataManagerIsIn new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); testSessionManager.setApplicationContext(mockApplicationContext); - testSessionManager.getSyncInitFuture().get(); inOrder.verify(mockGaugeManager).initializeGaugeMetadataManager(any()); - inOrder.verify(mockGaugeManager).logGaugeMetadata(any(), any()); - } - - @Test - public void testOnUpdateAppStateDoesNothingDuringAppStart() { - String oldSessionId = SessionManager.getInstance().perfSession().sessionId(); - - assertThat(oldSessionId).isNotNull(); - assertThat(oldSessionId).isEqualTo(SessionManager.getInstance().perfSession().sessionId()); - - AppStateMonitor.getInstance().setIsColdStart(true); - - SessionManager.getInstance().onUpdateAppState(ApplicationProcessState.FOREGROUND); - assertThat(oldSessionId).isEqualTo(SessionManager.getInstance().perfSession().sessionId()); - } - - @Test - public void testOnUpdateAppStateGeneratesNewSessionIdOnForegroundState() { - String oldSessionId = SessionManager.getInstance().perfSession().sessionId(); - - assertThat(oldSessionId).isNotNull(); - assertThat(oldSessionId).isEqualTo(SessionManager.getInstance().perfSession().sessionId()); - - SessionManager.getInstance().onUpdateAppState(ApplicationProcessState.FOREGROUND); - assertThat(oldSessionId).isNotEqualTo(SessionManager.getInstance().perfSession().sessionId()); - } - - @Test - public void testOnUpdateAppStateDoesntGenerateNewSessionIdOnBackgroundState() { - String oldSessionId = SessionManager.getInstance().perfSession().sessionId(); - - assertThat(oldSessionId).isNotNull(); - assertThat(oldSessionId).isEqualTo(SessionManager.getInstance().perfSession().sessionId()); - - SessionManager.getInstance().onUpdateAppState(ApplicationProcessState.BACKGROUND); - assertThat(oldSessionId).isEqualTo(SessionManager.getInstance().perfSession().sessionId()); - } - - @Test - public void testOnUpdateAppStateGeneratesNewSessionIdOnBackgroundStateIfPerfSessionExpires() { - when(mockPerfSession.isSessionRunningTooLong()).thenReturn(true); - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - String oldSessionId = testSessionManager.perfSession().sessionId(); - - assertThat(oldSessionId).isNotNull(); - assertThat(oldSessionId).isEqualTo(testSessionManager.perfSession().sessionId()); - - testSessionManager.onUpdateAppState(ApplicationProcessState.BACKGROUND); - assertThat(oldSessionId).isNotEqualTo(testSessionManager.perfSession().sessionId()); - } - - @Test - public void - testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsVerbose() { - forceVerboseSession(); - - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.onUpdateAppState(ApplicationProcessState.FOREGROUND); - - verify(mockGaugeManager) - .logGaugeMetadata( - anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class)); - } - - @Test - public void - testOnUpdateAppStateDoesntMakeGaugeManagerLogGaugeMetadataOnForegroundStateIfSessionIsNonVerbose() { - forceNonVerboseSession(); - - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.onUpdateAppState(ApplicationProcessState.FOREGROUND); - - verify(mockGaugeManager, never()) - .logGaugeMetadata( - anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class)); - } - - @Test - public void - testOnUpdateAppStateDoesntMakeGaugeManagerLogGaugeMetadataOnBackgroundStateEvenIfSessionIsVerbose() { - forceVerboseSession(); - - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.onUpdateAppState(ApplicationProcessState.BACKGROUND); - - verify(mockGaugeManager, never()) - .logGaugeMetadata( - anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class)); - } - - @Test - public void - testOnUpdateAppStateMakesGaugeManagerLogGaugeMetadataOnBackgroundAppStateIfSessionIsVerboseAndTimedOut() { - when(mockPerfSession.isSessionRunningTooLong()).thenReturn(true); - forceVerboseSession(); - - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.onUpdateAppState(ApplicationProcessState.BACKGROUND); - - verify(mockGaugeManager) - .logGaugeMetadata( - anyString(), nullable(com.google.firebase.perf.v1.ApplicationProcessState.class)); - } - - @Test - public void testOnUpdateAppStateMakesGaugeManagerStartCollectingGaugesIfSessionIsVerbose() { - forceVerboseSession(); - - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.onUpdateAppState(ApplicationProcessState.FOREGROUND); - - verify(mockGaugeManager) - .startCollectingGauges(AdditionalMatchers.not(eq(mockPerfSession)), any()); } // LogGaugeData on new perf session when Verbose @@ -210,60 +87,33 @@ public void testOnUpdateAppStateMakesGaugeManagerStartCollectingGaugesIfSessionI // Mark Session as expired after time limit. @Test - public void testOnUpdateAppStateMakesGaugeManagerStopCollectingGaugesIfSessionIsNonVerbose() { + public void testUpdatePerfSessionMakesGaugeManagerStopCollectingGaugesIfSessionIsNonVerbose() { forceNonVerboseSession(); SessionManager testSessionManager = new SessionManager(mockGaugeManager, mockPerfSession, mockAppStateMonitor); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId")); + testSessionManager.updatePerfSession(createTestSession(1)); verify(mockGaugeManager).stopCollectingGauges(); } @Test - public void testOnUpdateAppStateMakesGaugeManagerStopCollectingGaugesWhenSessionsDisabled() { + public void testUpdatePerfSessionMakesGaugeManagerStopCollectingGaugesWhenSessionsDisabled() { forceSessionsFeatureDisabled(); SessionManager testSessionManager = - new SessionManager( - mockGaugeManager, PerfSession.createWithId("testSessionId"), mockAppStateMonitor); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2")); + new SessionManager(mockGaugeManager, createTestSession(1), mockAppStateMonitor); + testSessionManager.updatePerfSession(createTestSession(2)); verify(mockGaugeManager).stopCollectingGauges(); } - @Test - public void testGaugeMetadataIsFlushedOnlyWhenNewVerboseSessionIsCreated() { - when(mockPerfSession.isSessionRunningTooLong()).thenReturn(false); - - // Start with a non verbose session - forceNonVerboseSession(); - SessionManager testSessionManager = - new SessionManager( - mockGaugeManager, PerfSession.createWithId("testSessionId1"), mockAppStateMonitor); - - verify(mockGaugeManager, times(0)) - .logGaugeMetadata( - eq("testSessionId1"), - eq(com.google.firebase.perf.v1.ApplicationProcessState.FOREGROUND)); - - // Forcing a verbose session will enable Gauge collection - forceVerboseSession(); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2")); - verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId2"), any()); - - // Force a non-verbose session and verify if we are not logging metadata - forceVerboseSession(); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId3")); - verify(mockGaugeManager, times(1)).logGaugeMetadata(eq("testSessionId3"), any()); - } - @Test public void testSessionIdDoesNotUpdateIfPerfSessionRunsTooLong() { Timer mockTimer = mock(Timer.class); when(mockClock.getTime()).thenReturn(mockTimer); - PerfSession session = new PerfSession("sessionId", mockClock); + PerfSession session = new PerfSession(testSessionId(1), mockClock); SessionManager testSessionManager = new SessionManager(mockGaugeManager, session, mockAppStateMonitor); @@ -273,26 +123,29 @@ public void testSessionIdDoesNotUpdateIfPerfSessionRunsTooLong() { .thenReturn(TimeUnit.HOURS.toMicros(5)); // Default Max Session Length is 4 hours assertThat(session.isSessionRunningTooLong()).isTrue(); - assertThat(testSessionManager.perfSession().sessionId()).isEqualTo("sessionId"); + assertThat(testSessionManager.perfSession().sessionId()).isEqualTo(testSessionId(1)); } @Test - public void testPerfSessionExpiredMakesGaugeManagerStopsCollectingGaugesIfSessionIsVerbose() { - forceVerboseSession(); + public void testUpdatePerfSessionStartsCollectingGaugesIfSessionIsVerbose() { Timer mockTimer = mock(Timer.class); when(mockClock.getTime()).thenReturn(mockTimer); + when(mockAppStateMonitor.getAppState()).thenReturn(ApplicationProcessState.FOREGROUND); - PerfSession session = new PerfSession("sessionId", mockClock); - SessionManager testSessionManager = - new SessionManager(mockGaugeManager, session, mockAppStateMonitor); + PerfSession previousSession = createTestSession(1); + previousSession.setGaugeAndEventCollectionEnabled(false); - assertThat(session.isSessionRunningTooLong()).isFalse(); + PerfSession newSession = createTestSession(2); + newSession.setGaugeAndEventCollectionEnabled(true); - when(mockTimer.getDurationMicros()) - .thenReturn(TimeUnit.HOURS.toMicros(5)); // Default Max Session Length is 4 hours + SessionManager testSessionManager = + new SessionManager(mockGaugeManager, previousSession, mockAppStateMonitor); + testSessionManager.updatePerfSession(newSession); + testSessionManager.setApplicationContext(mockApplicationContext); - assertThat(session.isSessionRunningTooLong()).isTrue(); - verify(mockGaugeManager, times(0)).logGaugeMetadata(any(), any()); + verify(mockGaugeManager, times(1)).initializeGaugeMetadataManager(mockApplicationContext); + verify(mockGaugeManager, times(1)) + .startCollectingGauges(newSession, ApplicationProcessState.FOREGROUND); } @Test @@ -303,7 +156,7 @@ public void testPerfSession_sessionAwareObjects_doesntNotifyIfNotRegistered() { FakeSessionAwareObject spySessionAwareObjectOne = spy(new FakeSessionAwareObject()); FakeSessionAwareObject spySessionAwareObjectTwo = spy(new FakeSessionAwareObject()); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId1")); + testSessionManager.updatePerfSession(createTestSession(1)); verify(spySessionAwareObjectOne, never()) .updateSession(ArgumentMatchers.nullable(PerfSession.class)); @@ -322,8 +175,8 @@ public void testPerfSession_sessionAwareObjects_NotifiesIfRegistered() { testSessionManager.registerForSessionUpdates(new WeakReference<>(spySessionAwareObjectOne)); testSessionManager.registerForSessionUpdates(new WeakReference<>(spySessionAwareObjectTwo)); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId1")); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2")); + testSessionManager.updatePerfSession(createTestSession(1)); + testSessionManager.updatePerfSession(createTestSession(2)); verify(spySessionAwareObjectOne, times(2)) .updateSession(ArgumentMatchers.nullable(PerfSession.class)); @@ -347,11 +200,11 @@ public void testPerfSession_sessionAwareObjects_DoesNotNotifyIfUnregistered() { testSessionManager.registerForSessionUpdates(weakSpySessionAwareObjectOne); testSessionManager.registerForSessionUpdates(weakSpySessionAwareObjectTwo); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId1")); + testSessionManager.updatePerfSession(createTestSession(1)); testSessionManager.unregisterForSessionUpdates(weakSpySessionAwareObjectOne); testSessionManager.unregisterForSessionUpdates(weakSpySessionAwareObjectTwo); - testSessionManager.updatePerfSession(PerfSession.createWithId("testSessionId2")); + testSessionManager.updatePerfSession(createTestSession(2)); verify(spySessionAwareObjectOne, times(1)) .updateSession(ArgumentMatchers.nullable(PerfSession.class)); diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java index 5090d66c8b9..61ae0c57132 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeManagerTest.java @@ -15,6 +15,8 @@ package com.google.firebase.perf.session.gauges; import static com.google.common.truth.Truth.assertThat; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.createTestSession; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.testSessionId; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doReturn; @@ -32,7 +34,6 @@ import com.google.firebase.perf.config.ConfigResolver; import com.google.firebase.perf.session.PerfSession; import com.google.firebase.perf.transport.TransportManager; -import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.Timer; import com.google.firebase.perf.v1.AndroidMemoryReading; import com.google.firebase.perf.v1.ApplicationProcessState; @@ -124,7 +125,7 @@ public void setUp() { @Test public void testStartCollectingGaugesStartsCollectingMetricsInBackgroundState() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); verify(fakeCpuGaugeCollector) .startCollecting( @@ -138,7 +139,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInBackgroundState() @Test public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.FOREGROUND); verify(fakeCpuGaugeCollector) .startCollecting( @@ -153,7 +154,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() @Test public void testStartCollectingGaugesDoesNotStartCollectingMetricsWithUnknownApplicationProcessState() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges( fakeSession, ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN); verify(fakeCpuGaugeCollector, never()) @@ -167,7 +168,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithValidFrequencyInBackground() { // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyBackgroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.BACKGROUND); // Verify that Cpu metric collection is not started @@ -180,7 +181,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyBackgroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.BACKGROUND); // Verify that Cpu metric collection is not started @@ -197,7 +198,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() startCollectingGaugesOnBackground_invalidMemoryCaptureMs_onlyDisableMemoryCollection() { // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyBackgroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.BACKGROUND); // Verify that Memory metric collection is not started @@ -210,7 +211,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyBackgroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(2); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.BACKGROUND); // Verify that Memory metric collection is not started @@ -226,7 +227,7 @@ public void testStartCollectingGaugesStartsCollectingMetricsInForegroundState() public void stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithValidFrequency() { // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.FOREGROUND); // Verify that Cpu metric collection is not started @@ -239,7 +240,7 @@ public void stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithV // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(2); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); // Verify that Cpu metric collection is not started @@ -256,7 +257,7 @@ public void stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithV startCollectingGaugesOnForeground_invalidMemoryCaptureMs_onlyDisableMemoryCollection() { // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.FOREGROUND); // Verify that Memory metric collection is not started @@ -269,7 +270,7 @@ public void stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithV // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(2); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); // Verify that Memory metric collection is not started @@ -283,7 +284,7 @@ public void stopCollectingCPUMetric_invalidCPUCaptureFrequency_OtherMetricsWithV @Test public void testStartCollectingGaugesDoesNotStartAJobToConsumeMetricsWithUnknownAppState() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges( fakeSession, ApplicationProcessState.APPLICATION_PROCESS_STATE_UNKNOWN); assertThat(fakeScheduledExecutorService.isEmpty()).isTrue(); @@ -294,14 +295,14 @@ public void stopCollectingCPUMetrics_invalidCPUCaptureFrequency_appInForegrounf( // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); } @@ -311,14 +312,14 @@ public void stopCollectingGauges_invalidMemoryCollectionFrequency_appInForegroun // PASS 1: Test with 0 doReturn(0L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); // PASS 2: Test with -ve value doReturn(-25L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(2); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); } @@ -329,7 +330,7 @@ public void stopCollectingGauges_invalidGaugeCollectionFrequency_appInForeground doReturn(0L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); doReturn(0L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isTrue(); @@ -337,7 +338,7 @@ public void stopCollectingGauges_invalidGaugeCollectionFrequency_appInForeground doReturn(-25L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); doReturn(-25L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession2 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession2 = createTestSession(2); testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isTrue(); } @@ -347,7 +348,7 @@ public void startCollectingGauges_validGaugeCollectionFrequency_appInForeground( doReturn(25L).when(mockConfigResolver).getSessionsCpuCaptureFrequencyForegroundMs(); doReturn(15L).when(mockConfigResolver).getSessionsMemoryCaptureFrequencyForegroundMs(); - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.FOREGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); @@ -357,7 +358,7 @@ public void startCollectingGauges_validGaugeCollectionFrequency_appInForeground( @Test public void testStartCollectingGaugesStartsAJobToConsumeTheGeneratedMetrics() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); @@ -383,15 +384,15 @@ public void testStartCollectingGaugesStartsAJobToConsumeTheGeneratedMetrics() { getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric, fakeCpuMetricReading1, fakeCpuMetricReading2); + testSessionId(1), recordedGaugeMetric, fakeCpuMetricReading1, fakeCpuMetricReading2); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric, fakeMemoryMetricReading1, fakeMemoryMetricReading2); + testSessionId(1), recordedGaugeMetric, fakeMemoryMetricReading1, fakeMemoryMetricReading2); } @Test public void testStopCollectingGaugesStopsCollectingAllGaugeMetrics() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); verify(fakeCpuGaugeCollector) @@ -405,7 +406,7 @@ public void testStopCollectingGaugesStopsCollectingAllGaugeMetrics() { @Test public void testStopCollectingGaugesCreatesOneLastJobToConsumeAnyPendingMetrics() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); assertThat(fakeScheduledExecutorService.isEmpty()).isFalse(); @@ -426,14 +427,14 @@ public void testStopCollectingGaugesCreatesOneLastJobToConsumeAnyPendingMetrics( GaugeMetric recordedGaugeMetric = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric, fakeCpuMetricReading); + testSessionId(1), recordedGaugeMetric, fakeCpuMetricReading); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric, fakeMemoryMetricReading); + testSessionId(1), recordedGaugeMetric, fakeMemoryMetricReading); } @Test public void testGaugeManagerClearsTheQueueEachRun() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); @@ -465,7 +466,7 @@ public void testGaugeManagerClearsTheQueueEachRun() { @Test public void testStartingGaugeManagerWithNewSessionIdButSameAppState() { - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); // Start collecting Gauges. testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.BACKGROUND); @@ -479,9 +480,9 @@ public void testStartingGaugeManagerWithNewSessionIdButSameAppState() { GaugeMetric recordedGaugeMetric1 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeCpuMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeCpuMetricReading1); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeMemoryMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeMemoryMetricReading1); // One Cpu and Memory metric was added when the gauge was collecting for the previous sessionId. CpuMetricReading fakeCpuMetricReading2 = createFakeCpuMetricReading(400, 500); @@ -490,7 +491,7 @@ public void testStartingGaugeManagerWithNewSessionIdButSameAppState() { createFakeAndroidMetricReading(/* currentUsedAppJavaHeapMemoryKb= */ 2345); fakeMemoryGaugeCollector.memoryMetricReadings.add(fakeMemoryMetricReading2); - PerfSession fakeSession2 = new PerfSession("sessionId2", new Clock()); + PerfSession fakeSession2 = createTestSession(2); // Start collecting gauges for new session, but same app state. testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.BACKGROUND); @@ -500,9 +501,9 @@ public void testStartingGaugeManagerWithNewSessionIdButSameAppState() { GaugeMetric recordedGaugeMetric2 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeCpuMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeCpuMetricReading2); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeMemoryMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeMemoryMetricReading2); // Collect some more Cpu and Memory metrics and verify that they're associated with new // sessionId and state. @@ -516,14 +517,14 @@ public void testStartingGaugeManagerWithNewSessionIdButSameAppState() { GaugeMetric recordedGaugeMetric3 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId2", recordedGaugeMetric3, fakeCpuMetricReading3); + testSessionId(2), recordedGaugeMetric3, fakeCpuMetricReading3); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId2", recordedGaugeMetric3, fakeMemoryMetricReading3); + testSessionId(2), recordedGaugeMetric3, fakeMemoryMetricReading3); } @Test public void testStartGaugeManagerWithSameSessionIdButDifferentAppState() { - PerfSession fakeSession = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession = createTestSession(1); // Start collecting Gauges. testGaugeManager.startCollectingGauges(fakeSession, ApplicationProcessState.BACKGROUND); @@ -537,9 +538,9 @@ public void testStartGaugeManagerWithSameSessionIdButDifferentAppState() { GaugeMetric recordedGaugeMetric1 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeCpuMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeCpuMetricReading1); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeMemoryMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeMemoryMetricReading1); // One Cpu and Memory metric was added when the gauge was collecting for the previous sessionId. CpuMetricReading fakeCpuMetricReading2 = createFakeCpuMetricReading(400, 500); @@ -556,9 +557,9 @@ public void testStartGaugeManagerWithSameSessionIdButDifferentAppState() { GaugeMetric recordedGaugeMetric2 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeCpuMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeCpuMetricReading2); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeMemoryMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeMemoryMetricReading2); // Collect some more Cpu and Memory metrics and verify that they're associated with new // sessionId and state. @@ -572,14 +573,14 @@ public void testStartGaugeManagerWithSameSessionIdButDifferentAppState() { GaugeMetric recordedGaugeMetric3 = getLastRecordedGaugeMetric(ApplicationProcessState.FOREGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric3, fakeCpuMetricReading3); + testSessionId(1), recordedGaugeMetric3, fakeCpuMetricReading3); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric3, fakeMemoryMetricReading3); + testSessionId(1), recordedGaugeMetric3, fakeMemoryMetricReading3); } @Test public void testStartGaugeManagerWithNewSessionIdAndNewAppState() { - PerfSession fakeSession1 = new PerfSession("sessionId", new Clock()); + PerfSession fakeSession1 = createTestSession(1); // Start collecting Gauges. testGaugeManager.startCollectingGauges(fakeSession1, ApplicationProcessState.BACKGROUND); @@ -593,9 +594,9 @@ public void testStartGaugeManagerWithNewSessionIdAndNewAppState() { GaugeMetric recordedGaugeMetric1 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeCpuMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeCpuMetricReading1); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric1, fakeMemoryMetricReading1); + testSessionId(1), recordedGaugeMetric1, fakeMemoryMetricReading1); // One Cpu and Memory metric was added when the gauge was collecting for the previous sessionId. CpuMetricReading fakeCpuMetricReading2 = createFakeCpuMetricReading(400, 500); @@ -604,7 +605,7 @@ public void testStartGaugeManagerWithNewSessionIdAndNewAppState() { createFakeAndroidMetricReading(/* currentUsedAppJavaHeapMemoryKb= */ 2345); fakeMemoryGaugeCollector.memoryMetricReadings.add(fakeMemoryMetricReading2); - PerfSession fakeSession2 = new PerfSession("sessionId2", new Clock()); + PerfSession fakeSession2 = createTestSession(2); // Start collecting gauges for new session and new app state testGaugeManager.startCollectingGauges(fakeSession2, ApplicationProcessState.FOREGROUND); @@ -614,9 +615,9 @@ public void testStartGaugeManagerWithNewSessionIdAndNewAppState() { GaugeMetric recordedGaugeMetric2 = getLastRecordedGaugeMetric(ApplicationProcessState.BACKGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeCpuMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeCpuMetricReading2); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId", recordedGaugeMetric2, fakeMemoryMetricReading2); + testSessionId(1), recordedGaugeMetric2, fakeMemoryMetricReading2); // Collect some more Cpu and Memory metrics and verify that they're associated with new // sessionId and state. @@ -630,9 +631,9 @@ public void testStartGaugeManagerWithNewSessionIdAndNewAppState() { GaugeMetric recordedGaugeMetric3 = getLastRecordedGaugeMetric(ApplicationProcessState.FOREGROUND, 1); assertThatCpuGaugeMetricWasSentToTransport( - "sessionId2", recordedGaugeMetric3, fakeCpuMetricReading3); + testSessionId(2), recordedGaugeMetric3, fakeCpuMetricReading3); assertThatMemoryGaugeMetricWasSentToTransport( - "sessionId2", recordedGaugeMetric3, fakeMemoryMetricReading3); + testSessionId(2), recordedGaugeMetric3, fakeMemoryMetricReading3); } @Test @@ -641,13 +642,13 @@ public void testLogGaugeMetadataSendDataToTransport() { when(fakeGaugeMetadataManager.getMaxAppJavaHeapMemoryKb()).thenReturn(1000); when(fakeGaugeMetadataManager.getMaxEncouragedAppJavaHeapMemoryKb()).thenReturn(800); - testGaugeManager.logGaugeMetadata("sessionId", ApplicationProcessState.FOREGROUND); + testGaugeManager.logGaugeMetadata(testSessionId(1), ApplicationProcessState.FOREGROUND); GaugeMetric recordedGaugeMetric = getLastRecordedGaugeMetric(ApplicationProcessState.FOREGROUND, 1); GaugeMetadata recordedGaugeMetadata = recordedGaugeMetric.getGaugeMetadata(); - assertThat(recordedGaugeMetric.getSessionId()).isEqualTo("sessionId"); + assertThat(recordedGaugeMetric.getSessionId()).isEqualTo(testSessionId(1)); assertThat(recordedGaugeMetadata.getDeviceRamSizeKb()) .isEqualTo(fakeGaugeMetadataManager.getDeviceRamSizeKb()); @@ -658,7 +659,7 @@ public void testLogGaugeMetadataSendDataToTransport() { } @Test - public void testLogGaugeMetadataDoesntLogWhenGaugeMetadataManagerNotAvailable() { + public void testLogGaugeMetadataDoesNotLogWhenGaugeMetadataManagerNotAvailable() { testGaugeManager = new GaugeManager( @@ -669,7 +670,8 @@ public void testLogGaugeMetadataDoesntLogWhenGaugeMetadataManagerNotAvailable() new Lazy<>(() -> fakeCpuGaugeCollector), new Lazy<>(() -> fakeMemoryGaugeCollector)); - assertThat(testGaugeManager.logGaugeMetadata("sessionId", ApplicationProcessState.FOREGROUND)) + assertThat( + testGaugeManager.logGaugeMetadata(testSessionId(1), ApplicationProcessState.FOREGROUND)) .isFalse(); } @@ -685,18 +687,20 @@ public void testLogGaugeMetadataLogsAfterApplicationContextIsSet() { new Lazy<>(() -> fakeCpuGaugeCollector), new Lazy<>(() -> fakeMemoryGaugeCollector)); - assertThat(testGaugeManager.logGaugeMetadata("sessionId", ApplicationProcessState.FOREGROUND)) + assertThat( + testGaugeManager.logGaugeMetadata(testSessionId(1), ApplicationProcessState.FOREGROUND)) .isFalse(); testGaugeManager.initializeGaugeMetadataManager(ApplicationProvider.getApplicationContext()); - assertThat(testGaugeManager.logGaugeMetadata("sessionId", ApplicationProcessState.FOREGROUND)) + assertThat( + testGaugeManager.logGaugeMetadata(testSessionId(1), ApplicationProcessState.FOREGROUND)) .isTrue(); GaugeMetric recordedGaugeMetric = getLastRecordedGaugeMetric(ApplicationProcessState.FOREGROUND, 1); GaugeMetadata recordedGaugeMetadata = recordedGaugeMetric.getGaugeMetadata(); - assertThat(recordedGaugeMetric.getSessionId()).isEqualTo("sessionId"); + assertThat(recordedGaugeMetric.getSessionId()).isEqualTo(testSessionId(1)); } @Test diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeMetadataManagerTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeMetadataManagerTest.java index 292747121dd..1592f77e5ad 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeMetadataManagerTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/session/gauges/GaugeMetadataManagerTest.java @@ -15,26 +15,20 @@ package com.google.firebase.perf.session.gauges; import static com.google.common.truth.Truth.assertThat; -import static java.nio.charset.StandardCharsets.UTF_8; import static org.mockito.MockitoAnnotations.initMocks; import static org.robolectric.Shadows.shadowOf; import android.app.ActivityManager; import android.content.Context; -import android.os.Environment; import androidx.test.core.app.ApplicationProvider; import com.google.firebase.perf.FirebasePerformanceTestBase; import com.google.firebase.perf.util.StorageUnit; -import java.io.File; import java.io.IOException; -import java.io.Writer; -import java.nio.file.Files; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.robolectric.RobolectricTestRunner; -import org.robolectric.shadows.ShadowEnvironment; /** Unit tests for {@link com.google.firebase.perf.session.gauges.GaugeMetadataManager} */ @RunWith(RobolectricTestRunner.class) @@ -49,12 +43,11 @@ public class GaugeMetadataManagerTest extends FirebasePerformanceTestBase { @Mock private Runtime runtime; private ActivityManager activityManager; - private Context appContext; @Before public void setUp() { initMocks(this); - appContext = ApplicationProvider.getApplicationContext(); + Context appContext = ApplicationProvider.getApplicationContext(); activityManager = (ActivityManager) appContext.getSystemService(Context.ACTIVITY_SERVICE); mockMemory(); @@ -90,62 +83,5 @@ public void testGetDeviceRamSize_returnsExpectedValue() throws IOException { int ramSize = testGaugeMetadataManager.getDeviceRamSizeKb(); assertThat(ramSize).isEqualTo(StorageUnit.BYTES.toKilobytes(DEVICE_RAM_SIZE_BYTES)); - assertThat(ramSize).isEqualTo(testGaugeMetadataManager.readTotalRAM(createFakeMemInfoFile())); } - - /** @return The file path of this fake file which can be used to read the file. */ - private String createFakeMemInfoFile() throws IOException { - // Due to file permission issues on forge, it's easiest to just write this file to the emulated - // robolectric external storage. - ShadowEnvironment.setExternalStorageState(Environment.MEDIA_MOUNTED); - - File file = new File(Environment.getExternalStorageDirectory(), "FakeProcMemInfoFile"); - Writer fileWriter; - - fileWriter = Files.newBufferedWriter(file.toPath(), UTF_8); - fileWriter.write(MEM_INFO_CONTENTS); - fileWriter.close(); - - return file.getAbsolutePath(); - } - - private static final String MEM_INFO_CONTENTS = - "MemTotal: " - + DEVICE_RAM_SIZE_KB - + " kB\n" - + "MemFree: 542404 kB\n" - + "MemAvailable: 1392324 kB\n" - + "Buffers: 64292 kB\n" - + "Cached: 826180 kB\n" - + "SwapCached: 4196 kB\n" - + "Active: 934768 kB\n" - + "Inactive: 743812 kB\n" - + "Active(anon): 582132 kB\n" - + "Inactive(anon): 241500 kB\n" - + "Active(file): 352636 kB\n" - + "Inactive(file): 502312 kB\n" - + "Unevictable: 5148 kB\n" - + "Mlocked: 256 kB\n" - + "SwapTotal: 524284 kB\n" - + "SwapFree: 484800 kB\n" - + "Dirty: 4 kB\n" - + "Writeback: 0 kB\n" - + "AnonPages: 789404 kB\n" - + "Mapped: 241928 kB\n" - + "Shmem: 30632 kB\n" - + "Slab: 122320 kB\n" - + "SReclaimable: 42552 kB\n" - + "SUnreclaim: 79768 kB\n" - + "KernelStack: 22816 kB\n" - + "PageTables: 35344 kB\n" - + "NFS_Unstable: 0 kB\n" - + "Bounce: 0 kB\n" - + "WritebackTmp: 0 kB\n" - + "CommitLimit: 2042280 kB\n" - + "Committed_AS: 76623352 kB\n" - + "VmallocTotal: 251658176 kB\n" - + "VmallocUsed: 232060 kB\n" - + "VmallocChunk: 251347444 kB\n" - + "NvMapMemFree: 48640 kB\n" - + "NvMapMemUsed: 471460 kB\n"; } diff --git a/firebase-perf/src/test/java/com/google/firebase/perf/transport/TransportManagerTest.java b/firebase-perf/src/test/java/com/google/firebase/perf/transport/TransportManagerTest.java index 5376265aa0e..b10a48e135f 100644 --- a/firebase-perf/src/test/java/com/google/firebase/perf/transport/TransportManagerTest.java +++ b/firebase-perf/src/test/java/com/google/firebase/perf/transport/TransportManagerTest.java @@ -15,6 +15,8 @@ package com.google.firebase.perf.transport; import static com.google.common.truth.Truth.assertThat; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.createTestSession; +import static com.google.firebase.perf.session.FirebaseSessionsTestHelperKt.testSessionId; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.clearInvocations; import static org.mockito.Mockito.mock; @@ -40,7 +42,6 @@ import com.google.firebase.perf.config.ConfigResolver; import com.google.firebase.perf.session.SessionManager; import com.google.firebase.perf.shadows.ShadowPreconditions; -import com.google.firebase.perf.util.Clock; import com.google.firebase.perf.util.Constants; import com.google.firebase.perf.util.Constants.CounterNames; import com.google.firebase.perf.v1.AndroidMemoryReading; @@ -1168,8 +1169,7 @@ public void logGaugeMetric_globalCustomAttributesAreNotAdded() { public void logTraceMetric_sessionEnabled_doesNotStripOffSessionId() { TraceMetric.Builder validTrace = createValidTraceMetric().toBuilder(); List perfSessions = new ArrayList<>(); - perfSessions.add( - new com.google.firebase.perf.session.PerfSession("fakeSessionId", new Clock()).build()); + perfSessions.add(createTestSession(1).build()); validTrace.addAllPerfSessions(perfSessions); testTransportManager.log(validTrace.build()); @@ -1178,7 +1178,7 @@ public void logTraceMetric_sessionEnabled_doesNotStripOffSessionId() { PerfMetric loggedPerfMetric = getLastLoggedEvent(times(1)); assertThat(loggedPerfMetric.getTraceMetric().getPerfSessionsCount()).isEqualTo(1); assertThat(loggedPerfMetric.getTraceMetric().getPerfSessions(0).getSessionId()) - .isEqualTo("fakeSessionId"); + .isEqualTo(testSessionId(1)); } @Test @@ -1186,8 +1186,7 @@ public void logNetworkMetric_sessionEnabled_doesNotStripOffSessionId() { NetworkRequestMetric.Builder validNetworkRequest = createValidNetworkRequestMetric().toBuilder(); List perfSessions = new ArrayList<>(); - perfSessions.add( - new com.google.firebase.perf.session.PerfSession("fakeSessionId", new Clock()).build()); + perfSessions.add(createTestSession(1).build()); validNetworkRequest.clearPerfSessions().addAllPerfSessions(perfSessions); testTransportManager.log(validNetworkRequest.build()); @@ -1196,7 +1195,7 @@ public void logNetworkMetric_sessionEnabled_doesNotStripOffSessionId() { PerfMetric loggedPerfMetric = getLastLoggedEvent(times(1)); assertThat(loggedPerfMetric.getNetworkRequestMetric().getPerfSessionsCount()).isEqualTo(1); assertThat(loggedPerfMetric.getNetworkRequestMetric().getPerfSessions(0).getSessionId()) - .isEqualTo("fakeSessionId"); + .isEqualTo(testSessionId(1)); } @Test diff --git a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt index 8d3548c8f4b..4b636a155e0 100644 --- a/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt +++ b/firebase-sessions/src/main/kotlin/com/google/firebase/sessions/api/FirebaseSessionsDependencies.kt @@ -40,19 +40,6 @@ object FirebaseSessionsDependencies { */ @JvmStatic fun addDependency(subscriberName: SessionSubscriber.Name) { - if (subscriberName == SessionSubscriber.Name.PERFORMANCE) { - throw IllegalArgumentException( - """ - Incompatible versions of Firebase Perf and Firebase Sessions. - A safe combination would be: - firebase-sessions:1.1.0 - firebase-crashlytics:18.5.0 - firebase-perf:20.5.0 - For more information contact Firebase Support. - """ - .trimIndent() - ) - } if (dependencies.containsKey(subscriberName)) { Log.d(TAG, "Dependency $subscriberName already added.") return