diff options
| author | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2016-05-17 23:02:04 +0200 |
|---|---|---|
| committer | Gertjan van den Burg <gertjanvandenburg@gmail.com> | 2016-05-17 23:02:04 +0200 |
| commit | 7d9f7e9341ab22599ea541959dbf9323661c777f (patch) | |
| tree | 93b9262f64b606089b6b85aceafc47fa631887e8 /tests | |
| parent | make blas and lapack calls more compact (diff) | |
| download | gensvm-7d9f7e9341ab22599ea541959dbf9323661c777f.tar.gz gensvm-7d9f7e9341ab22599ea541959dbf9323661c777f.zip | |
start adding unit tests
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/Makefile | 28 | ||||
| -rw-r--r-- | tests/include/dbg.h | 36 | ||||
| -rw-r--r-- | tests/include/minunit.h | 34 | ||||
| -rwxr-xr-x | tests/runtests.sh | 38 | ||||
| -rw-r--r-- | tests/src/test_gensvm_base.c | 64 | ||||
| -rw-r--r-- | tests/src/test_gensvm_copy.c | 267 | ||||
| -rw-r--r-- | tests/src/test_gensvm_grid.c | 26 | ||||
| -rw-r--r-- | tests/src/test_gensvm_queue.c | 58 | ||||
| -rw-r--r-- | tests/src/test_gensvm_simplex.c | 68 | ||||
| -rw-r--r-- | tests/src/test_gensvm_task.c | 26 |
10 files changed, 645 insertions, 0 deletions
diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..dc5e0c5 --- /dev/null +++ b/tests/Makefile @@ -0,0 +1,28 @@ +CC=gcc +CFLAGS=-Wall -O3 -g -rdynamic -DNDEBUG $(OPTFLAGS) +INCLUDE=-I../include/ -I./include +LIB=-L../lib + +override LDFLAGS+=-lgensvm -lm + +TEST_SRC=$(wildcard src/test_*.c) +TESTS=$(patsubst src/%.c,bin/%,$(TEST_SRC)) + +.PHONY: all + +all: $(TESTS) + bash ./runtests.sh + +bin/%: src/%.c + @echo $< + @$(CC) $< -o $@ $(CFLAGS) $(INCLUDE) $(LIB) $(LDFLAGS) + +valgrind: + VALGRIND="valgrind --error-limit=no --leak-check=full \ + --log-file=/tmp/valgrind-%p.log --track-origins=yes \ + --show-leak-kinds=all -v" $(MAKE) + +clean: + rm -rf $(TESTS) + rm -f ./tests.log + rm -f /tmp/valgrind*.log diff --git a/tests/include/dbg.h b/tests/include/dbg.h new file mode 100644 index 0000000..0401ea1 --- /dev/null +++ b/tests/include/dbg.h @@ -0,0 +1,36 @@ +#ifndef __dbg_h__ +#define __dbg_h__ + +#include <stdio.h> +#include <errno.h> +#include <string.h> + +#ifdef NDEBUG +#define debug(M, ...) +#else +#define debug(M, ...) fprintf(stderr, "DEBUG %s:%d: " M "\n", __FILE__, \ + __LINE__, ##__VA_ARGS__) +#endif + +#define clean_errno() (errno == 0 ? "None" : strerror(errno)) + +#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", \ + __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) + +#define log_warn(M, ...) fprintf(stderr, "[WARN] (%s:%d: errno: %s) " M "\n", \ + __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__) + +#define log_info(M, ...) fprintf(stderr, "[INFO] (%s:%d) " M "\n", \ + __FILE__, __LINE__, ##__VA_ARGS__) + +#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; \ + goto error; } + +#define sentinel(M, ...) { log_err(M, ##__VA_ARGS__); errno=0; goto error; } + +#define check_mem(A) check((A), "Out of memory."); + +#define check_debug(A, M, ...) if (!(A)) { debug(M, ##__VA_ARGS__); errno=0; \ + goto error; } + +#endif diff --git a/tests/include/minunit.h b/tests/include/minunit.h new file mode 100644 index 0000000..4197310 --- /dev/null +++ b/tests/include/minunit.h @@ -0,0 +1,34 @@ +#undef NDEBUG +#ifndef _minunit_h +#define _minunit_h + +#include "dbg.h" +#include <stdlib.h> + +#define mu_suite_start() char *message = NULL + +#define mu_assert(test, message) if (!(test)) { log_err(message); return message; } + +#define mu_run_test(test) debug("\n-----%s", " " #test); \ + message = test(); tests_run++; if (message) return message; + +#define RUN_TESTS(name) int main(int argc, char *argv[]) {\ + argc = 1; \ + debug("\n-----\nRUNNING: %s", argv[0]);\ + printf("----\nRUNNING: %s\n", argv[0]);\ + char *result = name();\ + if (result != 0) {\ + printf("\033[91mFAILED:\033[0m %s\n", result);\ + }\ + else {\ + printf("ALL TESTS \033[92mPASSED\033[0m\n");\ + }\ + printf("Tests run: %d\n", tests_run);\ + exit(result != 0);\ +} + +#define mu_test_missing() printf("\033[33;1mWARNING: Test missing\033[0m\n"); + +int tests_run; + +#endif diff --git a/tests/runtests.sh b/tests/runtests.sh new file mode 100755 index 0000000..0de79d8 --- /dev/null +++ b/tests/runtests.sh @@ -0,0 +1,38 @@ +#!/bin/bash + +echo -e "\033[95mRunning unit tests:\033[0m" + +for i in bin/test_* +do + if test -f $i + then + if $VALGRIND ./$i 2>> ./tests.log + then + echo $i PASS + else + echo "ERROR in test $i: here's ./tests.log" + echo "------" + tail ./tests.log + exit 1 + fi + if [ ! -z "$VALGRIND" ] + then + for log in `ls /tmp/valgrind-*.log`; + do + cmdstr=$(head -n 4 $log | tail -n 1) + if [[ $cmdstr == *"$i"* ]] + then + tailstr=$(tail -n 1 $log) + if [[ $tailstr == *"0 errors from 0 contexts"* ]] + then + echo -e "\033[92mVALGRIND GOOD\033[0m" + else + echo -e "\033[91mVALGRIND BAD\033[0m" + fi + fi + done + fi + fi +done + +echo "" diff --git a/tests/src/test_gensvm_base.c b/tests/src/test_gensvm_base.c new file mode 100644 index 0000000..2f12579 --- /dev/null +++ b/tests/src/test_gensvm_base.c @@ -0,0 +1,64 @@ +/** + * @file test_gensvm_base.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_base.c functions + */ + +#include "minunit.h" +#include "gensvm_base.h" + +char *test_init_free_model() +{ + struct GenModel *model = gensvm_init_model(); + gensvm_free_model(model); + return NULL; +} + +char *test_allocate_free_model() +{ + struct GenModel *model = gensvm_init_model(); + model->n = 3; + model->m = 4; + model->K = 5; + gensvm_allocate_model(model); + gensvm_free_model(model); + return NULL; +} + +char *test_reallocate_free_model() +{ + struct GenModel *model = gensvm_init_model(); + model->n = 3; + model->m = 4; + model->K = 5; + gensvm_allocate_model(model); + gensvm_reallocate_model(model, 3, 4); + model->n = 4; + gensvm_reallocate_model(model, 4, 4); + gensvm_reallocate_model(model, 4, 5); + gensvm_reallocate_model(model, 3, 4); + + gensvm_free_model(model); + return NULL; +} + +char *test_init_free_data() +{ + struct GenData *data = gensvm_init_data(); + gensvm_free_data(data); + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_init_free_model); + mu_run_test(test_allocate_free_model); + mu_run_test(test_reallocate_free_model); + mu_run_test(test_init_free_data); + + return NULL; +} + +RUN_TESTS(all_tests); diff --git a/tests/src/test_gensvm_copy.c b/tests/src/test_gensvm_copy.c new file mode 100644 index 0000000..a9636bb --- /dev/null +++ b/tests/src/test_gensvm_copy.c @@ -0,0 +1,267 @@ +/** + * @file test_gensvm_copy.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_copy.c functions + */ + +#include "minunit.h" +#include "gensvm_copy.h" + +char *test_copy_model_linear() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_LINEAR; + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_LINEAR, "to->kerneltype incorrect"); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_poly_1() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_POLY; + from_model->kernelparam = Calloc(double, 3); + from_model->kernelparam[0] = 1.0; + from_model->kernelparam[1] = 2.0; + from_model->kernelparam[2] = 3.0; + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, "to->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_POLY, "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 1.0, + "to->kernelparam[0] is incorrect."); + mu_assert(to_model->kernelparam[1] == 2.0, + "to->kernelparam[1] is incorrect."); + mu_assert(to_model->kernelparam[2] == 3.0, + "to->kernelparam[2] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_poly_2() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_POLY; + from_model->kernelparam = Calloc(double, 3); + from_model->kernelparam[0] = 1.0; + from_model->kernelparam[1] = 2.0; + from_model->kernelparam[2] = 3.0; + to_model->kernelparam = Calloc(double, 3); + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_POLY, "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 1.0, + "to->kernelparam[0] is incorrect."); + mu_assert(to_model->kernelparam[1] == 2.0, + "to->kernelparam[1] is incorrect."); + mu_assert(to_model->kernelparam[2] == 3.0, + "to->kernelparam[2] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_rbf_1() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_RBF; + from_model->kernelparam = Calloc(double, 1); + from_model->kernelparam[0] = 5.0; + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_RBF, "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 5.0, + "to->kernelparam[0] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_rbf_2() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_RBF; + from_model->kernelparam = Calloc(double, 1); + from_model->kernelparam[0] = 5.0; + to_model->kernelparam = Calloc(double, 1); + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_RBF, "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 5.0, + "to->kernelparam[0] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_sigmoid_1() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_SIGMOID; + from_model->kernelparam = Calloc(double, 2); + from_model->kernelparam[0] = 5.0; + from_model->kernelparam[1] = 10.0; + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_SIGMOID, + "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 5.0, + "to->kernelparam[0] is incorrect."); + mu_assert(to_model->kernelparam[1] == 10.0, + "to->kernelparam[1] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *test_copy_model_sigmoid_2() +{ + struct GenModel *from_model = gensvm_init_model(); + struct GenModel *to_model = gensvm_init_model(); + + from_model->p = 2.0; + from_model->lambda = 1.0; + from_model->epsilon = 1e-8; + from_model->kappa = 1.0; + from_model->weight_idx = 2; + from_model->kerneltype = K_SIGMOID; + from_model->kernelparam = Calloc(double, 2); + from_model->kernelparam[0] = 5.0; + from_model->kernelparam[1] = 10.0; + to_model->kernelparam = Calloc(double, 2); + + gensvm_copy_model(from_model, to_model); + + mu_assert(to_model->p == 2.0, "to_model->p incorrect."); + mu_assert(to_model->lambda == 1.0, "to_model->lambda incorrect."); + mu_assert(to_model->epsilon == 1e-8, "to_model->epsilon incorrect."); + mu_assert(to_model->kappa == 1.0, "to_model->kappa incorrect."); + mu_assert(to_model->weight_idx == 2, + "to_model->weight_idx incorrect."); + mu_assert(to_model->kerneltype == K_SIGMOID, + "to->kerneltype incorrect"); + mu_assert(to_model->kernelparam[0] == 5.0, + "to->kernelparam[0] is incorrect."); + mu_assert(to_model->kernelparam[1] == 10.0, + "to->kernelparam[1] is incorrect."); + + gensvm_free_model(from_model); + gensvm_free_model(to_model); + + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_copy_model_linear); + mu_run_test(test_copy_model_poly_1); + mu_run_test(test_copy_model_poly_2); + mu_run_test(test_copy_model_rbf_1); + mu_run_test(test_copy_model_rbf_2); + mu_run_test(test_copy_model_sigmoid_1); + mu_run_test(test_copy_model_sigmoid_2); + + return NULL; +} + +RUN_TESTS(all_tests); diff --git a/tests/src/test_gensvm_grid.c b/tests/src/test_gensvm_grid.c new file mode 100644 index 0000000..6979c5b --- /dev/null +++ b/tests/src/test_gensvm_grid.c @@ -0,0 +1,26 @@ +/** + * @file test_gensvm_grid.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_grid.c functions + */ + +#include "minunit.h" +#include "gensvm_grid.h" + +char *test_init_free_grid() +{ + struct GenGrid *grid = gensvm_init_grid(); + gensvm_free_grid(grid); + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_init_free_grid); + + return NULL; +} + +RUN_TESTS(all_tests); diff --git a/tests/src/test_gensvm_queue.c b/tests/src/test_gensvm_queue.c new file mode 100644 index 0000000..542d15c --- /dev/null +++ b/tests/src/test_gensvm_queue.c @@ -0,0 +1,58 @@ +/** + * @file test_gensvm_queue.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_queue.c functions + */ + +#include "minunit.h" +#include "gensvm_task.h" +#include "gensvm_queue.h" + +char *test_init_free_queue() +{ + struct GenQueue *queue = gensvm_init_queue(); + gensvm_free_queue(queue); + return NULL; +} + +char *test_get_next_task() +{ + struct GenQueue *q = gensvm_init_queue(); + q->N = 3; + q->i = 0; + q->tasks = Calloc(struct GenTask *, 3); + + struct GenTask *task_1 = gensvm_init_task(); + struct GenTask *task_2 = gensvm_init_task(); + struct GenTask *task_3 = gensvm_init_task(); + task_1->ID = 1; + task_2->ID = 2; + task_3->ID = 3; + + q->tasks[0] = task_1; + q->tasks[1] = task_2; + q->tasks[2] = task_3; + + struct GenTask *t = NULL; + t = get_next_task(q); + mu_assert(t == task_1, "first task is not task_1"); + t = get_next_task(q); + t = get_next_task(q); + mu_assert(t == task_3, "third task is not task_3"); + + gensvm_free_queue(q); + + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_init_free_queue); + mu_run_test(test_get_next_task); + + return NULL; +} + +RUN_TESTS(all_tests); diff --git a/tests/src/test_gensvm_simplex.c b/tests/src/test_gensvm_simplex.c new file mode 100644 index 0000000..c13c4ea --- /dev/null +++ b/tests/src/test_gensvm_simplex.c @@ -0,0 +1,68 @@ +/** + * @file test_gensvm_simplex.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_simplex.c functions + */ + +#include "minunit.h" +#include "gensvm_simplex.h" + +char *test_simplex_1() +{ + double *U = Calloc(double, 2*1); + + gensvm_simplex(2, U); + + mu_assert(matrix_get(U, 1, 0, 0) == -0.5, "U(0, 0) incorrect."); + mu_assert(matrix_get(U, 1, 1, 0) == 0.5, "U(1, 0) incorrect."); + + free(U); + + return NULL; +} + +char *test_simplex_2() +{ + double *U = Calloc(double, 4*3); + + gensvm_simplex(4, U); + + mu_assert(matrix_get(U, 3, 0, 0) == -0.5, "U(0, 0) incorrect."); + mu_assert(matrix_get(U, 3, 1, 0) == 0.5, "U(1, 0) incorrect."); + mu_assert(matrix_get(U, 3, 2, 0) == 0.0, "U(2, 0) incorrect."); + mu_assert(matrix_get(U, 3, 3, 0) == 0.0, "U(3, 0) incorrect."); + + mu_assert(fabs(matrix_get(U, 3, 0, 1) - -0.5/sqrt(3)) < 1e-14, + "U(0, 1) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 1, 1) - -0.5/sqrt(3)) < 1e-14, + "U(1, 1) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 2, 1) - 1.0/sqrt(3)) < 1e-14, + "U(2, 1) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 3, 1) - 0.0) < 1e-14, + "U(3, 1) incorrect."); + + mu_assert(fabs(matrix_get(U, 3, 0, 2) - -1.0/sqrt(24)) < 1e-14, + "U(0, 2) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 1, 2) - -1.0/sqrt(24)) < 1e-14, + "U(1, 2) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 2, 2) - -1.0/sqrt(24)) < 1e-14, + "U(2, 2) incorrect."); + mu_assert(fabs(matrix_get(U, 3, 3, 2) - 3.0/sqrt(24)) < 1e-14, + "U(3, 2) incorrect."); + + free(U); + + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_simplex_1); + mu_run_test(test_simplex_2); + + return NULL; +} + +RUN_TESTS(all_tests); diff --git a/tests/src/test_gensvm_task.c b/tests/src/test_gensvm_task.c new file mode 100644 index 0000000..e39634b --- /dev/null +++ b/tests/src/test_gensvm_task.c @@ -0,0 +1,26 @@ +/** + * @file test_gensvm_task.c + * @author Gertjan van den Burg + * @date May, 2016 + * @brief Unit tests for gensvm_task.c functions + */ + +#include "minunit.h" +#include "gensvm_task.h" + +char *test_init_free_task() +{ + struct GenTask *task = gensvm_init_task(); + gensvm_free_task(task); + return NULL; +} + +char *all_tests() +{ + mu_suite_start(); + mu_run_test(test_init_free_task); + + return NULL; +} + +RUN_TESTS(all_tests); |
