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
77cd6cfe
Commit
77cd6cfe
authored
Dec 09, 2013
by
willem
Browse files
Passing more tests
parent
4469906e
Changes
7
Hide 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