{ "A successful message delays offline status": { "describeName": "Offline:", "itName": "A successful message delays offline status", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchAck": [ 2 ] }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } } ] }, "Client stays offline during credential change": { "describeName": "Offline:", "itName": "Client stays offline during credential change", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "enableNetwork": false, "expectedState": { "activeLimboDocs": [ ], "activeTargets": { }, "enqueuedLimboDocs": [ ] } }, { "changeUser": "user1" }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ], "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } } ] }, "Empty queries are resolved if client goes offline": { "describeName": "Offline:", "itName": "Empty queries are resolved if client goes offline", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } } ] }, "New queries return immediately with fromCache=true when offline due to OnlineState timeout.": { "describeName": "Offline:", "itName": "New queries return immediately with fromCache=true when offline due to OnlineState timeout.", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "runTimer": "online_state_timeout", "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection2" }, "targetId": 4 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection2" } } ], "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" }, "4": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection2" } ], "resumeToken": "" } } } } ] }, "New queries return immediately with fromCache=true when offline due to stream failures.": { "describeName": "Offline:", "itName": "New queries return immediately with fromCache=true when offline due to stream failures.", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection2" }, "targetId": 4 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection2" } } ], "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" }, "4": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection2" } ], "resumeToken": "" } } } } ] }, "OnlineState timeout triggers offline behavior": { "describeName": "Offline:", "itName": "OnlineState timeout triggers offline behavior", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "runTimer": "online_state_timeout", "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchAck": [ 2 ] }, { "watchEntity": { "docs": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "targets": [ 2 ] } }, { "watchCurrent": [ [ 2 ], "resume-token-1000" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1000 }, "expectedSnapshotEvents": [ { "added": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "errorCode": 0, "fromCache": false, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "runTimer": "all" }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "resume-token-1000" } } } }, { "runTimer": "online_state_timeout", "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] } ] }, "Queries return from cache when network disabled": { "describeName": "Offline:", "itName": "Queries return from cache when network disabled", "tags": [ "eager-gc" ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "enableNetwork": false, "expectedState": { "activeLimboDocs": [ ], "activeTargets": { }, "enqueuedLimboDocs": [ ] } }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ], "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "userUnlisten": [ 2, { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "expectedState": { "activeTargets": { } } }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 4 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ], "expectedState": { "activeTargets": { "4": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "userUnlisten": [ 4, { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "expectedState": { "activeTargets": { } } } ] }, "Queries revert to fromCache=true when offline.": { "describeName": "Offline:", "itName": "Queries revert to fromCache=true when offline.", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchAck": [ 2 ] }, { "watchEntity": { "docs": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "targets": [ 2 ] } }, { "watchCurrent": [ [ 2 ], "resume-token-1000" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1000 }, "expectedSnapshotEvents": [ { "added": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "errorCode": 0, "fromCache": false, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "resume-token-1000" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchAck": [ 2 ] }, { "watchEntity": { "docs": [ ], "targets": [ 2 ] } }, { "watchCurrent": [ [ 2 ], "resume-token-1000" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1000 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": false, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] } ] }, "Queries with limbo documents handle going offline.": { "describeName": "Offline:", "itName": "Queries with limbo documents handle going offline.", "tags": [ ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchAck": [ 2 ] }, { "watchEntity": { "docs": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "targets": [ 2 ] } }, { "watchCurrent": [ [ 2 ], "resume-token-1000" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1000 }, "expectedSnapshotEvents": [ { "added": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ], "errorCode": 0, "fromCache": false, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "watchReset": [ 2 ] }, { "watchCurrent": [ [ 2 ], "resume-token-1001" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1001 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ], "expectedState": { "activeLimboDocs": [ "collection/a" ], "activeTargets": { "1": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection/a" } ], "resumeToken": "", "targetPurpose": "TargetPurposeLimboResolution" }, "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedState": { "activeTargets": { "1": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection/a" } ], "resumeToken": "", "targetPurpose": "TargetPurposeLimboResolution" }, "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "resume-token-1001" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "watchAck": [ 2 ] }, { "watchEntity": { "docs": [ ], "targets": [ 2 ] } }, { "watchCurrent": [ [ 2 ], "resume-token-1001" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1001 } }, { "watchAck": [ 1 ] }, { "watchEntity": { "docs": [ ], "targets": [ 1 ] } }, { "watchCurrent": [ [ 1 ], "resume-token-1001" ] }, { "watchSnapshot": { "targetIds": [ ], "version": 1001 }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": false, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "removed": [ { "createTime": 0, "key": "collection/a", "options": { "hasCommittedMutations": false, "hasLocalMutations": false }, "value": { "key": "a" }, "version": 1000 } ] } ], "expectedState": { "activeLimboDocs": [ ], "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "resume-token-1001" } } } } ] }, "Removing all listeners delays \"Offline\" status on next listen": { "comment": "Marked as no-lru because when a listen is re-added, it gets a new target id rather than reusing one", "describeName": "Offline:", "itName": "Removing all listeners delays \"Offline\" status on next listen", "tags": [ "eager-gc" ], "config": { "numClients": 1, "useEagerGCForMemory": true }, "steps": [ { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 2 }, "expectedState": { "activeTargets": { "2": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] }, { "userUnlisten": [ 2, { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "expectedState": { "activeTargets": { } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true } }, { "userListen": { "query": { "filters": [ ], "orderBys": [ ], "path": "collection" }, "targetId": 4 }, "expectedState": { "activeTargets": { "4": { "queries": [ { "filters": [ ], "orderBys": [ ], "path": "collection" } ], "resumeToken": "" } } } }, { "watchStreamClose": { "error": { "code": 14, "message": "Simulated Backend Error" }, "runBackoffTimer": true }, "expectedSnapshotEvents": [ { "errorCode": 0, "fromCache": true, "hasPendingWrites": false, "query": { "filters": [ ], "orderBys": [ ], "path": "collection" } } ] } ] } }