Skip to content

Commit c0b7e27

Browse files
committed
Clean up tests
1 parent ebea05b commit c0b7e27

File tree

3 files changed

+207
-283
lines changed

3 files changed

+207
-283
lines changed

firebase-sessions/src/test/kotlin/com/google/firebase/sessions/settings/RemoteSettingsTest.kt

Lines changed: 106 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ package com.google.firebase.sessions.settings
1919
import androidx.test.ext.junit.runners.AndroidJUnit4
2020
import com.google.common.truth.Truth.assertThat
2121
import com.google.firebase.FirebaseApp
22-
import com.google.firebase.installations.FirebaseInstallationsApi
23-
import com.google.firebase.sessions.ApplicationInfo
2422
import com.google.firebase.sessions.SessionEvents
25-
import com.google.firebase.sessions.TimeProvider
2623
import com.google.firebase.sessions.testing.FakeFirebaseApp
2724
import com.google.firebase.sessions.testing.FakeFirebaseInstallations
2825
import com.google.firebase.sessions.testing.FakeRemoteConfigFetcher
@@ -31,55 +28,46 @@ import com.google.firebase.sessions.testing.FakeTimeProvider
3128
import kotlin.time.Duration.Companion.minutes
3229
import kotlin.time.Duration.Companion.seconds
3330
import kotlinx.coroutines.Dispatchers
34-
import kotlinx.coroutines.ExperimentalCoroutinesApi
3531
import kotlinx.coroutines.delay
3632
import kotlinx.coroutines.launch
37-
import kotlinx.coroutines.test.UnconfinedTestDispatcher
38-
import kotlinx.coroutines.test.runCurrent
3933
import kotlinx.coroutines.test.runTest
4034
import kotlinx.coroutines.withTimeout
4135
import org.json.JSONObject
4236
import org.junit.After
4337
import org.junit.Test
4438
import org.junit.runner.RunWith
4539

46-
@OptIn(ExperimentalCoroutinesApi::class)
4740
@RunWith(AndroidJUnit4::class)
4841
class RemoteSettingsTest {
4942

5043
@Test
51-
fun remoteSettings_successfulFetchCachesValues() =
52-
runTest(UnconfinedTestDispatcher()) {
53-
val firebaseApp = FakeFirebaseApp().firebaseApp
54-
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
55-
val fakeFetcher = FakeRemoteConfigFetcher()
56-
57-
val remoteSettings =
58-
buildRemoteSettings(
59-
FakeTimeProvider(),
60-
firebaseInstallations,
61-
SessionEvents.getApplicationInfo(firebaseApp),
62-
fakeFetcher,
63-
FakeSettingsCache(),
64-
)
65-
66-
runCurrent()
44+
fun remoteSettings_successfulFetchCachesValues() = runTest {
45+
val firebaseApp = FakeFirebaseApp().firebaseApp
46+
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
47+
val fakeFetcher = FakeRemoteConfigFetcher()
6748

68-
assertThat(remoteSettings.sessionEnabled).isNull()
69-
assertThat(remoteSettings.samplingRate).isNull()
70-
assertThat(remoteSettings.sessionRestartTimeout).isNull()
49+
val remoteSettings =
50+
RemoteSettings(
51+
FakeTimeProvider(),
52+
firebaseInstallations,
53+
SessionEvents.getApplicationInfo(firebaseApp),
54+
fakeFetcher,
55+
FakeSettingsCache(),
56+
)
7157

72-
fakeFetcher.responseJSONObject = JSONObject(VALID_RESPONSE)
73-
remoteSettings.updateSettings()
58+
assertThat(remoteSettings.sessionEnabled).isNull()
59+
assertThat(remoteSettings.samplingRate).isNull()
60+
assertThat(remoteSettings.sessionRestartTimeout).isNull()
7461

75-
runCurrent()
62+
fakeFetcher.responseJSONObject = JSONObject(VALID_RESPONSE)
63+
remoteSettings.updateSettings()
7664

77-
assertThat(remoteSettings.sessionEnabled).isFalse()
78-
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
79-
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
65+
assertThat(remoteSettings.sessionEnabled).isFalse()
66+
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
67+
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
8068

81-
remoteSettings.clearCachedSettings()
82-
}
69+
remoteSettings.clearCachedSettings()
70+
}
8371

8472
@Test
8573
fun remoteSettings_successfulFetchWithLessConfigsCachesOnlyReceivedValues() = runTest {
@@ -88,16 +76,14 @@ class RemoteSettingsTest {
8876
val fakeFetcher = FakeRemoteConfigFetcher()
8977

9078
val remoteSettings =
91-
buildRemoteSettings(
79+
RemoteSettings(
9280
FakeTimeProvider(),
9381
firebaseInstallations,
9482
SessionEvents.getApplicationInfo(firebaseApp),
9583
fakeFetcher,
9684
FakeSettingsCache(),
9785
)
9886

99-
runCurrent()
100-
10187
assertThat(remoteSettings.sessionEnabled).isNull()
10288
assertThat(remoteSettings.samplingRate).isNull()
10389
assertThat(remoteSettings.sessionRestartTimeout).isNull()
@@ -107,8 +93,6 @@ class RemoteSettingsTest {
10793
fakeFetcher.responseJSONObject = fetchedResponse
10894
remoteSettings.updateSettings()
10995

110-
runCurrent()
111-
11296
assertThat(remoteSettings.sessionEnabled).isNull()
11397
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
11498
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
@@ -124,7 +108,7 @@ class RemoteSettingsTest {
124108
val fakeTimeProvider = FakeTimeProvider()
125109

126110
val remoteSettings =
127-
buildRemoteSettings(
111+
RemoteSettings(
128112
fakeTimeProvider,
129113
firebaseInstallations,
130114
SessionEvents.getApplicationInfo(firebaseApp),
@@ -137,8 +121,6 @@ class RemoteSettingsTest {
137121
fakeFetcher.responseJSONObject = fetchedResponse
138122
remoteSettings.updateSettings()
139123

140-
runCurrent()
141-
142124
assertThat(remoteSettings.sessionEnabled).isFalse()
143125
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
144126
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
@@ -152,8 +134,6 @@ class RemoteSettingsTest {
152134
fakeFetcher.responseJSONObject = fetchedResponse
153135
remoteSettings.updateSettings()
154136

155-
runCurrent()
156-
157137
assertThat(remoteSettings.sessionEnabled).isTrue()
158138
assertThat(remoteSettings.samplingRate).isEqualTo(0.25)
159139
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(20.minutes)
@@ -162,110 +142,99 @@ class RemoteSettingsTest {
162142
}
163143

164144
@Test
165-
fun remoteSettings_successfulFetchWithEmptyConfigRetainsOldConfigs() =
166-
runTest(UnconfinedTestDispatcher()) {
167-
val firebaseApp = FakeFirebaseApp().firebaseApp
168-
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
169-
val fakeFetcher = FakeRemoteConfigFetcher()
170-
val fakeTimeProvider = FakeTimeProvider()
171-
172-
val remoteSettings =
173-
buildRemoteSettings(
174-
fakeTimeProvider,
175-
firebaseInstallations,
176-
SessionEvents.getApplicationInfo(firebaseApp),
177-
fakeFetcher,
178-
FakeSettingsCache(),
179-
)
180-
181-
val fetchedResponse = JSONObject(VALID_RESPONSE)
182-
fetchedResponse.getJSONObject("app_quality").put("cache_duration", 1)
183-
fakeFetcher.responseJSONObject = fetchedResponse
184-
remoteSettings.updateSettings()
185-
186-
runCurrent()
187-
fakeTimeProvider.addInterval(31.seconds)
188-
189-
assertThat(remoteSettings.sessionEnabled).isFalse()
190-
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
191-
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
192-
193-
fetchedResponse.remove("app_quality")
194-
195-
// Sleep for a second before updating configs
196-
Thread.sleep(2000)
197-
198-
fakeFetcher.responseJSONObject = fetchedResponse
199-
remoteSettings.updateSettings()
200-
201-
runCurrent()
202-
Thread.sleep(30)
203-
204-
assertThat(remoteSettings.sessionEnabled).isFalse()
205-
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
206-
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
207-
208-
remoteSettings.clearCachedSettings()
209-
}
145+
fun remoteSettings_successfulFetchWithEmptyConfigRetainsOldConfigs() = runTest {
146+
val firebaseApp = FakeFirebaseApp().firebaseApp
147+
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
148+
val fakeFetcher = FakeRemoteConfigFetcher()
149+
val fakeTimeProvider = FakeTimeProvider()
150+
151+
val remoteSettings =
152+
RemoteSettings(
153+
fakeTimeProvider,
154+
firebaseInstallations,
155+
SessionEvents.getApplicationInfo(firebaseApp),
156+
fakeFetcher,
157+
FakeSettingsCache(),
158+
)
159+
160+
val fetchedResponse = JSONObject(VALID_RESPONSE)
161+
fetchedResponse.getJSONObject("app_quality").put("cache_duration", 1)
162+
fakeFetcher.responseJSONObject = fetchedResponse
163+
remoteSettings.updateSettings()
164+
165+
fakeTimeProvider.addInterval(31.seconds)
166+
167+
assertThat(remoteSettings.sessionEnabled).isFalse()
168+
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
169+
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
170+
171+
fetchedResponse.remove("app_quality")
172+
173+
fakeFetcher.responseJSONObject = fetchedResponse
174+
remoteSettings.updateSettings()
175+
176+
assertThat(remoteSettings.sessionEnabled).isFalse()
177+
assertThat(remoteSettings.samplingRate).isEqualTo(0.75)
178+
assertThat(remoteSettings.sessionRestartTimeout).isEqualTo(40.minutes)
179+
180+
remoteSettings.clearCachedSettings()
181+
}
210182

211183
@Test
212-
fun remoteSettings_fetchWhileFetchInProgress() =
213-
runTest(UnconfinedTestDispatcher()) {
214-
// This test does:
215-
// 1. Do a fetch with a fake fetcher that will block for 3 seconds.
216-
// 2. While that is happening, do a second fetch.
217-
// - First fetch is still fetching, so second fetch should fall through to the mutex.
218-
// - Second fetch will be blocked until first completes.
219-
// - First fetch returns, should unblock the second fetch.
220-
// - Second fetch should go into mutex, sees cache is valid in "double check," exist early.
221-
// 3. After a fetch completes, do a third fetch.
222-
// - First fetch should have have updated the cache.
223-
// - Third fetch should exit even earlier, never having gone into the mutex.
224-
225-
val firebaseApp = FakeFirebaseApp().firebaseApp
226-
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
227-
val fakeFetcherWithDelay =
228-
FakeRemoteConfigFetcher(JSONObject(VALID_RESPONSE), networkDelay = 3.seconds)
229-
230-
fakeFetcherWithDelay.responseJSONObject
231-
.getJSONObject("app_quality")
232-
.put("sampling_rate", 0.125)
233-
234-
val remoteSettingsWithDelay =
235-
buildRemoteSettings(
236-
FakeTimeProvider(),
237-
firebaseInstallations,
238-
SessionEvents.getApplicationInfo(firebaseApp),
239-
configsFetcher = fakeFetcherWithDelay,
240-
FakeSettingsCache(),
241-
)
242-
243-
// Do the first fetch. This one should fetched the configsFetcher.
244-
val firstFetch = launch(Dispatchers.Default) { remoteSettingsWithDelay.updateSettings() }
245-
246-
// Wait a second, and then do the second fetch while first is still running.
247-
// This one should block until the first fetch completes, but then exit early.
248-
launch(Dispatchers.Default) {
249-
delay(1.seconds)
250-
remoteSettingsWithDelay.updateSettings()
251-
}
184+
fun remoteSettings_fetchWhileFetchInProgress() = runTest {
185+
// This test does:
186+
// 1. Do a fetch with a fake fetcher that will block for 3 seconds.
187+
// 2. While that is happening, do a second fetch.
188+
// - First fetch is still fetching, so second fetch should fall through to the mutex.
189+
// - Second fetch will be blocked until first completes.
190+
// - First fetch returns, should unblock the second fetch.
191+
// - Second fetch should go into mutex, sees cache is valid in "double check," exist early.
192+
// 3. After a fetch completes, do a third fetch.
193+
// - First fetch should have have updated the cache.
194+
// - Third fetch should exit even earlier, never having gone into the mutex.
195+
196+
val firebaseApp = FakeFirebaseApp().firebaseApp
197+
val firebaseInstallations = FakeFirebaseInstallations("FaKeFiD")
198+
val fakeFetcherWithDelay =
199+
FakeRemoteConfigFetcher(JSONObject(VALID_RESPONSE), networkDelay = 3.seconds)
200+
201+
fakeFetcherWithDelay.responseJSONObject.getJSONObject("app_quality").put("sampling_rate", 0.125)
202+
203+
val remoteSettingsWithDelay =
204+
RemoteSettings(
205+
FakeTimeProvider(),
206+
firebaseInstallations,
207+
SessionEvents.getApplicationInfo(firebaseApp),
208+
configsFetcher = fakeFetcherWithDelay,
209+
FakeSettingsCache(),
210+
)
252211

253-
// Wait until the first fetch is done, then do a third fetch.
254-
// This one should not even block, and exit early.
255-
firstFetch.join()
256-
withTimeout(1.seconds) { remoteSettingsWithDelay.updateSettings() }
212+
// Do the first fetch. This one should fetched the configsFetcher.
213+
val firstFetch = launch(Dispatchers.Default) { remoteSettingsWithDelay.updateSettings() }
257214

258-
// Assert that the configsFetcher was fetched exactly once.
259-
assertThat(fakeFetcherWithDelay.timesCalled).isEqualTo(1)
260-
assertThat(remoteSettingsWithDelay.samplingRate).isEqualTo(0.125)
215+
// Wait a second, and then do the second fetch while first is still running.
216+
// This one should block until the first fetch completes, but then exit early.
217+
launch(Dispatchers.Default) {
218+
delay(1.seconds)
219+
remoteSettingsWithDelay.updateSettings()
261220
}
262221

222+
// Wait until the first fetch is done, then do a third fetch.
223+
// This one should not even block, and exit early.
224+
firstFetch.join()
225+
withTimeout(1.seconds) { remoteSettingsWithDelay.updateSettings() }
226+
227+
// Assert that the configsFetcher was fetched exactly once.
228+
assertThat(fakeFetcherWithDelay.timesCalled).isEqualTo(1)
229+
assertThat(remoteSettingsWithDelay.samplingRate).isEqualTo(0.125)
230+
}
231+
263232
@After
264233
fun cleanUp() {
265234
FirebaseApp.clearInstancesForTest()
266235
}
267236

268-
internal companion object {
237+
private companion object {
269238
const val VALID_RESPONSE =
270239
"""
271240
{
@@ -284,30 +253,5 @@ class RemoteSettingsTest {
284253
}
285254
}
286255
"""
287-
288-
/**
289-
* Build an instance of [RemoteSettings] using the Dagger factory.
290-
*
291-
* This is needed because the SDK vendors Dagger to a difference namespace, but it does not for
292-
* these unit tests. The [RemoteSettings.lazySettingsCache] has type [dagger.Lazy] in these
293-
* tests, but type `com.google.firebase.sessions.dagger.Lazy` in the SDK. This method to build
294-
* the instance is the easiest I could find that does not need any reference to [dagger.Lazy] in
295-
* the test code.
296-
*/
297-
fun buildRemoteSettings(
298-
timeProvider: TimeProvider,
299-
firebaseInstallationsApi: FirebaseInstallationsApi,
300-
appInfo: ApplicationInfo,
301-
configsFetcher: CrashlyticsSettingsFetcher,
302-
settingsCache: SettingsCache,
303-
): RemoteSettings =
304-
RemoteSettings_Factory.create(
305-
{ timeProvider },
306-
{ firebaseInstallationsApi },
307-
{ appInfo },
308-
{ configsFetcher },
309-
{ settingsCache },
310-
)
311-
.get()
312256
}
313257
}

0 commit comments

Comments
 (0)