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
9caa7c5a
Commit
9caa7c5a
authored
Oct 24, 2013
by
willem
Browse files
New tests
parent
03aa7488
Changes
3
Hide whitespace changes
Inline
Side-by-side
raft.h
View file @
9caa7c5a
...
@@ -14,27 +14,6 @@ typedef struct {
...
@@ -14,27 +14,6 @@ typedef struct {
void
*
udata_address
;
void
*
udata_address
;
}
raft_peer_configuration_t
;
}
raft_peer_configuration_t
;
#if 0
typedef struct {
/* -1 uses implementation default */
int election_timeout;
/* -1 uses implementation default */
int request_timeout;
/* Terminated by udata_address being NULL */
raft_peer_configuration_t *peers;
} raft_configuration_t;
#endif
/* messages */
#if 0
enum {
MSG_RequestVote,
MSG_RequestVoteResponse,
MSG_AppendEntries,
MSG_AppendEntriesResponse
};
#endif
typedef
struct
{
typedef
struct
{
/* term candidate's term */
/* term candidate's term */
int
term
;
int
term
;
...
@@ -49,12 +28,22 @@ typedef struct {
...
@@ -49,12 +28,22 @@ typedef struct {
int
last_log_term
;
int
last_log_term
;
}
msg_requestvote_t
;
}
msg_requestvote_t
;
/**
* every server must send commands in this format */
typedef
struct
{
typedef
struct
{
unsigned
int
id
;
unsigned
int
id
;
unsigned
char
*
data
;
unsigned
char
*
data
;
unsigned
int
len
;
unsigned
int
len
;
}
msg_command_t
;
}
msg_command_t
;
typedef
struct
{
unsigned
int
term
;
unsigned
int
id
;
unsigned
char
*
data
;
unsigned
int
len
;
}
raft_command_t
;
typedef
struct
{
typedef
struct
{
unsigned
int
id
;
unsigned
int
id
;
int
was_committed
;
int
was_committed
;
...
@@ -74,7 +63,7 @@ typedef struct {
...
@@ -74,7 +63,7 @@ typedef struct {
int
prev_log_index
;
int
prev_log_index
;
int
prev_log_term
;
int
prev_log_term
;
int
n_entries
;
int
n_entries
;
void
*
entries
;
msg_command_t
*
entries
;
int
leader_commit
;
int
leader_commit
;
}
msg_appendentries_t
;
}
msg_appendentries_t
;
...
@@ -124,7 +113,6 @@ typedef struct {
...
@@ -124,7 +113,6 @@ typedef struct {
func_applylog_f
applylog
;
func_applylog_f
applylog
;
}
raft_external_functions_t
;
}
raft_external_functions_t
;
typedef
struct
{
typedef
struct
{
int
pass
;
int
pass
;
// recv_appendentries_f recv_appendentries,
// recv_appendentries_f recv_appendentries,
...
@@ -195,7 +183,7 @@ int raft_send_requestvote(raft_server_t* me, int peer);
...
@@ -195,7 +183,7 @@ int raft_send_requestvote(raft_server_t* me, int peer);
void
raft_send_appendentries
(
raft_server_t
*
me
,
int
peer
);
void
raft_send_appendentries
(
raft_server_t
*
me
,
int
peer
);
int
raft_append_command
(
raft_server_t
*
me
,
unsigned
char
*
data
,
int
len
);
int
raft_append_command
(
raft_server_t
*
me
_
,
raft_command_t
*
c
);
void
raft_commit_command
(
raft_server_t
*
me
,
int
logIndex
);
void
raft_commit_command
(
raft_server_t
*
me
,
int
logIndex
);
...
...
raft_server.c
View file @
9caa7c5a
...
@@ -109,7 +109,6 @@ static long __peer_compare(
...
@@ -109,7 +109,6 @@ static long __peer_compare(
return
obj
-
other
;
return
obj
-
other
;
}
}
raft_server_t
*
raft_new
()
raft_server_t
*
raft_new
()
{
{
raft_server_private_t
*
me
;
raft_server_private_t
*
me
;
...
@@ -123,6 +122,7 @@ raft_server_t* raft_new()
...
@@ -123,6 +122,7 @@ raft_server_t* raft_new()
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
raft_set_request_timeout
((
void
*
)
me
,
500
);
raft_set_request_timeout
((
void
*
)
me
,
500
);
raft_set_election_timeout
((
void
*
)
me
,
1000
);
raft_set_election_timeout
((
void
*
)
me
,
1000
);
// me->log_map = hashmap_new(__log_hash, __log_compare, 100);
// me->peers = hashmap_new(__peer_hash, __peer_compare, 100);
// me->peers = hashmap_new(__peer_hash, __peer_compare, 100);
return
(
void
*
)
me
;
return
(
void
*
)
me
;
}
}
...
@@ -255,22 +255,47 @@ int raft_recv_appendentries(raft_server_t* me_, const int peer, msg_appendentrie
...
@@ -255,22 +255,47 @@ int raft_recv_appendentries(raft_server_t* me_, const int peer, msg_appendentrie
ae
->
prev_log_index
<
raft_get_current_index
(
me_
))
ae
->
prev_log_index
<
raft_get_current_index
(
me_
))
{
{
r
.
success
=
0
;
r
.
success
=
0
;
goto
done
;
}
}
else
if
(
raft_is_candidate
(
me_
))
{
{
if
(
raft_is_candidate
(
me_
))
raft_become_follower
(
me_
);
{
}
raft_become_follower
(
me_
);
}
if
(
raft_get_current_term
(
me_
)
<
ae
->
term
)
{
raft_set_current_term
(
me_
,
ae
->
term
);
}
int
i
;
for
(
i
=
0
;
i
<
ae
->
n_entries
;
i
++
)
{
msg_command_t
*
cmd
;
raft_command_t
*
c
;
cmd
=
&
ae
->
entries
[
i
];
c
=
malloc
(
sizeof
(
raft_command_t
));
c
->
term
=
raft_get_current_term
(
me_
);
c
->
len
=
cmd
->
len
;
c
->
id
=
cmd
->
id
;
c
->
data
=
malloc
(
cmd
->
len
);
memcpy
(
c
->
data
,
cmd
->
data
,
cmd
->
len
);
if
(
raft_get_current_term
(
me_
)
<
ae
->
term
)
if
(
0
==
raft_append_command
(
me_
,
c
)
)
{
{
raft_set_current_term
(
me_
,
ae
->
term
);
/* failure, we couldn't append it for some reason */
r
.
success
=
0
;
goto
done
;
}
}
r
.
success
=
1
;
}
}
r
.
success
=
1
;
done:
if
(
me
->
ext_func
&&
me
->
ext_func
->
send
)
if
(
me
->
ext_func
&&
me
->
ext_func
->
send
)
me
->
ext_func
->
send
(
me
->
caller
,
NULL
,
peer
,
(
void
*
)
&
r
,
me
->
ext_func
->
send
(
me
->
caller
,
NULL
,
peer
,
(
void
*
)
&
r
,
sizeof
(
msg_appendentries_response_t
));
sizeof
(
msg_appendentries_response_t
));
...
@@ -278,6 +303,13 @@ int raft_recv_appendentries(raft_server_t* me_, const int peer, msg_appendentrie
...
@@ -278,6 +303,13 @@ int raft_recv_appendentries(raft_server_t* me_, const int peer, msg_appendentrie
return
0
;
return
0
;
}
}
raft_command_t
*
raft_get_command_from_index
(
raft_server_t
*
me_
,
int
idx
)
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
NULL
;
}
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
peer
,
msg_appendentries_response_t
*
ae
)
int
raft_recv_appendentries_response
(
raft_server_t
*
me_
,
int
peer
,
msg_appendentries_response_t
*
ae
)
{
{
return
0
;
return
0
;
...
@@ -319,7 +351,6 @@ int raft_votes_is_majority(const int npeers, const int nvotes)
...
@@ -319,7 +351,6 @@ int raft_votes_is_majority(const int npeers, const int nvotes)
return
0
;
return
0
;
half
=
npeers
/
2
;
half
=
npeers
/
2
;
printf
(
"%d %d %d
\n
"
,
npeers
,
nvotes
,
half
+
1
);
return
half
+
1
<=
nvotes
;
return
half
+
1
<=
nvotes
;
}
}
...
@@ -417,9 +448,12 @@ int raft_recv_command(raft_server_t* me_, int peer, msg_command_t* cmd)
...
@@ -417,9 +448,12 @@ int raft_recv_command(raft_server_t* me_, int peer, msg_command_t* cmd)
return
0
;
return
0
;
}
}
/**
* @return number of items within log */
int
raft_get_log_count
(
raft_server_t
*
me_
)
int
raft_get_log_count
(
raft_server_t
*
me_
)
{
{
return
0
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
return
arrayqueue_count
(
me
->
log
);
}
}
int
raft_get_voted_for
(
raft_server_t
*
me_
)
int
raft_get_voted_for
(
raft_server_t
*
me_
)
...
@@ -485,17 +519,17 @@ int raft_send_requestvote(raft_server_t* me_, int peer)
...
@@ -485,17 +519,17 @@ int raft_send_requestvote(raft_server_t* me_, int peer)
return
0
;
return
0
;
}
}
int
raft_append_command
(
raft_server_t
*
me_
,
unsigned
char
*
data
,
int
len
)
/**
* Appends command using the current term.
* Note: we make the assumption that current term is up-to-date
* @return 0 if unsuccessful */
int
raft_append_command
(
raft_server_t
*
me_
,
raft_command_t
*
c
)
{
{
raft_server_private_t
*
me
=
(
void
*
)
me_
;
raft_server_private_t
*
me
=
(
void
*
)
me_
;
char
*
d
;
arrayqueue_offer
(
me
->
log
,
c
);
d
=
malloc
(
len
);
memcpy
(
d
,
data
,
len
);
arrayqueue_offer
(
me
->
log
,
d
);
me
->
current_index
+=
1
;
me
->
current_index
+=
1
;
return
0
;
return
1
;
}
}
void
raft_set_commit_index
(
raft_server_t
*
me_
,
int
commit_idx
)
void
raft_set_commit_index
(
raft_server_t
*
me_
,
int
commit_idx
)
...
...
test_server.c
View file @
9caa7c5a
...
@@ -117,14 +117,89 @@ void TestRaft_server_starts_with_request_timeout_of_500ms(CuTest * tc)
...
@@ -117,14 +117,89 @@ void TestRaft_server_starts_with_request_timeout_of_500ms(CuTest * tc)
CuAssertTrue
(
tc
,
500
==
raft_get_request_timeout
(
r
));
CuAssertTrue
(
tc
,
500
==
raft_get_request_timeout
(
r
));
}
}
void
TestRaft_server_increases_logindex
_when_command_appended
(
CuTest
*
tc
)
void
TestRaft_server_
command_append_
increases_logindex
(
CuTest
*
tc
)
{
{
void
*
r
;
void
*
r
;
raft_command_t
cmd
;
char
*
str
=
"aaa"
;
cmd
.
data
=
str
;
cmd
.
len
=
3
;
cmd
.
id
=
0
;
cmd
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_index
(
r
));
raft_append_command
(
r
,
&
cmd
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_index
(
r
));
}
void
TestRaft_server_append_command_means_command_gets_current_term
(
CuTest
*
tc
)
{
void
*
r
;
raft_command_t
cmd
;
char
*
str
=
"aaa"
;
cmd
.
data
=
str
;
cmd
.
len
=
3
;
cmd
.
id
=
0
;
cmd
.
term
=
1
;
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_index
(
r
));
raft_append_command
(
r
,
&
cmd
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_index
(
r
));
}
void
TestRaft_server_append_command_not_sucessful_if_command_with_id_already_appended
(
CuTest
*
tc
)
{
void
*
r
;
raft_command_t
cmd
;
char
*
str
=
"aaa"
;
cmd
.
data
=
str
;
cmd
.
len
=
3
;
cmd
.
id
=
0
;
cmd
.
term
=
1
;
r
=
raft_new
();
r
=
raft_new
();
CuAssertTrue
(
tc
,
0
==
raft_get_current_index
(
r
));
CuAssertTrue
(
tc
,
0
==
raft_get_current_index
(
r
));
raft_append_command
(
r
,
"aaa"
,
3
);
raft_append_command
(
r
,
&
cmd
);
raft_append_command
(
r
,
&
cmd
);
CuAssertTrue
(
tc
,
1
==
raft_get_current_index
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_current_index
(
r
));
/* different ID so we can be successful */
cmd
.
id
=
1
;
raft_append_command
(
r
,
&
cmd
);
CuAssertTrue
(
tc
,
2
==
raft_get_current_index
(
r
));
}
void
TestRaft_server_command_is_retrieveable_using_index
(
CuTest
*
tc
)
{
void
*
r
;
raft_command_t
cmd
;
raft_command_t
*
cmd_appended
;
char
*
str
=
"aaa"
;
char
*
str2
=
"bbb"
;
cmd
.
term
=
1
;
r
=
raft_new
();
cmd
.
id
=
0
;
cmd
.
data
=
str
;
cmd
.
len
=
3
;
raft_append_command
(
r
,
&
cmd
);
/* different ID so we can be successful */
cmd
.
id
=
1
;
cmd
.
data
=
str2
;
cmd
.
len
=
3
;
raft_append_command
(
r
,
&
cmd
);
//CuAssertTrue(tc, (cmd_appended = raft_get_command_from_index(r,1)));
//CuAssertTrue(tc, !strncmp(cmd_appended->data,str2,3));
}
}
// If commitIndex > lastApplied: increment lastApplied, apply
// If commitIndex > lastApplied: increment lastApplied, apply
...
@@ -407,6 +482,62 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
...
@@ -407,6 +482,62 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
CuAssertTrue
(
tc
,
2
==
raft_get_current_term
(
r
));
}
}
void
TestRaft_follower_doesnt_log_after_appendentry_if_no_entries_are_specified
(
CuTest
*
tc
)
{
void
*
r
;
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
/* appendentry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
/* log size s */
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
}
void
TestRaft_follower_increases_log_after_appendentry
(
CuTest
*
tc
)
{
void
*
r
;
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
/* appendentry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
/* log size s */
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
}
/* 5.3 */
/* 5.3 */
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev_log_index_which_matches_prev_log_term
(
CuTest
*
tc
)
void
TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev_log_index_which_matches_prev_log_term
(
CuTest
*
tc
)
{
{
...
@@ -471,8 +602,15 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
...
@@ -471,8 +602,15 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ae
.
prev_log_index
=
0
;
ae
.
prev_log_index
=
0
;
ae
.
prev_log_term
=
0
;
ae
.
prev_log_term
=
0
;
raft_command_t
cmd
;
char
*
str
=
"111"
;
/* increase log size */
/* increase log size */
raft_append_command
(
r
,
"111"
,
3
);
cmd
.
data
=
str
;
cmd
.
len
=
3
;
cmd
.
id
=
0
;
cmd
.
term
=
1
;
raft_append_command
(
r
,
&
cmd
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
/* pass a appendentry that is newer */
/* pass a appendentry that is newer */
...
@@ -591,34 +729,6 @@ void TestRaft_follower_recv_appendentries_set_commitindex_to_LeaderCommit(CuTest
...
@@ -591,34 +729,6 @@ void TestRaft_follower_recv_appendentries_set_commitindex_to_LeaderCommit(CuTest
CuAssertTrue
(
tc
,
3
==
raft_get_commit_index
(
r
));
CuAssertTrue
(
tc
,
3
==
raft_get_commit_index
(
r
));
}
}
void
TestRaft_follower_increases_log_after_appendentry
(
CuTest
*
tc
)
{
void
*
r
;
msg_appendentries_t
ae
;
/* 2 peers */
raft_peer_configuration_t
cfg
[]
=
{
{(
-
1
),(
void
*
)
1
},
{(
-
1
),(
void
*
)
2
},
{(
-
1
),
NULL
}};
/* appendentry */
memset
(
&
ae
,
0
,
sizeof
(
msg_appendentries_t
));
r
=
raft_new
();
raft_set_configuration
(
r
,
cfg
);
raft_set_state
(
r
,
RAFT_STATE_FOLLOWER
);
/* log size s */
CuAssertTrue
(
tc
,
0
==
raft_get_log_count
(
r
));
raft_recv_appendentries
(
r
,
1
,
&
ae
);
CuAssertTrue
(
tc
,
1
==
raft_get_log_count
(
r
));
}
void
TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones
(
CuTest
*
tc
)
void
TestRaft_follower_rejects_appendentries_if_idx_and_term_dont_match_preceding_ones
(
CuTest
*
tc
)
{
{
void
*
r
;
void
*
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