mirror of
https://github.com/firebase/firebase-ios-sdk
synced 2026-11-11 22:55:59 +05:45
[Port of https://github.com/firebase/firebase-js-sdk/commit/0fa319e5e019dd0d40ab441d2ff9f8f6d4724e43] * Refactored FSTOnlineState tracking out of FSTRemoteStore and into new FSTOnlineStateTracker component. * Added a 10 second timeout to transition from OnlineState.Unknown to OnlineState.Offline rather than waiting indefinitely for the stream to succeed or fail. * Removed hack to run SpecTests using an FSTDispatchQueue that wrapped dispatch_get_main_queue(). This was incompatible with [FSTDispatchQueue runDelayedCallbacksUntil:] since it queues work and blocks waiting for it to complete. Now spec tests create / use a proper FSTDispatchQueue. * Added a SpecTest to verify OnlineState timeout behavior. * Misc cleanup: * Renamed FSTOnlineState states: Failed => Offline, Healthy => Online * Renamed FSTTimerIds (ListenStreamConnection => ListenStreamConnectionBackoff) * Added ability to run timers from spec tests.
870 lines
18 KiB
JSON
870 lines
18 KiB
JSON
{
|
|
"Empty queries are resolved if client goes offline": {
|
|
"describeName": "Offline:",
|
|
"itName": "Empty queries are resolved if client goes offline",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"A successful message delays offline status": {
|
|
"describeName": "Offline:",
|
|
"itName": "A successful message delays offline status",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"Removing all listeners delays \"Offline\" status on next listen": {
|
|
"describeName": "Offline:",
|
|
"itName": "Removing all listeners delays \"Offline\" status on next listen",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"userUnlisten": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"userListen": [
|
|
4,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"4": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"Queries revert to fromCache=true when offline.": {
|
|
"describeName": "Offline:",
|
|
"itName": "Queries revert to fromCache=true when offline.",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"targets": [
|
|
2
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1000"
|
|
],
|
|
"watchSnapshot": 1000,
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"added": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"errorCode": 0,
|
|
"fromCache": false,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": "resume-token-1000"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [],
|
|
"targets": [
|
|
2
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1000"
|
|
],
|
|
"watchSnapshot": 1000,
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": false,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"Queries with limbo documents handle going offline.": {
|
|
"describeName": "Offline:",
|
|
"itName": "Queries with limbo documents handle going offline.",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"targets": [
|
|
2
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1000"
|
|
],
|
|
"watchSnapshot": 1000,
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"added": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"errorCode": 0,
|
|
"fromCache": false,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchReset": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1001"
|
|
],
|
|
"watchSnapshot": 1001,
|
|
"stateExpect": {
|
|
"limboDocs": [
|
|
"collection/a"
|
|
],
|
|
"activeTargets": {
|
|
"1": {
|
|
"query": {
|
|
"path": "collection/a",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
},
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
},
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"1": {
|
|
"query": {
|
|
"path": "collection/a",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
},
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": "resume-token-1001"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [],
|
|
"targets": [
|
|
2
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1001"
|
|
],
|
|
"watchSnapshot": 1001
|
|
},
|
|
{
|
|
"watchAck": [
|
|
1
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [],
|
|
"targets": [
|
|
1
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
1
|
|
],
|
|
"resume-token-1001"
|
|
],
|
|
"watchSnapshot": 1001,
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"removed": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"errorCode": 0,
|
|
"fromCache": false,
|
|
"hasPendingWrites": false
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"limboDocs": [],
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": "resume-token-1001"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
]
|
|
},
|
|
"OnlineState timeout triggers offline behavior": {
|
|
"describeName": "Offline:",
|
|
"itName": "OnlineState timeout triggers offline behavior",
|
|
"tags": [],
|
|
"config": {
|
|
"useGarbageCollection": true
|
|
},
|
|
"steps": [
|
|
{
|
|
"userListen": [
|
|
2,
|
|
{
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
}
|
|
],
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": ""
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"runTimer": "online_state_timeout",
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"watchAck": [
|
|
2
|
|
]
|
|
},
|
|
{
|
|
"watchEntity": {
|
|
"docs": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"targets": [
|
|
2
|
|
]
|
|
}
|
|
},
|
|
{
|
|
"watchCurrent": [
|
|
[
|
|
2
|
|
],
|
|
"resume-token-1000"
|
|
],
|
|
"watchSnapshot": 1000,
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"added": [
|
|
[
|
|
"collection/a",
|
|
1000,
|
|
{
|
|
"key": "a"
|
|
}
|
|
]
|
|
],
|
|
"errorCode": 0,
|
|
"fromCache": false,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
},
|
|
{
|
|
"runTimer": "all"
|
|
},
|
|
{
|
|
"watchStreamClose": {
|
|
"error": {
|
|
"code": 14,
|
|
"message": "Simulated Backend Error"
|
|
}
|
|
},
|
|
"stateExpect": {
|
|
"activeTargets": {
|
|
"2": {
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"resumeToken": "resume-token-1000"
|
|
}
|
|
}
|
|
}
|
|
},
|
|
{
|
|
"runTimer": "online_state_timeout",
|
|
"expect": [
|
|
{
|
|
"query": {
|
|
"path": "collection",
|
|
"filters": [],
|
|
"orderBys": []
|
|
},
|
|
"errorCode": 0,
|
|
"fromCache": true,
|
|
"hasPendingWrites": false
|
|
}
|
|
]
|
|
}
|
|
]
|
|
}
|
|
}
|