Browse Source

more tests...and some little structural changes to make then happen correctly with coverage reports. KEEP IN MIND: coverage reports lie to you. (But they are a good hint to see whats not testes enough

release0.1.5
Georg Hopp 14 years ago
parent
commit
34217eabac
  1. 2
      .gitignore
  2. 10
      Makefile.am.coverage
  3. 5
      include/class/class.h
  4. 2
      src/class/Makefile.am
  5. 0
      src/class/interface/i_class.c
  6. 13
      src/http/Makefile.am
  7. 0
      src/http/interface/i_http_intro.c
  8. 0
      src/http/parser/p_body.c
  9. 0
      src/http/parser/p_header.c
  10. 0
      src/http/parser/p_post_vars.c
  11. 0
      src/http/parser/p_request_vars.c
  12. 0
      src/http/worker/answer.c
  13. 3
      src/logger/Makefile.am
  14. 0
      src/logger/interface/i_logger.c
  15. 26
      tests/Makefile.am
  16. 32
      tests/classTest.c
  17. BIN
      tests/loggerTest
  18. 83
      tests/loggerTest.c
  19. 35
      tests/mock/mock_class.c
  20. 29
      tests/mock/mock_logger.c
  21. 20
      tests/mock/mock_logger.h
  22. 10
      tests/runtest.c
  23. 6
      tests/runtest.h

2
.gitignore

@ -11,6 +11,8 @@ Makefile.in
m4/ m4/
/docs/ /docs/
/INSTALL /INSTALL
coverage.base
coverage.run
coverage.info coverage.info
coveragereport/ coveragereport/
*.m4 *.m4

10
Makefile.am.coverage

@ -10,13 +10,19 @@
.PHONY: coverage-html generate-coverage-html clean-coverage-html .PHONY: coverage-html generate-coverage-html clean-coverage-html
coverage-html: clean-gcda 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) -k check
$(MAKE) $(AM_MAKEFLAGS) generate-coverage-html $(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: generate-coverage-html:
@echo Collecting coverage data @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 clean-coverage-html: clean-gcda
-$(LCOV) --directory $(top_builddir) -z -$(LCOV) --directory $(top_builddir) -z

5
include/class/class.h

@ -66,10 +66,13 @@
}; struct class * const _##name = &c_##name }; struct class * const _##name = &c_##name
#define INIT_CLASS(class) ((class)->init? (class)->init() : (class)) #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 IFACE_GET(class,iface) (interfaceGet(&((class)->impl),(iface)))
#define HAS_PARENT(class) (NULL != ((class)->parent) && INIT_CLASS((class)->parent)) #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 * \todo actually i use gcc feature ## for variadoc... think about
* a way to make this standard. * a way to make this standard.

2
src/class/Makefile.am

@ -2,5 +2,5 @@ ACLOCAL_AMFLAGS = -I m4
noinst_LIBRARIES = libclass.a 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/ libclass_a_CFLAGS = -Wall -I ../../include/

0
src/class/interface/class.c → src/class/interface/i_class.c

13
src/http/Makefile.am

@ -1,5 +1,4 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = subdir-objects
MSG = message.c \ MSG = message.c \
message/has_keep_alive.c \ message/has_keep_alive.c \
@ -21,15 +20,15 @@ RESP = response.c \
PARSER = parser.c \ PARSER = parser.c \
parser/parse.c \ parser/parse.c \
parser/new_message.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 = writer.c \
writer/write.c writer/write.c
WORKER = worker.c \ WORKER = worker.c \
worker/process.c \ worker/process.c \
worker/write.c \
worker/answer.c \
worker/get_asset.c \ worker/get_asset.c \
worker/add_common_header.c worker/add_common_header.c
HEADER = header.c \ HEADER = header.c \
@ -38,5 +37,5 @@ HEADER = header.c \
noinst_LIBRARIES = libhttp.a noinst_LIBRARIES = libhttp.a
libhttp_a_SOURCES = $(MSG) $(MSGQ) $(REQ) $(RESP) $(PARSER) $(WRITER) \ 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/ libhttp_a_CFLAGS = -Wall -I ../../include/

0
src/http/interface/http_intro.c → src/http/interface/i_http_intro.c

0
src/http/parser/body.c → src/http/parser/p_body.c

0
src/http/parser/header.c → src/http/parser/p_header.c

0
src/http/parser/post_vars.c → src/http/parser/p_post_vars.c

0
src/http/parser/request_vars.c → src/http/parser/p_request_vars.c

0
src/http/worker/write.c → src/http/worker/answer.c

3
src/logger/Makefile.am

@ -1,7 +1,6 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
AUTOMAKE_OPTIONS = subdir-objects
noinst_LIBRARIES = liblogger.a 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/ liblogger_a_CFLAGS = -Wall -I ../../include/

0
src/logger/interface/logger.c → src/logger/interface/i_logger.c

26
tests/Makefile.am

@ -1,17 +1,24 @@
ACLOCAL_AMFLAGS = -I m4 ACLOCAL_AMFLAGS = -I m4
TESTS_ENVIRONMENT = valgrind --error-exitcode=123 --leak-check=full --quiet 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 COMMON = runtest.c
CLASS = $(COMMON) \ CLASS = $(COMMON) \
../src/class/interface.c \ ../src/class/interface.c \
../src/class/interface/class.c \
../src/class/interface/i_class.c \
mock/mock_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 \ #SOCKET = $(LOGGER) ../src/socket.c ../src/socket/listen.c \
# ../src/socket/accept.c ../src/socket/connect.c # ../src/socket/accept.c ../src/socket/connect.c
#SERVER = $(SOCKET) ../src/server.c ../src/server/run.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_CFLAGS = -Wall -ggdb -O0 -fprofile-arcs -ftest-coverage -I ../include -I .. -I .
classTest_LDFLAGS = -lgcov 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_SOURCES = $(SOCKET) socketTest.c
#socketTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I . #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 . #serverTest_CFLAGS = -Wall -ggdb -O0 -I ../include -I .. -I .
EXTRA_DIST = runtest.h mock/mock_class.h EXTRA_DIST = runtest.h mock/mock_class.h
check-build: $(check_PROGRAMS)

32
tests/classTest.c

@ -60,7 +60,18 @@ testNew(void)
ASSERT_OBJECT_NOT_NULL(mock); ASSERT_OBJECT_NOT_NULL(mock);
ASSERT_EQUAL(1, _called); 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; return TEST_OK;
} }
@ -82,9 +93,28 @@ testDelete(void)
return TEST_OK; 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[] = { const testfunc tests[] = {
testNew, testNew,
testNewFail,
testDelete, testDelete,
testClone
}; };
const size_t count = FUNCS_COUNT(tests); const size_t count = FUNCS_COUNT(tests);

BIN
tests/loggerTest

83
tests/loggerTest.c

@ -21,73 +21,94 @@
#include <stdlib.h> #include <stdlib.h>
#include "runtest.h" #include "runtest.h"
#include "cclass.h"
#include "class.h"
#include "logger.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 static
int int
__setUp()
testLoggerLevel()
{ {
logger = new(LOGGER, NULL);
logger = new(MockLogger, LOGGER_ERR);
ASSERT_INSTANCE_OF(MockLogger, logger);
ASSERT_EQUAL(LOGGER_ERR, logger->min_level);
loggerLog(logger, LOGGER_WARNING, "foo %d %s", 123, "bar");
ASSERT_STRING_EQUAL("", ((MockLogger)logger)->message);
ASSERT_INSTANCE_OF(LOGGER, logger);
loggerLog(logger, LOGGER_ERR, "foo %d %s", 123, "bar");
ASSERT_STRING_EQUAL("[ERR] foo 123 bar", ((MockLogger)logger)->message);
logger_add(logger, logfnct_mock);
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; return TEST_OK;
} }
int (* const setUp)() = __setUp;
static static
int 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; return TEST_OK;
} }
int (* const tearDown)() = __tearDown;
static static
int 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; return TEST_OK;
} }
const testfunc tests[] = { const testfunc tests[] = {
testLogger
testLoggerLevel,
testLoggerStderr,
testLoggerSyslog
}; };
const size_t count = FUNCS_COUNT(tests); const size_t count = FUNCS_COUNT(tests);

35
tests/mock/mock_class.c

@ -41,6 +41,9 @@ mockCtor(void * _this, va_list * params)
_called = 1; _called = 1;
this->value = va_arg(* params, int); this->value = va_arg(* params, int);
if (321 == this->value)
return -1;
return 0; return 0;
} }
@ -52,32 +55,18 @@ mockDtor(void * _this)
_called = 1; _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 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: // vim: set et ts=4 sw=4:

29
tests/mock/mock_logger.c

@ -0,0 +1,29 @@
#include <stdio.h>
#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:

20
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:

10
tests/runtest.c

@ -36,20 +36,12 @@ const char results[3] = {
TEST_ERROR_CHAR TEST_ERROR_CHAR
}; };
int
isObject(void * object)
{
class_ptr class = GET_CLASS(object);
return (class->magic == CLASS_MAGIC);
}
int int
isObjectNull(void * object) isObjectNull(void * object)
{ {
class_ptr class = GET_CLASS(object); class_ptr class = GET_CLASS(object);
if (! isObject(object)) {
if (! IS_OBJECT(object)) {
return 0; return 0;
} }

6
tests/runtest.h

@ -26,6 +26,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <string.h> #include <string.h>
#include "class.h"
enum RESULT_TYPES { enum RESULT_TYPES {
TEST_OK=0, TEST_OK=0,
@ -94,7 +95,7 @@ enum RESULT_TYPES {
return TEST_FAILED; } return TEST_FAILED; }
#define ASSERT_OBJECT(val) \ #define ASSERT_OBJECT(val) \
if (! isObject((val))) { \
if (! IS_OBJECT((val))) { \
printf("%s[%d]: Assertion failed that %s IS an object\n", \ printf("%s[%d]: Assertion failed that %s IS an object\n", \
__FILE__, __LINE__, #val); \ __FILE__, __LINE__, #val); \
return TEST_FAILED; } return TEST_FAILED; }
@ -112,7 +113,7 @@ enum RESULT_TYPES {
return TEST_FAILED; } return TEST_FAILED; }
#define ASSERT_INSTANCE_OF(class, val) \ #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", \ printf("%s[%d]: Assertion failed that %s is instance of %s\n", \
__FILE__, __LINE__, #val, #class); \ __FILE__, __LINE__, #val, #class); \
return TEST_FAILED; } return TEST_FAILED; }
@ -130,7 +131,6 @@ extern int (* const tearDown)();
int isMemNull(void * _mem, size_t size); int isMemNull(void * _mem, size_t size);
int isObjectNull(void * _object); int isObjectNull(void * _object);
int isObject(void * _object);
#endif//__RUNTEST_h__ #endif//__RUNTEST_h__
// vim: set et ts=4 sw=4: // vim: set et ts=4 sw=4:
Loading…
Cancel
Save