Commit b98eedcb authored by willem's avatar willem
Browse files

Improvewd elections

parent de5373a9
...@@ -121,7 +121,7 @@ CuTest* CuTestNew(const char* name, TestFunction function) ...@@ -121,7 +121,7 @@ CuTest* CuTestNew(const char* name, TestFunction function)
void CuTestRun(CuTest* tc) void CuTestRun(CuTest* tc)
{ {
#if 0 /* debugging */ #if 1 /* debugging */
printf(" running %s\n", tc->name); printf(" running %s\n", tc->name);
#endif #endif
jmp_buf buf; jmp_buf buf;
......
...@@ -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_log.c raft_peer.c test_server.c test_server_request_vote.c test_peer.c test_log.c mock_send_functions.c CuTest.c $(LLQUEUE_DIR)/linked_list_queue.c tests_main: main_test.c raft_server.c raft_log.c raft_node.c test_server.c test_server_request_vote.c test_node.c test_log.c test_scenario.c mock_send_functions.c CuTest.c $(LLQUEUE_DIR)/linked_list_queue.c
$(CC) $(CCFLAGS) -o $@ $^ $(CC) $(CCFLAGS) -o $@ $^
./tests_main ./tests_main
......
...@@ -17,33 +17,114 @@ ...@@ -17,33 +17,114 @@
#include "raft.h" #include "raft.h"
typedef struct { typedef struct {
void* outbox;
void* inbox; void* inbox;
void* raft;
} sender_t; } sender_t;
int sender_send(void* caller, void* udata, int peer, const unsigned char* data, int len) typedef struct {
void* data;
int len;
/* what type of message is it? */
int type;
/* who sent this? */
int sender;
} msg_t;
static sender_t** __senders = NULL;
static int __nsenders = 0;
void senders_new()
{
__senders = NULL;
__nsenders = 0;
}
int sender_send(void* caller, void* udata, int peer, int type,
const unsigned char* data, int len)
{ {
sender_t* me = caller; sender_t* me = caller;
unsigned char * n; msg_t* m;
m = malloc(sizeof(msg_t));
m->type = type;
m->len = len;
m->data = malloc(len);
m->sender = raft_get_nodeid(udata);
memcpy(m->data,data,len);
llqueue_offer(me->outbox,m);
if (__nsenders > peer)
{
llqueue_offer(__senders[peer]->inbox, m);
}
n = malloc(len);
memcpy(n,data,len);
llqueue_offer(me->inbox,n);
return 0; return 0;
} }
void* sender_new() void* sender_new(void* address)
{ {
sender_t* me; sender_t* me;
me = malloc(sizeof(sender_t)); me = malloc(sizeof(sender_t));
me->outbox = llqueue_new();
me->inbox = llqueue_new(); me->inbox = llqueue_new();
__senders = realloc(__senders,sizeof(sender_t*) * (++__nsenders));
__senders[__nsenders-1] = me;
return me; return me;
} }
void* sender_poll_msg(void* s) void* sender_poll_msg_data(void* s)
{ {
sender_t* me = s; sender_t* me = s;
msg_t* msg;
msg = llqueue_poll(me->outbox);
return NULL != msg ? msg->data : NULL;
}
void sender_set_raft(void* s, void* r)
{
sender_t* me = s;
me->raft = r;
}
int sender_msgs_available(void* s)
{
sender_t* me = s;
return 0 < llqueue_count(me->inbox);
}
void sender_poll_msgs(void* s)
{
sender_t* me = s;
msg_t* m;
while ((m = llqueue_poll(me->inbox)))
{
switch (m->type)
{
case RAFT_MSG_APPENDENTRIES:
raft_recv_appendentries(me->raft, m->sender, m->data);
break;
case RAFT_MSG_APPENDENTRIES_RESPONSE:
raft_recv_appendentries_response(me->raft, m->sender, m->data);
break;
case RAFT_MSG_REQUESTVOTE:
raft_recv_requestvote(me->raft, m->sender, m->data);
break;
case RAFT_MSG_REQUESTVOTE_RESPONSE:
raft_recv_requestvote_response(me->raft, m->sender, m->data);
break;
case RAFT_MSG_ENTRY:
raft_recv_entry(me->raft, m->sender, m->data);
break;
case RAFT_MSG_ENTRY_RESPONSE:
//raft_recv_entry_response(me->raft, m->sender, m->data);
break;
return llqueue_poll(me->inbox); }
}
} }
int sender_send(void* caller, void* udata, int peer, int sender_send(void* caller, void* udata, int peer, int type,
const unsigned char* data, const int len); const unsigned char* data, const int len);
void* sender_new(); void* sender_new(void* address);
void* sender_poll_msg(void* s); void* sender_poll_msg_data(void* s);
int sender_msgs_available(void* s);
...@@ -7,12 +7,12 @@ enum { ...@@ -7,12 +7,12 @@ enum {
}; };
typedef struct { typedef struct {
/* So that we can tell which peers were removed/added */ /* So that we can tell which nodes were removed/added */
int old_id; int old_id;
/* User data pointer for addressing. /* User data pointer for addressing.
* ie. This is most likely a (IP,Port) tuple */ * ie. This is most likely a (IP,Port) tuple */
void* udata_address; void* udata_address;
} raft_peer_configuration_t; } raft_node_configuration_t;
typedef struct { typedef struct {
/* term candidate's term */ /* term candidate's term */
...@@ -41,8 +41,8 @@ typedef struct { ...@@ -41,8 +41,8 @@ typedef struct {
unsigned int id; unsigned int id;
unsigned char* data; unsigned char* data;
unsigned int len; unsigned int len;
/* number of peers that have this entry */ /* number of nodes that have this entry */
unsigned int npeers; unsigned int nnodes;
} raft_entry_t; } raft_entry_t;
typedef struct { typedef struct {
...@@ -85,12 +85,22 @@ typedef struct { ...@@ -85,12 +85,22 @@ typedef struct {
int first_idx; int first_idx;
} msg_appendentries_response_t; } msg_appendentries_response_t;
enum {
RAFT_MSG_REQUESTVOTE,
RAFT_MSG_REQUESTVOTE_RESPONSE,
RAFT_MSG_APPENDENTRIES,
RAFT_MSG_APPENDENTRIES_RESPONSE,
RAFT_MSG_ENTRY,
RAFT_MSG_ENTRY_RESPONSE,
};
typedef int ( typedef int (
*func_send_f *func_send_f
) ( ) (
void *caller, void *caller,
void *udata, void *udata,
int peer, int node,
int type,
const unsigned char *send_data, const unsigned char *send_data,
const int len const int len
); );
...@@ -120,16 +130,16 @@ typedef struct { ...@@ -120,16 +130,16 @@ typedef struct {
func_send_f send; func_send_f send;
func_log_f log; func_log_f log;
func_applylog_f applylog; func_applylog_f applylog;
} raft_external_functions_t; } raft_cbs_t;
typedef void* raft_server_t; typedef void* raft_server_t;
typedef void* raft_peer_t; typedef void* raft_node_t;
raft_server_t* raft_new(); raft_server_t* raft_new();
int raft_get_voted_for(raft_server_t* me); int raft_get_voted_for(raft_server_t* me);
void raft_set_callbacks(raft_server_t* me, raft_external_functions_t* funcs, void* caller); void raft_set_callbacks(raft_server_t* me, raft_cbs_t* funcs, void* caller);
void raft_election_start(raft_server_t* me); void raft_election_start(raft_server_t* me);
...@@ -141,11 +151,11 @@ int raft_receive_append_entries(raft_server_t* me, msg_appendentries_t* ae); ...@@ -141,11 +151,11 @@ int raft_receive_append_entries(raft_server_t* me, msg_appendentries_t* ae);
int raft_periodic(raft_server_t* me, int msec_since_last_period); int raft_periodic(raft_server_t* me, int msec_since_last_period);
int raft_recv_appendentries(raft_server_t* me, int peer, msg_appendentries_t* ae); int raft_recv_appendentries(raft_server_t* me, int node, msg_appendentries_t* ae);
int raft_recv_requestvote(raft_server_t* me, int peer, msg_requestvote_t* vr); int raft_recv_requestvote(raft_server_t* me, int node, msg_requestvote_t* vr);
int raft_recv_requestvote_response(raft_server_t* me, int peer, msg_requestvote_response_t* r); int raft_recv_requestvote_response(raft_server_t* me, int node, msg_requestvote_response_t* r);
void raft_execute_entry(raft_server_t* me); void raft_execute_entry(raft_server_t* me);
...@@ -153,15 +163,15 @@ void raft_set_election_timeout(raft_server_t* me, int millisec); ...@@ -153,15 +163,15 @@ void raft_set_election_timeout(raft_server_t* me, int millisec);
int raft_get_election_timeout(raft_server_t* me); int raft_get_election_timeout(raft_server_t* me);
int raft_vote(raft_server_t* me, int peer); void raft_vote(raft_server_t* me, int node);
raft_peer_t* raft_add_peer(raft_server_t* me, int peer_udata); raft_node_t* raft_add_node(raft_server_t* me, int node_udata);
int raft_remove_peer(raft_server_t* me, int peer); int raft_remove_node(raft_server_t* me, int node);
int raft_get_num_peers(raft_server_t* me); int raft_get_num_nodes(raft_server_t* me);
int raft_recv_entry(raft_server_t* me, int peer, msg_entry_t* cmd); int raft_recv_entry(raft_server_t* me, int node, msg_entry_t* cmd);
int raft_get_log_count(raft_server_t* me); int raft_get_log_count(raft_server_t* me);
...@@ -181,9 +191,9 @@ int raft_is_leader(raft_server_t* me); ...@@ -181,9 +191,9 @@ int raft_is_leader(raft_server_t* me);
int raft_is_candidate(raft_server_t* me); int raft_is_candidate(raft_server_t* me);
int raft_send_requestvote(raft_server_t* me, int peer); int raft_send_requestvote(raft_server_t* me, int node);
void raft_send_appendentries(raft_server_t* me, int peer); void raft_send_appendentries(raft_server_t* me, int node);
int raft_append_entry(raft_server_t* me_, raft_entry_t* c); int raft_append_entry(raft_server_t* me_, raft_entry_t* c);
...@@ -199,20 +209,23 @@ void raft_set_request_timeout(raft_server_t* me_, int millisec); ...@@ -199,20 +209,23 @@ void raft_set_request_timeout(raft_server_t* me_, int millisec);
int raft_get_last_applied_idx(raft_server_t* me); int raft_get_last_applied_idx(raft_server_t* me);
raft_peer_t* raft_peer_new(void* udata); raft_node_t* raft_node_new(void* udata);
int raft_peer_is_leader(raft_peer_t* peer); int raft_node_is_leader(raft_node_t* node);
int raft_peer_get_next_idx(raft_peer_t* peer); int raft_node_get_next_idx(raft_node_t* node);
void raft_peer_set_next_idx(raft_peer_t* peer, int nextIdx); void raft_node_set_next_idx(raft_node_t* node, int nextIdx);
void raft_set_configuration(raft_server_t* me_, raft_peer_configuration_t* peers); void raft_set_configuration(raft_server_t* me_,
raft_node_configuration_t* nodes, int me_idx);
int raft_votes_is_majority(const int npeers, const int nvotes); int raft_votes_is_majority(const int nnodes, const int nvotes);
int raft_apply_entry(raft_server_t* me_); int raft_apply_entry(raft_server_t* me_);
raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int idx); raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int idx);
raft_peer_t* raft_get_peer(raft_server_t *me_, int peerid); raft_node_t* raft_get_node(raft_server_t *me_, int nodeid);
int raft_get_nodeid(raft_server_t* me_);
...@@ -111,7 +111,7 @@ int log_append_entry(log_t* me_, raft_entry_t* c) ...@@ -111,7 +111,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].npeers = 0; me->entries[me->back].nnodes = 0;
me->count++; me->count++;
me->back++; me->back++;
return 1; return 1;
...@@ -224,14 +224,14 @@ void log_free(log_t * me_) ...@@ -224,14 +224,14 @@ void log_free(log_t * me_)
free(me); free(me);
} }
void log_mark_peer_has_committed(log_t* me_, int idx) void log_mark_node_has_committed(log_t* me_, int idx)
{ {
log_private_t* me = (void*)me_; log_private_t* me = (void*)me_;
raft_entry_t* e; raft_entry_t* e;
if ((e = log_get_from_idx(me_,idx))) if ((e = log_get_from_idx(me_,idx)))
{ {
e->npeers += 1; e->nnodes += 1;
} }
} }
/**
* Copyright (c) 2013, Willem-Hendrik Thiart
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
* @file
* @brief Implementation of a Raft server
* @author Willem Thiart himself@willemthiart.com
* @version 0.1
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "raft.h"
typedef struct {
void* udata;
int next_idx;
} raft_node_private_t;
raft_node_t* raft_node_new(void* udata)
{
raft_node_private_t* me;
me = calloc(1,sizeof(raft_node_private_t));
me->udata = udata;
return (void*)me;
}
int raft_node_is_leader(raft_node_t* me_)
{
return 0;
}
int raft_node_get_next_idx(raft_node_t* me_)
{
raft_node_private_t* me = (void*)me_;
return me->next_idx;
}
void raft_node_set_next_idx(raft_node_t* me_, int nextIdx)
{
raft_node_private_t* me = (void*)me_;
me->next_idx = nextIdx;
}
/**
* @file
* @brief
* @author Willem Thiart himself@willemthiart.com
* @version 0.1
*
* @section LICENSE
* Copyright (c) 2011, Willem-Hendrik Thiart
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* The names of its contributors may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL WILLEM-HENDRIK THIART BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "raft.h"
typedef struct {
void* udata;
int next_idx;
} raft_peer_private_t;
raft_peer_t* raft_peer_new(void* udata)
{
raft_peer_private_t* me;
me = calloc(1,sizeof(raft_peer_private_t));
me->udata = udata;
return (void*)me;
}
int raft_peer_is_leader(raft_peer_t* me_)
{
return 0;
}
int raft_peer_get_next_idx(raft_peer_t* me_)
{
raft_peer_private_t* me = (void*)me_;
return me->next_idx;
}
void raft_peer_set_next_idx(raft_peer_t* me_, int nextIdx)
{
raft_peer_private_t* me = (void*)me_;
me->next_idx = nextIdx;
}
...@@ -76,21 +76,23 @@ typedef struct { ...@@ -76,21 +76,23 @@ typedef struct {
int current_idx; int current_idx;
/* amount of time left till timeout */ /* amount of time left till timeout */
int timeout_elapased; int timeout_elapsed;
/* who has voted for me. This is an array with N = 'npeers' elements */ /* who has voted for me. This is an array with N = 'nnodes' elements */
int *votes_for_me; int *votes_for_me;
raft_peer_t* peers; raft_node_t* nodes;
int npeers; int nnodes;
int election_timeout; int election_timeout;
int request_timeout; int request_timeout;
/* callbacks */ /* callbacks */
raft_external_functions_t cb; raft_cbs_t cb;
void* cb_ctx; void* cb_ctx;
int nodeid;
union { union {
leader_t leader; leader_t leader;
candidate_t candidate; candidate_t candidate;
...@@ -106,7 +108,7 @@ static void __log(raft_server_t *me_, void *src, const char *fmt, ...) ...@@ -106,7 +108,7 @@ static void __log(raft_server_t *me_, void *src, const char *fmt, ...)
va_start(args, fmt); va_start(args, fmt);
vsprintf(buf, fmt, args); vsprintf(buf, fmt, args);
//printf("%s\n", buf); printf("%d: %s\n", me->nodeid, buf);
//__FUNC_log(bto,src,buf); //__FUNC_log(bto,src,buf);
} }
...@@ -117,9 +119,10 @@ raft_server_t* raft_new() ...@@ -117,9 +119,10 @@ 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->voted_for = -1; me->voted_for = -1;
me->current_idx = 1; me->current_idx = 1;
me->timeout_elapased = 0; me->timeout_elapsed = 0;
me->log = log_new(); me->log = log_new();
raft_set_state((void*)me,RAFT_STATE_FOLLOWER); raft_set_state((void*)me,RAFT_STATE_FOLLOWER);
raft_set_request_timeout((void*)me, 500); raft_set_request_timeout((void*)me, 500);
...@@ -146,6 +149,11 @@ void raft_set_request_timeout(raft_server_t* me_, int millisec) ...@@ -146,6 +149,11 @@ void raft_set_request_timeout(raft_server_t* me_, int millisec)
me->request_timeout = millisec; me->request_timeout = millisec;
} }
int raft_get_nodeid(raft_server_t* me_)
{
return ((raft_server_private_t*)me_)->nodeid;
}
int raft_get_election_timeout(raft_server_t* me_) int raft_get_election_timeout(raft_server_t* me_)
{ {
return ((raft_server_private_t*)me_)->election_timeout; return ((raft_server_private_t*)me_)->election_timeout;
...@@ -156,14 +164,15 @@ int raft_get_request_timeout(raft_server_t* me_) ...@@ -156,14 +164,15 @@ int raft_get_request_timeout(raft_server_t* me_)
return ((raft_server_private_t*)me_)->request_timeout; return ((raft_server_private_t*)me_)->request_timeout;
} }
int raft_vote(raft_server_t* me_, int peer) void raft_vote(raft_server_t* me_, int node)
{ {
return 0; raft_server_private_t* me = (void*)me_;
me->voted_for = node;
} }
int raft_get_num_peers(raft_server_t* me_) int raft_get_num_nodes(raft_server_t* me_)
{ {
return ((raft_server_private_t*)me_)->npeers; return ((raft_server_private_t*)me_)->nnodes;
} }
void raft_set_state(raft_server_t* me_, int state) void raft_set_state(raft_server_t* me_, int state)
...@@ -177,25 +186,25 @@ int raft_get_state(raft_server_t* me_) ...@@ -177,25 +186,25 @@ int raft_get_state(raft_server_t* me_)
return ((raft_server_private_t*)me_)->state; return ((raft_server_private_t*)me_)->state;
} }
raft_peer_t* raft_get_peer(raft_server_t *me_, int peerid) 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 (peerid < 0 || me->npeers <= peerid) if (nodeid < 0 || me->nnodes <= nodeid)
return NULL; return NULL;
return me->peers[peerid]; return me->nodes[nodeid];
} }
/** /**
* @return number of peers that this server has */ * @return number of nodes that this server has */
int raft_get_npeers(raft_server_t* me_) int raft_get_nnodes(raft_server_t* me_)
{ {
return ((raft_server_private_t*)me_)->npeers; return ((raft_server_private_t*)me_)->nnodes;
} }
int raft_get_timeout_elapsed(raft_server_t* me_) int raft_get_timeout_elapsed(raft_server_t* me_)
{ {
return ((raft_server_private_t*)me_)->timeout_elapased; return ((raft_server_private_t*)me_)->timeout_elapsed;
} }
/** /**
...@@ -250,8 +259,7 @@ int raft_is_candidate(raft_server_t* me_) ...@@ -250,8 +259,7 @@ int raft_is_candidate(raft_server_t* me_)
int raft_get_my_id(raft_server_t* me_) int raft_get_my_id(raft_server_t* me_)
{ {
// TODO return ((raft_server_private_t*)me_)->nodeid;
return 0;
} }
void raft_set_commit_idx(raft_server_t* me_, int idx) void raft_set_commit_idx(raft_server_t* me_, int idx)
...@@ -277,11 +285,11 @@ int raft_get_commit_idx(raft_server_t* me_) ...@@ -277,11 +285,11 @@ int raft_get_commit_idx(raft_server_t* me_)
} }
void raft_set_callbacks(raft_server_t* me_, void raft_set_callbacks(raft_server_t* me_,
raft_external_functions_t* funcs, void* cb_ctx) raft_cbs_t* funcs, void* cb_ctx)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
memcpy(&me->cb, funcs, sizeof(raft_external_functions_t)); memcpy(&me->cb, funcs, sizeof(raft_cbs_t));
me->cb_ctx = cb_ctx; me->cb_ctx = cb_ctx;
} }
...@@ -289,8 +297,9 @@ void raft_election_start(raft_server_t* me_) ...@@ -289,8 +297,9 @@ void raft_election_start(raft_server_t* me_)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
// TODO: randomise timeout __log(me_, NULL, "election starting: %d %d, term: %d",
me->timeout_elapased = 0; me->election_timeout, me->timeout_elapsed, me->current_term);
/* time to throw our hat in */ /* time to throw our hat in */
raft_become_candidate(me_); raft_become_candidate(me_);
} }
...@@ -300,12 +309,14 @@ void raft_become_leader(raft_server_t* me_) ...@@ -300,12 +309,14 @@ void raft_become_leader(raft_server_t* me_)
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int i; int i;
__log(me_, NULL, "becoming leader");
raft_set_state(me_,RAFT_STATE_LEADER); raft_set_state(me_,RAFT_STATE_LEADER);
me->voted_for = -1;
for (i=0; i<me->npeers; i++) for (i=0; i<me->nnodes; i++)
{ {
raft_peer_t* p = raft_get_peer(me_, i); if (me->nodeid == i) continue;
raft_peer_set_next_idx(p, raft_get_current_idx(me_)+1); raft_node_t* p = raft_get_node(me_, i);
raft_node_set_next_idx(p, raft_get_current_idx(me_)+1);
raft_send_appendentries(me_, i); raft_send_appendentries(me_, i);
} }
} }
...@@ -315,28 +326,27 @@ void raft_become_candidate(raft_server_t* me_) ...@@ -315,28 +326,27 @@ void raft_become_candidate(raft_server_t* me_)
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int i; int i;
memset(me->votes_for_me,0,sizeof(int) * me->npeers); __log(me_, NULL, "becoming candidate");
memset(me->votes_for_me, 0, sizeof(int) * me->nnodes);
me->current_term += 1; me->current_term += 1;
me->voted_for = 0; raft_vote(me_, me->nodeid);
me->timeout_elapased = 0; raft_set_state(me_, RAFT_STATE_CANDIDATE);
raft_set_state(me_,RAFT_STATE_CANDIDATE); me->timeout_elapsed = rand() % 500;
/* request votes from nodes */
/* request votes from peers */ for (i=0; i<me->nnodes; i++)
for (i=0; i<me->npeers; i++)
{ {
msg_requestvote_t rv; if (me->nodeid == i) continue;
raft_send_requestvote(me_, i);
rv.term = me->current_term;
rv.candidate_id = 0;//me->current_term;
// rv.last_log_idx = me->log
if (me->cb.send)
me->cb.send(me->cb_ctx,NULL, i, (void*)&rv, sizeof(msg_requestvote_t));
} }
} }
void raft_become_follower(raft_server_t* me_) void raft_become_follower(raft_server_t* me_)
{ {
raft_set_state(me_,RAFT_STATE_FOLLOWER); raft_server_private_t* me = (void*)me_;
__log(me_, NULL, "becoming follower");
raft_set_state(me_, RAFT_STATE_FOLLOWER);
me->voted_for = -1;
} }
/** /**
...@@ -356,9 +366,14 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period) ...@@ -356,9 +366,14 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
break; break;
} }
me->timeout_elapased += msec_since_last_period; if (me->state != RAFT_STATE_LEADER)
if (me->election_timeout < me->timeout_elapased) {
me->timeout_elapsed += msec_since_last_period;
if (me->election_timeout <= me->timeout_elapsed)
{
raft_election_start(me_); raft_election_start(me_);
}
}
return 1; return 1;
} }
...@@ -372,19 +387,21 @@ raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int etyidx) ...@@ -372,19 +387,21 @@ raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int etyidx)
/** /**
* @return 0 on error */ * @return 0 on error */
int raft_recv_appendentries_response(raft_server_t* me_, int raft_recv_appendentries_response(raft_server_t* me_,
int peer, msg_appendentries_response_t* aer) int node, msg_appendentries_response_t* aer)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
raft_peer_t* p; raft_node_t* p;
__log(me_, NULL, "received appendentries response from: %d", node);
p = raft_get_peer(me_, peer); p = raft_get_node(me_, node);
if (1 == aer->success) if (1 == aer->success)
{ {
int i; int i;
for (i=aer->first_idx; i<=aer->current_idx; i++) for (i=aer->first_idx; i<=aer->current_idx; i++)
log_mark_peer_has_committed(me->log, i); log_mark_node_has_committed(me->log, i);
while (1) while (1)
{ {
...@@ -393,7 +410,7 @@ int raft_recv_appendentries_response(raft_server_t* me_, ...@@ -393,7 +410,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->npeers / 2 <= e->npeers) if (e && me->nnodes / 2 <= e->nnodes)
{ {
if (0 == raft_apply_entry(me_)) break; if (0 == raft_apply_entry(me_)) break;
} }
...@@ -407,11 +424,11 @@ int raft_recv_appendentries_response(raft_server_t* me_, ...@@ -407,11 +424,11 @@ int raft_recv_appendentries_response(raft_server_t* me_,
{ {
/* If AppendEntries fails because of log inconsistency: /* If AppendEntries fails because of log inconsistency:
decrement nextIndex and retry (5.3) */ decrement nextIndex and retry (5.3) */
assert(0 <= raft_peer_get_next_idx(p)); assert(0 <= raft_node_get_next_idx(p));
// TODO does this have test coverage? // TODO does this have test coverage?
// TODO can jump back to where peer is different instead of iterating // TODO can jump back to where node is different instead of iterating
raft_peer_set_next_idx(p, raft_peer_get_next_idx(p)-1); raft_node_set_next_idx(p, raft_node_get_next_idx(p)-1);
raft_send_appendentries(me_, peer); raft_send_appendentries(me_, node);
} }
return 1; return 1;
...@@ -421,12 +438,16 @@ int raft_recv_appendentries_response(raft_server_t* me_, ...@@ -421,12 +438,16 @@ int raft_recv_appendentries_response(raft_server_t* me_,
* @return 0 on error */ * @return 0 on error */
int raft_recv_appendentries( int raft_recv_appendentries(
raft_server_t* me_, raft_server_t* me_,
const int peer, const int node,
msg_appendentries_t* ae) msg_appendentries_t* ae)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
msg_appendentries_response_t r; msg_appendentries_response_t r;
me->timeout_elapsed = 0;
__log(me_, NULL, "received appendentries from: %d", node);
r.term = me->current_term; r.term = me->current_term;
/* we've found a leader who is legitimate */ /* we've found a leader who is legitimate */
...@@ -516,11 +537,11 @@ int raft_recv_appendentries( ...@@ -516,11 +537,11 @@ int raft_recv_appendentries(
/* TODO: replace malloc with mempoll/arena */ /* TODO: replace malloc with mempoll/arena */
c = malloc(sizeof(raft_entry_t)); c = malloc(sizeof(raft_entry_t));
c->term = raft_get_current_term(me_); c->term = me->current_term;
c->len = cmd->len; c->len = cmd->len;
c->id = cmd->id; c->id = cmd->id;
c->data = malloc(cmd->len); c->data = malloc(cmd->len);
memcpy(c->data,cmd->data,cmd->len); memcpy(c->data, cmd->data, cmd->len);
if (0 == raft_append_entry(me_, c)) if (0 == raft_append_entry(me_, c))
{ {
__log(me_, NULL, "AE failure; couldn't append entry"); __log(me_, NULL, "AE failure; couldn't append entry");
...@@ -535,67 +556,81 @@ int raft_recv_appendentries( ...@@ -535,67 +556,81 @@ int raft_recv_appendentries(
done: done:
if (me->cb.send) if (me->cb.send)
me->cb.send(me->cb_ctx, NULL, peer, (void*)&r, me->cb.send(me->cb_ctx, me, node, RAFT_MSG_APPENDENTRIES_RESPONSE,
sizeof(msg_appendentries_response_t)); (void*)&r, sizeof(msg_appendentries_response_t));
return 1; return 1;
} }
int raft_recv_requestvote(raft_server_t* me_, int peer, msg_requestvote_t* vr) int raft_recv_requestvote(raft_server_t* me_, int node, msg_requestvote_t* vr)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
msg_requestvote_response_t r; msg_requestvote_response_t r;
if (vr->term < raft_get_current_term(me_)) if (raft_get_current_term(me_) < vr->term)
{ {
r.vote_granted = 0; me->voted_for = -1;
} }
/* TODO: what's this for? */
else if (-1 == me->voted_for) if (vr->term < raft_get_current_term(me_) ||
/* we've already voted */
-1 != me->voted_for ||
/* we have a more up-to-date log */
vr->last_log_idx < me->current_idx)
{ {
r.vote_granted = 0; r.vote_granted = 0;
} }
else else
{ {
me->voted_for = peer; raft_vote(me_,node);
r.vote_granted = 1; r.vote_granted = 1;
} }
__log(me_, NULL, "node requested vote: %d replying: %s",
node, r.vote_granted == 1 ? "granted" : "not granted");
r.term = raft_get_current_term(me_); r.term = raft_get_current_term(me_);
if (me->cb.send) if (me->cb.send)
me->cb.send(me->cb_ctx, NULL, peer, (void*)&r, me->cb.send(me->cb_ctx, me, node, RAFT_MSG_REQUESTVOTE_RESPONSE,
sizeof(msg_requestvote_response_t)); (void*)&r, sizeof(msg_requestvote_response_t));
return 0; return 0;
} }
int raft_votes_is_majority(const int npeers, const int nvotes) int raft_votes_is_majority(const int nnodes, const int nvotes)
{ {
int half; int half;
if (npeers < nvotes) if (nnodes < nvotes)
return 0; return 0;
half = npeers / 2; half = nnodes / 2;
return half + 1 <= nvotes; return half + 1 <= nvotes;
} }
/** /**
* @param peer The peer this response was sent by */ * @param node The node this response was sent by */
int raft_recv_requestvote_response(raft_server_t* me_, int peer, msg_requestvote_response_t* r) int raft_recv_requestvote_response(raft_server_t* me_, int node,
msg_requestvote_response_t* r)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
assert(peer < me->npeers); __log(me_, NULL, "node responded to requestvote: %d status: %s",
node, r->vote_granted == 1 ? "granted" : "not granted");
if (r->term != raft_get_current_term(me_)) if (raft_is_leader(me_))
return 0; return 0;
assert(node < me->nnodes);
// if (r->term != raft_get_current_term(me_))
// return 0;
if (1 == r->vote_granted) if (1 == r->vote_granted)
{ {
int votes; int votes;
me->votes_for_me[peer] = 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->npeers, votes)) if (raft_votes_is_majority(me->nnodes, votes))
raft_become_leader(me_); raft_become_leader(me_);
} }
...@@ -603,15 +638,17 @@ int raft_recv_requestvote_response(raft_server_t* me_, int peer, msg_requestvote ...@@ -603,15 +638,17 @@ int raft_recv_requestvote_response(raft_server_t* me_, int peer, msg_requestvote
} }
int raft_send_entry_response(raft_server_t* me_, int raft_send_entry_response(raft_server_t* me_,
int peerid, int etyid, int was_committed) int node, int etyid, int was_committed)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
msg_entry_response_t res; msg_entry_response_t res;
__log(me_, NULL, "send entry response to: %d", node);
res.id = etyid; res.id = etyid;
res.was_committed = was_committed; res.was_committed = was_committed;
if (me->cb.send) if (me->cb.send)
me->cb.send(me->cb_ctx, NULL, peerid, me->cb.send(me->cb_ctx, me, node, RAFT_MSG_ENTRY_RESPONSE,
(void*)&res, sizeof(msg_entry_response_t)); (void*)&res, sizeof(msg_entry_response_t));
return 0; return 0;
} }
...@@ -620,34 +657,42 @@ int raft_send_entry_response(raft_server_t* me_, ...@@ -620,34 +657,42 @@ int raft_send_entry_response(raft_server_t* me_,
* Receive an ENTRY message. * Receive an ENTRY message.
* Append entry to log * Append entry to log
* Send APPENDENTRIES to followers */ * Send APPENDENTRIES to followers */
int raft_recv_entry(raft_server_t* me_, int peer, msg_entry_t* cmd) int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* cmd)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
raft_entry_t ety; raft_entry_t ety;
int res, i; int res, i;
ety.term = raft_get_current_term(me_); __log(me_, NULL, "received entry from: %d", node);
ety.term = me->current_term;
ety.id = cmd->id; ety.id = cmd->id;
ety.data = cmd->data; ety.data = cmd->data;
ety.len = cmd->len; ety.len = cmd->len;
res = raft_append_entry(me_, &ety); res = raft_append_entry(me_, &ety);
raft_send_entry_response(me_, peer, cmd->id, res); raft_send_entry_response(me_, node, cmd->id, res);
for (i=0; i<me->npeers; i++) for (i=0; i<me->nnodes; i++)
{
if (me->nodeid == i) continue;
raft_send_appendentries(me_,i); raft_send_appendentries(me_,i);
}
return 0; return 0;
} }
/** /**
* @return 0 on error */ * @return 0 on error */
int raft_send_requestvote(raft_server_t* me_, int peer) int raft_send_requestvote(raft_server_t* me_, int node)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
msg_requestvote_t rv; msg_requestvote_t rv;
rv.term = raft_get_current_term(me_); __log(me_, NULL, "sending requestvote to: %d", node);
rv.term = me->current_term;
rv.last_log_idx = raft_get_current_idx(me_); rv.last_log_idx = raft_get_current_idx(me_);
if (me->cb.send) if (me->cb.send)
me->cb.send(me->cb_ctx,NULL, peer, (void*)&rv, sizeof(msg_requestvote_t)); me->cb.send(me->cb_ctx, me, node, RAFT_MSG_REQUESTVOTE,
(void*)&rv, sizeof(msg_requestvote_t));
return 1; return 1;
} }
...@@ -677,6 +722,8 @@ int raft_apply_entry(raft_server_t* me_) ...@@ -677,6 +722,8 @@ int raft_apply_entry(raft_server_t* me_)
if (!log_get_from_idx(me->log, me->last_applied_idx+1)) if (!log_get_from_idx(me->log, me->last_applied_idx+1))
return 0; return 0;
__log(me_, NULL, "applying log: %d", me->last_applied_idx);
me->last_applied_idx++; me->last_applied_idx++;
if (me->commit_idx < me->last_applied_idx) if (me->commit_idx < me->last_applied_idx)
me->commit_idx = me->last_applied_idx; me->commit_idx = me->last_applied_idx;
...@@ -686,42 +733,48 @@ int raft_apply_entry(raft_server_t* me_) ...@@ -686,42 +733,48 @@ int raft_apply_entry(raft_server_t* me_)
return 1; return 1;
} }
void raft_send_appendentries(raft_server_t* me_, int peer) void raft_send_appendentries(raft_server_t* me_, int node)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
__log(me_, NULL, "sending appendentries to: %d", node);
if (!(me->cb.send)) if (!(me->cb.send))
return; return;
msg_appendentries_t ae; msg_appendentries_t ae;
raft_peer_t* p = raft_get_peer(me_, peer); raft_node_t* p = raft_get_node(me_, node);
ae.term = raft_get_current_term(me_); ae.term = me->current_term;
ae.leader_id = raft_get_my_id(me_); ae.leader_id = raft_get_my_id(me_);
ae.prev_log_term = raft_peer_get_next_idx(p); ae.prev_log_term = raft_node_get_next_idx(p);
// ae.prev_log_idx = // TODO:
me->cb.send(me->cb_ctx, NULL, peer, ae.prev_log_idx = 0;
ae.n_entries = 0;
me->cb.send(me->cb_ctx, me, node, RAFT_MSG_APPENDENTRIES,
(void*)&ae, sizeof(msg_appendentries_t)); (void*)&ae, sizeof(msg_appendentries_t));
} }
/** /**
* Set configuration * Set configuration
* @param peers Array of peers, end of array is marked by NULL entry */ * @param nodes Array of nodes, end of array is marked by NULL entry
* @param me_idx Which node is myself */
void raft_set_configuration(raft_server_t* me_, void raft_set_configuration(raft_server_t* me_,
raft_peer_configuration_t* peers) raft_node_configuration_t* nodes, int me_idx)
{ {
raft_server_private_t* me = (void*)me_; raft_server_private_t* me = (void*)me_;
int npeers; int nnodes;
/* TODO: one memory allocation only please */ /* TODO: one memory allocation only please */
for (npeers=0; peers->udata_address; peers++) for (nnodes=0; nodes->udata_address; nodes++)
{ {
npeers++; nnodes++;
me->peers = realloc(me->peers,sizeof(raft_peer_t*) * npeers); me->nodes = realloc(me->nodes,sizeof(raft_node_t*) * nnodes);
me->npeers = npeers; me->nnodes = nnodes;
me->peers[npeers-1] = raft_peer_new(peers); me->nodes[nnodes-1] = raft_node_new(nodes);
} }
me->votes_for_me = calloc(npeers, sizeof(int)); me->votes_for_me = calloc(nnodes, sizeof(int));
me->nodeid = me_idx;
} }
/** /**
...@@ -731,9 +784,12 @@ int raft_get_nvotes_for_me(raft_server_t* me_) ...@@ -731,9 +784,12 @@ 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->npeers; i++) for (i=0, votes=0; i<me->nnodes; i++)
{
if (me->nodeid == i) continue;
if (1 == me->votes_for_me[i]) if (1 == me->votes_for_me[i])
votes += 1; votes += 1;
}
if (raft_get_voted_for(me_) == raft_get_my_id(me_)) if (raft_get_voted_for(me_) == raft_get_my_id(me_))
votes += 1; votes += 1;
...@@ -741,3 +797,4 @@ int raft_get_nvotes_for_me(raft_server_t* me_) ...@@ -741,3 +797,4 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
return votes; return votes;
} }
/*--------------------------------------------------------------79-characters-*/
...@@ -59,7 +59,7 @@ void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc) ...@@ -59,7 +59,7 @@ void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc)
CuAssertTrue(tc, NULL == log_get_from_idx(l,2)); CuAssertTrue(tc, NULL == log_get_from_idx(l,2));
} }
void TestLog_mark_peer_has_committed_adds_peers(CuTest * tc) void TestLog_mark_node_has_committed_adds_nodes(CuTest * tc)
{ {
void *l; void *l;
raft_entry_t e1, e2, e3; raft_entry_t e1, e2, e3;
...@@ -67,11 +67,11 @@ void TestLog_mark_peer_has_committed_adds_peers(CuTest * tc) ...@@ -67,11 +67,11 @@ void TestLog_mark_peer_has_committed_adds_peers(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)->npeers); CuAssertTrue(tc, 0 == log_get_from_idx(l,1)->nnodes);
log_mark_peer_has_committed(l, 1); log_mark_node_has_committed(l, 1);
CuAssertTrue(tc, 1 == log_get_from_idx(l,1)->npeers); CuAssertTrue(tc, 1 == log_get_from_idx(l,1)->nnodes);
log_mark_peer_has_committed(l, 1); log_mark_node_has_committed(l, 1);
CuAssertTrue(tc, 2 == log_get_from_idx(l,1)->npeers); CuAssertTrue(tc, 2 == log_get_from_idx(l,1)->nnodes);
} }
void TestLog_delete(CuTest * tc) void TestLog_delete(CuTest * tc)
......
...@@ -9,12 +9,12 @@ ...@@ -9,12 +9,12 @@
#include "raft.h" #include "raft.h"
void TestRaft_peer_set_nextIdx(CuTest * tc) void TestRaft_node_set_nextIdx(CuTest * tc)
{ {
raft_peer_t *p; raft_node_t *p;
p = raft_peer_new((void*)1); p = raft_node_new((void*)1);
raft_peer_set_next_idx(p,3); raft_node_set_next_idx(p,3);
CuAssertTrue(tc, 3 == raft_peer_get_next_idx(p)); CuAssertTrue(tc, 3 == raft_node_get_next_idx(p));
} }
...@@ -10,6 +10,9 @@ ...@@ -10,6 +10,9 @@
#include "raft.h" #include "raft.h"
#include "mock_send_functions.h" #include "mock_send_functions.h"
// TODO: appendentries receipt resets elapsed time timeout
// TODO: leader doesn't timeout and cause election
#if 0 #if 0
void T_estRaft_server_voted_for_records_who_we_voted_for(CuTest * tc) void T_estRaft_server_voted_for_records_who_we_voted_for(CuTest * tc)
{ {
...@@ -34,11 +37,22 @@ void TestRaft_server_set_currentterm_sets_term(CuTest * tc) ...@@ -34,11 +37,22 @@ void TestRaft_server_set_currentterm_sets_term(CuTest * tc)
void *r; void *r;
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 0 == raft_get_current_term(r)); 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));
} }
void TestRaft_server_voting_results_in_voting(CuTest * tc)
{
void *r;
r = raft_new();
raft_vote(r,1);
CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_vote(r,9);
CuAssertTrue(tc, 9 == raft_get_voted_for(r));
}
void TestRaft_election_start_increments_term(CuTest * tc) void TestRaft_election_start_increments_term(CuTest * tc)
{ {
void *r; void *r;
...@@ -50,37 +64,37 @@ void TestRaft_election_start_increments_term(CuTest * tc) ...@@ -50,37 +64,37 @@ void TestRaft_election_start_increments_term(CuTest * tc)
} }
#if 0 #if 0
void T_estRaft_add_peer(CuTest * tc) void T_estRaft_add_node(CuTest * tc)
{ {
void *r; void *r;
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 0 == raft_get_num_peers(r)); CuAssertTrue(tc, 0 == raft_get_num_nodes(r));
raft_add_peer(r,(void*)1); raft_add_node(r,(void*)1);
CuAssertTrue(tc, 1 == raft_get_num_peers(r)); CuAssertTrue(tc, 1 == raft_get_num_nodes(r));
} }
void T_estRaft_dont_add_duplicate_peers(CuTest * tc) void T_estRaft_dont_add_duplicate_nodes(CuTest * tc)
{ {
void *r; void *r;
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 0 == raft_get_num_peers(r)); CuAssertTrue(tc, 0 == raft_get_num_nodes(r));
raft_add_peer(r,(void*)1); raft_add_node(r,(void*)1);
CuAssertTrue(tc, NULL == raft_add_peer(r,(void*)1)); CuAssertTrue(tc, NULL == raft_add_node(r,(void*)1));
CuAssertTrue(tc, 1 == raft_get_num_peers(r)); CuAssertTrue(tc, 1 == raft_get_num_nodes(r));
} }
void T_estRaft_remove_peer(CuTest * tc) void T_estRaft_remove_node(CuTest * tc)
{ {
void *r; void *r;
void *peer; void *node;
r = raft_new(); r = raft_new();
peer = raft_add_peer(r,(void*)1); node = raft_add_node(r,(void*)1);
CuAssertTrue(tc, 1 == raft_get_num_peers(r)); CuAssertTrue(tc, 1 == raft_get_num_nodes(r));
raft_remove_peer(r,peer); raft_remove_node(r,node);
CuAssertTrue(tc, 0 == raft_get_num_peers(r)); CuAssertTrue(tc, 0 == raft_get_num_nodes(r));
} }
#endif #endif
...@@ -345,41 +359,42 @@ void TestRaft_server_election_timeout_sets_to_zero_when_elapsed_time_greater_tha ...@@ -345,41 +359,42 @@ void TestRaft_server_election_timeout_sets_to_zero_when_elapsed_time_greater_tha
/* greater than 1000 */ /* greater than 1000 */
raft_periodic(r,2000); raft_periodic(r,2000);
CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r)); /* less than 1000 as the timeout would be randomised */
CuAssertTrue(tc, raft_get_timeout_elapsed(r) < 1000);
} }
void TestRaft_server_cfg_sets_npeers(CuTest * tc) void TestRaft_server_cfg_sets_nnodes(CuTest * tc)
{ {
void *r; void *r;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
CuAssertTrue(tc, 2 == raft_get_npeers(r)); CuAssertTrue(tc, 2 == raft_get_nnodes(r));
} }
void TestRaft_server_cant_get_peer_we_dont_have(CuTest * tc) void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc)
{ {
void *r; void *r;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
CuAssertTrue(tc, NULL != raft_get_peer(r,0)); CuAssertTrue(tc, NULL != raft_get_node(r,0));
CuAssertTrue(tc, NULL != raft_get_peer(r,1)); CuAssertTrue(tc, NULL != raft_get_node(r,1));
CuAssertTrue(tc, NULL == raft_get_peer(r,2)); CuAssertTrue(tc, NULL == raft_get_node(r,2));
} }
/* If term > currentTerm, set currentTerm to term (step down if candidate or leader) */ /* If term > currentTerm, set currentTerm to term (step down if candidate or leader) */
...@@ -411,14 +426,14 @@ void TestRaft_server_dont_increase_votes_for_me_when_receive_request_vote_respon ...@@ -411,14 +426,14 @@ void TestRaft_server_dont_increase_votes_for_me_when_receive_request_vote_respon
void *r; void *r;
msg_requestvote_response_t rvr; msg_requestvote_response_t rvr;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_current_term(r,1); raft_set_current_term(r,1);
CuAssertTrue(tc, 0 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 0 == raft_get_nvotes_for_me(r));
...@@ -436,14 +451,14 @@ void TestRaft_server_increase_votes_for_me_when_receive_request_vote_response( ...@@ -436,14 +451,14 @@ void TestRaft_server_increase_votes_for_me_when_receive_request_vote_response(
void *r; void *r;
msg_requestvote_response_t rvr; msg_requestvote_response_t rvr;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_current_term(r,1); raft_set_current_term(r,1);
CuAssertTrue(tc, 0 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 0 == raft_get_nvotes_for_me(r));
...@@ -461,30 +476,31 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term ...@@ -461,30 +476,31 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_requestvote_t rv; msg_requestvote_t rv;
msg_requestvote_response_t *rvr; msg_requestvote_response_t *rvr;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
sender = sender_new(); sender = sender_new(NULL);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_current_term(r,2);
raft_set_current_term(r,1); /* term is less than current term */
memset(&rv,0,sizeof(msg_requestvote_t)); memset(&rv,0,sizeof(msg_requestvote_t));
rv.term = 2; rv.term = 1;
raft_recv_requestvote(r,1,&rv); raft_recv_requestvote(r,1,&rv);
rvr = sender_poll_msg(sender);
rvr = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rvr); CuAssertTrue(tc, NULL != rvr);
CuAssertTrue(tc, 0 == rvr->vote_granted); CuAssertTrue(tc, 0 == rvr->vote_granted);
} }
...@@ -498,32 +514,35 @@ void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate( ...@@ -498,32 +514,35 @@ void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate(
void *r; void *r;
void *sender; void *sender;
void *msg; void *msg;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_requestvote_t rv; msg_requestvote_t rv;
msg_requestvote_response_t *rvr; msg_requestvote_response_t *rvr;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
memset(&rv,0,sizeof(msg_requestvote_response_t));
rv.term = 1;
sender = sender_new();
sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_current_term(r,1);
raft_vote(r,1); raft_vote(r,0);
memset(&rv,0,sizeof(msg_requestvote_t));
rv.term = 1;
rv.candidate_id = 1;
rv.last_log_idx = 0;
rv.last_log_term = 1;
raft_recv_requestvote(r,1,&rv); raft_recv_requestvote(r,1,&rv);
rvr = sender_poll_msg(sender);
rvr = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rvr); CuAssertTrue(tc, NULL != rvr);
CuAssertTrue(tc, 0 == rvr->vote_granted); CuAssertTrue(tc, 0 == rvr->vote_granted);
} }
...@@ -538,28 +557,39 @@ void TestRaft_follower_becomes_follower_is_follower(CuTest * tc) ...@@ -538,28 +557,39 @@ void TestRaft_follower_becomes_follower_is_follower(CuTest * tc)
CuAssertTrue(tc, raft_is_follower(r)); CuAssertTrue(tc, raft_is_follower(r));
} }
void TestRaft_follower_becomes_follower_clears_voted_for(CuTest * tc)
{
void *r;
r = raft_new();
raft_vote(r,1);
CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_become_follower(r);
CuAssertTrue(tc, -1 == raft_get_voted_for(r));
}
/* 5.1 */ /* 5.1 */
void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentterm(CuTest * tc) void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentterm(CuTest * tc)
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_appendentries_t ae; msg_appendentries_t ae;
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
sender = sender_new(); sender = sender_new(NULL);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
/* term is low */ /* term is low */
...@@ -571,7 +601,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt ...@@ -571,7 +601,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
/* response is false */ /* response is false */
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 0 == aer->success); CuAssertTrue(tc, 0 == aer->success);
} }
...@@ -584,20 +614,20 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current ...@@ -584,20 +614,20 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
msg_appendentries_t ae; msg_appendentries_t ae;
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
sender = sender_new(); sender = sender_new(NULL);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
/* older currentterm */ /* older currentterm */
...@@ -611,7 +641,7 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current ...@@ -611,7 +641,7 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
/* appendentry has newer term, so we change our currentterm */ /* appendentry has newer term, so we change our currentterm */
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
/* term has been updated */ /* term has been updated */
...@@ -624,14 +654,14 @@ void TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified( ...@@ -624,14 +654,14 @@ void TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified(
msg_appendentries_t ae; msg_appendentries_t ae;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_state(r,RAFT_STATE_FOLLOWER); raft_set_state(r,RAFT_STATE_FOLLOWER);
...@@ -659,21 +689,21 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc) ...@@ -659,21 +689,21 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
char *str = "aaa"; char *str = "aaa";
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
sender = sender_new(); sender = sender_new(NULL);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_state(r,RAFT_STATE_FOLLOWER); raft_set_state(r,RAFT_STATE_FOLLOWER);
...@@ -697,7 +727,7 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc) ...@@ -697,7 +727,7 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
...@@ -711,12 +741,12 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev ...@@ -711,12 +741,12 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
void *msg; void *msg;
msg_entry_t ety; msg_entry_t ety;
char *str = "aaa"; char *str = "aaa";
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -724,9 +754,9 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev ...@@ -724,9 +754,9 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
msg_appendentries_t ae; msg_appendentries_t ae;
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
/* term is different from appendentries */ /* term is different from appendentries */
...@@ -751,7 +781,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev ...@@ -751,7 +781,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
/* trigger reply */ /* trigger reply */
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
/* reply is false */ /* reply is false */
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
...@@ -767,20 +797,20 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -767,20 +797,20 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
raft_entry_t *ety_appended; raft_entry_t *ety_appended;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
sender = sender_new(); sender = sender_new(NULL);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_current_term(r,1); raft_set_current_term(r,1);
...@@ -824,7 +854,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -824,7 +854,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
...@@ -836,21 +866,21 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT ...@@ -836,21 +866,21 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
sender = sender_new(); sender = sender_new(NULL);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_current_term(r,1); raft_set_current_term(r,1);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
...@@ -869,7 +899,7 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT ...@@ -869,7 +899,7 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
...@@ -881,20 +911,20 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t ...@@ -881,20 +911,20 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
msg_appendentries_t ae; msg_appendentries_t ae;
...@@ -923,7 +953,7 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t ...@@ -923,7 +953,7 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
/* set to 4 because commitIDX is lower */ /* set to 4 because commitIDX is lower */
...@@ -934,20 +964,20 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest * ...@@ -934,20 +964,20 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest *
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
msg_appendentries_t ae; msg_appendentries_t ae;
...@@ -976,7 +1006,7 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest * ...@@ -976,7 +1006,7 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest *
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
msg_appendentries_response_t *aer; msg_appendentries_response_t *aer;
aer = sender_poll_msg(sender); aer = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != aer); CuAssertTrue(tc, NULL != aer);
CuAssertTrue(tc, 1 == aer->success); CuAssertTrue(tc, 1 == aer->success);
/* set to 3 because leaderCommit is lower */ /* set to 3 because leaderCommit is lower */
...@@ -990,15 +1020,15 @@ void T_estRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedi ...@@ -990,15 +1020,15 @@ void T_estRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedi
msg_appendentries_t ae; msg_appendentries_t ae;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_current_term(r,1); raft_set_current_term(r,1);
...@@ -1028,15 +1058,15 @@ void T_estRaft_follower_resends_entry_if_request_from_leader_timesout(CuTest * t ...@@ -1028,15 +1058,15 @@ void T_estRaft_follower_resends_entry_if_request_from_leader_timesout(CuTest * t
r = raft_new(); r = raft_new();
/* three nodes */ /* three nodes */
peer = raft_add_peer(r,(void*)1); node = raft_add_node(r,(void*)1);
raft_add_peer(r,(void*)2); raft_add_node(r,(void*)2);
raft_set_state(r,RAFT_STATE_FOLLOWER); raft_set_state(r,RAFT_STATE_FOLLOWER);
/* log size s */ /* log size s */
CuAssertTrue(tc, 0 == raft_get_log_count(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_appendentries(r,peer,&ae); raft_recv_appendentries(r,node,&ae);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
} }
#endif #endif
...@@ -1045,8 +1075,8 @@ void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * t ...@@ -1045,8 +1075,8 @@ void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * t
{ {
void *r; void *r;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1057,7 +1087,7 @@ void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * t ...@@ -1057,7 +1087,7 @@ void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * t
/* 1 second election timeout */ /* 1 second election timeout */
raft_set_election_timeout(r, 1000); raft_set_election_timeout(r, 1000);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* 1.001 seconds have passed */ /* 1.001 seconds have passed */
raft_periodic(r, 1001); raft_periodic(r, 1001);
...@@ -1071,13 +1101,13 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe ...@@ -1071,13 +1101,13 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1086,16 +1116,16 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe ...@@ -1086,16 +1116,16 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
msg_requestvote_t rv; msg_requestvote_t rv;
msg_requestvote_response_t *rvr; msg_requestvote_response_t *rvr;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* request vote */ /* request vote */
/* vote indicates candidate's log is not complete compared to follower */ /* vote indicates candidate's log is not complete compared to follower */
memset(&rv,0,sizeof(msg_requestvote_t)); memset(&rv,0,sizeof(msg_requestvote_t));
rv.term = 1; rv.term = 1;
rv.candidate_id = 0; rv.candidate_id = 1;
rv.last_log_idx = 1; rv.last_log_idx = 1;
rv.last_log_term = 1; rv.last_log_term = 1;
...@@ -1105,12 +1135,11 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe ...@@ -1105,12 +1135,11 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
/* vote not granted */ /* vote not granted */
raft_recv_requestvote(r,1,&rv); raft_recv_requestvote(r,1,&rv);
rvr = sender_poll_msg(sender); rvr = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rvr); CuAssertTrue(tc, NULL != rvr);
CuAssertTrue(tc, 0 == rvr->vote_granted); CuAssertTrue(tc, 0 == rvr->vote_granted);
} }
void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc) void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc)
{ {
void *r; void *r;
...@@ -1128,9 +1157,9 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc) ...@@ -1128,9 +1157,9 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc)
r = raft_new(); r = raft_new();
CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_become_candidate(r);
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 1 == raft_get_current_term(r));
raft_become_candidate(r);
CuAssertTrue(tc, 2 == raft_get_current_term(r));
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -1142,7 +1171,7 @@ void TestRaft_follower_becoming_candidate_votes_for_self(CuTest * tc) ...@@ -1142,7 +1171,7 @@ void TestRaft_follower_becoming_candidate_votes_for_self(CuTest * tc)
CuAssertTrue(tc, -1 == raft_get_voted_for(r)); CuAssertTrue(tc, -1 == raft_get_voted_for(r));
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 0 == raft_get_voted_for(r)); CuAssertTrue(tc, raft_get_nodeid(r) == raft_get_voted_for(r));
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
} }
...@@ -1155,11 +1184,12 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc) ...@@ -1155,11 +1184,12 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc)
raft_set_election_timeout(r, 1000); raft_set_election_timeout(r, 1000);
CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r));
raft_periodic(r, 100); raft_periodic(r, 900);
CuAssertTrue(tc, 100 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 900 == raft_get_timeout_elapsed(r));
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r)); /* time is selected randomly */
CuAssertTrue(tc, raft_get_timeout_elapsed(r) < 900);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -1167,21 +1197,21 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe ...@@ -1167,21 +1197,21 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
/* 2 peers */
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),(void*)3},
{(-1),NULL}}; {(-1),NULL}};
msg_requestvote_t* rv; msg_requestvote_t* rv;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* set term so we can check it gets included in the outbound message */ /* set term so we can check it gets included in the outbound message */
raft_set_current_term(r,2); raft_set_current_term(r,2);
...@@ -1190,12 +1220,13 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe ...@@ -1190,12 +1220,13 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe
/* becoming candidate triggers vote requests */ /* becoming candidate triggers vote requests */
raft_become_candidate(r); raft_become_candidate(r);
/* 2 peers = 2 vote requests */ /* 2 nodes = 2 vote requests */
rv = sender_poll_msg(sender); rv = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 2 != rv->term);
CuAssertTrue(tc, 3 == rv->term); CuAssertTrue(tc, 3 == rv->term);
/* TODO: there should be more items */ /* TODO: there should be more items */
rv = sender_poll_msg(sender); rv = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 3 == rv->term); CuAssertTrue(tc, 3 == rv->term);
} }
...@@ -1205,13 +1236,13 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C ...@@ -1205,13 +1236,13 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1222,20 +1253,20 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C ...@@ -1222,20 +1253,20 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C
vr.term = 1; vr.term = 1;
vr.vote_granted = 1; vr.vote_granted = 1;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_election_timeout(r,1000); raft_set_election_timeout(r,1000);
/* server wants to be leader, so becomes candidate */ /* server wants to be leader, so becomes candidate */
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 2 == raft_get_current_term(r));
/* clock over (ie. 1000 + 1), causing new election */ /* clock over (ie. 1000 + 1), causing new election */
raft_periodic(r,1001); raft_periodic(r,1001);
CuAssertTrue(tc, 2 == raft_get_current_term(r)); CuAssertTrue(tc, 3 == raft_get_current_term(r));
/* receiving this vote gives the server majority */ /* receiving this vote gives the server majority */
// raft_recv_requestvote_response(r,1,&vr); // raft_recv_requestvote_response(r,1,&vr);
...@@ -1247,13 +1278,13 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) ...@@ -1247,13 +1278,13 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),(void*)3}, {(-1),(void*)3},
...@@ -1263,20 +1294,22 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) ...@@ -1263,20 +1294,22 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
msg_requestvote_response_t vr; msg_requestvote_response_t vr;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
CuAssertTrue(tc, 5 == raft_get_npeers(r)); CuAssertTrue(tc, 5 == raft_get_nnodes(r));
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
/* vote for self */
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 2 == raft_get_current_term(r));
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
/* a vote for us */ /* a vote for us */
memset(&vr,0,sizeof(msg_requestvote_response_t)); memset(&vr,0,sizeof(msg_requestvote_response_t));
vr.term = 1; vr.term = 2;
vr.vote_granted = 1; vr.vote_granted = 1;
/* get one vote */ /* get one vote */
raft_recv_requestvote_response(r,1,&vr); raft_recv_requestvote_response(r,1,&vr);
CuAssertTrue(tc, 2 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 2 == raft_get_nvotes_for_me(r));
...@@ -1285,7 +1318,6 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) ...@@ -1285,7 +1318,6 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
/* get another vote /* get another vote
* now has majority (ie. 3/5 votes) */ * now has majority (ie. 3/5 votes) */
raft_recv_requestvote_response(r,2,&vr); raft_recv_requestvote_response(r,2,&vr);
CuAssertTrue(tc, 3 == raft_get_nvotes_for_me(r));
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
} }
...@@ -1295,13 +1327,13 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted( ...@@ -1295,13 +1327,13 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
void *r; void *r;
void *sender; void *sender;
void *msg; void *msg;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1309,17 +1341,18 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted( ...@@ -1309,17 +1341,18 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
msg_requestvote_response_t* rvr; msg_requestvote_response_t* rvr;
msg_requestvote_t rv; msg_requestvote_t rv;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_vote(r,1); raft_vote(r,0);
memset(&rv,0,sizeof(msg_requestvote_t)); memset(&rv,0,sizeof(msg_requestvote_t));
raft_recv_requestvote(r,1,&rv); raft_recv_requestvote(r,1,&rv);
rvr = sender_poll_msg(sender); /* we've vote already, so won't respond with a vote granted... */
rvr = sender_poll_msg_data(sender);
CuAssertTrue(tc, 0 == rvr->vote_granted); CuAssertTrue(tc, 0 == rvr->vote_granted);
} }
...@@ -1328,21 +1361,21 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc) ...@@ -1328,21 +1361,21 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc)
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_requestvote_t* rv; msg_requestvote_t* rv;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
...@@ -1350,7 +1383,7 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc) ...@@ -1350,7 +1383,7 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc)
raft_set_current_idx(r,3); raft_set_current_idx(r,3);
raft_send_requestvote(r,1); raft_send_requestvote(r,1);
rv = sender_poll_msg(sender); rv = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 3 == rv->last_log_idx); CuAssertTrue(tc, 3 == rv->last_log_idx);
CuAssertTrue(tc, 5 == rv->term); CuAssertTrue(tc, 5 == rv->term);
...@@ -1362,30 +1395,30 @@ void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower(CuTest ...@@ -1362,30 +1395,30 @@ void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower(CuTest
void *r; void *r;
void *sender; void *sender;
void *msg; void *msg;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(NULL);
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
sender = sender_new();
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
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));
/* receive recent appendentries */
msg_appendentries_t ae;
memset(&ae,0,sizeof(msg_appendentries_t));
ae.term = 1;
raft_recv_appendentries(r,1,&ae); raft_recv_appendentries(r,1,&ae);
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
} }
...@@ -1395,13 +1428,13 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f ...@@ -1395,13 +1428,13 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1409,10 +1442,10 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f ...@@ -1409,10 +1442,10 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f
msg_appendentries_t ae; msg_appendentries_t ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* server's log is newer */ /* server's log is newer */
raft_set_current_term(r,1); raft_set_current_term(r,1);
...@@ -1443,38 +1476,51 @@ void TestRaft_leader_becomes_leader_is_leader(CuTest * tc) ...@@ -1443,38 +1476,51 @@ void TestRaft_leader_becomes_leader_is_leader(CuTest * tc)
CuAssertTrue(tc, raft_is_leader(r)); CuAssertTrue(tc, raft_is_leader(r));
} }
void TestRaft_leader_when_becomes_leader_all_peers_have_nextidx_equal_to_lastlog_idx_plus_1(CuTest * tc) void TestRaft_leader_becomes_leader_clears_voted_for(CuTest * tc)
{
void *r;
r = raft_new();
raft_vote(r,1);
CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_become_leader(r);
CuAssertTrue(tc, -1 == raft_get_voted_for(r));
}
void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog_idx_plus_1(CuTest * tc)
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),(void*)3},
{(-1),NULL}}; {(-1),NULL}};
msg_appendentries_t* ae; msg_appendentries_t* ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* candidate to leader */ /* candidate to leader */
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_become_leader(r); raft_become_leader(r);
int i; int i;
for (i=0; i<raft_get_npeers(r); i++) for (i=0; i<raft_get_nnodes(r); i++)
{ {
raft_peer_t* p = raft_get_peer(r,i); if (i==0) continue;
raft_node_t* p = raft_get_node(r,i);
CuAssertTrue(tc, raft_get_current_idx(r) + 1 == CuAssertTrue(tc, raft_get_current_idx(r) + 1 ==
raft_peer_get_next_idx(p)); raft_node_get_next_idx(p));
} }
} }
...@@ -1483,32 +1529,32 @@ void TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries(CuTest * ...@@ -1483,32 +1529,32 @@ void TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries(CuTest *
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ raft_node_configuration_t cfg[] = {
raft_peer_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),(void*)3},
{(-1),NULL}}; {(-1),NULL}};
msg_appendentries_t* ae; msg_appendentries_t* ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* candidate to leader */ /* candidate to leader */
raft_set_state(r,RAFT_STATE_CANDIDATE); raft_set_state(r,RAFT_STATE_CANDIDATE);
raft_become_leader(r); raft_become_leader(r);
/* receive appendentries messages for both peers */ /* receive appendentries messages for both nodes */
ae = sender_poll_msg(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
ae = sender_poll_msg(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
} }
...@@ -1519,21 +1565,21 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc) ...@@ -1519,21 +1565,21 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
{ {
void *r, *sender; void *r, *sender;
msg_entry_response_t *cr; msg_entry_response_t *cr;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* I am the leader */ /* I am the leader */
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
...@@ -1553,7 +1599,7 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc) ...@@ -1553,7 +1599,7 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
raft_apply_entry(r); raft_apply_entry(r);
/* leader sent response to entry message */ /* leader sent response to entry message */
cr = sender_poll_msg(sender); cr = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != cr); CuAssertTrue(tc, NULL != cr);
} }
...@@ -1562,13 +1608,13 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(Cu ...@@ -1562,13 +1608,13 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(Cu
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1576,21 +1622,21 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(Cu ...@@ -1576,21 +1622,21 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(Cu
msg_appendentries_t* ae; msg_appendentries_t* ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* i'm leader */ /* i'm leader */
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
void* p; void* p;
p = raft_get_peer(r,0); p = raft_get_node(r,0);
raft_peer_set_next_idx(p, 4); raft_node_set_next_idx(p, 4);
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r,0); raft_send_appendentries(r,0);
ae = sender_poll_msg(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
} }
...@@ -1599,13 +1645,13 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis ...@@ -1599,13 +1645,13 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1613,17 +1659,17 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis ...@@ -1613,17 +1659,17 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis
msg_appendentries_t* ae; msg_appendentries_t* ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
/* i'm leader */ /* i'm leader */
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r,0); raft_send_appendentries(r,0);
ae = sender_poll_msg(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
} }
...@@ -1637,8 +1683,8 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc) ...@@ -1637,8 +1683,8 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc)
{ {
void *r; void *r;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1650,7 +1696,7 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc) ...@@ -1650,7 +1696,7 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc)
ety.len = strlen("entry"); ety.len = strlen("entry");
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
CuAssertTrue(tc, 0 == raft_get_log_count(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
...@@ -1664,8 +1710,8 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc) ...@@ -1664,8 +1710,8 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc)
{ {
void *r; void *r;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1676,7 +1722,7 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc) ...@@ -1676,7 +1722,7 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc)
ety.len = strlen("entry"); ety.len = strlen("entry");
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
CuAssertTrue(tc, 0 == raft_get_log_count(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
...@@ -1693,20 +1739,20 @@ void TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_on ...@@ -1693,20 +1739,20 @@ void TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_on
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
msg_appendentries_response_t aer; msg_appendentries_response_t aer;
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_callbacks(r,&funcs,sender); raft_set_callbacks(r,&funcs,sender);
/* I'm the leader */ /* I'm the leader */
...@@ -1767,13 +1813,13 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C ...@@ -1767,13 +1813,13 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C
{ {
void *r; void *r;
void *sender; void *sender;
raft_external_functions_t funcs = { raft_cbs_t funcs = {
.send = sender_send, .send = sender_send,
.log = NULL .log = NULL
}; };
/* 2 peers */ /* 2 nodes */
raft_peer_configuration_t cfg[] = { raft_node_configuration_t cfg[] = {
{(-1),(void*)1}, {(-1),(void*)1},
{(-1),(void*)2}, {(-1),(void*)2},
{(-1),NULL}}; {(-1),NULL}};
...@@ -1781,9 +1827,9 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C ...@@ -1781,9 +1827,9 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C
msg_appendentries_t ae; msg_appendentries_t ae;
sender = sender_new(); sender = sender_new(NULL);
r = raft_new(); r = raft_new();
raft_set_configuration(r,cfg); raft_set_configuration(r,cfg,0);
raft_set_state(r,RAFT_STATE_LEADER); raft_set_state(r,RAFT_STATE_LEADER);
raft_set_current_term(r,5); raft_set_current_term(r,5);
......
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