Start of tests for persistence reading.

pull/1203/head
Roger A. Light 7 years ago
parent b6356735b4
commit 9411d94842

3
.gitignore vendored

@ -62,7 +62,8 @@ test/lib/cpp/*.test
test/unit/coverage.info test/unit/coverage.info
test/unit/mosq_test test/unit/mosq_test
test/unit/out test/unit/persist_read_test
test/unit/out/
www/cache/ www/cache/
__pycache__ __pycache__

@ -129,9 +129,7 @@ int db__open(struct mosquitto__config *config, struct mosquitto_db *db)
db->unpwd = NULL; db->unpwd = NULL;
#ifdef WITH_PERSISTENCE #ifdef WITH_PERSISTENCE
if(config->persistence && config->persistence_filepath){ if(persist__restore(db)) return 1;
if(persist__restore(db)) return 1;
}
#endif #endif
return MOSQ_ERR_SUCCESS; return MOSQ_ERR_SUCCESS;

@ -438,7 +438,10 @@ int persist__restore(struct mosquitto_db *db)
assert(db); assert(db);
assert(db->config); assert(db->config);
assert(db->config->persistence_filepath);
if(!db->config->persistence || db->config->persistence_filepath == NULL){
return MOSQ_ERR_SUCCESS;
}
db->msg_store_load = NULL; db->msg_store_load = NULL;

@ -1,8 +1,8 @@
include ../../config.mk include ../../config.mk
.PHONY: all test clean coverage .PHONY: all test test-broker test-lib clean coverage
CFLAGS=-I../.. -I../../lib -coverage -Wall -ggdb CFLAGS=-I../.. -I../../lib -I../../src -coverage -Wall -ggdb
TEST_LDFLAGS=-lcunit -coverage TEST_LDFLAGS=-lcunit -coverage
TEST_OBJS = test.o \ TEST_OBJS = test.o \
@ -22,31 +22,55 @@ LIB_OBJS = memory_mosq.o \
util_topic.o \ util_topic.o \
utf8_mosq.o utf8_mosq.o
PERSIST_READ_TEST_OBJS = \
persist_read_test.o \
persist_read_stubs.o
PERSIST_READ_OBJS = \
memory_mosq.o \
persist_read.o \
util_mosq.o
all : test all : test
mosq_test : ${TEST_OBJS} ${LIB_OBJS} mosq_test : ${TEST_OBJS} ${LIB_OBJS}
$(CROSS_COMPILE)$(CC) -o $@ $^ ${TEST_LDFLAGS} $(CROSS_COMPILE)$(CC) -o $@ $^ ${TEST_LDFLAGS}
persist_read_test : ${PERSIST_READ_TEST_OBJS} ${PERSIST_READ_OBJS}
$(CROSS_COMPILE)$(CC) -o $@ $^ ${TEST_LDFLAGS}
memory_mosq.o : ../../lib/memory_mosq.c memory_mosq.o : ../../lib/memory_mosq.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^ $(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
packet_datatypes.o : ../../lib/packet_datatypes.c packet_datatypes.o : ../../lib/packet_datatypes.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^ $(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
persist_read.o : ../../src/persist_read.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -DWITH_BROKER -DWITH_PERSISTENCE -c -o $@ $^
property_mosq.o : ../../lib/property_mosq.c property_mosq.o : ../../lib/property_mosq.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^ $(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
util_mosq.o : ../../lib/util_mosq.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
util_topic.o : ../../lib/util_topic.c util_topic.o : ../../lib/util_topic.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^ $(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
utf8_mosq.o : ../../lib/utf8_mosq.c utf8_mosq.o : ../../lib/utf8_mosq.c
$(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^ $(CROSS_COMPILE)$(CC) $(CFLAGS) -c -o $@ $^
test : mosq_test test-lib : mosq_test
./mosq_test ./mosq_test
test-broker : persist_read_test
./persist_read_test
test : test-broker test-lib
clean : clean :
-rm -rf mosq_test *.o *.gcda *.gcno coverage.info out/ -rm -rf mosq_test persist_read_test
-rm -rf *.o *.gcda *.gcno coverage.info out/
coverage : coverage :
lcov --capture --directory . --output-file coverage.info lcov --capture --directory . --output-file coverage.info

@ -0,0 +1 @@
corruptcorruptcorruptcorruptcorruptcorrupt

@ -0,0 +1,133 @@
#include <time.h>
#define WITH_BROKER
#include <logging_mosq.h>
#include <memory_mosq.h>
#include <mosquitto_broker_internal.h>
#include <net_mosq.h>
#include <send_mosq.h>
#include <time_mosq.h>
extern uint64_t last_retained;
extern char *last_sub;
extern int last_qos;
struct mosquitto *context__init(struct mosquitto_db *db, mosq_sock_t sock)
{
return mosquitto__calloc(1, sizeof(struct mosquitto));
}
int db__message_store(struct mosquitto_db *db, const struct mosquitto *source, uint16_t source_mid, char *topic, int qos, uint32_t payloadlen, mosquitto__payload_uhpa *payload, int retain, struct mosquitto_msg_store **stored, uint32_t message_expiry_interval, mosquitto_property *properties, dbid_t store_id)
{
struct mosquitto_msg_store *temp = NULL;
int rc = MOSQ_ERR_SUCCESS;
temp = mosquitto__calloc(1, sizeof(struct mosquitto_msg_store));
if(!temp){
rc = MOSQ_ERR_NOMEM;
goto error;
}
if(source && source->id){
temp->source_id = mosquitto__strdup(source->id);
}else{
temp->source_id = mosquitto__strdup("");
}
if(!temp->source_id){
rc = MOSQ_ERR_NOMEM;
goto error;
}
if(source && source->username){
temp->source_username = mosquitto__strdup(source->username);
if(!temp->source_username){
rc = MOSQ_ERR_NOMEM;
goto error;
}
}
if(source){
temp->source_listener = source->listener;
}
temp->source_mid = source_mid;
temp->mid = 0;
temp->qos = qos;
temp->retain = retain;
temp->topic = topic;
topic = NULL;
temp->payloadlen = payloadlen;
temp->properties = properties;
if(payloadlen){
UHPA_MOVE(temp->payload, *payload, payloadlen);
}else{
temp->payload.ptr = NULL;
}
if(message_expiry_interval > 0){
temp->message_expiry_time = time(NULL) + message_expiry_interval;
}else{
temp->message_expiry_time = 0;
}
temp->dest_ids = NULL;
temp->dest_id_count = 0;
db->msg_store_count++;
db->msg_store_bytes += payloadlen;
(*stored) = temp;
if(!store_id){
temp->db_id = ++db->last_db_id;
}else{
temp->db_id = store_id;
}
db->msg_store = temp;
return MOSQ_ERR_SUCCESS;
error:
mosquitto__free(topic);
if(temp){
mosquitto__free(temp->source_id);
mosquitto__free(temp->source_username);
mosquitto__free(temp->topic);
mosquitto__free(temp);
}
UHPA_FREE(*payload, payloadlen);
return rc;
}
int log__printf(struct mosquitto *mosq, int priority, const char *fmt, ...)
{
return 0;
}
time_t mosquitto_time(void)
{
return 123;
}
int net__socket_close(struct mosquitto_db *db, struct mosquitto *mosq)
{
return MOSQ_ERR_SUCCESS;
}
int send__pingreq(struct mosquitto *mosq)
{
return MOSQ_ERR_SUCCESS;
}
int sub__add(struct mosquitto_db *db, struct mosquitto *context, const char *sub, int qos, uint32_t identifier, int options, struct mosquitto__subhier **root)
{
last_sub = strdup(sub);
last_qos = qos;
return MOSQ_ERR_SUCCESS;
}
int sub__messages_queue(struct mosquitto_db *db, const char *source_id, const char *topic, int qos, int retain, struct mosquitto_msg_store **stored)
{
if(retain){
last_retained = (*stored)->db_id;
}
return MOSQ_ERR_SUCCESS;
}

@ -0,0 +1,436 @@
/* Tests for persistence.
*
* FIXME - these need to be aggressive about finding failures, at the moment
* they are just confirming that good behaviour works. */
#include <CUnit/CUnit.h>
#include <CUnit/Basic.h>
#define WITH_BROKER
#define WITH_PERSISTENCE
#include "mosquitto_broker_internal.h"
#include "persist.h"
uint64_t last_retained;
char *last_sub = NULL;
int last_qos;
static void TEST_persistence_disabled(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
}
static void TEST_empty_file(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/empty.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
}
static void TEST_corrupt_header(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/corrupt-header-short.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, 1);
config.persistence_filepath = "files/persist_read/corrupt-header-long.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, 1);
}
static void TEST_unsupported_version(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/unsupported-version.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, 1);
}
static void TEST_v3_config_ok(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-cfg.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_EQUAL(db.last_db_id, 0x7856341200000000);
}
static void TEST_v3_config_truncated(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-cfg-truncated.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, 1);
CU_ASSERT_EQUAL(db.last_db_id, 0);
}
static void TEST_v3_config_bad_dbid(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-cfg-bad-dbid.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, 1);
CU_ASSERT_EQUAL(db.last_db_id, 0);
}
static void TEST_v3_bad_chunk(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-bad-chunk.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_EQUAL(db.last_db_id, 0x17);
}
static void TEST_v3_message_store(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-message-store.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_EQUAL(db.msg_store_count, 1);
CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
CU_ASSERT_PTR_NOT_NULL(db.msg_store);
if(db.msg_store){
CU_ASSERT_EQUAL(db.msg_store->db_id, 1);
CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
CU_ASSERT_EQUAL(db.msg_store->mid, 0);
CU_ASSERT_EQUAL(db.msg_store->qos, 2);
CU_ASSERT_EQUAL(db.msg_store->retain, 1);
CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
if(db.msg_store->payloadlen == 7){
CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
}
}
}
static void TEST_v3_client(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
struct mosquitto *context;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-client.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
CU_ASSERT_PTR_NOT_NULL(context);
if(context){
CU_ASSERT_PTR_NULL(context->inflight_msgs);
CU_ASSERT_EQUAL(context->last_mid, 0x5287);
CU_ASSERT_EQUAL(context->disconnect_t, 0x23);
}
}
static void TEST_v3_client_message(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
struct mosquitto *context;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-client-message.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
CU_ASSERT_PTR_NOT_NULL(context);
if(context){
CU_ASSERT_PTR_NOT_NULL(context->inflight_msgs);
if(context->inflight_msgs){
CU_ASSERT_PTR_NULL(context->inflight_msgs->next);
CU_ASSERT_PTR_NOT_NULL(context->inflight_msgs->store);
if(context->inflight_msgs->store){
CU_ASSERT_EQUAL(context->inflight_msgs->store->ref_count, 1);
CU_ASSERT_STRING_EQUAL(context->inflight_msgs->store->source_id, "source_id");
CU_ASSERT_EQUAL(context->inflight_msgs->store->source_mid, 2);
CU_ASSERT_EQUAL(context->inflight_msgs->store->mid, 0);
CU_ASSERT_EQUAL(context->inflight_msgs->store->qos, 2);
CU_ASSERT_EQUAL(context->inflight_msgs->store->retain, 1);
CU_ASSERT_STRING_EQUAL(context->inflight_msgs->store->topic, "topic");
CU_ASSERT_EQUAL(context->inflight_msgs->store->payloadlen, 7);
if(context->inflight_msgs->store->payloadlen == 7){
CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(context->inflight_msgs->store), "payload", 7);
}
}
CU_ASSERT_EQUAL(context->inflight_msgs->mid, 0x73);
CU_ASSERT_EQUAL(context->inflight_msgs->qos, 1);
CU_ASSERT_EQUAL(context->inflight_msgs->retain, 0);
CU_ASSERT_EQUAL(context->inflight_msgs->direction, mosq_md_out);
CU_ASSERT_EQUAL(context->inflight_msgs->state, mosq_ms_wait_for_puback);
CU_ASSERT_EQUAL(context->inflight_msgs->dup, 0);
}
}
}
static void TEST_v3_retain(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
last_retained = 0;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-retain.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_EQUAL(db.msg_store_count, 1);
CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
CU_ASSERT_PTR_NOT_NULL(db.msg_store);
if(db.msg_store){
CU_ASSERT_EQUAL(db.msg_store->db_id, 0x54);
CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
CU_ASSERT_EQUAL(db.msg_store->source_mid, 2);
CU_ASSERT_EQUAL(db.msg_store->mid, 0);
CU_ASSERT_EQUAL(db.msg_store->qos, 2);
CU_ASSERT_EQUAL(db.msg_store->retain, 1);
CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
if(db.msg_store->payloadlen == 7){
CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
}
}
CU_ASSERT_EQUAL(last_retained, 0x54);
}
static void TEST_v3_sub(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
struct mosquitto *context;
int rc;
last_sub = NULL;
last_qos = -1;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v3-sub.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_PTR_NOT_NULL(db.contexts_by_id);
HASH_FIND(hh_id, db.contexts_by_id, "client-id", strlen("client-id"), context);
CU_ASSERT_PTR_NOT_NULL(context);
if(context){
CU_ASSERT_PTR_NOT_NULL(last_sub);
if(last_sub){
CU_ASSERT_STRING_EQUAL(last_sub, "subscription")
free(last_sub);
}
CU_ASSERT_EQUAL(last_qos, 1);
}
}
static void TEST_v4_message_store(void)
{
struct mosquitto_db db;
struct mosquitto__config config;
int rc;
memset(&db, 0, sizeof(struct mosquitto_db));
memset(&config, 0, sizeof(struct mosquitto__config));
db.config = &config;
config.persistence = true;
config.persistence_filepath = "files/persist_read/v4-message-store.test-db";
rc = persist__restore(&db);
CU_ASSERT_EQUAL(rc, MOSQ_ERR_SUCCESS);
CU_ASSERT_EQUAL(db.msg_store_count, 1);
CU_ASSERT_EQUAL(db.msg_store_bytes, 7);
CU_ASSERT_PTR_NOT_NULL(db.msg_store);
if(db.msg_store){
CU_ASSERT_EQUAL(db.msg_store->db_id, 0xFEDCBA9876543210);
CU_ASSERT_STRING_EQUAL(db.msg_store->source_id, "source_id");
CU_ASSERT_EQUAL(db.msg_store->source_mid, 0x88);
CU_ASSERT_EQUAL(db.msg_store->mid, 0);
CU_ASSERT_EQUAL(db.msg_store->qos, 1);
CU_ASSERT_EQUAL(db.msg_store->retain, 0);
CU_ASSERT_STRING_EQUAL(db.msg_store->topic, "topic");
CU_ASSERT_EQUAL(db.msg_store->payloadlen, 7);
if(db.msg_store->payloadlen == 7){
CU_ASSERT_NSTRING_EQUAL(UHPA_ACCESS_PAYLOAD(db.msg_store), "payload", 7);
}
}
}
/* ========================================================================
* TEST SUITE SETUP
* ======================================================================== */
int init_persist_read_tests(void)
{
CU_pSuite test_suite = NULL;
test_suite = CU_add_suite("Persist read", NULL, NULL);
if(!test_suite){
printf("Error adding CUnit persist read test suite.\n");
return 1;
}
if(0
|| !CU_add_test(test_suite, "Persistence disabled", TEST_persistence_disabled)
|| !CU_add_test(test_suite, "Empty file", TEST_empty_file)
|| !CU_add_test(test_suite, "Corrupt header", TEST_corrupt_header)
|| !CU_add_test(test_suite, "Unsupported version", TEST_unsupported_version)
|| !CU_add_test(test_suite, "v3 config ok", TEST_v3_config_ok)
|| !CU_add_test(test_suite, "v3 config bad truncated", TEST_v3_config_truncated)
|| !CU_add_test(test_suite, "v3 config bad dbid", TEST_v3_config_bad_dbid)
|| !CU_add_test(test_suite, "v3 bad chunk", TEST_v3_bad_chunk)
|| !CU_add_test(test_suite, "v3 message store", TEST_v3_message_store)
|| !CU_add_test(test_suite, "v3 client", TEST_v3_client)
|| !CU_add_test(test_suite, "v3 client message", TEST_v3_client_message)
|| !CU_add_test(test_suite, "v3 retain", TEST_v3_retain)
|| !CU_add_test(test_suite, "v3 sub", TEST_v3_sub)
|| !CU_add_test(test_suite, "v4 message store", TEST_v4_message_store)
){
printf("Error adding persist CUnit tests.\n");
return 1;
}
return 0;
}
int main(int argc, char *argv[])
{
if(CU_initialize_registry() != CUE_SUCCESS){
printf("Error initializing CUnit registry.\n");
return 1;
}
if(0
|| init_persist_read_tests()
){
CU_cleanup_registry();
return 1;
}
CU_basic_set_mode(CU_BRM_VERBOSE);
CU_basic_run_tests();
CU_cleanup_registry();
return 0;
}
Loading…
Cancel
Save