3838import com .google .common .collect .Sets ;
3939import com .google .firebase .database .collection .ImmutableSortedSet ;
4040import com .google .firebase .firestore .EventListener ;
41+ import com .google .firebase .firestore .FirebaseFirestore ;
4142import com .google .firebase .firestore .FirebaseFirestoreException ;
4243import com .google .firebase .firestore .FirebaseFirestoreSettings ;
4344import com .google .firebase .firestore .LoadBundleTask ;
5455import com .google .firebase .firestore .core .Query ;
5556import com .google .firebase .firestore .core .QueryListener ;
5657import com .google .firebase .firestore .core .SyncEngine ;
58+ import com .google .firebase .firestore .local .LocalStore ;
59+ import com .google .firebase .firestore .local .LruGarbageCollector ;
60+ import com .google .firebase .firestore .local .MemoryLruReferenceDelegate ;
5761import com .google .firebase .firestore .local .Persistence ;
5862import com .google .firebase .firestore .local .PersistenceTestHelpers ;
5963import com .google .firebase .firestore .local .QueryPurpose ;
64+ import com .google .firebase .firestore .local .SQLiteLruReferenceDelegate ;
6065import com .google .firebase .firestore .local .TargetData ;
6166import com .google .firebase .firestore .model .DocumentKey ;
6267import com .google .firebase .firestore .model .MutableDocument ;
@@ -158,7 +163,7 @@ public abstract class SpecTestCase implements RemoteStoreCallback {
158163 ? Sets .newHashSet ("no-android" , "multi-client" )
159164 : Sets .newHashSet ("no-android" , BENCHMARK_TAG , "multi-client" );
160165
161- private boolean garbageCollectionEnabled ;
166+ private boolean useEagerGcForMemory ;
162167 private int maxConcurrentLimboResolutions ;
163168 private boolean networkEnabled = true ;
164169
@@ -170,7 +175,9 @@ public abstract class SpecTestCase implements RemoteStoreCallback {
170175 private AsyncQueue queue ;
171176 private MockDatastore datastore ;
172177 private RemoteStore remoteStore ;
178+ private LocalStore localStore ;
173179 private SyncEngine syncEngine ;
180+ private LruGarbageCollector lruGarbageCollector ;
174181 private EventManager eventManager ;
175182 private DatabaseInfo databaseInfo ;
176183
@@ -268,7 +275,7 @@ protected void specSetUp(JSONObject config) {
268275
269276 outstandingWrites = new HashMap <>();
270277
271- this .garbageCollectionEnabled = config .optBoolean ("useGarbageCollection " , false );
278+ this .useEagerGcForMemory = config .optBoolean ("useEagerGCForMemory " , true );
272279 this .maxConcurrentLimboResolutions =
273280 config .optInt ("maxConcurrentLimboResolutions" , Integer .MAX_VALUE );
274281
@@ -317,10 +324,19 @@ private void initClient() {
317324 maxConcurrentLimboResolutions ,
318325 new FirebaseFirestoreSettings .Builder ().build ());
319326
320- ComponentProvider provider =
321- initializeComponentProvider (configuration , garbageCollectionEnabled );
327+ ComponentProvider provider = initializeComponentProvider (configuration , useEagerGcForMemory );
322328 localPersistence = provider .getPersistence ();
329+ if (localPersistence .getReferenceDelegate () instanceof SQLiteLruReferenceDelegate ) {
330+ lruGarbageCollector =
331+ ((SQLiteLruReferenceDelegate ) localPersistence .getReferenceDelegate ())
332+ .getGarbageCollector ();
333+ } else if (localPersistence .getReferenceDelegate () instanceof MemoryLruReferenceDelegate ) {
334+ lruGarbageCollector =
335+ ((MemoryLruReferenceDelegate ) localPersistence .getReferenceDelegate ())
336+ .getGarbageCollector ();
337+ }
323338 remoteStore = provider .getRemoteStore ();
339+ localStore = provider .getLocalStore ();
324340 syncEngine = provider .getSyncEngine ();
325341 eventManager = provider .getEventManager ();
326342 }
@@ -473,6 +489,7 @@ private List<Integer> parseIntList(@Nullable JSONArray arr) throws JSONException
473489 //
474490
475491 private void doListen (JSONObject listenSpec ) throws Exception {
492+ FirebaseFirestore .setLoggingEnabled (true );
476493 int expectedId = listenSpec .getInt ("targetId" );
477494 Query query = parseQuery (listenSpec .getJSONObject ("query" ));
478495 // TODO: Allow customizing listen options in spec tests
@@ -789,6 +806,15 @@ private void doChangeUser(@Nullable String uid) throws Exception {
789806 queue .runSync (() -> syncEngine .handleCredentialChange (currentUser ));
790807 }
791808
809+ private void doTriggerLruGc (long cacheThreshold ) throws Exception {
810+ queue .runSync (
811+ () -> {
812+ if (lruGarbageCollector != null ) {
813+ localStore .collectGarbage (lruGarbageCollector .withNewThreshold (cacheThreshold ));
814+ }
815+ });
816+ }
817+
792818 private void doRestart () throws Exception {
793819 queue .runSync (
794820 () -> {
@@ -861,6 +887,9 @@ private void doStep(JSONObject step) throws Exception {
861887 // "changeUser".
862888 String uid = step .isNull ("changeUser" ) ? null : step .getString ("changeUser" );
863889 doChangeUser (uid );
890+ } else if (step .has ("triggerLruGC" )) {
891+ long cacheThreshold = step .getLong ("triggerLruGC" );
892+ doTriggerLruGc (cacheThreshold );
864893 } else if (step .has ("restart" )) {
865894 doRestart ();
866895 } else if (step .has ("applyClientState" )) {
0 commit comments