From 43f7f54dadecb1d11b4fd9cd2af4889043865490 Mon Sep 17 00:00:00 2001 From: Daniel Silverstone Date: Sun, 11 Jun 2017 11:14:40 +0100 Subject: Switch to a check based test suite, start fixing bugs --- Makefile | 11 ++- include/nslog/nslog.h | 1 + src/core.c | 6 +- test/Makefile | 2 +- test/basic.c | 41 ---------- test/basictests.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++++++ test/explicitfilter.c | 50 ------------ test/testmain.c | 50 ++++++++++++ test/tests.h | 21 +++++ 9 files changed, 305 insertions(+), 95 deletions(-) delete mode 100644 test/basic.c create mode 100644 test/basictests.c delete mode 100644 test/explicitfilter.c create mode 100644 test/testmain.c create mode 100644 test/tests.h diff --git a/Makefile b/Makefile index 184f9d4..26cf49f 100644 --- a/Makefile +++ b/Makefile @@ -17,7 +17,7 @@ NSSHARED ?= $(PREFIX)/share/netsurf-buildsystem include $(NSSHARED)/makefiles/Makefile.tools # Reevaluate when used, as BUILDDIR won't be defined yet -TESTRUNNER = test/runtest.sh $(BUILDDIR) $(EXEEXT) +TESTRUNNER = $(BUILDDIR)/test_testrunner$(EXEEXT) # Toolchain flags WARNFLAGS := -Wall -W -Wundef -Wpointer-arith -Wcast-align \ @@ -48,6 +48,15 @@ TESTLDFLAGS := -lm -l$(COMPONENT) $(TESTLDFLAGS) include $(NSBUILD)/Makefile.top +ifeq ($(WANT_TEST),yes) + ifneq ($(PKGCONFIG),) + TESTCFLAGS := $(TESTCFLAGS) $(shell $(PKGCONFIG) --cflags check) + TESTLDFLAGS := $(TESTLDFLAGS) $(shell $(PKGCONFIG) --libs check) + else + TESTLDFLAGS := $(TESTLDFLAGS) -lcheck + endif +endif + # Extra installation rules I := /$(INCLUDEDIR)/nslog INSTALL_ITEMS := $(INSTALL_ITEMS) $(I):include/nslog/nslog.h diff --git a/include/nslog/nslog.h b/include/nslog/nslog.h index 550bffb..fc3ead4 100644 --- a/include/nslog/nslog.h +++ b/include/nslog/nslog.h @@ -104,6 +104,7 @@ void nslog__log(nslog_entry_context_t *ctx, typedef enum { NSLOG_NO_ERROR = 0, NSLOG_NO_MEMORY = 1, + NSLOG_UNCORKED = 2, } nslog_error; typedef void (*nslog_callback)(void *context, nslog_entry_context_t *ctx, diff --git a/src/core.c b/src/core.c index 978f169..95d06c2 100644 --- a/src/core.c +++ b/src/core.c @@ -73,7 +73,7 @@ static void nslog__log_corked(nslog_entry_context_t *ctx, va_list args) { /* If corked, we need to store a copy */ - struct nslog_cork_chain *newcork = malloc(sizeof(*newcork) + measured_len + 1); + struct nslog_cork_chain *newcork = calloc(sizeof(struct nslog_cork_chain) + measured_len + 1, 1); if (newcork == NULL) { /* Wow, something went wrong */ return; @@ -157,6 +157,8 @@ nslog_error nslog_uncork() free(ent); } nslog__corked = false; + return NSLOG_NO_ERROR; + } else { + return NSLOG_UNCORKED; } - return NSLOG_NO_ERROR; } diff --git a/test/Makefile b/test/Makefile index 033033f..36d5092 100644 --- a/test/Makefile +++ b/test/Makefile @@ -1,3 +1,3 @@ -DIR_TEST_ITEMS := basic:basic.c explicitfilter:explicitfilter.c +DIR_TEST_ITEMS := testrunner:testmain.c;basictests.c include $(NSBUILD)/Makefile.subdir diff --git a/test/basic.c b/test/basic.c deleted file mode 100644 index d514814..0000000 --- a/test/basic.c +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2017 Daniel Silverstone - * - * This file is part of libnslog. - * - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - */ - -#include "nslog/nslog.h" - -#include - -NSLOG_DEFINE_CATEGORY(test, "Test category"); - -static void test_render_function( - void *_ctx, nslog_entry_context_t *ctx, - const char *fmt, va_list args) -{ - (void)ctx; - fprintf(stderr, "%s %s:%d [%s] %s() ", - nslog_level_name(ctx->level), - ctx->filename, ctx->lineno, - ctx->category->name, - ctx->funcname); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); -} - -int main(int argc, char **argv) -{ - nslog_set_render_callback(test_render_function, NULL); - NSLOG(test, INFO, "Pre-uncorking"); - fprintf(stderr, "About to nslog_uncork()\n"); - nslog_uncork(); - fprintf(stderr, "Uncorked now\n"); - NSLOG(test, WARN, "argc=%d", argc); - for (int i = 0; i < argc; ++i) - NSLOG(test, WARN, "argv[%d] = %s", i, argv[i]); - return 0; -} diff --git a/test/basictests.c b/test/basictests.c new file mode 100644 index 0000000..4d94059 --- /dev/null +++ b/test/basictests.c @@ -0,0 +1,218 @@ +/* test/basictests.c + * + * Basic tests for the test suite for libnslog + * + * Copyright 2009,2017 The NetSurf Browser Project + * Daniel Silverstone + */ + +#include +#include +#include +#include +#include + +#include "tests.h" + +#ifndef UNUSED +#define UNUSED(x) (void)(x) +#endif + +#ifndef NDEBUG + +/* Tests go here which need assert() to be checked */ + +#endif + +NSLOG_DEFINE_CATEGORY(test, "Top level test category"); + +static void *captured_render_context = NULL; +static nslog_entry_context_t captured_context = { 0 }; +static char captured_rendered_message[4096] = { 0 }; +static int captured_rendered_message_length = 0; +static int captured_message_count = 0; + +static const char* anchor_context_1 = "1"; + +static void +nslog__test__render_function(void *_ctx, nslog_entry_context_t *ctx, + const char *fmt, va_list args) +{ + captured_context = *ctx; + captured_render_context = _ctx; + captured_rendered_message_length = + vsnprintf(captured_rendered_message, + sizeof(captured_rendered_message), + fmt, args); + captured_message_count++; +} + +/**** The next set of tests need a fixture set ****/ + +static void +with_simple_context_setup(void) +{ + captured_render_context = NULL; + memset(&captured_context, 0, sizeof(captured_context)); + memset(captured_rendered_message, 0, sizeof(captured_rendered_message)); + captured_rendered_message_length = 0; + captured_message_count = 0; + fail_unless(nslog_set_render_callback( + nslog__test__render_function, + (void *)anchor_context_1) == NSLOG_NO_ERROR, + "Unable to set up render callback"); +} + +static void +with_simple_context_teardown(void) +{ + /* Nothing to do to tear down */ +} + +START_TEST (test_nslog_trivial_corked_message) +{ + NSLOG(test, INFO, "Hello %s", "world"); + fail_unless(nslog_uncork() == NSLOG_NO_ERROR, + "Unable to uncork"); + fail_unless(captured_message_count == 1, + "Captured message count was wrong"); + fail_unless(captured_render_context == anchor_context_1, + "Captured context wasn't passed through"); + fail_unless(strcmp(captured_context.category->name, "test") == 0, + "Captured context category wasn't normalised"); + fail_unless(captured_context.category == &__nslog_category_test, + "Captured context category wasn't the one we wanted"); + fail_unless(captured_rendered_message_length == 11, + "Captured message wasn't correct length"); + fail_unless(strcmp(captured_rendered_message, "Hello world") == 0, + "Captured message wasn't correct"); + fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0, + "Captured message wasn't correct filename"); + fail_unless(strcmp(captured_context.funcname, "test_nslog_trivial_corked_message") == 0, + "Captured message wasn't correct function name"); +} +END_TEST + +START_TEST (test_nslog_trivial_uncorked_message) +{ + fail_unless(nslog_uncork() == NSLOG_NO_ERROR, + "Unable to uncork"); + fail_unless(captured_message_count == 0, + "Unusual, we had messages from before uncorking"); + NSLOG(test, INFO, "Hello %s", "world"); + fail_unless(captured_message_count == 1, + "Captured message count was wrong"); + fail_unless(captured_render_context == anchor_context_1, + "Captured context wasn't passed through"); + fail_unless(strcmp(captured_context.category->name, "test") == 0, + "Captured context category wasn't normalised"); + fail_unless(captured_context.category == &__nslog_category_test, + "Captured context category wasn't the one we wanted"); + fail_unless(captured_rendered_message_length == 11, + "Captured message wasn't correct length"); + fail_unless(strcmp(captured_rendered_message, "Hello world") == 0, + "Captured message wasn't correct"); + fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0, + "Captured message wasn't correct filename"); + fail_unless(strcmp(captured_context.funcname, "test_nslog_trivial_uncorked_message") == 0, + "Captured message wasn't correct function name"); +} +END_TEST + +/**** The next set of tests need a fixture set for filters ****/ + +static nslog_filter_t *cat_test = NULL; +static nslog_filter_t *cat_another = NULL; + +static const char *anchor_context_2 = "2"; + +static void +with_simple_filter_context_setup(void) +{ + captured_render_context = NULL; + memset(&captured_context, 0, sizeof(captured_context)); + memset(captured_rendered_message, 0, sizeof(captured_rendered_message)); + captured_rendered_message_length = 0; + captured_message_count = 0; + fail_unless(nslog_set_render_callback( + nslog__test__render_function, + (void *)anchor_context_2) == NSLOG_NO_ERROR, + "Unable to set up render callback"); + fail_unless(nslog_filter_category_new("test", &cat_test) == NSLOG_NO_ERROR, + "Unable to create a category filter for 'test'"); + fail_unless(nslog_filter_category_new("another", &cat_another) == NSLOG_NO_ERROR, + "Unable to create a category filter for 'another'"); +} + +static void +with_simple_filter_context_teardown(void) +{ + /* Nothing to do to tear down */ + fail_unless(nslog_filter_set_active(NULL, NULL) == NSLOG_NO_ERROR, + "Unable to clear active filter"); + cat_test = nslog_filter_unref(cat_test); + cat_another = nslog_filter_unref(cat_another); +} + +START_TEST (test_nslog_simple_filter_corked_message) +{ + NSLOG(test, INFO, "Hello world"); + fail_unless(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR, + "Unable to set active filter to cat:test"); + fail_unless(nslog_uncork() == NSLOG_NO_ERROR, + "Unable to uncork"); + fail_unless(captured_message_count == 1, + "Captured message count was wrong"); + fail_unless(captured_render_context == anchor_context_2, + "Captured context wasn't passed through"); + fail_unless(strcmp(captured_context.category->name, "test") == 0, + "Captured context category wasn't normalised"); + fail_unless(captured_context.category == &__nslog_category_test, + "Captured context category wasn't the one we wanted"); + fail_unless(captured_rendered_message_length == 11, + "Captured message wasn't correct length"); + fail_unless(strcmp(captured_rendered_message, "Hello world") == 0, + "Captured message wasn't correct"); + fail_unless(strcmp(captured_context.filename, "test/basictests.c") == 0, + "Captured message wasn't correct filename"); + fail_unless(strcmp(captured_context.funcname, "test_nslog_simple_filter_corked_message") == 0, + "Captured message wasn't correct function name"); + +} +END_TEST + +/**** And the suites are set up here ****/ + +void +nslog_basic_suite(SRunner *sr) +{ + Suite *s = suite_create("libnslog: Basic tests"); + TCase *tc_basic = tcase_create("Abort checking"); + +#ifndef NDEBUG + /* + tcase_add_test_raise_signal(tc_basic, + test_lwc_string_hash_value_aborts, + SIGABRT); + */ +#endif + + suite_add_tcase(s, tc_basic); + + tc_basic = tcase_create("Simple log checks, no filters"); + + tcase_add_checked_fixture(tc_basic, with_simple_context_setup, + with_simple_context_teardown); + tcase_add_test(tc_basic, test_nslog_trivial_corked_message); + tcase_add_test(tc_basic, test_nslog_trivial_uncorked_message); + suite_add_tcase(s, tc_basic); + + tc_basic = tcase_create("Simple filter checks"); + + tcase_add_checked_fixture(tc_basic, with_simple_filter_context_setup, + with_simple_filter_context_teardown); + tcase_add_test(tc_basic, test_nslog_simple_filter_corked_message); + suite_add_tcase(s, tc_basic); + + srunner_add_suite(sr, s); +} diff --git a/test/explicitfilter.c b/test/explicitfilter.c deleted file mode 100644 index c7aca8a..0000000 --- a/test/explicitfilter.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017 Daniel Silverstone - * - * This file is part of libnslog. - * - * Licensed under the MIT License, - * http://www.opensource.org/licenses/mit-license.php - */ - -#include "nslog/nslog.h" - -#include -#include - -NSLOG_DEFINE_CATEGORY(test, "Test category"); - -static void test_render_function( - void *_ctx, nslog_entry_context_t *ctx, - const char *fmt, va_list args) -{ - (void)ctx; - fprintf(stderr, "%s %s:%d [%s] %s() ", - nslog_level_name(ctx->level), - ctx->filename, ctx->lineno, - ctx->category->name, - ctx->funcname); - vfprintf(stderr, fmt, args); - fprintf(stderr, "\n"); -} - -int main(int argc, char **argv) -{ - nslog_set_render_callback(test_render_function, NULL); - nslog_uncork(); - - nslog_filter_t *cat_test, *cat_another; - - assert(nslog_filter_category_new("test", &cat_test) == NSLOG_NO_ERROR); - assert(nslog_filter_category_new("another", &cat_another) == NSLOG_NO_ERROR); - - NSLOG(test, INFO, "Hurrah, a message!"); - assert(nslog_filter_set_active(cat_test, NULL) == NSLOG_NO_ERROR); - NSLOG(test, INFO, "You should see me."); - assert(nslog_filter_set_active(cat_another, NULL) == NSLOG_NO_ERROR); - NSLOG(test, INFO, "You should not see me!"); - assert(nslog_filter_set_active(NULL, NULL) == NSLOG_NO_ERROR); - NSLOG(test, INFO, "You should see this one though."); - - return 0; -} diff --git a/test/testmain.c b/test/testmain.c new file mode 100644 index 0000000..9a6b257 --- /dev/null +++ b/test/testmain.c @@ -0,0 +1,50 @@ +/* test/testmain.c + * + * Core of the test suite for libnslog + * + * Copyright 2009, 2017 The NetSurf Browser Project + * Daniel Silverstone + */ + +#include +#include + +#include "tests.h" + +#ifndef UNUSED +#define UNUSED(x) ((x) = (x)) +#endif + +/* This means that assertion failures are silent in tests */ +#ifndef NDEBUG +void __assert_fail(const char *__assertion, const char *__file, + unsigned int __line, const char *__function) { + (void)__assertion; + (void)__file; + (void)__line; + (void)__function; + abort(); +} +#endif + +int +main(int argc, char **argv) +{ + int number_failed = 0; + SRunner *sr; + + UNUSED(argc); + UNUSED(argv); + + sr = srunner_create(suite_create("Test suite for libnslog")); + + nslog_basic_suite(sr); + + srunner_set_fork_status(sr, CK_FORK); + srunner_run_all(sr, CK_ENV); + number_failed = srunner_ntests_failed(sr); + + srunner_free(sr); + + return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/test/tests.h b/test/tests.h new file mode 100644 index 0000000..37cdd8d --- /dev/null +++ b/test/tests.h @@ -0,0 +1,21 @@ +/* test/tests.h + * + * Set of test suites for libnslog + * + * Copyright 2009,2017 The NetSurf Browser Project + * Daniel Silverstone + */ + +#ifndef nslog_tests_h_ +#define nslog_tests_h_ + +#include +#include + +#include + +#include "nslog/nslog.h" + +extern void nslog_basic_suite(SRunner *); + +#endif /* nslog_tests_h_ */ -- cgit v1.2.3