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
b98eedcb
Commit
b98eedcb
authored
Dec 23, 2013
by
willem
Browse files
Improvewd elections
parent
de5373a9
Changes
12
Show whitespace changes
Inline
Side-by-side
CuTest.c
View file @
b98eedcb
...
@@ -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
;
...
...
Makefile
View file @
b98eedcb
...
@@ -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
...
...
mock_send_functions.c
View file @
b98eedcb
...
@@ -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
);
}
}
}
}
mock_send_functions.h
View file @
b98eedcb
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
);
raft.h
View file @
b98eedcb
...
@@ -7,12 +7,12 @@ enum {
...
@@ -7,12 +7,12 @@ enum {
};
};
typedef
struct
{
typedef
struct
{
/* So that we can tell which
peer
s were removed/added */
/* So that we can tell which
node
s 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
peer
s that have this entry */
/* number of
node
s that have this entry */
unsigned
int
n
peer
s
;
unsigned
int
n
node
s
;
}
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_function
s_t
;
}
raft_
cb
s_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_function
s_t
*
funcs
,
void
*
caller
);
void
raft_set_callbacks
(
raft_server_t
*
me
,
raft_
cb
s_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_
peer
s
(
raft_server_t
*
me
);
int
raft_get_num_
node
s
(
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
n
peer
s
,
const
int
nvotes
);
int
raft_votes_is_majority
(
const
int
n
node
s
,
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_
);
raft_log.c
View file @
b98eedcb
...
@@ -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
].
n
peer
s
=
0
;
me
->
entries
[
me
->
back
].
n
node
s
=
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
->
n
peer
s
+=
1
;
e
->
n
node
s
+=
1
;
}
}
}
}
raft_node.c
0 → 100644
View file @
b98eedcb
/**
* 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
;
}
raft_peer.c
deleted
100644 → 0
View file @
de5373a9
/**
* @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
;
}
raft_server.c
View file @
b98eedcb
...
@@ -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_elap
a
sed
;
int
timeout_elapsed
;
/* who has voted for me. This is an array with N = 'n
peer
s' elements */
/* who has voted for me. This is an array with N = 'n
node
s' elements */
int
*
votes_for_me
;
int
*
votes_for_me
;
raft_
peer_t
*
peer
s
;
raft_
node_t
*
node
s
;
int
n
peer
s
;
int
n
node
s
;
int
election_timeout
;
int
election_timeout
;
int
request_timeout
;
int
request_timeout
;
/* callbacks */
/* callbacks */
raft_
external_function
s_t
cb
;
raft_
cb
s_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_elap
a
sed
=
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_
peer
s
(
raft_server_t
*
me_
)
int
raft_get_num_
node
s
(
raft_server_t
*
me_
)
{
{
return
((
raft_server_private_t
*
)
me_
)
->
n
peer
s
;
return
((
raft_server_private_t
*
)
me_
)
->
n
node
s
;
}
}
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
peer
id
)
raft_
node
_t
*
raft_get_
node
(
raft_server_t
*
me_
,
int
node
id
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
if
(
peer
id
<
0
||
me
->
n
peer
s
<=
peer
id
)
if
(
node
id
<
0
||
me
->
n
node
s
<=
node
id
)
return
NULL
;
return
NULL
;
return
me
->
peers
[
peer
id
];
return
me
->
nodes
[
node
id
];
}
}
/**
/**
* @return number of
peer
s that this server has */
* @return number of
node
s that this server has */
int
raft_get_n
peer
s
(
raft_server_t
*
me_
)
int
raft_get_n
node
s
(
raft_server_t
*
me_
)
{
{
return
((
raft_server_private_t
*
)
me_
)
->
n
peer
s
;
return
((
raft_server_private_t
*
)
me_
)
->
n
node
s
;
}
}
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_elap
a
sed
;
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_function
s_t
*
funcs
,
void
*
cb_ctx
)
raft_
cb
s_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_function
s_t
));
memcpy
(
&
me
->
cb
,
funcs
,
sizeof
(
raft_
cb
s_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
->
n
peer
s
;
i
++
)
for
(
i
=
0
;
i
<
me
->
n
node
s
;
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
->
n
peer
s
/
2
<=
e
->
n
peer
s
)
if
(
e
&&
me
->
n
node
s
/
2
<=
e
->
n
node
s
)
{
{
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
n
peer
s
,
const
int
nvotes
)
int
raft_votes_is_majority
(
const
int
n
node
s
,
const
int
nvotes
)
{
{
int
half
;
int
half
;
if
(
n
peer
s
<
nvotes
)
if
(
n
node
s
<
nvotes
)
return
0
;
return
0
;
half
=
n
peer
s
/
2
;
half
=
n
node
s
/
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_t
er
m
(
me_
))
if
(
r
aft_is_lead
er
(
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
->
n
peer
s
,
votes
))
if
(
raft_votes_is_majority
(
me
->
n
node
s
,
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
n
peer
s
;
int
n
node
s
;
/* TODO: one memory allocation only please */
/* TODO: one memory allocation only please */
for
(
n
peer
s
=
0
;
peer
s
->
udata_address
;
peer
s
++
)
for
(
n
node
s
=
0
;
node
s
->
udata_address
;
node
s
++
)
{
{
n
peer
s
++
;
n
node
s
++
;
me
->
peer
s
=
realloc
(
me
->
peer
s
,
sizeof
(
raft_
peer
_t
*
)
*
n
peer
s
);
me
->
node
s
=
realloc
(
me
->
node
s
,
sizeof
(
raft_
node
_t
*
)
*
n
node
s
);
me
->
n
peer
s
=
n
peer
s
;
me
->
n
node
s
=
n
node
s
;
me
->
peers
[
npeer
s
-
1
]
=
raft_
peer
_new
(
peer
s
);
me
->
nodes
[
nnode
s
-
1
]
=
raft_
node
_new
(
node
s
);
}
}
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-*/
test_log.c
View file @
b98eedcb
...
@@ -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_
peer
s
(
CuTest
*
tc
)
void
TestLog_mark_
node
_has_committed_adds_
node
s
(
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
)
->
n
peer
s
);
CuAssertTrue
(
tc
,
0
==
log_get_from_idx
(
l
,
1
)
->
n
node
s
);
log_mark_
peer
_has_committed
(
l
,
1
);
log_mark_
node
_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
n
peer
s
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
n
node
s
);
log_mark_
peer
_has_committed
(
l
,
1
);
log_mark_
node
_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
n
peer
s
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
n
node
s
);
}
}
void
TestLog_delete
(
CuTest
*
tc
)
void
TestLog_delete
(
CuTest
*
tc
)
...
...
test_
peer
.c
→
test_
node
.c
View file @
b98eedcb
...
@@ -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
));
}
}
test_server.c
View file @
b98eedcb
...
@@ -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_
peer
s(r));
CuAssertTrue(tc, 0 == raft_get_num_
node
s(r));
raft_add_
peer
(r,(void*)1);
raft_add_
node
(r,(void*)1);
CuAssertTrue(tc, 1 == raft_get_num_
peer
s(r));
CuAssertTrue(tc, 1 == raft_get_num_
node
s(r));
}
}
void T_estRaft_dont_add_duplicate_
peer
s(CuTest * tc)
void T_estRaft_dont_add_duplicate_
node
s(CuTest * tc)
{
{
void *r;
void *r;
r = raft_new();
r = raft_new();
CuAssertTrue(tc, 0 == raft_get_num_
peer
s(r));
CuAssertTrue(tc, 0 == raft_get_num_
node
s(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_
peer
s(r));
CuAssertTrue(tc, 1 == raft_get_num_
node
s(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_
peer
s(r));
CuAssertTrue(tc, 1 == raft_get_num_
node
s(r));
raft_remove_
peer(r,peer
);
raft_remove_
node(r,node
);
CuAssertTrue(tc, 0 == raft_get_num_
peer
s(r));
CuAssertTrue(tc, 0 == raft_get_num_
node
s(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_n
peer
s
(
CuTest
*
tc
)
void
TestRaft_server_cfg_sets_n
node
s
(
CuTest
*
tc
)
{
{
void
*
r
;
void
*
r
;
/* 2
peer
s */
/* 2
node
s */
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_n
peer
s
(
r
));
CuAssertTrue
(
tc
,
2
==
raft_get_n
node
s
(
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
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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
,
1
00
);
raft_periodic
(
r
,
9
00
);
CuAssertTrue
(
tc
,
1
00
==
raft_get_timeout_elapsed
(
r
));
CuAssertTrue
(
tc
,
9
00
==
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_function
s_t
funcs
=
{
raft_
cb
s_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
peer
s = 2 vote requests */
/* 2
node
s = 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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_n
peer
s
(
r
));
CuAssertTrue
(
tc
,
5
==
raft_get_n
node
s
(
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
msg_requestvote_t
*
rv
;
msg_requestvote_t
*
rv
;
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_n
peer
s
(
r
);
i
++
)
for
(
i
=
0
;
i
<
raft_get_n
node
s
(
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_function
s_t
funcs
=
{
raft_
cb
s_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
peer
s */
/* receive appendentries messages for both
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
msg_appendentries_response_t
aer
;
msg_appendentries_response_t
aer
;
/* 2
peer
s */
/* 2
node
s */
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_function
s_t
funcs
=
{
raft_
cb
s_t
funcs
=
{
.
send
=
sender_send
,
.
send
=
sender_send
,
.
log
=
NULL
.
log
=
NULL
};
};
/* 2
peer
s */
/* 2
node
s */
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
);
...
...
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