diff --git a/.gitignore b/.gitignore index edf81c9..f9e7c69 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,8 @@ Makefile.in m4/ /docs/ /INSTALL +coverage.base +coverage.run coverage.info coveragereport/ *.m4 diff --git a/Makefile.am.coverage b/Makefile.am.coverage index 72e718b..470d456 100644 --- a/Makefile.am.coverage +++ b/Makefile.am.coverage @@ -10,13 +10,19 @@ .PHONY: coverage-html generate-coverage-html clean-coverage-html coverage-html: clean-gcda + -$(MAKE) -C tests $(AM_MAKEFLAGS) -k check-build + $(MAKE) $(AM_MAKEFLAGS) init-coverage-html -$(MAKE) $(AM_MAKEFLAGS) -k check $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html + + init-coverage-html: + $(LCOV) -d $(top_builddir) -c -i -o coverage.base --no-checksum --compat-libtool generate-coverage-html: @echo Collecting coverage data - $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool - LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info + $(LCOV) -d $(top_builddir) -c -o coverage.run --no-checksum --compat-libtool + $(LCOV) -d $(top_builddir) -a ./coverage.base -a ./coverage.run -o coverage.info --no-checksum --compat-libtool + LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --branch-coverage --show-details coverage.info clean-coverage-html: clean-gcda -$(LCOV) --directory $(top_builddir) -z diff --git a/include/class/class.h b/include/class/class.h index 4a8146c..b8b38cc 100644 --- a/include/class/class.h +++ b/include/class/class.h @@ -66,10 +66,13 @@ }; struct class * const _##name = &c_##name #define INIT_CLASS(class) ((class)->init? (class)->init() : (class)) -#define GET_CLASS(object) (INIT_CLASS(*(class_ptr *)((object) - sizeof(void*)))) +#define GET_CLASS(object) (INIT_CLASS(*(class_ptr *)((void*)(object) - sizeof(void*)))) #define IFACE_GET(class,iface) (interfaceGet(&((class)->impl),(iface))) #define HAS_PARENT(class) (NULL != ((class)->parent) && INIT_CLASS((class)->parent)) +#define IS_OBJECT(obj) ((GET_CLASS((obj)))->magic == CLASS_MAGIC) +#define INSTANCE_OF(class,obj) ((GET_CLASS((obj))) == _##class) + /** * \todo actually i use gcc feature ## for variadoc... think about * a way to make this standard. diff --git a/src/class/Makefile.am b/src/class/Makefile.am index 0f13153..2b5b0ad 100644 --- a/src/class/Makefile.am +++ b/src/class/Makefile.am @@ -2,5 +2,5 @@ ACLOCAL_AMFLAGS = -I m4 noinst_LIBRARIES = libclass.a -libclass_a_SOURCES = interface.c interface/class.c +libclass_a_SOURCES = interface.c interface/i_class.c libclass_a_CFLAGS = -Wall -I ../../include/ diff --git a/src/class/interface/class.c b/src/class/interface/i_class.c similarity index 100% rename from src/class/interface/class.c rename to src/class/interface/i_class.c diff --git a/src/http/Makefile.am b/src/http/Makefile.am index d6c64b1..e6b2ace 100644 --- a/src/http/Makefile.am +++ b/src/http/Makefile.am @@ -1,5 +1,4 @@ ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = subdir-objects MSG = message.c \ message/has_keep_alive.c \ @@ -21,15 +20,15 @@ RESP = response.c \ PARSER = parser.c \ parser/parse.c \ parser/new_message.c \ - parser/header.c \ - parser/body.c \ - parser/request_vars.c \ - parser/post_vars.c + parser/p_header.c \ + parser/p_body.c \ + parser/p_request_vars.c \ + parser/p_post_vars.c WRITER = writer.c \ writer/write.c WORKER = worker.c \ worker/process.c \ - worker/write.c \ + worker/answer.c \ worker/get_asset.c \ worker/add_common_header.c HEADER = header.c \ @@ -38,5 +37,5 @@ HEADER = header.c \ noinst_LIBRARIES = libhttp.a libhttp_a_SOURCES = $(MSG) $(MSGQ) $(REQ) $(RESP) $(PARSER) $(WRITER) \ - $(WORKER) $(HEADER) interface/http_intro.c + $(WORKER) $(HEADER) interface/i_http_intro.c libhttp_a_CFLAGS = -Wall -I ../../include/ diff --git a/src/http/interface/http_intro.c b/src/http/interface/i_http_intro.c similarity index 100% rename from src/http/interface/http_intro.c rename to src/http/interface/i_http_intro.c diff --git a/src/http/parser/body.c b/src/http/parser/p_body.c similarity index 100% rename from src/http/parser/body.c rename to src/http/parser/p_body.c diff --git a/src/http/parser/header.c b/src/http/parser/p_header.c similarity index 100% rename from src/http/parser/header.c rename to src/http/parser/p_header.c diff --git a/src/http/parser/post_vars.c b/src/http/parser/p_post_vars.c similarity index 100% rename from src/http/parser/post_vars.c rename to src/http/parser/p_post_vars.c diff --git a/src/http/parser/request_vars.c b/src/http/parser/p_request_vars.c similarity index 100% rename from src/http/parser/request_vars.c rename to src/http/parser/p_request_vars.c diff --git a/src/http/worker/write.c b/src/http/worker/answer.c similarity index 100% rename from src/http/worker/write.c rename to src/http/worker/answer.c diff --git a/src/logger/Makefile.am b/src/logger/Makefile.am index dc433f1..261a0b9 100644 --- a/src/logger/Makefile.am +++ b/src/logger/Makefile.am @@ -1,7 +1,6 @@ ACLOCAL_AMFLAGS = -I m4 -AUTOMAKE_OPTIONS = subdir-objects noinst_LIBRARIES = liblogger.a -liblogger_a_SOURCES = interface/logger.c logger.c stderr.c syslog.c +liblogger_a_SOURCES = interface/i_logger.c logger.c stderr.c syslog.c liblogger_a_CFLAGS = -Wall -I ../../include/ diff --git a/src/logger/interface/logger.c b/src/logger/interface/i_logger.c similarity index 100% rename from src/logger/interface/logger.c rename to src/logger/interface/i_logger.c diff --git a/tests/Makefile.am b/tests/Makefile.am index 1bdee2a..bb2385f 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,17 +1,24 @@ ACLOCAL_AMFLAGS = -I m4 TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet -TESTS = classTest# loggerTest socketTest serverTest -check_PROGRAMS = classTest# loggerTest socketTest serverTest +TESTS = classTest loggerTest# socketTest serverTest +check_PROGRAMS = classTest loggerTest# socketTest serverTest COMMON = runtest.c CLASS = $(COMMON) \ ../src/class/interface.c \ - ../src/class/interface/class.c \ + ../src/class/interface/i_class.c \ mock/mock_class.c -#LOGGER = $(COMMON) ../src/logger.c ../src/interface/logger.c \ -# ../src/logger/stderr.c ../src/logger/syslog.c +LOGGER = $(COMMON) \ + ../src/class/interface.c \ + ../src/class/interface/i_class.c \ + ../src/logger/logger.c \ + ../src/logger/stderr.c \ + ../src/logger/syslog.c \ + ../src/logger/interface/i_logger.c \ + mock/mock_logger.c + #SOCKET = $(LOGGER) ../src/socket.c ../src/socket/listen.c \ # ../src/socket/accept.c ../src/socket/connect.c #SERVER = $(SOCKET) ../src/server.c ../src/server/run.c \ @@ -21,9 +28,10 @@ classTest_SOURCES = $(CLASS) classTest.c classTest_CFLAGS = -Wall -ggdb -O0 -fprofile-arcs -ftest-coverage -I ../include -I .. -I . classTest_LDFLAGS = -lgcov -#loggerTest_SOURCES = $(LOGGER) loggerTest.c -#loggerTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . -# +loggerTest_SOURCES = $(LOGGER) loggerTest.c +loggerTest_CFLAGS = -Wall -ggdb -O0 -fprofile-arcs -ftest-coverage -I ../include -I .. -I . +loggerTest_LDFLAGS = -lgcov + #socketTest_SOURCES = $(SOCKET) socketTest.c #socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . # @@ -31,3 +39,5 @@ classTest_LDFLAGS = -lgcov #serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . EXTRA_DIST = runtest.h mock/mock_class.h + +check-build: $(check_PROGRAMS) diff --git a/tests/classTest.c b/tests/classTest.c index a16b757..a9847e8 100644 --- a/tests/classTest.c +++ b/tests/classTest.c @@ -60,7 +60,18 @@ testNew(void) ASSERT_OBJECT_NOT_NULL(mock); ASSERT_EQUAL(1, _called); - ASSERT_EQUAL(123, mockClassGetValue(mock)); + ASSERT_EQUAL(123, mock->value); + + return TEST_OK; +} + +static +int +testNewFail(void) +{ + mock = new(MockClass, 321); + + ASSERT_NULL(mock); return TEST_OK; } @@ -82,9 +93,28 @@ testDelete(void) return TEST_OK; } +static +int +testClone(void) +{ + MockClass clone; + + mock = new(MockClass, 123); + clone = clone(mock); + + ASSERT_INSTANCE_OF(MockClass, clone); + ASSERT_EQUAL(mock->value, clone->value); + + delete(clone); + + return TEST_OK; +} + const testfunc tests[] = { testNew, + testNewFail, testDelete, + testClone }; const size_t count = FUNCS_COUNT(tests); diff --git a/tests/loggerTest b/tests/loggerTest new file mode 100755 index 0000000..08e44f2 Binary files /dev/null and b/tests/loggerTest differ diff --git a/tests/loggerTest.c b/tests/loggerTest.c index 2727a47..acf6bff 100644 --- a/tests/loggerTest.c +++ b/tests/loggerTest.c @@ -21,73 +21,94 @@ #include #include "runtest.h" -#include "cclass.h" +#include "class.h" #include "logger.h" +#include "mock/mock_logger.h" -int level = -1; -char * msg = NULL; +const char testname[] = "loggerTest"; +Logger logger = NULL; + -static void -logfnct_mock(int _level, const char * _msg) +static +int +__setUp() { - level = _level; - msg = malloc(strlen(_msg) + 1); - strcpy(msg, _msg); + return TEST_OK; } +int (* const setUp)() = __setUp; -const char testname[] = "loggerTest"; -LOGGER logger = NULL; +static +int +__tearDown() +{ + if (NULL != logger) { + ASSERT_OBJECT(logger); + delete(logger); + } + return TEST_OK; +} +int (* const tearDown)() = __tearDown; static int -__setUp() +testLoggerLevel() { - logger = new(LOGGER, NULL); + logger = new(MockLogger, LOGGER_ERR); - ASSERT_INSTANCE_OF(LOGGER, logger); + ASSERT_INSTANCE_OF(MockLogger, logger); + ASSERT_EQUAL(LOGGER_ERR, logger->min_level); - logger_add(logger, logfnct_mock); + loggerLog(logger, LOGGER_WARNING, "foo %d %s", 123, "bar"); + + ASSERT_STRING_EQUAL("", ((MockLogger)logger)->message); + + loggerLog(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); + ASSERT_STRING_EQUAL("[ERR] foo 123 bar", ((MockLogger)logger)->message); + + mockLoggerCleanMsg((MockLogger)logger); + loggerLog(logger, LOGGER_CRIT, "foo %d %s", 123, "bar"); + ASSERT_STRING_EQUAL("[CRIT] foo 123 bar", ((MockLogger)logger)->message); return TEST_OK; } -int (* const setUp)() = __setUp; static int -__tearDown() +testLoggerStderr() { - level = -1; + logger = new(LoggerStderr, LOGGER_ERR); - if (NULL != msg) { - free(msg); - msg = NULL; - } + freopen("/dev/null", "w", stderr); + loggerLog(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); - if (NULL != logger) { - ASSERT_OBJECT(logger); - delete(&logger); - } + /** + * \todo think about a way to assert something here + */ return TEST_OK; } -int (* const tearDown)() = __tearDown; static int -testLogger() +testLoggerSyslog() { - logger_log(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); + logger = new(LoggerSyslog, LOGGER_ERR); + + loggerLog(logger, LOGGER_ERR, "foo %d %s", 123, "bar"); - ASSERT_EQUAL(LOGGER_ERR, level); - ASSERT_STRING_EQUAL("foo 123 bar", msg); + /** + * \todo think about a way to assert something here + */ return TEST_OK; } const testfunc tests[] = { - testLogger + testLoggerLevel, + testLoggerStderr, + testLoggerSyslog }; const size_t count = FUNCS_COUNT(tests); diff --git a/tests/mock/mock_class.c b/tests/mock/mock_class.c index f603d94..6088e16 100644 --- a/tests/mock/mock_class.c +++ b/tests/mock/mock_class.c @@ -41,6 +41,9 @@ mockCtor(void * _this, va_list * params) _called = 1; this->value = va_arg(* params, int); + if (321 == this->value) + return -1; + return 0; } @@ -52,32 +55,18 @@ mockDtor(void * _this) _called = 1; } -INIT_IFACE(Class, mockCtor, mockDtor, NULL); -CREATE_CLASS(MockClass, NULL, IFACE(Class)); - -/** - * ~~~ method implementations ~~~~~~~~ - */ - -int -mockClassGetValue(MockClass this) -{ - return this->value; -} - +static +inline void -mockClassSetValue(MockClass this, int value) +mockClone(void * _this, void * _base) { - this->value = value; -} + MockClass this = _this; + MockClass base = _base; -/** - * ~~~ helper for mock assertions ~~~~~~~~ - */ -void * -getConstruct() -{ - return mockCtor; + this->value = base->value; } +INIT_IFACE(Class, mockCtor, mockDtor, mockClone); +CREATE_CLASS(MockClass, NULL, IFACE(Class)); + // vim: set et ts=4 sw=4: diff --git a/tests/mock/mock_logger.c b/tests/mock/mock_logger.c new file mode 100644 index 0000000..6423f8c --- /dev/null +++ b/tests/mock/mock_logger.c @@ -0,0 +1,29 @@ +#include + +#include "class.h" +#include "logger.h" +#include "mock/mock_logger.h" + +static +void +logMock(void * _this, logger_level level, const char * const msg) +{ + MockLogger this = _this; + + snprintf(this->message, + MOCK_MESSAGE_MAX - 1, + "[%s] %s", + logger_level_str[level], + msg); +} + +void +mockLoggerCleanMsg(MockLogger this) +{ + this->message[0] = 0; +} + +INIT_IFACE(Logger, logMock); +CREATE_CLASS(MockLogger, Logger, IFACE(Logger)); + +// vim: set ts=4 sw=4: diff --git a/tests/mock/mock_logger.h b/tests/mock/mock_logger.h new file mode 100644 index 0000000..47dbcee --- /dev/null +++ b/tests/mock/mock_logger.h @@ -0,0 +1,20 @@ +#ifndef __MOCK_MOCK_LOGGER_H__ +#define __MOCK_MOCK_LOGGER_H__ + +#define MOCK_MESSAGE_MAX 1024 + +#include "class.h" +#include "logger.h" + +CLASS(MockLogger) +{ + EXTENDS(Logger); + + char message[MOCK_MESSAGE_MAX]; +}; + +void mockLoggerCleanMsg(MockLogger); + +#endif // __MOCK_MOCK_LOGGER_H__ + +// vim: set ts=4 sw=4: diff --git a/tests/runtest.c b/tests/runtest.c index ed85345..450ae19 100644 --- a/tests/runtest.c +++ b/tests/runtest.c @@ -36,20 +36,12 @@ const char results[3] = { TEST_ERROR_CHAR }; -int -isObject(void * object) -{ - class_ptr class = GET_CLASS(object); - - return (class->magic == CLASS_MAGIC); -} - int isObjectNull(void * object) { class_ptr class = GET_CLASS(object); - if (! isObject(object)) { + if (! IS_OBJECT(object)) { return 0; } diff --git a/tests/runtest.h b/tests/runtest.h index 8245172..1b60fd7 100644 --- a/tests/runtest.h +++ b/tests/runtest.h @@ -26,6 +26,7 @@ #include #include +#include "class.h" enum RESULT_TYPES { TEST_OK=0, @@ -94,7 +95,7 @@ enum RESULT_TYPES { return TEST_FAILED; } #define ASSERT_OBJECT(val) \ - if (! isObject((val))) { \ + if (! IS_OBJECT((val))) { \ printf("%s[%d]: Assertion failed that %s IS an object\n", \ __FILE__, __LINE__, #val); \ return TEST_FAILED; } @@ -112,7 +113,7 @@ enum RESULT_TYPES { return TEST_FAILED; } #define ASSERT_INSTANCE_OF(class, val) \ - if (! instanceOf(class, val)) { \ + if (! INSTANCE_OF(class, val)) { \ printf("%s[%d]: Assertion failed that %s is instance of %s\n", \ __FILE__, __LINE__, #val, #class); \ return TEST_FAILED; } @@ -130,7 +131,6 @@ extern int (* const tearDown)(); int isMemNull(void * _mem, size_t size); int isObjectNull(void * _object); -int isObject(void * _object); #endif//__RUNTEST_h__ // vim: set et ts=4 sw=4: