21
21
import static com .google .firebase .firestore .testutil .TestUtil .path ;
22
22
import static com .google .firebase .firestore .testutil .TestUtil .query ;
23
23
import static com .google .firebase .firestore .testutil .TestUtil .version ;
24
+ import static com .google .firebase .firestore .util .Assert .fail ;
24
25
import static java .util .Arrays .asList ;
25
26
import static org .junit .Assert .assertEquals ;
26
27
import static org .junit .Assert .assertFalse ;
36
37
import com .google .firebase .firestore .model .DocumentKey ;
37
38
import com .google .firebase .firestore .model .ResourcePath ;
38
39
import com .google .firebase .firestore .proto .MaybeDocument ;
40
+ import com .google .firebase .firestore .proto .Target ;
39
41
import com .google .firebase .firestore .proto .WriteBatch ;
40
42
import com .google .firebase .firestore .remote .RemoteSerializer ;
41
43
import com .google .firestore .v1 .Document ;
42
44
import com .google .firestore .v1 .Write ;
45
+ import com .google .protobuf .InvalidProtocolBufferException ;
46
+ import com .google .protobuf .Timestamp ;
43
47
import java .util .ArrayList ;
44
48
import java .util .HashMap ;
45
49
import java .util .HashSet ;
@@ -436,6 +440,68 @@ public void existingDocumentsRemainReadableAfterIndexFreeMigration() {
436
440
assertResultsContain (results , "coll/new" );
437
441
}
438
442
443
+ @ Test
444
+ public void dropsLastLimboFreeSnapshotIfPreviouslyDowngraded () {
445
+ schema .runMigrations (0 , 9 );
446
+
447
+ db .execSQL (
448
+ "INSERT INTO targets (target_id, canonical_id, target_proto) VALUES (?,?, ?)" ,
449
+ new Object [] {1 , "foo" , createDummyQueryTargetWithLimboFreeVersion (1 ).toByteArray ()});
450
+ db .execSQL (
451
+ "INSERT INTO targets (target_id, canonical_id, target_proto) VALUES (?, ?, ?)" ,
452
+ new Object [] {2 , "bar" , createDummyQueryTargetWithLimboFreeVersion (2 ).toByteArray ()});
453
+ db .execSQL (
454
+ "INSERT INTO targets (target_id, canonical_id, target_proto) VALUES (?,?, ?)" ,
455
+ new Object [] {3 , "baz" , createDummyQueryTargetWithLimboFreeVersion (3 ).toByteArray ()});
456
+
457
+ schema .runMigrations (0 , 8 );
458
+ schema .runMigrations (8 , 9 );
459
+
460
+ int rowCount =
461
+ new SQLitePersistence .Query (db , "SELECT target_id, target_proto FROM targets" )
462
+ .forEach (
463
+ cursor -> {
464
+ int targetId = cursor .getInt (0 );
465
+ byte [] targetProtoBytes = cursor .getBlob (1 );
466
+
467
+ try {
468
+ Target targetProto = Target .parseFrom (targetProtoBytes );
469
+ assertEquals (targetId , targetProto .getTargetId ());
470
+ assertFalse (targetProto .hasLastLimboFreeSnapshotVersion ());
471
+ } catch (InvalidProtocolBufferException e ) {
472
+ fail ("Failed to decode Query data" );
473
+ }
474
+ });
475
+
476
+ assertEquals (3 , rowCount );
477
+ }
478
+
479
+ @ Test
480
+ public void keepsLastLimboFreeSnapshotIfNotDowngraded () {
481
+ schema .runMigrations (0 , 9 );
482
+
483
+ db .execSQL (
484
+ "INSERT INTO targets (target_id, canonical_id, target_proto) VALUES (?,?, ?)" ,
485
+ new Object [] {1 , "foo" , createDummyQueryTargetWithLimboFreeVersion (1 ).toByteArray ()});
486
+
487
+ // Make sure that we don't drop the lastLimboFreeSnapshotVersion if we are already on schema
488
+ // version 9.
489
+ schema .runMigrations (9 , 9 );
490
+
491
+ new SQLitePersistence .Query (db , "SELECT target_proto FROM targets" )
492
+ .forEach (
493
+ cursor -> {
494
+ byte [] targetProtoBytes = cursor .getBlob (0 );
495
+
496
+ try {
497
+ Target targetProto = Target .parseFrom (targetProtoBytes );
498
+ assertTrue (targetProto .hasLastLimboFreeSnapshotVersion ());
499
+ } catch (InvalidProtocolBufferException e ) {
500
+ fail ("Failed to decode Query data" );
501
+ }
502
+ });
503
+ }
504
+
439
505
private SQLiteRemoteDocumentCache createRemoteDocumentCache () {
440
506
DatabaseId databaseId = DatabaseId .forProject ("foo" );
441
507
LocalSerializer serializer = new LocalSerializer (new RemoteSerializer (databaseId ));
@@ -460,6 +526,13 @@ private byte[] createDummyDocument(String name) {
460
526
.toByteArray ();
461
527
}
462
528
529
+ private Target createDummyQueryTargetWithLimboFreeVersion (int targetId ) {
530
+ return Target .newBuilder ()
531
+ .setTargetId (targetId )
532
+ .setLastLimboFreeSnapshotVersion (Timestamp .newBuilder ().setSeconds (42 ))
533
+ .build ();
534
+ }
535
+
463
536
private void assertResultsContain (
464
537
ImmutableSortedMap <DocumentKey , com .google .firebase .firestore .model .Document > actualResults ,
465
538
String ... docs ) {
0 commit comments