-
Notifications
You must be signed in to change notification settings - Fork 9.8k
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
raft/rafttest: introduce datadriven testing #11005
Conversation
Picks up some fixes for papercuts.
Thanks for the reviews so far. I need to address some more additional comments and clean up some more, will ping when it's ready. |
Codecov Report
@@ Coverage Diff @@
## master #11005 +/- ##
=========================================
+ Coverage 63.98% 64.18% +0.2%
=========================================
Files 402 402
Lines 37646 37712 +66
=========================================
+ Hits 24087 24205 +118
+ Misses 11955 11897 -58
- Partials 1604 1610 +6
Continue to review full report at Codecov.
|
It has often been tedious to test the interactions between multi-member Raft groups, especially when many steps were required to reach a certain scenario. Often, this boilerplate was as boring as it is hard to write and hard to maintain, making it attractive to resort to shortcuts whenever possible, which in turn tended to undercut how meaningful and maintainable the tests ended up being - that is, if the tests were even written, which sometimes they weren't. This change introduces a datadriven framework specifically for testing deterministically the interaction between multiple members of a raft group with the goal of reducing the friction for writing these tests to near zero. In the near term, this will be used to add thorough testing for joint consensus (which is already available today, but wildly undertested), but just converting an existing test into this framework has shown that the concise representation and built-in inspection of log messages highlights unexpected behavior much more readily than the previous unit tests did (the test in question is `snapshot_succeed_via_app_resp`; the reader is invited to compare the old and new version of it). The main building block is `InteractionEnv`, which holds on to the state of the whole system and exposes various relevant methods for manipulating it, including but not limited to adding nodes, delivering and dropping messages, and proposing configuration changes. All of this is extensible so that in the future I hope to use it to explore the phenomena discussed in etcd-io#7625 (comment) which requires injecting appropriate "crash points" in the Ready handling loop. Discussions of the "what if X happened in state Y" can quickly be made concrete by "scripting up an interaction test". Additionally, this framework is intentionally not kept internal to the raft package.. Though this is in its infancy, a goal is that it should be possible for a suite of interaction tests to allow applications to validate that their Storage implementation behaves accordingly, simply by running a raft-provided interaction suite against their Storage.
Going to merge this now, but happy to address any follow-up comments. |
It has often been tedious to test the interactions between multi-member
Raft groups, especially when many steps were required to reach a certain
scenario. Often, this boilerplate was as boring as it is hard to write and
hard to maintain, making it attractive to resort to shortcuts whenever
possible, which in turn tended to undercut how meaningful and maintainable
the tests ended up being - that is, if the tests were even written, which
sometimes they weren't.
This change introduces a datadriven framework specifically for testing
deterministically the interaction between multiple members of a raft group
with the goal of reducing the friction for writing these tests to near
zero.
In the near term, this will be used to add thorough testing for joint
consensus (which is already available today, but wildly undertested), but
just converting an existing test into this framework has shown that the
concise representation and built-in inspection of log messages highlights
unexpected behavior much more readily than the previous unit tests did (the
test in question is
snapshot_succeed_via_app_resp
; the reader is invitedto compare the old and new version of it).
The main building block is
InteractionEnv
, which holds on to the state ofthe whole system and exposes various relevant methods for manipulating it,
including but not limited to adding nodes, delivering and dropping
messages, and proposing configuration changes. All of this is extensible so
that in the future I hope to use it to explore the phenomena discussed in
#7625 (comment)
which requires injecting appropriate "crash points" in the Ready handling
loop. Discussions of the "what if X happened in state Y" can quickly be
made concrete by "scripting up an interaction test".
Additionally, this framework is intentionally not kept internal to the raft
package.. Though this is in its infancy, a goal is that it should be
possible for a suite of interaction tests to allow applications to validate
that their Storage implementation behaves accordingly, simply by running a
raft-provided interaction suite against their Storage.