Test concurrent submissions that affect same entity #1202
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR adds a test for getodk/central#705. It runs the race condition described in the issue many times, asserting that it is successful each time.
Why is this the best possible solution? Were any other approaches considered?
The test in #1033 takes a more explanatory approach, beginning transactions manually and controlling the timing of queries. I think that test is helpful, but it didn't seem useful to just copy it for this new issue. It's also not easy to control the timing of
Entities._processSubmissionEvent()
, which I think would be needed in order to write such a test.The test that I wrote runs the race condition described in the issue. Even without locking, things occasionally work fine: the offline update doesn't end up stuck in the backlog. That's the case <10% of the time on my local machine. Given that things sometimes work, I run the race condition 50 times. I think it's nice to have a test that demonstrates the race condition as described in the issue and that fails if locking is removed.
I tried to do more to control the timing of
Entities._processSubmissionEvent()
, thinking that that would allow me to run the race condition only once. Specifically, this is what I had in mind:Entities._computeBaseVersion()
is run.However, it turned out to be harder than expected to spy on
Entities._computeBaseVersion()
. Each time a new container is created, it looks like the query modules are recreated (injector()
in lib/model/container.js). Further, a new container is created when a parent transaction is begun. I was able to spy onEntities._computeBaseVersion()
in the container supplied to the test, but that didn't end up being the sameEntities._computeBaseVersion()
run byEntities._processSubmissionEvent()
, as processing an event begins a new transaction.Before submitting this PR, please make sure you have:
make test
and confirmed all checks still pass OR confirm CircleCI build passes