Skip to content

Commit acff0f4

Browse files
committed
yarn prettier
1 parent 677b9e7 commit acff0f4

File tree

1 file changed

+116
-118
lines changed

1 file changed

+116
-118
lines changed

packages/firestore/test/integration/api/query.test.ts

+116-118
Original file line numberDiff line numberDiff line change
@@ -2064,136 +2064,134 @@ apiDescribe('Queries', (persistence: boolean) => {
20642064
});
20652065
});
20662066

2067-
it(
2068-
'resuming a query should use bloom filter to avoid full requery',
2069-
async () => {
2070-
// Create 100 documents in a new collection.
2071-
const testDocs: { [key: string]: object } = {};
2072-
for (let i = 1; i <= 100; i++) {
2073-
testDocs['doc' + i] = { key: i };
2074-
}
2067+
it('resuming a query should use bloom filter to avoid full requery', async () => {
2068+
// Create 100 documents in a new collection.
2069+
const testDocs: { [key: string]: object } = {};
2070+
for (let i = 1; i <= 100; i++) {
2071+
testDocs['doc' + i] = { key: i };
2072+
}
20752073

2076-
// The function that runs a single iteration of the test.
2077-
// Below this definition, there is a "while" loop that calls this
2078-
// function potentially multiple times.
2079-
const runTestIteration = async (
2080-
coll: CollectionReference,
2081-
db: Firestore
2082-
): Promise<'retry' | 'passed'> => {
2083-
// Run a query to populate the local cache with the 100 documents
2084-
// and a resume token.
2085-
const snapshot1 = await getDocs(coll);
2086-
expect(snapshot1.size, 'snapshot1.size').to.equal(100);
2074+
// The function that runs a single iteration of the test.
2075+
// Below this definition, there is a "while" loop that calls this
2076+
// function potentially multiple times.
2077+
const runTestIteration = async (
2078+
coll: CollectionReference,
2079+
db: Firestore
2080+
): Promise<'retry' | 'passed'> => {
2081+
// Run a query to populate the local cache with the 100 documents
2082+
// and a resume token.
2083+
const snapshot1 = await getDocs(coll);
2084+
expect(snapshot1.size, 'snapshot1.size').to.equal(100);
2085+
2086+
// Delete 50 of the 100 documents. Do this in a transaction, rather
2087+
// than deleteDoc(), to avoid affecting the local cache.
2088+
await runTransaction(db, async txn => {
2089+
for (let i = 1; i <= 50; i++) {
2090+
txn.delete(doc(coll, 'doc' + i));
2091+
}
2092+
});
20872093

2088-
// Delete 50 of the 100 documents. Do this in a transaction, rather
2089-
// than deleteDoc(), to avoid affecting the local cache.
2090-
await runTransaction(db, async txn => {
2091-
for (let i = 1; i <= 50; i++) {
2092-
txn.delete(doc(coll, 'doc' + i));
2094+
// Wait for 10 seconds, during which Watch will stop tracking the
2095+
// query and will send an existence filter rather than "delete"
2096+
// events when the query is resumed.
2097+
await new Promise(resolve => setTimeout(resolve, 10000));
2098+
2099+
// Resume the query and expect to get a snapshot with the 50
2100+
// remaining documents. Use some internal testing hooks to "capture"
2101+
// the existence filter mismatches to later verify that Watch sent a
2102+
// bloom filter, and it was used to avert a full requery.
2103+
const existenceFilterMismatches = await captureExistenceFilterMismatches(
2104+
async () => {
2105+
const snapshot2 = await getDocs(coll);
2106+
// TODO(b/270731363): Remove the "if" condition below once the
2107+
// Firestore Emulator is fixed to send an existence filter. At the
2108+
// time of writing, the Firestore emulator fails to send an
2109+
// existence filter, resulting in the client including the deleted
2110+
// documents in the snapshot of the resumed query.
2111+
if (!(USE_EMULATOR && snapshot2.size === 100)) {
2112+
expect(snapshot2.size, 'snapshot2.size').to.equal(50);
20932113
}
2094-
});
2095-
2096-
// Wait for 10 seconds, during which Watch will stop tracking the
2097-
// query and will send an existence filter rather than "delete"
2098-
// events when the query is resumed.
2099-
await new Promise(resolve => setTimeout(resolve, 10000));
2100-
2101-
// Resume the query and expect to get a snapshot with the 50
2102-
// remaining documents. Use some internal testing hooks to "capture"
2103-
// the existence filter mismatches to later verify that Watch sent a
2104-
// bloom filter, and it was used to avert a full requery.
2105-
const existenceFilterMismatches =
2106-
await captureExistenceFilterMismatches(async () => {
2107-
const snapshot2 = await getDocs(coll);
2108-
// TODO(b/270731363): Remove the "if" condition below once the
2109-
// Firestore Emulator is fixed to send an existence filter. At the
2110-
// time of writing, the Firestore emulator fails to send an
2111-
// existence filter, resulting in the client including the deleted
2112-
// documents in the snapshot of the resumed query.
2113-
if (!(USE_EMULATOR && snapshot2.size === 100)) {
2114-
expect(snapshot2.size, 'snapshot2.size').to.equal(50);
2115-
}
2116-
});
2117-
2118-
// Skip the verification of the existence filter mismatch when
2119-
// persistence is disabled because without persistence there is no
2120-
// resume token specified in the subsequent call to getDocs(), and,
2121-
// therefore, Watch will _not_ send an existence filter.
2122-
if (!persistence) {
2123-
return 'passed';
21242114
}
2115+
);
21252116

2126-
// Skip the verification of the existence filter mismatch when
2127-
// testing against the Firestore emulator because the Firestore
2128-
// emulator does not include the `unchanged_names` bloom filter when
2129-
// it sends ExistenceFilter messages. Some day the emulator _may_
2130-
// implement this logic, at which time this short-circuit can be
2131-
// removed.
2132-
if (USE_EMULATOR) {
2133-
return 'passed';
2134-
}
2117+
// Skip the verification of the existence filter mismatch when
2118+
// persistence is disabled because without persistence there is no
2119+
// resume token specified in the subsequent call to getDocs(), and,
2120+
// therefore, Watch will _not_ send an existence filter.
2121+
if (!persistence) {
2122+
return 'passed';
2123+
}
21352124

2136-
// Verify that upon resuming the query that Watch sent an existence
2137-
// filter that included a bloom filter, and that the bloom filter
2138-
// was successfully used to avoid a full requery.
2139-
// TODO(b/271949433) Remove this check for "nightly" once the bloom
2140-
// filter logic is deployed to production, circa May 2023.
2141-
if (TARGET_BACKEND === 'nightly') {
2142-
expect(
2143-
existenceFilterMismatches,
2144-
'existenceFilterMismatches'
2145-
).to.have.length(1);
2146-
const { localCacheCount, existenceFilterCount, bloomFilter } =
2147-
existenceFilterMismatches[0];
2148-
2149-
expect(localCacheCount, 'localCacheCount').to.equal(100);
2150-
expect(existenceFilterCount, 'existenceFilterCount').to.equal(50);
2151-
if (!bloomFilter) {
2152-
expect.fail(
2153-
'The existence filter should have specified ' +
2154-
'a bloom filter in its `unchanged_names` field.'
2155-
);
2156-
throw new Error('should never get here');
2157-
}
2125+
// Skip the verification of the existence filter mismatch when
2126+
// testing against the Firestore emulator because the Firestore
2127+
// emulator does not include the `unchanged_names` bloom filter when
2128+
// it sends ExistenceFilter messages. Some day the emulator _may_
2129+
// implement this logic, at which time this short-circuit can be
2130+
// removed.
2131+
if (USE_EMULATOR) {
2132+
return 'passed';
2133+
}
21582134

2159-
expect(bloomFilter.hashCount, 'bloomFilter.hashCount').to.be.above(0);
2160-
expect(
2161-
bloomFilter.bitmapLength,
2162-
'bloomFilter.bitmapLength'
2163-
).to.be.above(0);
2164-
expect(bloomFilter.padding, 'bloomFilterPadding').to.be.above(0);
2165-
expect(bloomFilter.padding, 'bloomFilterPadding').to.be.below(8);
2166-
2167-
// Retry the entire test if a bloom filter false positive occurs.
2168-
// Although statistically rare, false positives are expected to
2169-
// happen occasionally. When a false positive _does_ happen, just
2170-
// retry the test with a different set of documents. If that retry
2171-
// _also_ experiences a false positive, then fail the test because
2172-
// that is so improbable that something must have gone wrong.
2173-
if (attemptNumber > 1 && !bloomFilter.applied) {
2174-
return 'retry';
2175-
}
2176-
expect(bloomFilter.applied, 'bloomFilter.applied').to.be.true;
2135+
// Verify that upon resuming the query that Watch sent an existence
2136+
// filter that included a bloom filter, and that the bloom filter
2137+
// was successfully used to avoid a full requery.
2138+
// TODO(b/271949433) Remove this check for "nightly" once the bloom
2139+
// filter logic is deployed to production, circa May 2023.
2140+
if (TARGET_BACKEND === 'nightly') {
2141+
expect(
2142+
existenceFilterMismatches,
2143+
'existenceFilterMismatches'
2144+
).to.have.length(1);
2145+
const { localCacheCount, existenceFilterCount, bloomFilter } =
2146+
existenceFilterMismatches[0];
2147+
2148+
expect(localCacheCount, 'localCacheCount').to.equal(100);
2149+
expect(existenceFilterCount, 'existenceFilterCount').to.equal(50);
2150+
if (!bloomFilter) {
2151+
expect.fail(
2152+
'The existence filter should have specified ' +
2153+
'a bloom filter in its `unchanged_names` field.'
2154+
);
2155+
throw new Error('should never get here');
21772156
}
21782157

2179-
return 'passed';
2180-
};
2181-
2182-
// Run the test
2183-
let attemptNumber = 0;
2184-
while (true) {
2185-
attemptNumber++;
2186-
const iterationResult = await withTestCollection(
2187-
persistence,
2188-
testDocs,
2189-
runTestIteration
2190-
);
2191-
if (iterationResult === 'passed') {
2192-
break;
2158+
expect(bloomFilter.hashCount, 'bloomFilter.hashCount').to.be.above(0);
2159+
expect(
2160+
bloomFilter.bitmapLength,
2161+
'bloomFilter.bitmapLength'
2162+
).to.be.above(0);
2163+
expect(bloomFilter.padding, 'bloomFilterPadding').to.be.above(0);
2164+
expect(bloomFilter.padding, 'bloomFilterPadding').to.be.below(8);
2165+
2166+
// Retry the entire test if a bloom filter false positive occurs.
2167+
// Although statistically rare, false positives are expected to
2168+
// happen occasionally. When a false positive _does_ happen, just
2169+
// retry the test with a different set of documents. If that retry
2170+
// _also_ experiences a false positive, then fail the test because
2171+
// that is so improbable that something must have gone wrong.
2172+
if (attemptNumber > 1 && !bloomFilter.applied) {
2173+
return 'retry';
21932174
}
2175+
expect(bloomFilter.applied, 'bloomFilter.applied').to.be.true;
2176+
}
2177+
2178+
return 'passed';
2179+
};
2180+
2181+
// Run the test
2182+
let attemptNumber = 0;
2183+
while (true) {
2184+
attemptNumber++;
2185+
const iterationResult = await withTestCollection(
2186+
persistence,
2187+
testDocs,
2188+
runTestIteration
2189+
);
2190+
if (iterationResult === 'passed') {
2191+
break;
21942192
}
21952193
}
2196-
).timeout('90s');
2194+
}).timeout('90s');
21972195
});
21982196

21992197
function verifyDocumentChange<T>(

0 commit comments

Comments
 (0)