Unverified Commit a634de6f authored by Ozan Tezcan's avatar Ozan Tezcan Committed by GitHub
Browse files

Add sanitizer support and fix leaks in tests (#167)

parent 75926627
...@@ -25,3 +25,19 @@ jobs: ...@@ -25,3 +25,19 @@ jobs:
make gcov make gcov
- name: Upload to codecov - name: Upload to codecov
uses: codecov/codecov-action@v2 uses: codecov/codecov-action@v2
address-sanitizer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: |
make tests SANITIZER=address
undefined-sanitizer:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run tests
run: |
make tests SANITIZER=undefined
...@@ -7,6 +7,9 @@ ...@@ -7,6 +7,9 @@
# Tests : # Tests :
# mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug # mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug
# make && make tests_full # make && make tests_full
# SANITIZER :
# mkdir build && cd build && cmake .. -DSANITIZER=address
# make && make check
project(raft C) project(raft C)
cmake_minimum_required(VERSION 3.7.2) cmake_minimum_required(VERSION 3.7.2)
...@@ -107,6 +110,25 @@ set(RAFT_SOURCE_FILES ...@@ -107,6 +110,25 @@ set(RAFT_SOURCE_FILES
src/raft_server_properties.c) src/raft_server_properties.c)
add_library(raft STATIC ${RAFT_SOURCE_FILES}) add_library(raft STATIC ${RAFT_SOURCE_FILES})
if (SANITIZER)
if ("${SANITIZER}" STREQUAL "address")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
add_link_options(-fsanitize=address)
elseif ("${SANITIZER}" STREQUAL "undefined")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
add_link_options(-fsanitize=undefined)
elseif ("${SANITIZER}" STREQUAL "thread")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
add_link_options(-fsanitize=thread)
else ()
message(FATAL_ERROR "Unknown sanitizer: ${SANITIZER}")
endif ()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-sanitize-recover=all -fno-omit-frame-pointer")
message(STATUS "Using sanitizer: ${SANITIZER}")
endif ()
target_compile_options(raft PRIVATE -g -Wall -Wextra -pedantic) target_compile_options(raft PRIVATE -g -Wall -Wextra -pedantic)
target_include_directories(raft PRIVATE include) target_include_directories(raft PRIVATE include)
......
...@@ -8,6 +8,28 @@ INC = -I include ...@@ -8,6 +8,28 @@ INC = -I include
GCOV_CFLAGS = -fprofile-arcs -ftest-coverage GCOV_CFLAGS = -fprofile-arcs -ftest-coverage
SHELL = /bin/bash SHELL = /bin/bash
CFLAGS += -Iinclude -fno-omit-frame-pointer -fno-common -fsigned-char -g -O2 -fPIC CFLAGS += -Iinclude -fno-omit-frame-pointer -fno-common -fsigned-char -g -O2 -fPIC
ifdef SANITIZER
ifeq ($(SANITIZER),address)
MALLOC = libc
CFLAGS += -fsanitize=address -fno-sanitize-recover=all -fno-omit-frame-pointer
LDFLAGS += -fsanitize=address
else
ifeq ($(SANITIZER),undefined)
MALLOC = libc
CFLAGS += -fsanitize=undefined -fno-sanitize-recover=all -fno-omit-frame-pointer
LDFLAGS += -fsanitize=undefined
else
ifeq ($(SANITIZER),thread)
CFLAGS += -fsanitize=thread -fno-sanitize-recover=all -fno-omit-frame-pointer
LDFLAGS += -fsanitize=thread
else
$(error "unknown sanitizer=${SANITIZER}")
endif
endif
endif
endif
ifeq ($(COVERAGE), 1) ifeq ($(COVERAGE), 1)
CFLAGS += $(GCOV_CFLAGS) CFLAGS += $(GCOV_CFLAGS)
TEST_CFLAGS = $(CFLAGS) TEST_CFLAGS = $(CFLAGS)
......
...@@ -269,6 +269,7 @@ int raft_log_poll(raft_log_t *me, raft_entry_t **etyp) ...@@ -269,6 +269,7 @@ int raft_log_poll(raft_log_t *me, raft_entry_t **etyp)
raft_entry_release(me->entries[me->front]); raft_entry_release(me->entries[me->front]);
me->entries[me->front] = NULL;
me->front++; me->front++;
me->front = me->front % me->size; me->front = me->front % me->size;
me->count--; me->count--;
......
...@@ -47,6 +47,12 @@ CuString* CuStringNew(void) ...@@ -47,6 +47,12 @@ CuString* CuStringNew(void)
return str; return str;
} }
void CuStringFree(CuString *cu)
{
free(cu->buffer);
free(cu);
}
void CuStringResize(CuString* str, int newSize) void CuStringResize(CuString* str, int newSize)
{ {
str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize); str->buffer = (char*) realloc(str->buffer, sizeof(char) * newSize);
...@@ -119,6 +125,12 @@ CuTest* CuTestNew(const char* name, TestFunction function) ...@@ -119,6 +125,12 @@ CuTest* CuTestNew(const char* name, TestFunction function)
return tc; return tc;
} }
void CuTestFree(CuTest *test)
{
free(test->name);
free(test);
}
void CuTestRun(CuTest* tc) void CuTestRun(CuTest* tc)
{ {
#if 0 /* debugging */ #if 0 /* debugging */
...@@ -236,6 +248,14 @@ CuSuite* CuSuiteNew(void) ...@@ -236,6 +248,14 @@ CuSuite* CuSuiteNew(void)
return testSuite; return testSuite;
} }
void CuSuiteFree(CuSuite *testSuite)
{
for (int i = 0; i < testSuite->count; i++) {
CuTestFree(testSuite->list[i]);
}
free(testSuite);
}
void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase) void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase)
{ {
assert(testSuite->count < MAX_TEST_CASES); assert(testSuite->count < MAX_TEST_CASES);
......
...@@ -24,6 +24,7 @@ typedef struct ...@@ -24,6 +24,7 @@ typedef struct
void CuStringInit(CuString* str); void CuStringInit(CuString* str);
CuString* CuStringNew(void); CuString* CuStringNew(void);
void CuStringFree(CuString *cu);
void CuStringRead(CuString* str, const char* path); void CuStringRead(CuString* str, const char* path);
void CuStringAppend(CuString* str, const char* text); void CuStringAppend(CuString* str, const char* text);
void CuStringAppendChar(CuString* str, char ch); void CuStringAppendChar(CuString* str, char ch);
...@@ -39,16 +40,17 @@ typedef void (*TestFunction)(CuTest *); ...@@ -39,16 +40,17 @@ typedef void (*TestFunction)(CuTest *);
struct CuTest struct CuTest
{ {
const char* name; char *name;
TestFunction function; TestFunction function;
int failed; int failed;
int ran; int ran;
const char* message; const char *message;
jmp_buf *jumpBuf; jmp_buf *jumpBuf;
}; };
void CuTestInit(CuTest* t, const char* name, TestFunction function); void CuTestInit(CuTest* t, const char* name, TestFunction function);
CuTest* CuTestNew(const char* name, TestFunction function); CuTest* CuTestNew(const char* name, TestFunction function);
void CuTestFree(CuTest *test);
void CuTestRun(CuTest* tc); void CuTestRun(CuTest* tc);
/* Internal versions of assert functions -- use the public versions */ /* Internal versions of assert functions -- use the public versions */
...@@ -104,6 +106,7 @@ typedef struct ...@@ -104,6 +106,7 @@ typedef struct
void CuSuiteInit(CuSuite* testSuite); void CuSuiteInit(CuSuite* testSuite);
CuSuite* CuSuiteNew(void); CuSuite* CuSuiteNew(void);
void CuSuiteFree(CuSuite *testSuite);
void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase); void CuSuiteAdd(CuSuite* testSuite, CuTest *testCase);
void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2); void CuSuiteAddSuite(CuSuite* testSuite, CuSuite* testSuite2);
void CuSuiteRun(CuSuite* testSuite); void CuSuiteRun(CuSuite* testSuite);
......
...@@ -3,11 +3,11 @@ ...@@ -3,11 +3,11 @@
static raft_entry_t *__MAKE_ENTRY(int id, raft_term_t term, const char *data) static raft_entry_t *__MAKE_ENTRY(int id, raft_term_t term, const char *data)
{ {
raft_entry_t *ety = raft_entry_new(data ? strlen(data) : 0); raft_entry_t *ety = raft_entry_new(data ? strlen(data) + 1 : 0);
ety->id = id; ety->id = id;
ety->term = term; ety->term = term;
if (data) { if (data) {
memcpy(ety->data, data, strlen(data)); memcpy(ety->data, data, strlen(data) + 1);
} }
return ety; return ety;
} }
...@@ -36,6 +36,7 @@ static void __RAFT_APPEND_ENTRY(void *r, int id, raft_term_t term, const char *d ...@@ -36,6 +36,7 @@ static void __RAFT_APPEND_ENTRY(void *r, int id, raft_term_t term, const char *d
{ {
raft_entry_t *e = __MAKE_ENTRY(id, term, data); raft_entry_t *e = __MAKE_ENTRY(id, term, data);
raft_append_entry(r, e); raft_append_entry(r, e);
raft_entry_release(e);
raft_node_set_match_idx(raft_get_my_node(r), raft_get_current_idx(r)); raft_node_set_match_idx(raft_get_my_node(r), raft_get_current_idx(r));
} }
...@@ -45,6 +46,7 @@ static void __RAFT_APPEND_ENTRIES_SEQ_ID(void *r, int count, int id, raft_term_t ...@@ -45,6 +46,7 @@ static void __RAFT_APPEND_ENTRIES_SEQ_ID(void *r, int count, int id, raft_term_t
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
raft_entry_t *e = __MAKE_ENTRY(id++, term, data); raft_entry_t *e = __MAKE_ENTRY(id++, term, data);
raft_append_entry(r, e); raft_append_entry(r, e);
raft_entry_release(e);
} }
} }
...@@ -54,6 +56,7 @@ static void __RAFT_APPEND_ENTRIES_SEQ_ID_TERM(void *r, int count, int id, raft_t ...@@ -54,6 +56,7 @@ static void __RAFT_APPEND_ENTRIES_SEQ_ID_TERM(void *r, int count, int id, raft_t
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
raft_entry_t *e = __MAKE_ENTRY(id++, term++, data); raft_entry_t *e = __MAKE_ENTRY(id++, term++, data);
raft_append_entry(r, e); raft_append_entry(r, e);
raft_entry_release(e);
} }
} }
......
...@@ -137,7 +137,9 @@ void* sender_poll_msg_data(void* s) ...@@ -137,7 +137,9 @@ void* sender_poll_msg_data(void* s)
{ {
sender_t* me = s; sender_t* me = s;
msg_t* msg = llqueue_poll(me->outbox); msg_t* msg = llqueue_poll(me->outbox);
return NULL != msg ? msg->data : NULL; void *data = msg ? msg->data : NULL;
free(msg);
return data;
} }
void sender_set_raft(void* s, void* r) void sender_set_raft(void* s, void* r)
...@@ -164,10 +166,15 @@ void sender_poll_msgs(void* s) ...@@ -164,10 +166,15 @@ void sender_poll_msgs(void* s)
{ {
case RAFT_APPENDENTRIES_REQ: case RAFT_APPENDENTRIES_REQ:
{ {
raft_appendentries_req_t *ae = m->data;
raft_appendentries_resp_t response; raft_appendentries_resp_t response;
raft_recv_appendentries(me->raft, m->sender, m->data, &response); raft_recv_appendentries(me->raft, m->sender, m->data, &response);
__append_msg(me, &response, RAFT_APPENDENTRIES_RESP, __append_msg(me, &response, RAFT_APPENDENTRIES_RESP,
sizeof(response), m->sender, me->raft); sizeof(response), m->sender, me->raft);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
free(ae->entries);
} }
break; break;
case RAFT_APPENDENTRIES_RESP: case RAFT_APPENDENTRIES_RESP:
...@@ -199,5 +206,8 @@ void sender_poll_msgs(void* s) ...@@ -199,5 +206,8 @@ void sender_poll_msgs(void* s)
#endif #endif
break; break;
} }
free(m->data);
free(m);
} }
} }
...@@ -59,9 +59,8 @@ static int __log_pop( ...@@ -59,9 +59,8 @@ static int __log_pop(
raft_index_t entry_idx raft_index_t entry_idx
) )
{ {
raft_entry_t* copy = malloc(sizeof(*entry)); raft_entry_hold(entry);
memcpy(copy, entry, sizeof(*entry)); llqueue_offer(user_data, entry);
llqueue_offer(user_data, copy);
return 0; return 0;
} }
...@@ -82,28 +81,20 @@ raft_log_cbs_t log_funcs = { ...@@ -82,28 +81,20 @@ raft_log_cbs_t log_funcs = {
.log_pop = __log_pop .log_pop = __log_pop
}; };
void* __set_up()
{
void* queue = llqueue_new();
void *r = raft_new();
raft_set_callbacks(r, &funcs, queue);
raft_log_set_callbacks(raft_get_log(r), &log_funcs, r);
return r;
}
void TestLog_new_is_empty(CuTest * tc) void TestLog_new_is_empty(CuTest * tc)
{ {
void *l; void *l;
l = raft_log_new(); l = raft_log_new();
CuAssertTrue(tc, 0 == raft_log_count(l)); CuAssertTrue(tc, 0 == raft_log_count(l));
raft_log_free(l);
} }
void TestLog_append_is_not_empty(CuTest * tc) void TestLog_append_is_not_empty(CuTest * tc)
{ {
void *l; void *l;
void *r = raft_new(); void *r = raft_new();
raft_entry_t *e;
l = raft_log_new(); l = raft_log_new();
raft_log_cbs_t funcs = { raft_log_cbs_t funcs = {
...@@ -112,19 +103,35 @@ void TestLog_append_is_not_empty(CuTest * tc) ...@@ -112,19 +103,35 @@ void TestLog_append_is_not_empty(CuTest * tc)
raft_log_set_callbacks(l, &funcs, r); raft_log_set_callbacks(l, &funcs, r);
__LOG_APPEND_ENTRY(l, 1, 0, NULL); __LOG_APPEND_ENTRY(l, 1, 0, NULL);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
raft_log_poll(l, &e);
raft_entry_release(e);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_get_at_idx(CuTest * tc) void TestLog_get_at_idx(CuTest * tc)
{ {
void *l; void *l;
raft_entry_t *e1, *e2, *e3;
l = raft_log_new(); l = raft_log_new();
__LOG_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL); __LOG_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL);
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
CuAssertIntEquals(tc, 1, raft_log_get_at_idx(l, 1)->id); e1 = raft_log_get_at_idx(l, 1);
CuAssertIntEquals(tc, 2, raft_log_get_at_idx(l, 2)->id); CuAssertIntEquals(tc, 1, e1->id);
CuAssertIntEquals(tc, 3, raft_log_get_at_idx(l, 3)->id); raft_entry_release(e1);
e2 = raft_log_get_at_idx(l, 2);
CuAssertIntEquals(tc, 2, e2->id);
raft_entry_release(e2);
e3 = raft_log_get_at_idx(l, 3);
CuAssertIntEquals(tc, 3, e3->id);
raft_entry_release(e3);
raft_log_free(l);
} }
void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc) void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc)
...@@ -137,11 +144,18 @@ void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc) ...@@ -137,11 +144,18 @@ void TestLog_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc)
__LOG_APPEND_ENTRY(l, 1, 0, NULL); __LOG_APPEND_ENTRY(l, 1, 0, NULL);
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2));
raft_entry_t *e;
raft_log_poll(l, &e);
raft_entry_release(e);
raft_log_free(l);
} }
void TestLog_delete(CuTest * tc) void TestLog_delete(CuTest * tc)
{ {
void *l; void *l;
raft_entry_t *e;
void* queue = llqueue_new(); void* queue = llqueue_new();
void *r = raft_new(); void *r = raft_new();
...@@ -161,19 +175,39 @@ void TestLog_delete(CuTest * tc) ...@@ -161,19 +175,39 @@ void TestLog_delete(CuTest * tc)
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l));
e = raft_log_get_at_idx(l, 3);
raft_log_delete(l, 3); raft_log_delete(l, 3);
CuAssertIntEquals(tc, 2, raft_log_count(l)); CuAssertIntEquals(tc, 2, raft_log_count(l));
CuAssertIntEquals(tc, 3, ((raft_entry_t*)llqueue_poll(queue))->id); raft_entry_release(e);
e = llqueue_poll(queue);
CuAssertIntEquals(tc, 3, e->id);
CuAssertIntEquals(tc, 2, raft_log_count(l)); CuAssertIntEquals(tc, 2, raft_log_count(l));
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3));
raft_entry_release(e);
e = raft_log_get_at_idx(l, 2);
raft_log_delete(l, 2); raft_log_delete(l, 2);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
raft_entry_release(e);
e = llqueue_poll(queue);
CuAssertIntEquals(tc, 2, e->id);
CuAssertIntEquals(tc, 1, raft_log_count(l));
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2));
raft_entry_release(e);
e = raft_log_get_at_idx(l, 1);
raft_log_delete(l, 1); raft_log_delete(l, 1);
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
raft_entry_release(e);
e = llqueue_poll(queue);
CuAssertIntEquals(tc, 1, e->id);
CuAssertIntEquals(tc, 0, raft_log_count(l));
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 1)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 1));
raft_entry_release(e);
raft_log_free(l);
llqueue_free(queue);
raft_destroy(r);
} }
void TestLog_delete_onwards(CuTest * tc) void TestLog_delete_onwards(CuTest * tc)
...@@ -196,11 +230,32 @@ void TestLog_delete_onwards(CuTest * tc) ...@@ -196,11 +230,32 @@ void TestLog_delete_onwards(CuTest * tc)
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
/* even 3 gets deleted */ /* even 3 gets deleted */
raft_entry_t *e2 = raft_log_get_at_idx(l, 2);
raft_entry_t *e3 = raft_log_get_at_idx(l, 3);
raft_log_delete(l, 2); raft_log_delete(l, 2);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
CuAssertIntEquals(tc, 1, raft_log_get_at_idx(l, 1)->id); CuAssertIntEquals(tc, 1, raft_log_get_at_idx(l, 1)->id);
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2));
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3));
raft_entry_release(e2);
raft_entry_release(e3);
raft_entry_t *e;
while (raft_log_poll(l, &e) == 0) {
raft_entry_release(e);
}
while ((e = llqueue_poll(queue)) != NULL) {
raft_entry_release(e);
}
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_delete_handles_log_pop_failure(CuTest * tc) void TestLog_delete_handles_log_pop_failure(CuTest * tc)
...@@ -227,6 +282,20 @@ void TestLog_delete_handles_log_pop_failure(CuTest * tc) ...@@ -227,6 +282,20 @@ void TestLog_delete_handles_log_pop_failure(CuTest * tc)
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
CuAssertIntEquals(tc, 3, ((raft_entry_t*) raft_log_peektail(l))->id); CuAssertIntEquals(tc, 3, ((raft_entry_t*) raft_log_peektail(l))->id);
raft_entry_t *e;
while (raft_log_poll(l, &e) == 0) {
raft_entry_release(e);
}
while ((e = llqueue_poll(queue)) != NULL) {
raft_entry_release(e);
}
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_delete_fails_for_idx_zero(CuTest * tc) void TestLog_delete_fails_for_idx_zero(CuTest * tc)
...@@ -247,6 +316,20 @@ void TestLog_delete_fails_for_idx_zero(CuTest * tc) ...@@ -247,6 +316,20 @@ void TestLog_delete_fails_for_idx_zero(CuTest * tc)
raft_log_set_callbacks(l, &log_funcs, r); raft_log_set_callbacks(l, &log_funcs, r);
__LOG_APPEND_ENTRIES_SEQ_ID(l, 4, 1, 0, NULL); __LOG_APPEND_ENTRIES_SEQ_ID(l, 4, 1, 0, NULL);
CuAssertIntEquals(tc, raft_log_delete(l, 0), -1); CuAssertIntEquals(tc, raft_log_delete(l, 0), -1);
raft_entry_t *e;
while (raft_log_poll(l, &e) == 0) {
raft_entry_release(e);
}
while ((e = llqueue_poll(queue)) != NULL) {
raft_entry_release(e);
}
raft_log_free(l);
llqueue_free(queue);
raft_destroy(r);
} }
void TestLog_poll(CuTest * tc) void TestLog_poll(CuTest * tc)
...@@ -288,6 +371,7 @@ void TestLog_poll(CuTest * tc) ...@@ -288,6 +371,7 @@ void TestLog_poll(CuTest * tc)
CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 2));
CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 3)); CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 3));
CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l));
raft_entry_release(ety);
/* remove 2nd */ /* remove 2nd */
ety = NULL; ety = NULL;
...@@ -299,6 +383,7 @@ void TestLog_poll(CuTest * tc) ...@@ -299,6 +383,7 @@ void TestLog_poll(CuTest * tc)
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2));
CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 3)); CuAssertTrue(tc, NULL != raft_log_get_at_idx(l, 3));
CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l));
raft_entry_release(ety);
/* remove 3rd */ /* remove 3rd */
ety = NULL; ety = NULL;
...@@ -310,6 +395,11 @@ void TestLog_poll(CuTest * tc) ...@@ -310,6 +395,11 @@ void TestLog_poll(CuTest * tc)
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 2));
CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3)); CuAssertTrue(tc, NULL == raft_log_get_at_idx(l, 3));
CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 3, raft_log_get_current_idx(l));
raft_entry_release(ety);
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_peektail(CuTest * tc) void TestLog_peektail(CuTest * tc)
...@@ -321,6 +411,14 @@ void TestLog_peektail(CuTest * tc) ...@@ -321,6 +411,14 @@ void TestLog_peektail(CuTest * tc)
__LOG_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL); __LOG_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL);
CuAssertIntEquals(tc, 3, raft_log_count(l)); CuAssertIntEquals(tc, 3, raft_log_count(l));
CuAssertIntEquals(tc, 3, raft_log_peektail(l)->id); CuAssertIntEquals(tc, 3, raft_log_peektail(l)->id);
raft_entry_t *e;
while (raft_log_poll(l, &e) == 0) {
raft_entry_release(e);
}
raft_log_free(l);
} }
#if 0 #if 0
...@@ -347,6 +445,8 @@ void TestLog_load_from_snapshot(CuTest * tc) ...@@ -347,6 +445,8 @@ void TestLog_load_from_snapshot(CuTest * tc)
CuAssertIntEquals(tc, 0, raft_log_load_from_snapshot(l, 10, 5)); CuAssertIntEquals(tc, 0, raft_log_load_from_snapshot(l, 10, 5));
CuAssertIntEquals(tc, 10, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 10, raft_log_get_current_idx(l));
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
raft_log_free(l);
} }
void TestLog_load_from_snapshot_clears_log(CuTest * tc) void TestLog_load_from_snapshot_clears_log(CuTest * tc)
...@@ -359,14 +459,31 @@ void TestLog_load_from_snapshot_clears_log(CuTest * tc) ...@@ -359,14 +459,31 @@ void TestLog_load_from_snapshot_clears_log(CuTest * tc)
CuAssertIntEquals(tc, 2, raft_log_count(l)); CuAssertIntEquals(tc, 2, raft_log_count(l));
CuAssertIntEquals(tc, 2, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 2, raft_log_get_current_idx(l));
raft_entry_t *e1 = raft_log_get_at_idx(l, 1);
raft_entry_t *e2 = raft_log_get_at_idx(l, 2);
CuAssertIntEquals(tc, 0, raft_log_load_from_snapshot(l, 10, 5)); CuAssertIntEquals(tc, 0, raft_log_load_from_snapshot(l, 10, 5));
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
CuAssertIntEquals(tc, 10, raft_log_get_current_idx(l)); CuAssertIntEquals(tc, 10, raft_log_get_current_idx(l));
raft_entry_release(e1);
raft_entry_release(e2);
raft_entry_t *e;
while (raft_log_poll(l, &e) == 0) {
raft_entry_release(e);
}
raft_log_free(l);
} }
void TestLog_front_pushes_across_boundary(CuTest * tc) void TestLog_front_pushes_across_boundary(CuTest * tc)
{ {
void* r = __set_up(); void* queue = llqueue_new();
void *r = raft_new();
raft_set_callbacks(r, &funcs, queue);
raft_log_set_callbacks(raft_get_log(r), &log_funcs, r);
void *l; void *l;
...@@ -378,9 +495,16 @@ void TestLog_front_pushes_across_boundary(CuTest * tc) ...@@ -378,9 +495,16 @@ void TestLog_front_pushes_across_boundary(CuTest * tc)
__LOG_APPEND_ENTRY(l, 1, 0, NULL); __LOG_APPEND_ENTRY(l, 1, 0, NULL);
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 1); CuAssertIntEquals(tc, ety->id, 1);
raft_entry_release(ety);
__LOG_APPEND_ENTRY(l, 2, 0, NULL); __LOG_APPEND_ENTRY(l, 2, 0, NULL);
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 2); CuAssertIntEquals(tc, ety->id, 2);
raft_entry_release(ety);
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuTest * tc) void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuTest * tc)
...@@ -397,6 +521,7 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT ...@@ -397,6 +521,7 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT
/* poll */ /* poll */
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 1); CuAssertIntEquals(tc, ety->id, 1);
raft_entry_release(ety);
/* append */ /* append */
__LOG_APPEND_ENTRY(l, 2, 0, NULL); __LOG_APPEND_ENTRY(l, 2, 0, NULL);
...@@ -404,6 +529,7 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT ...@@ -404,6 +529,7 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT
/* poll */ /* poll */
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 2); CuAssertIntEquals(tc, ety->id, 2);
raft_entry_release(ety);
/* append append */ /* append append */
__LOG_APPEND_ENTRY(l, 3, 0, NULL); __LOG_APPEND_ENTRY(l, 3, 0, NULL);
...@@ -412,6 +538,13 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT ...@@ -412,6 +538,13 @@ void TestLog_front_and_back_pushed_across_boundary_with_enlargement_required(CuT
/* poll */ /* poll */
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 3); CuAssertIntEquals(tc, ety->id, 3);
raft_entry_release(ety);
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 4);
raft_entry_release(ety);
raft_log_free(l);
} }
void TestLog_delete_after_polling(CuTest * tc) void TestLog_delete_after_polling(CuTest * tc)
...@@ -430,14 +563,19 @@ void TestLog_delete_after_polling(CuTest * tc) ...@@ -430,14 +563,19 @@ void TestLog_delete_after_polling(CuTest * tc)
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 1); CuAssertIntEquals(tc, ety->id, 1);
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
raft_entry_release(ety);
/* append */ /* append */
__LOG_APPEND_ENTRY(l, 2, 0, NULL); __LOG_APPEND_ENTRY(l, 2, 0, NULL);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
/* poll */ /* poll */
raft_entry_t *e = raft_log_get_at_idx(l, 2);
CuAssertIntEquals(tc, raft_log_delete(l, 1), 0); CuAssertIntEquals(tc, raft_log_delete(l, 1), 0);
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
raft_entry_release(e);
raft_log_free(l);
} }
void TestLog_delete_after_polling_from_double_append(CuTest * tc) void TestLog_delete_after_polling_from_double_append(CuTest * tc)
...@@ -466,14 +604,26 @@ void TestLog_delete_after_polling_from_double_append(CuTest * tc) ...@@ -466,14 +604,26 @@ void TestLog_delete_after_polling_from_double_append(CuTest * tc)
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 1); CuAssertIntEquals(tc, ety->id, 1);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
raft_entry_release(ety);
/* append */ /* append */
__LOG_APPEND_ENTRY(l, 3, 0, NULL); __LOG_APPEND_ENTRY(l, 3, 0, NULL);
CuAssertIntEquals(tc, 2, raft_log_count(l)); CuAssertIntEquals(tc, 2, raft_log_count(l));
/* poll */ /* poll */
CuAssertIntEquals(tc, raft_log_delete(l, 1), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 2);
CuAssertIntEquals(tc, 1, raft_log_count(l));
raft_entry_release(ety);
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 3);
CuAssertIntEquals(tc, 0, raft_log_count(l)); CuAssertIntEquals(tc, 0, raft_log_count(l));
raft_entry_release(ety);
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc) void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc)
...@@ -502,6 +652,7 @@ void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc) ...@@ -502,6 +652,7 @@ void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc)
CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0); CuAssertIntEquals(tc, raft_log_poll(l, (void *) &ety), 0);
CuAssertIntEquals(tc, ety->id, 1); CuAssertIntEquals(tc, ety->id, 1);
CuAssertIntEquals(tc, 1, raft_log_count(l)); CuAssertIntEquals(tc, 1, raft_log_count(l));
raft_entry_release(ety);
/* get off-by-one index */ /* get off-by-one index */
long n_etys; long n_etys;
...@@ -514,6 +665,15 @@ void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc) ...@@ -514,6 +665,15 @@ void TestLog_get_from_idx_with_base_off_by_one(CuTest * tc)
CuAssertPtrNotNull(tc, e); CuAssertPtrNotNull(tc, e);
CuAssertIntEquals(tc, n_etys, 1); CuAssertIntEquals(tc, n_etys, 1);
CuAssertIntEquals(tc, e[0]->id, 2); CuAssertIntEquals(tc, e[0]->id, 2);
raft_entry_t *entry;
while (raft_log_poll(l, &entry) == 0) {
raft_entry_release(entry);
}
llqueue_free(queue);
raft_log_free(l);
raft_destroy(r);
} }
int main(void) int main(void)
...@@ -543,5 +703,10 @@ int main(void) ...@@ -543,5 +703,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
...@@ -61,8 +61,8 @@ static const raft_log_impl_t *impl = &raft_log_internal_impl; ...@@ -61,8 +61,8 @@ static const raft_log_impl_t *impl = &raft_log_internal_impl;
static void __LOGIMPL_APPEND_ENTRY(void *l, int id, raft_term_t term, const char *data) static void __LOGIMPL_APPEND_ENTRY(void *l, int id, raft_term_t term, const char *data)
{ {
raft_entry_t *e = __MAKE_ENTRY(id, term, data); raft_entry_t *e = __MAKE_ENTRY(id, term, data);
impl->append(l, e); impl->append(l, e);
raft_entry_release(e);
} }
static void __LOGIMPL_APPEND_ENTRIES_SEQ_ID(void *l, int count, int id, raft_term_t term, const char *data) static void __LOGIMPL_APPEND_ENTRIES_SEQ_ID(void *l, int count, int id, raft_term_t term, const char *data)
...@@ -71,6 +71,7 @@ static void __LOGIMPL_APPEND_ENTRIES_SEQ_ID(void *l, int count, int id, raft_ter ...@@ -71,6 +71,7 @@ static void __LOGIMPL_APPEND_ENTRIES_SEQ_ID(void *l, int count, int id, raft_ter
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
raft_entry_t *e = __MAKE_ENTRY(id++, term, data); raft_entry_t *e = __MAKE_ENTRY(id++, term, data);
impl->append(l, e); impl->append(l, e);
raft_entry_release(e);
} }
} }
...@@ -81,29 +82,45 @@ void TestLogImpl_new_is_empty(CuTest * tc) ...@@ -81,29 +82,45 @@ void TestLogImpl_new_is_empty(CuTest * tc)
l = impl->init(NULL, NULL); l = impl->init(NULL, NULL);
CuAssertTrue(tc, 0 == impl->count(l)); CuAssertTrue(tc, 0 == impl->count(l));
CuAssertTrue(tc, 1 == impl->first_idx(l)); CuAssertTrue(tc, 1 == impl->first_idx(l));
impl->free(l);
} }
void TestLogImpl_append_is_not_empty(CuTest * tc) void TestLogImpl_append_is_not_empty(CuTest * tc)
{ {
void *l; void *l;
void *r = raft_new(); void *r = raft_new();
l = impl->init(r, NULL); l = impl->init(r, NULL);
__LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL); __LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL);
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
impl->free(l);
raft_destroy(r);
} }
void TestLogImpl_get_at_idx(CuTest * tc) void TestLogImpl_get_at_idx(CuTest * tc)
{ {
void *l; void *l;
raft_entry_t *e;
l = impl->init(NULL, NULL); l = impl->init(NULL, NULL);
__LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL); __LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL);
CuAssertIntEquals(tc, 3, impl->count(l)); CuAssertIntEquals(tc, 3, impl->count(l));
CuAssertIntEquals(tc, 1, impl->get(l, 1)->id);
CuAssertIntEquals(tc, 2, impl->get(l, 2)->id); e = impl->get(l, 1);
CuAssertIntEquals(tc, 3, impl->get(l, 3)->id); CuAssertIntEquals(tc, 1, e->id);
raft_entry_release(e);
e = impl->get(l, 2);
CuAssertIntEquals(tc, 2, e->id);
raft_entry_release(e);
e = impl->get(l, 3);
CuAssertIntEquals(tc, 3, e->id);
raft_entry_release(e);
impl->free(l);
} }
void TestLogImpl_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc) void TestLogImpl_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc)
...@@ -116,19 +133,21 @@ void TestLogImpl_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc) ...@@ -116,19 +133,21 @@ void TestLogImpl_get_at_idx_returns_null_where_out_of_bounds(CuTest * tc)
__LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL); __LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL);
CuAssertTrue(tc, NULL == impl->get(l, 2)); CuAssertTrue(tc, NULL == impl->get(l, 2));
impl->free(l);
} }
static void event_entry_enqueue(void *arg, raft_entry_t *e, raft_index_t idx) static void event_entry_enqueue(void *arg, raft_entry_t *e, raft_index_t idx)
{ {
raft_entry_t* copy = malloc(sizeof(*e)); raft_entry_hold(e);
memcpy(copy, e, sizeof(*e)); llqueue_offer(arg, e);
llqueue_offer(arg, copy);
} }
void TestLogImpl_pop(CuTest * tc) void TestLogImpl_pop(CuTest * tc)
{ {
void* queue = llqueue_new(); void* queue = llqueue_new();
void *l; void *l;
raft_entry_t *ety;
void *r = raft_new(); void *r = raft_new();
raft_cbs_t funcs = { raft_cbs_t funcs = {
...@@ -141,11 +160,16 @@ void TestLogImpl_pop(CuTest * tc) ...@@ -141,11 +160,16 @@ void TestLogImpl_pop(CuTest * tc)
CuAssertIntEquals(tc, 3, impl->count(l)); CuAssertIntEquals(tc, 3, impl->count(l));
CuAssertIntEquals(tc, 3, impl->current_idx(l)); CuAssertIntEquals(tc, 3, impl->current_idx(l));
event_entry_enqueue(queue, impl->get(l, 3), 3); ety = impl->get(l, 3);
event_entry_enqueue(queue, ety, 3);
impl->pop(l, 3); impl->pop(l, 3);
CuAssertIntEquals(tc, 2, impl->count(l)); CuAssertIntEquals(tc, 2, impl->count(l));
CuAssertIntEquals(tc, 3, ((raft_entry_t*)llqueue_poll(queue))->id); raft_entry_release(ety);
ety = llqueue_poll(queue);
CuAssertIntEquals(tc, 3, ety->id);
CuAssertTrue(tc, NULL == impl->get(l, 3)); CuAssertTrue(tc, NULL == impl->get(l, 3));
raft_entry_release(ety);
impl->pop(l, 2); impl->pop(l, 2);
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
...@@ -154,6 +178,10 @@ void TestLogImpl_pop(CuTest * tc) ...@@ -154,6 +178,10 @@ void TestLogImpl_pop(CuTest * tc)
impl->pop(l, 1); impl->pop(l, 1);
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
CuAssertTrue(tc, NULL == impl->get(l, 1)); CuAssertTrue(tc, NULL == impl->get(l, 1));
llqueue_free(queue);
impl->free(l);
raft_destroy(r);
} }
void TestLogImpl_pop_onwards(CuTest * tc) void TestLogImpl_pop_onwards(CuTest * tc)
...@@ -161,6 +189,7 @@ void TestLogImpl_pop_onwards(CuTest * tc) ...@@ -161,6 +189,7 @@ void TestLogImpl_pop_onwards(CuTest * tc)
void *r = raft_new(); void *r = raft_new();
void *l; void *l;
raft_entry_t *e;
l = impl->init(r, NULL); l = impl->init(r, NULL);
__LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL); __LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 3, 1, 0, NULL);
...@@ -169,9 +198,15 @@ void TestLogImpl_pop_onwards(CuTest * tc) ...@@ -169,9 +198,15 @@ void TestLogImpl_pop_onwards(CuTest * tc)
/* even 3 gets deleted */ /* even 3 gets deleted */
impl->pop(l, 2); impl->pop(l, 2);
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
CuAssertIntEquals(tc, 1, impl->get(l, 1)->id);
e = impl->get(l, 1);
CuAssertIntEquals(tc, 1, e->id);
CuAssertTrue(tc, NULL == impl->get(l, 2)); CuAssertTrue(tc, NULL == impl->get(l, 2));
CuAssertTrue(tc, NULL == impl->get(l, 3)); CuAssertTrue(tc, NULL == impl->get(l, 3));
raft_entry_release(e);
impl->free(l);
raft_destroy(r);
} }
...@@ -184,13 +219,17 @@ void TestLogImpl_pop_fails_for_idx_zero(CuTest * tc) ...@@ -184,13 +219,17 @@ void TestLogImpl_pop_fails_for_idx_zero(CuTest * tc)
l = impl->init(r, NULL); l = impl->init(r, NULL);
__LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 4, 1, 0, NULL); __LOGIMPL_APPEND_ENTRIES_SEQ_ID(l, 4, 1, 0, NULL);
CuAssertIntEquals(tc, impl->pop(l, 0), -1); CuAssertIntEquals(tc, impl->pop(l, 0), -1);
impl->free(l);
raft_destroy(r);
} }
void TestLogImpl_poll(CuTest * tc) void TestLogImpl_poll(CuTest * tc)
{ {
void *l;
void *r = raft_new(); void *r = raft_new();
raft_entry_t *e;
void *l;
l = impl->init(r, NULL); l = impl->init(r, NULL);
__LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL); __LOGIMPL_APPEND_ENTRY(l, 1, 0, NULL);
...@@ -203,38 +242,45 @@ void TestLogImpl_poll(CuTest * tc) ...@@ -203,38 +242,45 @@ void TestLogImpl_poll(CuTest * tc)
CuAssertIntEquals(tc, 3, impl->count(l)); CuAssertIntEquals(tc, 3, impl->count(l));
CuAssertIntEquals(tc, 3, impl->current_idx(l)); CuAssertIntEquals(tc, 3, impl->current_idx(l));
raft_entry_t *ety;
/* remove 1st */ /* remove 1st */
ety = NULL;
CuAssertIntEquals(tc, impl->poll(l, 2), 0); CuAssertIntEquals(tc, impl->poll(l, 2), 0);
CuAssertIntEquals(tc, 2, impl->count(l)); CuAssertIntEquals(tc, 2, impl->count(l));
CuAssertIntEquals(tc, 2, impl->first_idx(l)); CuAssertIntEquals(tc, 2, impl->first_idx(l));
CuAssertTrue(tc, NULL == impl->get(l, 1)); CuAssertTrue(tc, NULL == impl->get(l, 1));
CuAssertTrue(tc, NULL != impl->get(l, 2));
CuAssertIntEquals(tc, impl->get(l, 2)->id, 2); e = impl->get(l, 2);
CuAssertTrue(tc, NULL != impl->get(l, 3)); CuAssertTrue(tc, NULL != e);
CuAssertIntEquals(tc, impl->get(l, 3)->id, 3); CuAssertIntEquals(tc, e->id, 2);
raft_entry_release(e);
e = impl->get(l, 3);
CuAssertTrue(tc, NULL != e);
CuAssertIntEquals(tc, e->id, 3);
CuAssertIntEquals(tc, 3, impl->current_idx(l)); CuAssertIntEquals(tc, 3, impl->current_idx(l));
raft_entry_release(e);
/* remove 2nd */ /* remove 2nd */
ety = NULL;
CuAssertIntEquals(tc, impl->poll(l, 3), 0); CuAssertIntEquals(tc, impl->poll(l, 3), 0);
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
CuAssertTrue(tc, NULL == impl->get(l, 1)); CuAssertTrue(tc, NULL == impl->get(l, 1));
CuAssertTrue(tc, NULL == impl->get(l, 2)); CuAssertTrue(tc, NULL == impl->get(l, 2));
CuAssertTrue(tc, NULL != impl->get(l, 3));
CuAssertIntEquals(tc, impl->get(l, 3)->id, 3); e = impl->get(l, 3);
CuAssertTrue(tc, NULL != e);
CuAssertIntEquals(tc, e->id, 3);
CuAssertIntEquals(tc, 3, impl->current_idx(l)); CuAssertIntEquals(tc, 3, impl->current_idx(l));
raft_entry_release(e);
/* remove 3rd */ /* remove 3rd */
ety = NULL;
CuAssertIntEquals(tc, impl->poll(l, 4), 0); CuAssertIntEquals(tc, impl->poll(l, 4), 0);
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
CuAssertTrue(tc, NULL == impl->get(l, 1)); CuAssertTrue(tc, NULL == impl->get(l, 1));
CuAssertTrue(tc, NULL == impl->get(l, 2)); CuAssertTrue(tc, NULL == impl->get(l, 2));
CuAssertTrue(tc, NULL == impl->get(l, 3)); CuAssertTrue(tc, NULL == impl->get(l, 3));
CuAssertIntEquals(tc, 3, impl->current_idx(l)); CuAssertIntEquals(tc, 3, impl->current_idx(l));
impl->free(l);
raft_destroy(r);
} }
void TestLogImpl_reset_after_compaction(CuTest * tc) void TestLogImpl_reset_after_compaction(CuTest * tc)
...@@ -250,6 +296,8 @@ void TestLogImpl_reset_after_compaction(CuTest * tc) ...@@ -250,6 +296,8 @@ void TestLogImpl_reset_after_compaction(CuTest * tc)
/* Current index is 9 (first_idx - 1), but log is empty */ /* Current index is 9 (first_idx - 1), but log is empty */
CuAssertIntEquals(tc, 9, impl->current_idx(l)); CuAssertIntEquals(tc, 9, impl->current_idx(l));
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
impl->free(l);
} }
void TestLogImpl_load_from_snapshot_clears_log(CuTest * tc) void TestLogImpl_load_from_snapshot_clears_log(CuTest * tc)
...@@ -265,6 +313,8 @@ void TestLogImpl_load_from_snapshot_clears_log(CuTest * tc) ...@@ -265,6 +313,8 @@ void TestLogImpl_load_from_snapshot_clears_log(CuTest * tc)
impl->reset(l, 10, 1); impl->reset(l, 10, 1);
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
CuAssertIntEquals(tc, 9, impl->current_idx(l)); CuAssertIntEquals(tc, 9, impl->current_idx(l));
impl->free(l);
} }
void TestLogImpl_pop_after_polling(CuTest * tc) void TestLogImpl_pop_after_polling(CuTest * tc)
...@@ -294,12 +344,16 @@ void TestLogImpl_pop_after_polling(CuTest * tc) ...@@ -294,12 +344,16 @@ void TestLogImpl_pop_after_polling(CuTest * tc)
CuAssertIntEquals(tc, impl->pop(l, 1), 0); CuAssertIntEquals(tc, impl->pop(l, 1), 0);
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
CuAssertIntEquals(tc, 1, impl->current_idx(l)); CuAssertIntEquals(tc, 1, impl->current_idx(l));
impl->free(l);
} }
void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc) void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc)
{ {
void *r = raft_new();
void *l; void *l;
void *r = raft_new();
raft_entry_t *e;
l = impl->init(r, NULL); l = impl->init(r, NULL);
...@@ -309,8 +363,10 @@ void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc) ...@@ -309,8 +363,10 @@ void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc)
/* poll */ /* poll */
CuAssertIntEquals(tc, impl->poll(l, 2), 0); CuAssertIntEquals(tc, impl->poll(l, 2), 0);
CuAssertIntEquals(tc, impl->get(l, 2)->id, 2); e = impl->get(l, 2);
CuAssertIntEquals(tc, e->id, 2);
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
raft_entry_release(e);
/* append */ /* append */
__LOGIMPL_APPEND_ENTRY(l, 3, 0, NULL); __LOGIMPL_APPEND_ENTRY(l, 3, 0, NULL);
...@@ -319,6 +375,9 @@ void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc) ...@@ -319,6 +375,9 @@ void TestLogImpl_pop_after_polling_from_double_append(CuTest * tc)
/* pop */ /* pop */
CuAssertIntEquals(tc, impl->pop(l, 1), 0); CuAssertIntEquals(tc, impl->pop(l, 1), 0);
CuAssertIntEquals(tc, 0, impl->count(l)); CuAssertIntEquals(tc, 0, impl->count(l));
impl->free(l);
raft_destroy(r);
} }
void TestLogImpl_get_from_idx_with_base_off_by_one(CuTest * tc) void TestLogImpl_get_from_idx_with_base_off_by_one(CuTest * tc)
...@@ -338,12 +397,16 @@ void TestLogImpl_get_from_idx_with_base_off_by_one(CuTest * tc) ...@@ -338,12 +397,16 @@ void TestLogImpl_get_from_idx_with_base_off_by_one(CuTest * tc)
CuAssertIntEquals(tc, 1, impl->count(l)); CuAssertIntEquals(tc, 1, impl->count(l));
/* get off-by-one index */ /* get off-by-one index */
raft_entry_t *e[1]; raft_entry_t *e[1] = {NULL};
CuAssertIntEquals(tc, impl->get_batch(l, 1, 1, e), 0); CuAssertIntEquals(tc, impl->get_batch(l, 1, 1, e), 0);
/* now get the correct index */ /* now get the correct index */
CuAssertIntEquals(tc, impl->get_batch(l, 2, 1, e), 1); CuAssertIntEquals(tc, impl->get_batch(l, 2, 1, e), 1);
CuAssertIntEquals(tc, e[0]->id, 2); CuAssertIntEquals(tc, e[0]->id, 2);
raft_entry_release(e[0]);
impl->free(l);
raft_destroy(r);
} }
int main(void) int main(void)
...@@ -369,5 +432,10 @@ int main(void) ...@@ -369,5 +432,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
...@@ -15,6 +15,7 @@ void TestRaft_node_set_nextIdx(CuTest * tc) ...@@ -15,6 +15,7 @@ void TestRaft_node_set_nextIdx(CuTest * tc)
raft_node_t *p = raft_node_new((void *) 1, 1, 1); raft_node_t *p = raft_node_new((void *) 1, 1, 1);
raft_node_set_next_idx(p, 3); raft_node_set_next_idx(p, 3);
CuAssertTrue(tc, 3 == raft_node_get_next_idx(p)); CuAssertTrue(tc, 3 == raft_node_get_next_idx(p));
raft_node_free(p);
} }
...@@ -29,5 +30,10 @@ int main(void) ...@@ -29,5 +30,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
...@@ -88,5 +88,10 @@ int main(void) ...@@ -88,5 +88,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
...@@ -103,6 +103,8 @@ void TestRaft_server_voted_for_records_who_we_voted_for(CuTest * tc) ...@@ -103,6 +103,8 @@ void TestRaft_server_voted_for_records_who_we_voted_for(CuTest * tc)
raft_add_node(r, NULL, 2, 0); raft_add_node(r, NULL, 2, 0);
raft_vote(r, raft_get_node(r, 2)); raft_vote(r, raft_get_node(r, 2));
CuAssertTrue(tc, 2 == raft_get_voted_for(r)); CuAssertTrue(tc, 2 == raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_server_get_my_node(CuTest * tc) void TestRaft_server_get_my_node(CuTest * tc)
...@@ -111,6 +113,8 @@ void TestRaft_server_get_my_node(CuTest * tc) ...@@ -111,6 +113,8 @@ void TestRaft_server_get_my_node(CuTest * tc)
raft_node_t* me = raft_add_node(r, NULL, 1, 1); raft_node_t* me = raft_add_node(r, NULL, 1, 1);
raft_add_node(r, NULL, 2, 0); raft_add_node(r, NULL, 2, 0);
CuAssertTrue(tc, me == raft_get_my_node(r)); CuAssertTrue(tc, me == raft_get_my_node(r));
raft_destroy(r);
} }
void TestRaft_server_idx_starts_at_1(CuTest * tc) void TestRaft_server_idx_starts_at_1(CuTest * tc)
...@@ -122,12 +126,16 @@ void TestRaft_server_idx_starts_at_1(CuTest * tc) ...@@ -122,12 +126,16 @@ void TestRaft_server_idx_starts_at_1(CuTest * tc)
__RAFT_APPEND_ENTRY(r, 1, 1, "aaa"); __RAFT_APPEND_ENTRY(r, 1, 1, "aaa");
CuAssertTrue(tc, 1 == raft_get_current_idx(r)); CuAssertTrue(tc, 1 == raft_get_current_idx(r));
raft_destroy(r);
} }
void TestRaft_server_currentterm_defaults_to_0(CuTest * tc) void TestRaft_server_currentterm_defaults_to_0(CuTest * tc)
{ {
void *r = raft_new(); void *r = raft_new();
CuAssertTrue(tc, 0 == raft_get_current_term(r)); CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_server_set_currentterm_sets_term(CuTest * tc) void TestRaft_server_set_currentterm_sets_term(CuTest * tc)
...@@ -136,6 +144,8 @@ void TestRaft_server_set_currentterm_sets_term(CuTest * tc) ...@@ -136,6 +144,8 @@ void TestRaft_server_set_currentterm_sets_term(CuTest * tc)
raft_set_callbacks(r, &generic_funcs, NULL); raft_set_callbacks(r, &generic_funcs, NULL);
raft_set_current_term(r, 5); raft_set_current_term(r, 5);
CuAssertTrue(tc, 5 == raft_get_current_term(r)); CuAssertTrue(tc, 5 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_server_voting_results_in_voting(CuTest * tc) void TestRaft_server_voting_results_in_voting(CuTest * tc)
...@@ -149,6 +159,8 @@ void TestRaft_server_voting_results_in_voting(CuTest * tc) ...@@ -149,6 +159,8 @@ void TestRaft_server_voting_results_in_voting(CuTest * tc)
CuAssertTrue(tc, 1 == raft_get_voted_for(r)); CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_vote(r, raft_get_node(r, 9)); raft_vote(r, raft_get_node(r, 9));
CuAssertTrue(tc, 9 == raft_get_voted_for(r)); CuAssertTrue(tc, 9 == raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc) void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc)
...@@ -160,6 +172,8 @@ void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc) ...@@ -160,6 +172,8 @@ void TestRaft_server_add_node_makes_non_voting_node_voting(CuTest * tc)
raft_add_node(r, NULL, 9, 0); raft_add_node(r, NULL, 9, 0);
CuAssertTrue(tc, raft_node_is_voting(n1)); CuAssertTrue(tc, raft_node_is_voting(n1));
CuAssertIntEquals(tc, 1, raft_get_num_nodes(r)); CuAssertIntEquals(tc, 1, raft_get_num_nodes(r));
raft_destroy(r);
} }
void TestRaft_server_add_node_with_already_existing_id_is_not_allowed(CuTest * tc) void TestRaft_server_add_node_with_already_existing_id_is_not_allowed(CuTest * tc)
...@@ -170,6 +184,8 @@ void TestRaft_server_add_node_with_already_existing_id_is_not_allowed(CuTest * t ...@@ -170,6 +184,8 @@ void TestRaft_server_add_node_with_already_existing_id_is_not_allowed(CuTest * t
CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 9, 0)); CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 11, 0)); CuAssertTrue(tc, NULL == raft_add_node(r, NULL, 11, 0));
raft_destroy(r);
} }
void TestRaft_server_add_non_voting_node_with_already_existing_id_is_not_allowed(CuTest * tc) void TestRaft_server_add_non_voting_node_with_already_existing_id_is_not_allowed(CuTest * tc)
...@@ -180,6 +196,8 @@ void TestRaft_server_add_non_voting_node_with_already_existing_id_is_not_allowed ...@@ -180,6 +196,8 @@ void TestRaft_server_add_non_voting_node_with_already_existing_id_is_not_allowed
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0)); CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0)); CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0));
raft_destroy(r);
} }
void TestRaft_server_add_non_voting_node_with_already_existing_voting_id_is_not_allowed(CuTest * tc) void TestRaft_server_add_non_voting_node_with_already_existing_voting_id_is_not_allowed(CuTest * tc)
...@@ -190,6 +208,8 @@ void TestRaft_server_add_non_voting_node_with_already_existing_voting_id_is_not_ ...@@ -190,6 +208,8 @@ void TestRaft_server_add_non_voting_node_with_already_existing_voting_id_is_not_
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0)); CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 9, 0));
CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0)); CuAssertTrue(tc, NULL == raft_add_non_voting_node(r, NULL, 11, 0));
raft_destroy(r);
} }
void TestRaft_server_remove_node(CuTest * tc) void TestRaft_server_remove_node(CuTest * tc)
...@@ -203,6 +223,8 @@ void TestRaft_server_remove_node(CuTest * tc) ...@@ -203,6 +223,8 @@ void TestRaft_server_remove_node(CuTest * tc)
CuAssertTrue(tc, NULL != raft_get_node(r, 9)); CuAssertTrue(tc, NULL != raft_get_node(r, 9));
raft_remove_node(r, n2); raft_remove_node(r, n2);
CuAssertTrue(tc, NULL == raft_get_node(r, 9)); CuAssertTrue(tc, NULL == raft_get_node(r, 9));
raft_destroy(r);
} }
void TestRaft_election_start_does_not_increment_term(CuTest * tc) void TestRaft_election_start_does_not_increment_term(CuTest * tc)
...@@ -213,6 +235,8 @@ void TestRaft_election_start_does_not_increment_term(CuTest * tc) ...@@ -213,6 +235,8 @@ void TestRaft_election_start_does_not_increment_term(CuTest * tc)
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
raft_election_start(r, 0); raft_election_start(r, 0);
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 1 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_election_become_candidate_increments_term(CuTest * tc) void TestRaft_election_become_candidate_increments_term(CuTest * tc)
...@@ -223,6 +247,8 @@ void TestRaft_election_become_candidate_increments_term(CuTest * tc) ...@@ -223,6 +247,8 @@ void TestRaft_election_become_candidate_increments_term(CuTest * tc)
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 2 == raft_get_current_term(r)); CuAssertTrue(tc, 2 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_set_state(CuTest * tc) void TestRaft_set_state(CuTest * tc)
...@@ -243,12 +269,16 @@ void TestRaft_set_state(CuTest * tc) ...@@ -243,12 +269,16 @@ void TestRaft_set_state(CuTest * tc)
raft_set_state(r, RAFT_STATE_FOLLOWER); raft_set_state(r, RAFT_STATE_FOLLOWER);
CuAssertTrue(tc, RAFT_STATE_FOLLOWER == raft_get_state(r)); CuAssertTrue(tc, RAFT_STATE_FOLLOWER == raft_get_state(r));
CuAssertStrEquals(tc, "follower", raft_get_state_str(r)); CuAssertStrEquals(tc, "follower", raft_get_state_str(r));
raft_destroy(r);
} }
void TestRaft_server_starts_as_follower(CuTest * tc) void TestRaft_server_starts_as_follower(CuTest * tc)
{ {
void *r = raft_new(); void *r = raft_new();
CuAssertTrue(tc, RAFT_STATE_FOLLOWER == raft_get_state(r)); CuAssertTrue(tc, RAFT_STATE_FOLLOWER == raft_get_state(r));
raft_destroy(r);
} }
void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc) void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc)
...@@ -259,6 +289,8 @@ void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc) ...@@ -259,6 +289,8 @@ void TestRaft_server_starts_with_election_timeout_of_1000ms(CuTest * tc)
raft_config(r, 0, RAFT_CONFIG_ELECTION_TIMEOUT, &election_timeout); raft_config(r, 0, RAFT_CONFIG_ELECTION_TIMEOUT, &election_timeout);
CuAssertTrue(tc, 1000 == election_timeout); CuAssertTrue(tc, 1000 == election_timeout);
raft_destroy(r);
} }
void TestRaft_server_starts_with_request_timeout_of_200ms(CuTest * tc) void TestRaft_server_starts_with_request_timeout_of_200ms(CuTest * tc)
...@@ -269,6 +301,8 @@ void TestRaft_server_starts_with_request_timeout_of_200ms(CuTest * tc) ...@@ -269,6 +301,8 @@ void TestRaft_server_starts_with_request_timeout_of_200ms(CuTest * tc)
raft_config(r, 0, RAFT_CONFIG_REQUEST_TIMEOUT, &request_timeout); raft_config(r, 0, RAFT_CONFIG_REQUEST_TIMEOUT, &request_timeout);
CuAssertTrue(tc, 200 == request_timeout); CuAssertTrue(tc, 200 == request_timeout);
raft_destroy(r);
} }
void TestRaft_server_entry_append_increases_logidx(CuTest* tc) void TestRaft_server_entry_append_increases_logidx(CuTest* tc)
...@@ -279,7 +313,10 @@ void TestRaft_server_entry_append_increases_logidx(CuTest* tc) ...@@ -279,7 +313,10 @@ void TestRaft_server_entry_append_increases_logidx(CuTest* tc)
raft_entry_t *ety = __MAKE_ENTRY(1, 1, "aaa"); raft_entry_t *ety = __MAKE_ENTRY(1, 1, "aaa");
CuAssertTrue(tc, 0 == raft_get_current_idx(r)); CuAssertTrue(tc, 0 == raft_get_current_idx(r));
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_entry_release(ety);
CuAssertTrue(tc, 1 == raft_get_current_idx(r)); CuAssertTrue(tc, 1 == raft_get_current_idx(r));
raft_destroy(r);
} }
// this eems like a total duplicte of previous test case // this eems like a total duplicte of previous test case
...@@ -291,7 +328,10 @@ void TestRaft_server_append_entry_means_entry_gets_current_term(CuTest* tc) ...@@ -291,7 +328,10 @@ void TestRaft_server_append_entry_means_entry_gets_current_term(CuTest* tc)
raft_entry_t *ety = __MAKE_ENTRY(1, 1, "aaa"); raft_entry_t *ety = __MAKE_ENTRY(1, 1, "aaa");
CuAssertTrue(tc, 0 == raft_get_current_idx(r)); CuAssertTrue(tc, 0 == raft_get_current_idx(r));
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_entry_release(ety);
CuAssertTrue(tc, 1 == raft_get_current_idx(r)); CuAssertTrue(tc, 1 == raft_get_current_idx(r));
raft_destroy(r);
} }
void TestRaft_server_append_entry_is_retrievable(CuTest * tc) void TestRaft_server_append_entry_is_retrievable(CuTest * tc)
...@@ -305,8 +345,11 @@ void TestRaft_server_append_entry_is_retrievable(CuTest * tc) ...@@ -305,8 +345,11 @@ void TestRaft_server_append_entry_is_retrievable(CuTest * tc)
__RAFT_APPEND_ENTRY(r, 100, 1, "aaa"); __RAFT_APPEND_ENTRY(r, 100, 1, "aaa");
raft_entry_t* kept = raft_get_entry_from_idx(r, 1); raft_entry_t* kept = raft_get_entry_from_idx(r, 1);
CuAssertIntEquals(tc, 3, kept->data_len); CuAssertIntEquals(tc, 4, kept->data_len);
CuAssertStrEquals(tc, "aaa", kept->data); CuAssertStrEquals(tc, "aaa", kept->data);
raft_entry_release(kept);
raft_destroy(r);
} }
static int __raft_logentry_offer( static int __raft_logentry_offer(
...@@ -364,6 +407,9 @@ void TestRaft_server_entry_is_retrieveable_using_idx(CuTest* tc) ...@@ -364,6 +407,9 @@ void TestRaft_server_entry_is_retrieveable_using_idx(CuTest* tc)
CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2))); CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2)));
CuAssertTrue(tc, !strncmp(ety_appended->data, str2, 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, str2, 3));
raft_entry_release(ety_appended);
raft_destroy(r);
} }
void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc) void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc)
...@@ -375,6 +421,8 @@ void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc) ...@@ -375,6 +421,8 @@ void TestRaft_server_wont_apply_entry_if_we_dont_have_entry_to_apply(CuTest* tc)
raft_apply_entry(r); raft_apply_entry(r);
CuAssertTrue(tc, 0 == raft_get_last_applied_idx(r)); CuAssertTrue(tc, 0 == raft_get_last_applied_idx(r));
CuAssertTrue(tc, 0 == raft_get_commit_idx(r)); CuAssertTrue(tc, 0 == raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_server_wont_apply_entry_if_there_isnt_a_majority(CuTest* tc) void TestRaft_server_wont_apply_entry_if_there_isnt_a_majority(CuTest* tc)
...@@ -397,6 +445,8 @@ void TestRaft_server_wont_apply_entry_if_there_isnt_a_majority(CuTest* tc) ...@@ -397,6 +445,8 @@ void TestRaft_server_wont_apply_entry_if_there_isnt_a_majority(CuTest* tc)
/* Not allowed to be applied because we haven't confirmed a majority yet */ /* Not allowed to be applied because we haven't confirmed a majority yet */
CuAssertTrue(tc, 0 == raft_get_last_applied_idx(r)); CuAssertTrue(tc, 0 == raft_get_last_applied_idx(r));
CuAssertTrue(tc, 0 == raft_get_commit_idx(r)); CuAssertTrue(tc, 0 == raft_get_commit_idx(r));
raft_destroy(r);
} }
/* If commitidx > lastApplied: increment lastApplied, apply log[lastApplied] /* If commitidx > lastApplied: increment lastApplied, apply log[lastApplied]
...@@ -427,6 +477,8 @@ void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx( ...@@ -427,6 +477,8 @@ void TestRaft_server_increment_lastApplied_when_lastApplied_lt_commitidx(
/* let time lapse */ /* let time lapse */
raft_periodic_internal(r, 1); raft_periodic_internal(r, 1);
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_user_applylog_error_propogates_to_periodic( void TestRaft_user_applylog_error_propogates_to_periodic(
...@@ -454,6 +506,8 @@ void TestRaft_user_applylog_error_propogates_to_periodic( ...@@ -454,6 +506,8 @@ void TestRaft_user_applylog_error_propogates_to_periodic(
/* let time lapse */ /* let time lapse */
CuAssertIntEquals(tc, RAFT_ERR_SHUTDOWN, raft_periodic_internal(r, 1)); CuAssertIntEquals(tc, RAFT_ERR_SHUTDOWN, raft_periodic_internal(r, 1));
CuAssertIntEquals(tc, 0, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 0, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc) void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc)
...@@ -472,6 +526,8 @@ void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc) ...@@ -472,6 +526,8 @@ void TestRaft_server_apply_entry_increments_last_applied_idx(CuTest* tc)
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
raft_apply_entry(r); raft_apply_entry(r);
CuAssertTrue(tc, 1 == raft_get_last_applied_idx(r)); CuAssertTrue(tc, 1 == raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc) void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc)
...@@ -486,6 +542,8 @@ void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc) ...@@ -486,6 +542,8 @@ void TestRaft_server_periodic_elapses_election_timeout(CuTest * tc)
raft_periodic_internal(r, 100); raft_periodic_internal(r, 100);
CuAssertTrue(tc, 100 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 100 == raft_get_timeout_elapsed(r));
raft_destroy(r);
} }
void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_there_is_are_more_than_1_nodes(CuTest * tc) void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_there_is_are_more_than_1_nodes(CuTest * tc)
...@@ -506,6 +564,8 @@ void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_there_is_ ...@@ -506,6 +564,8 @@ void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_there_is_
raft_periodic_internal(r, 1001); raft_periodic_internal(r, 1001);
CuAssertTrue(tc, 0 == raft_is_leader(r)); CuAssertTrue(tc, 0 == raft_is_leader(r));
raft_destroy(r);
} }
void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_we_are_not_voting_node(CuTest * tc) void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_we_are_not_voting_node(CuTest * tc)
...@@ -519,6 +579,8 @@ void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_we_are_no ...@@ -519,6 +579,8 @@ void TestRaft_server_election_timeout_does_not_promote_us_to_leader_if_we_are_no
CuAssertTrue(tc, 0 == raft_is_leader(r)); CuAssertTrue(tc, 0 == raft_is_leader(r));
CuAssertTrue(tc, 0 == raft_get_current_term(r)); CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_server_election_timeout_does_not_start_election_if_there_are_no_voting_nodes(CuTest * tc) void TestRaft_server_election_timeout_does_not_start_election_if_there_are_no_voting_nodes(CuTest * tc)
...@@ -532,6 +594,8 @@ void TestRaft_server_election_timeout_does_not_start_election_if_there_are_no_vo ...@@ -532,6 +594,8 @@ void TestRaft_server_election_timeout_does_not_start_election_if_there_are_no_vo
raft_periodic_internal(r, 1001); raft_periodic_internal(r, 1001);
CuAssertTrue(tc, 0 == raft_get_current_term(r)); CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_node(CuTest * tc) void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_node(CuTest * tc)
...@@ -546,6 +610,8 @@ void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only ...@@ -546,6 +610,8 @@ void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
CuAssertTrue(tc, old_term + 1 == raft_get_current_term(r)); CuAssertTrue(tc, old_term + 1 == raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_voting_node(CuTest * tc) void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only_1_voting_node(CuTest * tc)
...@@ -565,6 +631,8 @@ void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only ...@@ -565,6 +631,8 @@ void TestRaft_server_election_timeout_does_promote_us_to_leader_if_there_is_only
raft_periodic_internal(r, 1001); raft_periodic_internal(r, 1001);
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
raft_destroy(r);
} }
void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc) void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc)
...@@ -581,8 +649,11 @@ void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc ...@@ -581,8 +649,11 @@ void TestRaft_server_recv_entry_auto_commits_if_we_are_the_only_node(CuTest * tc
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
CuAssertTrue(tc, 2 == raft_get_commit_idx(r)); CuAssertTrue(tc, 2 == raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_server_recv_entry_fails_if_there_is_already_a_voting_change(CuTest * tc) void TestRaft_server_recv_entry_fails_if_there_is_already_a_voting_change(CuTest * tc)
...@@ -601,12 +672,16 @@ void TestRaft_server_recv_entry_fails_if_there_is_already_a_voting_change(CuTest ...@@ -601,12 +672,16 @@ void TestRaft_server_recv_entry_fails_if_there_is_already_a_voting_change(CuTest
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
CuAssertTrue(tc, 0 == raft_recv_entry(r, ety, &cr)); CuAssertTrue(tc, 0 == raft_recv_entry(r, ety, &cr));
raft_entry_release(ety);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
raft_entry_t *ety2 = __MAKE_ENTRY(2, 1, "entry"); raft_entry_t *ety2 = __MAKE_ENTRY(2, 1, "entry");
ety2->type = RAFT_LOGTYPE_ADD_NODE; ety2->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertTrue(tc, RAFT_ERR_ONE_VOTING_CHANGE_ONLY == raft_recv_entry(r, ety2, &cr)); CuAssertTrue(tc, RAFT_ERR_ONE_VOTING_CHANGE_ONLY == raft_recv_entry(r, ety2, &cr));
raft_entry_release(ety2);
CuAssertTrue(tc, 1 == raft_get_commit_idx(r)); CuAssertTrue(tc, 1 == raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_server_cfg_sets_num_nodes(CuTest * tc) void TestRaft_server_cfg_sets_num_nodes(CuTest * tc)
...@@ -616,6 +691,8 @@ void TestRaft_server_cfg_sets_num_nodes(CuTest * tc) ...@@ -616,6 +691,8 @@ void TestRaft_server_cfg_sets_num_nodes(CuTest * tc)
raft_add_node(r, NULL, 2, 0); raft_add_node(r, NULL, 2, 0);
CuAssertTrue(tc, 2 == raft_get_num_nodes(r)); CuAssertTrue(tc, 2 == raft_get_num_nodes(r));
raft_destroy(r);
} }
void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc) void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc)
...@@ -628,6 +705,8 @@ void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc) ...@@ -628,6 +705,8 @@ void TestRaft_server_cant_get_node_we_dont_have(CuTest * tc)
CuAssertTrue(tc, NULL != raft_get_node(r, 1)); CuAssertTrue(tc, NULL != raft_get_node(r, 1));
CuAssertTrue(tc, NULL != raft_get_node(r, 2)); CuAssertTrue(tc, NULL != raft_get_node(r, 2));
CuAssertTrue(tc, NULL == raft_get_node(r, 3)); CuAssertTrue(tc, NULL == raft_get_node(r, 3));
raft_destroy(r);
} }
/* If term > currentTerm, set currentTerm to term (step down if candidate or /* If term > currentTerm, set currentTerm to term (step down if candidate or
...@@ -675,6 +754,8 @@ void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_n ...@@ -675,6 +754,8 @@ void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_n
int e = raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr); int e = raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr);
CuAssertIntEquals(tc, 0, e); CuAssertIntEquals(tc, 0, e);
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_term_is_not_equal( void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_term_is_not_equal(
...@@ -699,6 +780,8 @@ void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_t ...@@ -699,6 +780,8 @@ void TestRaft_server_recv_requestvote_response_dont_increase_votes_for_me_when_t
rvr.vote_granted = 1; rvr.vote_granted = 1;
raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr); raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr);
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_response_increase_votes_for_me( void TestRaft_server_recv_requestvote_response_increase_votes_for_me(
...@@ -732,6 +815,8 @@ void TestRaft_server_recv_requestvote_response_increase_votes_for_me( ...@@ -732,6 +815,8 @@ void TestRaft_server_recv_requestvote_response_increase_votes_for_me(
int e = raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr); int e = raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr);
CuAssertIntEquals(tc, 0, e); CuAssertIntEquals(tc, 0, e);
CuAssertTrue(tc, 2 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 2 == raft_get_nvotes_for_me(r));
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_response_must_be_candidate_to_receive( void TestRaft_server_recv_requestvote_response_must_be_candidate_to_receive(
...@@ -759,6 +844,8 @@ void TestRaft_server_recv_requestvote_response_must_be_candidate_to_receive( ...@@ -759,6 +844,8 @@ void TestRaft_server_recv_requestvote_response_must_be_candidate_to_receive(
rvr.vote_granted = 1; rvr.vote_granted = 1;
raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr); raft_recv_requestvote_response(r, raft_get_node(r, 2), &rvr);
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
raft_destroy(r);
} }
/* Reply false if term < currentTerm (§5.1) */ /* Reply false if term < currentTerm (§5.1) */
...@@ -786,6 +873,8 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term ...@@ -786,6 +873,8 @@ void TestRaft_server_recv_requestvote_reply_false_if_term_less_than_current_term
int e = raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); int e = raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertIntEquals(tc, 0, e); CuAssertIntEquals(tc, 0, e);
CuAssertIntEquals(tc, 0, rvr.vote_granted); CuAssertIntEquals(tc, 0, rvr.vote_granted);
raft_destroy(r);
} }
void TestRaft_leader_recv_requestvote_does_not_step_down( void TestRaft_leader_recv_requestvote_does_not_step_down(
...@@ -815,6 +904,8 @@ void TestRaft_leader_recv_requestvote_does_not_step_down( ...@@ -815,6 +904,8 @@ void TestRaft_leader_recv_requestvote_does_not_step_down(
rv.term = 1; rv.term = 1;
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertIntEquals(tc, 1, raft_get_leader_id(r)); CuAssertIntEquals(tc, 1, raft_get_leader_id(r));
raft_destroy(r);
} }
/* Reply true if term >= currentTerm (§5.1) */ /* Reply true if term >= currentTerm (§5.1) */
...@@ -843,6 +934,8 @@ void TestRaft_server_recv_requestvote_reply_true_if_term_greater_than_or_equal_t ...@@ -843,6 +934,8 @@ void TestRaft_server_recv_requestvote_reply_true_if_term_greater_than_or_equal_t
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 1 == rvr.vote_granted); CuAssertTrue(tc, 1 == rvr.vote_granted);
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_reset_timeout( void TestRaft_server_recv_requestvote_reset_timeout(
...@@ -872,6 +965,8 @@ void TestRaft_server_recv_requestvote_reset_timeout( ...@@ -872,6 +965,8 @@ void TestRaft_server_recv_requestvote_reset_timeout(
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 1 == rvr.vote_granted); CuAssertTrue(tc, 1 == rvr.vote_granted);
CuAssertIntEquals(tc, 0, raft_get_timeout_elapsed(r)); CuAssertIntEquals(tc, 0, raft_get_timeout_elapsed(r));
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than_current_term( void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than_current_term(
...@@ -903,6 +998,8 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than ...@@ -903,6 +998,8 @@ void TestRaft_server_recv_requestvote_candidate_step_down_if_term_is_higher_than
CuAssertIntEquals(tc, 1, raft_is_follower(r)); CuAssertIntEquals(tc, 1, raft_is_follower(r));
CuAssertIntEquals(tc, 2, raft_get_current_term(r)); CuAssertIntEquals(tc, 2, raft_get_current_term(r));
CuAssertIntEquals(tc, 2, raft_get_voted_for(r)); CuAssertIntEquals(tc, 2, raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_server_recv_requestvote_depends_on_candidate_id( void TestRaft_server_recv_requestvote_depends_on_candidate_id(
...@@ -934,6 +1031,8 @@ void TestRaft_server_recv_requestvote_depends_on_candidate_id( ...@@ -934,6 +1031,8 @@ void TestRaft_server_recv_requestvote_depends_on_candidate_id(
CuAssertIntEquals(tc, 1, raft_is_follower(r)); CuAssertIntEquals(tc, 1, raft_is_follower(r));
CuAssertIntEquals(tc, 2, raft_get_current_term(r)); CuAssertIntEquals(tc, 2, raft_get_current_term(r));
CuAssertIntEquals(tc, 3, raft_get_voted_for(r)); CuAssertIntEquals(tc, 3, raft_get_voted_for(r));
raft_destroy(r);
} }
/* If votedFor is null or candidateId, and candidate's log is at /* If votedFor is null or candidateId, and candidate's log is at
...@@ -970,6 +1069,8 @@ void TestRaft_server_recv_requestvote_dont_grant_vote_if_we_didnt_vote_for_this_ ...@@ -970,6 +1069,8 @@ void TestRaft_server_recv_requestvote_dont_grant_vote_if_we_didnt_vote_for_this_
raft_vote_for_nodeid(r, 0); raft_vote_for_nodeid(r, 0);
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 0 == rvr.vote_granted); CuAssertTrue(tc, 0 == rvr.vote_granted);
raft_destroy(r);
} }
/* If requestvote is received within the minimum election timeout of /* If requestvote is received within the minimum election timeout of
...@@ -1011,6 +1112,8 @@ void TestRaft_server_recv_requestvote_ignore_if_master_is_fresh(CuTest * tc) ...@@ -1011,6 +1112,8 @@ void TestRaft_server_recv_requestvote_ignore_if_master_is_fresh(CuTest * tc)
raft_periodic_internal(r, 1001); raft_periodic_internal(r, 1001);
raft_recv_requestvote(r, raft_get_node(r, 3), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 3), &rv, &rvr);
CuAssertTrue(tc, 1 == rvr.vote_granted); CuAssertTrue(tc, 1 == rvr.vote_granted);
raft_destroy(r);
} }
void TestRaft_server_recv_prevote_ignore_if_candidate(CuTest * tc) void TestRaft_server_recv_prevote_ignore_if_candidate(CuTest * tc)
...@@ -1034,6 +1137,8 @@ void TestRaft_server_recv_prevote_ignore_if_candidate(CuTest * tc) ...@@ -1034,6 +1137,8 @@ void TestRaft_server_recv_prevote_ignore_if_candidate(CuTest * tc)
CuAssertTrue(tc, raft_is_candidate(r)); CuAssertTrue(tc, raft_is_candidate(r));
CuAssertTrue(tc, raft_get_nvotes_for_me(r) == 1); CuAssertTrue(tc, raft_get_nvotes_for_me(r) == 1);
raft_destroy(r);
} }
void TestRaft_server_recv_reqvote_ignore_if_not_candidate(CuTest * tc) void TestRaft_server_recv_reqvote_ignore_if_not_candidate(CuTest * tc)
...@@ -1056,6 +1161,8 @@ void TestRaft_server_recv_reqvote_ignore_if_not_candidate(CuTest * tc) ...@@ -1056,6 +1161,8 @@ void TestRaft_server_recv_reqvote_ignore_if_not_candidate(CuTest * tc)
CuAssertTrue(tc, raft_is_precandidate(r)); CuAssertTrue(tc, raft_is_precandidate(r));
CuAssertTrue(tc, raft_get_nvotes_for_me(r) == 1); CuAssertTrue(tc, raft_get_nvotes_for_me(r) == 1);
raft_destroy(r);
} }
void TestRaft_server_recv_reqvote_always_update_term(CuTest * tc) void TestRaft_server_recv_reqvote_always_update_term(CuTest * tc)
...@@ -1078,6 +1185,8 @@ void TestRaft_server_recv_reqvote_always_update_term(CuTest * tc) ...@@ -1078,6 +1185,8 @@ void TestRaft_server_recv_reqvote_always_update_term(CuTest * tc)
CuAssertTrue(tc, raft_is_follower(r)); CuAssertTrue(tc, raft_is_follower(r));
CuAssertTrue(tc, raft_get_current_term(r) == 3); CuAssertTrue(tc, raft_get_current_term(r) == 3);
raft_destroy(r);
} }
void TestRaft_follower_becomes_follower_is_follower(CuTest * tc) void TestRaft_follower_becomes_follower_is_follower(CuTest * tc)
...@@ -1086,6 +1195,8 @@ void TestRaft_follower_becomes_follower_is_follower(CuTest * tc) ...@@ -1086,6 +1195,8 @@ void TestRaft_follower_becomes_follower_is_follower(CuTest * tc)
raft_add_node(r, NULL, 1, 1); raft_add_node(r, NULL, 1, 1);
raft_become_follower(r); raft_become_follower(r);
CuAssertTrue(tc, raft_is_follower(r)); CuAssertTrue(tc, raft_is_follower(r));
raft_destroy(r);
} }
void TestRaft_follower_becomes_follower_does_not_clear_voted_for(CuTest * tc) void TestRaft_follower_becomes_follower_does_not_clear_voted_for(CuTest * tc)
...@@ -1103,6 +1214,8 @@ void TestRaft_follower_becomes_follower_does_not_clear_voted_for(CuTest * tc) ...@@ -1103,6 +1214,8 @@ void TestRaft_follower_becomes_follower_does_not_clear_voted_for(CuTest * tc)
CuAssertIntEquals(tc, 1, raft_get_voted_for(r)); CuAssertIntEquals(tc, 1, raft_get_voted_for(r));
raft_become_follower(r); raft_become_follower(r);
CuAssertIntEquals(tc, 1, raft_get_voted_for(r)); CuAssertIntEquals(tc, 1, raft_get_voted_for(r));
raft_destroy(r);
} }
/* 5.1 */ /* 5.1 */
...@@ -1134,6 +1247,8 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt ...@@ -1134,6 +1247,8 @@ void TestRaft_follower_recv_appendentries_reply_false_if_term_less_than_currentt
CuAssertTrue(tc, 0 == aer.success); CuAssertTrue(tc, 0 == aer.success);
/* rejected appendentries doesn't change the current leader. */ /* rejected appendentries doesn't change the current leader. */
CuAssertTrue(tc, -1 == raft_get_leader_id(r)); CuAssertTrue(tc, -1 == raft_get_leader_id(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_snapshot_reply_false_if_term_less_than_currentterm( void TestRaft_follower_recv_snapshot_reply_false_if_term_less_than_currentterm(
...@@ -1166,6 +1281,8 @@ void TestRaft_follower_recv_snapshot_reply_false_if_term_less_than_currentterm( ...@@ -1166,6 +1281,8 @@ void TestRaft_follower_recv_snapshot_reply_false_if_term_less_than_currentterm(
/* rejected snapshot req doesn't change the current leader. */ /* rejected snapshot req doesn't change the current leader. */
CuAssertTrue(tc, raft_get_leader_id(r) == RAFT_NODE_ID_NONE); CuAssertTrue(tc, raft_get_leader_id(r) == RAFT_NODE_ID_NONE);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_does_not_need_node(CuTest * tc) void TestRaft_follower_recv_appendentries_does_not_need_node(CuTest * tc)
...@@ -1184,6 +1301,8 @@ void TestRaft_follower_recv_appendentries_does_not_need_node(CuTest * tc) ...@@ -1184,6 +1301,8 @@ void TestRaft_follower_recv_appendentries_does_not_need_node(CuTest * tc)
raft_appendentries_resp_t aer; raft_appendentries_resp_t aer;
raft_recv_appendentries(r, NULL, &ae, &aer); raft_recv_appendentries(r, NULL, &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
raft_destroy(r);
} }
/* TODO: check if test case is needed */ /* TODO: check if test case is needed */
...@@ -1222,6 +1341,8 @@ void TestRaft_follower_recv_appendentries_updates_currentterm_if_term_gt_current ...@@ -1222,6 +1341,8 @@ 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));
/* and leader has been updated */ /* and leader has been updated */
CuAssertIntEquals(tc, 2, raft_get_leader_id(r)); CuAssertIntEquals(tc, 2, raft_get_leader_id(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_does_not_log_if_no_entries_are_specified( void TestRaft_follower_recv_appendentries_does_not_log_if_no_entries_are_specified(
...@@ -1255,6 +1376,8 @@ void TestRaft_follower_recv_appendentries_does_not_log_if_no_entries_are_specifi ...@@ -1255,6 +1376,8 @@ void TestRaft_follower_recv_appendentries_does_not_log_if_no_entries_are_specifi
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 0 == raft_get_log_count(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_increases_log(CuTest * tc) void TestRaft_follower_recv_appendentries_increases_log(CuTest * tc)
...@@ -1291,10 +1414,18 @@ void TestRaft_follower_recv_appendentries_increases_log(CuTest * tc) ...@@ -1291,10 +1414,18 @@ void TestRaft_follower_recv_appendentries_increases_log(CuTest * tc)
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
raft_entry_t* log = raft_get_entry_from_idx(r, 1); raft_entry_t* log = raft_get_entry_from_idx(r, 1);
CuAssertTrue(tc, 2 == log->term); CuAssertTrue(tc, 2 == log->term);
raft_entry_release(log);
raft_destroy(r);
} }
/* 5.3 */ /* 5.3 */
...@@ -1333,8 +1464,15 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev ...@@ -1333,8 +1464,15 @@ void TestRaft_follower_recv_appendentries_reply_false_if_doesnt_have_log_at_prev
/* trigger reply */ /* trigger reply */
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* reply is false */ /* reply is false */
CuAssertTrue(tc, 0 == aer.success); CuAssertTrue(tc, 0 == aer.success);
raft_destroy(r);
} }
static raft_entry_t* __create_mock_entries_for_conflict_tests( static raft_entry_t* __create_mock_entries_for_conflict_tests(
...@@ -1355,6 +1493,7 @@ static raft_entry_t* __create_mock_entries_for_conflict_tests( ...@@ -1355,6 +1493,7 @@ static raft_entry_t* __create_mock_entries_for_conflict_tests(
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2))); CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2)));
CuAssertTrue(tc, !strncmp(ety_appended->data, str2, 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, str2, 3));
raft_entry_release(ety_appended);
/* this log will be overwritten by a later appendentries */ /* this log will be overwritten by a later appendentries */
char *str3 = strs[2]; char *str3 = strs[2];
...@@ -1387,6 +1526,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1387,6 +1526,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
char* strs[] = {"111", "222", "333"}; char* strs[] = {"111", "222", "333"};
raft_entry_t *ety_appended = __create_mock_entries_for_conflict_tests(tc, r, strs); raft_entry_t *ety_appended = __create_mock_entries_for_conflict_tests(tc, r, strs);
raft_entry_release(ety_appended);
/* pass a appendentry that is newer */ /* pass a appendentry that is newer */
memset(&ae, 0, sizeof(raft_appendentries_req_t)); memset(&ae, 0, sizeof(raft_appendentries_req_t));
...@@ -1403,12 +1543,22 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1403,12 +1543,22 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* str1 is still there */ /* str1 is still there */
CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 1))); CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 1)));
CuAssertTrue(tc, !strncmp(ety_appended->data, strs[0], 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, strs[0], 3));
raft_entry_release(ety_appended);
/* str4 has overwritten the last 2 entries */ /* str4 has overwritten the last 2 entries */
CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2))); CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 2)));
CuAssertTrue(tc, !strncmp(ety_appended->data, str4, 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, str4, 3));
raft_entry_release(ety_appended);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries_via_prev_log_idx_at_idx_0( void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries_via_prev_log_idx_at_idx_0(
...@@ -1431,6 +1581,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1431,6 +1581,7 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
char* strs[] = {"111", "222", "333"}; char* strs[] = {"111", "222", "333"};
raft_entry_t *ety_appended = __create_mock_entries_for_conflict_tests(tc, r, strs); raft_entry_t *ety_appended = __create_mock_entries_for_conflict_tests(tc, r, strs);
raft_entry_release(ety_appended);
/* pass a appendentry that is newer */ /* pass a appendentry that is newer */
...@@ -1447,9 +1598,18 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1447,9 +1598,18 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* str1 is gone */ /* str1 is gone */
CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 1))); CuAssertTrue(tc, NULL != (ety_appended = raft_get_entry_from_idx(r, 1)));
CuAssertTrue(tc, !strncmp(ety_appended->data, str4, 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, str4, 3));
raft_entry_release(ety_appended);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries_greater_than_prev_log_idx( void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_entries_greater_than_prev_log_idx(
...@@ -1471,10 +1631,9 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1471,10 +1631,9 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
char* strs[] = {"111", "222", "333"}; char* strs[] = {"111", "222", "333"};
raft_entry_t *ety_appended; raft_entry_t *ety_appended = __create_mock_entries_for_conflict_tests(tc, r, strs);
__create_mock_entries_for_conflict_tests(tc, r, strs);
CuAssertIntEquals(tc, 3, raft_get_log_count(r)); CuAssertIntEquals(tc, 3, raft_get_log_count(r));
raft_entry_release(ety_appended);
memset(&ae, 0, sizeof(raft_appendentries_req_t)); memset(&ae, 0, sizeof(raft_appendentries_req_t));
ae.term = 2; ae.term = 2;
...@@ -1485,10 +1644,18 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en ...@@ -1485,10 +1644,18 @@ void TestRaft_follower_recv_appendentries_delete_entries_if_conflict_with_new_en
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(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, 1)));
CuAssertTrue(tc, !strncmp(ety_appended->data, strs[0], 3)); CuAssertTrue(tc, !strncmp(ety_appended->data, strs[0], 3));
raft_entry_release(ety_appended);
raft_destroy(r);
} }
// TODO: add TestRaft_follower_recv_appendentries_delete_entries_if_term_is_different // TODO: add TestRaft_follower_recv_appendentries_delete_entries_if_term_is_different
...@@ -1521,6 +1688,13 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log( ...@@ -1521,6 +1688,13 @@ void TestRaft_follower_recv_appendentries_add_new_entries_not_already_in_log(
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertTrue(tc, 2 == raft_get_log_count(r)); CuAssertTrue(tc, 2 == raft_get_log_count(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_log( void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_log(
...@@ -1549,12 +1723,18 @@ void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_l ...@@ -1549,12 +1723,18 @@ void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_l
ae.n_entries = 1; ae.n_entries = 1;
memset(&aer, 0, sizeof(aer)); memset(&aer, 0, sizeof(aer));
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
memset(&aer, 0, sizeof(aer)); memset(&aer, 0, sizeof(aer));
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
/* still successful even when no raft_append_entry() happened! */ /* still successful even when no raft_append_entry() happened! */
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 1, raft_get_log_count(r)); CuAssertIntEquals(tc, 1, raft_get_log_count(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* lets get the server to append 2 now! */ /* lets get the server to append 2 now! */
ae.entries = __MAKE_ENTRY_ARRAY_SEQ_ID(2, 1, 1, "aaa"); ae.entries = __MAKE_ENTRY_ARRAY_SEQ_ID(2, 1, 1, "aaa");
ae.n_entries = 2; ae.n_entries = 2;
...@@ -1562,6 +1742,13 @@ void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_l ...@@ -1562,6 +1742,13 @@ void TestRaft_follower_recv_appendentries_does_not_add_dupe_entries_already_in_l
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
typedef enum { typedef enum {
...@@ -1642,6 +1829,7 @@ void TestRaft_follower_recv_appendentries_partial_failures( ...@@ -1642,6 +1829,7 @@ void TestRaft_follower_recv_appendentries_partial_failures(
error.idx = 2; error.idx = 2;
memset(&aer, 0, sizeof(aer)); memset(&aer, 0, sizeof(aer));
int err = raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); int err = raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertIntEquals(tc, RAFT_ERR_NOMEM, err); CuAssertIntEquals(tc, RAFT_ERR_NOMEM, err);
CuAssertIntEquals(tc, 1, aer.success); CuAssertIntEquals(tc, 1, aer.success);
CuAssertIntEquals(tc, 1, aer.current_idx); CuAssertIntEquals(tc, 1, aer.current_idx);
...@@ -1649,6 +1837,7 @@ void TestRaft_follower_recv_appendentries_partial_failures( ...@@ -1649,6 +1837,7 @@ void TestRaft_follower_recv_appendentries_partial_failures(
raft_entry_t *tmp = raft_get_entry_from_idx(r, 2); raft_entry_t *tmp = raft_get_entry_from_idx(r, 2);
CuAssertTrue(tc, NULL != tmp); CuAssertTrue(tc, NULL != tmp);
CuAssertIntEquals(tc, 1, tmp->term); CuAssertIntEquals(tc, 1, tmp->term);
raft_entry_release(tmp);
/* Ask log_offer to fail at entry 3. */ /* Ask log_offer to fail at entry 3. */
error.type = __RAFT_LOG_OFFER_ERR; error.type = __RAFT_LOG_OFFER_ERR;
...@@ -1662,6 +1851,7 @@ void TestRaft_follower_recv_appendentries_partial_failures( ...@@ -1662,6 +1851,7 @@ void TestRaft_follower_recv_appendentries_partial_failures(
tmp = raft_get_entry_from_idx(r, 2); tmp = raft_get_entry_from_idx(r, 2);
CuAssertTrue(tc, NULL != tmp); CuAssertTrue(tc, NULL != tmp);
CuAssertIntEquals(tc, 2, tmp->term); CuAssertIntEquals(tc, 2, tmp->term);
raft_entry_release(tmp);
/* No more errors. */ /* No more errors. */
memset(&error, 0, sizeof(error)); memset(&error, 0, sizeof(error));
...@@ -1671,6 +1861,13 @@ void TestRaft_follower_recv_appendentries_partial_failures( ...@@ -1671,6 +1861,13 @@ void TestRaft_follower_recv_appendentries_partial_failures(
CuAssertIntEquals(tc, 1, aer.success); CuAssertIntEquals(tc, 1, aer.success);
CuAssertIntEquals(tc, 3, aer.current_idx); CuAssertIntEquals(tc, 3, aer.current_idx);
CuAssertIntEquals(tc, 3, raft_get_current_idx(r)); CuAssertIntEquals(tc, 3, raft_get_current_idx(r));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
/* If leaderCommit > commitidx, set commitidx = /* If leaderCommit > commitidx, set commitidx =
...@@ -1697,10 +1894,10 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx( ...@@ -1697,10 +1894,10 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(
ae.prev_log_term = 0; ae.prev_log_term = 0;
/* include entries */ /* include entries */
raft_entry_req_t e[4] = { raft_entry_req_t e[4] = {
{ .id = 1, .term = 1 }, { .id = 1, .term = 1, .refs = 1 },
{ .id = 2, .term = 1 }, { .id = 2, .term = 1, .refs = 1 },
{ .id = 3, .term = 1 }, { .id = 3, .term = 1, .refs = 1 },
{ .id = 4, .term = 1 } { .id = 4, .term = 1, .refs = 1}
}; };
raft_entry_req_t *e_array[4] = { raft_entry_req_t *e_array[4] = {
&e[0], &e[1], &e[2], &e[3] &e[0], &e[1], &e[2], &e[3]
...@@ -1721,6 +1918,8 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx( ...@@ -1721,6 +1918,8 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_prevLogIdx(
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
/* set to 4 because commitIDX is lower */ /* set to 4 because commitIDX is lower */
CuAssertIntEquals(tc, 4, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 4, raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit( void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(
...@@ -1745,10 +1944,10 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit( ...@@ -1745,10 +1944,10 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(
ae.prev_log_term = 0; ae.prev_log_term = 0;
/* include entries */ /* include entries */
raft_entry_req_t e[4] = { raft_entry_req_t e[4] = {
{ .id = 1, .term = 1 }, { .id = 1, .term = 1, .refs = 1 },
{ .id = 2, .term = 1 }, { .id = 2, .term = 1, .refs = 1 },
{ .id = 3, .term = 1 }, { .id = 3, .term = 1, .refs = 1 },
{ .id = 4, .term = 1 } { .id = 4, .term = 1, .refs = 1 }
}; };
raft_entry_req_t *e_array[4] = { raft_entry_req_t *e_array[4] = {
&e[0], &e[1], &e[2], &e[3] &e[0], &e[1], &e[2], &e[3]
...@@ -1770,6 +1969,8 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit( ...@@ -1770,6 +1969,8 @@ void TestRaft_follower_recv_appendentries_set_commitidx_to_LeaderCommit(
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
/* set to 3 because leaderCommit is lower */ /* set to 3 because leaderCommit is lower */
CuAssertIntEquals(tc, 3, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 3, raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_failure_includes_current_idx( void TestRaft_follower_recv_appendentries_failure_includes_current_idx(
...@@ -1808,6 +2009,8 @@ void TestRaft_follower_recv_appendentries_failure_includes_current_idx( ...@@ -1808,6 +2009,8 @@ void TestRaft_follower_recv_appendentries_failure_includes_current_idx(
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 0 == aer.success); CuAssertTrue(tc, 0 == aer.success);
CuAssertIntEquals(tc, 2, aer.current_idx); CuAssertIntEquals(tc, 2, aer.current_idx);
raft_destroy(r);
} }
void TestRaft_follower_becomes_precandidate_when_election_timeout_occurs( void TestRaft_follower_becomes_precandidate_when_election_timeout_occurs(
...@@ -1832,6 +2035,8 @@ void TestRaft_follower_becomes_precandidate_when_election_timeout_occurs( ...@@ -1832,6 +2035,8 @@ void TestRaft_follower_becomes_precandidate_when_election_timeout_occurs(
/* is a candidate now */ /* is a candidate now */
CuAssertTrue(tc, 1 == raft_is_precandidate(r)); CuAssertTrue(tc, 1 == raft_is_precandidate(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -1878,6 +2083,8 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log( ...@@ -1878,6 +2083,8 @@ void TestRaft_follower_dont_grant_vote_if_candidate_has_a_less_complete_log(
rv.last_log_term = 3; rv.last_log_term = 3;
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertIntEquals(tc, 1, rvr.vote_granted); CuAssertIntEquals(tc, 1, rvr.vote_granted);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs( void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs(
...@@ -1905,6 +2112,11 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs( ...@@ -1905,6 +2112,11 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs(
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* The server sends a follow up AE /* The server sends a follow up AE
* NOTE: the server has received a response from the last AE so * NOTE: the server has received a response from the last AE so
* prev_log_idx has been incremented */ * prev_log_idx has been incremented */
...@@ -1917,6 +2129,11 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs( ...@@ -1917,6 +2129,11 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs(
ae.n_entries = 4; ae.n_entries = 4;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* receive a heartbeat /* receive a heartbeat
* NOTE: the leader hasn't received the response to the last AE so it can * NOTE: the leader hasn't received the response to the last AE so it can
* only assume prev_Log_idx is still 1 */ * only assume prev_Log_idx is still 1 */
...@@ -1929,6 +2146,8 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs( ...@@ -1929,6 +2146,8 @@ void TestRaft_follower_recv_appendentries_heartbeat_does_not_overwrite_logs(
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 5, raft_get_current_idx(r)); CuAssertIntEquals(tc, 5, raft_get_current_idx(r));
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries( void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries(
...@@ -1956,6 +2175,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries( ...@@ -1956,6 +2175,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries(
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* Follow up AE. Node responded with success */ /* Follow up AE. Node responded with success */
memset(&ae, 0, sizeof(raft_appendentries_req_t)); memset(&ae, 0, sizeof(raft_appendentries_req_t));
ae.term = 1; ae.term = 1;
...@@ -1967,6 +2191,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries( ...@@ -1967,6 +2191,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries(
ae.leader_commit = 4; ae.leader_commit = 4;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
/* The server sends a follow up AE */ /* The server sends a follow up AE */
memset(&ae, 0, sizeof(raft_appendentries_req_t)); memset(&ae, 0, sizeof(raft_appendentries_req_t));
ae.term = 1; ae.term = 1;
...@@ -1978,6 +2207,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries( ...@@ -1978,6 +2207,11 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries(
ae.leader_commit = 4; ae.leader_commit = 4;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 6, raft_get_current_idx(r)); CuAssertIntEquals(tc, 6, raft_get_current_idx(r));
CuAssertIntEquals(tc, 4, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 4, raft_get_commit_idx(r));
...@@ -1995,8 +2229,15 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries( ...@@ -1995,8 +2229,15 @@ void TestRaft_follower_recv_appendentries_does_not_deleted_commited_entries(
ae.leader_commit = 4; ae.leader_commit = 4;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, 6, raft_get_current_idx(r)); CuAssertIntEquals(tc, 6, raft_get_current_idx(r));
raft_destroy(r);
} }
void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc) void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc)
...@@ -2010,6 +2251,8 @@ void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc) ...@@ -2010,6 +2251,8 @@ void TestRaft_candidate_becomes_candidate_is_candidate(CuTest * tc)
raft_add_node(r, NULL, 1, 1); raft_add_node(r, NULL, 1, 1);
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, raft_is_candidate(r)); CuAssertTrue(tc, raft_is_candidate(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2026,6 +2269,8 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc) ...@@ -2026,6 +2269,8 @@ void TestRaft_follower_becoming_candidate_increments_current_term(CuTest * tc)
CuAssertTrue(tc, 0 == raft_get_current_term(r)); CuAssertTrue(tc, 0 == raft_get_current_term(r));
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 1 == raft_get_current_term(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2043,6 +2288,8 @@ void TestRaft_follower_becoming_candidate_votes_for_self(CuTest * tc) ...@@ -2043,6 +2288,8 @@ void TestRaft_follower_becoming_candidate_votes_for_self(CuTest * tc)
raft_become_candidate(r); raft_become_candidate(r);
CuAssertTrue(tc, raft_get_nodeid(r) == raft_get_voted_for(r)); CuAssertTrue(tc, raft_get_nodeid(r) == raft_get_voted_for(r));
CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r)); CuAssertTrue(tc, 1 == raft_get_nvotes_for_me(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2066,6 +2313,8 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc) ...@@ -2066,6 +2313,8 @@ void TestRaft_follower_becoming_candidate_resets_election_timeout(CuTest * tc)
raft_become_candidate(r); raft_become_candidate(r);
/* time is selected randomly */ /* time is selected randomly */
CuAssertTrue(tc, raft_get_timeout_elapsed(r) < 1000); CuAssertTrue(tc, raft_get_timeout_elapsed(r) < 1000);
raft_destroy(r);
} }
void TestRaft_follower_recv_appendentries_resets_election_timeout( void TestRaft_follower_recv_appendentries_resets_election_timeout(
...@@ -2091,6 +2340,8 @@ void TestRaft_follower_recv_appendentries_resets_election_timeout( ...@@ -2091,6 +2340,8 @@ void TestRaft_follower_recv_appendentries_resets_election_timeout(
ae.term = 1; ae.term = 1;
raft_recv_appendentries(r, raft_get_node(r, 1), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 1), &ae, &aer);
CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2121,10 +2372,15 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers( ...@@ -2121,10 +2372,15 @@ void TestRaft_follower_becoming_candidate_requests_votes_from_other_servers(
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 2 != rv->term); CuAssertTrue(tc, 2 != rv->term);
CuAssertTrue(tc, 3 == rv->term); CuAssertTrue(tc, 3 == rv->term);
raft_free(rv);
/* TODO: there should be more items */ /* TODO: there should be more items */
rv = sender_poll_msg_data(sender); rv = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertTrue(tc, 3 == rv->term); CuAssertTrue(tc, 3 == rv->term);
raft_free(rv);
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2171,6 +2427,8 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election( ...@@ -2171,6 +2427,8 @@ void TestRaft_candidate_election_timeout_and_no_leader_results_in_new_election(
/* receiving this vote gives the server majority */ /* receiving this vote gives the server majority */
raft_recv_requestvote_response(r, raft_get_node(r, 2), &vr1); raft_recv_requestvote_response(r, raft_get_node(r, 2), &vr1);
CuAssertIntEquals(tc, RAFT_STATE_LEADER, raft_get_state(r)); CuAssertIntEquals(tc, RAFT_STATE_LEADER, raft_get_state(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2213,6 +2471,8 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc) ...@@ -2213,6 +2471,8 @@ void TestRaft_candidate_receives_majority_of_votes_becomes_leader(CuTest * tc)
* now has majority (ie. 3/5 votes) */ * now has majority (ie. 3/5 votes) */
raft_recv_requestvote_response(r, raft_get_node(r, 3), &vr); raft_recv_requestvote_response(r, raft_get_node(r, 3), &vr);
CuAssertTrue(tc, 1 == raft_is_leader(r)); CuAssertTrue(tc, 1 == raft_is_leader(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2239,6 +2499,8 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted( ...@@ -2239,6 +2499,8 @@ void TestRaft_candidate_will_not_respond_to_voterequest_if_it_has_already_voted(
/* we've vote already, so won't respond with a vote granted... */ /* we've vote already, so won't respond with a vote granted... */
CuAssertTrue(tc, 0 == rvr.vote_granted); CuAssertTrue(tc, 0 == rvr.vote_granted);
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2264,12 +2526,15 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc) ...@@ -2264,12 +2526,15 @@ void TestRaft_candidate_requestvote_includes_logidx(CuTest * tc)
__RAFT_APPEND_ENTRY(r, 102, 3, "aaa"); __RAFT_APPEND_ENTRY(r, 102, 3, "aaa");
raft_send_requestvote(r, raft_get_node(r, 2)); raft_send_requestvote(r, raft_get_node(r, 2));
raft_requestvote_req_t * rv = sender_poll_msg_data(sender); raft_requestvote_req_t *rv = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != rv); CuAssertTrue(tc, NULL != rv);
CuAssertIntEquals(tc, 3, rv->last_log_idx); CuAssertIntEquals(tc, 3, rv->last_log_idx);
CuAssertIntEquals(tc, 5, rv->term); CuAssertIntEquals(tc, 5, rv->term);
CuAssertIntEquals(tc, 3, rv->last_log_term); CuAssertIntEquals(tc, 3, rv->last_log_term);
CuAssertIntEquals(tc, 1, rv->candidate_id); CuAssertIntEquals(tc, 1, rv->candidate_id);
free(rv);
raft_destroy(r);
} }
void TestRaft_candidate_recv_requestvote_response_becomes_follower_if_current_term_is_less_than_term( void TestRaft_candidate_recv_requestvote_response_becomes_follower_if_current_term_is_less_than_term(
...@@ -2301,6 +2566,8 @@ void TestRaft_candidate_recv_requestvote_response_becomes_follower_if_current_te ...@@ -2301,6 +2566,8 @@ void TestRaft_candidate_recv_requestvote_response_becomes_follower_if_current_te
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
CuAssertTrue(tc, 2 == raft_get_current_term(r)); CuAssertTrue(tc, 2 == raft_get_current_term(r));
CuAssertTrue(tc, -1 == raft_get_voted_for(r)); CuAssertTrue(tc, -1 == raft_get_voted_for(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2336,6 +2603,8 @@ void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower( ...@@ -2336,6 +2603,8 @@ void TestRaft_candidate_recv_appendentries_frm_leader_results_in_follower(
CuAssertTrue(tc, 2 == raft_get_leader_id(r)); CuAssertTrue(tc, 2 == raft_get_leader_id(r));
CuAssertTrue(tc, 1 == raft_get_current_term(r)); CuAssertTrue(tc, 1 == raft_get_current_term(r));
CuAssertTrue(tc, -1 == raft_get_voted_for(r)); CuAssertTrue(tc, -1 == raft_get_voted_for(r));
raft_destroy(r);
} }
/* Candidate 5.2 */ /* Candidate 5.2 */
...@@ -2381,6 +2650,8 @@ void TestRaft_candidate_recv_appendentries_from_same_term_results_in_step_down( ...@@ -2381,6 +2650,8 @@ void TestRaft_candidate_recv_appendentries_from_same_term_results_in_step_down(
* Node self votes for Other2 * Node self votes for Other2
*/ */
CuAssertIntEquals(tc, 1, raft_get_voted_for(r)); CuAssertIntEquals(tc, 1, raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_candidate_recv_appendentries_from_higher_term_results_in_step_down( void TestRaft_candidate_recv_appendentries_from_higher_term_results_in_step_down(
...@@ -2411,6 +2682,8 @@ void TestRaft_candidate_recv_appendentries_from_higher_term_results_in_step_down ...@@ -2411,6 +2682,8 @@ void TestRaft_candidate_recv_appendentries_from_higher_term_results_in_step_down
raft_recv_appendentries(r, raft_get_node(r, 2), &append_req2, &append_resp); raft_recv_appendentries(r, raft_get_node(r, 2), &append_req2, &append_resp);
CuAssertIntEquals(tc, 1, raft_is_follower(r)); CuAssertIntEquals(tc, 1, raft_is_follower(r));
CuAssertIntEquals(tc, 4, raft_get_current_term(r)); CuAssertIntEquals(tc, 4, raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_candidate_recv_snapshot_from_higher_term_results_in_step_down( void TestRaft_candidate_recv_snapshot_from_higher_term_results_in_step_down(
...@@ -2442,6 +2715,8 @@ void TestRaft_candidate_recv_snapshot_from_higher_term_results_in_step_down( ...@@ -2442,6 +2715,8 @@ void TestRaft_candidate_recv_snapshot_from_higher_term_results_in_step_down(
raft_recv_snapshot(r, raft_get_node(r, 2), &snapshot_req2, &snapshot_resp); raft_recv_snapshot(r, raft_get_node(r, 2), &snapshot_req2, &snapshot_resp);
CuAssertIntEquals(tc, 1, raft_is_follower(r)); CuAssertIntEquals(tc, 1, raft_is_follower(r));
CuAssertIntEquals(tc, 6, raft_get_current_term(r)); CuAssertIntEquals(tc, 6, raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_leader_becomes_leader_is_leader(CuTest * tc) void TestRaft_leader_becomes_leader_is_leader(CuTest * tc)
...@@ -2452,6 +2727,8 @@ void TestRaft_leader_becomes_leader_is_leader(CuTest * tc) ...@@ -2452,6 +2727,8 @@ void TestRaft_leader_becomes_leader_is_leader(CuTest * tc)
CuAssertTrue(tc, raft_is_leader(r)); CuAssertTrue(tc, raft_is_leader(r));
CuAssertTrue(tc, raft_get_leader_node(r) == n); CuAssertTrue(tc, raft_get_leader_node(r) == n);
raft_destroy(r);
} }
void TestRaft_leader_becomes_leader_does_not_clear_voted_for(CuTest * tc) void TestRaft_leader_becomes_leader_does_not_clear_voted_for(CuTest * tc)
...@@ -2468,6 +2745,8 @@ void TestRaft_leader_becomes_leader_does_not_clear_voted_for(CuTest * tc) ...@@ -2468,6 +2745,8 @@ void TestRaft_leader_becomes_leader_does_not_clear_voted_for(CuTest * tc)
CuAssertTrue(tc, 1 == raft_get_voted_for(r)); CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_become_leader(r); raft_become_leader(r);
CuAssertTrue(tc, 1 == raft_get_voted_for(r)); CuAssertTrue(tc, 1 == raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog_idx_plus_1( void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog_idx_plus_1(
...@@ -2495,6 +2774,8 @@ void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog ...@@ -2495,6 +2774,8 @@ void TestRaft_leader_when_becomes_leader_all_nodes_have_nextidx_equal_to_lastlog
CuAssertTrue(tc, raft_get_current_idx(r) + 1 == CuAssertTrue(tc, raft_get_current_idx(r) + 1 ==
raft_node_get_next_idx(p)); raft_node_get_next_idx(p));
} }
raft_destroy(r);
} }
/* 5.2 */ /* 5.2 */
...@@ -2518,10 +2799,23 @@ void TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries( ...@@ -2518,10 +2799,23 @@ void TestRaft_leader_when_it_becomes_a_leader_sends_empty_appendentries(
raft_become_leader(r); raft_become_leader(r);
/* receive appendentries messages for both nodes */ /* receive appendentries messages for both nodes */
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t *ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
/* 5.2 /* 5.2
...@@ -2549,10 +2843,18 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc) ...@@ -2549,10 +2843,18 @@ void TestRaft_leader_responds_to_entry_msg_when_entry_is_committed(CuTest * tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
/* trigger response through commit */ /* trigger response through commit */
raft_apply_entry(r); raft_apply_entry(r);
raft_destroy(r);
}
static void read_request_dummy_cb(void *arg, int safe)
{
} }
void TestRaft_non_leader_recv_entry_msg_fails(CuTest * tc) void TestRaft_non_leader_recv_entry_msg_fails(CuTest * tc)
...@@ -2570,11 +2872,14 @@ void TestRaft_non_leader_recv_entry_msg_fails(CuTest * tc) ...@@ -2570,11 +2872,14 @@ void TestRaft_non_leader_recv_entry_msg_fails(CuTest * tc)
/* receive entry */ /* receive entry */
int e = raft_recv_entry(r, ety, &cr); int e = raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertTrue(tc, RAFT_ERR_NOT_LEADER == e); CuAssertTrue(tc, RAFT_ERR_NOT_LEADER == e);
/* receive read request */ /* receive read request */
e = raft_recv_read_request(r, NULL, NULL); e = raft_recv_read_request(r, read_request_dummy_cb, NULL);
CuAssertTrue(tc, RAFT_ERR_NOT_LEADER == e); CuAssertTrue(tc, RAFT_ERR_NOT_LEADER == e);
raft_destroy(r);
} }
/* 5.3 */ /* 5.3 */
...@@ -2602,6 +2907,13 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx( ...@@ -2602,6 +2907,13 @@ void TestRaft_leader_sends_appendentries_with_NextIdx_when_PrevIdx_gt_NextIdx(
raft_send_appendentries(r, p); raft_send_appendentries(r, p);
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t * ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
void TestRaft_leader_sends_appendentries_with_leader_commit( void TestRaft_leader_sends_appendentries_with_leader_commit(
...@@ -2622,10 +2934,7 @@ void TestRaft_leader_sends_appendentries_with_leader_commit( ...@@ -2622,10 +2934,7 @@ void TestRaft_leader_sends_appendentries_with_leader_commit(
raft_set_state(r, RAFT_STATE_LEADER); raft_set_state(r, RAFT_STATE_LEADER);
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
int i; for (int i = 0; i < 10; i++) {
for (i=0; i<10; i++)
{
__RAFT_APPEND_ENTRY(r, 1, 1, "aaa"); __RAFT_APPEND_ENTRY(r, 1, 1, "aaa");
} }
...@@ -2633,9 +2942,16 @@ void TestRaft_leader_sends_appendentries_with_leader_commit( ...@@ -2633,9 +2942,16 @@ void TestRaft_leader_sends_appendentries_with_leader_commit(
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r, raft_get_node(r, 2)); raft_send_appendentries(r, raft_get_node(r, 2));
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t * ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
CuAssertTrue(tc, ae->leader_commit == 10); CuAssertTrue(tc, ae->leader_commit == 10);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
void TestRaft_leader_sends_appendentries_with_prevLogIdx( void TestRaft_leader_sends_appendentries_with_prevLogIdx(
...@@ -2658,10 +2974,16 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx( ...@@ -2658,10 +2974,16 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx(
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r, raft_get_node(r, 2)); raft_send_appendentries(r, raft_get_node(r, 2));
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t * ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
CuAssertIntEquals(tc, 0, ae->prev_log_idx); CuAssertIntEquals(tc, 0, ae->prev_log_idx);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_node_t* n = raft_get_node(r, 2); raft_node_t* n = raft_get_node(r, 2);
/* add 1 entry */ /* add 1 entry */
...@@ -2676,6 +2998,12 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx( ...@@ -2676,6 +2998,12 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx(
CuAssertIntEquals(tc, 100, ae->entries[0]->id); CuAssertIntEquals(tc, 100, ae->entries[0]->id);
CuAssertIntEquals(tc, 2, ae->entries[0]->term); CuAssertIntEquals(tc, 2, ae->entries[0]->term);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
/* set next_idx */ /* set next_idx */
/* receive appendentries messages */ /* receive appendentries messages */
raft_node_set_next_idx(n, 2); raft_node_set_next_idx(n, 2);
...@@ -2683,6 +3011,14 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx( ...@@ -2683,6 +3011,14 @@ void TestRaft_leader_sends_appendentries_with_prevLogIdx(
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
CuAssertTrue(tc, ae->prev_log_idx == 1); CuAssertTrue(tc, ae->prev_log_idx == 1);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0( void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0(
...@@ -2705,7 +3041,12 @@ void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0( ...@@ -2705,7 +3041,12 @@ void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0(
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r, raft_get_node(r, 2)); raft_send_appendentries(r, raft_get_node(r, 2));
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t *ae = sender_poll_msg_data(sender);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
/* add an entry */ /* add an entry */
/* receive appendentries messages */ /* receive appendentries messages */
...@@ -2716,6 +3057,14 @@ void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0( ...@@ -2716,6 +3057,14 @@ void TestRaft_leader_sends_appendentries_when_node_has_next_idx_of_0(
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
CuAssertTrue(tc, ae->prev_log_idx == 0); CuAssertTrue(tc, ae->prev_log_idx == 0);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc) void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc)
...@@ -2738,7 +3087,12 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc) ...@@ -2738,7 +3087,12 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc)
/* receive appendentries messages */ /* receive appendentries messages */
raft_node_t* n = raft_get_node(r, 2); raft_node_t* n = raft_get_node(r, 2);
raft_send_appendentries(r, n); raft_send_appendentries(r, n);
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t *ae = sender_poll_msg_data(sender);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_node_set_next_idx(n, 1); raft_node_set_next_idx(n, 1);
__RAFT_APPEND_ENTRY(r, 100, 1, "aaa"); __RAFT_APPEND_ENTRY(r, 100, 1, "aaa");
...@@ -2748,6 +3102,11 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc) ...@@ -2748,6 +3102,11 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc)
CuAssertIntEquals(tc, 0,ae->prev_log_idx); CuAssertIntEquals(tc, 0,ae->prev_log_idx);
CuAssertIntEquals(tc, 1, ae->n_entries); CuAssertIntEquals(tc, 1, ae->n_entries);
CuAssertIntEquals(tc, 2, raft_node_get_next_idx(n)); CuAssertIntEquals(tc, 2, raft_node_get_next_idx(n));
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_node_set_next_idx(n, 1); raft_node_set_next_idx(n, 1);
__RAFT_APPEND_ENTRY(r, 101, 1, "bbb"); __RAFT_APPEND_ENTRY(r, 101, 1, "bbb");
...@@ -2757,6 +3116,13 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc) ...@@ -2757,6 +3116,13 @@ void TestRaft_leader_updates_next_idx_on_send_ae(CuTest *tc)
CuAssertIntEquals(tc, 0,ae->prev_log_idx); CuAssertIntEquals(tc, 0,ae->prev_log_idx);
CuAssertIntEquals(tc, 2, ae->n_entries); CuAssertIntEquals(tc, 2, ae->n_entries);
CuAssertIntEquals(tc, 3, raft_node_get_next_idx(n)); CuAssertIntEquals(tc, 3, raft_node_get_next_idx(n));
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
/* 5.3 */ /* 5.3 */
...@@ -2779,8 +3145,16 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis ...@@ -2779,8 +3145,16 @@ void TestRaft_leader_retries_appendentries_with_decremented_NextIdx_log_inconsis
/* receive appendentries messages */ /* receive appendentries messages */
raft_send_appendentries(r, raft_get_node(r, 2)); raft_send_appendentries(r, raft_get_node(r, 2));
raft_appendentries_req_t * ae = sender_poll_msg_data(sender); raft_appendentries_req_t *ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
/* /*
...@@ -2804,7 +3178,10 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc) ...@@ -2804,7 +3178,10 @@ void TestRaft_leader_append_entry_to_log_increases_idxno(CuTest * tc)
CuAssertTrue(tc, 0 == raft_get_log_count(r)); CuAssertTrue(tc, 0 == raft_get_log_count(r));
raft_recv_entry(r, ety, NULL); raft_recv_entry(r, ety, NULL);
raft_entry_release(ety);
CuAssertTrue(tc, 1 == raft_get_log_count(r)); CuAssertTrue(tc, 1 == raft_get_log_count(r));
raft_destroy(r);
} }
#if 0 #if 0
...@@ -2905,6 +3282,8 @@ void TestRaft_leader_recv_appendentries_response_increase_commit_idx_when_majori ...@@ -2905,6 +3282,8 @@ void TestRaft_leader_recv_appendentries_response_increase_commit_idx_when_majori
CuAssertIntEquals(tc, 2, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 2, raft_get_commit_idx(r));
raft_periodic_internal(r, 1); raft_periodic_internal(r, 1);
CuAssertIntEquals(tc, 2, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 2, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_for_node( void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_for_node(
...@@ -2953,6 +3332,8 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_for_nod ...@@ -2953,6 +3332,8 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_for_nod
raft_recv_appendentries_response(r, node, &aer); raft_recv_appendentries_response(r, node, &aer);
CuAssertIntEquals(tc, 1, has_sufficient_logs_flag); CuAssertIntEquals(tc, 1, has_sufficient_logs_flag);
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_fail_set_has_sufficient_logs_for_node_if_not_addition_committed( void TestRaft_leader_recv_appendentries_response_fail_set_has_sufficient_logs_for_node_if_not_addition_committed(
...@@ -2996,6 +3377,8 @@ void TestRaft_leader_recv_appendentries_response_fail_set_has_sufficient_logs_fo ...@@ -2996,6 +3377,8 @@ void TestRaft_leader_recv_appendentries_response_fail_set_has_sufficient_logs_fo
raft_node_set_voting(node, 0); raft_node_set_voting(node, 0);
raft_recv_appendentries_response(r, node, &aer); raft_recv_appendentries_response(r, node, &aer);
CuAssertIntEquals(tc, 0, has_sufficient_logs_flag); CuAssertIntEquals(tc, 0, has_sufficient_logs_flag);
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_increase_commit_idx_using_voting_nodes_majority( void TestRaft_leader_recv_appendentries_response_increase_commit_idx_using_voting_nodes_majority(
...@@ -3043,6 +3426,8 @@ void TestRaft_leader_recv_appendentries_response_increase_commit_idx_using_votin ...@@ -3043,6 +3426,8 @@ void TestRaft_leader_recv_appendentries_response_increase_commit_idx_using_votin
/* leader will now have majority followers who have appended this log */ /* leader will now have majority followers who have appended this log */
raft_periodic_internal(r, 1); raft_periodic_internal(r, 1);
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_duplicate_does_not_decrement_match_idx( void TestRaft_leader_recv_appendentries_response_duplicate_does_not_decrement_match_idx(
...@@ -3095,6 +3480,8 @@ void TestRaft_leader_recv_appendentries_response_duplicate_does_not_decrement_ma ...@@ -3095,6 +3480,8 @@ void TestRaft_leader_recv_appendentries_response_duplicate_does_not_decrement_ma
aer.current_idx = 1; aer.current_idx = 1;
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertIntEquals(tc, 2, raft_node_get_match_idx(raft_get_node(r, 2))); CuAssertIntEquals(tc, 2, raft_node_get_match_idx(raft_get_node(r, 2)));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_do_not_increase_commit_idx_because_of_old_terms_with_majority( void TestRaft_leader_recv_appendentries_response_do_not_increase_commit_idx_because_of_old_terms_with_majority(
...@@ -3176,6 +3563,8 @@ void TestRaft_leader_recv_appendentries_response_do_not_increase_commit_idx_beca ...@@ -3176,6 +3563,8 @@ void TestRaft_leader_recv_appendentries_response_do_not_increase_commit_idx_beca
CuAssertIntEquals(tc, 3, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 3, raft_get_commit_idx(r));
raft_periodic_internal(r, 1); raft_periodic_internal(r, 1);
CuAssertIntEquals(tc, 3, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 3, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx( void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx(
...@@ -3214,6 +3603,12 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx( ...@@ -3214,6 +3603,12 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx(
CuAssertIntEquals(tc, 4, ae->prev_log_term); CuAssertIntEquals(tc, 4, ae->prev_log_term);
CuAssertIntEquals(tc, 4, ae->prev_log_idx); CuAssertIntEquals(tc, 4, ae->prev_log_idx);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
/* receive mock success responses */ /* receive mock success responses */
memset(&aer, 0, sizeof(raft_appendentries_resp_t)); memset(&aer, 0, sizeof(raft_appendentries_resp_t));
aer.term = 4; aer.term = 4;
...@@ -3230,6 +3625,12 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx( ...@@ -3230,6 +3625,12 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx(
/* since current_idx is 1, and we are up 5, if it reset next_idx correctly, we should have 4 entries */ /* since current_idx is 1, and we are up 5, if it reset next_idx correctly, we should have 4 entries */
CuAssertIntEquals(tc, 4, ae->n_entries); CuAssertIntEquals(tc, 4, ae->n_entries);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
/* receive mock success responses */ /* receive mock success responses */
memset(&aer, 0, sizeof(raft_appendentries_resp_t)); memset(&aer, 0, sizeof(raft_appendentries_resp_t));
aer.term = 4; aer.term = 4;
...@@ -3238,6 +3639,8 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx( ...@@ -3238,6 +3639,8 @@ void TestRaft_leader_recv_appendentries_response_jumps_to_lower_next_idx(
CuAssertIntEquals(tc, 0, raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer)); CuAssertIntEquals(tc, 0, raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer));
// it's 6 and not 2 because the raft_send_appendentries() that is sent at end of recv_response send the rest // it's 6 and not 2 because the raft_send_appendentries() that is sent at end of recv_response send the rest
CuAssertIntEquals(tc, 6, raft_node_get_next_idx(node)); CuAssertIntEquals(tc, 6, raft_node_get_next_idx(node));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * tc) void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * tc)
...@@ -3267,8 +3670,22 @@ void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * t ...@@ -3267,8 +3670,22 @@ void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * t
raft_send_appendentries(r, raft_get_node(r, 2)); raft_send_appendentries(r, raft_get_node(r, 2));
raft_send_appendentries(r, raft_get_node(r, 3)); raft_send_appendentries(r, raft_get_node(r, 3));
CuAssertTrue(tc, NULL != sender_poll_msg_data(sender)); raft_appendentries_req_t *ae;
CuAssertTrue(tc, NULL != sender_poll_msg_data(sender)); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_become_follower(r); raft_become_follower(r);
...@@ -3280,6 +3697,8 @@ void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * t ...@@ -3280,6 +3697,8 @@ void TestRaft_leader_recv_appendentries_response_retry_only_if_leader(CuTest * t
aer.current_idx = 1; aer.current_idx = 1;
CuAssertTrue(tc, 0 == raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer)); CuAssertTrue(tc, 0 == raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer));
CuAssertTrue(tc, NULL == sender_poll_msg_data(sender)); CuAssertTrue(tc, NULL == sender_poll_msg_data(sender));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_without_node(CuTest *tc) void TestRaft_leader_recv_appendentries_response_without_node(CuTest *tc)
...@@ -3305,6 +3724,8 @@ void TestRaft_leader_recv_appendentries_response_without_node(CuTest *tc) ...@@ -3305,6 +3724,8 @@ void TestRaft_leader_recv_appendentries_response_without_node(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_recv_appendentries_response(r, NULL, &aer)); CuAssertIntEquals(tc, 0, raft_recv_appendentries_response(r, NULL, &aer));
/* Verify response was ignored and term is not 5000. */ /* Verify response was ignored and term is not 5000. */
CuAssertIntEquals(tc, 1, raft_get_current_term(r)); CuAssertIntEquals(tc, 1, raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_snapshot_response_without_node(CuTest *tc) void TestRaft_leader_recv_snapshot_response_without_node(CuTest *tc)
...@@ -3333,6 +3754,8 @@ void TestRaft_leader_recv_snapshot_response_without_node(CuTest *tc) ...@@ -3333,6 +3754,8 @@ void TestRaft_leader_recv_snapshot_response_without_node(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_recv_snapshot_response(r, NULL, &resp)); CuAssertIntEquals(tc, 0, raft_recv_snapshot_response(r, NULL, &resp));
/* Verify response was ignored and term is not 5000. */ /* Verify response was ignored and term is not 5000. */
CuAssertIntEquals(tc, 1, raft_get_current_term(r)); CuAssertIntEquals(tc, 1, raft_get_current_term(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_entry_resets_election_timeout( void TestRaft_leader_recv_entry_resets_election_timeout(
...@@ -3351,7 +3774,10 @@ void TestRaft_leader_recv_entry_resets_election_timeout( ...@@ -3351,7 +3774,10 @@ void TestRaft_leader_recv_entry_resets_election_timeout(
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, mety, &cr); raft_recv_entry(r, mety, &cr);
raft_entry_release(mety);
CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r)); CuAssertTrue(tc, 0 == raft_get_timeout_elapsed(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_entry_is_committed_returns_0_if_not_committed(CuTest * tc) void TestRaft_leader_recv_entry_is_committed_returns_0_if_not_committed(CuTest * tc)
...@@ -3377,10 +3803,13 @@ void TestRaft_leader_recv_entry_is_committed_returns_0_if_not_committed(CuTest * ...@@ -3377,10 +3803,13 @@ void TestRaft_leader_recv_entry_is_committed_returns_0_if_not_committed(CuTest *
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, mety, &cr); raft_recv_entry(r, mety, &cr);
raft_entry_release(mety);
CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr)); CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr));
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
CuAssertTrue(tc, 1 == raft_msg_entry_response_committed(r, &cr)); CuAssertTrue(tc, 1 == raft_msg_entry_response_committed(r, &cr));
raft_destroy(r);
} }
void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest * tc) void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest * tc)
...@@ -3406,6 +3835,8 @@ void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest ...@@ -3406,6 +3835,8 @@ void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, mety, &cr); raft_recv_entry(r, mety, &cr);
raft_entry_release(mety);
CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr)); CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr));
CuAssertTrue(tc, cr.term == 1); CuAssertTrue(tc, cr.term == 1);
CuAssertTrue(tc, cr.idx == 1); CuAssertTrue(tc, cr.idx == 1);
...@@ -3427,6 +3858,13 @@ void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest ...@@ -3427,6 +3858,13 @@ void TestRaft_leader_recv_entry_is_committed_returns_neg_1_if_invalidated(CuTest
CuAssertTrue(tc, 1 == raft_get_current_idx(r)); CuAssertTrue(tc, 1 == raft_get_current_idx(r));
CuAssertTrue(tc, 1 == raft_get_commit_idx(r)); CuAssertTrue(tc, 1 == raft_get_commit_idx(r));
CuAssertTrue(tc, -1 == raft_msg_entry_response_committed(r, &cr)); CuAssertTrue(tc, -1 == raft_msg_entry_response_committed(r, &cr));
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc) void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc)
...@@ -3452,6 +3890,7 @@ void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc ...@@ -3452,6 +3890,7 @@ void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, mety, &cr); raft_recv_entry(r, mety, &cr);
raft_entry_release(mety);
CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr)); CuAssertTrue(tc, 0 == raft_msg_entry_response_committed(r, &cr));
CuAssertTrue(tc, cr.term == 2); CuAssertTrue(tc, cr.term == 2);
CuAssertTrue(tc, cr.idx == 1); CuAssertTrue(tc, cr.idx == 1);
...@@ -3472,6 +3911,13 @@ void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc ...@@ -3472,6 +3911,13 @@ void TestRaft_leader_recv_entry_fails_if_prevlogidx_less_than_commit(CuTest * tc
ae.n_entries = 1; ae.n_entries = 1;
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertIntEquals(tc, 0, aer.success); CuAssertIntEquals(tc, 0, aer.success);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
int backpressure(raft_server_t* raft, void* udata, raft_node_t* node) int backpressure(raft_server_t* raft, void* udata, raft_node_t* node)
...@@ -3510,11 +3956,14 @@ void TestRaft_leader_recv_entry_does_not_send_new_appendentries_to_slow_nodes(Cu ...@@ -3510,11 +3956,14 @@ void TestRaft_leader_recv_entry_does_not_send_new_appendentries_to_slow_nodes(Cu
/* receive entry */ /* receive entry */
raft_entry_resp_t cr; raft_entry_resp_t cr;
raft_recv_entry(r, mety, &cr); raft_recv_entry(r, mety, &cr);
raft_entry_release(mety);
/* check if the slow node got sent this appendentries */ /* check if the slow node got sent this appendentries */
raft_appendentries_req_t * ae; raft_appendentries_req_t * ae;
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL == ae); CuAssertTrue(tc, NULL == ae);
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_failure_does_not_set_node_nextid_to_0( void TestRaft_leader_recv_appendentries_response_failure_does_not_set_node_nextid_to_0(
...@@ -3555,6 +4004,8 @@ void TestRaft_leader_recv_appendentries_response_failure_does_not_set_node_nexti ...@@ -3555,6 +4004,8 @@ void TestRaft_leader_recv_appendentries_response_failure_does_not_set_node_nexti
CuAssertIntEquals(tc, 2, raft_node_get_next_idx(p)); CuAssertIntEquals(tc, 2, raft_node_get_next_idx(p));
raft_recv_appendentries_response(r, p, &aer); raft_recv_appendentries_response(r, p, &aer);
CuAssertIntEquals(tc, 2, raft_node_get_next_idx(p)); CuAssertIntEquals(tc, 2, raft_node_get_next_idx(p));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_increment_idx_of_node( void TestRaft_leader_recv_appendentries_response_increment_idx_of_node(
...@@ -3587,6 +4038,8 @@ void TestRaft_leader_recv_appendentries_response_increment_idx_of_node( ...@@ -3587,6 +4038,8 @@ void TestRaft_leader_recv_appendentries_response_increment_idx_of_node(
aer.current_idx = 0; aer.current_idx = 0;
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertIntEquals(tc, 1, raft_node_get_next_idx(p)); CuAssertIntEquals(tc, 1, raft_node_get_next_idx(p));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_drop_message_if_term_is_old( void TestRaft_leader_recv_appendentries_response_drop_message_if_term_is_old(
...@@ -3612,12 +4065,15 @@ void TestRaft_leader_recv_appendentries_response_drop_message_if_term_is_old( ...@@ -3612,12 +4065,15 @@ void TestRaft_leader_recv_appendentries_response_drop_message_if_term_is_old(
CuAssertTrue(tc, 1 == raft_node_get_next_idx(p)); CuAssertTrue(tc, 1 == raft_node_get_next_idx(p));
/* receive OLD mock success responses */ /* receive OLD mock success responses */
raft_appendentries_resp_t aer; raft_appendentries_resp_t aer = {
aer.term = 1; .term = 1,
aer.success = 1; .success = 1,
aer.current_idx = 1; .current_idx = 1
};
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertTrue(tc, 1 == raft_node_get_next_idx(p)); CuAssertTrue(tc, 1 == raft_node_get_next_idx(p));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_steps_down_if_term_is_newer( void TestRaft_leader_recv_appendentries_response_steps_down_if_term_is_newer(
...@@ -3642,13 +4098,16 @@ void TestRaft_leader_recv_appendentries_response_steps_down_if_term_is_newer( ...@@ -3642,13 +4098,16 @@ void TestRaft_leader_recv_appendentries_response_steps_down_if_term_is_newer(
CuAssertTrue(tc, 1 == raft_node_get_next_idx(p)); CuAssertTrue(tc, 1 == raft_node_get_next_idx(p));
/* receive NEW mock failed responses */ /* receive NEW mock failed responses */
raft_appendentries_resp_t aer; raft_appendentries_resp_t aer = {
aer.term = 3; .term = 3,
aer.success = 0; .success = 0,
aer.current_idx = 2; .current_idx = 2
};
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
CuAssertTrue(tc, -1 == raft_get_leader_id(r)); CuAssertTrue(tc, -1 == raft_get_leader_id(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_steps_down_if_newer( void TestRaft_leader_recv_appendentries_steps_down_if_newer(
...@@ -3684,6 +4143,8 @@ void TestRaft_leader_recv_appendentries_steps_down_if_newer( ...@@ -3684,6 +4143,8 @@ void TestRaft_leader_recv_appendentries_steps_down_if_newer(
* consider node 2 the leader. */ * consider node 2 the leader. */
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
CuAssertTrue(tc, 2 == raft_get_leader_id(r)); CuAssertTrue(tc, 2 == raft_get_leader_id(r));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_steps_down_if_newer_term( void TestRaft_leader_recv_appendentries_steps_down_if_newer_term(
...@@ -3712,6 +4173,8 @@ void TestRaft_leader_recv_appendentries_steps_down_if_newer_term( ...@@ -3712,6 +4173,8 @@ void TestRaft_leader_recv_appendentries_steps_down_if_newer_term(
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == raft_is_follower(r)); CuAssertTrue(tc, 1 == raft_is_follower(r));
raft_destroy(r);
} }
void TestRaft_leader_sends_empty_appendentries_every_request_timeout( void TestRaft_leader_sends_empty_appendentries_every_request_timeout(
...@@ -3740,16 +4203,31 @@ void TestRaft_leader_sends_empty_appendentries_every_request_timeout( ...@@ -3740,16 +4203,31 @@ void TestRaft_leader_sends_empty_appendentries_every_request_timeout(
raft_appendentries_req_t * ae; raft_appendentries_req_t * ae;
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
ae = sender_poll_msg_data(sender); for (raft_index_t i = 0; i < ae->n_entries; i++) {
CuAssertTrue(tc, NULL != ae); raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL == ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
/* force request timeout */ /* force request timeout */
raft_periodic_internal(r, 501); raft_periodic_internal(r, 501);
ae = sender_poll_msg_data(sender); ae = sender_poll_msg_data(sender);
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
/* TODO: If a server receives a request with a stale term number, it rejects the request. */ /* TODO: If a server receives a request with a stale term number, it rejects the request. */
...@@ -3803,6 +4281,8 @@ void TestRaft_leader_recv_requestvote_responds_without_granting(CuTest * tc) ...@@ -3803,6 +4281,8 @@ void TestRaft_leader_recv_requestvote_responds_without_granting(CuTest * tc)
raft_recv_requestvote(r, raft_get_node(r, 3), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 3), &rv, &rvr);
CuAssertTrue(tc, 0 == rvr.vote_granted); CuAssertTrue(tc, 0 == rvr.vote_granted);
raft_destroy(r);
} }
#if 0 #if 0
...@@ -3892,6 +4372,8 @@ void TestRaft_leader_recv_entry_add_nonvoting_node_remove_and_revert(CuTest *tc) ...@@ -3892,6 +4372,8 @@ void TestRaft_leader_recv_entry_add_nonvoting_node_remove_and_revert(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_delete_entry_from_idx(r, etyr.idx)); CuAssertIntEquals(tc, 0, raft_delete_entry_from_idx(r, etyr.idx));
CuAssertIntEquals(tc, 1, raft_node_is_active(raft_get_node(r, 3))); CuAssertIntEquals(tc, 1, raft_node_is_active(raft_get_node(r, 3)));
CuAssertIntEquals(tc, 0, raft_node_is_voting(raft_get_node(r, 3))); CuAssertIntEquals(tc, 0, raft_node_is_voting(raft_get_node(r, 3)));
raft_destroy(r);
} }
void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_voting_committed( void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_voting_committed(
...@@ -3924,10 +4406,12 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v ...@@ -3924,10 +4406,12 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v
ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE; ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE;
raft_entry_resp_t etyr; raft_entry_resp_t etyr;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &etyr)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &etyr));
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "3"); ety = __MAKE_ENTRY(2, 1, "3");
ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE; ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &etyr)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &etyr));
raft_entry_release(ety);
raft_appendentries_resp_t aer = { raft_appendentries_resp_t aer = {
.term = 1, .success = 1, .current_idx = 2 .term = 1, .success = 1, .current_idx = 2
...@@ -3941,6 +4425,7 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v ...@@ -3941,6 +4425,7 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v
ety = __MAKE_ENTRY(3, 1, "3"); ety = __MAKE_ENTRY(3, 1, "3");
ety->type = RAFT_LOGTYPE_ADD_NODE; ety->type = RAFT_LOGTYPE_ADD_NODE;
raft_recv_entry(r, ety, &etyr); raft_recv_entry(r, ety, &etyr);
raft_entry_release(ety);
/* we now get a response from node 2, but it's still behind */ /* we now get a response from node 2, but it's still behind */
raft_node_set_addition_committed(raft_get_node(r, 2), 1); raft_node_set_addition_committed(raft_get_node(r, 2), 1);
...@@ -3960,6 +4445,8 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v ...@@ -3960,6 +4445,8 @@ void TestRaft_leader_recv_appendentries_response_set_has_sufficient_logs_after_v
CuAssertIntEquals(tc, 1, has_sufficient_logs_flag); CuAssertIntEquals(tc, 1, has_sufficient_logs_flag);
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertIntEquals(tc, 2, has_sufficient_logs_flag); CuAssertIntEquals(tc, 2, has_sufficient_logs_flag);
raft_destroy(r);
} }
struct read_request_arg { struct read_request_arg {
...@@ -4042,6 +4529,8 @@ void TestRaft_read_action_callback( ...@@ -4042,6 +4529,8 @@ void TestRaft_read_action_callback(
raft_periodic_internal(r, 1); raft_periodic_internal(r, 1);
CuAssertIntEquals(tc, 1, ra.calls); CuAssertIntEquals(tc, 1, ra.calls);
CuAssertIntEquals(tc, 0, ra.last_cb_safe); CuAssertIntEquals(tc, 0, ra.last_cb_safe);
raft_destroy(r);
} }
void single_node_commits_noop_cb(void* arg, int can_read) void single_node_commits_noop_cb(void* arg, int can_read)
...@@ -4065,6 +4554,8 @@ void TestRaft_single_node_commits_noop(CuTest * tc) ...@@ -4065,6 +4554,8 @@ void TestRaft_single_node_commits_noop(CuTest * tc)
CuAssertIntEquals(tc, 1, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 1, raft_get_commit_idx(r));
CuAssertStrEquals(tc, "success", str); CuAssertStrEquals(tc, "success", str);
raft_destroy(r);
} }
/* /*
...@@ -4105,6 +4596,8 @@ void TestRaft_server_recv_requestvote_with_transfer_node(CuTest * tc) ...@@ -4105,6 +4596,8 @@ void TestRaft_server_recv_requestvote_with_transfer_node(CuTest * tc)
rv.prevote = 0; rv.prevote = 0;
raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr); raft_recv_requestvote(r, raft_get_node(r, 2), &rv, &rvr);
CuAssertTrue(tc, 1 == rvr.vote_granted); CuAssertTrue(tc, 1 == rvr.vote_granted);
raft_destroy(r);
} }
/* /*
...@@ -4125,6 +4618,8 @@ void TestRaft_targeted_node_becomes_candidate_when_before_real_timeout_occurs(Cu ...@@ -4125,6 +4618,8 @@ void TestRaft_targeted_node_becomes_candidate_when_before_real_timeout_occurs(Cu
raft_timeout_now(r); raft_timeout_now(r);
CuAssertTrue(tc, 1 == raft_is_candidate(r)); CuAssertTrue(tc, 1 == raft_is_candidate(r));
raft_destroy(r);
} }
void quorum_msg_id_correctness_cb(void* arg, int can_read) void quorum_msg_id_correctness_cb(void* arg, int can_read)
...@@ -4181,6 +4676,8 @@ void TestRaft_quorum_msg_id_correctness(CuTest * tc) ...@@ -4181,6 +4676,8 @@ void TestRaft_quorum_msg_id_correctness(CuTest * tc)
raft_node_set_match_msgid(raft_get_node(r, 3), 2); raft_node_set_match_msgid(raft_get_node(r, 3), 2);
raft_periodic_internal(r, 200); raft_periodic_internal(r, 200);
CuAssertIntEquals(tc, 1, val); CuAssertIntEquals(tc, 1, val);
raft_destroy(r);
} }
int timeoutnow_sent = 0; int timeoutnow_sent = 0;
...@@ -4225,6 +4722,8 @@ void TestRaft_callback_timeoutnow_at_set_if_up_to_date(CuTest *tc) ...@@ -4225,6 +4722,8 @@ void TestRaft_callback_timeoutnow_at_set_if_up_to_date(CuTest *tc)
ret = raft_transfer_leader(r, 2, 0); ret = raft_transfer_leader(r, 2, 0);
CuAssertIntEquals(tc, 0, ret); CuAssertIntEquals(tc, 0, ret);
CuAssertTrue(tc, 1 == timeoutnow_sent); CuAssertTrue(tc, 1 == timeoutnow_sent);
raft_destroy(r);
} }
void TestRaft_callback_timeoutnow_at_send_appendentries_response_if_up_to_date(CuTest *tc) void TestRaft_callback_timeoutnow_at_send_appendentries_response_if_up_to_date(CuTest *tc)
...@@ -4265,6 +4764,8 @@ void TestRaft_callback_timeoutnow_at_send_appendentries_response_if_up_to_date(C ...@@ -4265,6 +4764,8 @@ void TestRaft_callback_timeoutnow_at_send_appendentries_response_if_up_to_date(C
/* Verify we won't send timeout now message twice. */ /* Verify we won't send timeout now message twice. */
raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer); raft_recv_appendentries_response(r, raft_get_node(r, 2), &aer);
CuAssertTrue(tc, 1 == timeoutnow_sent); CuAssertTrue(tc, 1 == timeoutnow_sent);
raft_destroy(r);
} }
void TestRaft_leader_steps_down_if_there_is_no_quorum(CuTest * tc) void TestRaft_leader_steps_down_if_there_is_no_quorum(CuTest * tc)
...@@ -4317,6 +4818,8 @@ void TestRaft_leader_steps_down_if_there_is_no_quorum(CuTest * tc) ...@@ -4317,6 +4818,8 @@ void TestRaft_leader_steps_down_if_there_is_no_quorum(CuTest * tc)
// No ack along quorum_timeout, leader will step down. // No ack along quorum_timeout, leader will step down.
raft_periodic_internal(r, quorum_timeout + 1); raft_periodic_internal(r, quorum_timeout + 1);
CuAssertTrue(tc, !raft_is_leader(r)); CuAssertTrue(tc, !raft_is_leader(r));
raft_destroy(r);
} }
void TestRaft_vote_for_unknown_node(CuTest * tc) void TestRaft_vote_for_unknown_node(CuTest * tc)
...@@ -4413,6 +4916,11 @@ void TestRaft_unknown_node_can_become_leader(CuTest * tc) ...@@ -4413,6 +4916,11 @@ void TestRaft_unknown_node_can_become_leader(CuTest * tc)
CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id); CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id);
CuAssertTrue(tc, resp.success == 1); CuAssertTrue(tc, resp.success == 1);
for (raft_index_t i = 0; i < req_append.n_entries; i++) {
raft_entry_release(req_append.entries[i]);
}
raft_free(req_append.entries);
// Send another req with incremented leader_commit to commit the addition // Send another req with incremented leader_commit to commit the addition
raft_appendentries_req_t req_commit = { raft_appendentries_req_t req_commit = {
.term = 1, .term = 1,
...@@ -4457,6 +4965,11 @@ void TestRaft_unknown_node_can_become_leader(CuTest * tc) ...@@ -4457,6 +4965,11 @@ void TestRaft_unknown_node_can_become_leader(CuTest * tc)
CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id); CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id);
CuAssertTrue(tc, resp.success == 1); CuAssertTrue(tc, resp.success == 1);
for (raft_index_t i = 0; i < req_add_node.n_entries; i++) {
raft_entry_release(req_add_node.entries[i]);
}
raft_free(req_add_node.entries);
raft_periodic_internal(r, 1000); raft_periodic_internal(r, 1000);
CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id); CuAssertIntEquals(tc, raft_get_leader_id(r), req_append.leader_id);
CuAssertTrue(tc, resp.success == 1); CuAssertTrue(tc, resp.success == 1);
...@@ -4489,6 +5002,7 @@ void TestRaft_removed_node_starts_election(CuTest * tc) ...@@ -4489,6 +5002,7 @@ void TestRaft_removed_node_starts_election(CuTest * tc)
entry->type = RAFT_LOGTYPE_REMOVE_NODE; entry->type = RAFT_LOGTYPE_REMOVE_NODE;
raft_recv_entry(r, entry, &entry_resp); raft_recv_entry(r, entry, &entry_resp);
raft_entry_release(entry);
CuAssertTrue(r, raft_is_leader(r)); CuAssertTrue(r, raft_is_leader(r));
CuAssertTrue(r, !raft_node_is_active(n1)); CuAssertTrue(r, !raft_node_is_active(n1));
CuAssertTrue(r, raft_node_is_active(n2)); CuAssertTrue(r, raft_node_is_active(n2));
...@@ -4546,11 +5060,14 @@ void TestRaft_verify_append_entries_fields_are_set(CuTest * tc) ...@@ -4546,11 +5060,14 @@ void TestRaft_verify_append_entries_fields_are_set(CuTest * tc)
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_entry_release(ety);
raft_set_current_term(r, 300); raft_set_current_term(r, 300);
raft_set_commit_idx(r, 4); raft_set_commit_idx(r, 4);
raft_node_set_next_idx(raft_get_node(r, 2), 2); raft_node_set_next_idx(raft_get_node(r, 2), 2);
raft_send_appendentries_all(r); raft_send_appendentries_all(r);
raft_destroy(r);
} }
void cb_notify_transfer_event(raft_server_t *raft, void *udata, raft_leader_transfer_e state) void cb_notify_transfer_event(raft_server_t *raft, void *udata, raft_leader_transfer_e state)
...@@ -4590,6 +5107,8 @@ void Test_reset_transfer_leader(CuTest *tc) ...@@ -4590,6 +5107,8 @@ void Test_reset_transfer_leader(CuTest *tc)
CuAssertIntEquals(tc, 0, ret); CuAssertIntEquals(tc, 0, ret);
raft_periodic_internal(r, 2); raft_periodic_internal(r, 2);
CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_TIMEOUT, state); CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_TIMEOUT, state);
raft_destroy(r);
} }
void Test_transfer_leader_success(CuTest *tc) void Test_transfer_leader_success(CuTest *tc)
...@@ -4616,6 +5135,8 @@ void Test_transfer_leader_success(CuTest *tc) ...@@ -4616,6 +5135,8 @@ void Test_transfer_leader_success(CuTest *tc)
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_EXPECTED_LEADER, state); CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_EXPECTED_LEADER, state);
raft_destroy(r);
} }
void Test_transfer_leader_unexpected(CuTest *tc) void Test_transfer_leader_unexpected(CuTest *tc)
...@@ -4644,6 +5165,8 @@ void Test_transfer_leader_unexpected(CuTest *tc) ...@@ -4644,6 +5165,8 @@ void Test_transfer_leader_unexpected(CuTest *tc)
raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer); raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer);
CuAssertTrue(tc, 1 == aer.success); CuAssertTrue(tc, 1 == aer.success);
CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_UNEXPECTED_LEADER, state); CuAssertIntEquals(tc, RAFT_LEADER_TRANSFER_UNEXPECTED_LEADER, state);
raft_destroy(r);
} }
void Test_transfer_leader_not_leader(CuTest *tc) void Test_transfer_leader_not_leader(CuTest *tc)
...@@ -4656,6 +5179,8 @@ void Test_transfer_leader_not_leader(CuTest *tc) ...@@ -4656,6 +5179,8 @@ void Test_transfer_leader_not_leader(CuTest *tc)
int ret = raft_transfer_leader(r, 3, 0); int ret = raft_transfer_leader(r, 3, 0);
CuAssertIntEquals(tc, RAFT_ERR_NOT_LEADER, ret); CuAssertIntEquals(tc, RAFT_ERR_NOT_LEADER, ret);
raft_destroy(r);
} }
void Test_transfer_automatic(CuTest *tc) void Test_transfer_automatic(CuTest *tc)
...@@ -4683,6 +5208,8 @@ void Test_transfer_automatic(CuTest *tc) ...@@ -4683,6 +5208,8 @@ void Test_transfer_automatic(CuTest *tc)
CuAssertIntEquals(tc, 0, ret); CuAssertIntEquals(tc, 0, ret);
CuAssertIntEquals(tc, 3, raft_get_transfer_leader(r)); CuAssertIntEquals(tc, 3, raft_get_transfer_leader(r));
raft_destroy(r);
} }
void TestRaft_config(CuTest *tc) void TestRaft_config(CuTest *tc)
...@@ -4722,6 +5249,8 @@ void TestRaft_config(CuTest *tc) ...@@ -4722,6 +5249,8 @@ void TestRaft_config(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_config(r, 1, RAFT_CONFIG_DISABLE_APPLY, 1)); CuAssertIntEquals(tc, 0, raft_config(r, 1, RAFT_CONFIG_DISABLE_APPLY, 1));
CuAssertIntEquals(tc, 0, raft_config(r, 0, RAFT_CONFIG_DISABLE_APPLY, &tmp)); CuAssertIntEquals(tc, 0, raft_config(r, 0, RAFT_CONFIG_DISABLE_APPLY, &tmp));
CuAssertIntEquals(tc, 1, val); CuAssertIntEquals(tc, 1, val);
raft_destroy(r);
} }
static int cb_send_ae(raft_server_t *raft, void *udata, raft_node_t *node, static int cb_send_ae(raft_server_t *raft, void *udata, raft_node_t *node,
...@@ -4777,6 +5306,8 @@ void TestRaft_limit_appendentries_size(CuTest *tc) ...@@ -4777,6 +5306,8 @@ void TestRaft_limit_appendentries_size(CuTest *tc)
* 10 entries. */ * 10 entries. */
raft_send_appendentries_all(r); raft_send_appendentries_all(r);
CuAssertIntEquals(tc, 20, appendentries_msg_count); CuAssertIntEquals(tc, 20, appendentries_msg_count);
raft_destroy(r);
} }
static int cb_sendmsg(raft_server_t *raft, void *udata, raft_node_t *node, static int cb_sendmsg(raft_server_t *raft, void *udata, raft_node_t *node,
...@@ -4808,7 +5339,7 @@ void TestRaft_flush_sends_msg(CuTest *tc) ...@@ -4808,7 +5339,7 @@ void TestRaft_flush_sends_msg(CuTest *tc)
raft_set_current_term(r, 1); raft_set_current_term(r, 1);
raft_become_leader(r); raft_become_leader(r);
raft_recv_read_request(r, NULL, NULL); raft_recv_read_request(r, read_request_dummy_cb, NULL);
/* Verify that we send appendentries if the next msgid of a node equals /* Verify that we send appendentries if the next msgid of a node equals
* to the last read request's msgid. */ * to the last read request's msgid. */
...@@ -4818,6 +5349,8 @@ void TestRaft_flush_sends_msg(CuTest *tc) ...@@ -4818,6 +5349,8 @@ void TestRaft_flush_sends_msg(CuTest *tc)
int msg_send = appendentries_msg_count; int msg_send = appendentries_msg_count;
raft_flush(r, 0); raft_flush(r, 0);
CuAssertIntEquals(tc, msg_send + 1, appendentries_msg_count); CuAssertIntEquals(tc, msg_send + 1, appendentries_msg_count);
raft_destroy(r);
} }
void TestRaft_recv_appendentries_does_not_change_next_idx(CuTest *tc) void TestRaft_recv_appendentries_does_not_change_next_idx(CuTest *tc)
...@@ -4860,6 +5393,8 @@ void TestRaft_recv_appendentries_does_not_change_next_idx(CuTest *tc) ...@@ -4860,6 +5393,8 @@ void TestRaft_recv_appendentries_does_not_change_next_idx(CuTest *tc)
CuAssertIntEquals(tc, 201, raft_node_get_next_idx(node)); CuAssertIntEquals(tc, 201, raft_node_get_next_idx(node));
CuAssertIntEquals(tc, 21, raft_node_get_next_msgid(node)); CuAssertIntEquals(tc, 21, raft_node_get_next_msgid(node));
raft_destroy(r);
} }
#define OPERATION_DURATION 10000 /* milliseconds */ #define OPERATION_DURATION 10000 /* milliseconds */
...@@ -4916,6 +5451,8 @@ void TestRaft_apply_entry_timeout(CuTest *tc) ...@@ -4916,6 +5451,8 @@ void TestRaft_apply_entry_timeout(CuTest *tc)
raft_exec_operations(r); raft_exec_operations(r);
CuAssertIntEquals(tc, 0, raft_pending_operations(r)); CuAssertIntEquals(tc, 0, raft_pending_operations(r));
CuAssertIntEquals(tc, 21, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 21, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void read_request(void *arg, int can_read) void read_request(void *arg, int can_read)
...@@ -4965,6 +5502,8 @@ void TestRaft_apply_read_request_timeout(CuTest *tc) ...@@ -4965,6 +5502,8 @@ void TestRaft_apply_read_request_timeout(CuTest *tc)
raft_exec_operations(r); raft_exec_operations(r);
CuAssertIntEquals(tc, 0, raft_pending_operations(r)); CuAssertIntEquals(tc, 0, raft_pending_operations(r));
CuAssertIntEquals(tc, 0, remaining); CuAssertIntEquals(tc, 0, remaining);
raft_destroy(r);
} }
...@@ -5004,6 +5543,8 @@ void TestRaft_test_metadata_on_restart(CuTest *tc) ...@@ -5004,6 +5543,8 @@ void TestRaft_test_metadata_on_restart(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_restore_metadata(r, test_term, test_vote)); CuAssertIntEquals(tc, 0, raft_restore_metadata(r, test_term, test_vote));
CuAssertIntEquals(tc, 1, raft_get_current_term(r)); CuAssertIntEquals(tc, 1, raft_get_current_term(r));
CuAssertIntEquals(tc, 10, raft_get_voted_for(r)); CuAssertIntEquals(tc, 10, raft_get_voted_for(r));
raft_destroy(r);
} }
void TestRaft_rebuild_config_after_restart(CuTest *tc) void TestRaft_rebuild_config_after_restart(CuTest *tc)
...@@ -5024,22 +5565,28 @@ void TestRaft_rebuild_config_after_restart(CuTest *tc) ...@@ -5024,22 +5565,28 @@ void TestRaft_rebuild_config_after_restart(CuTest *tc)
raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "1"); raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "1");
ety->type = RAFT_LOGTYPE_ADD_NODE; ety->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertTrue(tc, 0 == raft_recv_entry(r, ety, NULL)); CuAssertTrue(tc, 0 == raft_recv_entry(r, ety, NULL));
raft_entry_release(ety);
raft_periodic_internal(r, 2000); raft_periodic_internal(r, 2000);
raft_entry_t *ety2 = __MAKE_ENTRY(2, 1, "2"); raft_entry_t *ety2 = __MAKE_ENTRY(2, 1, "2");
ety2->type = RAFT_LOGTYPE_ADD_NODE; ety2->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertTrue(tc, 0 == raft_recv_entry(r, ety2, NULL)); CuAssertTrue(tc, 0 == raft_recv_entry(r, ety2, NULL));
raft_entry_release(ety2);
raft_entry_t *ety3 = __MAKE_ENTRY(3, 1, "3"); raft_entry_t *ety3 = __MAKE_ENTRY(3, 1, "3");
ety3->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE; ety3->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE;
CuAssertTrue(tc, 0 == raft_recv_entry(r, ety3, NULL)); CuAssertTrue(tc, 0 == raft_recv_entry(r, ety3, NULL));
raft_entry_release(ety3);
/* Cluster has three nodes in the configuration now. A bit hacky but let's /* Cluster has three nodes in the configuration now. A bit hacky but let's
* create another server and use first server's log implementation for the * create another server and use first server's log implementation for the
* new server. We are just simulating the restart scenario. Normally, new * new server. We are just simulating the restart scenario. Normally, new
* server would read log entries from the disk. */ * server would read log entries from the disk. */
raft_server_t *r2 = raft_new(); raft_server_t *r2 = raft_new();
raft_log_free(r2->log);
r2->log = raft_get_log(r); r2->log = raft_get_log(r);
r->log = NULL;
raft_set_callbacks(r2, &funcs, NULL); raft_set_callbacks(r2, &funcs, NULL);
raft_add_non_voting_node(r2, NULL, 1, 1); raft_add_non_voting_node(r2, NULL, 1, 1);
...@@ -5057,6 +5604,9 @@ void TestRaft_rebuild_config_after_restart(CuTest *tc) ...@@ -5057,6 +5604,9 @@ void TestRaft_rebuild_config_after_restart(CuTest *tc)
CuAssertIntEquals(tc, raft_node_is_active(n1), raft_node_is_active(n2)); CuAssertIntEquals(tc, raft_node_is_active(n1), raft_node_is_active(n2));
CuAssertIntEquals(tc, raft_node_is_voting(n1), raft_node_is_voting(n2)); CuAssertIntEquals(tc, raft_node_is_voting(n1), raft_node_is_voting(n2));
} }
raft_destroy(r);
raft_destroy(r2);
} }
void TestRaft_delete_configuration_change_entries(CuTest *tc) void TestRaft_delete_configuration_change_entries(CuTest *tc)
...@@ -5084,6 +5634,7 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc) ...@@ -5084,6 +5634,7 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc)
raft_entry_t *ety = __MAKE_ENTRY(1, 1, "3"); raft_entry_t *ety = __MAKE_ENTRY(1, 1, "3");
ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE; ety->type = RAFT_LOGTYPE_ADD_NONVOTING_NODE;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL));
raft_entry_release(ety);
/* If there idx is out of bounds, delete should return immediately. */ /* If there idx is out of bounds, delete should return immediately. */
CuAssertIntEquals(tc, 0, raft_delete_entry_from_idx(r, 3)); CuAssertIntEquals(tc, 0, raft_delete_entry_from_idx(r, 3));
...@@ -5092,6 +5643,7 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc) ...@@ -5092,6 +5643,7 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc)
ety = __MAKE_ENTRY(1, 1, "3"); ety = __MAKE_ENTRY(1, 1, "3");
ety->type = RAFT_LOGTYPE_REMOVE_NODE; ety->type = RAFT_LOGTYPE_REMOVE_NODE;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL));
raft_entry_release(ety);
/* Another configuration change entry should be rejected. */ /* Another configuration change entry should be rejected. */
ety = __MAKE_ENTRY(1, 1, "4"); ety = __MAKE_ENTRY(1, 1, "4");
...@@ -5112,6 +5664,9 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc) ...@@ -5112,6 +5664,9 @@ void TestRaft_delete_configuration_change_entries(CuTest *tc)
/* Configuration change entry should be accepted now. */ /* Configuration change entry should be accepted now. */
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL));
raft_entry_release(ety);
raft_destroy(r);
} }
static int fail_sequence = 0; static int fail_sequence = 0;
...@@ -5151,6 +5706,8 @@ void TestRaft_propagate_persist_metadata_failure(CuTest *tc) ...@@ -5151,6 +5706,8 @@ void TestRaft_propagate_persist_metadata_failure(CuTest *tc)
fail_sequence = 0; fail_sequence = 0;
e = raft_begin_load_snapshot(r, 2, 10); e = raft_begin_load_snapshot(r, 2, 10);
CuAssertIntEquals(tc, e, -1); CuAssertIntEquals(tc, e, -1);
raft_destroy(r);
} }
void TestRaft_reject_config_change_before_log_replay(CuTest *tc) void TestRaft_reject_config_change_before_log_replay(CuTest *tc)
...@@ -5168,11 +5725,15 @@ void TestRaft_reject_config_change_before_log_replay(CuTest *tc) ...@@ -5168,11 +5725,15 @@ void TestRaft_reject_config_change_before_log_replay(CuTest *tc)
raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "1"); raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "1");
ety->type = RAFT_LOGTYPE_ADD_NODE; ety->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, NULL));
raft_entry_release(ety);
raft_periodic_internal(r, 2000); raft_periodic_internal(r, 2000);
/* To simulate restart, restore log with the first node's data.*/ /* To simulate restart, restore log with the first node's data.*/
raft_server_t *r2 = raft_new(); raft_server_t *r2 = raft_new();
raft_log_free(r2->log);
r2->log = raft_get_log(r); r2->log = raft_get_log(r);
r->log = NULL;
raft_set_callbacks(r2, &funcs, NULL); raft_set_callbacks(r2, &funcs, NULL);
raft_add_non_voting_node(r2, NULL, 1, 1); raft_add_non_voting_node(r2, NULL, 1, 1);
...@@ -5200,6 +5761,10 @@ void TestRaft_reject_config_change_before_log_replay(CuTest *tc) ...@@ -5200,6 +5761,10 @@ void TestRaft_reject_config_change_before_log_replay(CuTest *tc)
CuAssertIntEquals(tc, 0, raft_recv_entry(r2, ety, NULL)); CuAssertIntEquals(tc, 0, raft_recv_entry(r2, ety, NULL));
CuAssertIntEquals(tc, RAFT_ERR_ONE_VOTING_CHANGE_ONLY, CuAssertIntEquals(tc, RAFT_ERR_ONE_VOTING_CHANGE_ONLY,
raft_recv_entry(r2, ety, NULL)); raft_recv_entry(r2, ety, NULL));
raft_entry_release(ety);
raft_destroy(r);
raft_destroy(r2);
} }
int main(void) int main(void)
...@@ -5364,5 +5929,10 @@ int main(void) ...@@ -5364,5 +5929,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
...@@ -226,14 +226,19 @@ void TestRaft_leader_begin_snapshot_fails_if_no_logs_to_compact(CuTest * tc) ...@@ -226,14 +226,19 @@ void TestRaft_leader_begin_snapshot_fails_if_no_logs_to_compact(CuTest * tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
CuAssertIntEquals(tc, -1, raft_begin_snapshot(r)); CuAssertIntEquals(tc, -1, raft_begin_snapshot(r));
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
CuAssertIntEquals(tc, 0, raft_begin_snapshot(r)); CuAssertIntEquals(tc, 0, raft_begin_snapshot(r));
raft_destroy(r);
} }
void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc) void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc)
...@@ -260,6 +265,7 @@ void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc ...@@ -260,6 +265,7 @@ void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
...@@ -268,6 +274,8 @@ void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc ...@@ -268,6 +274,8 @@ void TestRaft_leader_will_not_apply_entry_if_snapshot_is_in_progress(CuTest * tc
raft_set_commit_idx(r, 2); raft_set_commit_idx(r, 2);
CuAssertIntEquals(tc, -1, raft_apply_entry(r)); CuAssertIntEquals(tc, -1, raft_apply_entry(r));
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_leader_snapshot_end_fails_if_snapshot_not_in_progress(CuTest * tc) void TestRaft_leader_snapshot_end_fails_if_snapshot_not_in_progress(CuTest * tc)
...@@ -286,6 +294,8 @@ void TestRaft_leader_snapshot_end_fails_if_snapshot_not_in_progress(CuTest * tc) ...@@ -286,6 +294,8 @@ void TestRaft_leader_snapshot_end_fails_if_snapshot_not_in_progress(CuTest * tc)
raft_set_state(r, RAFT_STATE_LEADER); raft_set_state(r, RAFT_STATE_LEADER);
CuAssertIntEquals(tc, 0, raft_get_log_count(r)); CuAssertIntEquals(tc, 0, raft_get_log_count(r));
CuAssertIntEquals(tc, -1, raft_end_snapshot(r)); CuAssertIntEquals(tc, -1, raft_end_snapshot(r));
raft_destroy(r);
} }
void TestRaft_leader_snapshot_begin_fails_if_less_than_2_logs_to_compact(CuTest * tc) void TestRaft_leader_snapshot_begin_fails_if_less_than_2_logs_to_compact(CuTest * tc)
...@@ -311,9 +321,12 @@ void TestRaft_leader_snapshot_begin_fails_if_less_than_2_logs_to_compact(CuTest ...@@ -311,9 +321,12 @@ void TestRaft_leader_snapshot_begin_fails_if_less_than_2_logs_to_compact(CuTest
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
CuAssertIntEquals(tc, 1, raft_get_log_count(r)); CuAssertIntEquals(tc, 1, raft_get_log_count(r));
CuAssertIntEquals(tc, -1, raft_begin_snapshot(r)); CuAssertIntEquals(tc, -1, raft_begin_snapshot(r));
raft_destroy(r);
} }
void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc) void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc)
...@@ -341,12 +354,18 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc) ...@@ -341,12 +354,18 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 2); raft_set_commit_idx(r, 2);
CuAssertIntEquals(tc, 3, raft_get_log_count(r)); CuAssertIntEquals(tc, 3, raft_get_log_count(r));
CuAssertIntEquals(tc, 2, raft_get_num_snapshottable_logs(r)); CuAssertIntEquals(tc, 2, raft_get_num_snapshottable_logs(r));
CuAssertIntEquals(tc, 1, raft_get_last_log_term(r)); CuAssertIntEquals(tc, 1, raft_get_last_log_term(r));
...@@ -365,6 +384,7 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc) ...@@ -365,6 +384,7 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc)
/* snapshot doesn't work if only one entry to snapshot, so add another one */ /* snapshot doesn't work if only one entry to snapshot, so add another one */
ety = __MAKE_ENTRY(4, 1, "entry"); ety = __MAKE_ENTRY(4, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 4); raft_set_commit_idx(r, 4);
CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000)); CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000));
...@@ -379,6 +399,8 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc) ...@@ -379,6 +399,8 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted(CuTest * tc)
CuAssertIntEquals(tc, 4, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 4, raft_get_commit_idx(r));
CuAssertIntEquals(tc, 4, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 4, raft_get_last_applied_idx(r));
CuAssertIntEquals(tc, 1, raft_get_last_log_term(r)); CuAssertIntEquals(tc, 1, raft_get_last_log_term(r));
raft_destroy(r);
} }
void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc) void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc)
...@@ -406,10 +428,16 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc) ...@@ -406,10 +428,16 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 2); raft_set_commit_idx(r, 2);
CuAssertIntEquals(tc, 3, raft_get_log_count(r)); CuAssertIntEquals(tc, 3, raft_get_log_count(r));
CuAssertIntEquals(tc, 2, raft_get_num_snapshottable_logs(r)); CuAssertIntEquals(tc, 2, raft_get_num_snapshottable_logs(r));
...@@ -421,6 +449,8 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc) ...@@ -421,6 +449,8 @@ void TestRaft_leader_snapshot_end_succeeds_if_log_compacted2(CuTest * tc)
CuAssertIntEquals(tc, 2, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 2, raft_get_commit_idx(r));
CuAssertIntEquals(tc, 2, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 2, raft_get_last_applied_idx(r));
CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000)); CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000));
raft_destroy(r);
} }
void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc) void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc)
...@@ -446,8 +476,12 @@ void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc) ...@@ -446,8 +476,12 @@ void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
CuAssertIntEquals(tc, 1, raft_get_num_snapshottable_logs(r)); CuAssertIntEquals(tc, 1, raft_get_num_snapshottable_logs(r));
...@@ -456,6 +490,8 @@ void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc) ...@@ -456,6 +490,8 @@ void TestRaft_joinee_needs_to_get_snapshot(CuTest * tc)
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
CuAssertIntEquals(tc, -1, raft_apply_entry(r)); CuAssertIntEquals(tc, -1, raft_apply_entry(r));
CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 1, raft_get_last_applied_idx(r));
raft_destroy(r);
} }
void TestRaft_follower_load_from_snapshot(CuTest * tc) void TestRaft_follower_load_from_snapshot(CuTest * tc)
...@@ -472,9 +508,6 @@ void TestRaft_follower_load_from_snapshot(CuTest * tc) ...@@ -472,9 +508,6 @@ void TestRaft_follower_load_from_snapshot(CuTest * tc)
raft_set_state(r, RAFT_STATE_FOLLOWER); raft_set_state(r, RAFT_STATE_FOLLOWER);
CuAssertIntEquals(tc, 0, raft_get_log_count(r)); CuAssertIntEquals(tc, 0, raft_get_log_count(r));
/* entry message */
raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "entry");
CuAssertIntEquals(tc, 0, raft_get_log_count(r)); CuAssertIntEquals(tc, 0, raft_get_log_count(r));
CuAssertIntEquals(tc, 0, raft_begin_load_snapshot(r, 5, 5)); CuAssertIntEquals(tc, 0, raft_begin_load_snapshot(r, 5, 5));
CuAssertIntEquals(tc, 0, raft_end_load_snapshot(r)); CuAssertIntEquals(tc, 0, raft_end_load_snapshot(r));
...@@ -486,13 +519,19 @@ void TestRaft_follower_load_from_snapshot(CuTest * tc) ...@@ -486,13 +519,19 @@ void TestRaft_follower_load_from_snapshot(CuTest * tc)
CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000)); CuAssertIntEquals(tc, 0, raft_periodic_internal(r, 1000));
/* current idx means snapshot was unnecessary */ /* current idx means snapshot was unnecessary */
ety = __MAKE_ENTRY(2, 1, "entry"); raft_entry_t *ety = __MAKE_ENTRY(2, 1, "entry");
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_entry_release(ety);
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
raft_append_entry(r, ety); raft_append_entry(r, ety);
raft_entry_release(ety);
raft_set_commit_idx(r, 7); raft_set_commit_idx(r, 7);
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 6, 5)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 6, 5));
CuAssertIntEquals(tc, 7, raft_get_commit_idx(r)); CuAssertIntEquals(tc, 7, raft_get_commit_idx(r));
raft_destroy(r);
} }
void TestRaft_follower_load_from_snapshot_fails_if_term_is_0(CuTest * tc) void TestRaft_follower_load_from_snapshot_fails_if_term_is_0(CuTest * tc)
...@@ -509,6 +548,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_term_is_0(CuTest * tc) ...@@ -509,6 +548,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_term_is_0(CuTest * tc)
raft_set_state(r, RAFT_STATE_FOLLOWER); raft_set_state(r, RAFT_STATE_FOLLOWER);
CuAssertIntEquals(tc, 0, raft_get_log_count(r)); CuAssertIntEquals(tc, 0, raft_get_log_count(r));
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 0, 5)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 0, 5));
raft_destroy(r);
} }
void TestRaft_follower_load_from_snapshot_fails_if_already_loaded(CuTest * tc) void TestRaft_follower_load_from_snapshot_fails_if_already_loaded(CuTest * tc)
...@@ -534,6 +575,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_already_loaded(CuTest * tc) ...@@ -534,6 +575,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_already_loaded(CuTest * tc)
CuAssertIntEquals(tc, 5, raft_get_last_applied_idx(r)); CuAssertIntEquals(tc, 5, raft_get_last_applied_idx(r));
CuAssertIntEquals(tc, RAFT_ERR_SNAPSHOT_ALREADY_LOADED, raft_begin_load_snapshot(r, 5, 5)); CuAssertIntEquals(tc, RAFT_ERR_SNAPSHOT_ALREADY_LOADED, raft_begin_load_snapshot(r, 5, 5));
raft_destroy(r);
} }
void TestRaft_follower_load_from_snapshot_does_not_break_cluster_safety(CuTest * tc) void TestRaft_follower_load_from_snapshot_does_not_break_cluster_safety(CuTest * tc)
...@@ -558,6 +601,8 @@ void TestRaft_follower_load_from_snapshot_does_not_break_cluster_safety(CuTest * ...@@ -558,6 +601,8 @@ void TestRaft_follower_load_from_snapshot_does_not_break_cluster_safety(CuTest *
__RAFT_APPEND_ENTRY(r, 3, 1, "entry"); __RAFT_APPEND_ENTRY(r, 3, 1, "entry");
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 2, 2)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 2, 2));
raft_destroy(r);
} }
void TestRaft_follower_load_from_snapshot_fails_if_log_is_newer(CuTest * tc) void TestRaft_follower_load_from_snapshot_fails_if_log_is_newer(CuTest * tc)
...@@ -577,6 +622,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_log_is_newer(CuTest * tc) ...@@ -577,6 +622,8 @@ void TestRaft_follower_load_from_snapshot_fails_if_log_is_newer(CuTest * tc)
raft_set_last_applied_idx(r, 5); raft_set_last_applied_idx(r, 5);
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 2, 2)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_begin_load_snapshot(r, 2, 2));
raft_destroy(r);
} }
void TestRaft_leader_sends_snapshot_when_node_next_index_was_compacted(CuTest* tc) void TestRaft_leader_sends_snapshot_when_node_next_index_was_compacted(CuTest* tc)
...@@ -637,6 +684,8 @@ void TestRaft_leader_sends_snapshot_when_node_next_index_was_compacted(CuTest* t ...@@ -637,6 +684,8 @@ void TestRaft_leader_sends_snapshot_when_node_next_index_was_compacted(CuTest* t
CuAssertIntEquals(tc, 3, ae.term); CuAssertIntEquals(tc, 3, ae.term);
CuAssertIntEquals(tc, 3, ae.prev_log_idx); CuAssertIntEquals(tc, 3, ae.prev_log_idx);
CuAssertIntEquals(tc, 2, ae.prev_log_term); CuAssertIntEquals(tc, 2, ae.prev_log_term);
raft_destroy(r);
} }
void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc) void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc)
...@@ -662,8 +711,11 @@ void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc) ...@@ -662,8 +711,11 @@ void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc)
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
...@@ -672,6 +724,9 @@ void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc) ...@@ -672,6 +724,9 @@ void TestRaft_recv_entry_fails_if_snapshot_in_progress(CuTest* tc)
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
ety->type = RAFT_LOGTYPE_ADD_NODE; ety->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertIntEquals(tc, RAFT_ERR_SNAPSHOT_IN_PROGRESS, raft_recv_entry(r, ety, &cr)); CuAssertIntEquals(tc, RAFT_ERR_SNAPSHOT_IN_PROGRESS, raft_recv_entry(r, ety, &cr));
raft_entry_release(ety);
raft_destroy(r);
} }
void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* tc) void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* tc)
...@@ -697,8 +752,11 @@ void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* t ...@@ -697,8 +752,11 @@ void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* t
/* receive entry */ /* receive entry */
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
raft_set_commit_idx(r, 1); raft_set_commit_idx(r, 1);
...@@ -709,6 +767,9 @@ void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* t ...@@ -709,6 +767,9 @@ void TestRaft_recv_entry_succeeds_if_snapshot_nonblocking_apply_is_set(CuTest* t
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
ety->type = RAFT_LOGTYPE_ADD_NODE; ety->type = RAFT_LOGTYPE_ADD_NODE;
CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &cr)); CuAssertIntEquals(tc, 0, raft_recv_entry(r, ety, &cr));
raft_entry_release(ety);
raft_destroy(r);
} }
...@@ -740,6 +801,13 @@ void TestRaft_follower_recv_appendentries_is_successful_when_previous_log_idx_eq ...@@ -740,6 +801,13 @@ void TestRaft_follower_recv_appendentries_is_successful_when_previous_log_idx_eq
ae.n_entries = 1; ae.n_entries = 1;
CuAssertIntEquals(tc, 0, raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer)); CuAssertIntEquals(tc, 0, raft_recv_appendentries(r, raft_get_node(r, 2), &ae, &aer));
CuAssertIntEquals(tc, 1, aer.success); CuAssertIntEquals(tc, 1, aer.success);
for (raft_index_t i = 0; i < ae.n_entries; i++) {
raft_entry_release(ae.entries[i]);
}
raft_free(ae.entries);
raft_destroy(r);
} }
void TestRaft_leader_sends_appendentries_with_correct_prev_log_idx_when_snapshotted( void TestRaft_leader_sends_appendentries_with_correct_prev_log_idx_when_snapshotted(
...@@ -775,6 +843,14 @@ void TestRaft_leader_sends_appendentries_with_correct_prev_log_idx_when_snapshot ...@@ -775,6 +843,14 @@ void TestRaft_leader_sends_appendentries_with_correct_prev_log_idx_when_snapshot
CuAssertTrue(tc, NULL != ae); CuAssertTrue(tc, NULL != ae);
CuAssertIntEquals(tc, 2, ae->prev_log_term); CuAssertIntEquals(tc, 2, ae->prev_log_term);
CuAssertIntEquals(tc, 4, ae->prev_log_idx); CuAssertIntEquals(tc, 4, ae->prev_log_idx);
for (raft_index_t i = 0; i < ae->n_entries; i++) {
raft_entry_release(ae->entries[i]);
}
raft_free(ae->entries);
raft_free(ae);
raft_destroy(r);
} }
void TestRaft_cancel_snapshot_restores_state(CuTest* tc) void TestRaft_cancel_snapshot_restores_state(CuTest* tc)
...@@ -798,9 +874,11 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc) ...@@ -798,9 +874,11 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc)
/* single entry */ /* single entry */
raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "entry"); raft_entry_req_t *ety = __MAKE_ENTRY(1, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(2, 1, "entry"); ety = __MAKE_ENTRY(2, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
raft_set_commit_idx(r, 2); raft_set_commit_idx(r, 2);
CuAssertIntEquals(tc, 0, raft_begin_snapshot(r)); CuAssertIntEquals(tc, 0, raft_begin_snapshot(r));
...@@ -809,8 +887,12 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc) ...@@ -809,8 +887,12 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc)
/* more entries */ /* more entries */
ety = __MAKE_ENTRY(3, 1, "entry"); ety = __MAKE_ENTRY(3, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
ety = __MAKE_ENTRY(4, 1, "entry"); ety = __MAKE_ENTRY(4, 1, "entry");
raft_recv_entry(r, ety, &cr); raft_recv_entry(r, ety, &cr);
raft_entry_release(ety);
CuAssertIntEquals(tc, 2, raft_get_log_count(r)); CuAssertIntEquals(tc, 2, raft_get_log_count(r));
CuAssertIntEquals(tc, 2, raft_get_snapshot_last_idx(r)); CuAssertIntEquals(tc, 2, raft_get_snapshot_last_idx(r));
...@@ -823,6 +905,8 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc) ...@@ -823,6 +905,8 @@ void TestRaft_cancel_snapshot_restores_state(CuTest* tc)
/* snapshot no longer in progress, index must not have changed */ /* snapshot no longer in progress, index must not have changed */
CuAssertIntEquals(tc, 0, raft_snapshot_is_in_progress(r)); CuAssertIntEquals(tc, 0, raft_snapshot_is_in_progress(r));
CuAssertIntEquals(tc, 2, raft_get_snapshot_last_idx(r)); CuAssertIntEquals(tc, 2, raft_get_snapshot_last_idx(r));
raft_destroy(r);
} }
void TestRaft_leader_sends_snapshot_if_log_was_compacted(CuTest* tc) void TestRaft_leader_sends_snapshot_if_log_was_compacted(CuTest* tc)
...@@ -875,13 +959,16 @@ void TestRaft_leader_sends_snapshot_if_log_was_compacted(CuTest* tc) ...@@ -875,13 +959,16 @@ void TestRaft_leader_sends_snapshot_if_log_was_compacted(CuTest* tc)
raft_node_set_match_idx(node, 1); raft_node_set_match_idx(node, 1);
raft_node_set_next_idx(node, 2); raft_node_set_next_idx(node, 2);
raft_appendentries_resp_t aer; raft_appendentries_resp_t aer = {
aer.term = 1; .term = 1,
aer.success = 0; .success = 0,
aer.current_idx = 1; .current_idx = 1
};
raft_recv_appendentries_response(r, node, &aer); raft_recv_appendentries_response(r, node, &aer);
CuAssertIntEquals(tc, 1, send_snapshot_count); CuAssertIntEquals(tc, 1, send_snapshot_count);
raft_destroy(r);
} }
void TestRaft_clear_snapshot_on_leader_change(CuTest * tc) void TestRaft_clear_snapshot_on_leader_change(CuTest * tc)
...@@ -922,6 +1009,8 @@ void TestRaft_clear_snapshot_on_leader_change(CuTest * tc) ...@@ -922,6 +1009,8 @@ void TestRaft_clear_snapshot_on_leader_change(CuTest * tc)
raft_recv_snapshot(r, NULL, &msg, &resp); raft_recv_snapshot(r, NULL, &msg, &resp);
CuAssertIntEquals(tc, 1, data.clear); CuAssertIntEquals(tc, 1, data.clear);
CuAssertIntEquals(tc, 2, data.store_chunk); CuAssertIntEquals(tc, 2, data.store_chunk);
raft_destroy(r);
} }
void TestRaft_reject_wrong_offset(CuTest * tc) void TestRaft_reject_wrong_offset(CuTest * tc)
...@@ -962,6 +1051,8 @@ void TestRaft_reject_wrong_offset(CuTest * tc) ...@@ -962,6 +1051,8 @@ void TestRaft_reject_wrong_offset(CuTest * tc)
CuAssertIntEquals(tc, 0, resp.success); CuAssertIntEquals(tc, 0, resp.success);
CuAssertIntEquals(tc, 50, resp.offset); CuAssertIntEquals(tc, 50, resp.offset);
raft_destroy(r);
} }
void TestRaft_set_last_chunk_on_duplicate(CuTest * tc) void TestRaft_set_last_chunk_on_duplicate(CuTest * tc)
...@@ -1014,6 +1105,8 @@ void TestRaft_set_last_chunk_on_duplicate(CuTest * tc) ...@@ -1014,6 +1105,8 @@ void TestRaft_set_last_chunk_on_duplicate(CuTest * tc)
CuAssertIntEquals(tc, 1, resp.success); CuAssertIntEquals(tc, 1, resp.success);
CuAssertIntEquals(tc, 1, resp.last_chunk); CuAssertIntEquals(tc, 1, resp.last_chunk);
raft_destroy(r);
} }
void TestRaft_set_last_chunk_if_log_is_more_advanced(CuTest * tc) void TestRaft_set_last_chunk_if_log_is_more_advanced(CuTest * tc)
...@@ -1059,6 +1152,8 @@ void TestRaft_set_last_chunk_if_log_is_more_advanced(CuTest * tc) ...@@ -1059,6 +1152,8 @@ void TestRaft_set_last_chunk_if_log_is_more_advanced(CuTest * tc)
CuAssertIntEquals(tc, 0, data.load); CuAssertIntEquals(tc, 0, data.load);
CuAssertIntEquals(tc, 1, resp.success); CuAssertIntEquals(tc, 1, resp.success);
CuAssertIntEquals(tc, 1, resp.last_chunk); CuAssertIntEquals(tc, 1, resp.last_chunk);
raft_destroy(r);
} }
void TestRaft_report_fail_on_load_snapshot_error(CuTest * tc) void TestRaft_report_fail_on_load_snapshot_error(CuTest * tc)
...@@ -1147,6 +1242,8 @@ void TestRaft_report_fail_on_load_snapshot_error(CuTest * tc) ...@@ -1147,6 +1242,8 @@ void TestRaft_report_fail_on_load_snapshot_error(CuTest * tc)
CuAssertIntEquals(tc, 1, resp.success); CuAssertIntEquals(tc, 1, resp.success);
CuAssertIntEquals(tc, 80, resp.offset); CuAssertIntEquals(tc, 80, resp.offset);
CuAssertIntEquals(tc, 1, resp.last_chunk); CuAssertIntEquals(tc, 1, resp.last_chunk);
raft_destroy(r);
} }
void TestRaft_restore_after_restart(CuTest * tc) void TestRaft_restore_after_restart(CuTest * tc)
...@@ -1159,11 +1256,15 @@ void TestRaft_restore_after_restart(CuTest * tc) ...@@ -1159,11 +1256,15 @@ void TestRaft_restore_after_restart(CuTest * tc)
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_restore_snapshot(r, -1, 3)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_restore_snapshot(r, -1, 3));
CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_restore_snapshot(r, 11, 5)); CuAssertIntEquals(tc, RAFT_ERR_MISUSE, raft_restore_snapshot(r, 11, 5));
raft_destroy(r);
r = raft_new(); r = raft_new();
raft_add_node(r, NULL, 1, 1); raft_add_node(r, NULL, 1, 1);
/* Restore should work on start-up */ /* Restore should work on start-up */
CuAssertIntEquals(tc, 0, raft_restore_snapshot(r, 11, 5)); CuAssertIntEquals(tc, 0, raft_restore_snapshot(r, 11, 5));
raft_destroy(r);
} }
int main(void) int main(void)
...@@ -1201,5 +1302,10 @@ int main(void) ...@@ -1201,5 +1302,10 @@ int main(void)
CuSuiteDetails(suite, output); CuSuiteDetails(suite, output);
printf("%s\n", output->buffer); printf("%s\n", output->buffer);
return suite->failCount == 0 ? 0 : 1; int rc = suite->failCount == 0 ? 0 : 1;
CuStringFree(output);
CuSuiteFree(suite);
return rc;
} }
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment