Introducing unit test in EFL using cvs check library for the test

suite (http://check.sourceforge.net/) and lcov from cvs also for the
coverage accounting (http://ltp.sourceforge.net/coverage/lcov.php).
   This first set provide an overall coverage rate for src/lib 2111
of 2607 lines (81.0%) for eet. And it helped in finding and fixing
the bugs of the last three days.


SVN revision: 34591
This commit is contained in:
Cedric BAIL 2008-05-16 15:07:03 +00:00
parent d7cf02c1b5
commit 0f5070cf40
11 changed files with 1415 additions and 3 deletions

View File

@ -8,4 +8,37 @@
(IS_SIMPLE_TYPE) to alloc the correct amount (using the correct type
offset). Also fixed a hash (EET_G_HASH) of simple types too.
2008-05-14 Cedric BAIL
* Fix convertion from a text to a hash (EET_G_HASH).
* Fix inlined string (EET_T_INLINED_STRING) dump/undump by introducing
the new word for the parser 'inlined'.
2008-05-15 Cedric BAIL
* Fix a typo preventing the parsing of unsigned int (EET_T_UINT).
* Fix group of simple type by implicitly creating a structure with
the simple type in it.
* Remove dead code handling group of simple type and put assert
instead.
2008-05-16 Cedric BAIL
* Fix eet_data_descriptor3_new as it purpose was to introduce
str_direct_alloc/str_direct_free usage. Application should now receive
direct pointer to read only (mmaped) string.
* Fix EET_FILE_MODE_READ_WRITE when file doesn't exist.
* Fix some miss use of efn->offset.
* Introduce unit test in EFL. The current set provide an overall
coverage rate of 2111 of 2607 lines (81.0%) for eet. It helped
finding and fixing the bugs of the last three days.
The test suite is based on library check. At this time we need
cvs version, look at http://check.sourceforge.net/ to find it.
The covering is done by lcov and we also need the cvs version that
you can found at http://ltp.sourceforge.net/coverage/lcov.php.

View File

@ -39,3 +39,11 @@ after the mingw32ce case
3) run configure with the option
--host=arm-wince-cegcc
NOTE: If you want to be able to run make check, you need library check
from http://check.sourceforge.net/.
NOTE: If you want to be able to run coverage test over eet, you will need
lcov from http://ltp.sourceforge.net/coverage/lcov.php.
NOTE: For coverage support you also need check support.

View File

@ -38,3 +38,49 @@ gendoc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = eet.pc
if EET_ENABLE_TESTS
check-local:
@./src/tests/eet_suite
else
check-local:
@echo "reconfigure with --enable-tests"
endif
if EET_ENABLE_COVERAGE
lcov-reset:
@rm -rf coverage
@find . -name "*.gcda" -exec rm {} \;
@lcov --directory . --zerocounters
lcov-report:
@mkdir coverage
@lcov --compat-libtool --directory . --capture --output-file coverage/coverage.info
@lcov -l coverage/coverage.info | grep -v "`cd $(top_srcdir) && pwd`" | cut -d: -f1 > coverage/remove
@lcov -r coverage/coverage.info `cat coverage/remove` > coverage/coverage.cleaned.info
@rm coverage/remove
@mv coverage/coverage.cleaned.info coverage/coverage.info
@genhtml -t "$(PACKAGE_STRING)" -o coverage coverage/coverage.info
coverage:
@make lcov-reset
@make check
@make lcov-report
clean-local:
@rm -rf coverage
else
lcov-reset:
@echo "reconfigure with --enable-gcov"
lcov-report:
@echo "reconfigure with --enable-gcov"
coverage:
@echo "reconfigure with --enable-tests --enable-gcov"
endif

View File

@ -29,6 +29,8 @@ SNAP=`echo $PACKAGE_VERSION | awk -F. '{printf("%s", $4);}'`
version_info=`expr $VMAJ + $VMIN`":$VMIC:$VMIN"
AC_SUBST(version_info)
PKG_PROG_PKG_CONFIG
WIN32_CFLAGS=""
WIN32_LIBS=""
lt_no_undefined=""
@ -115,6 +117,73 @@ int main (int argc, char **argv) {
], AC_MSG_WARN([Cannot check when cross-compiling -- assuming null is okay])
)
dnl Unit Tests
AC_ARG_ENABLE(tests,
[AC_HELP_STRING([--enable-tests], [Enable tests @<:@default=no@:>@])],
[
if test "x${enableval}" = "xyes" ; then
enable_tests="yes"
else
enable_tests="no"
fi
],
[enable_tests="no"]
)
AC_MSG_CHECKING([if tests are built])
AC_MSG_RESULT([${enable_tests}])
if test "x${enable_tests}" = "xyes" ; then
PKG_CHECK_MODULES([CHECK],
[check >= 0.9.5],
[dummy="yes"],
[enable_tests="no"]
)
fi
AM_CONDITIONAL(EET_ENABLE_TESTS, test "x${enable_tests}" = "xyes")
dnl Coverage
AC_ARG_ENABLE(coverage,
[AC_HELP_STRING([--enable-coverage],
[compile with coverage profiling instrumentation @<:@default=no@:>@])],
[
if test "x${enableval}" = "xyes" ; then
enable_coverage="yes"
else
enable_coverage="no"
fi],
[enable_coverage="no"]
)
AC_MSG_CHECKING([whether to use profiling instrumentation])
AC_MSG_RESULT($enable_coverage)
if test "x$enable_tests" = "xno" -a "x$enable_coverage" = "xyes"; then
enable_coverage="no"
fi
if test "x$enable_coverage" = "xyes"; then
AC_CHECK_PROG(have_lcov,
[lcov],
[yes],
[no]
)
if test "x$have_lcov" = "xyes" ; then
COVERAGE_CFLAGS="-fprofile-arcs -ftest-coverage"
COVERAGE_LIBS="-lgcov"
dnl remove any optimisation flag and force debug symbols
CFLAGS="-g -O0"
else
AC_MSG_WARN([lcov is not found, disable profiling instrumentation])
enable_coverage="no"
fi
fi
AC_SUBST(COVERAGE_CFLAGS)
AC_SUBST(COVERAGE_LIBS)
AM_CONDITIONAL(EET_ENABLE_COVERAGE, test "x$enable_coverage" = "xyes")
#AM_CHECK_DOXYGEN()
AC_OUTPUT([
@ -124,6 +193,7 @@ eet.c
src/Makefile
src/lib/Makefile
src/bin/Makefile
src/tests/Makefile
README
eet.spec
])
@ -141,6 +211,9 @@ echo "------------------------------------------------------------------------"
echo
echo "Configuration Options Summary:"
echo
echo " Tests................: ${enable_tests}"
echo " Coverage.............: ${enable_coverage}"
echo
echo " Compilation..........: make"
echo
echo " Installation.........: make install"

View File

@ -1,3 +1,3 @@
MAINTAINERCLEANFILES = Makefile.in
SUBDIRS = lib bin
SUBDIRS = lib bin tests

View File

@ -7,7 +7,8 @@ AM_CPPFLAGS = \
-DPACKAGE_BIN_DIR=\"$(bindir)\" \
-DPACKAGE_LIB_DIR=\"$(libdir)\" \
-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
@EVIL_CFLAGS@
@EVIL_CFLAGS@ \
@COVERAGE_CFLAGS@
include_HEADERS = Eet.h
@ -22,8 +23,11 @@ eet_dictionary.c \
eet_utils.c
libeet_la_CFLAGS = @WIN32_CFLAGS@
libeet_la_LIBADD = @EVIL_LIBS@ @WIN32_LIBS@ -lz -ljpeg @fnmatch_libs@ -lm
libeet_la_LIBADD = @COVERAGE_LIBS@ @EVIL_LIBS@ @WIN32_LIBS@ -lz -ljpeg @fnmatch_libs@ -lm
libeet_la_LDFLAGS = @lt_no_undefined@ @lt_enable_auto_import@ -version-info @version_info@
libeet_la_DEPENDENCIES = $(top_builddir)/config.h
EXTRA_DIST = Eet_private.h
clean-local:
@rm -rf *.gcno

View File

@ -0,0 +1,17 @@
MAINTAINERCLEANFILES = Makefile.in
AM_CPPFLAGS = \
-I$(top_srcdir)/src/lib \
@CHECK_CFLAGS@
if EET_ENABLE_TESTS
check_PROGRAMS = eet_suite
eet_suite_SOURCES = eet_suite.c eet_data_suite.c
eet_suite_LDADD = @CHECK_LIBS@ $(top_builddir)/src/lib/libeet.la
EXTRA_DIST = eet_suite.h
endif

View File

@ -0,0 +1,3 @@
The purpose of the current test is to check the validity of the result in a
normal environment. But we should at some point also test the robustness of
this library when for example malloc fail.

View File

@ -0,0 +1,163 @@
#include <string.h>
#include <stdio.h>
#include "eet_suite.h"
static char*
_eet_str_direct_alloc(const char *str)
{
return (char*) str;
}
static void
_eet_str_direct_free(const char *str)
{
}
/* Internal list stuff. */
struct _Eet_List
{
Eet_List *next;
const void *data;
};
Eet_List*
eet_list_prepend(Eet_List *list, const void *data)
{
Eet_List *new;
new = malloc(sizeof (Eet_List));
if (!new) return list;
new->next = list;
new->data = data;
return new;
}
Eet_List*
eet_list_next(Eet_List *list)
{
if (!list) return NULL;
return list->next;
}
void*
eet_list_data(Eet_List *list)
{
if (!list) return NULL;
return (void*) list->data;
}
void
eet_list_free(Eet_List *list)
{
while (list)
{
Eet_List *current = list;
list = list->next;
free(current);
}
}
/* Internal hash stuff */
struct _Eet_Hash
{
Eet_List *bucket[256];
};
typedef struct _Eet_Hash_Item Eet_Hash_Item;
struct _Eet_Hash_Item
{
const void *data;
char *key;
};
static inline int
_eet_hash_gen(const char *key)
{
unsigned int hash_num = 5381;
const unsigned char *ptr;
if (!key) return 0;
for (ptr = (unsigned char *)key; *ptr; ptr++)
hash_num = (hash_num * 33) ^ *ptr;
hash_num &= 0xff;
return (int)hash_num;
}
void
eet_hash_foreach(const Eet_Hash *hash, int (*func) (const Eet_Hash *hash, const char *key, void *data, void *fdata), const void *fdata)
{
int i;
if (!hash) return ;
for (i = 0; i < 256; ++i)
{
Eet_List *over;
for (over = hash->bucket[i]; over; over = eet_list_next(over))
{
Eet_Hash_Item *item = eet_list_data(over);
if (!func(hash, item->key, (void*) item->data, (void*) fdata)) return ;
}
}
}
Eet_Hash*
eet_hash_add(Eet_Hash *hash, const char *key, const void *data)
{
Eet_Hash_Item *item;
Eet_List *find;
int index;
if (!hash) hash = calloc(1, sizeof (Eet_Hash));
if (!hash) return NULL;
item = malloc(sizeof (Eet_Hash_Item) + strlen(key) + 1);
if (!item) return hash;
item->data = data;
item->key = (char*)(item + 1);
strcpy(item->key, key);
hash->bucket[_eet_hash_gen(key)] = eet_list_prepend(hash->bucket[_eet_hash_gen(key)], item);
return hash;
}
void
eet_hash_free(Eet_Hash *hash)
{
int i;
if (!hash) return ;
for (i = 0; i < 256; ++i)
{
Eet_List *over;
for (over = hash->bucket[i]; over; over = eet_list_next(over))
free(eet_list_data(over));
eet_list_free(hash->bucket[i]);
}
free(hash);
}
void
eet_test_setup_eddc(Eet_Data_Descriptor_Class *eddc)
{
eddc->version = EET_DATA_DESCRIPTOR_CLASS_VERSION;
eddc->func.mem_alloc = NULL;
eddc->func.mem_free = NULL;
eddc->func.str_alloc = NULL;
eddc->func.str_free = NULL;
eddc->func.list_next = eet_list_next;
eddc->func.list_append = eet_list_prepend;
eddc->func.list_data = eet_list_data;
eddc->func.list_free = eet_list_free;
eddc->func.hash_foreach = eet_hash_foreach;
eddc->func.hash_add = eet_hash_add;
eddc->func.hash_free = eet_hash_free;
eddc->func.str_direct_alloc = _eet_str_direct_alloc;
eddc->func.str_direct_free = _eet_str_direct_free;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
#ifndef _EET_SUITE_H
# define _EET_SUITE_H
#include "Eet.h"
typedef struct _Eet_List Eet_List;
typedef struct _Eet_Hash Eet_Hash;
Eet_List* eet_list_prepend(Eet_List *list, const void *data);
Eet_List* eet_list_next(Eet_List *list);
void* eet_list_data(Eet_List *list);
void eet_list_free(Eet_List *list);
void eet_hash_foreach(const Eet_Hash *hash, int (*func) (const Eet_Hash *hash, const char *key, void *data, void *fdata), const void *fdata);
Eet_Hash* eet_hash_add(Eet_Hash *hash, const char *key, const void *data);
void eet_hash_free(Eet_Hash *hash);
void eet_test_setup_eddc(Eet_Data_Descriptor_Class *eddc);
#endif /* _EET_SUITE_H */