summaryrefslogtreecommitdiff
path: root/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c')
-rw-r--r--libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c387
1 files changed, 387 insertions, 0 deletions
diff --git a/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c
new file mode 100644
index 0000000..7449b4b
--- /dev/null
+++ b/libs/ode-0.16.1/libccd/src/testsuites/cu/cu.c
@@ -0,0 +1,387 @@
+/***
+ * CU - C unit testing framework
+ * ---------------------------------
+ * Copyright (c)2007,2008,2009 Daniel Fiser <danfis@danfis.cz>
+ *
+ *
+ * This file is part of CU.
+ *
+ * CU is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 3 of
+ * the License, or (at your option) any later version.
+ *
+ * CU is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include "cu.h"
+
+/** Declared here, because I didn't find header file where it is declared */
+char *strsignal(int sig);
+
+const char *cu_current_test;
+const char *cu_current_test_suite;
+int cu_success_test_suites = 0;
+int cu_fail_test_suites = 0;
+int cu_success_tests = 0;
+int cu_fail_tests = 0;
+int cu_success_checks = 0;
+int cu_fail_checks = 0;
+
+char cu_out_prefix[CU_OUT_PREFIX_LENGTH+1] = "";
+
+
+/* globally used file descriptor for reading/writing messages */
+int fd;
+
+/* indicate if test was failed */
+int test_failed;
+
+/* codes of messages */
+#define CHECK_FAILED '0'
+#define CHECK_SUCCEED '1'
+#define TEST_FAILED '2'
+#define TEST_SUCCEED '3'
+#define TEST_SUITE_FAILED '4'
+#define TEST_SUITE_SUCCEED '5'
+#define END '6'
+#define TEST_NAME '7'
+
+/* predefined messages */
+#define MSG_CHECK_SUCCEED write(fd, "1\n", 2)
+#define MSG_TEST_FAILED write(fd, "2\n", 2)
+#define MSG_TEST_SUCCEED write(fd, "3\n", 2)
+#define MSG_TEST_SUITE_FAILED write(fd, "4\n", 2)
+#define MSG_TEST_SUITE_SUCCEED write(fd, "5\n", 2)
+#define MSG_END write(fd, "6\n", 2)
+
+/* length of buffers */
+#define BUF_LEN 1000
+#define MSGBUF_LEN 300
+
+
+static void redirect_out_err(const char *testName);
+static void close_out_err(void);
+static void run_test_suite(const char *ts_name, cu_test_suite_t *ts);
+static void receive_messages(void);
+
+static void cu_run_fork(const char *ts_name, cu_test_suite_t *test_suite);
+static void cu_print_results(void);
+
+void cu_run(int argc, char *argv[])
+{
+ cu_test_suites_t *tss;
+ int i;
+ char found = 0;
+
+ if (argc > 1){
+ for (i=1; i < argc; i++){
+ tss = cu_test_suites;
+ while (tss->name != NULL && tss->test_suite != NULL){
+ if (strcmp(argv[i], tss->name) == 0){
+ found = 1;
+ cu_run_fork(tss->name, tss->test_suite);
+ break;
+ }
+ tss++;
+ }
+
+ if (tss->name == NULL || tss->test_suite == NULL){
+ fprintf(stderr, "ERROR: Could not find test suite '%s'\n", argv[i]);
+ }
+ }
+
+ if (found == 1)
+ cu_print_results();
+
+ }else{
+ tss = cu_test_suites;
+ while (tss->name != NULL && tss->test_suite != NULL){
+ cu_run_fork(tss->name, tss->test_suite);
+ tss++;
+ }
+ cu_print_results();
+ }
+
+
+}
+
+static void cu_run_fork(const char *ts_name, cu_test_suite_t *ts)
+{
+ int pipefd[2];
+ int pid;
+ int status;
+
+ if (pipe(pipefd) == -1){
+ perror("Pipe error");
+ exit(-1);
+ }
+
+ fprintf(stdout, " -> %s [IN PROGESS]\n", ts_name);
+ fflush(stdout);
+
+ pid = fork();
+ if (pid < 0){
+ perror("Fork error");
+ exit(-1);
+ }
+
+ if (pid == 0){
+ /* close read end of pipe */
+ close(pipefd[0]);
+
+ fd = pipefd[1];
+
+ /* run testsuite, messages go to fd */
+ run_test_suite(ts_name, ts);
+
+ MSG_END;
+ close(fd);
+
+ /* stop process where running testsuite */
+ exit(0);
+ }else{
+ /* close write end of pipe */
+ close(pipefd[1]);
+
+ fd = pipefd[0];
+
+ /* receive and interpret all messages */
+ receive_messages();
+
+ /* wait for children */
+ wait(&status);
+ if (!WIFEXITED(status)){ /* if child process ends up abnormaly */
+ if (WIFSIGNALED(status)){
+ fprintf(stdout, "Test suite was terminated by signal %d (%s).\n",
+ WTERMSIG(status), strsignal(WTERMSIG(status)));
+ }else{
+ fprintf(stdout, "Test suite terminated abnormaly!\n");
+ }
+
+ /* mark this test suite as failed, because was terminated
+ * prematurely */
+ cu_fail_test_suites++;
+ }
+
+ close(fd);
+
+ fprintf(stdout, " -> %s [DONE]\n\n", ts_name);
+ fflush(stdout);
+ }
+
+}
+
+static void run_test_suite(const char *ts_name, cu_test_suite_t *ts)
+{
+ int test_suite_failed = 0;
+ char buffer[MSGBUF_LEN];
+ int len;
+
+ /* set up current test suite name for later messaging... */
+ cu_current_test_suite = ts_name;
+
+ /* redirect stdout and stderr */
+ redirect_out_err(cu_current_test_suite);
+
+ while (ts->name != NULL && ts->func != NULL){
+ test_failed = 0;
+
+ /* set up name of test for later messaging */
+ cu_current_test = ts->name;
+
+ /* send message what test is currently running */
+ len = snprintf(buffer, MSGBUF_LEN, "%c --> Running %s...\n",
+ TEST_NAME, cu_current_test);
+ write(fd, buffer, len);
+
+ /* run test */
+ (*(ts->func))();
+
+ if (test_failed){
+ MSG_TEST_FAILED;
+ test_suite_failed = 1;
+ }else{
+ MSG_TEST_SUCCEED;
+ }
+
+ ts++; /* next test in test suite */
+ }
+
+ if (test_suite_failed){
+ MSG_TEST_SUITE_FAILED;
+ }else{
+ MSG_TEST_SUITE_SUCCEED;
+ }
+
+ /* close redirected stdout and stderr */
+ close_out_err();
+}
+
+
+static void receive_messages(void)
+{
+ char buf[BUF_LEN]; /* buffer */
+ int buf_len; /* how many chars stored in buf */
+ char bufout[MSGBUF_LEN]; /* buffer which can be printed out */
+ int bufout_len;
+ int state = 0; /* 0 - waiting for code, 1 - copy msg to stdout */
+ int i;
+ int end = 0; /* end of messages? */
+
+ bufout_len = 0;
+ while((buf_len = read(fd, buf, BUF_LEN)) > 0 && !end){
+ for (i=0; i < buf_len; i++){
+
+ /* Prepare message for printing out */
+ if (state == 1 || state == 2){
+ if (bufout_len < MSGBUF_LEN)
+ bufout[bufout_len++] = buf[i];
+ }
+
+ /* reset state on '\n' in msg */
+ if (buf[i] == '\n'){
+ /* copy messages out */
+ if (state == 1)
+ write(1, bufout, bufout_len);
+ if (state == 2)
+ write(2, bufout, bufout_len);
+
+ state = 0;
+ bufout_len = 0;
+ continue;
+ }
+
+ if (state == 0){
+ if (buf[i] == CHECK_FAILED){
+ cu_fail_checks++;
+ state = 2;
+ }else if (buf[i] == TEST_NAME){
+ state = 1;
+ }else if (buf[i] == CHECK_SUCCEED){
+ cu_success_checks++;
+ }else if (buf[i] == TEST_FAILED){
+ cu_fail_tests++;
+ }else if (buf[i] == TEST_SUCCEED){
+ cu_success_tests++;
+ }else if (buf[i] == TEST_SUITE_FAILED){
+ cu_fail_test_suites++;
+ }else if (buf[i] == TEST_SUITE_SUCCEED){
+ cu_success_test_suites++;
+ }else if (buf[i] == END){
+ end = 1;
+ break;
+ }
+ }
+ }
+ }
+}
+
+void cu_success_assertation(void)
+{
+ MSG_CHECK_SUCCEED;
+}
+
+void cu_fail_assertation(const char *file, int line, const char *msg)
+{
+ char buf[MSGBUF_LEN];
+ int len;
+
+ len = snprintf(buf, MSGBUF_LEN, "%c%s:%d (%s::%s) :: %s\n",
+ CHECK_FAILED,
+ file, line, cu_current_test_suite, cu_current_test, msg);
+ write(fd, buf, len);
+
+ /* enable test_failed flag */
+ test_failed = 1;
+}
+
+static void cu_print_results(void)
+{
+ fprintf(stdout, "\n");
+ fprintf(stdout, "==================================================\n");
+ fprintf(stdout, "| | failed | succeed | total |\n");
+ fprintf(stdout, "|------------------------------------------------|\n");
+ fprintf(stdout, "| assertations: | %6d | %7d | %5d |\n",
+ cu_fail_checks, cu_success_checks,
+ cu_success_checks+cu_fail_checks);
+ fprintf(stdout, "| tests: | %6d | %7d | %5d |\n",
+ cu_fail_tests, cu_success_tests,
+ cu_success_tests+cu_fail_tests);
+ fprintf(stdout, "| tests suites: | %6d | %7d | %5d |\n",
+ cu_fail_test_suites, cu_success_test_suites,
+ cu_success_test_suites+cu_fail_test_suites);
+ fprintf(stdout, "==================================================\n");
+}
+
+void cu_set_out_prefix(const char *str)
+{
+ strncpy(cu_out_prefix, str, CU_OUT_PREFIX_LENGTH);
+}
+
+static void redirect_out_err(const char *test_name)
+{
+ char buf[100];
+
+ snprintf(buf, 99, "%stmp.%s.out", cu_out_prefix, test_name);
+ if (freopen(buf, "w", stdout) == NULL){
+ perror("Redirecting of stdout failed");
+ exit(-1);
+ }
+
+ snprintf(buf, 99, "%stmp.%s.err", cu_out_prefix, test_name);
+ if (freopen(buf, "w", stderr) == NULL){
+ perror("Redirecting of stderr failed");
+ exit(-1);
+ }
+}
+
+static void close_out_err(void)
+{
+ fclose(stdout);
+ fclose(stderr);
+}
+
+
+#ifdef CU_ENABLE_TIMER
+/* global variables for timer functions */
+struct timespec __cu_timer;
+static struct timespec __cu_timer_start, __cu_timer_stop;
+
+const struct timespec *cuTimer(void)
+{
+ return &__cu_timer;
+}
+
+void cuTimerStart(void)
+{
+ clock_gettime(CLOCK_MONOTONIC, &__cu_timer_start);
+}
+
+const struct timespec *cuTimerStop(void)
+{
+ clock_gettime(CLOCK_MONOTONIC, &__cu_timer_stop);
+
+ /* store into t difference between time_start and time_end */
+ if (__cu_timer_stop.tv_nsec > __cu_timer_start.tv_nsec){
+ __cu_timer.tv_nsec = __cu_timer_stop.tv_nsec - __cu_timer_start.tv_nsec;
+ __cu_timer.tv_sec = __cu_timer_stop.tv_sec - __cu_timer_start.tv_sec;
+ }else{
+ __cu_timer.tv_nsec = __cu_timer_stop.tv_nsec + 1000000000L - __cu_timer_start.tv_nsec;
+ __cu_timer.tv_sec = __cu_timer_stop.tv_sec - 1 - __cu_timer_start.tv_sec;
+ }
+
+ return &__cu_timer;
+}
+#endif /* CU_ENABLE_TIMER */