Use ctest.h for unit test. Enable unit test on travis CI.
authorZhang Xianyi <traits.zhang@gmail.com>
Fri, 29 Jan 2016 03:35:31 +0000 (11:35 +0800)
committerZhang Xianyi <traits.zhang@gmail.com>
Fri, 29 Jan 2016 03:35:31 +0000 (11:35 +0800)
.travis.yml
Makefile
utest/Makefile
utest/ctest.h [new file with mode: 0644]
utest/main.c [deleted file]
utest/openblas_utest.h [moved from utest/common_utest.h with 70% similarity]
utest/test_amax.c
utest/utest_main.c [new file with mode: 0644]

index c36ed94..990bed8 100644 (file)
@@ -28,6 +28,7 @@ script:
  - make QUIET_MAKE=1 DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE
  - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C test DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi
  - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C ctest DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi
+ - if [ "$TARGET_BOX" == "LINUX32" ] || [ "$TARGET_BOX" == "LINUX64" ]; then make -C utest DYNAMIC_ARCH=1 TARGET=NEHALEM NUM_THREADS=32 $BTYPE; fi
 
 # whitelist
 branches:
index 4282627..945641f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,10 +7,6 @@ ifneq ($(DYNAMIC_ARCH), 1)
 BLASDIRS += kernel
 endif
 
-ifdef UTEST_CHECK
-SANITY_CHECK = 1
-endif
-
 ifdef SANITY_CHECK
 BLASDIRS += reference
 endif
index fa05458..1d0edb6 100644 (file)
@@ -6,51 +6,21 @@ TARGET=openblas_utest
 .PHONY : all
 .NOTPARALLEL : all run_test $(TARGET)
 
-CUNIT_URL=http://downloads.sourceforge.net/project/cunit/CUnit/2.1-2/CUnit-2.1-2-src.tar.bz2
-CUNIT_DIR=$(CURDIR)/CUnit-2.1-2
-
-CUNIT_LIB=$(CUNIT_DIR)/lib/libcunit.a
-
-CFLAGS +=-I$(CUNIT_DIR)/include
-
 include $(TOPDIR)/Makefile.system
 
-OBJS=main.o test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_amax.o test_fork.o
+OBJS=utest_main.o test_amax.o
+#test_rot.o test_swap.o test_axpy.o test_dotu.o test_rotmg.o test_dsdot.o test_fork.o
 
 all : run_test
 
-CUnit-2.1-2-src.tar.bz2:
-ifeq ($(OSNAME), Darwin)
-       curl -O $(CUNIT_URL)
-else
-       wget $(CUNIT_URL)
-endif
-
-$(CUNIT_DIR): CUnit-2.1-2-src.tar.bz2
-       @if test `$(MD5SUM) CUnit-2.1-2-src.tar.bz2 | $(AWK) '{print $$1}'` = 31c62bd7a65007737ba28b7aafc44d3a; then \
-               echo $(TAR) xjf $< ;\
-               $(TAR) xjf $< ; \
-       else \
-               rm -rf $(CUNIT_DIR) ;\
-               echo "  Cannot download CUnit-2.1-2-src.tar.bz2 or the MD5 check sum is wrong (Please use orignal)."; \
-               exit 1; \
-       fi
-
-
-$(CUNIT_LIB): $(CUNIT_DIR)
-       (cd $(CUNIT_DIR); CC=$(CC) CFLAGS="$(CFLAGS)" ./configure --prefix=$(CUNIT_DIR))
-       $(MAKE) -C $(CUNIT_DIR)
-       $(MAKE) -C $(CUNIT_DIR) install
-
-$(TARGET): $(CUNIT_LIB) $(OBJS)
-       $(CC) $(CFLAGS) -o $@ $^ ../$(LIBNAME) $(CUNIT_LIB) $(EXTRALIB)
+$(TARGET): $(OBJS)
+       $(CC) $(CFLAGS) -o $@ $^ ../$(LIBNAME) $(EXTRALIB)
 
 run_test: $(TARGET)
        ./$(TARGET)
 
 clean:
        -rm -f *.o $(TARGET)
-       -rm -rf $(CUNIT_DIR)
 
 libs:
 
diff --git a/utest/ctest.h b/utest/ctest.h
new file mode 100644 (file)
index 0000000..89c7ac9
--- /dev/null
@@ -0,0 +1,523 @@
+/* Copyright 2011-2015 Bas van den Berg
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CTEST_H
+#define CTEST_H
+
+#if defined _WIN32 || defined __CYGWIN__
+#ifndef WIN32
+#define WIN32
+#endif
+#endif
+
+#ifndef WIN32
+#define WEAK __attribute__ ((weak))
+#else
+#define WEAK
+#endif
+
+#include <inttypes.h> /* intmax_t, uintmax_t, PRI* */
+#include <stddef.h> /* size_t */
+
+typedef void (*SetupFunc)(void*);
+typedef void (*TearDownFunc)(void*);
+
+struct ctest {
+    const char* ssname;  // suite name
+    const char* ttname;  // test name
+    void (*run)();
+    int skip;
+
+    void* data;
+    SetupFunc setup;
+    TearDownFunc teardown;
+
+    unsigned int magic;
+};
+
+#define __FNAME(sname, tname) __ctest_##sname##_##tname##_run
+#define __TNAME(sname, tname) __ctest_##sname##_##tname
+
+#define __CTEST_MAGIC (0xdeadbeef)
+#ifdef __APPLE__
+#define __Test_Section __attribute__ ((used, section ("__DATA, .ctest")))
+#else
+#define __Test_Section __attribute__ ((used, section (".ctest")))
+#endif
+
+#define __CTEST_STRUCT(sname, tname, _skip, __data, __setup, __teardown) \
+    static struct ctest __TNAME(sname, tname) __Test_Section = { \
+        .ssname=#sname, \
+        .ttname=#tname, \
+        .run = __FNAME(sname, tname), \
+        .skip = _skip, \
+        .data = __data, \
+        .setup = (SetupFunc)__setup,                                   \
+        .teardown = (TearDownFunc)__teardown,                          \
+        .magic = __CTEST_MAGIC };
+
+#define CTEST_DATA(sname) struct sname##_data
+
+#define CTEST_SETUP(sname) \
+    void WEAK sname##_setup(struct sname##_data* data)
+
+#define CTEST_TEARDOWN(sname) \
+    void WEAK sname##_teardown(struct sname##_data* data)
+
+#define __CTEST_INTERNAL(sname, tname, _skip) \
+    void __FNAME(sname, tname)(); \
+    __CTEST_STRUCT(sname, tname, _skip, NULL, NULL, NULL) \
+    void __FNAME(sname, tname)()
+
+#ifdef __APPLE__
+#define SETUP_FNAME(sname) NULL
+#define TEARDOWN_FNAME(sname) NULL
+#else
+#define SETUP_FNAME(sname) sname##_setup
+#define TEARDOWN_FNAME(sname) sname##_teardown
+#endif
+
+#define __CTEST2_INTERNAL(sname, tname, _skip) \
+    static struct sname##_data  __ctest_##sname##_data; \
+    CTEST_SETUP(sname); \
+    CTEST_TEARDOWN(sname); \
+    void __FNAME(sname, tname)(struct sname##_data* data); \
+    __CTEST_STRUCT(sname, tname, _skip, &__ctest_##sname##_data, SETUP_FNAME(sname), TEARDOWN_FNAME(sname)) \
+    void __FNAME(sname, tname)(struct sname##_data* data)
+
+
+void CTEST_LOG(const char* fmt, ...);
+void CTEST_ERR(const char* fmt, ...);  // doesn't return
+
+#define CTEST(sname, tname) __CTEST_INTERNAL(sname, tname, 0)
+#define CTEST_SKIP(sname, tname) __CTEST_INTERNAL(sname, tname, 1)
+
+#define CTEST2(sname, tname) __CTEST2_INTERNAL(sname, tname, 0)
+#define CTEST2_SKIP(sname, tname) __CTEST2_INTERNAL(sname, tname, 1)
+
+
+void assert_str(const char* exp, const char* real, const char* caller, int line);
+#define ASSERT_STR(exp, real) assert_str(exp, real, __FILE__, __LINE__)
+
+void assert_data(const unsigned char* exp, size_t expsize,
+                 const unsigned char* real, size_t realsize,
+                 const char* caller, int line);
+#define ASSERT_DATA(exp, expsize, real, realsize) \
+    assert_data(exp, expsize, real, realsize, __FILE__, __LINE__)
+
+void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line);
+#define ASSERT_EQUAL(exp, real) assert_equal(exp, real, __FILE__, __LINE__)
+
+void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
+#define ASSERT_EQUAL_U(exp, real) assert_equal_u(exp, real, __FILE__, __LINE__)
+
+void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line);
+#define ASSERT_NOT_EQUAL(exp, real) assert_not_equal(exp, real, __FILE__, __LINE__)
+
+void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line);
+#define ASSERT_NOT_EQUAL_U(exp, real) assert_not_equal_u(exp, real, __FILE__, __LINE__)
+
+void assert_null(void* real, const char* caller, int line);
+#define ASSERT_NULL(real) assert_null((void*)real, __FILE__, __LINE__)
+
+void assert_not_null(const void* real, const char* caller, int line);
+#define ASSERT_NOT_NULL(real) assert_not_null(real, __FILE__, __LINE__)
+
+void assert_true(int real, const char* caller, int line);
+#define ASSERT_TRUE(real) assert_true(real, __FILE__, __LINE__)
+
+void assert_false(int real, const char* caller, int line);
+#define ASSERT_FALSE(real) assert_false(real, __FILE__, __LINE__)
+
+void assert_fail(const char* caller, int line);
+#define ASSERT_FAIL() assert_fail(__FILE__, __LINE__)
+
+void assert_dbl_near(double exp, double real, double tol, const char* caller, int line);
+#define ASSERT_DBL_NEAR(exp, real) assert_dbl_near(exp, real, 1e-4, __FILE__, __LINE__)
+#define ASSERT_DBL_NEAR_TOL(exp, real, tol) assert_dbl_near(exp, real, tol, __FILE__, __LINE__)
+
+void assert_dbl_far(double exp, double real, double tol, const char* caller, int line);
+#define ASSERT_DBL_FAR(exp, real) assert_dbl_far(exp, real, 1e-4, __FILE__, __LINE__)
+#define ASSERT_DBL_FAR_TOL(exp, real, tol) assert_dbl_far(exp, real, tol, __FILE__, __LINE__)
+
+#ifdef CTEST_MAIN
+
+#include <setjmp.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef __APPLE__
+#include <dlfcn.h>
+#endif
+
+static size_t ctest_errorsize;
+static char* ctest_errormsg;
+#define MSG_SIZE 4096
+static char ctest_errorbuffer[MSG_SIZE];
+static jmp_buf ctest_err;
+static int color_output = 1;
+static const char* suite_name;
+
+typedef int (*filter_func)(struct ctest*);
+
+#define ANSI_BLACK    "\033[0;30m"
+#define ANSI_RED      "\033[0;31m"
+#define ANSI_GREEN    "\033[0;32m"
+#define ANSI_YELLOW   "\033[0;33m"
+#define ANSI_BLUE     "\033[0;34m"
+#define ANSI_MAGENTA  "\033[0;35m"
+#define ANSI_CYAN     "\033[0;36m"
+#define ANSI_GREY     "\033[0;37m"
+#define ANSI_DARKGREY "\033[01;30m"
+#define ANSI_BRED     "\033[01;31m"
+#define ANSI_BGREEN   "\033[01;32m"
+#define ANSI_BYELLOW  "\033[01;33m"
+#define ANSI_BBLUE    "\033[01;34m"
+#define ANSI_BMAGENTA "\033[01;35m"
+#define ANSI_BCYAN    "\033[01;36m"
+#define ANSI_WHITE    "\033[01;37m"
+#define ANSI_NORMAL   "\033[0m"
+
+static CTEST(suite, test) { }
+
+inline static void vprint_errormsg(const char* const fmt, va_list ap) {
+       // (v)snprintf returns the number that would have been written
+    const int ret = vsnprintf(ctest_errormsg, ctest_errorsize, fmt, ap);
+    if (ret < 0) {
+               ctest_errormsg[0] = 0x00;
+    } else {
+       const size_t size = (size_t) ret;
+       const size_t s = (ctest_errorsize <= size ? size -ctest_errorsize : size);
+       // ctest_errorsize may overflow at this point
+               ctest_errorsize -= s;
+               ctest_errormsg += s;
+    }
+}
+
+inline static void print_errormsg(const char* const fmt, ...) {
+    va_list argp;
+    va_start(argp, fmt);
+    vprint_errormsg(fmt, argp);
+    va_end(argp);
+}
+
+static void msg_start(const char* color, const char* title) {
+    if (color_output) {
+       print_errormsg("%s", color);
+    }
+    print_errormsg("  %s: ", title);
+}
+
+static void msg_end() {
+    if (color_output) {
+       print_errormsg(ANSI_NORMAL);
+    }
+    print_errormsg("\n");
+}
+
+void CTEST_LOG(const char* fmt, ...)
+{
+    va_list argp;
+    msg_start(ANSI_BLUE, "LOG");
+
+    va_start(argp, fmt);
+    vprint_errormsg(fmt, argp);
+    va_end(argp);
+
+    msg_end();
+}
+
+void CTEST_ERR(const char* fmt, ...)
+{
+    va_list argp;
+    msg_start(ANSI_YELLOW, "ERR");
+
+    va_start(argp, fmt);
+    vprint_errormsg(fmt, argp);
+    va_end(argp);
+
+    msg_end();
+    longjmp(ctest_err, 1);
+}
+
+void assert_str(const char* exp, const char*  real, const char* caller, int line) {
+    if ((exp == NULL && real != NULL) ||
+        (exp != NULL && real == NULL) ||
+        (exp && real && strcmp(exp, real) != 0)) {
+        CTEST_ERR("%s:%d  expected '%s', got '%s'", caller, line, exp, real);
+    }
+}
+
+void assert_data(const unsigned char* exp, size_t expsize,
+                 const unsigned char* real, size_t realsize,
+                 const char* caller, int line) {
+    size_t i;
+    if (expsize != realsize) {
+        CTEST_ERR("%s:%d  expected %" PRIuMAX " bytes, got %" PRIuMAX, caller, line, (uintmax_t) expsize, (uintmax_t) realsize);
+    }
+    for (i=0; i<expsize; i++) {
+        if (exp[i] != real[i]) {
+            CTEST_ERR("%s:%d expected 0x%02x at offset %" PRIuMAX " got 0x%02x",
+                caller, line, exp[i], (uintmax_t) i, real[i]);
+        }
+    }
+}
+
+void assert_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
+    if (exp != real) {
+        CTEST_ERR("%s:%d  expected %" PRIdMAX ", got %" PRIdMAX, caller, line, exp, real);
+    }
+}
+
+void assert_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
+    if (exp != real) {
+        CTEST_ERR("%s:%d  expected %" PRIuMAX ", got %" PRIuMAX, caller, line, exp, real);
+    }
+}
+
+void assert_not_equal(intmax_t exp, intmax_t real, const char* caller, int line) {
+    if ((exp) == (real)) {
+        CTEST_ERR("%s:%d  should not be %" PRIdMAX, caller, line, real);
+    }
+}
+
+void assert_not_equal_u(uintmax_t exp, uintmax_t real, const char* caller, int line) {
+    if ((exp) == (real)) {
+        CTEST_ERR("%s:%d  should not be %" PRIuMAX, caller, line, real);
+    }
+}
+
+void assert_dbl_near(double exp, double real, double tol, const char* caller, int line) {
+    double diff = exp - real;
+    double absdiff = diff;
+    /* avoid using fabs and linking with a math lib */
+    if(diff < 0) {
+      absdiff *= -1;
+    }
+    if (absdiff > tol) {
+        CTEST_ERR("%s:%d  expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
+    }
+}
+
+void assert_dbl_far(double exp, double real, double tol, const char* caller, int line) {
+    double diff = exp - real;
+    double absdiff = diff;
+    /* avoid using fabs and linking with a math lib */
+    if(diff < 0) {
+      absdiff *= -1;
+    }
+    if (absdiff <= tol) {
+        CTEST_ERR("%s:%d  expected %0.3e, got %0.3e (diff %0.3e, tol %0.3e)", caller, line, exp, real, diff, tol);
+    }
+}
+
+void assert_null(void* real, const char* caller, int line) {
+    if ((real) != NULL) {
+        CTEST_ERR("%s:%d  should be NULL", caller, line);
+    }
+}
+
+void assert_not_null(const void* real, const char* caller, int line) {
+    if (real == NULL) {
+        CTEST_ERR("%s:%d  should not be NULL", caller, line);
+    }
+}
+
+void assert_true(int real, const char* caller, int line) {
+    if ((real) == 0) {
+        CTEST_ERR("%s:%d  should be true", caller, line);
+    }
+}
+
+void assert_false(int real, const char* caller, int line) {
+    if ((real) != 0) {
+        CTEST_ERR("%s:%d  should be false", caller, line);
+    }
+}
+
+void assert_fail(const char* caller, int line) {
+    CTEST_ERR("%s:%d  shouldn't come here", caller, line);
+}
+
+
+static int suite_all(struct ctest* t) {
+    (void) t; // fix unused parameter warning
+    return 1;
+}
+
+static int suite_filter(struct ctest* t) {
+    return strncmp(suite_name, t->ssname, strlen(suite_name)) == 0;
+}
+
+static uint64_t getCurrentTime() {
+    struct timeval now;
+    gettimeofday(&now, NULL);
+    uint64_t now64 = (uint64_t) now.tv_sec;
+    now64 *= 1000000;
+    now64 += ((uint64_t) now.tv_usec);
+    return now64;
+}
+
+static void color_print(const char* color, const char* text) {
+    if (color_output)
+        printf("%s%s"ANSI_NORMAL"\n", color, text);
+    else
+        printf("%s\n", text);
+}
+
+#ifdef __APPLE__
+static void *find_symbol(struct ctest *test, const char *fname)
+{
+    size_t len = strlen(test->ssname) + 1 + strlen(fname);
+    char *symbol_name = (char *) malloc(len + 1);
+    memset(symbol_name, 0, len + 1);
+    snprintf(symbol_name, len + 1, "%s_%s", test->ssname, fname);
+
+    //fprintf(stderr, ">>>> dlsym: loading %s\n", symbol_name);
+    void *symbol = dlsym(RTLD_DEFAULT, symbol_name);
+    if (!symbol) {
+        //fprintf(stderr, ">>>> ERROR: %s\n", dlerror());
+    }
+    // returns NULL on error
+
+    free(symbol_name);
+    return symbol;
+}
+#endif
+
+#ifdef CTEST_SEGFAULT
+#include <signal.h>
+static void sighandler(int signum)
+{
+    char msg[128];
+    sprintf(msg, "[SIGNAL %d: %s]", signum, sys_siglist[signum]);
+    color_print(ANSI_BRED, msg);
+    fflush(stdout);
+
+    /* "Unregister" the signal handler and send the signal back to the process
+     * so it can terminate as expected */
+    signal(signum, SIG_DFL);
+    kill(getpid(), signum);
+}
+#endif
+
+int ctest_main(int argc, const char *argv[])
+{
+    static int total = 0;
+    static int num_ok = 0;
+    static int num_fail = 0;
+    static int num_skip = 0;
+    static int index = 1;
+    static filter_func filter = suite_all;
+
+#ifdef CTEST_SEGFAULT
+    signal(SIGSEGV, sighandler);
+#endif
+
+    if (argc == 2) {
+        suite_name = argv[1];
+        filter = suite_filter;
+    }
+#ifdef CTEST_NO_COLORS
+    color_output = 0;
+#else
+    color_output = isatty(1);
+#endif
+    uint64_t t1 = getCurrentTime();
+
+    struct ctest* ctest_begin = &__TNAME(suite, test);
+    struct ctest* ctest_end = &__TNAME(suite, test);
+    // find begin and end of section by comparing magics
+    while (1) {
+        struct ctest* t = ctest_begin-1;
+        if (t->magic != __CTEST_MAGIC) break;
+        ctest_begin--;
+    }
+    while (1) {
+        struct ctest* t = ctest_end+1;
+        if (t->magic != __CTEST_MAGIC) break;
+        ctest_end++;
+    }
+    ctest_end++;    // end after last one
+
+    static struct ctest* test;
+    for (test = ctest_begin; test != ctest_end; test++) {
+        if (test == &__TNAME(suite, test)) continue;
+        if (filter(test)) total++;
+    }
+
+    for (test = ctest_begin; test != ctest_end; test++) {
+        if (test == &__TNAME(suite, test)) continue;
+        if (filter(test)) {
+            ctest_errorbuffer[0] = 0;
+            ctest_errorsize = MSG_SIZE-1;
+            ctest_errormsg = ctest_errorbuffer;
+            printf("TEST %d/%d %s:%s ", index, total, test->ssname, test->ttname);
+            fflush(stdout);
+            if (test->skip) {
+                color_print(ANSI_BYELLOW, "[SKIPPED]");
+                num_skip++;
+            } else {
+                int result = setjmp(ctest_err);
+                if (result == 0) {
+#ifdef __APPLE__
+                    if (!test->setup) {
+                        test->setup = (SetupFunc) find_symbol(test, "setup");
+                    }
+                    if (!test->teardown) {
+                        test->teardown = (TearDownFunc) find_symbol(test, "teardown");
+                    }
+#endif
+
+                    if (test->setup) test->setup(test->data);
+                    if (test->data)
+                        test->run(test->data);
+                    else
+                        test->run();
+                    if (test->teardown) test->teardown(test->data);
+                    // if we got here it's ok
+#ifdef CTEST_COLOR_OK
+                    color_print(ANSI_BGREEN, "[OK]");
+#else
+                    printf("[OK]\n");
+#endif
+                    num_ok++;
+                } else {
+                    color_print(ANSI_BRED, "[FAIL]");
+                    num_fail++;
+                }
+                if (ctest_errorsize != MSG_SIZE-1) printf("%s", ctest_errorbuffer);
+            }
+            index++;
+        }
+    }
+    uint64_t t2 = getCurrentTime();
+
+    const char* color = (num_fail) ? ANSI_BRED : ANSI_GREEN;
+    char results[80];
+    sprintf(results, "RESULTS: %d tests (%d ok, %d failed, %d skipped) ran in %" PRIu64 " ms", total, num_ok, num_fail, num_skip, (t2 - t1)/1000);
+    color_print(color, results);
+    return num_fail;
+}
+
+#endif
+
+#endif
+
diff --git a/utest/main.c b/utest/main.c
deleted file mode 100644 (file)
index 770d145..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/*****************************************************************************
-Copyright (c) 2011-2014, The OpenBLAS Project
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
-   1. Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimer.
-
-   2. Redistributions in binary form must reproduce the above copyright
-      notice, this list of conditions and the following disclaimer in
-      the documentation and/or other materials provided with the
-      distribution.
-   3. Neither the name of the OpenBLAS project nor the names of 
-      its contributors may be used to endorse or promote products 
-      derived from this software without specific prior written 
-      permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
-USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-**********************************************************************************/
-
-#include <stdio.h>
-#include <string.h>
-
-#include "common_utest.h"
-#include <CUnit/Basic.h>
-
-CU_TestInfo test_level1[]={
-       {"Testing srot when incx || incy == 0",test_srot_inc_0},
-       {"Testing drot when incx || incy == 0",test_drot_inc_0},
-       {"Testing csrot when incx || incy == 0",test_csrot_inc_0},
-       {"Testing zdrot when incx || incy == 0",test_zdrot_inc_0},
-
-       {"Testing sswap with incx || incy == 0",test_sswap_inc_0},
-       {"Testing dswap with incx || incy == 0",test_dswap_inc_0},
-       {"Testing cswap with incx || incy == 0",test_cswap_inc_0},
-       {"Testing zswap with incx || incy == 0",test_zswap_inc_0},
-
-       {"Testing saxpy with incx || incy == 0",test_saxpy_inc_0},
-       {"Testing daxpy with incx || incy == 0",test_daxpy_inc_0},
-       {"Testing caxpy with incx || incy == 0",test_caxpy_inc_0},
-       {"Testing zaxpy with incx || incy == 0",test_zaxpy_inc_0},
-
-       {"Testing zdotu with n == 1",test_zdotu_n_1},
-       {"Testing zdotu with input x & y offset == 1",test_zdotu_offset_1},
-
-       {"Testing drotmg",test_drotmg},
-       {"Testing drotmg with D1 == D2 && X1 == X2",test_drotmg_D1eqD2_X1eqX2},
-
-       {"Testing dsdot with n == 1",test_dsdot_n_1},
-
-       {"Testing samax", test_samax},
-
-#if !defined(USE_OPENMP) && !defined(OS_WINDOWS)
-       // The GNU OpenMP implementation libgomp is not fork-safe (as of 4.8.2):
-       // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60035
-       // Hence skip this test when OpenBLAS is built with OpenMP.
-       {"Testing fork safety", test_fork_safety},
-#endif
-
-       CU_TEST_INFO_NULL,
-};
-
-CU_SuiteInfo suites[]={
-       {"Level1 Test Suite", NULL,NULL,test_level1},
-       CU_SUITE_INFO_NULL,
-};
-
-int main()
-{
-       CU_ErrorCode error;
-       if (CUE_SUCCESS != CU_initialize_registry())
-               return CU_get_error();
-
-       error=CU_register_suites(suites);
-
-       if (error != CUE_SUCCESS) {
-               perror(CU_get_error_msg());
-               CU_cleanup_registry();
-               return CU_get_error();
-
-       }
-
-
-
-       printf("Seting OK\n");
-       fflush(stdout);
-
-       /* Run all tests using the CUnit Basic interface */
-       CU_basic_set_mode(CU_BRM_VERBOSE);
-
-       CU_basic_run_tests();
-
-       CU_cleanup_registry();
-
-       return CU_get_error();
-
-}
-
similarity index 70%
rename from utest/common_utest.h
rename to utest/openblas_utest.h
index d170ed2..fb70fdc 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
-Copyright (c) 2011-2014, The OpenBLAS Project
+Copyright (c) 2011-2016, The OpenBLAS Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -31,40 +31,14 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 **********************************************************************************/
 
-#ifndef COMMON_UTEST_H_
-#define COMMON_UTEST_H_
-#include <CUnit/CUnit.h>
+#ifndef _OPENBLAS_UTEST_H_
+#define _OPENBLAS_UTEST_H_
 
-#include <common.h>
-
-#define CHECK_EPS 0.00002
-
-//Testcase list
-void test_drot_inc_0(void);
-void test_srot_inc_0(void);
-void test_zdrot_inc_0(void);
-void test_csrot_inc_0(void);
-
-void test_dswap_inc_0(void);
-void test_zswap_inc_0(void);
-void test_sswap_inc_0(void);
-void test_cswap_inc_0(void);
-
-void test_daxpy_inc_0(void);
-void test_zaxpy_inc_0(void);
-void test_saxpy_inc_0(void);
-void test_caxpy_inc_0(void);
+#include <stdlib.h>
+#include "ctest.h"
 
-void test_zdotu_n_1(void);
-void test_zdotu_offset_1(void);
-
-void test_drotmg(void);
-void test_drotmg_D1eqD2_X1eqX2();
-
-void test_dsdot_n_1(void);
-
-void test_samax(void);
-
-void test_fork_safety(void);
+#include <common.h>
 
+#define SINGLE_EPS 1e-04
+#define DOUBLE_EPS 1e-13
 #endif
index 3195a6e..829da24 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
-Copyright (c) 2011-2014, The OpenBLAS Project
+Copyright (c) 2011-2016, The OpenBLAS Project
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,15 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 **********************************************************************************/
 
-#include "common_utest.h"
+#include "openblas_utest.h"
 
-void test_samax()
-{
+CTEST(amax, samax){
   int N=3, inc=1;
   float te_max=0.0, tr_max=0.0;
   float x[]={-1.1, 2.2, -3.3};
 
   te_max=BLASFUNC(samax)(&N, x, &inc);
-
-  tr_max=BLASFUNC_REF(samax)(&N, x, &inc);
-
-  CU_ASSERT_DOUBLE_EQUAL(te_max, tr_max, CHECK_EPS);
+  tr_max=3.3;
+  
+  ASSERT_DBL_NEAR_TOL((double)(tr_max), (double)(te_max), SINGLE_EPS);
 }
diff --git a/utest/utest_main.c b/utest/utest_main.c
new file mode 100644 (file)
index 0000000..68660c1
--- /dev/null
@@ -0,0 +1,48 @@
+/*****************************************************************************
+Copyright (c) 2011-2016, The OpenBLAS Project
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in
+      the documentation and/or other materials provided with the
+      distribution.
+   3. Neither the name of the OpenBLAS project nor the names of 
+      its contributors may be used to endorse or promote products 
+      derived from this software without specific prior written 
+      permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**********************************************************************************/
+
+#include <stdio.h>
+
+#define CTEST_MAIN
+#define CTEST_SEGFAULT
+
+#include "openblas_utest.h"
+
+int main(int argc, const char ** argv){
+
+  int num_fail=0;
+
+  num_fail=ctest_main(argc, argv);
+
+  return num_fail;
+}