Add 3 helper APIs on top of MITM callbacks #119
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.
Part of #68
These helper APIs all have proven needs in existing tests, and this commit converts at least 1 test for each type of helper API to demonstrate how they can be used.
callback.SendError
: the simplest of the new APIs. This sends an HTTP error instead of the response a configurable number of times, after which point it passes the response through. Useful for testing that clients retry endpoints.callback.PassiveChannel
: this sniffs callback data and sends it on a buffered (non-blocking) or unbuffered (blocking) channel. Useful for testing that the client sent a request.callback.ActiveChannel
: this is a passive channel but it also allows responses to be sent back for each intercepted callback. As such, it is always an unbuffered (blocking) channel. Useful for performing an action when the test sees a certain callback.Channels exist to reduce the amount of concurrent code that needs to be written for each test. It does this by:
Tests can just using normal Go
chan
, but then they will need to reimplement these things for each test.A good example of how this can simplify code is to look at how this PR changes
testUnprocessedToDeviceMessagesArentLostOnRestartJS
which closes the client when it detects a/sync
response. Previously, we needed 2 additional goroutines and multiple waiters to synchronise between them. Using a singleActiveChannel
, we only need 1 additional goroutine (to callStartSyncing()
as that blocks) and that's it. The channel manages the synchronisation between the callback goroutine and the test goroutine, meaning the test goroutine itself can manage checking the callback data, whereas this had to be done in the callback goroutine before. It is always preferable for the main test goroutine (the goroutine runningTestWhatever
) to deal with data, as that means the test needs no additional synchronisation primitives to control access to that data.