Commit dc4fc5f7 authored by willem's avatar willem
Browse files

Merge test_server_appendentries into test_follower

parent 49176fc7
...@@ -121,8 +121,9 @@ CuTest* CuTestNew(const char* name, TestFunction function) ...@@ -121,8 +121,9 @@ CuTest* CuTestNew(const char* name, TestFunction function)
void CuTestRun(CuTest* tc) void CuTestRun(CuTest* tc)
{ {
#if 0 /* debugging */
printf(" running %s\n", tc->name); printf(" running %s\n", tc->name);
#endif
jmp_buf buf; jmp_buf buf;
tc->jumpBuf = &buf; tc->jumpBuf = &buf;
if (setjmp(buf) == 0) if (setjmp(buf) == 0)
...@@ -263,49 +264,27 @@ void CuSuiteRun(CuSuite* testSuite) ...@@ -263,49 +264,27 @@ void CuSuiteRun(CuSuite* testSuite)
} }
} }
void CuSuiteSummary(CuSuite* testSuite, CuString* summary)
{
int i;
for (i = 0 ; i < testSuite->count ; ++i)
{
CuTest* testCase = testSuite->list[i];
CuStringAppend(summary, testCase->failed ? "F" : ".");
}
CuStringAppend(summary, "\n\n");
}
void CuSuiteDetails(CuSuite* testSuite, CuString* details) void CuSuiteDetails(CuSuite* testSuite, CuString* details)
{ {
int i; int i;
int failCount = 0; int failCount = 0;
if (testSuite->failCount == 0) CuStringAppendFormat(details, "%d..%d\n", 1, testSuite->count);
{
int passCount = testSuite->count - testSuite->failCount; for (i = 0 ; i < testSuite->count ; ++i)
const char* testWord = passCount == 1 ? "test" : "tests"; {
CuStringAppendFormat(details, "OK (%d %s)\n", passCount, testWord); CuTest* testCase = testSuite->list[i];
}
else if (testCase->failed)
{ {
if (testSuite->failCount == 1) failCount++;
CuStringAppend(details, "There was 1 failure:\n"); CuStringAppendFormat(details, "not ok %d - %s #%s\n",
else i+1, testCase->name, testCase->message);
CuStringAppendFormat(details, "There were %d failures:\n", testSuite->failCount); }
else
for (i = 0 ; i < testSuite->count ; ++i) {
{ CuStringAppendFormat(details, "ok %d - %s\n",
CuTest* testCase = testSuite->list[i]; i+1, testCase->name);
if (testCase->failed) }
{ }
failCount++;
CuStringAppendFormat(details, "%d) %s: %s\n",
failCount, testCase->name, testCase->message);
}
}
CuStringAppend(details, "\n!!!FAILURES!!!\n");
CuStringAppendFormat(details, "Runs: %d ", testSuite->count);
CuStringAppendFormat(details, "Passes: %d ", testSuite->count - testSuite->failCount);
CuStringAppendFormat(details, "Fails: %d\n", testSuite->failCount);
}
} }
...@@ -36,7 +36,7 @@ main_test.c: ...@@ -36,7 +36,7 @@ main_test.c:
fi fi
sh make-tests.sh "test_*.c" > main_test.c sh make-tests.sh "test_*.c" > main_test.c
tests_main: main_test.c raft_server.c raft_candidate.c raft_follower.c raft_leader.c test_server.c test_server_appendentries.c test_server_request_vote.c test_follower.c test_candidate.c test_leader.c mock_send_functions.c CuTest.c $(HASHMAP_DIR)/linked_list_hashmap.c $(LLQUEUE_DIR)/linked_list_queue.c tests_main: main_test.c raft_server.c raft_candidate.c raft_follower.c raft_leader.c test_server.c test_server_request_vote.c test_follower.c test_candidate.c test_leader.c mock_send_functions.c CuTest.c $(HASHMAP_DIR)/linked_list_hashmap.c $(LLQUEUE_DIR)/linked_list_queue.c
$(CC) $(CCFLAGS) -o $@ $^ $(CC) $(CCFLAGS) -o $@ $^
./tests_main ./tests_main
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
# Author: Asim Jalis # Author: Asim Jalis
# Date: 01/08/2003 # Date: 01/08/2003
FILES=$1 FILES=*.c
#if test $# -eq 0 ; then FILES=*.c ; else FILES=$* ; fi #if test $# -eq 0 ; then FILES=*.c ; else FILES=$* ; fi
...@@ -23,7 +23,7 @@ cat $FILES | grep '^void Test' | ...@@ -23,7 +23,7 @@ cat $FILES | grep '^void Test' |
-e 's/$/(CuTest*);/' \ -e 's/$/(CuTest*);/' \
-e 's/^/extern /' -e 's/^/extern /'
echo \ echo -n \
' '
void RunAllTests(void) void RunAllTests(void)
...@@ -41,7 +41,6 @@ cat $FILES | grep '^void Test' | ...@@ -41,7 +41,6 @@ cat $FILES | grep '^void Test' |
echo \ echo \
' '
CuSuiteRun(suite); CuSuiteRun(suite);
CuSuiteSummary(suite, output);
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\\n", output->buffer); printf("%s\\n", output->buffer);
} }
......
enum { enum {
RAFT_STATE_NONE,
RAFT_STATE_FOLLOWER, RAFT_STATE_FOLLOWER,
RAFT_STATE_CANDIDATE, RAFT_STATE_CANDIDATE,
RAFT_STATE_LEADER RAFT_STATE_LEADER
...@@ -144,16 +145,20 @@ void raft_become_candidate(raft_server_t* me); ...@@ -144,16 +145,20 @@ void raft_become_candidate(raft_server_t* me);
int raft_receive_append_entries(raft_server_t* me, msg_appendentries_t* ae); int raft_receive_append_entries(raft_server_t* me, msg_appendentries_t* ae);
int raft_periodic(void* me_); int raft_periodic(void* me_, int msec_since_last_period);
int raft_recv_appendentries(void* me_, void* peer, msg_appendentries_t* ae); int raft_recv_appendentries(void* me_, void* peer, msg_appendentries_t* ae);
int raft_recv_requestvote(void* me_, void* peer, msg_requestvote_t* vr); int raft_recv_requestvote(void* me_, void* peer, msg_requestvote_t* vr);
int raft_recv_requestvote_response(void* me_, void* peer, msg_requestvote_response_t* r);
void raft_execute_command(void* me_); void raft_execute_command(void* me_);
void raft_set_election_timeout(void* me_, int millisec); void raft_set_election_timeout(void* me_, int millisec);
int raft_get_election_timeout(void* me_);
int raft_vote(void* me_, void* peer); int raft_vote(void* me_, void* peer);
void* raft_add_peer(void* me_, void* peer_udata); void* raft_add_peer(void* me_, void* peer_udata);
...@@ -164,7 +169,7 @@ int raft_get_num_peers(void* me_); ...@@ -164,7 +169,7 @@ int raft_get_num_peers(void* me_);
int raft_recv_command(void* me_, void* peer, msg_command_t* cmd); int raft_recv_command(void* me_, void* peer, msg_command_t* cmd);
int raft_get_log_size(void* me_); int raft_get_log_count(void* me_);
void raft_set_current_term(void* me_,int term); void raft_set_current_term(void* me_,int term);
...@@ -183,3 +188,6 @@ int raft_is_leader(void* me_); ...@@ -183,3 +188,6 @@ int raft_is_leader(void* me_);
int raft_is_candidate(void* me_); int raft_is_candidate(void* me_);
int raft_send_requestvote(void* me_, void* peer); int raft_send_requestvote(void* me_, void* peer);
int raft_append_command(void* me_, unsigned char* data, int len);
...@@ -107,7 +107,7 @@ int raft_election_timeout_elapsed(void* me_) ...@@ -107,7 +107,7 @@ int raft_election_timeout_elapsed(void* me_)
} }
#endif #endif
int raft_periodic(void* me_) int raft_periodic(void* me_, int msec_since_last_period)
{ {
raft_server_t* me = me_; raft_server_t* me = me_;
...@@ -144,6 +144,11 @@ void raft_set_election_timeout(void* me_, int millisec) ...@@ -144,6 +144,11 @@ void raft_set_election_timeout(void* me_, int millisec)
{ {
} }
int raft_get_election_timeout(void* me_)
{
return 0;
}
int raft_vote(void* me_, void* peer) int raft_vote(void* me_, void* peer)
{ {
return 0; return 0;
...@@ -177,7 +182,7 @@ int raft_recv_command(void* me_, void* peer, msg_command_t* cmd) ...@@ -177,7 +182,7 @@ int raft_recv_command(void* me_, void* peer, msg_command_t* cmd)
return 0; return 0;
} }
int raft_get_log_size(void* me_) int raft_get_log_count(void* me_)
{ {
return 0; return 0;
} }
...@@ -226,3 +231,7 @@ int raft_send_requestvote(void* me_, void* peer) ...@@ -226,3 +231,7 @@ int raft_send_requestvote(void* me_, void* peer)
return 0; return 0;
} }
int raft_append_command(void* me_, unsigned char* data, int len)
{
return 0;
}
...@@ -46,29 +46,32 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc) ...@@ -46,29 +46,32 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc)
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_follower_becoming_candidate_requests_votes_from_other_server(CuTest * tc) void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTest * tc)
{ {
void *r; void *r;
void *sender; void *sender;
void *msg;
raft_external_functions_t funcs = { raft_external_functions_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_requestvote_t* rv;
sender = sender_new(); sender = sender_new();
r = raft_new(); r = raft_new();
raft_set_external_functions(r,&funcs,sender); raft_set_external_functions(r,&funcs,sender);
/* becoming candidate triggers vote requests */
raft_become_candidate(r); raft_become_candidate(r);
msg = sender_poll_msg(sender); rv = sender_poll_msg(sender);
// CuAssertTrue(tc, 1 == sender_msg_is_reqestvote(msg)); CuAssertTrue(tc, NULL != rv);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(CuTest * tc) void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(CuTest * tc)
{ {
void *r; void *r, *peer;
void *sender; void *sender;
void *msg; void *msg;
raft_external_functions_t funcs = { raft_external_functions_t funcs = {
...@@ -86,30 +89,24 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C ...@@ -86,30 +89,24 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C
r = raft_new(); r = raft_new();
/* three nodes */ /* three nodes */
raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender); raft_set_external_functions(r,&funcs,sender);
raft_set_current_term(r,1); raft_set_current_term(r,1);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_periodic(r); raft_periodic(r,1);
raft_recv_requestvote_response(r,&vr); raft_recv_requestvote_response(r,peer,&vr);
CuAssertTrue(tc, 0 == raft_is_leader(r)); CuAssertTrue(tc, 0 == raft_is_leader(r));
/* now has majority */ /* now has majority */
raft_recv_requestvote_response(r,&vr); raft_recv_requestvote_response(r,peer,&vr);
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
} }
/* Candidate 5.2 */
void TestRaft_candidate_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTest * tc)
{
}
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
{ {
void *r; void *r, *peer;
void *sender; void *sender;
void *msg; void *msg;
raft_external_functions_t funcs = { raft_external_functions_t funcs = {
...@@ -127,16 +124,16 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) ...@@ -127,16 +124,16 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
r = raft_new(); r = raft_new();
/* three nodes */ /* three nodes */
raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender); raft_set_external_functions(r,&funcs,sender);
raft_set_current_term(r,1); raft_set_current_term(r,1);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_recv_requestvote_response(r,&vr); raft_recv_requestvote_response(r,peer,&vr);
CuAssertTrue(tc, 0 == raft_is_leader(r)); CuAssertTrue(tc, 0 == raft_is_leader(r));
/* now has majority */ /* now has majority */
raft_recv_requestvote_response(r,&vr); raft_recv_requestvote_response(r,peer,&vr);
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
} }
...@@ -160,6 +157,8 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted( ...@@ -160,6 +157,8 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
sender = sender_new(); sender = sender_new();
r = raft_new(); r = raft_new();
raft_set_election_timeout(r,1000);
/* three nodes */ /* three nodes */
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
...@@ -168,48 +167,44 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted( ...@@ -168,48 +167,44 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
//raft_recv_requestvote( //raft_recv_requestvote(
CuAssertTrue(tc, 0 == raft_is_follower(r)); CuAssertTrue(tc, 0 == raft_is_follower(r));
raft_periodic(r); raft_periodic(r,1);
raft_recv_appendentries(r,peer,&ae); raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_candidate_will_reject_requestvote_if_its_log_is_more_complete(CuTest * tc) void TestRaft_candidate_requestvote_includes_loginfo(CuTest * tc)
{ {
void *r; void *r, *peer;
void *sender; void *sender;
void *msg;
raft_external_functions_t funcs = { raft_external_functions_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_requestvote_t* rv;
msg_requestvote_t rv;
memset(&rv,0,sizeof(msg_requestvote_t));
rv.lastLogTerm = 2;
rv.lastLogIndex = 2;
sender = sender_new(); sender = sender_new();
r = raft_new(); r = raft_new();
raft_set_state(r,RAFT_STATE_CANDIDATE);
/* three nodes */ /* three nodes */
raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender); raft_set_external_functions(r,&funcs,sender);
raft_set_current_term(r,5); raft_set_current_term(r,5);
raft_set_current_index(r,3); raft_set_current_index(r,3);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_send_requestvote(r,peer);
// raft_recv_requestvote(r,
CuAssertTrue(tc, 0 == raft_is_follower(r));
raft_periodic(r);
// raft_recv_appendentries(r,1,&ae); rv = sender_poll_msg(sender);
// CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 3 == rv->lastLogIndex);
CuAssertTrue(tc, 5 == rv->term);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_candidate_requestvote_includes_loginfo(CuTest * tc) void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower(CuTest * tc)
{ {
void *r, *peer; void *r, *peer;
void *sender; void *sender;
...@@ -219,59 +214,63 @@ void TestRaft_candidate_requestvote_includes_loginfo(CuTest * tc) ...@@ -219,59 +214,63 @@ void TestRaft_candidate_requestvote_includes_loginfo(CuTest * tc)
.log = NULL .log = NULL
}; };
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
sender = sender_new(); sender = sender_new();
r = raft_new(); r = raft_new();
/* three nodes */ /* three nodes */
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender); raft_set_external_functions(r,&funcs,sender);
raft_set_current_term(r,5); raft_set_current_term(r,1);
raft_set_current_index(r,3);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_send_requestvote(r,peer); CuAssertTrue(tc, 0 == raft_is_follower(r));
raft_periodic(r,1);
msg = sender_poll_msg(sender); raft_recv_appendentries(r,peer,&ae);
// CuAssertTrue(tc, msg_is_requestvote(msg)); CuAssertTrue(tc, 1 == raft_is_follower(r));
// CuAssertTrue(tc, 3 == msg_requestvote_get_index(msg));
// CuAssertTrue(tc, 5 == msg_requestvote_get_term(msg));
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower(CuTest * tc) void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_follower(CuTest * tc)
{ {
void *r, *peer; void *r, *peer;
void *sender; void *sender;
void *msg;
raft_external_functions_t funcs = { raft_external_functions_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_appendentries_t ae; msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
sender = sender_new(); sender = sender_new();
r = raft_new(); r = raft_new();
raft_set_external_functions(r,&funcs,sender);
/* server's log is newer */
raft_set_current_term(r,1);
raft_set_current_index(r,2);
/* three nodes */ /* three nodes */
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender); /* is a candidate */
raft_set_current_term(r,1);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
CuAssertTrue(tc, 0 == raft_is_follower(r)); CuAssertTrue(tc, 0 == raft_is_follower(r));
raft_periodic(r);
raft_recv_appendentries(r,peer,&ae); /* invalid leader determined by "leaders" old log */
CuAssertTrue(tc, 1 == raft_is_follower(r)); memset(&ae,0,sizeof(msg_appendentries_t));
} ae.term = 1;
ae.prevLogIndex = 1;
ae.prevLogTerm = 1;
/* Candidate 5.2 */ /* appendentry from invalid leader doesn't make candidate become follower */
void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_follower(CuTest * tc) raft_recv_appendentries(r,peer,&ae);
{ CuAssertTrue(tc, 0 == raft_is_follower(r));
} }
...@@ -9,11 +9,187 @@ ...@@ -9,11 +9,187 @@
#include "raft.h" #include "raft.h"
#include "mock_send_functions.h" #include "mock_send_functions.h"
/* 5.1 */
void TestRaft_follower_recv_appendentries_reply_false_when_term_less_than_currentterm(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
msg_appendentries_response_t *aer;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
/* higher current term */
raft_set_current_term(r,5);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
/* response is false */
aer = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 0 == aer->success);
}
void TestRaft_follower_recv_appendentries_updates_currentterm_when_term_gt_currentterm(CuTest * tc)
{
void *r, *peer;
msg_appendentries_t ae;
msg_appendentries_response_t *aer;
/* newer term */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
r = raft_new();
peer = raft_add_peer(r,(void*)1);
/* older currentterm */
raft_set_current_term(r,1);
/* appendentry has newer term, so we change our currentterm */
raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 2 == raft_get_current_term(r));
}
/* 5.3 */
void TestRaft_follower_recv_appendentries_reply_false_if_log_does_not_contain_entry_at_prevLogIndex(CuTest * tc)
{
void *r, *peer;
void *sender;
void *msg;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
msg_appendentries_response_t *aer;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_external_functions(r,&funcs,sender);
/* log index that server doesn't have */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 5;
ae.prevLogIndex = 5;
/* current term is old */
raft_set_current_term(r,5);
/* trigger reply */
raft_recv_appendentries(r,peer,&ae);
aer = sender_poll_msg(sender);
/* reply is false */
CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 0 == aer->success);
}
/* 5.3 */
void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries(CuTest * tc)
{
void *r, *peer;
msg_appendentries_t ae;
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,2);
/* first append entry */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
ae.prevLogIndex = 0;
ae.prevLogTerm = 0;
/* increase log size */
raft_append_command(r, "111", 3);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
/* pass a appendentry that is newer */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 0 == raft_get_log_count(r));
}
void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,1);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
// msg = sender_poll_msg(sender);
// CuAssertTrue(tc, aer);
// CuAssertTrue(tc, 1 == sender_msg_is_appendentries(msg));
// CuAssertTrue(tc, 1 == sender_msg_is_false(msg));
}
//If leaderCommit > commitIndex, set commitIndex =
//min(leaderCommit, last log index)
void TestRaft_follower_recv_appendentries_set_commitindex(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,1);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
// msg = sender_poll_msg(sender);
// CuAssertTrue(tc, aer);
// CuAssertTrue(tc, 1 == sender_msg_is_appendentries(msg));
// CuAssertTrue(tc, 1 == sender_msg_is_false(msg));
}
void TestRaft_follower_increases_log_after_appendentry(CuTest * tc) void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
{ {
void *r, *peer; void *r, *peer;
msg_appendentries_t ae; msg_appendentries_t ae;
/* appendentry */
memset(&ae,0,sizeof(msg_appendentries_t)); memset(&ae,0,sizeof(msg_appendentries_t));
r = raft_new(); r = raft_new();
...@@ -22,13 +198,13 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc) ...@@ -22,13 +198,13 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_current_term(r,1);
raft_set_state(r,RAFT_STATE_FOLLOWER); raft_set_state(r,RAFT_STATE_FOLLOWER);
CuAssertTrue(tc, 0 == raft_get_log_size(r)); /* log size s */
CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_appendentries(r,peer,&ae); raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 1 == raft_get_log_size(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
} }
void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones(CuTest * tc) void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones(CuTest * tc)
...@@ -36,29 +212,89 @@ void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedin ...@@ -36,29 +212,89 @@ void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedin
void *r, *peer; void *r, *peer;
msg_appendentries_t ae; msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
r = raft_new(); r = raft_new();
/* three nodes */ /* three nodes */
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_peer(r,(void*)2);
raft_set_current_term(r,1); raft_set_current_term(r,1);
raft_set_state(r,RAFT_STATE_FOLLOWER);
CuAssertTrue(tc, 0 == raft_get_log_size(r)); /* first append entry */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
ae.prevLogIndex = 0;
ae.prevLogTerm = 0;
CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_appendentries(r,peer,&ae); raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 1 == raft_get_log_size(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
} }
void TestRaft_follower_deletes_logentries_if_revealed_to_be_extraneous_by_new_appendentries(CuTest * tc) void TestRaft_follower_resends_command_if_request_from_leader_times_out(CuTest * tc)
{ {
} }
void TestRaft_follower_resends_command_if_request_from_leader_times_out(CuTest * tc) void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * tc)
{
void *r, *peer;
r = raft_new();
/* 1 second election timeout */
raft_set_election_timeout(r, 1000);
/* three nodes */
peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2);
/* 1.001 seconds have passed */
raft_periodic(r, 1001);
/* is a candidate now */
CuAssertTrue(tc, 1 == raft_is_candidate(r));
}
/* Candidate 5.2 */
void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTest * tc)
{ {
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_requestvote_t rv;
msg_requestvote_response_t *rvr;
sender = sender_new();
r = raft_new();
raft_set_external_functions(r,&funcs,sender);
/* three nodes */
peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2);
/* request vote */
/* vote indicates candidate's log is not complete compared to follower */
memset(&rv,0,sizeof(msg_requestvote_t));
rv.term = 1;
rv.candidateID = 0;
rv.lastLogIndex = 1;
rv.lastLogTerm = 1;
/* server's term and index are more up-to-date */
raft_set_current_term(r,1);
raft_set_current_index(r,2);
/* vote not granted */
raft_recv_requestvote(r,peer,&rv);
rvr = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != rvr);
CuAssertTrue(tc, 0 == rvr->voteGranted);
} }
...@@ -74,10 +74,10 @@ void TestRaft_leader_append_command_to_log_increases_idxno(CuTest * tc) ...@@ -74,10 +74,10 @@ void TestRaft_leader_append_command_to_log_increases_idxno(CuTest * tc)
r = raft_new(); r = raft_new();
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
CuAssertTrue(tc, 0 == raft_get_log_size(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_command(r,peer,&cmd); raft_recv_command(r,peer,&cmd);
CuAssertTrue(tc, 1 == raft_get_log_size(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
} }
void TestRaft_leader_doesnt_append_command_if_unique_id_is_duplicate(CuTest * tc) void TestRaft_leader_doesnt_append_command_if_unique_id_is_duplicate(CuTest * tc)
...@@ -92,13 +92,13 @@ void TestRaft_leader_doesnt_append_command_if_unique_id_is_duplicate(CuTest * tc ...@@ -92,13 +92,13 @@ void TestRaft_leader_doesnt_append_command_if_unique_id_is_duplicate(CuTest * tc
r = raft_new(); r = raft_new();
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
CuAssertTrue(tc, 0 == raft_get_log_size(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_command(r,peer,&cmd); raft_recv_command(r,peer,&cmd);
CuAssertTrue(tc, 1 == raft_get_log_size(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
raft_recv_command(r,peer,&cmd); raft_recv_command(r,peer,&cmd);
CuAssertTrue(tc, 1 == raft_get_log_size(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
} }
void TestRaft_leader_increase_commitno_when_majority_have_entry_and_atleast_one_newer_entry(CuTest * tc) void TestRaft_leader_increase_commitno_when_majority_have_entry_and_atleast_one_newer_entry(CuTest * tc)
......
...@@ -54,6 +54,7 @@ void TestRaft_remove_peer(CuTest * tc) ...@@ -54,6 +54,7 @@ void TestRaft_remove_peer(CuTest * tc)
r = raft_new(); r = raft_new();
peer = raft_add_peer(r,(void*)1); peer = raft_add_peer(r,(void*)1);
CuAssertTrue(tc, 1 == raft_get_num_peers(r));
raft_remove_peer(r,peer); raft_remove_peer(r,peer);
CuAssertTrue(tc, 0 == raft_get_num_peers(r)); CuAssertTrue(tc, 0 == raft_get_num_peers(r));
} }
...@@ -67,3 +68,28 @@ void TestRaft_set_state(CuTest * tc) ...@@ -67,3 +68,28 @@ void TestRaft_set_state(CuTest * tc)
CuAssertTrue(tc, RAFT_STATE_LEADER == raft_get_state(r)); CuAssertTrue(tc, RAFT_STATE_LEADER == raft_get_state(r));
} }
void TestRaft_server_starts_as_follower(CuTest * tc)
{
void *r;
r = raft_new();
CuAssertTrue(tc, RAFT_STATE_FOLLOWER == raft_get_state(r));
}
void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc)
{
void *r;
r = raft_new();
CuAssertTrue(tc, 1000 == raft_get_election_timeout(r));
}
void TestRaft_server_increases_logindex_when_command_appended(CuTest* tc)
{
void *r;
r = raft_new();
CuAssertTrue(tc, 0 == raft_get_current_index(r));
raft_append_command(r,"aaa", 3);
CuAssertTrue(tc, 1 == raft_get_current_index(r));
}
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "CuTest.h"
#include "raft.h"
#include "mock_send_functions.h"
/* 5.1 */
void TestRaft_server_recv_appendentries_reply_false_when_term_less_than_currentterm(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
msg_appendentries_response_t *aer;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
/* higher current term */
raft_set_current_term(r,5);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
/* response is false */
aer = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 0 == aer->success);
}
//Reply false if log doesnt contain an entry at prevLogIndex
//whose term matches prevLogTerm
// TODO
/* 5.3 */
void TestRaft_server_recv_appendentries_reply_false_if_log_does_not_contain_entry_at_prevLogIndex(CuTest * tc)
{
void *r, *peer;
void *sender;
void *msg;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
msg_appendentries_response_t *aer;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 5;
ae.prevLogIndex = 5;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,5);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
aer = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 0 == aer->success);
}
/* 5.3 */
void TestRaft_server_recv_appendentries_delete_entries_if_conflict_with_new_entries(CuTest * tc)
{
void *r, *peer;
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,1);
raft_recv_appendentries(r,peer,&ae);
}
void TestRaft_server_recv_appendentries_add_new_entries_not_already_in_log(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,1);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
// msg = sender_poll_msg(sender);
// CuAssertTrue(tc, aer);
// CuAssertTrue(tc, 1 == sender_msg_is_appendentries(msg));
// CuAssertTrue(tc, 1 == sender_msg_is_false(msg));
}
//If leaderCommit > commitIndex, set commitIndex =
//min(leaderCommit, last log index)
void TestRaft_server_recv_appendentries_set_commitindex(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_current_term(r,1);
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
// msg = sender_poll_msg(sender);
// CuAssertTrue(tc, aer);
// CuAssertTrue(tc, 1 == sender_msg_is_appendentries(msg));
// CuAssertTrue(tc, 1 == sender_msg_is_false(msg));
}
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