Commit 01e1b599 authored by Yossi Gottlieb's avatar Yossi Gottlieb
Browse files

Merge remote-tracking branch 'upstream/master'

parents 25df21a1 296c7e0b
......@@ -21,12 +21,13 @@ SHAREDEXT = dylib
CFLAGS += -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/
CFLAGS += -I/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk/usr/include
CFLAGS += $(ASANFLAGS)
CFLAGS += -Wno-nullability-completeness
else
SHAREDFLAGS = -shared
SHAREDEXT = so
endif
OBJECTS = raft_server.o raft_server_properties.o raft_node.o raft_log.o
OBJECTS = src/raft_server.o src/raft_server_properties.o src/raft_node.o src/raft_log.o
all: static shared
......@@ -58,10 +59,23 @@ tests: src/raft_server.c src/raft_server_properties.c src/raft_log.c src/raft_no
./tests_main
gcov raft_server.c
.PHONY: fuzzer_tests
fuzzer_tests:
.PHONY: test_fuzzer
test_fuzzer:
python tests/log_fuzzer.py
.PHONY: tests_full
tests_full:
make clean
make tests
make test_fuzzer
make test_virtraft
.PHONY: test_virtraft
test_virtraft:
cp src/*.c virtraft/deps/raft/
cp include/*.h virtraft/deps/raft/
cd virtraft; make clean; make; make tests
.PHONY: amalgamation
amalgamation:
./scripts/amalgamate.sh > raft.h
......@@ -72,7 +86,7 @@ infer: do_infer
.PHONY: do_infer
do_infer:
make clean
infer -- make static
infer -- make
clean:
@rm -f $(TEST_DIR)/main_test.c *.o $(GCOV_OUTPUT); \
......
......@@ -40,7 +40,7 @@ typedef struct
void* raft;
} log_private_t;
int mod(int a, int b)
static int mod(int a, int b)
{
int r = a % b;
return r < 0 ? r + b : r;
......
......@@ -233,7 +233,6 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
if (me->request_timeout <= me->timeout_elapsed)
raft_send_appendentries_all(me_);
}
else if (me->election_timeout_rand <= me->timeout_elapsed &&
/* Don't become the leader when building snapshots or bad things will
* happen when we get a client request */
......@@ -251,7 +250,7 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
if (me->last_applied_idx < raft_get_commit_idx(me_) &&
!raft_snapshot_is_in_progress(me_))
{
int e = raft_apply_entry(me_);
int e = raft_apply_all(me_);
if (0 != e)
return e;
}
......@@ -445,9 +444,15 @@ int raft_recv_appendentries(
__log(me_, node, "AE term doesn't match prev_term (ie. %d vs %d) ci:%d comi:%d lcomi:%d pli:%d",
ety->term, ae->prev_log_term, raft_get_current_idx(me_),
raft_get_commit_idx(me_), ae->leader_commit, ae->prev_log_idx);
if (ae->prev_log_idx <= raft_get_commit_idx(me_))
{
/* Should never happen; something is seriously wrong! */
__log(me_, node, "AE prev conflicts with committed entry");
e = RAFT_ERR_SHUTDOWN;
goto out;
}
/* Delete all the following log entries because they don't match */
e = raft_delete_entry_from_idx(me_,
max(ae->prev_log_idx, ae->leader_commit + 1));
e = raft_delete_entry_from_idx(me_, ae->prev_log_idx);
goto out;
}
}
......@@ -464,8 +469,17 @@ int raft_recv_appendentries(
raft_entry_t* ety = &ae->entries[i];
int ety_index = ae->prev_log_idx + 1 + i;
raft_entry_t* existing_ety = raft_get_entry_from_idx(me_, ety_index);
if (existing_ety && existing_ety->term != ety->term && me->commit_idx < ety_index)
if (existing_ety && existing_ety->term != ety->term)
{
if (ety_index <= raft_get_commit_idx(me_))
{
/* Should never happen; something is seriously wrong! */
__log(me_, node, "AE entry conflicts with committed entry ci:%d comi:%d lcomi:%d pli:%d",
raft_get_current_idx(me_), raft_get_commit_idx(me_),
ae->leader_commit, ae->prev_log_idx);
e = RAFT_ERR_SHUTDOWN;
goto out;
}
e = raft_delete_entry_from_idx(me_, ety_index);
if (0 != e)
goto out;
......@@ -1291,7 +1305,7 @@ int raft_begin_load_snapshot(
if (last_included_index == -1)
return -1;
if (last_included_index == 0 || last_included_index == 0)
if (last_included_index == 0 || last_included_term == 0)
return -1;
/* loading the snapshot will break cluster safety */
......
......@@ -43,6 +43,16 @@ int __raft_applylog(
return 0;
}
int __raft_applylog_shutdown(
raft_server_t* raft,
void *udata,
raft_entry_t *ety,
int idx
)
{
return RAFT_ERR_SHUTDOWN;
}
int __raft_send_requestvote(raft_server_t* raft,
void* udata,
raft_node_t* node,
......@@ -464,6 +474,37 @@ void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx(
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
}
void TestRaft_user_applylog_error_propogates_to_periodic(
CuTest* tc)
{
raft_cbs_t funcs = {
.persist_term = __raft_persist_term,
.applylog = __raft_applylog_shutdown,
};
void *r = raft_new();
raft_set_callbacks(r, &funcs, NULL);
/* must be follower */
raft_set_state(r, RAFT_STATE_FOLLOWER);
raft_set_current_term(r, 1);
raft_set_last_applied_idx(r, 0);
/* need at least one entry */
raft_entry_t ety = {};
ety.term = 1;
ety.id = 1;
ety.data.buf = "aaa";
ety.data.len = 3;
raft_append_entry(r, &ety);
raft_set_commit_idx(r, 1);
/* let time lapse */
CuAssertIntEquals(tc, RAFT_ERR_SHUTDOWN, raft_periodic(r, 1));
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
}
void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc)
{
raft_cbs_t funcs = {
......@@ -3134,10 +3175,6 @@ void TestRaft_leader_recv_appendentries_response_do_not_increase_commit_idx_beca
raft_recv_appendentries_response(r, raft_get_node(r, 3), &aer);
CuAssertIntEquals(tc, 3, raft_get_commit_idx(r));
raft_periodic(r, 1);
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
raft_periodic(r, 1);
CuAssertIntEquals(tc, 2, raft_get_last_applied_idx(r));
raft_periodic(r, 1);
CuAssertIntEquals(tc, 3, raft_get_last_applied_idx(r));
}
......
......@@ -369,6 +369,22 @@ void TestRaft_follower_load_from_snapshot(CuTest * tc)
CuAssertIntEquals(tc, 7, raft_get_commit_idx(r));
}
void TestRaft_follower_load_from_snapshot_fails_if_term_is_0(CuTest * tc)
{
raft_cbs_t funcs = {
};
void *r = raft_new();
raft_set_callbacks(r, &funcs, NULL);
raft_add_node(r, NULL, 1, 1);
raft_add_node(r, NULL, 2, 0);
raft_set_state(r, RAFT_STATE_FOLLOWER);
CuAssertIntEquals(tc, 0, raft_get_log_count(r));
CuAssertIntEquals(tc, -1, raft_begin_load_snapshot(r, 0, 5));
}
void TestRaft_follower_load_from_snapshot_fails_if_already_loaded(CuTest * tc)
{
raft_cbs_t funcs = {
......
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