Commit 9556f4ee authored by willem's avatar willem
Browse files

term defaults to 0 test case

parent c36ad399
...@@ -151,12 +151,15 @@ typedef struct { ...@@ -151,12 +151,15 @@ typedef struct {
/* length of entry data */ /* length of entry data */
unsigned int len; unsigned int len;
/* number of nodes that have this entry */ /* number of nodes that have this entry */
unsigned int nnodes; unsigned int num_nodes;
} raft_entry_t; } raft_entry_t;
/** /**
* Initialise a new raft server * Initialise a new raft server
* Election timeout defaults to 1000 milliseconds */ *
* Request timeout defaults to 200 milliseconds
* Election timeout defaults to 1000 milliseconds
* @return newly initialised raft server */
raft_server_t* raft_new(); raft_server_t* raft_new();
/** /**
......
...@@ -96,7 +96,7 @@ int log_append_entry(log_t* me_, raft_entry_t* c) ...@@ -96,7 +96,7 @@ int log_append_entry(log_t* me_, raft_entry_t* c)
// return 0; // return 0;
memcpy(&me->entries[me->back],c,sizeof(raft_entry_t)); memcpy(&me->entries[me->back],c,sizeof(raft_entry_t));
me->entries[me->back].nnodes = 0; me->entries[me->back].num_nodes = 0;
me->count++; me->count++;
me->back++; me->back++;
return 1; return 1;
...@@ -216,7 +216,7 @@ void log_mark_node_has_committed(log_t* me_, int idx) ...@@ -216,7 +216,7 @@ void log_mark_node_has_committed(log_t* me_, int idx)
if ((e = log_get_from_idx(me_,idx))) if ((e = log_get_from_idx(me_,idx)))
{ {
e->nnodes += 1; e->num_nodes += 1;
} }
} }
...@@ -22,32 +22,6 @@ ...@@ -22,32 +22,6 @@
#include "raft_private.h" #include "raft_private.h"
#include "raft_log.h" #include "raft_log.h"
typedef struct {
/* Array: For each server, index of the next log entry to send to
* that server (initialized to leader last log index +1) */
int next_index;
/* Array: for each server, index of highest log entry known to be
* replicated on server (initialized to 0, increases monotonically) */
int match_index;
/* The latest entry that each follower has acknowledged is the same as
* the leader's. This is used to calculate commitIndex on the leader. */
int last_agree_index;
} leader_t;
typedef struct {
/* The set of servers from which the candidate has
* received a RequestVote response in this term. */
int votes_responded;
/* The set of servers from which the candidate has received a vote in this
* term. */
int votes_granted;
} candidate_t;
typedef struct { typedef struct {
/* Persistent state: */ /* Persistent state: */
...@@ -79,11 +53,11 @@ typedef struct { ...@@ -79,11 +53,11 @@ typedef struct {
/* amount of time left till timeout */ /* amount of time left till timeout */
int timeout_elapsed; int timeout_elapsed;
/* who has voted for me. This is an array with N = 'nnodes' elements */ /* who has voted for me. This is an array with N = 'num_nodes' elements */
int *votes_for_me; int *votes_for_me;
raft_node_t* nodes; raft_node_t* nodes;
int nnodes; int num_nodes;
int election_timeout; int election_timeout;
int request_timeout; int request_timeout;
...@@ -95,11 +69,6 @@ typedef struct { ...@@ -95,11 +69,6 @@ typedef struct {
/* my node ID */ /* my node ID */
int nodeid; int nodeid;
union {
leader_t leader;
candidate_t candidate;
};
} raft_server_private_t; } raft_server_private_t;
static void __log(raft_server_t *me_, void *src, const char *fmt, ...) static void __log(raft_server_t *me_, void *src, const char *fmt, ...)
...@@ -121,14 +90,14 @@ raft_server_t* raft_new() ...@@ -121,14 +90,14 @@ raft_server_t* raft_new()
if (!(me = calloc(1, sizeof(raft_server_private_t)))) if (!(me = calloc(1, sizeof(raft_server_private_t))))
return NULL; return NULL;
me->current_term = 1; me->current_term = 0;
me->voted_for = -1; me->voted_for = -1;
me->current_idx = 1; me->current_idx = 1;
me->timeout_elapsed = 0; me->timeout_elapsed = 0;
me->log = log_new();
raft_set_state((void*)me, RAFT_STATE_FOLLOWER);
me->request_timeout = 200; me->request_timeout = 200;
me->election_timeout = 1000; me->election_timeout = 1000;
me->log = log_new();
raft_set_state((void*)me, RAFT_STATE_FOLLOWER);
return (void*)me; return (void*)me;
} }
...@@ -166,7 +135,7 @@ void raft_become_leader(raft_server_t* me_) ...@@ -166,7 +135,7 @@ void raft_become_leader(raft_server_t* me_)
__log(me_, NULL, "becoming leader"); __log(me_, NULL, "becoming leader");
raft_set_state(me_,RAFT_STATE_LEADER); raft_set_state(me_,RAFT_STATE_LEADER);
me->voted_for = -1; me->voted_for = -1;
for (i=0; i<me->nnodes; i++) for (i=0; i<me->num_nodes; i++)
{ {
if (me->nodeid == i) continue; if (me->nodeid == i) continue;
raft_node_t* p = raft_get_node(me_, i); raft_node_t* p = raft_get_node(me_, i);
...@@ -181,13 +150,13 @@ void raft_become_candidate(raft_server_t* me_) ...@@ -181,13 +150,13 @@ void raft_become_candidate(raft_server_t* me_)
int i; int i;
__log(me_, NULL, "becoming candidate"); __log(me_, NULL, "becoming candidate");
memset(me->votes_for_me, 0, sizeof(int) * me->nnodes); memset(me->votes_for_me, 0, sizeof(int) * me->num_nodes);
me->current_term += 1; me->current_term += 1;
raft_vote(me_, me->nodeid); raft_vote(me_, me->nodeid);
raft_set_state(me_, RAFT_STATE_CANDIDATE); raft_set_state(me_, RAFT_STATE_CANDIDATE);
me->timeout_elapsed = rand() % 500; me->timeout_elapsed = rand() % 500;
/* request votes from nodes */ /* request votes from nodes */
for (i=0; i<me->nnodes; i++) for (i=0; i<me->num_nodes; i++)
{ {
if (me->nodeid == i) continue; if (me->nodeid == i) continue;
raft_send_requestvote(me_, i); raft_send_requestvote(me_, i);
...@@ -271,7 +240,7 @@ int raft_recv_appendentries_response(raft_server_t* me_, ...@@ -271,7 +240,7 @@ int raft_recv_appendentries_response(raft_server_t* me_,
e = log_get_from_idx(me->log, me->last_applied_idx + 1); e = log_get_from_idx(me->log, me->last_applied_idx + 1);
/* majority has this */ /* majority has this */
if (e && me->nnodes / 2 <= e->nnodes) if (e && me->num_nodes / 2 <= e->num_nodes)
{ {
if (0 == raft_apply_entry(me_)) break; if (0 == raft_apply_entry(me_)) break;
} }
...@@ -455,13 +424,13 @@ int raft_recv_requestvote(raft_server_t* me_, int node, msg_requestvote_t* vr) ...@@ -455,13 +424,13 @@ int raft_recv_requestvote(raft_server_t* me_, int node, msg_requestvote_t* vr)
return 0; return 0;
} }
int raft_votes_is_majority(const int nnodes, const int nvotes) int raft_votes_is_majority(const int num_nodes, const int nvotes)
{ {
int half; int half;
if (nnodes < nvotes) if (num_nodes < nvotes)
return 0; return 0;
half = nnodes / 2; half = num_nodes / 2;
return half + 1 <= nvotes; return half + 1 <= nvotes;
} }
...@@ -476,7 +445,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node, ...@@ -476,7 +445,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node,
if (raft_is_leader(me_)) if (raft_is_leader(me_))
return 0; return 0;
assert(node < me->nnodes); assert(node < me->num_nodes);
// if (r->term != raft_get_current_term(me_)) // if (r->term != raft_get_current_term(me_))
// return 0; // return 0;
...@@ -487,7 +456,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node, ...@@ -487,7 +456,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node,
me->votes_for_me[node] = 1; me->votes_for_me[node] = 1;
votes = raft_get_nvotes_for_me(me_); votes = raft_get_nvotes_for_me(me_);
if (raft_votes_is_majority(me->nnodes, votes)) if (raft_votes_is_majority(me->num_nodes, votes))
raft_become_leader(me_); raft_become_leader(me_);
} }
...@@ -524,7 +493,7 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* e) ...@@ -524,7 +493,7 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* e)
ety.len = e->len; ety.len = e->len;
res = raft_append_entry(me_, &ety); res = raft_append_entry(me_, &ety);
raft_send_entry_response(me_, node, e->id, res); raft_send_entry_response(me_, node, e->id, res);
for (i=0; i<me->nnodes; i++) for (i=0; i<me->num_nodes; i++)
{ {
if (me->nodeid == i) continue; if (me->nodeid == i) continue;
raft_send_appendentries(me_,i); raft_send_appendentries(me_,i);
...@@ -604,7 +573,7 @@ void raft_send_appendentries_all(raft_server_t* me_) ...@@ -604,7 +573,7 @@ void raft_send_appendentries_all(raft_server_t* me_)
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int i; int i;
for (i=0; i<me->nnodes; i++) for (i=0; i<me->num_nodes; i++)
{ {
if (me->nodeid == i) continue; if (me->nodeid == i) continue;
raft_send_appendentries(me_, i); raft_send_appendentries(me_, i);
...@@ -615,17 +584,17 @@ void raft_set_configuration(raft_server_t* me_, ...@@ -615,17 +584,17 @@ void raft_set_configuration(raft_server_t* me_,
raft_node_configuration_t* nodes, int my_idx) raft_node_configuration_t* nodes, int my_idx)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int nnodes; int num_nodes;
/* TODO: one memory allocation only please */ /* TODO: one memory allocation only please */
for (nnodes=0; nodes->udata_address; nodes++) for (num_nodes=0; nodes->udata_address; nodes++)
{ {
nnodes++; num_nodes++;
me->nodes = realloc(me->nodes,sizeof(raft_node_t*) * nnodes); me->nodes = realloc(me->nodes,sizeof(raft_node_t*) * num_nodes);
me->nnodes = nnodes; me->num_nodes = num_nodes;
me->nodes[nnodes-1] = raft_node_new(nodes->udata_address); me->nodes[num_nodes-1] = raft_node_new(nodes->udata_address);
} }
me->votes_for_me = calloc(nnodes, sizeof(int)); me->votes_for_me = calloc(num_nodes, sizeof(int));
me->nodeid = my_idx; me->nodeid = my_idx;
} }
...@@ -634,7 +603,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_) ...@@ -634,7 +603,7 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int i, votes; int i, votes;
for (i=0, votes=0; i<me->nnodes; i++) for (i=0, votes=0; i<me->num_nodes; i++)
{ {
if (me->nodeid == i) continue; if (me->nodeid == i) continue;
if (1 == me->votes_for_me[i]) if (1 == me->votes_for_me[i])
...@@ -682,14 +651,14 @@ int raft_get_request_timeout(raft_server_t* me_) ...@@ -682,14 +651,14 @@ int raft_get_request_timeout(raft_server_t* me_)
int raft_get_num_nodes(raft_server_t* me_) int raft_get_num_nodes(raft_server_t* me_)
{ {
return ((raft_server_private_t*)me_)->nnodes; return ((raft_server_private_t*)me_)->num_nodes;
} }
raft_node_t* raft_get_node(raft_server_t *me_, int nodeid) raft_node_t* raft_get_node(raft_server_t *me_, int nodeid)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
if (nodeid < 0 || me->nnodes <= nodeid) if (nodeid < 0 || me->num_nodes <= nodeid)
return NULL; return NULL;
return me->nodes[nodeid]; return me->nodes[nodeid];
} }
......
...@@ -68,11 +68,11 @@ void TestLog_mark_node_has_committed_adds_nodes(CuTest * tc) ...@@ -68,11 +68,11 @@ void TestLog_mark_node_has_committed_adds_nodes(CuTest * tc)
l = log_new(); l = log_new();
e1.id = 1; e1.id = 1;
log_append_entry(l, &e1); log_append_entry(l, &e1);
CuAssertTrue(tc, 0 == log_get_from_idx(l,1)->nnodes); CuAssertTrue(tc, 0 == log_get_from_idx(l,1)->num_nodes);
log_mark_node_has_committed(l, 1); log_mark_node_has_committed(l, 1);
CuAssertTrue(tc, 1 == log_get_from_idx(l,1)->nnodes); CuAssertTrue(tc, 1 == log_get_from_idx(l,1)->num_nodes);
log_mark_node_has_committed(l, 1); log_mark_node_has_committed(l, 1);
CuAssertTrue(tc, 2 == log_get_from_idx(l,1)->nnodes); CuAssertTrue(tc, 2 == log_get_from_idx(l,1)->num_nodes);
} }
void TestLog_delete(CuTest * tc) void TestLog_delete(CuTest * tc)
......
...@@ -30,12 +30,19 @@ void TestRaft_server_idx_starts_at_1(CuTest * tc) ...@@ -30,12 +30,19 @@ void TestRaft_server_idx_starts_at_1(CuTest * tc)
CuAssertTrue(tc, 1 == raft_get_current_idx(r)); CuAssertTrue(tc, 1 == raft_get_current_idx(r));
} }
void TestRaft_server_currentterm_defaults_to_0(CuTest * tc)
{
void *r;
r = raft_new();
CuAssertTrue(tc, 0 == raft_get_current_term(r));
}
void TestRaft_server_set_currentterm_sets_term(CuTest * tc) void TestRaft_server_set_currentterm_sets_term(CuTest * tc)
{ {
void *r; void *r;
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 1 == raft_get_current_term(r));
raft_set_current_term(r,5); raft_set_current_term(r,5);
CuAssertTrue(tc, 5 == raft_get_current_term(r)); CuAssertTrue(tc, 5 == raft_get_current_term(r));
} }
...@@ -1155,9 +1162,9 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc) ...@@ -1155,9 +1162,9 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc)
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 2 == raft_get_current_term(r)); CuAssertTrue(tc, 1 == raft_get_current_term(r));
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
......
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