Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
Willemt Raft
Commits
77cd6cfe
Commit
77cd6cfe
authored
Dec 09, 2013
by
willem
Browse files
Passing more tests
parent
4469906e
Changes
7
Show whitespace changes
Inline
Side-by-side
Makefile
View file @
77cd6cfe
...
...
@@ -37,7 +37,7 @@ main_test.c:
fi
sh make-tests.sh
"test_*.c"
>
main_test.c
tests_main
:
main_test.c raft_server.c raft_log.c raft_candidate.c raft_follower.c raft_leader.c raft_peer.c test_server.c test_server_request_vote.c test_peer.c mock_send_functions.c CuTest.c
$(HASHMAP_DIR)/linked_list_hashmap.c
$(LLQUEUE_DIR)/linked_list_queue.c
$(AQUEUE_DIR)/arrayqueue.c
tests_main
:
main_test.c raft_server.c raft_log.c raft_candidate.c raft_follower.c raft_leader.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
$(CC)
$(CCFLAGS)
-o
$@
$^
./tests_main
...
...
raft.h
View file @
77cd6cfe
...
...
@@ -209,6 +209,7 @@ void raft_set_configuration(raft_server_t* me_, raft_peer_configuration_t* peers
int
raft_votes_is_majority
(
const
int
npeers
,
const
int
nvotes
);
void
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_log.c
View file @
77cd6cfe
...
...
@@ -15,8 +15,6 @@
#include <stdio.h>
#include <assert.h>
//#include "linked_list_hashmap.h"
#include "arrayqueue.h"
#include "raft.h"
#include "raft_log.h"
...
...
@@ -120,7 +118,11 @@ int raft_log_append_entry(raft_log_t* me_, raft_entry_t* c)
raft_entry_t
*
raft_log_get_from_idx
(
raft_log_t
*
me_
,
int
idx
)
{
raft_log_private_t
*
me
=
(
void
*
)
me_
;
int
i
=
(
me
->
front
+
idx
-
me
->
base_log_index
)
%
me
->
size
;
int
i
;
/* idx starts at 1 */
idx
-=
1
;
i
=
(
me
->
front
+
idx
-
me
->
base_log_index
)
%
me
->
size
;
return
&
me
->
entries
[
i
];
}
...
...
@@ -137,9 +139,12 @@ void raft_log_delete(raft_log_t* me_, int idx)
raft_log_private_t
*
me
=
(
void
*
)
me_
;
int
end
,
i
;
/* idx starts at 1 */
idx
-=
1
;
idx
-=
me
->
base_log_index
;
for
(
end
=
raft_log_count
(
me_
);
idx
<
end
;
idx
++
)
{
int
idx2
=
(
me
->
front
+
idx
-
me
->
base_log_index
)
%
me
->
size
;
me
->
back
--
;
me
->
count
--
;
}
...
...
@@ -164,9 +169,7 @@ void raft_log_delete(raft_log_t* me_, int idx)
/**
* Remove oldest entry
* @return oldest entry */
void
*
raft_log_poll
(
raft_log_t
*
me_
)
void
*
raft_log_poll
(
raft_log_t
*
me_
)
{
raft_log_private_t
*
me
=
(
void
*
)
me_
;
const
void
*
elem
;
...
...
@@ -180,11 +183,21 @@ void *raft_log_poll(
return
(
void
*
)
elem
;
}
/*
* @return youngest entry */
raft_entry_t
*
raft_log_peektail
(
raft_log_t
*
me_
)
{
raft_log_private_t
*
me
=
(
void
*
)
me_
;
const
void
*
elem
;
if
(
0
==
raft_log_count
(
me_
))
return
NULL
;
return
&
me
->
entries
[
me
->
back
];
}
/**
* Empty the queue. */
void
raft_log_empty
(
raft_log_t
*
me_
)
void
raft_log_empty
(
raft_log_t
*
me_
)
{
raft_log_private_t
*
me
=
(
void
*
)
me_
;
...
...
raft_log.h
View file @
77cd6cfe
...
...
@@ -9,3 +9,4 @@ int raft_log_count(raft_log_t* me_);
raft_entry_t
*
raft_log_get_from_idx
(
raft_log_t
*
me_
,
int
idx
);
raft_entry_t
*
raft_log_peektail
(
raft_log_t
*
me_
);
raft_peer.c
View file @
77cd6cfe
...
...
@@ -41,6 +41,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
typedef
struct
{
void
*
udata
;
int
next_idx
;
}
raft_peer_private_t
;
raft_peer_t
*
raft_peer_new
(
void
*
udata
)
...
...
@@ -58,10 +59,12 @@ int raft_peer_is_leader(raft_peer_t* me_)
int
raft_peer_get_next_index
(
raft_peer_t
*
me_
)
{
return
0
;
raft_peer_private_t
*
me
=
(
void
*
)
me_
;
return
me
->
next_idx
;
}
void
raft_peer_set_next_index
(
raft_peer_t
*
me_
,
int
nextIdx
)
{
raft_peer_private_t
*
me
=
(
void
*
)
me_
;
me
->
next_idx
=
nextIdx
;
}
raft_server.c
View file @
77cd6cfe
...
...
@@ -18,7 +18,6 @@
/* for varags */
#include <stdarg.h>
#include "linked_list_hashmap.h"
#include "raft.h"
#include "raft_log.h"
...
...
@@ -109,7 +108,7 @@ raft_server_t* raft_new()
if
(
!
(
me
=
calloc
(
1
,
sizeof
(
raft_server_private_t
))))
return
NULL
;
me
->
voted_for
=
-
1
;
me
->
current_idx
=
0
;
me
->
current_idx
=
1
;
me
->
timeout_elapased
=
0
;
me
->
log
=
raft_log_new
();
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
...
...
@@ -280,7 +279,7 @@ int raft_recv_appendentries(
#endif
if
(
-
1
!=
ae
->
prev_log_idx
)
if
(
0
!=
ae
->
prev_log_idx
)
{
raft_entry_t
*
e
;
...
...
@@ -299,11 +298,10 @@ int raft_recv_appendentries(
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
)))
if
((
e2
=
raft_get_entry_from_idx
(
me_
,
ae
->
prev_log_idx
+
1
)))
{
raft_log_delete
(
me
->
log
,
ae
->
prev_log_idx
+
1
);
raft_log_delete
(
me
->
log
,
ae
->
prev_log_idx
+
1
);
}
}
else
{
...
...
@@ -311,11 +309,21 @@ int raft_recv_appendentries(
assert
(
0
);
}
}
else
/* 5. If leaderCommit > commitIndex, set commitIndex =
min(leaderCommit, last log index) */
if
(
raft_get_commit_idx
(
me_
)
<
ae
->
leader_commit
)
{
raft_entry_t
*
e
=
raft_log_peektail
(
me
->
log
);
}
if
(
e
)
{
raft_set_commit_idx
(
me_
,
e
->
id
<
ae
->
leader_commit
?
e
->
id
:
ae
->
leader_commit
);
while
(
1
==
raft_apply_entry
(
me_
));
}
}
if
(
raft_is_candidate
(
me_
))
{
...
...
@@ -608,17 +616,20 @@ int raft_get_commit_idx(raft_server_t* me_)
}
/**
* Apply entry at lastApplied + 1 */
void
raft_apply_entry
(
raft_server_t
*
me_
)
* Apply entry at lastApplied + 1
* @return 1 if entry committed, 0 otherwise */
int
raft_apply_entry
(
raft_server_t
*
me_
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
if
(
me
->
last_applied_idx
==
raft_get_commit_idx
(
me_
))
return
;
return
0
;
me
->
last_applied_idx
++
;
// TODO: callback for state machine application goes here
return
1
;
}
void
raft_send_appendentries
(
raft_server_t
*
me_
,
int
peer
)
...
...
test_server.c
View file @
77cd6cfe
...
...
@@ -129,9 +129,9 @@ void TestRaft_server_entry_append_cant_append_if_id_is_zero(CuTest* tc)
ety
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_idx
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
0
==
raft_get_current_idx
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
}
void
TestRaft_server_entry_append_increases_logidx
(
CuTest
*
tc
)
...
...
@@ -146,9 +146,9 @@ void TestRaft_server_entry_append_increases_logidx(CuTest* tc)
ety
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
}
void
TestRaft_server_append_entry_means_entry_gets_current_term
(
CuTest
*
tc
)
...
...
@@ -163,9 +163,9 @@ void TestRaft_server_append_entry_means_entry_gets_current_term(CuTest* tc)
ety
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_idx
(
r
));
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
}
void
TestRaft_server_append_entry_not_sucessful_if_entry_with_id_already_appended
(
CuTest
*
tc
)
...
...
@@ -180,42 +180,44 @@ void TestRaft_server_append_entry_not_sucessful_if_entry_with_id_already_appende
ety
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_idx
(
r
));
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
));
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
/* different ID so we can be successful */
ety
.
id
=
2
;
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_idx
(
r
));
CuAssertTrue
(
tc
,
3
==
raft_get_current_idx
(
r
));
}
void
TestRaft_server_entry_is_retrieveable_using_idx
(
CuTest
*
tc
)
{
void
*
r
;
raft_entry_t
ety
;
raft_entry_t
e1
;
raft_entry_t
e2
;
raft_entry_t
*
ety_appended
;
char
*
str
=
"aaa"
;
char
*
str2
=
"bbb"
;
ety
.
term
=
1
;
r
=
raft_new
();
ety
.
id
=
1
;
ety
.
data
=
str
;
ety
.
len
=
3
;
raft_append_entry
(
r
,
&
ety
);
e1
.
term
=
1
;
e1
.
id
=
1
;
e1
.
data
=
str
;
e1
.
len
=
3
;
raft_append_entry
(
r
,
&
e1
);
/* different ID so we can be successful */
ety
.
id
=
2
;
ety
.
data
=
str2
;
ety
.
len
=
3
;
raft_append_entry
(
r
,
&
ety
);
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
1
)));
e2
.
term
=
1
;
e2
.
id
=
2
;
e2
.
data
=
str2
;
e2
.
len
=
3
;
raft_append_entry
(
r
,
&
e2
);
CuAssertTrue
(
tc
,
NULL
!=
(
ety_appended
=
raft_get_entry_from_idx
(
r
,
2
)));
printf
(
"retrieved: %.s %d
\n
"
,
3
,
(
char
*
)
ety_appended
->
data
,
ety_appended
->
id
);
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str2
,
3
));
}
...
...
@@ -542,7 +544,7 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
/* newer term for appendentry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
/* no prev log idx */
ae
.
prev_log_idx
=
-
1
;
ae
.
prev_log_idx
=
0
;
ae
.
term
=
2
;
/* appendentry has newer term, so we change our currentterm */
...
...
@@ -622,7 +624,7 @@ void TestRaft_follower_increases_log_after_appendentry(CuTest * tc)
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
/* first appendentries msg */
ae
.
prev_log_idx
=
-
1
;
ae
.
prev_log_idx
=
0
;
ae
.
leader_commit
=
5
;
/* include one entry */
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
...
...
@@ -695,7 +697,6 @@ 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
)
{
printf
(
"X
\n
"
);
void
*
r
;
void
*
sender
;
msg_appendentries_t
ae
;
...
...
@@ -739,7 +740,7 @@ 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
,
1
)));
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 */
...
...
@@ -750,7 +751,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ae
.
prev_log_idx
=
1
;
ae
.
prev_log_term
=
1
;
/* include one entry */
memset
(
&
ety
,
0
,
sizeof
(
msg_entry_t
));
memset
(
&
m
ety
,
0
,
sizeof
(
msg_entry_t
));
char
*
str3
=
"333"
;
mety
.
data
=
str3
;
mety
.
len
=
3
;
...
...
@@ -764,19 +765,17 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
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
,
str
2
,
3
));
CuAssertTrue
(
tc
,
!
strncmp
(
ety_appended
->
data
,
str
1
,
3
));
}
void
TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log
(
CuTest
*
tc
)
{
printf
(
"Y
\n
"
);
void
*
r
;
void
*
sender
;
raft_external_functions_t
funcs
=
{
.
send
=
sender_send
,
.
log
=
NULL
};
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
...
...
@@ -785,24 +784,31 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(CuT
{(
-
1
),
NULL
}};
/* appendentries has multiple entries */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
2
;
sender
=
sender_new
();
r
=
raft_new
();
sender
=
sender_new
();
raft_set_configuration
(
r
,
cfg
);
raft_set_current_term
(
r
,
1
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
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
);
e
[
0
].
id
=
1
;
e
[
1
].
id
=
2
;
ae
.
entries
=
e
;
ae
.
n_entries
=
2
;
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
0
)
;
//
msg
= sender_poll_msg(sender);
//
CuAssertTrue(tc, aer);
//
CuAssertTrue(tc, 1 ==
sender_msg_is_appendentries(msg)
);
//
CuAssertTrue(tc,
1
==
sender_msg_is_false(msg
));
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
CuAssertTrue
(
tc
,
2
==
raft_get_log_count
(
r
));
}
//If leaderCommit > commitidx, set commitidx =
...
...
@@ -815,7 +821,6 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t
.
send
=
sender_send
,
.
log
=
NULL
};
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
...
...
@@ -828,16 +833,36 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(CuTest * t
raft_set_configuration
(
r
,
cfg
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
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
);
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
);
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
ae
.
prev_log_idx
=
4
;
ae
.
prev_log_idx
=
3
;
ae
.
leader_commit
=
5
;
/* receipt of appendentries changes commit idx */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
/* set to 4 because prevLogIdx is lower */
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
/* set to 4 because commitIDX is lower */
CuAssertTrue
(
tc
,
4
==
raft_get_commit_idx
(
r
));
}
...
...
@@ -849,7 +874,6 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest *
.
send
=
sender_send
,
.
log
=
NULL
};
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
...
...
@@ -857,26 +881,46 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(CuTest *
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
sender
=
sender_new
();
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
);
raft_set_callbacks
(
r
,
&
funcs
,
sender
);
msg_appendentries_t
ae
;
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
);
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
);
/* receive an appendentry with commit */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
ae
.
term
=
1
;
ae
.
prev_log_term
=
1
;
ae
.
prev_log_idx
=
4
;
ae
.
prev_log_idx
=
3
;
ae
.
leader_commit
=
3
;
/* receipt of appendentries changes commit idx */
raft_recv_appendentries
(
r
,
1
,
&
ae
);
msg_appendentries_response_t
*
aer
;
aer
=
sender_poll_msg
(
sender
);
CuAssertTrue
(
tc
,
NULL
!=
aer
);
CuAssertTrue
(
tc
,
1
==
aer
->
success
);
/* set to 3 because leaderCommit is lower */
CuAssertTrue
(
tc
,
3
==
raft_get_commit_idx
(
r
));
}
void
TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones
(
CuTest
*
tc
)
#if 0
void T_estRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones(CuTest * tc)
{
void *r;
...
...
@@ -905,6 +949,7 @@ void TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_precedin
raft_recv_appendentries(r,1,&ae);
CuAssertTrue(tc, 1 == raft_get_log_count(r));
}
#endif
#if 0
void T_estRaft_follower_resends_entry_if_request_from_leader_timesout(CuTest * tc)
...
...
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