-
Notifications
You must be signed in to change notification settings - Fork 948
Clean up recovery spec tests #3085
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,10 @@ import { Code } from '../../../src/util/error'; | |
import { deletedDoc, doc, filter, path } from '../../util/helpers'; | ||
import { RpcError } from './spec_rpc_error'; | ||
|
||
// The IndexedDB action that the Watch stream uses to detect if IndexedDB access | ||
// is available again. | ||
const ASYNC_QUEUE_PROBER = 'Get last remote snapshot version'; | ||
|
||
describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | ||
specTest( | ||
'Write is acknowledged by primary client (with recovery)', | ||
|
@@ -34,11 +38,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.client(1) | ||
.expectPrimaryState(false) | ||
.userSets('collection/a', { v: 1 }) | ||
.failDatabaseTransactions({ | ||
'Locally write mutations': true, | ||
'Synchronize last document change read time': true, | ||
'Lookup mutation documents': true | ||
}) | ||
.failDatabaseTransactions('Lookup mutation documents') | ||
.client(0) | ||
.writeAcks('collection/a', 1, { expectUserCallback: false }) | ||
.client(1) | ||
|
@@ -62,24 +62,21 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
['multi-client'], | ||
() => { | ||
const query = Query.atPath(path('collection')); | ||
const doc1 = doc('collection/doc', 1, { foo: 'a' }); | ||
|
||
return client(0) | ||
.expectPrimaryState(true) | ||
.client(1) | ||
.expectPrimaryState(false) | ||
.userListens(query) | ||
.failDatabaseTransactions({ | ||
'Allocate target': true, | ||
'Lookup mutation documents': true, | ||
'Get new document changes': true | ||
}) | ||
.failDatabaseTransactions('Get new document changes') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same concern here: previously this failed to allocate a target at all, which should have caused the listen to fail. Now this is only failing much later. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar response: The target is already allocated and this seems like a copy/paste issue. Failed target allocations are tested in 'Fails targets that cannot be allocated'. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. I see it now. Thanks for talking it through with me. |
||
.client(0) | ||
.expectListen(query) | ||
.watchAcksFull(query, 1000) | ||
.watchAcksFull(query, 1000, doc1) | ||
.client(1) | ||
.recoverDatabase() | ||
.runTimer(TimerId.AsyncQueueRetry) | ||
.expectEvents(query, {}); | ||
.expectEvents(query, { added: [doc1] }); | ||
} | ||
); | ||
|
||
|
@@ -92,10 +89,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
return ( | ||
client(0) | ||
.expectPrimaryState(true) | ||
.failDatabaseTransactions({ | ||
'Allocate target': true, | ||
'Get target data': true | ||
}) | ||
.failDatabaseTransactions('Allocate target', 'Get target data') | ||
.client(1) | ||
.userListens(query) | ||
.client(0) | ||
|
@@ -105,10 +99,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.recoverDatabase() | ||
.runTimer(TimerId.AsyncQueueRetry) | ||
.expectListen(query) | ||
.failDatabaseTransactions({ | ||
'Allocate target': true, | ||
'Release target': true | ||
}) | ||
.failDatabaseTransactions('Release target') | ||
.client(1) | ||
.userUnlistens(query) | ||
.client(0) | ||
|
@@ -130,18 +121,12 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.expectNumOutstandingWrites(1) | ||
// We fail the write if we cannot persist the local mutation (via | ||
// 'Locally write mutations'). | ||
.failDatabaseTransactions({ | ||
'Locally write mutations': true | ||
}) | ||
.failDatabaseTransactions('Locally write mutations') | ||
.userSets('collection/key2', { bar: 'b' }) | ||
.expectUserCallbacks({ rejected: ['collection/key2'] }) | ||
// The write is considered successful if we can persist the local mutation | ||
// but fail to update view assignments (via 'notifyLocalViewChanges'). | ||
.failDatabaseTransactions({ | ||
'Locally write mutations': false, | ||
notifyLocalViewChanges: true, | ||
'Get next mutation batch': false | ||
}) | ||
.failDatabaseTransactions('notifyLocalViewChanges') | ||
.userSets('collection/key3', { bar: 'b' }) | ||
.recoverDatabase() | ||
.expectNumOutstandingWrites(2) | ||
|
@@ -178,11 +163,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
fromCache: true, | ||
hasPendingWrites: true | ||
}) | ||
.failDatabaseTransactions({ | ||
'Locally write mutations': true, | ||
notifyLocalViewChanges: true, | ||
'Get next mutation batch': true | ||
}) | ||
.failDatabaseTransactions('Locally write mutations') | ||
.userSets('collection/key2', { foo: 'b' }) | ||
.expectUserCallbacks({ rejected: ['collection/key2'] }) | ||
.recoverDatabase() | ||
|
@@ -213,12 +194,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
const doc2 = doc('collection/key2', 2, { foo: 'b' }); | ||
return spec() | ||
.userListens(query) | ||
.failDatabaseTransactions({ | ||
'Locally write mutations': false, | ||
notifyLocalViewChanges: true, | ||
'Get next mutation batch': false, | ||
'Set last stream token': false | ||
}) | ||
.failDatabaseTransactions('notifyLocalViewChanges') | ||
.userSets('collection/key1', { foo: 'a' }) | ||
.expectEvents(query, { | ||
added: [doc1Local], | ||
|
@@ -228,11 +204,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.recoverDatabase() | ||
.runTimer(TimerId.AsyncQueueRetry) | ||
.writeAcks('collection/key1', 1) | ||
.failDatabaseTransactions({ | ||
'Apply remote event': false, | ||
notifyLocalViewChanges: true, | ||
'Get last remote snapshot version': false | ||
}) | ||
.failDatabaseTransactions('notifyLocalViewChanges') | ||
.watchAcksFull(query, 1000, doc1, doc2) | ||
.expectEvents(query, { | ||
metadata: [doc1], | ||
|
@@ -256,11 +228,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.expectEvents(query, { | ||
added: [doc1] | ||
}) | ||
.failDatabaseTransactions({ | ||
'Apply remote event': false, | ||
notifyLocalViewChanges: true, | ||
'Get last remote snapshot version': false | ||
}) | ||
.failDatabaseTransactions('notifyLocalViewChanges') | ||
.watchSends({ removed: [query] }, deletedDoc1) | ||
.watchSnapshots(2000) | ||
.expectEvents(query, { | ||
|
@@ -282,7 +250,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.userListens(query1) | ||
.watchAcksFull(query1, 1) | ||
.expectEvents(query1, {}) | ||
.failDatabaseTransactions({ 'Allocate target': true }) | ||
.failDatabaseTransactions('Allocate target') | ||
.userListens(query2) | ||
.expectEvents(query2, { errorCode: Code.UNAVAILABLE }) | ||
.recoverDatabase() | ||
|
@@ -298,7 +266,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.userListens(query1) | ||
.watchAcksFull(query1, 1) | ||
.expectEvents(query1, {}) | ||
.failDatabaseTransactions({ 'Allocate target': true }) | ||
.failDatabaseTransactions('Allocate target') | ||
.userListens(query2) | ||
.expectEvents(query2, { errorCode: Code.UNAVAILABLE }) | ||
.recoverDatabase() | ||
|
@@ -320,12 +288,9 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
added: [doc1] | ||
}) | ||
.watchSends({ affects: [query] }, doc2) | ||
.failDatabaseTransactions({ | ||
'Get last remote snapshot version': true, | ||
'Release target': true | ||
}) | ||
.failDatabaseTransactions('Get last remote snapshot version') | ||
.watchSnapshots(1500) | ||
// `failDatabase()` causes us to go offline. | ||
// `failDatabaseTransactions()` causes us to go offline. | ||
.expectActiveTargets() | ||
.expectEvents(query, { fromCache: true }) | ||
.recoverDatabase() | ||
|
@@ -357,15 +322,12 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
.expectEvents(doc2Query, { | ||
added: [doc2] | ||
}) | ||
.failDatabaseTransactions({ | ||
'Get last remote snapshot version': true, | ||
'Release target': true | ||
}) | ||
.failDatabaseTransactions('Release target', ASYNC_QUEUE_PROBER) | ||
.watchRemoves( | ||
doc1Query, | ||
new RpcError(Code.PERMISSION_DENIED, 'Simulated target error') | ||
) | ||
// `failDatabase()` causes us to go offline. | ||
// `failDatabaseTransactions()` causes us to go offline. | ||
.expectActiveTargets() | ||
.expectEvents(doc1Query, { fromCache: true }) | ||
.expectEvents(doc2Query, { fromCache: true }) | ||
|
@@ -416,7 +378,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
}) | ||
.watchAcksFull(filteredQuery, 2000) | ||
.expectLimboDocs(doc1a.key) | ||
.failDatabaseTransactions({ 'Get last remote snapshot version': true }) | ||
.failDatabaseTransactions('Get last remote snapshot version') | ||
.watchAcksFull(limboQuery, 3000, doc1b) | ||
.expectActiveTargets() | ||
.recoverDatabase() | ||
|
@@ -459,10 +421,7 @@ describeSpec('Persistence Recovery', ['no-ios', 'no-android'], () => { | |
}) | ||
.watchAcksFull(filteredQuery, 2000) | ||
.expectLimboDocs(doc1.key) | ||
.failDatabaseTransactions({ | ||
'Apply remote event': true, | ||
'Get last remote snapshot version': true | ||
}) | ||
.failDatabaseTransactions('Apply remote event', ASYNC_QUEUE_PROBER) | ||
.watchRemoves( | ||
limboQuery, | ||
new RpcError(Code.PERMISSION_DENIED, 'Test error') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a different test than what was here before. Previously the write of the mutation to IndexedDB would fail (as would the lookup) but now this is failing just the lookup and allowing the write to succeed?
Alternatively, if this is working as intended, better names would help make it clearer just which transaction is failing. For example, if this were named
multitab.secondary.mutationLookup
it would be much, much clearer.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is already a dedicated test that test if "Locally write mutations" fails ("Recovers when write cannot be persisted"). The fact that "Locally write mutations" is part of this list seems like an oversight to me - the mutation gets written right before and not after we start injecting failures.
There are certainly improvements to the transaction names that we should make before we port to Android/iOS, but I would like to point out that 'Lookup mutation documents' is also used by the primary tab to load a mutation that has been written by a secondary tab.