31
31
import static org .junit .Assert .assertFalse ;
32
32
import static org .junit .Assert .assertNull ;
33
33
import static org .junit .Assert .assertTrue ;
34
- import static org .junit .Assume .assumeFalse ;
35
34
36
35
import android .os .SystemClock ;
37
-
38
36
import androidx .annotation .Nullable ;
39
37
import androidx .test .ext .junit .runners .AndroidJUnit4 ;
40
38
import com .google .android .gms .tasks .Task ;
@@ -1073,7 +1071,7 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1073
1071
.getFirestore ()
1074
1072
.runTransaction (
1075
1073
transaction -> {
1076
- for (int i = 0 ; i < createdDocuments .size (); i += 2 ) {
1074
+ for (int i = 0 ; i < createdDocuments .size (); i += 2 ) {
1077
1075
DocumentReference documentToDelete = createdDocuments .get (i );
1078
1076
transaction .delete (documentToDelete );
1079
1077
deletedDocumentIds .add (documentToDelete .getId ());
@@ -1089,8 +1087,10 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1089
1087
// testing hooks to "capture" the existence filter mismatches to verify that Watch sent a
1090
1088
// bloom filter, and it was used to avert a full requery.
1091
1089
QuerySnapshot snapshot2 ;
1092
- WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo existenceFilterMismatchInfo ;
1093
- ExistenceFilterMismatchAccumulator existenceFilterMismatchAccumulator = new ExistenceFilterMismatchAccumulator ();
1090
+ WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo
1091
+ existenceFilterMismatchInfo ;
1092
+ ExistenceFilterMismatchAccumulator existenceFilterMismatchAccumulator =
1093
+ new ExistenceFilterMismatchAccumulator ();
1094
1094
existenceFilterMismatchAccumulator .register ();
1095
1095
try {
1096
1096
snapshot2 = waitFor (collection .get ());
@@ -1099,7 +1099,9 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1099
1099
if (isRunningAgainstEmulator ()) {
1100
1100
existenceFilterMismatchInfo = null ;
1101
1101
} else {
1102
- existenceFilterMismatchInfo = existenceFilterMismatchAccumulator .waitForExistenceFilterMismatch (/*timeoutMillis=*/ 5000 );
1102
+ existenceFilterMismatchInfo =
1103
+ existenceFilterMismatchAccumulator .waitForExistenceFilterMismatch (
1104
+ /*timeoutMillis=*/ 5000 );
1103
1105
}
1104
1106
} finally {
1105
1107
existenceFilterMismatchAccumulator .unregister ();
@@ -1122,7 +1124,9 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1122
1124
expectedDocumentIds .add (documentRef .getId ());
1123
1125
}
1124
1126
}
1125
- assertWithMessage ("snapshot2.docs" ).that (actualDocumentIds ).containsExactlyElementsIn (expectedDocumentIds );
1127
+ assertWithMessage ("snapshot2.docs" )
1128
+ .that (actualDocumentIds )
1129
+ .containsExactlyElementsIn (expectedDocumentIds );
1126
1130
}
1127
1131
1128
1132
// Skip the verification of the existence filter mismatch when testing against the Firestore
@@ -1135,9 +1139,15 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1135
1139
1136
1140
// Verify that Watch sent an existence filter with the correct counts when the query was
1137
1141
// resumed.
1138
- assertWithMessage ("Watch should have sent an existence filter" ).that (existenceFilterMismatchInfo ).isNotNull ();
1139
- assertWithMessage ("localCacheCount" ).that (existenceFilterMismatchInfo .localCacheCount ()).isEqualTo (100 );
1140
- assertWithMessage ("existenceFilterCount" ).that (existenceFilterMismatchInfo .existenceFilterCount ()).isEqualTo (50 );
1142
+ assertWithMessage ("Watch should have sent an existence filter" )
1143
+ .that (existenceFilterMismatchInfo )
1144
+ .isNotNull ();
1145
+ assertWithMessage ("localCacheCount" )
1146
+ .that (existenceFilterMismatchInfo .localCacheCount ())
1147
+ .isEqualTo (100 );
1148
+ assertWithMessage ("existenceFilterCount" )
1149
+ .that (existenceFilterMismatchInfo .existenceFilterCount ())
1150
+ .isEqualTo (50 );
1141
1151
1142
1152
// Skip the verification of the bloom filter when testing against production because the bloom
1143
1153
// filter is only implemented in nightly.
@@ -1148,8 +1158,11 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1148
1158
}
1149
1159
1150
1160
// Verify that Watch sent a valid bloom filter.
1151
- WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterBloomFilterInfo bloomFilter = existenceFilterMismatchInfo .bloomFilter ();
1152
- assertWithMessage ("The bloom filter specified in the existence filter" ).that (bloomFilter ).isNotNull ();
1161
+ WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterBloomFilterInfo bloomFilter =
1162
+ existenceFilterMismatchInfo .bloomFilter ();
1163
+ assertWithMessage ("The bloom filter specified in the existence filter" )
1164
+ .that (bloomFilter )
1165
+ .isNotNull ();
1153
1166
assertWithMessage ("hashCount" ).that (bloomFilter .hashCount ()).isGreaterThan (0 );
1154
1167
assertWithMessage ("bitmapLength" ).that (bloomFilter .bitmapLength ()).isGreaterThan (0 );
1155
1168
assertWithMessage ("padding" ).that (bloomFilter .padding ()).isGreaterThan (0 );
@@ -1160,24 +1173,28 @@ public void resumingAQueryShouldUseBloomFilterToAvoidFullRequery() throws Except
1160
1173
// are expected to happen occasionally. When a false positive _does_ happen, just retry the
1161
1174
// test with a different set of documents. If that retry _also_ experiences a false positive,
1162
1175
// then fail the test because that is so improbable that something must have gone wrong.
1163
- if (attemptNumber == 1 && ! bloomFilter .applied ()) {
1176
+ if (attemptNumber == 1 && !bloomFilter .applied ()) {
1164
1177
continue ;
1165
1178
}
1166
1179
1167
- assertWithMessage ("bloom filter successfully applied with attemptNumber=" + attemptNumber ).that (bloomFilter .applied ()).isTrue ();
1180
+ assertWithMessage ("bloom filter successfully applied with attemptNumber=" + attemptNumber )
1181
+ .that (bloomFilter .applied ())
1182
+ .isTrue ();
1168
1183
}
1169
1184
}
1170
1185
1171
1186
private static final class ExistenceFilterMismatchAccumulator {
1172
1187
1173
- private final ExistenceFilterMismatchListenerImpl listener = new ExistenceFilterMismatchListenerImpl ();
1188
+ private final ExistenceFilterMismatchListenerImpl listener =
1189
+ new ExistenceFilterMismatchListenerImpl ();
1174
1190
private ListenerRegistration listenerRegistration = null ;
1175
1191
1176
1192
void register () {
1177
1193
if (listenerRegistration != null ) {
1178
1194
throw new IllegalStateException ("already registered" );
1179
1195
}
1180
- listenerRegistration = WatchChangeAggregatorTestingHooksAccessor .addExistenceFilterMismatchListener (listener );
1196
+ listenerRegistration =
1197
+ WatchChangeAggregatorTestingHooksAccessor .addExistenceFilterMismatchListener (listener );
1181
1198
}
1182
1199
1183
1200
void unregister () {
@@ -1189,27 +1206,33 @@ void unregister() {
1189
1206
}
1190
1207
1191
1208
@ Nullable
1192
- WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo waitForExistenceFilterMismatch (long timeoutMillis ) throws InterruptedException {
1209
+ WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo
1210
+ waitForExistenceFilterMismatch (long timeoutMillis ) throws InterruptedException {
1193
1211
if (listenerRegistration == null ) {
1194
- throw new IllegalStateException ("must be registered before waiting for an existence filter mismatch" );
1212
+ throw new IllegalStateException (
1213
+ "must be registered before waiting for an existence filter mismatch" );
1195
1214
}
1196
1215
return listener .waitForExistenceFilterMismatch (timeoutMillis );
1197
1216
}
1198
1217
1199
- private final class ExistenceFilterMismatchListenerImpl implements WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchListener {
1218
+ private final class ExistenceFilterMismatchListenerImpl
1219
+ implements WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchListener {
1200
1220
1201
- private final ArrayList <WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo > existenceFilterMismatches = new ArrayList <>();
1221
+ private final ArrayList <WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo >
1222
+ existenceFilterMismatches = new ArrayList <>();
1202
1223
1203
1224
@ Override
1204
- public void onExistenceFilterMismatch (WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo info ) {
1225
+ public void onExistenceFilterMismatch (
1226
+ WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo info ) {
1205
1227
synchronized (existenceFilterMismatches ) {
1206
1228
existenceFilterMismatches .add (info );
1207
1229
existenceFilterMismatches .notifyAll ();
1208
1230
}
1209
1231
}
1210
1232
1211
1233
@ Nullable
1212
- WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo waitForExistenceFilterMismatch (long timeoutMillis ) throws InterruptedException {
1234
+ WatchChangeAggregatorTestingHooksAccessor .ExistenceFilterMismatchInfo
1235
+ waitForExistenceFilterMismatch (long timeoutMillis ) throws InterruptedException {
1213
1236
if (timeoutMillis <= 0 ) {
1214
1237
throw new IllegalArgumentException ("invalid timeout: " + timeoutMillis );
1215
1238
}
@@ -1228,7 +1251,6 @@ WatchChangeAggregatorTestingHooksAccessor.ExistenceFilterMismatchInfo waitForExi
1228
1251
}
1229
1252
}
1230
1253
}
1231
-
1232
1254
}
1233
1255
1234
1256
// TODO(orquery): Enable this test when prod supports OR queries.
0 commit comments