Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
Willemt Raft
Commits
825ca97e
Commit
825ca97e
authored
Sep 20, 2013
by
willem
Browse files
Passing 4 tests
parent
47472f6e
Changes
10
Hide whitespace changes
Inline
Side-by-side
mock_send_functions.c
View file @
825ca97e
...
...
@@ -22,12 +22,12 @@ typedef struct {
int
sender_send
(
void
*
caller
,
void
*
udata
,
void
*
peer
,
const
unsigned
char
*
data
,
int
len
)
{
sender_t
*
me
=
udata
;
void
*
n
;
sender_t
*
me
=
caller
;
unsigned
char
*
n
;
n
=
malloc
(
len
);
memcpy
(
n
,
data
,
len
);
llqueue_offer
(
me
->
inbox
,
(
void
*
)
data
);
llqueue_offer
(
me
->
inbox
,
n
);
return
0
;
}
...
...
@@ -42,6 +42,8 @@ void* sender_new()
void
*
sender_poll_msg
(
void
*
s
)
{
return
NULL
;
sender_t
*
me
=
s
;
return
llqueue_poll
(
me
->
inbox
);
}
raft.h
View file @
825ca97e
...
...
@@ -6,26 +6,47 @@ enum {
RAFT_STATE_LEADER
};
typedef
struct
{
/* So that we can tell which peers were removed/added */
int
old_id
;
/* User data pointer for addressing.
* ie. This is most likely a (IP,Port) tuple */
void
*
udata_address
;
}
raft_peer_configuration_t
;
#if 0
typedef struct {
/* -1 uses implementation default */
int election_timeout;
/* -1 uses implementation default */
int request_timeout;
/* Terminated by udata_address being NULL */
raft_peer_configuration_t *peers;
} raft_configuration_t;
#endif
/* messages */
#if 0
enum {
MSG_RequestVote,
MSG_RequestVoteResponse,
MSG_AppendEntries,
MSG_AppendEntriesResponse
};
#endif
typedef
struct
{
/* term candidate's term */
int
term
;
/* candidateId candidate requesting vote */
int
candidate
ID
;
int
candidate
_id
;
/* index of candidate's last log entry */
int
last
LogI
ndex
;
int
last
_log_i
ndex
;
/* term of candidate's last log entry */
int
last
LogT
erm
;
int
last
_log_t
erm
;
}
msg_requestvote_t
;
typedef
struct
{
...
...
@@ -36,7 +57,7 @@ typedef struct {
typedef
struct
{
unsigned
int
id
;
int
was
C
ommitted
;
int
was
_c
ommitted
;
}
msg_command_response_t
;
typedef
struct
{
...
...
@@ -44,17 +65,17 @@ typedef struct {
int
term
;
/* true means candidate received vote */
int
vote
G
ranted
;
int
vote
_g
ranted
;
}
msg_requestvote_response_t
;
typedef
struct
{
int
term
;
int
leader
ID
;
int
prev
LogI
ndex
;
int
prev
LogT
erm
;
int
leader
_id
;
int
prev
_log_i
ndex
;
int
prev
_log_t
erm
;
int
n_entries
;
void
*
entries
;
int
leader
C
ommit
;
int
leader
_c
ommit
;
}
msg_appendentries_t
;
typedef
struct
{
...
...
@@ -110,46 +131,15 @@ typedef struct {
// recv_requestvote_f recv_requestvote,
}
raft_functions_t
;
typedef
void
*
raft_server_t
;
typedef
struct
{
/* Persistent state: */
/* the server's best guess of what the current term is
* starts at zero */
int
currentTerm
;
/* The candidate the server voted for in its current term,
* or Nil if it hasn't voted for any. */
int
votedFor
;
/* the log which is replicated */
void
*
log
;
typedef
void
*
raft_peer_t
;
/* Volatile state: */
raft_server_t
*
raft_new
();
/* Index of highest log entry known to be committed */
int
commitIndex
;
void
*
raft_get_voted_for
(
raft_server_t
*
me
);
/* Index of highest log entry applied to state machine */
int
lastApplied
;
/* follower/leader/candidate indicator */
int
state
;
raft_functions_t
*
func
;
/* callbacks */
raft_external_functions_t
*
ext_func
;
void
*
caller
;
int
logSize
;
}
raft_server_t
;
void
*
raft_new
();
void
raft_set_external_functions
(
void
*
r
,
raft_external_functions_t
*
funcs
,
void
*
caller
);
void
raft_set_external_functions
(
raft_server_t
*
me
,
raft_external_functions_t
*
funcs
,
void
*
caller
);
void
raft_election_start
(
void
*
r
);
...
...
@@ -159,67 +149,70 @@ void raft_become_candidate(raft_server_t* me);
int
raft_receive_append_entries
(
raft_server_t
*
me
,
msg_appendentries_t
*
ae
);
int
raft_periodic
(
void
*
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
,
void
*
peer
,
msg_appendentries_t
*
ae
);
int
raft_recv_
appendentries
(
void
*
me
_
,
void
*
peer
,
msg_
appendentries
_t
*
ae
);
int
raft_recv_
requestvote
(
raft_server_t
*
me
,
void
*
peer
,
msg_
requestvote
_t
*
vr
);
int
raft_recv_requestvote
(
void
*
me
_
,
void
*
peer
,
msg_requestvote_t
*
v
r
);
int
raft_recv_requestvote
_response
(
raft_server_t
*
me
,
void
*
peer
,
msg_requestvote_
response_
t
*
r
);
int
raft_
recv_requestvote_response
(
void
*
me_
,
void
*
peer
,
msg_requestvote_response
_t
*
r
);
void
raft_
execute_command
(
raft_server
_t
*
me
);
void
raft_
execute_command
(
void
*
me_
);
void
raft_
set_election_timeout
(
raft_server_t
*
me
,
int
millisec
);
void
raft_
s
et_election_timeout
(
void
*
me_
,
int
millisec
);
int
raft_
g
et_election_timeout
(
raft_server_t
*
me
);
int
raft_
get_election_timeout
(
void
*
me_
);
int
raft_
vote
(
raft_server_t
*
me
,
void
*
peer
);
int
raft_vote
(
void
*
me
_
,
void
*
peer
);
raft_peer_t
*
raft_add_peer
(
raft_server_t
*
me
,
void
*
peer
_udata
);
void
*
raft_
add_peer
(
void
*
me
_
,
void
*
peer
_udata
);
int
raft_
remove_peer
(
raft_server_t
*
me
,
void
*
peer
);
int
raft_
remove_peer
(
void
*
me_
,
void
*
peer
);
int
raft_
get_num_peers
(
raft_server_t
*
me
);
int
raft_
get_num_peers
(
void
*
me_
);
int
raft_
recv_command
(
raft_server_t
*
me
,
void
*
peer
,
msg_command_t
*
cmd
);
int
raft_
recv_command
(
void
*
me_
,
void
*
peer
,
msg_command
_t
*
cmd
);
int
raft_
get_log_count
(
raft_server
_t
*
me
);
int
raft_
g
et_
log_count
(
void
*
me_
);
void
raft_
s
et_
current_term
(
raft_server_t
*
me
,
int
term
);
void
raft_set_current_
term
(
void
*
me
_
,
int
term
);
void
raft_set_current_
index
(
raft_server_t
*
me
,
int
idx
);
void
raft_
s
et_current_
index
(
void
*
me_
,
int
idx
);
int
raft_
g
et_current_
term
(
raft_server_t
*
me
);
int
raft_
g
et_current_
term
(
void
*
me_
);
void
raft_
s
et_current_
index
(
raft_server_t
*
me
,
int
idx
);
void
raft_
s
et_current_index
(
void
*
me_
,
int
idx
);
int
raft_
g
et_current_index
(
raft_server_t
*
me
);
int
raft_
get_current_index
(
void
*
me
_
);
int
raft_
is_follower
(
raft_server_t
*
me
);
int
raft_is_
follower
(
void
*
me
_
);
int
raft_is_
leader
(
raft_server_t
*
me
);
int
raft_is_
leader
(
void
*
me
_
);
int
raft_is_
candidate
(
raft_server_t
*
me
);
int
raft_
is_candidate
(
void
*
me_
);
int
raft_
send_requestvote
(
raft_server_t
*
me
,
void
*
peer
);
int
raft_send_
requestvote
(
void
*
me
_
,
void
*
peer
);
void
raft_send_
appendentries
(
raft_server_t
*
me
,
void
*
peer
);
void
raft_
s
end_
appendentries
(
void
*
me
_
,
void
*
peer
);
int
raft_
app
end_
command
(
raft_server_t
*
me
,
unsigned
char
*
data
,
int
len
);
int
raft_
append
_command
(
void
*
me_
,
unsigned
char
*
data
,
int
len
);
void
raft_
commit
_command
(
raft_server_t
*
me
,
int
logIndex
);
void
raft_
commit_command
(
void
*
me_
,
int
logIndex
);
int
raft_
get_timeout_elapsed
(
raft_server_t
*
me
);
void
*
raft_
peer_new
(
);
void
raft_
set_commit_index
(
raft_server_t
*
me
,
int
commit_idx
);
int
raft_
peer_is_leader
(
void
*
peer
);
void
raft_
set_lastapplied_index
(
raft_server_t
*
me
,
int
idx
);
int
raft_
peer_get_next_index
(
void
*
peer
);
int
raft_
get_lastapplied_index
(
raft_server_t
*
me
);
void
raft_peer_
set_next_index
(
void
*
peer
,
int
nextIdx
);
raft_peer_
t
*
raft_peer_new
(
void
*
udata
);
void
raft_
set_commit_index
(
void
*
me_
,
int
commit_idx
);
int
raft_
peer_is_leader
(
raft_peer_t
*
peer
);
void
raft_
set_lastapplied_index
(
void
*
me_
,
int
idx
);
int
raft_
peer_get_next_index
(
raft_peer_t
*
peer
);
int
raft_
get_lastapplied_index
(
void
*
me_
);
void
raft_
peer_set_next_index
(
raft_peer_t
*
peer
,
int
nextIdx
);
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_peer_configuration_t
*
peers
);
raft_peer.c
View file @
825ca97e
/**
* @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>
...
...
@@ -7,25 +40,28 @@
#include "raft.h"
typedef
struct
{
int
pass
;
}
raft_peer_t
;
void
*
udata
;
}
raft_peer_
private_
t
;
void
*
raft_peer_new
()
raft_peer_t
*
raft_peer_new
(
void
*
udata
)
{
return
NULL
;
raft_peer_private_t
*
me
;
me
=
calloc
(
1
,
sizeof
(
raft_peer_private_t
));
me
->
udata
=
udata
;
return
(
void
*
)
me
;
}
int
raft_peer_is_leader
(
void
*
peer
)
int
raft_peer_is_leader
(
raft_peer_t
*
me_
)
{
return
0
;
}
int
raft_peer_get_next_index
(
void
*
peer
)
int
raft_peer_get_next_index
(
raft_peer_t
*
me_
)
{
return
0
;
}
void
raft_peer_set_next_index
(
void
*
peer
,
int
nextIdx
)
void
raft_peer_set_next_index
(
raft_peer_t
*
me_
,
int
nextIdx
)
{
}
raft_server.c
View file @
825ca97e
...
...
@@ -37,40 +37,101 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include <assert.h>
#include "linked_list_hashmap.h"
#include "raft.h"
void
*
raft_new
()
{
raft_server_t
*
me
;
typedef
struct
{
/* Persistent state: */
/* the server's best guess of what the current term is
* starts at zero */
int
current_term
;
/* The candidate the server voted for in its current term,
* or Nil if it hasn't voted for any. */
void
*
voted_for
;
/* the log which is replicated */
void
*
log
;
/* Volatile state: */
/* Index of highest log entry known to be committed */
int
commit_index
;
/* Index of highest log entry applied to state machine */
int
last_applied
;
/* follower/leader/candidate indicator */
int
state
;
raft_functions_t
*
func
;
/* callbacks */
raft_external_functions_t
*
ext_func
;
void
*
caller
;
/* indicates size of log */
int
current_index
;
me
=
calloc
(
1
,
sizeof
(
raft_server_t
));
/* amount of time left till timeout */
int
timeout_elapased
;
return
me
;
hashmap_t
*
peers
;
// int log_Size;
}
raft_server_private_t
;
static
unsigned
long
__peer_hash
(
const
void
*
obj
)
{
return
(
unsigned
long
)
obj
;
}
void
raft_free
(
void
*
me_
)
static
long
__peer_compare
(
const
void
*
obj
,
const
void
*
other
)
{
raft_server_t
*
me
=
me_
;
return
obj
-
other
;
}
free
(
me
);
raft_server_t
*
raft_new
()
{
raft_server_private_t
*
me
;
me
=
calloc
(
1
,
sizeof
(
raft_server_private_t
));
me
->
current_index
=
0
;
me
->
timeout_elapased
=
0
;
me
->
peers
=
hashmap_new
(
__peer_hash
,
__peer_compare
,
100
);
return
(
void
*
)
me
;
}
void
raft_free
(
raft_server_t
*
me_
)
{
free
(
me_
);
}
void
raft_set_state
(
void
*
me_
)
void
raft_set_state
(
raft_server_t
*
me_
)
{
raft_server_t
*
me
=
me_
;
}
int
raft_get_state
(
void
*
me_
)
int
raft_get_state
(
raft_server_t
*
me_
)
{
raft_server_t
*
me
=
me_
;
return
0
;
}
void
raft_set_external_functions
(
void
*
r
,
raft_external_functions_t
*
funcs
,
void
*
caller
)
void
raft_set_external_functions
(
raft_server_t
*
me_
,
raft_external_functions_t
*
funcs
,
void
*
caller
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
caller
=
caller
;
me
->
ext_func
=
funcs
;
}
void
raft_election_start
(
void
*
r
)
...
...
@@ -80,13 +141,33 @@ void raft_election_start(void* r)
/**
* Candidate i transitions to leader. */
void
raft_become_leader
(
raft_server_t
*
me
)
void
raft_become_leader
(
raft_server_t
*
me
_
)
{
}
void
raft_become_candidate
(
raft_server_t
*
me
)
void
raft_become_candidate
(
raft_server_t
*
me
_
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
hashmap_iterator_t
iter
;
void
*
p
;
me
->
current_term
+=
1
;
me
->
voted_for
=
me
;
me
->
timeout_elapased
=
0
;
for
(
hashmap_iterator
(
me
->
peers
,
&
iter
);
(
p
=
hashmap_iterator_next_value
(
me
->
peers
,
&
iter
));)
{
msg_requestvote_t
rv
;
rv
.
term
=
me
->
current_term
;
rv
.
candidate_id
=
0
;
//me->current_term;
// rv.last_log_index = me->log
if
(
me
->
ext_func
&&
me
->
ext_func
->
send
)
me
->
ext_func
->
send
(
me
->
caller
,
NULL
,
NULL
,
(
void
*
)
&
rv
,
sizeof
(
msg_requestvote_t
));
}
}
...
...
@@ -96,9 +177,9 @@ void raft_become_candidate(raft_server_t* me)
* Granting vote to candidate
*/
#if 0
int raft_election_timeout_elapsed(
void
* me_)
int raft_election_timeout_elapsed(
raft_server_t
* me_)
{
raft_server_t* me = me_;
raft_server_t* me
_
= me_;
if (nvalid_AEs_since_election == 0 || votes_granted_to_candidate_since_election == 0)
{
...
...
@@ -107,169 +188,192 @@ int raft_election_timeout_elapsed(void* me_)
}
#endif
int
raft_
periodic
(
void
*
me_
,
int
msec_since_last_period
)
int
raft_
get_timeout_elapsed
(
raft_server_t
*
me_
)
{
raft_server_t
*
me
=
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
timeout_elapased
;
}
int
raft_periodic
(
raft_server_t
*
me_
,
int
msec_since_last_period
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
timeout_elapased
+=
msec_since_last_period
;
return
0
;
}
/**
* Invoked by leader to replicate log entries (§5.3); also used as heartbeat (§5.2). */
int
raft_recv_appendentries
(
void
*
me_
,
void
*
peer
,
msg_appendentries_t
*
ae
)
int
raft_recv_appendentries
(
raft_server_t
*
me_
,
void
*
peer
,
msg_appendentries_t
*
ae
)
{
return
0
;
}
int
raft_recv_appendentries_response
(
void
*
me_
,
void
*
peer
,
msg_appendentries_response_t
*
ae
)
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
void
*
peer
,
msg_appendentries_response_t
*
ae
)
{
return
0
;
}
int
raft_recv_requestvote
(
void
*
me_
,
void
*
peer
,
msg_requestvote_t
*
vr
)
int
raft_recv_requestvote
(
raft_server_t
*
me_
,
void
*
peer
,
msg_requestvote_t
*
vr
)
{
return
0
;
}
int
raft_recv_requestvote_response
(
void
*
me_
,
void
*
peer
,
msg_requestvote_response_t
*
r
)
int
raft_recv_requestvote_response
(
raft_server_t
*
me_
,
void
*
peer
,
msg_requestvote_response_t
*
r
)
{
return
0
;
}
void
raft_execute_command
(
void
*
me_
)
void
raft_execute_command
(
raft_server_t
*
me_
)
{
}
void
raft_set_election_timeout
(
void
*
me_
,
int
millisec
)
void
raft_set_election_timeout
(
raft_server_t
*
me_
,
int
millisec
)
{
}
void
raft_set_request_timeout
(
void
*
me_
,
int
millisec
)
void
raft_set_request_timeout
(
raft_server_t
*
me_
,
int
millisec
)
{
}
int
raft_get_election_timeout
(
void
*
me_
)
int
raft_get_election_timeout
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_get_request_timeout
(
void
*
me_
)
int
raft_get_request_timeout
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_vote
(
void
*
me_
,
void
*
peer
)
int
raft_vote
(
raft_server_t
*
me_
,
void
*
peer
)
{
return
0
;
}
#if 0
void raft_set_configuration(raft_server_t* me)
raft_peer_t
*
raft_add_peer
(
raft_server_t
*
me_
,
void
*
peer_udata
)
{
return 0;
}
#endif
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_peer_t
*
p
;
void
*
raft_add_peer
(
void
*
me_
,
void
*
peer_udata
)
{
return
NULL
;
if
(
hashmap_get
(
me
->
peers
,
peer_udata
))
{
return
NULL
;
}
p
=
raft_peer_new
(
peer_udata
);
hashmap_put
(
me
->
peers
,
peer_udata
,
p
);
return
p
;
}
int
raft_remove_peer
(
void
*
me_
,
void
*
peer
)
int
raft_remove_peer
(
raft_server_t
*
me_
,
void
*
peer
)
{
return
0
;
}
int
raft_get_num_peers
(
void
*
me_
)
int
raft_get_num_peers
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_recv_command
(
void
*
me_
,
void
*
peer
,
msg_command_t
*
cmd
)
int
raft_recv_command
(
raft_server_t
*
me_
,
void
*
peer
,
msg_command_t
*
cmd
)
{
return
0
;
}
int
raft_get_log_count
(
void
*
me_
)
int
raft_get_log_count
(
raft_server_t
*
me_
)
{
return
0
;
}
void
raft_
s
et_
curren
t_
t
er
m
(
void
*
me_
,
int
term
)
void
*
raft_
g
et_
voted_for
(
raf
t_
s
er
ver_t
*
me_
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
voted_for
;
}
int
raft_
g
et_current_term
(
void
*
me_
)
void
raft_
s
et_current_term
(
raft_server_t
*
me_
,
int
term
)
{
return
0
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
current_term
=
term
;
}
void
raft_
s
et_current_
index
(
void
*
me_
,
int
idx
)
int
raft_
g
et_current_
term
(
raft_server_t
*
me_
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
current_term
;
}
void
raft_set_current_index
(
raft_server_t
*
me_
,
int
idx
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
me
->
current_index
=
idx
;
}
int
raft_get_current_index
(
void
*
me_
)
int
raft_get_current_index
(
raft_server_t
*
me_
)
{
return
0
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
current_index
;
}
int
raft_is_follower
(
void
*
me_
)
int
raft_is_follower
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_is_leader
(
void
*
me_
)
int
raft_is_leader
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_is_candidate
(
void
*
me_
)
int
raft_is_candidate
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_send_requestvote
(
void
*
me_
,
void
*
peer
)
int
raft_send_requestvote
(
raft_server_t
*
me_
,
void
*
peer
)
{
return
0
;
}
int
raft_append_command
(
void
*
me_
,
unsigned
char
*
data
,
int
len
)
int
raft_append_command
(
raft_server_t
*
me_
,
unsigned
char
*
data
,
int
len
)
{
return
0
;
}
void
raft_set_commit_index
(
void
*
me_
,
int
commit_idx
)
void
raft_set_commit_index
(
raft_server_t
*
me_
,
int
commit_idx
)
{
}
void
raft_set_lastapplied_index
(
void
*
me_
,
int
idx
)
void
raft_set_lastapplied_index
(
raft_server_t
*
me_
,
int
idx
)
{
}
int
raft_get_lastapplied_index
(
void
*
me_
)
int
raft_get_lastapplied_index
(
raft_server_t
*
me_
)
{
return
0
;
}
int
raft_get_commit_index
(
void
*
me_
)
int
raft_get_commit_index
(
raft_server_t
*
me_
)
{
return
0
;
}
void
raft_commit_command
(
void
*
me_
,
int
logIndex
)
void
raft_commit_command
(
raft_server_t
*
me_
,
int
logIndex
)
{
}
void
raft_send_appendentries
(
void
*
me_
,
void
*
peer
)
void
raft_send_appendentries
(
raft_server_t
*
me_
,
void
*
peer
)
{
}
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_peer_configuration_t
*
peers
)
{
}
test_candidate.c
View file @
825ca97e
...
...
@@ -28,9 +28,9 @@ void TestRaft_follower_becoming_candidate_votes_for_self(CuTest * tc)
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_
current_term
(
r
));
CuAssertTrue
(
tc
,
NULL
==
raft_get_
voted_for
(
r
));
raft_become_candidate
(
r
);
CuAssertTrue
(
tc
,
1
==
raft_get_
current_term
(
r
));
CuAssertTrue
(
tc
,
r
==
raft_get_
voted_for
(
r
));
}
/* Candidate 5.2 */
...
...
@@ -39,10 +39,13 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc)
void
*
r
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_timeout_elapsed
(
r
));
raft_periodic
(
r
,
100
);
CuAssertTrue
(
tc
,
100
==
raft_get_timeout_elapsed
(
r
));
CuAssertTrue
(
tc
,
0
==
raft_get_current_term
(
r
));
raft_become_candidate
(
r
);
CuAssertTrue
(
tc
,
1
==
raft_get_
current_term
(
r
));
CuAssertTrue
(
tc
,
0
==
raft_get_
timeout_elapsed
(
r
));
}
/* Candidate 5.2 */
...
...
@@ -54,18 +57,33 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe
.
send
=
sender_send
,
.
log
=
NULL
};
raft_peer_configuration_t
cfg
[]
=
{
/* 2 peers */
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
msg_requestvote_t
*
rv
;
sender
=
sender_new
();
r
=
raft_new
();
raft_set_external_functions
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
);
/* set term so we can check it gets included in the outbound message */
raft_set_current_term
(
r
,
2
);
raft_set_current_index
(
r
,
5
);
/* becoming candidate triggers vote requests */
raft_become_candidate
(
r
);
/* 2 peers = 2 vote requests */
rv
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rv
);
CuAssertTrue
(
tc
,
3
==
rv
->
term
);
/* TODO: there should be more items */
rv
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rv
);
CuAssertTrue
(
tc
,
3
==
rv
->
term
);
}
/* Candidate 5.2 */
...
...
@@ -78,12 +96,17 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C
.
send
=
sender_send
,
.
log
=
NULL
};
raft_peer_configuration_t
cfg
[]
=
{
/* 2 peers */
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
msg_requestvote_response_t
vr
;
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
vr
.
term
=
1
;
vr
.
vote
G
ranted
=
1
;
vr
.
vote
_g
ranted
=
1
;
sender
=
sender_new
();
...
...
@@ -118,7 +141,7 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
vr
.
term
=
1
;
vr
.
vote
G
ranted
=
1
;
vr
.
vote
_g
ranted
=
1
;
sender
=
sender_new
();
...
...
@@ -199,7 +222,7 @@ void TestRaft_candidate_requestvote_includes_logIndex(CuTest * tc)
rv
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rv
);
CuAssertTrue
(
tc
,
3
==
rv
->
last
LogI
ndex
);
CuAssertTrue
(
tc
,
3
==
rv
->
last
_log_i
ndex
);
CuAssertTrue
(
tc
,
5
==
rv
->
term
);
}
...
...
@@ -266,8 +289,8 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f
/* invalid leader determined by "leaders" old log */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev
LogI
ndex
=
1
;
ae
.
prev
LogT
erm
=
1
;
ae
.
prev
_log_i
ndex
=
1
;
ae
.
prev
_log_t
erm
=
1
;
/* appendentry from invalid leader doesn't make candidate become follower */
raft_recv_appendentries
(
r
,
peer
,
&
ae
);
...
...
test_follower.c
View file @
825ca97e
...
...
@@ -21,13 +21,14 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt
msg_appendentries_t
ae
;
msg_appendentries_response_t
*
aer
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
sender
=
sender_new
();
r
=
raft_new
();
peer
=
raft_add_peer
(
r
,(
void
*
)
1
);
/* term is low */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
/* higher current term */
raft_set_current_term
(
r
,
5
);
raft_set_external_functions
(
r
,
&
funcs
,
sender
);
...
...
@@ -62,7 +63,7 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
}
/* 5.3 */
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
LogI
ndex
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
_log_i
ndex
(
CuTest
*
tc
)
{
void
*
r
,
*
peer
;
void
*
sender
;
...
...
@@ -82,7 +83,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
/* log index that server doesn't have */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
5
;
ae
.
prev
LogI
ndex
=
5
;
ae
.
prev
_log_i
ndex
=
5
;
/* current term is old */
raft_set_current_term
(
r
,
5
);
...
...
@@ -105,14 +106,13 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
r
=
raft_new
();
peer
=
raft_add_peer
(
r
,(
void
*
)
1
);
raft_set_current_term
(
r
,
2
);
/* first append entry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev
LogI
ndex
=
0
;
ae
.
prev
LogT
erm
=
0
;
ae
.
prev
_log_i
ndex
=
0
;
ae
.
prev
_log_t
erm
=
0
;
/* increase log size */
raft_append_command
(
r
,
"111"
,
3
);
...
...
@@ -176,9 +176,9 @@ void TestRaft_follower_recv_appendentries_set_commitindex_to_prevLogIdx(CuTest *
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev
LogT
erm
=
1
;
ae
.
prev
LogI
ndex
=
4
;
ae
.
leader
C
ommit
=
5
;
ae
.
prev
_log_t
erm
=
1
;
ae
.
prev
_log_i
ndex
=
4
;
ae
.
leader
_c
ommit
=
5
;
/* receipt of appendentries changes commit index */
raft_recv_appendentries
(
r
,
peer
,
&
ae
);
...
...
@@ -204,9 +204,9 @@ void TestRaft_follower_recv_appendentries_set_commitindex_to_LeaderCommit(CuTest
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev
LogT
erm
=
1
;
ae
.
prev
LogI
ndex
=
4
;
ae
.
leader
C
ommit
=
3
;
ae
.
prev
_log_t
erm
=
1
;
ae
.
prev
_log_i
ndex
=
4
;
ae
.
leader
_c
ommit
=
3
;
/* receipt of appendentries changes commit index */
raft_recv_appendentries
(
r
,
peer
,
&
ae
);
...
...
@@ -255,8 +255,8 @@ void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedin
/* first append entry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev
LogI
ndex
=
0
;
ae
.
prev
LogT
erm
=
0
;
ae
.
prev
_log_i
ndex
=
0
;
ae
.
prev
_log_t
erm
=
0
;
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
...
...
@@ -335,9 +335,9 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
/* vote indicates candidate's log is not complete compared to follower */
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
rv
.
term
=
1
;
rv
.
candidate
ID
=
0
;
rv
.
last
LogI
ndex
=
1
;
rv
.
last
LogT
erm
=
1
;
rv
.
candidate
_id
=
0
;
rv
.
last
_log_i
ndex
=
1
;
rv
.
last
_log_t
erm
=
1
;
/* server's term and index are more up-to-date */
raft_set_current_term
(
r
,
1
);
...
...
@@ -347,6 +347,6 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
raft_recv_requestvote
(
r
,
peer
,
&
rv
);
rvr
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
G
ranted
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
_g
ranted
);
}
test_leader.c
View file @
825ca97e
...
...
@@ -237,8 +237,8 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
5
;
ae
.
prev
LogI
ndex
=
6
;
ae
.
prev
LogT
erm
=
5
;
ae
.
prev
_log_i
ndex
=
6
;
ae
.
prev
_log_t
erm
=
5
;
sender
=
sender_new
();
r
=
raft_new
();
...
...
test_peer.c
View file @
825ca97e
...
...
@@ -11,9 +11,9 @@
void
TestRaft_peer_set_nextIdx
(
CuTest
*
tc
)
{
void
*
p
;
raft_peer_t
*
p
;
p
=
raft_peer_new
();
p
=
raft_peer_new
(
(
void
*
)
1
);
raft_peer_set_next_index
(
p
,
3
);
CuAssertTrue
(
tc
,
3
==
raft_peer_get_next_index
(
p
));
}
...
...
test_server.c
View file @
825ca97e
...
...
@@ -47,6 +47,17 @@ void TestRaft_add_peer(CuTest * tc)
CuAssertTrue
(
tc
,
1
==
raft_get_num_peers
(
r
));
}
void
TestRaft_dont_add_duplicate_peers
(
CuTest
*
tc
)
{
void
*
r
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_num_peers
(
r
));
raft_add_peer
(
r
,(
void
*
)
1
);
CuAssertTrue
(
tc
,
NULL
==
raft_add_peer
(
r
,(
void
*
)
1
));
CuAssertTrue
(
tc
,
1
==
raft_get_num_peers
(
r
));
}
void
TestRaft_remove_peer
(
CuTest
*
tc
)
{
void
*
r
;
...
...
test_server_request_vote.c
View file @
825ca97e
...
...
@@ -40,7 +40,7 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term
raft_recv_requestvote
(
r
,
peer
,
&
rv
);
rvr
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
G
ranted
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
_g
ranted
);
}
// If votedFor is null or candidateId, and candidate's log is at
...
...
@@ -73,6 +73,6 @@ void TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate(
raft_recv_requestvote
(
r
,
peer
,
&
rv
);
rvr
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
G
ranted
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote
_g
ranted
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment