bring back UCX test - fixes #341

Wed, 20 Dec 2023 16:46:14 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 20 Dec 2023 16:46:14 +0100
changeset 766
e59b76889f00
parent 765
b5128bb44459
child 767
d31f4d4075dc

bring back UCX test - fixes #341

Makefile file | annotate | diff | comparison | revisions
configure file | annotate | diff | comparison | revisions
make/project.xml file | annotate | diff | comparison | revisions
make/update-rules.sh file | annotate | diff | comparison | revisions
src/Makefile file | annotate | diff | comparison | revisions
src/cx/common.h file | annotate | diff | comparison | revisions
src/cx/test.h file | annotate | diff | comparison | revisions
tests/Makefile file | annotate | diff | comparison | revisions
tests/test_utils.c file | annotate | diff | comparison | revisions
tests/test_utils.h file | annotate | diff | comparison | revisions
tests/ucxtest.c file | annotate | diff | comparison | revisions
     1.1 --- a/Makefile	Mon Dec 18 18:54:17 2023 +0100
     1.2 +++ b/Makefile	Wed Dec 20 16:46:14 2023 +0100
     1.3 @@ -23,7 +23,7 @@
     1.4  
     1.5  include config.mk
     1.6  
     1.7 -all: compile
     1.8 +all: compile test-compile
     1.9  
    1.10  install:
    1.11  	@cd src && $(MAKE) install
    1.12 @@ -57,11 +57,10 @@
    1.13  	@cd src && $(MAKE) static
    1.14  
    1.15  check: test-compile FORCE
    1.16 -	test "$(WITH_TESTS)" = "yes" && $(build_dir)/tests/ucxtest
    1.17 +	$(build_dir)/tests/ucxtest
    1.18  
    1.19  test-compile:
    1.20 -	@(test "$(WITH_TESTS)" = "yes" && cd tests && $(MAKE)) \
    1.21 -		|| echo "[ Tests disabled - skipped ]"
    1.22 +	cd tests && $(MAKE)
    1.23  
    1.24  docs: FORCE
    1.25  	@(test "$(WITH_DOCS_API)" = "yes" && cd docs && $(MAKE) all-api) \
    1.26 @@ -71,5 +70,6 @@
    1.27  
    1.28  update-rules:
    1.29  	make/update-rules.sh src
    1.30 +	CFLAGS='$(CFLAGS) -I../src' make/update-rules.sh tests '$$(TEST_DIR)'
    1.31  
    1.32  FORCE:
     2.1 --- a/configure	Mon Dec 18 18:54:17 2023 +0100
     2.2 +++ b/configure	Wed Dec 20 16:46:14 2023 +0100
     2.3 @@ -36,7 +36,6 @@
     2.4  src_dir=`pwd`
     2.5  DOXYGEN=`command -v doxygen`
     2.6  PANDOC=`command -v pandoc`
     2.7 -CMAKE=`command -v cmake`
     2.8  
     2.9  # features
    2.10  
    2.11 @@ -76,7 +75,6 @@
    2.12  Options:
    2.13    --debug                 add extra compile flags for debug builds
    2.14    --release               add extra compile flags for release builds
    2.15 -  --with-tests=(yes|no)
    2.16    --with-docs=(all|html|api|none)
    2.17  
    2.18  __EOF__
    2.19 @@ -107,7 +105,6 @@
    2.20          "--help"*) printhelp; abort_configure ;;
    2.21          "--debug")           BUILD_TYPE="debug" ;;
    2.22          "--release")         BUILD_TYPE="release" ;;
    2.23 -        "--with-tests="*) OPT_WITH_TESTS=${ARG#--with-tests=} ;;
    2.24          "--with-docs="*) OPT_WITH_DOCS=${ARG#--with-docs=} ;;
    2.25          "-"*) echo "unknown option: $ARG"; abort_configure ;;
    2.26      esac
    2.27 @@ -222,7 +219,6 @@
    2.28  src_dir="$src_dir"
    2.29  DOXYGEN="$DOXYGEN"
    2.30  PANDOC="$PANDOC"
    2.31 -CMAKE="$CMAKE"
    2.32  __EOF__
    2.33  
    2.34  # toolchain detection utilities
    2.35 @@ -235,9 +231,6 @@
    2.36  # check languages
    2.37  lang_c=
    2.38  lang_cpp=
    2.39 -if detect_cpp_compiler ; then
    2.40 -    lang_cpp=1
    2.41 -fi
    2.42  if detect_c_compiler ; then
    2.43      lang_c=1
    2.44  fi
    2.45 @@ -276,22 +269,6 @@
    2.46      echo no
    2.47      return 0
    2.48  }
    2.49 -dependency_error_cpp()
    2.50 -{
    2.51 -    printf "checking for cpp... "
    2.52 -    # dependency cpp
    2.53 -    while true
    2.54 -    do
    2.55 -        if [ -z "$lang_cpp" ] ; then
    2.56 -            break
    2.57 -        fi
    2.58 -        echo yes
    2.59 -        return 1
    2.60 -    done
    2.61 -
    2.62 -    echo no
    2.63 -    return 0
    2.64 -}
    2.65  dependency_error_c()
    2.66  {
    2.67      printf "checking for c... "
    2.68 @@ -384,24 +361,6 @@
    2.69      echo no
    2.70      return 0
    2.71  }
    2.72 -dependency_error_cmake()
    2.73 -{
    2.74 -    printf "checking for cmake... "
    2.75 -    # dependency cmake
    2.76 -    while true
    2.77 -    do
    2.78 -        if test -n "$CMAKE" > /dev/null ; then
    2.79 -            :
    2.80 -        else
    2.81 -            break
    2.82 -        fi
    2.83 -        echo yes
    2.84 -        return 1
    2.85 -    done
    2.86 -
    2.87 -    echo no
    2.88 -    return 0
    2.89 -}
    2.90  dependency_error_doxygen()
    2.91  {
    2.92      printf "checking for doxygen... "
    2.93 @@ -470,32 +429,6 @@
    2.94  #
    2.95  # OPTION VALUES
    2.96  #
    2.97 -checkopt_with_tests_yes()
    2.98 -{
    2.99 -    VERR=0
   2.100 -    if dependency_error_cpp ; then
   2.101 -        VERR=1
   2.102 -    fi
   2.103 -    if dependency_error_cmake ; then
   2.104 -        VERR=1
   2.105 -    fi
   2.106 -    if [ $VERR -ne 0 ]; then
   2.107 -        return 1
   2.108 -    fi
   2.109 -    cat >> "$TEMP_DIR/make.mk" << __EOF__
   2.110 -WITH_TESTS=yes
   2.111 -
   2.112 -__EOF__
   2.113 -    return 0
   2.114 -}
   2.115 -checkopt_with_tests_no()
   2.116 -{
   2.117 -    VERR=0
   2.118 -    if [ $VERR -ne 0 ]; then
   2.119 -        return 1
   2.120 -    fi
   2.121 -    return 0
   2.122 -}
   2.123  checkopt_with_docs_all()
   2.124  {
   2.125      VERR=0
   2.126 @@ -579,54 +512,6 @@
   2.127  
   2.128  # Features
   2.129  
   2.130 -# Option: --with-tests
   2.131 -if [ -z "$OPT_WITH_TESTS" ]; then
   2.132 -    echo "auto-detecting option 'with-tests'"
   2.133 -    SAVED_ERROR="$ERROR"
   2.134 -    SAVED_DEPENDENCIES_FAILED="$DEPENDENCIES_FAILED"
   2.135 -    ERROR=1
   2.136 -    while true
   2.137 -    do
   2.138 -        if checkopt_with_tests_yes ; then
   2.139 -            echo "  with-tests: yes" >> "$TEMP_DIR/options"
   2.140 -            ERROR=0
   2.141 -            break
   2.142 -        fi
   2.143 -        if checkopt_with_tests_no ; then
   2.144 -            echo "  with-tests: no" >> "$TEMP_DIR/options"
   2.145 -            ERROR=0
   2.146 -            break
   2.147 -        fi
   2.148 -        break
   2.149 -    done
   2.150 -    if [ $ERROR -ne 0 ]; then
   2.151 -        SAVED_ERROR=1
   2.152 -        SAVED_DEPENDENCIES_FAILED="option 'with-tests' $SAVED_DEPENDENCIES_FAILED"
   2.153 -    fi
   2.154 -    ERROR="$SAVED_ERROR"
   2.155 -    DEPENDENCIES_FAILED="$SAVED_DEPENDENCIES_FAILED"
   2.156 -else
   2.157 -    echo "checking option with-tests = $OPT_WITH_TESTS"
   2.158 -    if false; then
   2.159 -        false
   2.160 -    elif [ "$OPT_WITH_TESTS" = "yes" ]; then
   2.161 -        echo "  with-tests: $OPT_WITH_TESTS" >> $TEMP_DIR/options
   2.162 -        if checkopt_with_tests_yes ; then
   2.163 -            :
   2.164 -        else
   2.165 -            ERROR=1
   2.166 -            DEPENDENCIES_FAILED="option 'with-tests' $DEPENDENCIES_FAILED"
   2.167 -        fi
   2.168 -    elif [ "$OPT_WITH_TESTS" = "no" ]; then
   2.169 -        echo "  with-tests: $OPT_WITH_TESTS" >> $TEMP_DIR/options
   2.170 -        if checkopt_with_tests_no ; then
   2.171 -            :
   2.172 -        else
   2.173 -            ERROR=1
   2.174 -            DEPENDENCIES_FAILED="option 'with-tests' $DEPENDENCIES_FAILED"
   2.175 -        fi
   2.176 -    fi
   2.177 -fi
   2.178  # Option: --with-docs
   2.179  if [ -z "$OPT_WITH_DOCS" ]; then
   2.180      echo "auto-detecting option 'with-docs'"
     3.1 --- a/make/project.xml	Mon Dec 18 18:54:17 2023 +0100
     3.2 +++ b/make/project.xml	Wed Dec 20 16:46:14 2023 +0100
     3.3 @@ -4,7 +4,6 @@
     3.4  		<var name="src_dir" exec="true">pwd</var>
     3.5  		<var name="DOXYGEN" exec="true">command -v doxygen</var>
     3.6  		<var name="PANDOC" exec="true">command -v pandoc</var>
     3.7 -		<var name="CMAKE" exec="true">command -v cmake</var>
     3.8  	</config>
     3.9  
    3.10  	<dependency>
    3.11 @@ -61,14 +60,6 @@
    3.12  SHLIB_EXT=.so
    3.13  		</make>
    3.14  	</dependency>
    3.15 -	
    3.16 -	<dependency name="cpp">
    3.17 -		<lang>cpp</lang>
    3.18 -	</dependency>
    3.19 -
    3.20 -	<dependency name="cmake">
    3.21 -		<test>test -n "$CMAKE"</test>
    3.22 -	</dependency>
    3.23  
    3.24  	<dependency name="doxygen">
    3.25  		<test>test -n "$DOXYGEN"</test>
    3.26 @@ -79,15 +70,6 @@
    3.27  	</dependency>
    3.28  	
    3.29  	<target>
    3.30 -		<option arg="with-tests">
    3.31 -			<value str="yes">
    3.32 -				<dependencies>cpp,cmake</dependencies>
    3.33 -				<make>WITH_TESTS=yes</make>
    3.34 -			</value>
    3.35 -			<value str="no"/>
    3.36 -			<default value="yes"/>
    3.37 -			<default value="no"/>
    3.38 -		</option>
    3.39  		<option arg="with-docs">
    3.40  			<value str="all">
    3.41  				<dependencies>pandoc,doxygen</dependencies>
     4.1 --- a/make/update-rules.sh	Mon Dec 18 18:54:17 2023 +0100
     4.2 +++ b/make/update-rules.sh	Wed Dec 20 16:46:14 2023 +0100
     4.3 @@ -1,12 +1,17 @@
     4.4  #!/bin/sh
     4.5  
     4.6  dir="$1"
     4.7 +target="$2"
     4.8  
     4.9  if [ -z "$dir" ]; then
    4.10    echo "Usage: $0 <src_dir>"
    4.11    exit 1
    4.12  fi
    4.13  
    4.14 +if [ -z "$target" ]; then
    4.15 +  target='$(build_dir)'
    4.16 +fi
    4.17 +
    4.18  if [ -d "$dir" ]; then
    4.19    :
    4.20  else
    4.21 @@ -41,7 +46,7 @@
    4.22  sed '/FORCE:/q' Makefile.old > Makefile
    4.23  echo >> Makefile
    4.24  for file in `ls *.c` ; do
    4.25 -  "$CC" -MT "\$(build_dir)/${file/.c/\$(OBJ_EXT)}" -MM $CFLAGS "$file"
    4.26 +  "$CC" -MT "$target/${file/.c/\$(OBJ_EXT)}" -MM $CFLAGS "$file"
    4.27    printf '\t@echo "Compiling $<"\n'
    4.28    printf '\t$(CC) -o $@ $(CFLAGS) -c $<\n\n'
    4.29  done  >> Makefile
     5.1 --- a/src/Makefile	Mon Dec 18 18:54:17 2023 +0100
     5.2 +++ b/src/Makefile	Wed Dec 20 16:46:14 2023 +0100
     5.3 @@ -56,7 +56,7 @@
     5.4  	$(CC) -o $@ $(CFLAGS) -c $<
     5.5  
     5.6  $(build_dir)/array_list$(OBJ_EXT): array_list.c cx/array_list.h cx/list.h \
     5.7 - cx/common.h cx/collection.h cx/allocator.h cx/iterator.h
     5.8 + cx/common.h cx/collection.h cx/allocator.h cx/iterator.h cx/compare.h
     5.9  	@echo "Compiling $<"
    5.10  	$(CC) -o $@ $(CFLAGS) -c $<
    5.11  
    5.12 @@ -81,7 +81,7 @@
    5.13  
    5.14  $(build_dir)/linked_list$(OBJ_EXT): linked_list.c cx/linked_list.h \
    5.15   cx/common.h cx/list.h cx/collection.h cx/allocator.h cx/iterator.h \
    5.16 - cx/utils.h
    5.17 + cx/utils.h cx/compare.h
    5.18  	@echo "Compiling $<"
    5.19  	$(CC) -o $@ $(CFLAGS) -c $<
    5.20  
     6.1 --- a/src/cx/common.h	Mon Dec 18 18:54:17 2023 +0100
     6.2 +++ b/src/cx/common.h	Wed Dec 20 16:46:14 2023 +0100
     6.3 @@ -96,6 +96,7 @@
     6.4  #include <stdint.h>
     6.5  #include <sys/types.h>
     6.6  
     6.7 +#ifndef UCX_TEST_H
     6.8  /**
     6.9   * Function pointer compatible with fwrite-like functions.
    6.10   */
    6.11 @@ -105,6 +106,7 @@
    6.12          size_t,
    6.13          void *
    6.14  );
    6.15 +#endif // UCX_TEST_H
    6.16  
    6.17  /**
    6.18   * Function pointer compatible with fread-like functions.
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/src/cx/test.h	Wed Dec 20 16:46:14 2023 +0100
     7.3 @@ -0,0 +1,326 @@
     7.4 +/*
     7.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     7.6 + *
     7.7 + * Copyright 2017 Mike Becker, Olaf Wintermann All rights reserved.
     7.8 + *
     7.9 + * Redistribution and use in source and binary forms, with or without
    7.10 + * modification, are permitted provided that the following conditions are met:
    7.11 + *
    7.12 + *   1. Redistributions of source code must retain the above copyright
    7.13 + *      notice, this list of conditions and the following disclaimer.
    7.14 + *
    7.15 + *   2. Redistributions in binary form must reproduce the above copyright
    7.16 + *      notice, this list of conditions and the following disclaimer in the
    7.17 + *      documentation and/or other materials provided with the distribution.
    7.18 + *
    7.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    7.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    7.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    7.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    7.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    7.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    7.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    7.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    7.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    7.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    7.29 + * POSSIBILITY OF SUCH DAMAGE.
    7.30 + */
    7.31 + 
    7.32 +/**
    7.33 + * @file: test.h
    7.34 + * 
    7.35 + * UCX Test Framework.
    7.36 + * 
    7.37 + * Usage of this test framework:
    7.38 + *
    7.39 + * **** IN HEADER FILE: ****
    7.40 + *
    7.41 + * <pre>
    7.42 + * CX_TEST(function_name);
    7.43 + * CX_TEST_SUBROUTINE(subroutine_name, paramlist); // optional
    7.44 + * </pre>
    7.45 + *
    7.46 + * **** IN SOURCE FILE: ****
    7.47 + * <pre>
    7.48 + * CX_TEST_SUBROUTINE(subroutine_name, paramlist) {
    7.49 + *   // tests with CX_TEST_ASSERT()
    7.50 + * }
    7.51 + * 
    7.52 + * CX_TEST(function_name) {
    7.53 + *   // memory allocation and other stuff here
    7.54 + *   #CX_TEST_BEGIN
    7.55 + *   // tests with CX_TEST_ASSERT() and/or
    7.56 + *   // calls with CX_TEST_CALL_SUBROUTINE() here
    7.57 + *   #CX_TEST_END
    7.58 + *   // cleanup of memory here
    7.59 + * }
    7.60 + * </pre>
    7.61 + *
    7.62 + * @remark if a test fails, execution continues at the
    7.63 + * #CX_TEST_END macro! So make sure every necessary cleanup happens afterwards.
    7.64 + * 
    7.65 + * @attention Do not call own functions within a test, that use
    7.66 + * CX_TEST_ASSERT() macros and are not defined by using CX_TEST_SUBROUTINE().
    7.67 + *
    7.68 + * @author Mike Becker
    7.69 + * @author Olaf Wintermann
    7.70 + *
    7.71 + */
    7.72 +
    7.73 +#ifndef UCX_TEST_H
    7.74 +#define	UCX_TEST_H
    7.75 +
    7.76 +#include <stdlib.h>
    7.77 +#include <stdio.h>
    7.78 +#include <string.h>
    7.79 +#include <setjmp.h>
    7.80 +
    7.81 +#ifdef	__cplusplus
    7.82 +extern "C" {
    7.83 +#endif
    7.84 +
    7.85 +#ifndef __FUNCTION__
    7.86 +/**
    7.87 + * Alias for the <code>__func__</code> preprocessor macro.
    7.88 + * Some compilers use <code>__func__</code> and others use __FUNCTION__.
    7.89 + * We use __FUNCTION__ so we define it for those compilers which use
    7.90 + * <code>__func__</code>.
    7.91 + */
    7.92 +#define __FUNCTION__ __func__
    7.93 +#endif
    7.94 +
    7.95 +#ifndef UCX_COMMON_H
    7.96 +/**
    7.97 + * Function pointer compatible with fwrite-like functions.
    7.98 + */
    7.99 +typedef size_t (*cx_write_func)(
   7.100 +        void const *,
   7.101 +        size_t,
   7.102 +        size_t,
   7.103 +        void *
   7.104 +);
   7.105 +#endif // UCX_COMMON_H
   7.106 +
   7.107 +/** Type for the CxTestSuite. */
   7.108 +typedef struct CxTestSuite CxTestSuite;
   7.109 +
   7.110 +/** Pointer to a test function. */
   7.111 +typedef void(*CxTest)(CxTestSuite *, void *, cx_write_func);
   7.112 +
   7.113 +/** Type for the internal list of test cases. */
   7.114 +typedef struct CxTestSet CxTestSet;
   7.115 +
   7.116 +/** Structure for the internal list of test cases. */
   7.117 +struct CxTestSet {
   7.118 +    
   7.119 +    /** Test case. */
   7.120 +    CxTest test;
   7.121 +    
   7.122 +    /** Pointer to the next list element. */
   7.123 +    CxTestSet *next;
   7.124 +};
   7.125 +
   7.126 +/**
   7.127 + * A test suite containing multiple test cases.
   7.128 + */
   7.129 +struct CxTestSuite {
   7.130 +    
   7.131 +    /** The number of successful tests after the suite has been run. */
   7.132 +    unsigned int success;
   7.133 +    
   7.134 +    /** The number of failed tests after the suite has been run. */
   7.135 +    unsigned int failure;
   7.136 +
   7.137 +    /** The optional name of this test suite. */
   7.138 +    char const *name;
   7.139 +    
   7.140 +    /**
   7.141 +     * Internal list of test cases.
   7.142 +     * Use cx_test_register() to add tests to this list.
   7.143 +     */
   7.144 +    CxTestSet *tests;
   7.145 +};
   7.146 +
   7.147 +/**
   7.148 + * Creates a new test suite.
   7.149 + * @param name optional name of the suite
   7.150 + * @return a new test suite
   7.151 + */
   7.152 +static inline CxTestSuite* cx_test_suite_new(char const *name) {
   7.153 +    CxTestSuite* suite = (CxTestSuite*) malloc(sizeof(CxTestSuite));
   7.154 +    if (suite != NULL) {
   7.155 +        suite->name = name;
   7.156 +        suite->success = 0;
   7.157 +        suite->failure = 0;
   7.158 +        suite->tests = NULL;
   7.159 +    }
   7.160 +
   7.161 +    return suite;
   7.162 +}
   7.163 +
   7.164 +/**
   7.165 + * Destroys a test suite.
   7.166 + * @param suite the test suite to destroy
   7.167 + */
   7.168 +static inline void cx_test_suite_free(CxTestSuite* suite) {
   7.169 +    CxTestSet *l = suite->tests;
   7.170 +    while (l != NULL) {
   7.171 +        CxTestSet *e = l;
   7.172 +        l = l->next;
   7.173 +        free(e);
   7.174 +    }
   7.175 +    free(suite);
   7.176 +}
   7.177 +
   7.178 +/**
   7.179 + * Registers a test function with the specified test suite.
   7.180 + * 
   7.181 + * @param suite the suite, the test function shall be added to
   7.182 + * @param test the test function to register
   7.183 + * @return zero on success or non-zero on failure
   7.184 + */
   7.185 +static inline int cx_test_register(CxTestSuite* suite, CxTest test) {
   7.186 +    CxTestSet *t = (CxTestSet*) malloc(sizeof(CxTestSet));
   7.187 +    if (t) {
   7.188 +        t->test = test;
   7.189 +        t->next = NULL;
   7.190 +        if (suite->tests == NULL) {
   7.191 +            suite->tests = t;
   7.192 +        } else {
   7.193 +            CxTestSet *last = suite->tests;
   7.194 +            while (last->next) {
   7.195 +                last = last->next;
   7.196 +            }
   7.197 +            last->next = t;
   7.198 +        }
   7.199 +        return 0;
   7.200 +    } else {
   7.201 +        return 1;
   7.202 +    }
   7.203 +}
   7.204 +
   7.205 +/**
   7.206 + * Runs a test suite and writes the test log to the specified stream.
   7.207 + * @param suite the test suite to run
   7.208 + * @param out_target the target buffer or file to write the output to
   7.209 + * @param out_writer the write function writing to \p out_target
   7.210 + */
   7.211 +static inline void cx_test_run(CxTestSuite *suite,
   7.212 +                               void *out_target, cx_write_func out_writer) {
   7.213 +    if (suite->name == NULL) {
   7.214 +        out_writer("*** Test Suite ***\n", 1, 19, out_target);
   7.215 +    } else {
   7.216 +        out_writer("*** Test Suite : ", 1, 17, out_target);
   7.217 +        out_writer(suite->name, 1, strlen(suite->name), out_target);
   7.218 +        out_writer(" ***\n", 1, 5, out_target);
   7.219 +    }
   7.220 +    suite->success = 0;
   7.221 +    suite->failure = 0;
   7.222 +    for (CxTestSet *elem = suite->tests; elem; elem = elem->next) {
   7.223 +        elem->test(suite, out_target, out_writer);
   7.224 +    }
   7.225 +    out_writer("\nAll test completed.\n", 1, 21, out_target);
   7.226 +    char total[80];
   7.227 +    int len = snprintf(
   7.228 +            total, 80,
   7.229 +            "  Total:   %u\n  Success: %u\n  Failure: %u\n",
   7.230 +            suite->success + suite->failure, suite->success, suite->failure
   7.231 +    );
   7.232 +    out_writer(total, 1, len, out_target);
   7.233 +}
   7.234 +
   7.235 +/**
   7.236 + * Runs a test suite and writes the test log to the specified FILE stream.
   7.237 + * @param suite the test suite to run
   7.238 + * @param file the target file to write the output to
   7.239 + */
   7.240 +#define cx_test_run_f(suite, file) cx_test_run(suite, (void*)file, (cx_write_func)fwrite)
   7.241 +
   7.242 +/**
   7.243 + * Runs a test suite and writes the test log to stdout.
   7.244 + * @param suite the test suite to run
   7.245 + */
   7.246 +#define cx_test_run_stdout(suite) cx_test_run_f(suite, stdout)
   7.247 +
   7.248 +/**
   7.249 + * Macro for a #CxTest function header.
   7.250 + * 
   7.251 + * Use this macro to declare and/or define a #CxTest function.
   7.252 + * 
   7.253 + * @param name the name of the test function
   7.254 + */
   7.255 +#define CX_TEST(name) void name(CxTestSuite* _suite_,void *_output_, cx_write_func _writefnc_)
   7.256 +
   7.257 +/**
   7.258 + * Marks the begin of a test.
   7.259 + * <b>Note:</b> Any CX_TEST_ASSERT() calls must be performed <b>after</b>
   7.260 + * #CX_TEST_BEGIN.
   7.261 + * 
   7.262 + * @see #CX_TEST_END
   7.263 + */
   7.264 +#define CX_TEST_BEGIN _writefnc_("Running ", 1, 8, _output_);\
   7.265 +        _writefnc_(__FUNCTION__, 1, strlen(__FUNCTION__), _output_);\
   7.266 +        _writefnc_("... ", 1, 4, _output_);\
   7.267 +        jmp_buf _env_; \
   7.268 +        if (!setjmp(_env_)) {
   7.269 +
   7.270 +/**
   7.271 + * Checks a test assertion.
   7.272 + * If the assertion is correct, the test carries on. If the assertion is not
   7.273 + * correct, the specified message (terminated by a dot and a line break) is
   7.274 + * written to the test suites output stream.
   7.275 + * @param condition the condition to check
   7.276 + * @param message the message that shall be printed out on failure
   7.277 + */
   7.278 +#define CX_TEST_ASSERT(condition,message) if (!(condition)) { \
   7.279 +        _writefnc_(message".\n", 1, 2+strlen(message), _output_); \
   7.280 +        _suite_->failure++; \
   7.281 +        longjmp(_env_, 1);\
   7.282 +    }
   7.283 +
   7.284 +/**
   7.285 + * Macro for a test subroutine function header.
   7.286 + * 
   7.287 + * Use this to declare and/or define a subroutine that can be called by using
   7.288 + * CX_TEST_CALL_SUBROUTINE().
   7.289 + * 
   7.290 + * @param name the name of the subroutine
   7.291 + * @param ... the parameter list
   7.292 + * 
   7.293 + * @see CX_TEST_CALL_SUBROUTINE()
   7.294 + */
   7.295 +#define CX_TEST_SUBROUTINE(name,...) void name(CxTestSuite* _suite_,\
   7.296 +        void *_output_, jmp_buf _env_, __VA_ARGS__)
   7.297 +
   7.298 +/**
   7.299 + * Macro for calling a test subroutine.
   7.300 + * 
   7.301 + * Subroutines declared with CX_TEST_SUBROUTINE() can be called by using this
   7.302 + * macro.
   7.303 + * 
   7.304 + * <b>Note:</b> You may <b>only</b> call subroutines within a #CX_TEST_BEGIN-
   7.305 + * #CX_TEST_END-block.
   7.306 + * 
   7.307 + * @param name the name of the subroutine
   7.308 + * @param ... the argument list
   7.309 + * 
   7.310 + * @see CX_TEST_SUBROUTINE()
   7.311 + */
   7.312 +#define CX_TEST_CALL_SUBROUTINE(name,...) \
   7.313 +        name(_suite_,_output_,_writefnc_,_env_,__VA_ARGS__);
   7.314 +
   7.315 +/**
   7.316 + * Marks the end of a test.
   7.317 + * <b>Note:</b> Any CX_TEST_ASSERT() calls must be performed <b>before</b>
   7.318 + * #CX_TEST_END.
   7.319 + * 
   7.320 + * @see #CX_TEST_BEGIN
   7.321 + */
   7.322 +#define CX_TEST_END _writefnc_("success.\n", 1, 9, _output_); _suite_->success++;}
   7.323 +
   7.324 +#ifdef	__cplusplus
   7.325 +}
   7.326 +#endif
   7.327 +
   7.328 +#endif	/* UCX_TEST_H */
   7.329 +
     8.1 --- a/tests/Makefile	Mon Dec 18 18:54:17 2023 +0100
     8.2 +++ b/tests/Makefile	Wed Dec 20 16:46:14 2023 +0100
     8.3 @@ -23,13 +23,42 @@
     8.4  
     8.5  include ../config.mk
     8.6  
     8.7 +CFLAGS += -I../src
     8.8 +
     8.9  TEST_DIR=$(build_dir)/tests
    8.10  
    8.11 -all: $(TEST_DIR) $(build_dir)/libucx_static.a
    8.12 -	cd $(TEST_DIR) && $(CMAKE) -DSTLIB_EXT="$(STLIB_EXT)" "$(src_dir)/tests" && $(CMAKE) --build .
    8.13 -	@echo "[ Tests complete ]"
    8.14 +SRC = test_utils.c ucxtest.o
    8.15  
    8.16 -# do not define libucx.a target - if it wasn't build, we simply fail!
    8.17 +OBJ_EXT=.o
    8.18 +OBJ=$(SRC:%.c=$(TEST_DIR)/%$(OBJ_EXT))
    8.19 +
    8.20 +all: $(TEST_DIR) $(TEST_DIR)/ucxtest
    8.21 +
    8.22 +$(TEST_DIR)/ucxtest: $(build_dir)/libucx_static.a $(OBJ)
    8.23 +	$(CC) -o $@ $+
    8.24 +
    8.25 +$(build_dir)/libucx_static.a:
    8.26 +	test -f "$@"
    8.27  
    8.28  $(TEST_DIR):
    8.29 -	$(MKDIR) $@
    8.30 \ No newline at end of file
    8.31 +	$(MKDIR) $@
    8.32 +
    8.33 +FORCE:
    8.34 +
    8.35 +$(TEST_DIR)/test_map_generics$(OBJ_EXT): test_map_generics.c \
    8.36 + test_map_generics.h ../src/cx/map.h ../src/cx/common.h \
    8.37 + ../src/cx/collection.h ../src/cx/allocator.h ../src/cx/iterator.h \
    8.38 + ../src/cx/string.h ../src/cx/hash_key.h ../src/cx/hash_map.h \
    8.39 + ../src/cx/map.h
    8.40 +	@echo "Compiling $<"
    8.41 +	$(CC) -o $@ $(CFLAGS) -c $<
    8.42 +
    8.43 +$(TEST_DIR)/test_utils$(OBJ_EXT): test_utils.c test_utils.h \
    8.44 + ../src/cx/test.h
    8.45 +	@echo "Compiling $<"
    8.46 +	$(CC) -o $@ $(CFLAGS) -c $<
    8.47 +
    8.48 +$(TEST_DIR)/ucxtest$(OBJ_EXT): ucxtest.c test_utils.h ../src/cx/test.h
    8.49 +	@echo "Compiling $<"
    8.50 +	$(CC) -o $@ $(CFLAGS) -c $<
    8.51 +
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/tests/test_utils.c	Wed Dec 20 16:46:14 2023 +0100
     9.3 @@ -0,0 +1,37 @@
     9.4 +/*
     9.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
     9.6 + *
     9.7 + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
     9.8 + *
     9.9 + * Redistribution and use in source and binary forms, with or without
    9.10 + * modification, are permitted provided that the following conditions are met:
    9.11 + *
    9.12 + *   1. Redistributions of source code must retain the above copyright
    9.13 + *      notice, this list of conditions and the following disclaimer.
    9.14 + *
    9.15 + *   2. Redistributions in binary form must reproduce the above copyright
    9.16 + *      notice, this list of conditions and the following disclaimer in the
    9.17 + *      documentation and/or other materials provided with the distribution.
    9.18 + *
    9.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
    9.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    9.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    9.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    9.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    9.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    9.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    9.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    9.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    9.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    9.29 + * POSSIBILITY OF SUCH DAMAGE.
    9.30 + */
    9.31 +
    9.32 +#include "test_utils.h"
    9.33 +
    9.34 +CxTestSuite *cx_test_suite_utils(void) {
    9.35 +    CxTestSuite *suite = cx_test_suite_new("utils");
    9.36 +
    9.37 +    return suite;
    9.38 +}
    9.39 +
    9.40 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/tests/test_utils.h	Wed Dec 20 16:46:14 2023 +0100
    10.3 @@ -0,0 +1,46 @@
    10.4 +/*
    10.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    10.6 + *
    10.7 + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
    10.8 + *
    10.9 + * Redistribution and use in source and binary forms, with or without
   10.10 + * modification, are permitted provided that the following conditions are met:
   10.11 + *
   10.12 + *   1. Redistributions of source code must retain the above copyright
   10.13 + *      notice, this list of conditions and the following disclaimer.
   10.14 + *
   10.15 + *   2. Redistributions in binary form must reproduce the above copyright
   10.16 + *      notice, this list of conditions and the following disclaimer in the
   10.17 + *      documentation and/or other materials provided with the distribution.
   10.18 + *
   10.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   10.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   10.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   10.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   10.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   10.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   10.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   10.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   10.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   10.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   10.29 + * POSSIBILITY OF SUCH DAMAGE.
   10.30 + */
   10.31 +
   10.32 +#ifndef UCX_TEST_SUITE_UTILS_H
   10.33 +#define UCX_TEST_SUITE_UTILS_H
   10.34 +
   10.35 +#include "cx/test.h"
   10.36 +
   10.37 +#ifdef __cplusplus
   10.38 +extern "C" {
   10.39 +#endif
   10.40 +
   10.41 +
   10.42 +CxTestSuite *cx_test_suite_utils(void);
   10.43 +
   10.44 +
   10.45 +#ifdef __cplusplus
   10.46 +} // extern "C"
   10.47 +#endif
   10.48 +
   10.49 +#endif // UCX_TEST_SUITE_UTILS_H
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/tests/ucxtest.c	Wed Dec 20 16:46:14 2023 +0100
    11.3 @@ -0,0 +1,54 @@
    11.4 +/*
    11.5 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
    11.6 + *
    11.7 + * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
    11.8 + *
    11.9 + * Redistribution and use in source and binary forms, with or without
   11.10 + * modification, are permitted provided that the following conditions are met:
   11.11 + *
   11.12 + *   1. Redistributions of source code must retain the above copyright
   11.13 + *      notice, this list of conditions and the following disclaimer.
   11.14 + *
   11.15 + *   2. Redistributions in binary form must reproduce the above copyright
   11.16 + *      notice, this list of conditions and the following disclaimer in the
   11.17 + *      documentation and/or other materials provided with the distribution.
   11.18 + *
   11.19 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
   11.20 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   11.21 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   11.22 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
   11.23 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   11.24 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   11.25 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   11.26 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   11.27 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   11.28 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   11.29 + * POSSIBILITY OF SUCH DAMAGE.
   11.30 + */
   11.31 +
   11.32 +#include "test_utils.h"
   11.33 +
   11.34 +#define run_tests(suite) cx_test_run_stdout(suite); success += (suite)->success; failure += (suite)->failure
   11.35 +
   11.36 +int main(void) {
   11.37 +    printf("UCX Tests\n---------\n");
   11.38 +
   11.39 +    unsigned success = 0, failure = 0;
   11.40 +
   11.41 +    // create test suites
   11.42 +    CxTestSuite
   11.43 +    *utils = cx_test_suite_utils();
   11.44 +
   11.45 +    // run tests
   11.46 +    run_tests(utils);
   11.47 +
   11.48 +    // print overall result
   11.49 +    printf("\n\n*** OVERALL RESULT ***\n");
   11.50 +    printf("  Total:   %u\n  Success: %u\n  Failure: %u\n",
   11.51 +           success + failure, success, failure);
   11.52 +
   11.53 +    cx_test_suite_free(utils);
   11.54 +
   11.55 +    return failure > 0 ? 1 : 0;
   11.56 +}
   11.57 +

mercurial