From 35e1d6538a8767526b9cae66134441b146503a21 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Sat, 1 Jan 2011 17:33:42 +0100 Subject: [PATCH] unittest: framework for unit-testing This is the first approach at doing fairly clean and easy to write and debug unit tests. --- configure.ac | 3 +- tests/Makefile.am | 4 +-- tests/data/Makefile.am | 2 +- tests/data/test1300 | 30 +++++++++++++++++ tests/libtest/Makefile.inc | 1 + tests/libtest/first.c | 2 +- tests/runtests.pl | 11 ++++-- tests/unit/Makefile.am | 68 ++++++++++++++++++++++++++++++++++++++ tests/unit/Makefile.inc | 8 +++++ tests/unit/curlcheck.h | 31 +++++++++++++++++ tests/unit/unit1300.c | 34 +++++++++++++++++++ 11 files changed, 187 insertions(+), 7 deletions(-) create mode 100644 tests/data/test1300 create mode 100644 tests/unit/Makefile.am create mode 100644 tests/unit/Makefile.inc create mode 100644 tests/unit/curlcheck.h create mode 100644 tests/unit/unit1300.c diff --git a/configure.ac b/configure.ac index 1dab90e35..92adc5032 100644 --- a/configure.ac +++ b/configure.ac @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -2911,6 +2911,7 @@ AC_CONFIG_FILES([Makefile \ tests/data/Makefile \ tests/server/Makefile \ tests/libtest/Makefile \ + tests/unit/Makefile \ packages/Makefile \ packages/Win32/Makefile \ packages/Win32/cygwin/Makefile \ diff --git a/tests/Makefile.am b/tests/Makefile.am index 78450b100..decc2d8e2 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -5,7 +5,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -29,7 +29,7 @@ EXTRA_DIST = ftpserver.pl httpserver.pl secureserver.pl runtests.pl getpart.pm \ CMakeLists.txt certs/scripts/*.sh certs/Server* certs/EdelCurlRoot* \ serverhelp.pm tftpserver.pl rtspserver.pl directories.pm symbol-scan.pl -SUBDIRS = data server libtest +SUBDIRS = data server libtest unit PERLFLAGS = -I$(srcdir) diff --git a/tests/data/Makefile.am b/tests/data/Makefile.am index d4fa32abc..c7a1b467f 100644 --- a/tests/data/Makefile.am +++ b/tests/data/Makefile.am @@ -68,7 +68,7 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \ test1108 test1109 test1110 test1111 test1112 test129 test567 test568 \ test569 test570 test571 test572 test804 test805 test806 test807 test573 \ test313 test1115 test578 test579 test1116 test1200 test1201 test1202 \ - test1203 test1117 test1118 test1119 test1120 + test1203 test1117 test1118 test1119 test1120 test1300 filecheck: @mkdir test-place; \ diff --git a/tests/data/test1300 b/tests/data/test1300 new file mode 100644 index 000000000..8bbbecdef --- /dev/null +++ b/tests/data/test1300 @@ -0,0 +1,30 @@ + + + +unittest + + + +# +# Client-side + + +none + + +llist unit tests + + +unit1300 + + +unit1300 + + + +# +# Verify data after the test has been "shot" + + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index a0f1c0ecb..2354ecc60 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -164,3 +164,4 @@ lib573_SOURCES = lib573.c $(SUPPORTFILES) $(TESTUTIL) lib578_SOURCES = lib578.c $(SUPPORTFILES) lib579_SOURCES = lib579.c $(SUPPORTFILES) + diff --git a/tests/libtest/first.c b/tests/libtest/first.c index a0e713f48..53b372ba5 100644 --- a/tests/libtest/first.c +++ b/tests/libtest/first.c @@ -37,7 +37,7 @@ char *libtest_arg2=NULL; char *libtest_arg3=NULL; int test_argc; char **test_argv; - +int unitfail; /* for unittests */ int main(int argc, char **argv) { diff --git a/tests/runtests.pl b/tests/runtests.pl index 75f441bde..86bba844c 100755 --- a/tests/runtests.pl +++ b/tests/runtests.pl @@ -6,7 +6,7 @@ # | (__| |_| | _ <| |___ # \___|\___/|_| \_\_____| # -# Copyright (C) 1998 - 2010, Daniel Stenberg, , et al. +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. # # This software is licensed as described in the file COPYING, which # you should have received as part of this distribution. The terms @@ -145,6 +145,7 @@ my $DBGCURL=$CURL; #"../src/.libs/curl"; # alternative for debugging my $LOGDIR="log"; my $TESTDIR="$srcdir/data"; my $LIBDIR="./libtest"; +my $UNITDIR="./unit"; my $SERVERIN="$LOGDIR/server.input"; # what curl sent the server my $SERVER2IN="$LOGDIR/server2.input"; # what curl sent the second server my $CURLLOG="$LOGDIR/curl.log"; # all command lines run @@ -2630,7 +2631,13 @@ sub singletest { $cmdargs = " $cmd"; # $cmd is the command line for the test file $CURLOUT = $STDOUT; # sends received data to stdout - $CMDLINE="$LIBDIR/$tool"; + if($tool =~ /^lib/) { + $CMDLINE="$LIBDIR/$tool"; + } + elsif($tool =~ /^unit/) { + $CMDLINE="$UNITDIR/$tool"; + } + if(! -f $CMDLINE) { print "The tool set in the test case for this: '$tool' does not exist\n"; timestampskippedevents($testnum); diff --git a/tests/unit/Makefile.am b/tests/unit/Makefile.am new file mode 100644 index 000000000..69792283f --- /dev/null +++ b/tests/unit/Makefile.am @@ -0,0 +1,68 @@ +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) 1998 - 2011, Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at http://curl.haxx.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +########################################################################### +AUTOMAKE_OPTIONS = foreign nostdinc + +# Specify our include paths here, and do it relative to $(top_srcdir) and +# $(top_builddir), to ensure that these paths which belong to the library +# being currently built and tested are searched before the library which +# might possibly already be installed in the system. +# +# $(top_builddir)/include/curl for generated curlbuild.h included from curl.h +# $(top_builddir)/include for generated curlbuild.h included from lib/setup.h +# $(top_srcdir)/include is for libcurl's external include files +# $(top_builddir)/lib is for libcurl's generated lib/curl_config.h file +# $(top_srcdir)/lib is for libcurl's lib/setup.h and other "borrowed" files +# $(top_builddir)/ares is for in-tree c-ares's generated ares_build.h file +# $(top_srcdir)/ares is for in-tree c-ares's external include files + +if USE_EMBEDDED_ARES +INCLUDES = -I$(top_builddir)/include/curl \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/libtest \ + -I$(top_builddir)/ares \ + -I$(top_srcdir)/ares +else +INCLUDES = -I$(top_builddir)/include/curl \ + -I$(top_builddir)/include \ + -I$(top_srcdir)/include \ + -I$(top_builddir)/lib \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/tests/libtest +endif + +EXTRA_DIST = Makefile.inc + +LDADD = $(top_srcdir)/tests/libtest/first.o $(top_builddir)/lib/libcurl.la \ + @CURL_LIBS@ +DEPENDENCIES = $(top_builddir)/lib/libcurl.la + +# Makefile.inc provides the source defines (TESTUTIL, SUPPORTFILES, +# noinst_PROGRAMS, lib*_SOURCES, and lib*_CFLAGS) +include Makefile.inc + +if NO_UNDEFINED +# The -no-undefined flag is crucial to build fine on some platforms +UNDEF = -no-undefined +endif diff --git a/tests/unit/Makefile.inc b/tests/unit/Makefile.inc new file mode 100644 index 000000000..07d13188b --- /dev/null +++ b/tests/unit/Makefile.inc @@ -0,0 +1,8 @@ +# these files are used in every single unit test program + +UNITFILES = curlcheck.h + +# These are all unit test programs +noinst_PROGRAMS = unit1300 + +unit1300_SOURCES = unit1300.c $(UNITFILES) diff --git a/tests/unit/curlcheck.h b/tests/unit/curlcheck.h new file mode 100644 index 000000000..c34f99093 --- /dev/null +++ b/tests/unit/curlcheck.h @@ -0,0 +1,31 @@ +/***************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + */ + +#include "test.h" + +#define fail_unless(expr, msg) \ + if(!(expr)) { \ + fprintf(stderr, "%s:%d Assertion '%s' failed: %s" , \ + __FILE__, __LINE__, #expr, msg); \ + unitfail++; \ + } + +extern int unitfail; + +#define UNITTEST_START \ + int test(char *unused) \ + { \ + (void)unused; \ + unit_setup(); + +#define UNITTEST_STOP \ + unit_stop(); \ + return unitfail; \ + } + diff --git a/tests/unit/unit1300.c b/tests/unit/unit1300.c new file mode 100644 index 000000000..92c0a7ac9 --- /dev/null +++ b/tests/unit/unit1300.c @@ -0,0 +1,34 @@ +#include +#include "curl_config.h" +#include "setup.h" + +#include "llist.h" +#include "curlcheck.h" + +struct curl_llist *llist; + +static void test_curl_llist_dtor(void *key , void *value) +{ + /* used by the llist API, does nothing here */ + (void)key; + (void)value; +} + +static void unit_setup( void ) +{ + llist = Curl_llist_alloc( test_curl_llist_dtor ); +} + +static void unit_stop( void ) +{ + Curl_llist_destroy( llist, NULL ); +} + +UNITTEST_START + + fail_unless( llist->size == 0 , "list initial size should be zero" ); + fail_unless( llist->head == NULL , "list head should initiate to NULL" ); + fail_unless( llist->tail == NULL , "list tail should intiate to NULL" ); + fail_unless( llist->dtor == test_curl_llist_dtor , "list dtor shold initiate to test_curl_llist_dtor" ); + +UNITTEST_STOP