Skip to content

Commit 87b8c22

Browse files
committed
Remove the no-ios tag from bloom filter spec tests, now that the feature has been merged into the ios sdk in firebase/firebase-ios-sdk#11457
1 parent 59c7b58 commit 87b8c22

File tree

3 files changed

+151
-186
lines changed

3 files changed

+151
-186
lines changed

packages/firestore/test/unit/specs/existence_filter_spec.test.ts

Lines changed: 147 additions & 178 deletions
Original file line numberDiff line numberDiff line change
@@ -277,8 +277,7 @@ describeSpec('Existence Filters:', [], () => {
277277
*/
278278
specTest(
279279
'Full re-query is skipped when bloom filter can identify documents deleted',
280-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
281-
['no-ios'],
280+
[],
282281
() => {
283282
const query1 = query('collection');
284283
const docA = doc('collection/a', 1000, { v: 1 });
@@ -310,8 +309,7 @@ describeSpec('Existence Filters:', [], () => {
310309

311310
specTest(
312311
'Full re-query is triggered when bloom filter can not identify documents deleted',
313-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
314-
['no-ios'],
312+
[],
315313
() => {
316314
const query1 = query('collection');
317315
const docA = doc('collection/a', 1000, { v: 1 });
@@ -343,8 +341,7 @@ describeSpec('Existence Filters:', [], () => {
343341

344342
specTest(
345343
'Bloom filter can process special characters in document name',
346-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
347-
['no-ios'],
344+
[],
348345
() => {
349346
const query1 = query('collection');
350347
const docA = doc('collection/ÀÒ∑', 1000, { v: 1 });
@@ -372,8 +369,7 @@ describeSpec('Existence Filters:', [], () => {
372369

373370
specTest(
374371
'Bloom filter fills in default values for undefined padding and hashCount',
375-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
376-
['no-ios'],
372+
[],
377373
() => {
378374
const query1 = query('collection');
379375
const docA = doc('collection/a', 1000, { v: 1 });
@@ -411,7 +407,6 @@ describeSpec('Existence Filters:', [], () => {
411407
// Skip this test on Android and iOS because those platforms get the raw
412408
// bytes of the bloom filter and, therefore, are not subject to base64
413409
// decoding errors.
414-
['no-ios', 'no-android'],
415410
() => {
416411
const query1 = query('collection');
417412
const docA = doc('collection/a', 1000, { v: 1 });
@@ -445,8 +440,7 @@ describeSpec('Existence Filters:', [], () => {
445440

446441
specTest(
447442
'Full re-query is triggered when bloom filter hashCount is invalid',
448-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
449-
['no-ios'],
443+
[],
450444
() => {
451445
const query1 = query('collection');
452446
const docA = doc('collection/a', 1000, { v: 1 });
@@ -478,187 +472,162 @@ describeSpec('Existence Filters:', [], () => {
478472
}
479473
);
480474

481-
specTest(
482-
'Full re-query is triggered when bloom filter is empty',
483-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
484-
['no-ios'],
485-
() => {
486-
const query1 = query('collection');
487-
const docA = doc('collection/a', 1000, { v: 1 });
488-
const docB = doc('collection/b', 1000, { v: 1 });
489-
490-
//Generate an empty bloom filter.
491-
const bloomFilterProto = generateBloomFilterProto({
492-
contains: [],
493-
notContains: [],
494-
bitCount: 0,
495-
hashCount: 0
496-
});
497-
498-
return (
499-
spec()
500-
.userListens(query1)
501-
.watchAcksFull(query1, 1000, docA, docB)
502-
.expectEvents(query1, { added: [docA, docB] })
503-
// DocB is deleted in the next sync.
504-
.watchFilters([query1], [docA.key], bloomFilterProto)
505-
.watchSnapshots(2000)
506-
// Re-run query is triggered.
507-
.expectEvents(query1, { fromCache: true })
508-
.expectActiveTargets({
509-
query: query1,
510-
resumeToken: '',
511-
targetPurpose: TargetPurpose.ExistenceFilterMismatch
512-
})
513-
);
514-
}
515-
);
475+
specTest('Full re-query is triggered when bloom filter is empty', [], () => {
476+
const query1 = query('collection');
477+
const docA = doc('collection/a', 1000, { v: 1 });
478+
const docB = doc('collection/b', 1000, { v: 1 });
516479

517-
specTest(
518-
'Same documents can have different bloom filters',
519-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
520-
['no-ios'],
521-
() => {
522-
const query1 = query('collection', filter('v', '<=', 2));
523-
const query2 = query('collection', filter('v', '>=', 2));
480+
//Generate an empty bloom filter.
481+
const bloomFilterProto = generateBloomFilterProto({
482+
contains: [],
483+
notContains: [],
484+
bitCount: 0,
485+
hashCount: 0
486+
});
524487

525-
const docA = doc('collection/a', 1000, { v: 1 });
526-
const docB = doc('collection/b', 1000, { v: 2 });
527-
const docC = doc('collection/c', 1000, { v: 3 });
488+
return (
489+
spec()
490+
.userListens(query1)
491+
.watchAcksFull(query1, 1000, docA, docB)
492+
.expectEvents(query1, { added: [docA, docB] })
493+
// DocB is deleted in the next sync.
494+
.watchFilters([query1], [docA.key], bloomFilterProto)
495+
.watchSnapshots(2000)
496+
// Re-run query is triggered.
497+
.expectEvents(query1, { fromCache: true })
498+
.expectActiveTargets({
499+
query: query1,
500+
resumeToken: '',
501+
targetPurpose: TargetPurpose.ExistenceFilterMismatch
502+
})
503+
);
504+
});
528505

529-
const bloomFilterProto1 = generateBloomFilterProto({
530-
contains: [docB],
531-
notContains: [docA, docC],
532-
bitCount: 5,
533-
hashCount: 2
534-
});
535-
const bloomFilterProto2 = generateBloomFilterProto({
536-
contains: [docB],
537-
notContains: [docA, docC],
538-
bitCount: 4,
539-
hashCount: 1
540-
});
541-
return (
542-
spec()
543-
.userListens(query1)
544-
.watchAcksFull(query1, 1000, docA, docB)
545-
.expectEvents(query1, { added: [docA, docB] })
546-
.userListens(query2)
547-
.expectEvents(query2, { added: [docB], fromCache: true })
548-
.watchAcksFull(query2, 1001, docB, docC)
549-
.expectEvents(query2, { added: [docC] })
506+
specTest('Same documents can have different bloom filters', [], () => {
507+
const query1 = query('collection', filter('v', '<=', 2));
508+
const query2 = query('collection', filter('v', '>=', 2));
550509

551-
// DocA is deleted in the next sync for query1.
552-
.watchFilters([query1], [docB.key], bloomFilterProto1)
553-
.watchSnapshots(2000)
554-
// BloomFilter identify docA is deleted, skip full query.
555-
.expectEvents(query1, { fromCache: true })
556-
.expectLimboDocs(docA.key) // DocA is now in limbo.
557-
558-
// DocC is deleted in the next sync for query2.
559-
.watchFilters([query2], [docB.key], bloomFilterProto2)
560-
.watchSnapshots(3000)
561-
// BloomFilter identify docC is deleted, skip full query.
562-
.expectEvents(query2, { fromCache: true })
563-
.expectLimboDocs(docA.key, docC.key) // DocC is now in limbo.
564-
);
565-
}
566-
);
510+
const docA = doc('collection/a', 1000, { v: 1 });
511+
const docB = doc('collection/b', 1000, { v: 2 });
512+
const docC = doc('collection/c', 1000, { v: 3 });
513+
514+
const bloomFilterProto1 = generateBloomFilterProto({
515+
contains: [docB],
516+
notContains: [docA, docC],
517+
bitCount: 5,
518+
hashCount: 2
519+
});
520+
const bloomFilterProto2 = generateBloomFilterProto({
521+
contains: [docB],
522+
notContains: [docA, docC],
523+
bitCount: 4,
524+
hashCount: 1
525+
});
526+
return (
527+
spec()
528+
.userListens(query1)
529+
.watchAcksFull(query1, 1000, docA, docB)
530+
.expectEvents(query1, { added: [docA, docB] })
531+
.userListens(query2)
532+
.expectEvents(query2, { added: [docB], fromCache: true })
533+
.watchAcksFull(query2, 1001, docB, docC)
534+
.expectEvents(query2, { added: [docC] })
567535

568-
specTest(
569-
'Bloom filter is handled at global snapshot',
570-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
571-
['no-ios'],
572-
() => {
573-
const query1 = query('collection');
574-
const docA = doc('collection/a', 1000, { v: 1 });
575-
const docB = doc('collection/b', 2000, { v: 2 });
576-
const docC = doc('collection/c', 3000, { v: 3 });
536+
// DocA is deleted in the next sync for query1.
537+
.watchFilters([query1], [docB.key], bloomFilterProto1)
538+
.watchSnapshots(2000)
539+
// BloomFilter identify docA is deleted, skip full query.
540+
.expectEvents(query1, { fromCache: true })
541+
.expectLimboDocs(docA.key) // DocA is now in limbo.
542+
543+
// DocC is deleted in the next sync for query2.
544+
.watchFilters([query2], [docB.key], bloomFilterProto2)
545+
.watchSnapshots(3000)
546+
// BloomFilter identify docC is deleted, skip full query.
547+
.expectEvents(query2, { fromCache: true })
548+
.expectLimboDocs(docA.key, docC.key) // DocC is now in limbo.
549+
);
550+
});
577551

578-
const bloomFilterProto = generateBloomFilterProto({
579-
contains: [docA],
580-
notContains: [docB]
581-
});
552+
specTest('Bloom filter is handled at global snapshot', [], () => {
553+
const query1 = query('collection');
554+
const docA = doc('collection/a', 1000, { v: 1 });
555+
const docB = doc('collection/b', 2000, { v: 2 });
556+
const docC = doc('collection/c', 3000, { v: 3 });
582557

583-
return (
584-
spec()
585-
.userListens(query1)
586-
.watchAcksFull(query1, 1000, docA, docB)
587-
.expectEvents(query1, { added: [docA, docB] })
588-
// Send a mismatching existence filter with one document, but don't
589-
// send a new global snapshot. We should not see an event until we
590-
// receive the snapshot.
591-
.watchFilters([query1], [docA.key], bloomFilterProto)
592-
.watchSends({ affects: [query1] }, docC)
593-
.watchSnapshots(2000)
594-
.expectEvents(query1, { added: [docC], fromCache: true })
595-
// Re-run of the query1 is skipped, docB is in limbo.
596-
.expectLimboDocs(docB.key)
597-
);
598-
}
599-
);
558+
const bloomFilterProto = generateBloomFilterProto({
559+
contains: [docA],
560+
notContains: [docB]
561+
});
600562

601-
specTest(
602-
'Bloom filter limbo resolution is denied',
603-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
604-
['no-ios'],
605-
() => {
606-
const query1 = query('collection');
607-
const docA = doc('collection/a', 1000, { v: 1 });
608-
const docB = doc('collection/b', 1000, { v: 1 });
609-
const bloomFilterProto = generateBloomFilterProto({
610-
contains: [docA],
611-
notContains: [docB]
612-
});
613-
return spec()
563+
return (
564+
spec()
614565
.userListens(query1)
615566
.watchAcksFull(query1, 1000, docA, docB)
616567
.expectEvents(query1, { added: [docA, docB] })
568+
// Send a mismatching existence filter with one document, but don't
569+
// send a new global snapshot. We should not see an event until we
570+
// receive the snapshot.
617571
.watchFilters([query1], [docA.key], bloomFilterProto)
572+
.watchSends({ affects: [query1] }, docC)
618573
.watchSnapshots(2000)
619-
.expectEvents(query1, { fromCache: true })
620-
.expectLimboDocs(docB.key) // DocB is now in limbo.
621-
.watchRemoves(
622-
newQueryForPath(docB.key.path),
623-
new RpcError(Code.PERMISSION_DENIED, 'no')
624-
)
625-
.expectLimboDocs() // DocB is no longer in limbo.
626-
.expectEvents(query1, {
627-
removed: [docB]
628-
});
629-
}
630-
);
631-
632-
specTest(
633-
'Bloom filter with large size works as expected',
634-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
635-
['no-ios'],
636-
() => {
637-
const query1 = query('collection');
638-
const docs = [];
639-
for (let i = 0; i < 100; i++) {
640-
docs.push(doc(`collection/doc${i}`, 1000, { v: 1 }));
641-
}
642-
const docKeys = docs.map(item => item.key);
574+
.expectEvents(query1, { added: [docC], fromCache: true })
575+
// Re-run of the query1 is skipped, docB is in limbo.
576+
.expectLimboDocs(docB.key)
577+
);
578+
});
643579

644-
const bloomFilterProto = generateBloomFilterProto({
645-
contains: docs.slice(0, 50),
646-
notContains: docs.slice(50),
647-
bitCount: 1000,
648-
hashCount: 16
580+
specTest('Bloom filter limbo resolution is denied', [], () => {
581+
const query1 = query('collection');
582+
const docA = doc('collection/a', 1000, { v: 1 });
583+
const docB = doc('collection/b', 1000, { v: 1 });
584+
const bloomFilterProto = generateBloomFilterProto({
585+
contains: [docA],
586+
notContains: [docB]
587+
});
588+
return spec()
589+
.userListens(query1)
590+
.watchAcksFull(query1, 1000, docA, docB)
591+
.expectEvents(query1, { added: [docA, docB] })
592+
.watchFilters([query1], [docA.key], bloomFilterProto)
593+
.watchSnapshots(2000)
594+
.expectEvents(query1, { fromCache: true })
595+
.expectLimboDocs(docB.key) // DocB is now in limbo.
596+
.watchRemoves(
597+
newQueryForPath(docB.key.path),
598+
new RpcError(Code.PERMISSION_DENIED, 'no')
599+
)
600+
.expectLimboDocs() // DocB is no longer in limbo.
601+
.expectEvents(query1, {
602+
removed: [docB]
649603
});
650-
return (
651-
spec()
652-
.userListens(query1)
653-
.watchAcksFull(query1, 1000, ...docs)
654-
.expectEvents(query1, { added: docs })
655-
// Doc0 to doc49 are deleted in the next sync.
656-
.watchFilters([query1], docKeys.slice(0, 50), bloomFilterProto)
657-
.watchSnapshots(2000)
658-
// BloomFilter correctly identifies docs that deleted, skip full query.
659-
.expectEvents(query1, { fromCache: true })
660-
.expectLimboDocs(...docKeys.slice(50))
661-
);
604+
});
605+
606+
specTest('Bloom filter with large size works as expected', [], () => {
607+
const query1 = query('collection');
608+
const docs = [];
609+
for (let i = 0; i < 100; i++) {
610+
docs.push(doc(`collection/doc${i}`, 1000, { v: 1 }));
662611
}
663-
);
612+
const docKeys = docs.map(item => item.key);
613+
614+
const bloomFilterProto = generateBloomFilterProto({
615+
contains: docs.slice(0, 50),
616+
notContains: docs.slice(50),
617+
bitCount: 1000,
618+
hashCount: 16
619+
});
620+
return (
621+
spec()
622+
.userListens(query1)
623+
.watchAcksFull(query1, 1000, ...docs)
624+
.expectEvents(query1, { added: docs })
625+
// Doc0 to doc49 are deleted in the next sync.
626+
.watchFilters([query1], docKeys.slice(0, 50), bloomFilterProto)
627+
.watchSnapshots(2000)
628+
// BloomFilter correctly identifies docs that deleted, skip full query.
629+
.expectEvents(query1, { fromCache: true })
630+
.expectLimboDocs(...docKeys.slice(50))
631+
);
632+
});
664633
});

packages/firestore/test/unit/specs/limbo_spec.test.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -929,8 +929,7 @@ describeSpec('Limbo Documents:', [], () => {
929929

930930
specTest(
931931
'Limbo resolution throttling with bloom filter application',
932-
// TODO(b/278759251) Remove 'no-ios' once bloom filter is merged.
933-
['no-ios'],
932+
[],
934933
() => {
935934
const query1 = query('collection');
936935
const docA1 = doc('collection/a1', 1000, { key: 'a1' });

0 commit comments

Comments
 (0)