Commit aa3586ff authored by Willem Thiart's avatar Willem Thiart
Browse files

Add virtraft2

parent 3ff2682d
...@@ -72,9 +72,7 @@ tests_full: ...@@ -72,9 +72,7 @@ tests_full:
.PHONY: test_virtraft .PHONY: test_virtraft
test_virtraft: test_virtraft:
cp src/*.c virtraft/deps/raft/ python3 tests/virtraft2.py --servers 7 -i 20000 --compaction_rate 50 --drop_rate 5 -P 10 --seed 1 -m 3
cp include/*.h virtraft/deps/raft/
cd virtraft; make clean; make; make tests
.PHONY: amalgamation .PHONY: amalgamation
amalgamation: amalgamation:
......
...@@ -27,12 +27,43 @@ Quality Assurance ...@@ -27,12 +27,43 @@ Quality Assurance
We use the following methods to ensure that the library is safe: We use the following methods to ensure that the library is safe:
* A `simulator <https://github.com/willemt/virtraft>`_ is used to test the Raft invariants on unreliable networks * A simulator (virtraft2) is used to test the Raft invariants on unreliable networks
* `Fuzzing/property-based-testing <https://github.com/willemt/virtraft/blob/master/tests/test_fuzzer.py>`_ via `Hypothesis <https://github.com/DRMacIver/hypothesis/>`_ * `Fuzzing/property-based-testing <https://github.com/willemt/virtraft/blob/master/tests/test_fuzzer.py>`_ via `Hypothesis <https://github.com/DRMacIver/hypothesis/>`_
* All bugs have regression tests * All bugs have regression tests
* Many unit tests * Many unit tests
* `Usage <https://github.com/willemt/ticketd>`_ * `Usage <https://github.com/willemt/ticketd>`_
virtraft2
---------
This cluster simulator checks the following:
* Log Matching (servers must have matching logs)
* State Machine Safety (applied entries have the same ID)
* Election Safety (only one valid leader per term)
* Current Index Validity (does the current index have an existing entry?)
* Entry ID Monotonicity (entries aren't appended out of order)
* Committed entry popping (committed entries are not popped from the log)
* Log Accuracy (does the server's log match mirror an independent log?)
* Deadlock detection (does the cluster continuously make progress?)
Chaos generated by virtraft2:
* Random bi-directional partitions between nodes
* Message dropping
* Message duplication
* Membership change injection
* Random compactions
Run the simulator using:
.. code-block:: bash
:class: ignore
make test_virtraft
virtraft2 succeeds `virtraft <https://github.com/willemt/virtraft>`_
Single file amalgamation Single file amalgamation
======================== ========================
......
...@@ -10,14 +10,16 @@ ...@@ -10,14 +10,16 @@
#ifndef RAFT_H_ #ifndef RAFT_H_
#define RAFT_H_ #define RAFT_H_
#define RAFT_ERR_NOT_LEADER -2 typedef enum {
#define RAFT_ERR_ONE_VOTING_CHANGE_ONLY -3 RAFT_ERR_NOT_LEADER=-2,
#define RAFT_ERR_SHUTDOWN -4 RAFT_ERR_ONE_VOTING_CHANGE_ONLY=-3,
#define RAFT_ERR_NOMEM -5 RAFT_ERR_SHUTDOWN=-4,
#define RAFT_ERR_NEEDS_SNAPSHOT -6 RAFT_ERR_NOMEM=-5,
#define RAFT_ERR_SNAPSHOT_IN_PROGRESS -7 RAFT_ERR_NEEDS_SNAPSHOT=-6,
#define RAFT_ERR_SNAPSHOT_ALREADY_LOADED -8 RAFT_ERR_SNAPSHOT_IN_PROGRESS=-7,
#define RAFT_ERR_LAST -100 RAFT_ERR_SNAPSHOT_ALREADY_LOADED=-8,
RAFT_ERR_LAST=-100,
} raft_error_e;
typedef enum { typedef enum {
RAFT_MEMBERSHIP_ADD, RAFT_MEMBERSHIP_ADD,
......
...@@ -765,6 +765,7 @@ int raft_recv_entry(raft_server_t* me_, ...@@ -765,6 +765,7 @@ int raft_recv_entry(raft_server_t* me_,
r->idx = raft_get_current_idx(me_); r->idx = raft_get_current_idx(me_);
r->term = me->current_term; r->term = me->current_term;
/* FIXME: is this required if raft_append_entry does this too? */
if (raft_entry_is_voting_cfg_change(ety)) if (raft_entry_is_voting_cfg_change(ety))
me->voting_cfg_change_log_idx = raft_get_current_idx(me_); me->voting_cfg_change_log_idx = raft_get_current_idx(me_);
......
import cffi
import subprocess
ffi = cffi.FFI()
ffi.set_source(
"tests",
"""
""",
sources="""
src/raft_log.c
src/raft_server.c
src/raft_server_properties.c
src/raft_node.c
""".split(),
include_dirs=["include"],
)
library = ffi.compile()
ffi = cffi.FFI()
lib = ffi.dlopen(library)
def load(fname):
return '\n'.join(
[line for line in subprocess.check_output(
["gcc", "-E", fname]).decode('utf-8').split('\n')])
ffi.cdef('void *malloc(size_t __size);')
ffi.cdef(load('include/raft.h'))
ffi.cdef(load('include/raft_log.h'))
This diff is collapsed.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment