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
2a50ff78
Commit
2a50ff78
authored
Feb 01, 2015
by
Willem Thiart
Browse files
Linting; Fixed -Wunused-variable warnings
parent
9eacf4d0
Changes
5
Hide whitespace changes
Inline
Side-by-side
Makefile
View file @
2a50ff78
...
...
@@ -8,6 +8,7 @@ GCOV_CCFLAGS = -fprofile-arcs -ftest-coverage
SHELL
=
/bin/bash
CFLAGS
+=
-Iinclude
-Werror
-Werror
=
return
-type
-Werror
=
uninitialized
-Wcast-align
\
-Wno-pointer-sign
-fno-omit-frame-pointer
-fno-common
-fsigned-char
\
-Wunused-variable
\
$(GCOV_CCFLAGS)
-I
$(LLQUEUE_DIR)
-Iinclude
-g
-O2
-fPIC
UNAME
:=
$(
shell
uname
)
...
...
src/raft_log.c
View file @
2a50ff78
...
...
@@ -2,7 +2,7 @@
/**
* 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.
* found in the LICENSE file.
*
* @file
* @brief ADT for managing Raft log entries (aka entries)
...
...
@@ -24,13 +24,13 @@
typedef
struct
{
/* size of array */
int
size
;
int
size
;
/* the amount of elements in the array */
int
count
;
int
count
;
/* position of the queue */
int
front
,
back
;
int
front
,
back
;
/* we compact the log, and thus need to increment the base idx */
int
base_log_idx
;
...
...
@@ -40,7 +40,7 @@ typedef struct
static
void
__ensurecapacity
(
log_private_t
*
me
)
)
{
int
i
,
j
;
raft_entry_t
*
temp
;
...
...
@@ -48,7 +48,7 @@ static void __ensurecapacity(
if
(
me
->
count
<
me
->
size
)
return
;
temp
=
calloc
(
1
,
sizeof
(
raft_entry_t
)
*
me
->
size
*
2
);
temp
=
calloc
(
1
,
sizeof
(
raft_entry_t
)
*
me
->
size
*
2
);
for
(
i
=
0
,
j
=
me
->
front
;
i
<
me
->
count
;
i
++
,
j
++
)
{
...
...
@@ -70,11 +70,11 @@ log_t* log_new()
{
log_private_t
*
me
;
me
=
calloc
(
1
,
sizeof
(
log_private_t
));
me
=
calloc
(
1
,
sizeof
(
log_private_t
));
me
->
size
=
INITIAL_CAPACITY
;
me
->
count
=
0
;
me
->
back
=
in
(
me
)
->
front
=
0
;
me
->
entries
=
calloc
(
1
,
sizeof
(
raft_entry_t
)
*
me
->
size
);
me
->
entries
=
calloc
(
1
,
sizeof
(
raft_entry_t
)
*
me
->
size
);
return
(
void
*
)
me
;
}
...
...
@@ -90,7 +90,7 @@ int log_append_entry(log_t* me_, raft_entry_t* c)
// if (hashmap_get(me->log_map, (void*)c->id+1))
// 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
].
num_nodes
=
0
;
me
->
count
++
;
me
->
back
++
;
...
...
@@ -120,13 +120,13 @@ int log_count(log_t* me_)
void
log_delete
(
log_t
*
me_
,
int
idx
)
{
log_private_t
*
me
=
(
void
*
)
me_
;
int
end
,
i
;
int
end
;
/* idx starts at 1 */
idx
-=
1
;
idx
-=
me
->
base_log_idx
;
for
(
end
=
log_count
(
me_
);
idx
<
end
;
idx
++
)
for
(
end
=
log_count
(
me_
);
idx
<
end
;
idx
++
)
{
me
->
back
--
;
me
->
count
--
;
...
...
@@ -145,7 +145,7 @@ void log_delete(log_t* me_, int idx)
in(me)->back = in(me)->size;
elem = me->entries[in(me)->back];
return (void
*)
elem;
return (void*)elem;
#endif
}
...
...
@@ -160,22 +160,20 @@ void *log_poll(log_t * me_)
me
->
front
++
;
me
->
count
--
;
me
->
base_log_idx
++
;
return
(
void
*
)
elem
;
return
(
void
*
)
elem
;
}
raft_entry_t
*
log_peektail
(
log_t
*
me_
)
{
log_private_t
*
me
=
(
void
*
)
me_
;
const
void
*
elem
;
int
i
;
if
(
0
==
log_count
(
me_
))
return
NULL
;
if
(
0
==
me
->
back
)
return
&
me
->
entries
[
me
->
size
-
1
];
return
&
me
->
entries
[
me
->
size
-
1
];
else
return
&
me
->
entries
[
me
->
back
-
1
];
return
&
me
->
entries
[
me
->
back
-
1
];
}
void
log_empty
(
log_t
*
me_
)
...
...
@@ -197,12 +195,9 @@ void log_free(log_t * me_)
void
log_mark_node_has_committed
(
log_t
*
me_
,
int
idx
)
{
log_private_t
*
me
=
(
void
*
)
me_
;
raft_entry_t
*
e
;
if
((
e
=
log_get_from_idx
(
me_
,
idx
)))
{
if
((
e
=
log_get_from_idx
(
me_
,
idx
)))
e
->
num_nodes
+=
1
;
}
}
src/raft_server.c
View file @
2a50ff78
...
...
@@ -2,7 +2,7 @@
/**
* 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.
* found in the LICENSE file.
*
* @file
* @brief Implementation of a Raft server
...
...
@@ -25,15 +25,16 @@
static
void
__log
(
raft_server_t
*
me_
,
const
char
*
fmt
,
...)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
char
buf
[
1024
];
va_list
args
;
va_start
(
args
,
fmt
);
vsprintf
(
buf
,
fmt
,
args
);
#if 0 /* debugging */
raft_server_private_t* me = (void*)me_;
printf("%d: %s\n", me->nodeid, buf);
__FUNC_log(bto,src,buf);
__FUNC_log(bto,
src,
buf);
#endif
}
...
...
@@ -56,7 +57,7 @@ raft_server_t* raft_new()
}
void
raft_set_callbacks
(
raft_server_t
*
me_
,
raft_cbs_t
*
funcs
,
void
*
udata
)
raft_cbs_t
*
funcs
,
void
*
udata
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
...
...
@@ -77,7 +78,7 @@ void raft_election_start(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
__log
(
me_
,
"election starting: %d %d, term: %d"
,
me
->
election_timeout
,
me
->
timeout_elapsed
,
me
->
current_term
);
me
->
election_timeout
,
me
->
timeout_elapsed
,
me
->
current_term
);
raft_become_candidate
(
me_
);
}
...
...
@@ -89,13 +90,14 @@ void raft_become_leader(raft_server_t* me_)
__log
(
me_
,
"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
->
num_nodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
me
->
nodeid
==
i
)
continue
;
raft_node_t
*
p
=
raft_get_node
(
me_
,
i
);
raft_node_set_next_idx
(
p
,
raft_get_current_idx
(
me_
)
+
1
);
raft_node_set_next_idx
(
p
,
raft_get_current_idx
(
me_
)
+
1
);
raft_send_appendentries
(
me_
,
i
);
}
}
...
...
@@ -115,9 +117,10 @@ void raft_become_candidate(raft_server_t* me_)
/* we need a random factor here to prevent simultaneous candidates */
me
->
timeout_elapsed
=
rand
()
%
500
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_requestvote
(
me_
,
i
);
}
}
...
...
@@ -142,10 +145,8 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
{
case
RAFT_STATE_FOLLOWER
:
if
(
me
->
last_applied_idx
<
me
->
commit_idx
)
{
if
(
0
==
raft_apply_entry
(
me_
))
return
0
;
}
break
;
}
...
...
@@ -159,13 +160,9 @@ int raft_periodic(raft_server_t* me_, int msec_since_last_period)
me
->
timeout_elapsed
=
0
;
}
}
else
{
if
(
me
->
election_timeout
<=
me
->
timeout_elapsed
)
{
raft_election_start
(
me_
);
}
}
else
if
(
me
->
election_timeout
<=
me
->
timeout_elapsed
)
raft_election_start
(
me_
);
return
1
;
}
...
...
@@ -177,7 +174,7 @@ raft_entry_t* raft_get_entry_from_idx(raft_server_t* me_, int etyidx)
}
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
node
,
msg_appendentries_response_t
*
r
)
int
node
,
msg_appendentries_response_t
*
r
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_node_t
*
p
;
...
...
@@ -190,7 +187,7 @@ int raft_recv_appendentries_response(raft_server_t* me_,
{
int
i
;
for
(
i
=
r
->
first_idx
;
i
<=
r
->
current_idx
;
i
++
)
for
(
i
=
r
->
first_idx
;
i
<=
r
->
current_idx
;
i
++
)
log_mark_node_has_committed
(
me
->
log
,
i
);
while
(
1
)
...
...
@@ -202,12 +199,11 @@ int raft_recv_appendentries_response(raft_server_t* me_,
/* majority has this */
if
(
e
&&
me
->
num_nodes
/
2
<=
e
->
num_nodes
)
{
if
(
0
==
raft_apply_entry
(
me_
))
break
;
if
(
0
==
raft_apply_entry
(
me_
))
break
;
}
else
{
break
;
}
}
}
else
...
...
@@ -217,7 +213,7 @@ int raft_recv_appendentries_response(raft_server_t* me_,
assert
(
0
<=
raft_node_get_next_idx
(
p
));
// TODO does this have test coverage?
// TODO can jump back to where node is different instead of iterating
raft_node_set_next_idx
(
p
,
raft_node_get_next_idx
(
p
)
-
1
);
raft_node_set_next_idx
(
p
,
raft_node_get_next_idx
(
p
)
-
1
);
raft_send_appendentries
(
me_
,
node
);
}
...
...
@@ -225,9 +221,9 @@ int raft_recv_appendentries_response(raft_server_t* me_,
}
int
raft_recv_appendentries
(
raft_server_t
*
me_
,
const
int
node
,
msg_appendentries_t
*
ae
)
raft_server_t
*
me_
,
const
int
node
,
msg_appendentries_t
*
ae
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
msg_appendentries_response_t
r
;
...
...
@@ -252,7 +248,7 @@ int raft_recv_appendentries(
#if 0
if (-1 != ae->prev_log_idx &&
ae->prev_log_idx < raft_get_current_idx(me_))
ae->prev_log_idx < raft_get_current_idx(me_))
{
__log(me_, "AE prev_idx is less than current idx");
r.success = 0;
...
...
@@ -277,13 +273,11 @@ int raft_recv_appendentries(
}
/* 3. If an existing entry conflicts with a new one (same index
but different terms), delete the existing entry and all that
follow it (§5.3) */
but different terms), delete the existing entry and all that
follow it (§5.3) */
raft_entry_t
*
e2
;
if
((
e2
=
raft_get_entry_from_idx
(
me_
,
ae
->
prev_log_idx
+
1
)))
{
log_delete
(
me
->
log
,
ae
->
prev_log_idx
+
1
);
}
if
((
e2
=
raft_get_entry_from_idx
(
me_
,
ae
->
prev_log_idx
+
1
)))
log_delete
(
me
->
log
,
ae
->
prev_log_idx
+
1
);
}
else
{
...
...
@@ -303,8 +297,9 @@ int raft_recv_appendentries(
if
((
e
=
log_peektail
(
me
->
log
)))
{
raft_set_commit_idx
(
me_
,
e
->
id
<
ae
->
leader_commit
?
e
->
id
:
ae
->
leader_commit
);
while
(
1
==
raft_apply_entry
(
me_
));
e
->
id
:
ae
->
leader_commit
);
while
(
1
==
raft_apply_entry
(
me_
))
;
}
}
...
...
@@ -314,9 +309,9 @@ int raft_recv_appendentries(
raft_set_current_term
(
me_
,
ae
->
term
);
int
i
;
/* append all entries to log */
for
(
i
=
0
;
i
<
ae
->
n_entries
;
i
++
)
for
(
i
=
0
;
i
<
ae
->
n_entries
;
i
++
)
{
msg_entry_t
*
cmd
;
raft_entry_t
*
c
;
...
...
@@ -354,26 +349,22 @@ int raft_recv_requestvote(raft_server_t* me_, int node, msg_requestvote_t* vr)
msg_requestvote_response_t
r
;
if
(
raft_get_current_term
(
me_
)
<
vr
->
term
)
{
me
->
voted_for
=
-
1
;
}
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
;
}
else
{
raft_vote
(
me_
,
node
);
raft_vote
(
me_
,
node
);
r
.
vote_granted
=
1
;
}
__log
(
me_
,
"node requested vote: %d replying: %s"
,
node
,
r
.
vote_granted
==
1
?
"granted"
:
"not granted"
);
node
,
r
.
vote_granted
==
1
?
"granted"
:
"not granted"
);
r
.
term
=
raft_get_current_term
(
me_
);
if
(
me
->
cb
.
send_requestvote_response
)
...
...
@@ -393,12 +384,12 @@ int raft_votes_is_majority(const int num_nodes, const int nvotes)
}
int
raft_recv_requestvote_response
(
raft_server_t
*
me_
,
int
node
,
msg_requestvote_response_t
*
r
)
msg_requestvote_response_t
*
r
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
__log
(
me_
,
"node responded to requestvote: %d status: %s"
,
node
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
node
,
r
->
vote_granted
==
1
?
"granted"
:
"not granted"
);
if
(
raft_is_leader
(
me_
))
return
0
;
...
...
@@ -422,7 +413,7 @@ int raft_recv_requestvote_response(raft_server_t* me_, int node,
}
int
raft_send_entry_response
(
raft_server_t
*
me_
,
int
node
,
int
etyid
,
int
was_committed
)
int
node
,
int
etyid
,
int
was_committed
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
msg_entry_response_t
res
;
...
...
@@ -450,10 +441,11 @@ int raft_recv_entry(raft_server_t* me_, int node, msg_entry_t* e)
ety
.
len
=
e
->
len
;
res
=
raft_append_entry
(
me_
,
&
ety
);
raft_send_entry_response
(
me_
,
node
,
e
->
id
,
res
);
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_appendentries
(
me_
,
i
);
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_appendentries
(
me_
,
i
);
}
return
0
;
}
...
...
@@ -476,7 +468,7 @@ int raft_append_entry(raft_server_t* me_, raft_entry_t* c)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
if
(
1
==
log_append_entry
(
me
->
log
,
c
))
if
(
1
==
log_append_entry
(
me
->
log
,
c
))
{
me
->
current_idx
+=
1
;
return
1
;
...
...
@@ -489,7 +481,7 @@ int raft_apply_entry(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_entry_t
*
e
;
if
(
!
(
e
=
log_get_from_idx
(
me
->
log
,
me
->
last_applied_idx
+
1
)))
if
(
!
(
e
=
log_get_from_idx
(
me
->
log
,
me
->
last_applied_idx
+
1
)))
return
0
;
__log
(
me_
,
"applying log: %d"
,
me
->
last_applied_idx
);
...
...
@@ -529,26 +521,27 @@ void raft_send_appendentries_all(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
i
;
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
i
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
me
->
nodeid
==
i
)
continue
;
raft_send_appendentries
(
me_
,
i
);
}
}
void
raft_set_configuration
(
raft_server_t
*
me_
,
raft_node_configuration_t
*
nodes
,
int
my_idx
)
raft_node_configuration_t
*
nodes
,
int
my_idx
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
num_nodes
;
/* TODO: one memory allocation only please */
for
(
num_nodes
=
0
;
nodes
->
udata_address
;
nodes
++
)
for
(
num_nodes
=
0
;
nodes
->
udata_address
;
nodes
++
)
{
num_nodes
++
;
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
num_nodes
);
me
->
nodes
=
realloc
(
me
->
nodes
,
sizeof
(
raft_node_t
*
)
*
num_nodes
);
me
->
num_nodes
=
num_nodes
;
me
->
nodes
[
num_nodes
-
1
]
=
raft_node_new
(
nodes
->
udata_address
);
me
->
nodes
[
num_nodes
-
1
]
=
raft_node_new
(
nodes
->
udata_address
);
}
me
->
votes_for_me
=
calloc
(
num_nodes
,
sizeof
(
int
));
me
->
nodeid
=
my_idx
;
...
...
@@ -559,9 +552,10 @@ int raft_get_nvotes_for_me(raft_server_t* me_)
raft_server_private_t
*
me
=
(
void
*
)
me_
;
int
i
,
votes
;
for
(
i
=
0
,
votes
=
0
;
i
<
me
->
num_nodes
;
i
++
)
for
(
i
=
0
,
votes
=
0
;
i
<
me
->
num_nodes
;
i
++
)
{
if
(
me
->
nodeid
==
i
)
continue
;
if
(
me
->
nodeid
==
i
)
continue
;
if
(
1
==
me
->
votes_for_me
[
i
])
votes
+=
1
;
}
...
...
tests/test_log.c
View file @
2a50ff78
...
...
@@ -46,33 +46,33 @@ void TestLog_get_at_idx(CuTest * tc)
CuAssertTrue
(
tc
,
3
==
log_count
(
l
));
CuAssertTrue
(
tc
,
3
==
log_count
(
l
));
CuAssertTrue
(
tc
,
e2
.
id
==
log_get_from_idx
(
l
,
2
)
->
id
);
CuAssertTrue
(
tc
,
e2
.
id
==
log_get_from_idx
(
l
,
2
)
->
id
);
}
void
TestLog_get_at_idx_returns_null_where_out_of_bounds
(
CuTest
*
tc
)
{
void
*
l
;
raft_entry_t
e1
,
e2
,
e3
;
raft_entry_t
e1
;
l
=
log_new
();
e1
.
id
=
1
;
CuAssertTrue
(
tc
,
1
==
log_append_entry
(
l
,
&
e1
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
}
void
TestLog_mark_node_has_committed_adds_nodes
(
CuTest
*
tc
)
{
void
*
l
;
raft_entry_t
e1
,
e2
,
e3
;
raft_entry_t
e1
;
l
=
log_new
();
e1
.
id
=
1
;
log_append_entry
(
l
,
&
e1
);
CuAssertTrue
(
tc
,
0
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
CuAssertTrue
(
tc
,
0
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
log_mark_node_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
CuAssertTrue
(
tc
,
1
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
log_mark_node_has_committed
(
l
,
1
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
CuAssertTrue
(
tc
,
2
==
log_get_from_idx
(
l
,
1
)
->
num_nodes
);
}
void
TestLog_delete
(
CuTest
*
tc
)
...
...
@@ -89,15 +89,15 @@ void TestLog_delete(CuTest * tc)
CuAssertTrue
(
tc
,
1
==
log_append_entry
(
l
,
&
e3
));
CuAssertTrue
(
tc
,
3
==
log_count
(
l
));
log_delete
(
l
,
3
);
log_delete
(
l
,
3
);
CuAssertTrue
(
tc
,
2
==
log_count
(
l
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
3
));
log_delete
(
l
,
2
);
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
3
));
log_delete
(
l
,
2
);
CuAssertTrue
(
tc
,
1
==
log_count
(
l
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
log_delete
(
l
,
1
);
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
log_delete
(
l
,
1
);
CuAssertTrue
(
tc
,
0
==
log_count
(
l
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
1
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
1
));
}
void
TestLog_delete_onwards
(
CuTest
*
tc
)
...
...
@@ -115,11 +115,11 @@ void TestLog_delete_onwards(CuTest * tc)
CuAssertTrue
(
tc
,
3
==
log_count
(
l
));
/* even 3 gets deleted */
log_delete
(
l
,
2
);
log_delete
(
l
,
2
);
CuAssertTrue
(
tc
,
1
==
log_count
(
l
));
CuAssertTrue
(
tc
,
e1
.
id
==
log_get_from_idx
(
l
,
1
)
->
id
);
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
3
));
CuAssertTrue
(
tc
,
e1
.
id
==
log_get_from_idx
(
l
,
1
)
->
id
);
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
2
));
CuAssertTrue
(
tc
,
NULL
==
log_get_from_idx
(
l
,
3
));
}
void
TestLog_peektail
(
CuTest
*
tc
)
...
...
tests/test_server.c
View file @
2a50ff78
...
...
@@ -19,7 +19,7 @@ void TestRaft_server_voted_for_records_who_we_voted_for(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_vote
(
r
,
2
);
raft_vote
(
r
,
2
);
CuAssertTrue
(
tc
,
2
==
raft_get_voted_for
(
r
));
}
...
...
@@ -44,7 +44,7 @@ void TestRaft_server_set_currentterm_sets_term(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_set_current_term
(
r
,
5
);
raft_set_current_term
(
r
,
5
);
CuAssertTrue
(
tc
,
5
==
raft_get_current_term
(
r
));
}
...
...
@@ -53,9 +53,9 @@ void TestRaft_server_voting_results_in_voting(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_vote
(
r
,
1
);
raft_vote
(
r
,
1
);
CuAssertTrue
(
tc
,
1
==
raft_get_voted_for
(
r
));
raft_vote
(
r
,
9
);
raft_vote
(
r
,
9
);
CuAssertTrue
(
tc
,
9
==
raft_get_voted_for
(
r
));
}
...
...
@@ -64,7 +64,7 @@ void TestRaft_election_start_increments_term(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_set_current_term
(
r
,
1
);
raft_set_current_term
(
r
,
1
);
raft_election_start
(
r
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
}
...
...
@@ -74,7 +74,7 @@ void TestRaft_set_state(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
CuAssertTrue
(
tc
,
RAFT_STATE_LEADER
==
raft_get_state
(
r
));
}
...
...
@@ -115,7 +115,7 @@ void TestRaft_server_entry_append_cant_append_if_id_is_zero(CuTest* tc)
r
=
raft_new
();
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
}
...
...
@@ -132,7 +132,7 @@ void TestRaft_server_entry_append_increases_logidx(CuTest* tc)
r
=
raft_new
();
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
}
...
...
@@ -149,13 +149,15 @@ void TestRaft_server_append_entry_means_entry_gets_current_term(CuTest* tc)
r
=
raft_new
();
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
}
#if 0
/* TODO: no support for duplicate detection yet */
void T_estRaft_server_append_entry_not_sucessful_if_entry_with_id_already_appended(CuTest* tc)
void
T_estRaft_server_append_entry_not_sucessful_if_entry_with_id_already_appended(
CuTest* tc)
{
void *r;
raft_entry_t ety;
...
...
@@ -168,13 +170,13 @@ void T_estRaft_server_append_entry_not_sucessful_if_entry_with_id_already_append
r = raft_new();
CuAssertTrue(tc, 1 == raft_get_current_idx(r));
raft_append_entry(r,&ety);
raft_append_entry(r,&ety);
raft_append_entry(r,
&ety);
raft_append_entry(r,
&ety);
CuAssertTrue(tc, 2 == raft_get_current_idx(r));
/* different ID so we can be successful */
ety.id = 2;
raft_append_entry(r,&ety);
raft_append_entry(r,
&ety);
CuAssertTrue(tc, 3 == raft_get_current_idx(r));
}
#endif
...
...
@@ -194,28 +196,27 @@ void TestRaft_server_entry_is_retrieveable_using_idx(CuTest* tc)
e1
.
id
=
1
;
e1
.
data
=
str
;
e1
.
len
=
3
;
raft_append_entry
(
r
,
&
e1
);
raft_append_entry
(
r
,
&
e1
);
/* different ID so we can be successful */
e2
.
term
=
1
;
e2
.
id
=
2
;
e2
.
data
=
str2
;
e2
.
len
=
3
;
raft_append_entry
(
r
,
&
e2
);
raft_append_entry
(
r
,
&
e2
);
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
2
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str2
,
3
));
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
2
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str2
,
3
));
}
void
TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply
(
CuTest
*
tc
)
{
void
*
r
;
raft_entry_t
ety
;
raft_entry_t
*
ety_appended
;
char
*
str
=
"aaa"
;
r
=
raft_new
();
raft_set_commit_idx
(
r
,
0
);
raft_set_commit_idx
(
r
,
0
);
raft_set_last_applied_idx
(
r
,
0
);
raft_apply_entry
(
r
);
...
...
@@ -226,7 +227,7 @@ void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc)
ety
.
id
=
1
;
ety
.
data
=
str
;
ety
.
len
=
3
;
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
raft_apply_entry
(
r
);
CuAssertTrue
(
tc
,
1
==
raft_get_last_applied_idx
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_commit_idx
(
r
));
...
...
@@ -234,14 +235,15 @@ void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc)
/* If commitidx > lastApplied: increment lastApplied, apply log[lastApplied]
* to state machine (5.3) */
void
TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx
(
CuTest
*
tc
)
void
TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx
(
CuTest
*
tc
)
{
void
*
r
;
raft_entry_t
ety
;
r
=
raft_new
();
/* must be follower */
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
raft_set_current_term
(
r
,
1
);
raft_set_commit_idx
(
r
,
1
);
raft_set_last_applied_idx
(
r
,
0
);
...
...
@@ -251,10 +253,10 @@ void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx(CuTest*
ety
.
id
=
1
;
ety
.
data
=
"aaa"
;
ety
.
len
=
3
;
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
/* let time lapse */
raft_periodic
(
r
,
1
);
raft_periodic
(
r
,
1
);
CuAssertTrue
(
tc
,
0
!=
raft_get_last_applied_idx
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_last_applied_idx
(
r
));
}
...
...
@@ -263,19 +265,18 @@ void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc)
{
void
*
r
;
raft_entry_t
ety
;
raft_entry_t
*
ety_appended
;
char
*
str
=
"aaa"
;
ety
.
term
=
1
;
r
=
raft_new
();
raft_set_commit_idx
(
r
,
1
);
raft_set_commit_idx
(
r
,
1
);
raft_set_last_applied_idx
(
r
,
0
);
ety
.
id
=
1
;
ety
.
data
=
str
;
ety
.
len
=
3
;
raft_append_entry
(
r
,
&
ety
);
raft_append_entry
(
r
,
&
ety
);
raft_apply_entry
(
r
);
CuAssertTrue
(
tc
,
1
==
raft_get_last_applied_idx
(
r
));
}
...
...
@@ -289,14 +290,16 @@ void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc)
raft_set_election_timeout
(
r
,
1000
);
CuAssertTrue
(
tc
,
0
==
raft_get_timeout_elapsed
(
r
));
raft_periodic
(
r
,
0
);
raft_periodic
(
r
,
0
);
CuAssertTrue
(
tc
,
0
==
raft_get_timeout_elapsed
(
r
));
raft_periodic
(
r
,
100
);
raft_periodic
(
r
,
100
);
CuAssertTrue
(
tc
,
100
==
raft_get_timeout_elapsed
(
r
));
}
void
TestRaft_server_election_timeout_sets_to_zero_when_elapsed_time_greater_than_timeout
(
CuTest
*
tc
)
void
TestRaft_server_election_timeout_sets_to_zero_when_elapsed_time_greater_than_timeout
(
CuTest
*
tc
)
{
void
*
r
;
...
...
@@ -304,7 +307,7 @@ void TestRaft_server_election_timeout_sets_to_zero_when_elapsed_time_greater_tha
raft_set_election_timeout
(
r
,
1000
);
/* greater than 1000 */
raft_periodic
(
r
,
2000
);
raft_periodic
(
r
,
2000
);
/* less than 1000 as the timeout would be randomised */
CuAssertTrue
(
tc
,
raft_get_timeout_elapsed
(
r
)
<
1000
);
}
...
...
@@ -315,12 +318,13 @@ void TestRaft_server_cfg_sets_num_nodes(CuTest * tc)
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
CuAssertTrue
(
tc
,
2
==
raft_get_num_nodes
(
r
));
}
...
...
@@ -331,120 +335,125 @@ void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc)
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
CuAssertTrue
(
tc
,
NULL
!=
raft_get_node
(
r
,
0
));
CuAssertTrue
(
tc
,
NULL
!=
raft_get_node
(
r
,
1
));
CuAssertTrue
(
tc
,
NULL
==
raft_get_node
(
r
,
2
));
CuAssertTrue
(
tc
,
NULL
!=
raft_get_node
(
r
,
0
));
CuAssertTrue
(
tc
,
NULL
!=
raft_get_node
(
r
,
1
));
CuAssertTrue
(
tc
,
NULL
==
raft_get_node
(
r
,
2
));
}
/* If term > currentTerm, set currentTerm to term (step down if candidate or
* leader) */
void
TestRaft_votes_are_majority_is_true
(
CuTest
*
tc
)
)
{
/* 1 of 3 = lose */
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
3
,
1
));
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
3
,
1
));
/* 2 of 3 = win */
CuAssertTrue
(
tc
,
1
==
raft_votes_is_majority
(
3
,
2
));
CuAssertTrue
(
tc
,
1
==
raft_votes_is_majority
(
3
,
2
));
/* 2 of 5 = lose */
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
5
,
2
));
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
5
,
2
));
/* 3 of 5 = win */
CuAssertTrue
(
tc
,
1
==
raft_votes_is_majority
(
5
,
3
));
CuAssertTrue
(
tc
,
1
==
raft_votes_is_majority
(
5
,
3
));
/* 2 of 1?? This is an error */
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
1
,
2
));
CuAssertTrue
(
tc
,
0
==
raft_votes_is_majority
(
1
,
2
));
}
void
TestRaft_server_dont_increase_votes_for_me_when_receive_request_vote_response_is_not_granted
(
void
TestRaft_server_dont_increase_votes_for_me_when_receive_request_vote_response_is_not_granted
(
CuTest
*
tc
)
)
{
void
*
r
;
msg_requestvote_response_t
rvr
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
CuAssertTrue
(
tc
,
0
==
raft_get_nvotes_for_me
(
r
));
memset
(
&
rvr
,
0
,
sizeof
(
msg_requestvote_response_t
));
rvr
.
term
=
1
;
rvr
.
vote_granted
=
0
;
raft_recv_requestvote_response
(
r
,
1
,
&
rvr
);
raft_recv_requestvote_response
(
r
,
1
,
&
rvr
);
CuAssertTrue
(
tc
,
0
==
raft_get_nvotes_for_me
(
r
));
}
void
TestRaft_server_increase_votes_for_me_when_receive_request_vote_response
(
CuTest
*
tc
)
)
{
void
*
r
;
msg_requestvote_response_t
rvr
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
CuAssertTrue
(
tc
,
0
==
raft_get_nvotes_for_me
(
r
));
memset
(
&
rvr
,
0
,
sizeof
(
msg_requestvote_response_t
));
rvr
.
term
=
1
;
rvr
.
vote_granted
=
1
;
raft_recv_requestvote_response
(
r
,
1
,
&
rvr
);
raft_recv_requestvote_response
(
r
,
1
,
&
rvr
);
CuAssertTrue
(
tc
,
1
==
raft_get_nvotes_for_me
(
r
));
}
/* Reply false if term < currentTerm (5.1) */
void
TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term
(
CuTest
*
tc
)
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_requestvote_response
=
sender_requestvote_response
,
.
log
=
NULL
.
log
=
NULL
};
msg_requestvote_t
rv
;
msg_requestvote_response_t
*
rvr
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
sender
=
sender_new
(
NULL
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_current_term
(
r
,
2
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_current_term
(
r
,
2
);
/* term is less than current term */
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
rv
.
term
=
1
;
raft_recv_requestvote
(
r
,
1
,
&
rv
);
raft_recv_requestvote
(
r
,
1
,
&
rv
);
rvr
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
...
...
@@ -455,38 +464,38 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term
* least as up-to-date as local log, grant vote (5.2, 5.4) */
void
TestRaft_server_dont_grant_vote_if_we_didnt_vote_for_this_candidate
(
CuTest
*
tc
)
)
{
void
*
r
;
void
*
sender
;
void
*
msg
;
raft_cbs_t
funcs
=
{
.
send_requestvote_response
=
sender_requestvote_response
,
.
log
=
NULL
.
log
=
NULL
};
msg_requestvote_t
rv
;
msg_requestvote_response_t
*
rvr
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_vote
(
r
,
0
);
raft_vote
(
r
,
0
);
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
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_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
...
...
@@ -508,43 +517,46 @@ void TestRaft_follower_becomes_follower_clears_voted_for(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_vote
(
r
,
1
);
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 */
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
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
msg_appendentries_t
ae
;
msg_appendentries_response_t
*
aer
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
sender
=
sender_new
(
NULL
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
/* term is low */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
/* higher current term */
raft_set_current_term
(
r
,
5
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_set_current_term
(
r
,
5
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
/* response is false */
aer
=
sender_poll_msg_data
(
sender
);
...
...
@@ -553,7 +565,9 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt
}
/* TODO: check if test case is needed */
void
TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_currentterm
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_currentterm
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -562,31 +576,32 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
sender
=
sender_new
(
NULL
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
/* older currentterm */
raft_set_current_term
(
r
,
1
);
raft_set_current_term
(
r
,
1
);
/* newer term for appendentry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
/* no prev log idx */
ae
.
prev_log_idx
=
0
;
ae
.
term
=
2
;
/* 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_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
...
...
@@ -594,7 +609,8 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
}
void
TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified
(
CuTest
*
tc
)
void
TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified
(
CuTest
*
tc
)
{
void
*
r
;
...
...
@@ -602,27 +618,28 @@ void TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified(
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
/* log size s */
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
ae
.
prev_log_idx
=
4
;
ae
.
leader_commit
=
5
;
ae
.
n_entries
=
0
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
}
...
...
@@ -637,41 +654,42 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
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
);
/* log size s */
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
/* first appendentries msg */
ae
.
prev_log_idx
=
0
;
ae
.
leader_commit
=
5
;
/* include one entry */
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
ety
.
data
=
str
;
ety
.
len
=
3
;
ety
.
id
=
1
;
ae
.
entries
=
&
ety
;
ae
.
n_entries
=
1
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
aer
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
...
...
@@ -679,30 +697,32 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
}
/* 5.3 */
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev_log_idx_which_matches_prev_log_term
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev_log_idx_which_matches_prev_log_term
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
void
*
msg
;
msg_entry_t
ety
;
char
*
str
=
"aaa"
;
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
ae
;
msg_appendentries_response_t
*
aer
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
/* term is different from appendentries */
raft_set_current_term
(
r
,
2
);
...
...
@@ -711,13 +731,13 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
// TODO at log manually?
/* log idx that server doesn't have */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
2
;
ae
.
prev_log_idx
=
1
;
/* prev_log_term is less than current term (ie. 2) */
ae
.
prev_log_term
=
1
;
/* include one entry */
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
ety
.
data
=
str
;
ety
.
len
=
3
;
ety
.
id
=
1
;
...
...
@@ -725,7 +745,7 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
ae
.
n_entries
=
1
;
/* trigger reply */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
aer
=
sender_poll_msg_data
(
sender
);
/* reply is false */
...
...
@@ -734,7 +754,9 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
}
/* 5.3 */
void
TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -744,21 +766,22 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
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
);
raft_entry_t
ety
;
...
...
@@ -779,18 +802,18 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ety
.
term
=
1
;
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_log_count
(
r
));
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
2
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str2
,
3
));
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
2
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str2
,
3
));
/* pass a appendentry that is newer */
msg_entry_t
mety
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
2
;
ae
.
prev_log_idx
=
1
;
ae
.
prev_log_term
=
1
;
/* include one entry */
memset
(
&
mety
,
0
,
sizeof
(
msg_entry_t
));
memset
(
&
mety
,
0
,
sizeof
(
msg_entry_t
));
char
*
str3
=
"333"
;
mety
.
data
=
str3
;
mety
.
len
=
3
;
...
...
@@ -798,50 +821,52 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ae
.
entries
=
&
mety
;
ae
.
n_entries
=
1
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
aer
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
CuAssertTrue
(
tc
,
2
==
raft_get_log_count
(
r
));
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
1
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str1
,
3
));
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
1
)));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str1
,
3
));
}
void
TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
sender
=
sender_new
(
NULL
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_current_term
(
r
,
1
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_idx
=
0
;
ae
.
prev_log_term
=
1
;
/* include entries */
msg_entry_t
e
[
2
];
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
2
);
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
2
);
e
[
0
].
id
=
1
;
e
[
1
].
id
=
2
;
ae
.
entries
=
e
;
ae
.
n_entries
=
2
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg_data
(
sender
);
...
...
@@ -852,50 +877,52 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
/* If leaderCommit > commitidx, set commitidx =
* min(leaderCommit, last log idx) */
void
TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_idx
=
0
;
ae
.
prev_log_term
=
1
;
/* include entries */
msg_entry_t
e
[
4
];
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
4
);
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
4
);
e
[
0
].
id
=
1
;
e
[
1
].
id
=
2
;
e
[
2
].
id
=
3
;
e
[
3
].
id
=
4
;
ae
.
entries
=
e
;
ae
.
n_entries
=
4
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
ae
.
prev_log_idx
=
4
;
ae
.
leader_commit
=
5
;
/* receipt of appendentries changes commit idx */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg_data
(
sender
);
...
...
@@ -905,50 +932,52 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t
CuAssertTrue
(
tc
,
4
==
raft_get_commit_idx
(
r
));
}
void
TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_idx
=
0
;
ae
.
prev_log_term
=
1
;
/* include entries */
msg_entry_t
e
[
4
];
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
4
);
memset
(
&
e
,
0
,
sizeof
(
msg_entry_t
)
*
4
);
e
[
0
].
id
=
1
;
e
[
1
].
id
=
2
;
e
[
2
].
id
=
3
;
e
[
3
].
id
=
4
;
ae
.
entries
=
e
;
ae
.
n_entries
=
4
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
ae
.
prev_log_idx
=
3
;
ae
.
leader_commit
=
3
;
/* receipt of appendentries changes commit idx */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg_data
(
sender
);
...
...
@@ -958,22 +987,24 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest *
CuAssertTrue
(
tc
,
3
==
raft_get_commit_idx
(
r
));
}
void
TestRaft_follower_becomes_candidate_when_election_timeout_occurs
(
CuTest
*
tc
)
void
TestRaft_follower_becomes_candidate_when_election_timeout_occurs
(
CuTest
*
tc
)
{
void
*
r
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
r
=
raft_new
();
/* 1 second election timeout */
raft_set_election_timeout
(
r
,
1000
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* 1.001 seconds have passed */
raft_periodic
(
r
,
1001
);
...
...
@@ -983,20 +1014,22 @@ void TestRaft_follower_becomes_candidate_when_election_timeout_occurs(CuTest * t
}
/* Candidate 5.2 */
void
TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log
(
CuTest
*
tc
)
void
TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_requestvote_response
=
sender_requestvote_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_requestvote_t
rv
;
...
...
@@ -1004,23 +1037,23 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(CuTe
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* request vote */
/* 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
.
candidate_id
=
1
;
rv
.
last_log_idx
=
1
;
rv
.
last_log_term
=
1
;
/* server's term and idx are more up-to-date */
raft_set_current_term
(
r
,
1
);
raft_set_current_idx
(
r
,
2
);
raft_set_current_term
(
r
,
1
);
raft_set_current_idx
(
r
,
2
);
/* vote not granted */
raft_recv_requestvote
(
r
,
1
,
&
rv
);
raft_recv_requestvote
(
r
,
1
,
&
rv
);
rvr
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rvr
);
CuAssertTrue
(
tc
,
0
==
rvr
->
vote_granted
);
...
...
@@ -1078,7 +1111,8 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc)
CuAssertTrue
(
tc
,
raft_get_timeout_elapsed
(
r
)
<
900
);
}
void
TestRaft_follower_receiving_appendentries_resets_election_timeout
(
CuTest
*
tc
)
void
TestRaft_follower_receiving_appendentries_resets_election_timeout
(
CuTest
*
tc
)
{
void
*
r
;
...
...
@@ -1088,36 +1122,38 @@ void TestRaft_follower_receiving_appendentries_resets_election_timeout(CuTest *
raft_periodic
(
r
,
900
);
msg_appendentries_t
ae
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
0
==
raft_get_timeout_elapsed
(
r
));
}
/* Candidate 5.2 */
void
TestRaft_follower_becoming_candidate_requests_votes_from_other_servers
(
CuTest
*
tc
)
void
TestRaft_follower_becoming_candidate_requests_votes_from_other_servers
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_requestvote
=
sender_requestvote
,
.
log
=
NULL
.
log
=
NULL
};
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),(
void
*
)
3
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
(
void
*
)
3
},
{
(
-
1
),
NULL
}
};
msg_requestvote_t
*
rv
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* set term so we can check it gets included in the outbound message */
raft_set_current_term
(
r
,
2
);
raft_set_current_idx
(
r
,
5
);
raft_set_current_term
(
r
,
2
);
raft_set_current_idx
(
r
,
5
);
/* becoming candidate triggers vote requests */
raft_become_candidate
(
r
);
...
...
@@ -1134,7 +1170,8 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(CuTe
}
/* Candidate 5.2 */
void
TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election
(
CuTest
*
tc
)
void
TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -1144,29 +1181,30 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(C
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_requestvote_response_t
vr
;
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
vr
.
term
=
0
;
vr
.
vote_granted
=
1
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_election_timeout
(
r
,
1000
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_election_timeout
(
r
,
1000
);
/* server wants to be leader, so becomes candidate */
raft_become_candidate
(
r
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_term
(
r
));
/* clock over (ie. 1000 + 1), causing new election */
raft_periodic
(
r
,
1001
);
raft_periodic
(
r
,
1001
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
/* receiving this vote gives the server majority */
...
...
@@ -1185,21 +1223,22 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),(
void
*
)
3
},
{(
-
1
),(
void
*
)
4
},
{(
-
1
),(
void
*
)
5
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
(
void
*
)
3
},
{
(
-
1
),
(
void
*
)
4
},
{
(
-
1
),
(
void
*
)
5
},
{
(
-
1
),
NULL
}
};
msg_requestvote_response_t
vr
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
CuAssertTrue
(
tc
,
5
==
raft_get_num_nodes
(
r
));
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
/* vote for self */
raft_become_candidate
(
r
);
...
...
@@ -1207,49 +1246,50 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
CuAssertTrue
(
tc
,
1
==
raft_get_nvotes_for_me
(
r
));
/* a vote for us */
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
memset
(
&
vr
,
0
,
sizeof
(
msg_requestvote_response_t
));
vr
.
term
=
1
;
vr
.
vote_granted
=
1
;
/* 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
,
0
==
raft_is_leader
(
r
));
/* get another vote
* now has majority (ie. 3/5 votes) */
raft_recv_requestvote_response
(
r
,
2
,
&
vr
);
raft_recv_requestvote_response
(
r
,
2
,
&
vr
);
CuAssertTrue
(
tc
,
1
==
raft_is_leader
(
r
));
}
/* Candidate 5.2 */
void
TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted
(
CuTest
*
tc
)
void
TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
void
*
msg
;
raft_cbs_t
funcs
=
{
.
send_requestvote_response
=
sender_requestvote_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_requestvote_response_t
*
rvr
;
msg_requestvote_t
rv
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_vote
(
r
,
0
);
raft_vote
(
r
,
0
);
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
raft_recv_requestvote
(
r
,
1
,
&
rv
);
memset
(
&
rv
,
0
,
sizeof
(
msg_requestvote_t
));
raft_recv_requestvote
(
r
,
1
,
&
rv
);
/* we've vote already, so won't respond with a vote granted... */
rvr
=
sender_poll_msg_data
(
sender
);
...
...
@@ -1263,25 +1303,26 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc)
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_requestvote
=
sender_requestvote
,
.
log
=
NULL
.
log
=
NULL
};
msg_requestvote_t
*
rv
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_current_term
(
r
,
5
);
raft_set_current_idx
(
r
,
3
);
raft_send_requestvote
(
r
,
1
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_current_term
(
r
,
5
);
raft_set_current_idx
(
r
,
3
);
raft_send_requestvote
(
r
,
1
);
rv
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
rv
);
...
...
@@ -1290,40 +1331,43 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc)
}
/* Candidate 5.2 */
void
TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower
(
CuTest
*
tc
)
void
TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
void
*
msg
;
raft_cbs_t
funcs
=
{
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
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
));
/* receive recent appendentries */
msg_appendentries_t
ae
;
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
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
));
}
/* Candidate 5.2 */
void
TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_follower
(
CuTest
*
tc
)
void
TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_follower
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -1333,33 +1377,34 @@ void TestRaft_candidate_recv_appendentries_frm_invalid_leader_doesnt_result_in_f
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
ae
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* server's log is newer */
raft_set_current_term
(
r
,
1
);
raft_set_current_idx
(
r
,
2
);
raft_set_current_term
(
r
,
1
);
raft_set_current_idx
(
r
,
2
);
/* is a candidate */
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
CuAssertTrue
(
tc
,
0
==
raft_is_follower
(
r
));
/* invalid leader determined by "leaders" old log */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_idx
=
1
;
ae
.
prev_log_term
=
1
;
/* appendentry from invalid leader doesn't make candidate become follower */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
1
==
raft_is_candidate
(
r
));
}
...
...
@@ -1378,13 +1423,15 @@ void TestRaft_leader_becomes_leader_clears_voted_for(CuTest * tc)
void
*
r
;
r
=
raft_new
();
raft_vote
(
r
,
1
);
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
TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog_idx_plus_1
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -1394,57 +1441,59 @@ void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),(
void
*
)
3
},
{(
-
1
),
NULL
}};
msg_appendentries_t
*
ae
;
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
(
void
*
)
3
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* candidate to leader */
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_become_leader
(
r
);
int
i
;
for
(
i
=
0
;
i
<
raft_get_num_nodes
(
r
);
i
++
)
for
(
i
=
0
;
i
<
raft_get_num_nodes
(
r
);
i
++
)
{
if
(
i
==
0
)
continue
;
raft_node_t
*
p
=
raft_get_node
(
r
,
i
);
if
(
i
==
0
)
continue
;
raft_node_t
*
p
=
raft_get_node
(
r
,
i
);
CuAssertTrue
(
tc
,
raft_get_current_idx
(
r
)
+
1
==
raft_node_get_next_idx
(
p
));
raft_node_get_next_idx
(
p
));
}
}
/* 5.2 */
void
TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries
(
CuTest
*
tc
)
void
TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries
=
sender_appendentries
,
.
log
=
NULL
.
log
=
NULL
};
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),(
void
*
)
3
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
(
void
*
)
3
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
*
ae
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* candidate to leader */
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_set_state
(
r
,
RAFT_STATE_CANDIDATE
);
raft_become_leader
(
r
);
/* receive appendentries messages for both nodes */
...
...
@@ -1462,22 +1511,23 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
msg_entry_response_t
*
cr
;
raft_cbs_t
funcs
=
{
.
send_entries_response
=
sender_entries_response
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* I am the leader */
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
/* entry message */
...
...
@@ -1487,7 +1537,7 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
ety
.
len
=
strlen
(
"entry"
);
/* receive entry */
raft_recv_entry
(
r
,
1
,
&
ety
);
raft_recv_entry
(
r
,
1
,
&
ety
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
/* trigger response through commit */
...
...
@@ -1499,69 +1549,74 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
}
/* 5.3 */
void
TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx
(
CuTest
*
tc
)
void
TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries
=
sender_appendentries
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
*
ae
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* i'm leader */
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
void
*
p
;
p
=
raft_get_node
(
r
,
0
);
p
=
raft_get_node
(
r
,
0
);
raft_node_set_next_idx
(
p
,
4
);
/* receive appendentries messages */
raft_send_appendentries
(
r
,
0
);
raft_send_appendentries
(
r
,
0
);
ae
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
ae
);
}
/* 5.3 */
void
TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsistency
(
CuTest
*
tc
)
void
TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsistency
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries
=
sender_appendentries
,
.
log
=
NULL
.
log
=
NULL
};
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
*
ae
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
/* i'm leader */
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
/* receive appendentries messages */
raft_send_appendentries
(
r
,
0
);
raft_send_appendentries
(
r
,
0
);
ae
=
sender_poll_msg_data
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
ae
);
}
...
...
@@ -1576,9 +1631,10 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc)
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_entry_t
ety
;
ety
.
id
=
1
;
...
...
@@ -1586,11 +1642,11 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc)
ety
.
len
=
strlen
(
"entry"
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
raft_recv_entry
(
r
,
1
,
&
ety
);
raft_recv_entry
(
r
,
1
,
&
ety
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
}
...
...
@@ -1602,9 +1658,10 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc)
/* 2 nodes */
raft_node_configuration_t cfg[] = {
{(-1),(void*)1},
{(-1),(void*)2},
{(-1),NULL}};
{ (-1), (void*)1 },
{ (-1), (void*)2 },
{ (-1), NULL }
};
msg_entry_t ety;
ety.id = 1;
...
...
@@ -1612,46 +1669,49 @@ void T_estRaft_leader_doesnt_append_entry_if_unique_id_is_duplicate(CuTest * tc)
ety.len = strlen("entry");
r = raft_new();
raft_set_configuration(r,cfg,0);
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));
raft_recv_entry(r,1,&ety);
raft_recv_entry(r,
1,
&ety);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
raft_recv_entry(r,1,&ety);
raft_recv_entry(r,
1,
&ety);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
}
#endif
void
TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_one_newer_entry
(
CuTest
*
tc
)
void
TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_one_newer_entry
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
raft_cbs_t
funcs
=
{
.
send_appendentries
=
sender_appendentries
,
.
send_appendentries
=
sender_appendentries
,
.
send_appendentries_response
=
sender_appendentries_response
,
.
log
=
NULL
.
log
=
NULL
};
msg_appendentries_response_t
aer
;
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
/* I'm the leader */
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_current_term
(
r
,
1
);
raft_set_commit_idx
(
r
,
0
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_current_term
(
r
,
1
);
raft_set_commit_idx
(
r
,
0
);
/* the last applied idx will became 1, and then 2 */
raft_set_last_applied_idx
(
r
,
0
);
raft_set_last_applied_idx
(
r
,
0
);
/* append entries - we need two */
raft_entry_t
ety
;
...
...
@@ -1663,7 +1723,7 @@ void TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_on
ety
.
id
=
2
;
raft_append_entry
(
r
,
&
ety
);
memset
(
&
aer
,
0
,
sizeof
(
msg_appendentries_response_t
));
memset
(
&
aer
,
0
,
sizeof
(
msg_appendentries_response_t
));
/* FIRST entry log application */
/* send appendentries -
...
...
@@ -1675,8 +1735,8 @@ void TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_on
aer
.
success
=
1
;
aer
.
current_idx
=
1
;
aer
.
first_idx
=
1
;
raft_recv_appendentries_response
(
r
,
1
,
&
aer
);
raft_recv_appendentries_response
(
r
,
2
,
&
aer
);
raft_recv_appendentries_response
(
r
,
1
,
&
aer
);
raft_recv_appendentries_response
(
r
,
2
,
&
aer
);
/* leader will now have majority followers who have appended this log */
CuAssertTrue
(
tc
,
0
!=
raft_get_commit_idx
(
r
));
CuAssertTrue
(
tc
,
2
!=
raft_get_commit_idx
(
r
));
...
...
@@ -1693,14 +1753,15 @@ void TestRaft_leader_increase_commit_idx_when_majority_have_entry_and_atleast_on
aer
.
success
=
1
;
aer
.
current_idx
=
2
;
aer
.
first_idx
=
2
;
raft_recv_appendentries_response
(
r
,
1
,
&
aer
);
raft_recv_appendentries_response
(
r
,
2
,
&
aer
);
raft_recv_appendentries_response
(
r
,
1
,
&
aer
);
raft_recv_appendentries_response
(
r
,
2
,
&
aer
);
/* leader will now have majority followers who have appended this log */
CuAssertTrue
(
tc
,
2
==
raft_get_commit_idx
(
r
));
CuAssertTrue
(
tc
,
2
==
raft_get_last_applied_idx
(
r
));
}
void
TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself
(
CuTest
*
tc
)
void
TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself
(
CuTest
*
tc
)
{
void
*
r
;
void
*
sender
;
...
...
@@ -1710,26 +1771,27 @@ void TestRaft_leader_steps_down_if_received_appendentries_is_newer_than_itself(C
/* 2 nodes */
raft_node_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
{
(
-
1
),
(
void
*
)
1
},
{
(
-
1
),
(
void
*
)
2
},
{
(
-
1
),
NULL
}
};
msg_appendentries_t
ae
;
sender
=
sender_new
(
NULL
);
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_configuration
(
r
,
cfg
,
0
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_current_term
(
r
,
5
);
raft_set_current_idx
(
r
,
5
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
raft_set_state
(
r
,
RAFT_STATE_LEADER
);
raft_set_current_term
(
r
,
5
);
raft_set_current_idx
(
r
,
5
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
5
;
ae
.
prev_log_idx
=
6
;
ae
.
prev_log_term
=
5
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
1
==
raft_is_follower
(
r
));
}
...
...
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