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
RedisLabs 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 {
void
*
udata_address
;
}
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
{
/* term candidate's term */
int
term
;
...
...
@@ -49,12 +28,22 @@ typedef struct {
int
last_log_term
;
}
msg_requestvote_t
;
/**
* every server must send commands in this format */
typedef
struct
{
unsigned
int
id
;
unsigned
char
*
data
;
unsigned
int
len
;
}
msg_command_t
;
typedef
struct
{
unsigned
int
term
;
unsigned
int
id
;
unsigned
char
*
data
;
unsigned
int
len
;
}
raft_command_t
;
typedef
struct
{
unsigned
int
id
;
int
was_committed
;
...
...
@@ -74,7 +63,7 @@ typedef struct {
int
prev_log_index
;
int
prev_log_term
;
int
n_entries
;
void
*
entries
;
msg_command_t
*
entries
;
int
leader_commit
;
}
msg_appendentries_t
;
...
...
@@ -124,7 +113,6 @@ typedef struct {
func_applylog_f
applylog
;
}
raft_external_functions_t
;
typedef
struct
{
int
pass
;
// recv_appendentries_f recv_appendentries,
...
...
@@ -195,7 +183,7 @@ int raft_send_requestvote(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
);
...
...
raft_server.c
View file @
9caa7c5a
...
...
@@ -109,7 +109,6 @@ static long __peer_compare(
return
obj
-
other
;
}
raft_server_t
*
raft_new
()
{
raft_server_private_t
*
me
;
...
...
@@ -123,6 +122,7 @@ raft_server_t* raft_new()
raft_set_state
((
void
*
)
me
,
RAFT_STATE_FOLLOWER
);
raft_set_request_timeout
((
void
*
)
me
,
500
);
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);
return
(
void
*
)
me
;
}
...
...
@@ -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_
))
{
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
)
me
->
ext_func
->
send
(
me
->
caller
,
NULL
,
peer
,
(
void
*
)
&
r
,
sizeof
(
msg_appendentries_response_t
));
...
...
@@ -278,6 +303,13 @@ int raft_recv_appendentries(raft_server_t* me_, const int peer, msg_appendentrie
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
)
{
return
0
;
...
...
@@ -319,7 +351,6 @@ int raft_votes_is_majority(const int npeers, const int nvotes)
return
0
;
half
=
npeers
/
2
;
printf
(
"%d %d %d
\n
"
,
npeers
,
nvotes
,
half
+
1
);
return
half
+
1
<=
nvotes
;
}
...
...
@@ -417,9 +448,12 @@ int raft_recv_command(raft_server_t* me_, int peer, msg_command_t* cmd)
return
0
;
}
/**
* @return number of items within log */
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_
)
...
...
@@ -485,17 +519,17 @@ int raft_send_requestvote(raft_server_t* me_, int peer)
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_
;
char
*
d
;
d
=
malloc
(
len
);
memcpy
(
d
,
data
,
len
);
arrayqueue_offer
(
me
->
log
,
d
);
arrayqueue_offer
(
me
->
log
,
c
);
me
->
current_index
+=
1
;
return
0
;
return
1
;
}
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)
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
;
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
();
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
));
/* 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
...
...
@@ -407,6 +482,62 @@ 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
*
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 */
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
ae
.
prev_log_index
=
0
;
ae
.
prev_log_term
=
0
;
raft_command_t
cmd
;
char
*
str
=
"111"
;
/* 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
));
/* pass a appendentry that is newer */
...
...
@@ -591,34 +729,6 @@ void TestRaft_follower_recv_appendentries_set_commitindex_to_LeaderCommit(CuTest
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
*
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