Commit 47472f6e authored by willem's avatar willem
Browse files

Finished writing tests

parent dc4fc5f7
......@@ -36,7 +36,7 @@ main_test.c:
fi
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_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 raft_peer.c test_server.c test_server_request_vote.c test_follower.c test_candidate.c test_leader.c test_peer.c mock_send_functions.c CuTest.c $(HASHMAP_DIR)/linked_list_hashmap.c $(LLQUEUE_DIR)/linked_list_queue.c
$(CC) $(CCFLAGS) -o $@ $^
./tests_main
......
......@@ -34,6 +34,11 @@ typedef struct {
unsigned int len;
} msg_command_t;
typedef struct {
unsigned int id;
int wasCommitted;
} msg_command_response_t;
typedef struct {
/* currentTerm, for candidate to update itself */
int term;
......@@ -78,15 +83,24 @@ typedef void (
) (
void *udata,
void *src,
// bt_peer_t * peer,
const char *buf,
...
);
#endif
typedef int (
*func_applylog_f
) (
void *caller,
void *udata,
const unsigned char *data,
const int len
);
typedef struct {
func_send_f send;
func_log_f log;
func_applylog_f applylog;
} raft_external_functions_t;
......@@ -189,5 +203,23 @@ int raft_is_candidate(void* me_);
int raft_send_requestvote(void* me_, void* peer);
void raft_send_appendentries(void* me_, void* peer);
int raft_append_command(void* me_, unsigned char* data, int len);
void raft_commit_command(void* me_, int logIndex);
void* raft_peer_new();
int raft_peer_is_leader(void* peer);
int raft_peer_get_next_index(void* peer);
void raft_peer_set_next_index(void* peer, int nextIdx);
void raft_set_commit_index(void* me_, int commit_idx);
void raft_set_lastapplied_index(void* me_, int idx);
int raft_get_lastapplied_index(void* me_);
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "raft.h"
typedef struct {
int pass;
} raft_peer_t;
void* raft_peer_new()
{
return NULL;
}
int raft_peer_is_leader(void* peer)
{
return 0;
}
int raft_peer_get_next_index(void* peer)
{
return 0;
}
void raft_peer_set_next_index(void* peer, int nextIdx)
{
}
......@@ -144,11 +144,20 @@ void raft_set_election_timeout(void* me_, int millisec)
{
}
void raft_set_request_timeout(void* me_, int millisec)
{
}
int raft_get_election_timeout(void* me_)
{
return 0;
}
int raft_get_request_timeout(void* me_)
{
return 0;
}
int raft_vote(void* me_, void* peer)
{
return 0;
......@@ -235,3 +244,32 @@ int raft_append_command(void* me_, unsigned char* data, int len)
{
return 0;
}
void raft_set_commit_index(void* me_, int commit_idx)
{
}
void raft_set_lastapplied_index(void* me_, int idx)
{
}
int raft_get_lastapplied_index(void* me_)
{
return 0;
}
int raft_get_commit_index(void* me_)
{
return 0;
}
void raft_commit_command(void* me_, int logIndex)
{
}
void raft_send_appendentries(void* me_, void* peer)
{
}
......@@ -174,7 +174,7 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
}
/* Candidate 5.2 */
void TestRaft_candidate_requestvote_includes_loginfo(CuTest * tc)
void TestRaft_candidate_requestvote_includes_logIndex(CuTest * tc)
{
void *r, *peer;
void *sender;
......@@ -271,6 +271,6 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f
/* appendentry from invalid leader doesn't make candidate become follower */
raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 0 == raft_is_follower(r));
CuAssertTrue(tc, 1 == raft_is_candidate(r));
}
......@@ -10,7 +10,7 @@
#include "mock_send_functions.h"
/* 5.1 */
void TestRaft_follower_recv_appendentries_reply_false_when_term_less_than_currentterm(CuTest * tc)
void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentterm(CuTest * tc)
{
void *r, *peer;
void *sender;
......@@ -39,7 +39,7 @@ void TestRaft_follower_recv_appendentries_reply_false_when_term_less_than_curren
CuAssertTrue(tc, 0 == aer->success);
}
void TestRaft_follower_recv_appendentries_updates_currentterm_when_term_gt_currentterm(CuTest * tc)
void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_currentterm(CuTest * tc)
{
void *r, *peer;
msg_appendentries_t ae;
......@@ -62,7 +62,7 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_when_term_gt_curre
}
/* 5.3 */
void TestRaft_follower_recv_appendentries_reply_false_if_log_does_not_contain_entry_at_prevLogIndex(CuTest * tc)
void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prevLogIndex(CuTest * tc)
{
void *r, *peer;
void *sender;
......@@ -136,6 +136,7 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
};
msg_appendentries_t ae;
/* appendentries has multiple entries */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
......@@ -148,6 +149,7 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
raft_set_external_functions(r,&funcs,sender);
raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 0);
// msg = sender_poll_msg(sender);
// CuAssertTrue(tc, aer);
// CuAssertTrue(tc, 1 == sender_msg_is_appendentries(msg));
......@@ -156,7 +158,7 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
//If leaderCommit > commitIndex, set commitIndex =
//min(leaderCommit, last log index)
void TestRaft_follower_recv_appendentries_set_commitindex(CuTest * tc)
void TestRaft_follower_recv_appendentries_set_commitindex_to_prevLogIdx(CuTest * tc)
{
void *r, *peer;
void *sender;
......@@ -166,21 +168,50 @@ void TestRaft_follower_recv_appendentries_set_commitindex(CuTest * tc)
};
msg_appendentries_t ae;
sender = sender_new();
r = raft_new();
peer = raft_add_peer(r,(void*)1);
raft_set_external_functions(r,&funcs,sender);
/* receive an appendentry with commit */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 2;
ae.term = 1;
ae.prevLogTerm = 1;
ae.prevLogIndex = 4;
ae.leaderCommit = 5;
sender = sender_new();
/* receipt of appendentries changes commit index */
raft_recv_appendentries(r,peer,&ae);
/* set to 4 because prevLogIdx is lower */
CuAssertTrue(tc, 4 == raft_get_commit_index(r));
}
void TestRaft_follower_recv_appendentries_set_commitindex_to_LeaderCommit(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t ae;
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));
/* receive an appendentry with commit */
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
ae.prevLogTerm = 1;
ae.prevLogIndex = 4;
ae.leaderCommit = 3;
/* receipt of appendentries changes commit index */
raft_recv_appendentries(r,peer,&ae);
/* set to 3 because leaderCommit is lower */
CuAssertTrue(tc, 3 == raft_get_commit_index(r));
}
void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
......@@ -233,10 +264,31 @@ void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedin
CuAssertTrue(tc, 1 == raft_get_log_count(r));
}
void TestRaft_follower_resends_command_if_request_from_leader_times_out(CuTest * tc)
#if 0
void T_estRaft_follower_resends_command_if_request_from_leader_timesout(CuTest * tc)
{
void *r, *peer;
msg_appendentries_t ae;
/* appendentry */
memset(&ae,0,sizeof(msg_appendentries_t));
r = raft_new();
/* three nodes */
peer = raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2);
raft_set_state(r,RAFT_STATE_FOLLOWER);
/* log size s */
CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_appendentries(r,peer,&ae);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
}
#endif
void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * tc)
{
......
......@@ -14,46 +14,128 @@ void TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries(CuTest *
{
void *r;
void *sender;
void *msg;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_requestvote_response_t vr;
memset(&vr,0,sizeof(msg_requestvote_response_t));
vr.term = 1;
vr.voteGranted = 1;
msg_appendentries_t* ae;
sender = sender_new();
r = raft_new();
raft_set_external_functions(r,&funcs,sender);
/* three nodes */
raft_add_peer(r,(void*)1);
raft_add_peer(r,(void*)2);
raft_set_external_functions(r,&funcs,sender);
raft_set_current_term(r,1);
/* candidate to leader */
raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_become_leader(r);
/* receive appendentries messages for both peers */
ae = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != ae);
ae = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != ae);
}
/* 5.2 */
void TestRaft_leader_responds_to_command_msg_when_command_is_committed(CuTest * tc)
{
void *r, *peer, *sender;
msg_command_response_t *cr;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
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);
/* I am the leader */
raft_set_state(r,RAFT_STATE_LEADER);
CuAssertTrue(tc, 0 == raft_get_log_count(r));
/* command message */
msg_command_t cmd;
cmd.id = 1;
cmd.data = "command";
cmd.len = strlen("command");
/* receive command */
raft_recv_command(r,peer,&cmd);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
/* trigger response through commit */
raft_commit_command(r, 1);
/* leader sent response to command message */
cr = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != cr);
}
/* 5.3 */
void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t* ae;
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);
/* i'm leader */
raft_set_state(r,RAFT_STATE_LEADER);
/* receive appendentries messages */
raft_send_appendentries(r,peer);
ae = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != ae);
}
/* 5.3 */
void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsistency(CuTest * tc)
{
void *r, *peer;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_t* ae;
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);
/* i'm leader */
raft_set_state(r,RAFT_STATE_LEADER);
/* receive appendentries messages */
raft_send_appendentries(r,peer);
ae = sender_poll_msg(sender);
CuAssertTrue(tc, NULL != ae);
}
/*
......@@ -103,7 +185,43 @@ void TestRaft_leader_doesnt_append_command_if_unique_id_is_duplicate(CuTest * tc
void TestRaft_leader_increase_commitno_when_majority_have_entry_and_atleast_one_newer_entry(CuTest * tc)
{
void *p1, *p2;
void *r;
void *sender;
raft_external_functions_t funcs = {
.send = sender_send,
.log = NULL
};
msg_appendentries_response_t aer;
sender = sender_new();
r = raft_new();
/* 3 nodes */
p1 = raft_add_peer(r,(void*)1);
p2 = raft_add_peer(r,(void*)2);
/* I'm the leader */
raft_set_state(r,RAFT_STATE_LEADER);
/* the commit index will became 5 */
raft_set_current_term(r,5);
raft_set_current_index(r,5);
raft_set_commit_index(r,4);
raft_set_external_functions(r,&funcs,sender);
raft_send_appendentries(r, p1);
raft_send_appendentries(r, p2);
/* respond that we have the appendentries */
memset(&aer,0,sizeof(msg_appendentries_response_t));
aer.term = 5;
aer.success = 1;
/* announce to leader that the majority have appended this log */
raft_recv_appendentries_response(r,p1,&aer);
raft_recv_appendentries_response(r,p2,&aer);
CuAssertTrue(tc, 5 == raft_get_commit_index(r));
}
void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(CuTest * tc)
......
#include <stdbool.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include "CuTest.h"
#include "raft.h"
void TestRaft_peer_set_nextIdx(CuTest * tc)
{
void *p;
p = raft_peer_new();
raft_peer_set_next_index(p,3);
CuAssertTrue(tc, 3 == raft_peer_get_next_index(p));
}
......@@ -84,6 +84,14 @@ void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc)
CuAssertTrue(tc, 1000 == raft_get_election_timeout(r));
}
void TestRaft_server_starts_with_request_timeout_of_500ms(CuTest * tc)
{
void *r;
r = raft_new();
CuAssertTrue(tc, 500 == raft_get_election_timeout(r));
}
void TestRaft_server_increases_logindex_when_command_appended(CuTest* tc)
{
void *r;
......@@ -93,3 +101,17 @@ void TestRaft_server_increases_logindex_when_command_appended(CuTest* tc)
raft_append_command(r,"aaa", 3);
CuAssertTrue(tc, 1 == raft_get_current_index(r));
}
// If commitIndex > lastApplied: increment lastApplied, apply
// log[lastApplied] to state machine (5.3)
void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitIndex(CuTest* tc)
{
void *r;
r = raft_new();
raft_set_commit_index(r,5);
raft_set_lastapplied_index(r, 4);
raft_periodic(r,1);
CuAssertTrue(tc, 5 == raft_get_lastapplied_index(r));
}
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