On Sun, 2 Jan 2011, Kamil Dudka wrote:

Or maybe just force the unit tests link against the static libcurl library. That should be enough to make it work.

I am afraid this clashes with --disable-static, hence defeats any unit testing in our Fedora builds.

I spent a few minutes on this problem. I don't have any really good alternatives to using a static library for it. Trying to use object files directly will fail miserably due to all cross-dependencies.

Another problem struck me that is related: what about functions that are declared 'static' in the code? Shouldn't we be able to write unit tests for such functions as well? To make that possible we just might need to have special unit-test builds that don't have those functions static. Or can anyone think of other clever ways to do it?

I'm attaching my revised version of my patch that now has the unit tests in a new dedicated directory (tests/unit/). If nobody has any strong objections, I'll start off with pushing this within shortly and then we can work on things further from there.

--

 / daniel.haxx.se
From 09b6000cfe00f25a61c2dbd8129fe92b62e82a4e Mon Sep 17 00:00:00 2001
From: Daniel Stenberg <[email protected]>
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 1dab90e..92adc50 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2010, Daniel Stenberg, <[email protected]>, et al.
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, 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 78450b1..decc2d8 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -5,7 +5,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2010, Daniel Stenberg, <[email protected]>, et al.
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, 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 d4fa32a..c7a1b46 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 0000000..8bbbecd
--- /dev/null
+++ b/tests/data/test1300
@@ -0,0 +1,30 @@
+<testcase>
+<info>
+<keywords>
+unittest
+</keywords>
+</info>
+
+#
+# Client-side
+<client>
+<server>
+none
+</server>
+ <name>
+llist unit tests
+ </name>
+<tool>
+unit1300
+</tool>
+<command>
+unit1300
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+
+</verify>
+</testcase>
diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc
index a0f1c0e..2354ecc 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 a0e713f..53b372b 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 75f441b..86bba84 100755
--- a/tests/runtests.pl
+++ b/tests/runtests.pl
@@ -6,7 +6,7 @@
 #                            | (__| |_| |  _ <| |___
 #                             \___|\___/|_| \_\_____|
 #
-# Copyright (C) 1998 - 2010, Daniel Stenberg, <[email protected]>, et al.
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, 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 0000000..6979228
--- /dev/null
+++ b/tests/unit/Makefile.am
@@ -0,0 +1,68 @@
+#***************************************************************************
+#                                  _   _ ____  _
+#  Project                     ___| | | |  _ \| |
+#                             / __| | | | |_) | |
+#                            | (__| |_| |  _ <| |___
+#                             \___|\___/|_| \_\_____|
+#
+# Copyright (C) 1998 - 2011, Daniel Stenberg, <[email protected]>, 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 0000000..07d1318
--- /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 0000000..c34f990
--- /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 0000000..92c0a7a
--- /dev/null
+++ b/tests/unit/unit1300.c
@@ -0,0 +1,34 @@
+#include <stdlib.h>
+#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
-- 
1.7.2.3

-------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette:  http://curl.haxx.se/mail/etiquette.html

Reply via email to