Skip to content

Commit

Permalink
Merge pull request #142 from fjoncourt/c_unit_testing
Browse files Browse the repository at this point in the history
C unit testing - excellent, thank you Franck. I'll work on the relative path issue you mentioned as well.
  • Loading branch information
mrash committed Jan 17, 2015
2 parents 6b7a3bb + 1c81aef commit e8cfeaf
Show file tree
Hide file tree
Showing 21 changed files with 737 additions and 27 deletions.
5 changes: 5 additions & 0 deletions Makefile.am
Expand Up @@ -8,11 +8,16 @@ if WANT_SERVER
SERVER_DIR = server
endif

if WANT_C_UNIT_TESTS
C_UNIT_TESTS_DIR = test/c-unit-tests
endif

SUBDIRS = \
lib \
common \
$(CLIENT_DIR) \
$(SERVER_DIR) \
$(C_UNIT_TESTS_DIR) \
doc

EXTRA_DIST = \
Expand Down
64 changes: 64 additions & 0 deletions client/config_init.c
Expand Up @@ -52,6 +52,10 @@
#define BITMASK_ARRAY_SIZE 2 /*!< Number of 32bits integer used to handle bitmask in the fko_var_bitmask_t structure */
#define LF_CHAR 0x0A /*!< Hexadecimal value associated to the LF char */

#ifdef HAVE_C_UNIT_TESTS
DECLARE_TEST_SUITE(config_init, "Config init test suite");
#endif

/**
* Structure to handle long bitmask.
*
Expand Down Expand Up @@ -2586,3 +2590,63 @@ usage(void)
return;
}

#ifdef HAVE_C_UNIT_TESTS

DECLARE_TEST_SUITE_INIT(config_init)
{
log_set_verbosity(LOG_VERBOSITY_ERROR);
return 0;
}

DECLARE_TEST_SUITE_CLEANUP(config_init)
{
return 0;
}

DECLARE_UTEST(critical_var, "Check critcial vars")
{
CU_ASSERT(var_is_critical(FWKNOP_CLI_ARG_KEY_RIJNDAEL) == 1);
CU_ASSERT(var_is_critical(FWKNOP_CLI_ARG_WGET_CMD) == 0);
}

DECLARE_UTEST(check_var_bitmask, "Check var_bitmask functions")
{
fko_var_bitmask_t var_bitmask;

memset(&var_bitmask, 0x00, sizeof(fko_var_bitmask_t));

add_var_to_bitmask(FWKNOP_CLI_FIRST_ARG, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_FIRST_ARG, &var_bitmask) == 1);
CU_ASSERT(var_bitmask.dw[0] == 1);
remove_var_from_bitmask(FWKNOP_CLI_FIRST_ARG, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_FIRST_ARG, &var_bitmask) == 0);
CU_ASSERT(var_bitmask.dw[0] == 0);

add_var_to_bitmask(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask) == 1);
remove_var_from_bitmask(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_ARG_KEY_RIJNDAEL, &var_bitmask) == 0);

add_var_to_bitmask(FWKNOP_CLI_LAST_ARG, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG, &var_bitmask) == 1);
remove_var_from_bitmask(FWKNOP_CLI_LAST_ARG, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG, &var_bitmask) == 0);

add_var_to_bitmask(FWKNOP_CLI_LAST_ARG+32, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG+32, &var_bitmask) == 0);

add_var_to_bitmask(FWKNOP_CLI_LAST_ARG+34, &var_bitmask);
CU_ASSERT(bitmask_has_var(FWKNOP_CLI_LAST_ARG+34, &var_bitmask) == 0);
}

int register_ts_config_init(void)
{
ts_init(&TEST_SUITE(config_init), TEST_SUITE_DESCR(config_init), TEST_SUITE_INIT(config_init), TEST_SUITE_CLEANUP(config_init));
ts_add_utest(&TEST_SUITE(config_init), UTEST_FCT(critical_var), UTEST_DESCR(critical_var));
ts_add_utest(&TEST_SUITE(config_init), UTEST_FCT(check_var_bitmask), UTEST_DESCR(check_var_bitmask));

return register_ts(&TEST_SUITE(config_init));
}

#endif /* HAVE_C_UNIT_TESTS */

4 changes: 4 additions & 0 deletions client/config_init.h
Expand Up @@ -43,6 +43,10 @@
void config_init(fko_cli_options_t *options, int argc, char **argv);
void usage(void);

#ifdef HAVE_C_UNIT_TESTS
int register_ts_config_init(void);
#endif

#endif /* CONFIG_INIT_H */

/***EOF***/
2 changes: 1 addition & 1 deletion common/Makefile.am
Expand Up @@ -2,7 +2,7 @@ AUTOMAKE_OPTIONS = subdir-objects

noinst_LIBRARIES = libfko_util.a

libfko_util_source_files = ../lib/strlcpy.c ../lib/strlcat.c ../lib/fko_util.c ../lib/fko_util.h
libfko_util_source_files = ../lib/cunit_common.c cunit_common.h ../lib/strlcpy.c ../lib/strlcat.c ../lib/fko_util.c ../lib/fko_util.h

libfko_util_a_SOURCES = $(libfko_util_source_files)

Expand Down
6 changes: 6 additions & 0 deletions common/common.h
Expand Up @@ -42,6 +42,12 @@
#include <fiu-control.h>
#endif

/* Include cunit header if c unit testing support is enabled. */
#ifdef HAVE_C_UNIT_TESTS
#include "CUnit/Basic.h"
#include "cunit_common.h"
#endif

#include <stdio.h>

#if HAVE_SYS_TYPES_H
Expand Down
37 changes: 37 additions & 0 deletions common/cunit_common.h
@@ -0,0 +1,37 @@
#ifndef CUNIT_COMMON_H
#define CUNIT_COMMON_H

typedef struct c_unit_test
{
char description[128];
void (*func)(void);
} c_unit_test_t;

typedef struct c_unit_test_suite
{
char description[128];
int (*init_func)(void);
int (*cleanup_func)(void);
c_unit_test_t test_array[12];
int nb_c_unit_test;
} c_unit_test_suite_t;

#define UTEST_DESCR(name) ut_descr_##name
#define UTEST_FCT(name) ut_##name
#define TEST_SUITE(name) ts_##name
#define TEST_SUITE_DESCR(name) ts_descr_##name
#define TEST_SUITE_INIT(name) _ts_init_##name
#define TEST_SUITE_CLEANUP(name) _ts_cleanup_##name

#define DECLARE_TEST_SUITE(name, description) static const char ts_descr_##name[] = description; \
static c_unit_test_suite_t ts_##name;
#define DECLARE_TEST_SUITE_INIT(name) int _ts_init_##name(void)
#define DECLARE_TEST_SUITE_CLEANUP(name) int _ts_cleanup_##name(void)
#define DECLARE_UTEST(name, description) static const char ut_descr_##name[] = description; \
static void ut_##name(void)

void ts_init(c_unit_test_suite_t* ts, const char* description, int (*init)(void), int (*cleanup)(void));
void ts_add_utest(c_unit_test_suite_t* ts, void (*utest_func)(void), const char* utest_description);
int register_ts(c_unit_test_suite_t *ts);

#endif // CUNIT_COMMON_H
20 changes: 19 additions & 1 deletion configure.ac
Expand Up @@ -21,7 +21,7 @@ AC_CONFIG_AUX_DIR(config)

AC_CANONICAL_TARGET

AM_INIT_AUTOMAKE
AM_INIT_AUTOMAKE([subdir-objects])

dnl AM_MAINTAINER_MODE

Expand Down Expand Up @@ -153,6 +153,23 @@ if test "x$want_libfiu_support" = "xyes"; then
FKO_CHECK_COMPILER_ARG_LDFLAGS_ONLY([-lfiu])
fi

dnl Decide whether or not to enable C unit testing
dnl
want_c_unit_tests=no
AC_ARG_ENABLE([c-unit-tests],
[AS_HELP_STRING([--enable-c-unit-tests],
[Enable C unit testing with libcunit support @<:@default is to disable@:>@])],
[want_c_unit_tests=$enableval],
[])

if test "x$want_c_unit_tests" = "xyes"; then
AC_DEFINE([HAVE_C_UNIT_TESTS], [1], [Define for C unit testing support])
FKO_CHECK_COMPILER_ARG([-DHAVE_C_UNIT_TESTS])
FKO_CHECK_COMPILER_ARG_LDFLAGS_ONLY([-lcunit])
fi

AM_CONDITIONAL([WANT_C_UNIT_TESTS], [test "$want_c_unit_tests" = yes])

dnl Decide whether or not to compile in certain features that enable fuzzing
dnl of fwknop code - this is for testing purposes only.
dnl
Expand Down Expand Up @@ -693,6 +710,7 @@ AC_CONFIG_FILES([Makefile
client/Makefile
server/Makefile
common/Makefile
test/c-unit-tests/Makefile
doc/Makefile])
AC_OUTPUT
Expand Down
5 changes: 3 additions & 2 deletions lib/Makefile.am
Expand Up @@ -7,8 +7,9 @@ libfko_source_files = \
fko_message.h fko_nat_access.c fko_rand_value.c fko_server_auth.c \
fko.h fko_limits.h fko_timestamp.c fko_hmac.c hmac.c hmac.h \
fko_user.c fko_user.h md5.c md5.h rijndael.c rijndael.h sha1.c \
sha1.h sha2.c sha2.h fko_context.h fko_state.h fko_context.h \
gpgme_funcs.c gpgme_funcs.h strlcpy.c strlcat.c fko_util.c fko_util.h
sha1.h sha2.c sha2.h fko_context.h fko_state.h \
gpgme_funcs.c gpgme_funcs.h strlcpy.c strlcat.c fko_util.c fko_util.h \
cunit_common.c cunit_common.h

libfko_la_SOURCES = $(libfko_source_files)
libfko_la_LDFLAGS = -version-info 2:3:0 $(GPGME_LIBS) -export-symbols-regex '^fko_'
Expand Down
51 changes: 51 additions & 0 deletions lib/cunit_common.c
@@ -0,0 +1,51 @@
#ifdef HAVE_C_UNIT_TESTS

#include "cunit_common.h"
#include "stdlib.h"
#include "stdio.h"
#include "CUnit/Basic.h"

void ts_init(c_unit_test_suite_t* ts, const char* description, int (*init)(void), int (*cleanup)(void))
{
memset(ts, 0x00, sizeof(c_unit_test_suite_t));
strcpy(ts->description, description);
ts->init_func = init;
ts->cleanup_func = cleanup;
}

void ts_add_utest(c_unit_test_suite_t* ts, void (*utest_func)(void), const char* utest_description)
{
c_unit_test_t* utest = &(ts->test_array[ts->nb_c_unit_test]);

utest->func = utest_func;
strcpy(utest->description, utest_description);

(ts->nb_c_unit_test)++;
}

int register_ts(c_unit_test_suite_t *ts)
{
CU_pSuite pSuite = NULL;
int ix_utest;

pSuite = CU_add_suite(ts->description, ts->init_func, ts->cleanup_func);
if (NULL == pSuite) {
CU_cleanup_registry();
return CU_get_error();
}

/* add the tests to the suite */
for (ix_utest=0 ; ix_utest<ts->nb_c_unit_test ; ix_utest++)
{
c_unit_test_t* utest = &(ts->test_array[ix_utest]);
if (NULL == CU_add_test(pSuite, utest->description, utest->func))
{
CU_cleanup_registry();
return CU_get_error();
}
}

return 0;
}

#endif /* HAVE_C_UNIT_TESTS */
4 changes: 4 additions & 0 deletions lib/fko.h
Expand Up @@ -448,6 +448,10 @@ DLL_API int fko_gpg_signature_fpr_match(fko_ctx_t ctx, const char * const fpr,
}
#endif

#ifdef HAVE_C_UNIT_TESTS
int register_ts_fko_decode(void);
#endif

#endif /* FKO_H */

/***EOF***/
68 changes: 68 additions & 0 deletions lib/fko_decode.c
Expand Up @@ -36,6 +36,13 @@

#define FIELD_PARSERS 9

/* Char used to separate SPA fields in an SPA packet */
#define SPA_FIELD_SEPARATOR ":"

#ifdef HAVE_C_UNIT_TESTS
DECLARE_TEST_SUITE(fko_decode, "FKO decode test suite");
#endif

static int
num_fields(char *str)
{
Expand Down Expand Up @@ -590,4 +597,65 @@ fko_decode_spa_data(fko_ctx_t ctx)
return(FKO_SUCCESS);
}

#ifdef HAVE_C_UNIT_TESTS

DECLARE_UTEST(num_fields, "Count the number of SPA fields in a SPA packet")
{
int ix_field=0;
char spa_packet[(MAX_SPA_FIELDS+1)*3];

/* Zeroing the spa packet */
memset(spa_packet, 0, sizeof(spa_packet));

/* Check we are able to count the number of SPA fields */
for(ix_field=0 ; ix_field<=MAX_SPA_FIELDS+2 ; ix_field++)
{
strcat(spa_packet, "x");
CU_ASSERT(num_fields(spa_packet) == ix_field);
strcat(spa_packet, SPA_FIELD_SEPARATOR);
}

/* Check for possible overflow */
strcat(spa_packet, "x");
CU_ASSERT(num_fields(spa_packet) == MAX_SPA_FIELDS + 2);
strcat(spa_packet, "x");
strcat(spa_packet, SPA_FIELD_SEPARATOR);
CU_ASSERT(num_fields(spa_packet) == MAX_SPA_FIELDS + 2);
}

DECLARE_UTEST(last_field, "Count the number of bytes to the last :")
{
int ix_field;
char spa_packet[(MAX_SPA_FIELDS+1)*3];

/* Zeroing the spa packet */
memset(spa_packet, 0, sizeof(spa_packet));

/* Check for a valid count when the number of field is less than MAX_SPA_FIELDS */
CU_ASSERT(last_field("a:") == 2);
CU_ASSERT(last_field("ab:abc:") == 7);
CU_ASSERT(last_field("abc:abcd:") == 9);
CU_ASSERT(last_field("abc:abcd:abc") == 9);


/* */
for(ix_field=0 ; ix_field<=MAX_SPA_FIELDS+2 ; ix_field++)
{
strcat(spa_packet, "x");
strcat(spa_packet, SPA_FIELD_SEPARATOR);
}
CU_ASSERT(last_field(spa_packet) == ((MAX_SPA_FIELDS+2)*2));
}

int register_ts_fko_decode(void)
{
ts_init(&TEST_SUITE(fko_decode), TEST_SUITE_DESCR(fko_decode), NULL, NULL);
ts_add_utest(&TEST_SUITE(fko_decode), UTEST_FCT(num_fields), UTEST_DESCR(num_fields));
ts_add_utest(&TEST_SUITE(fko_decode), UTEST_FCT(last_field), UTEST_DESCR(last_field));

return register_ts(&TEST_SUITE(fko_decode));
}

#endif /* HAVE_C_UNIT_TESTS */

/***EOF***/
3 changes: 2 additions & 1 deletion server/Makefile.am
Expand Up @@ -12,7 +12,8 @@ fwknopd_SOURCES = fwknopd.c fwknopd.h config_init.c config_init.h \
fw_util_iptables.c fw_util_iptables.h \
fw_util_ipfw.c fw_util_ipfw.h \
fw_util_pf.c fw_util_pf.h cmd_opts.h \
extcmd.c extcmd.h
extcmd.c extcmd.h \
common.h

fwknopd_LDADD = $(top_builddir)/lib/libfko.la $(top_builddir)/common/libfko_util.a

Expand Down

0 comments on commit e8cfeaf

Please sign in to comment.