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;
} }
This diff is collapsed.
...@@ -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