From c2e11b9172bd6e62665b2c9cca6a1a4d3dd41c73 Mon Sep 17 00:00:00 2001 From: fanasina Date: Tue, 22 Aug 2023 09:25:11 +0200 Subject: [PATCH] debug parallel tests, some change in the legacy tests --- isgood | Bin 43064 -> 61944 bytes src/test_t/bk000_test_t.c | 450 +++++++++++++++++++++++++++ src/test_t/is_good.c | 27 +- src/test_t/test_t.c | 627 +++++++++++++++++++++++++++++++------- src/test_t/test_t.h | 221 +++++++++++--- src/tools_t/tools_t.c | 17 +- src/tools_t/tools_t.h | 37 +++ 7 files changed, 1213 insertions(+), 166 deletions(-) create mode 100644 src/test_t/bk000_test_t.c diff --git a/isgood b/isgood index e4a27c6d62980b82661707e043a16194cfa399f2..318a0fc6c66b3af89152aab35b5b37191e794b8b 100644 GIT binary patch literal 61944 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 literal 43064 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 Bv?2fi diff --git a/src/test_t/bk000_test_t.c b/src/test_t/bk000_test_t.c new file mode 100644 index 0000000..8db8270 --- /dev/null +++ b/src/test_t/bk000_test_t.c @@ -0,0 +1,450 @@ +#include "src/test_t/test_t.h" + +/* +#define DEFAULT_K "\033[0m" //Resets the text to default color +#define GREEN_K "\033[0;32m" +#define RED_K "\033[0;31m" + + +#define HK_EQ "[==========]" +#define HK_TR "[----------]" +#define HK_RN "[RUN ]" +#define HK_DN "[ DONE]" +#define HK_OK "[ OK ]" +#define HK_FL "[ FAILED ]" +#define HK_PS "[ PASSED ]" + +*/ + +#ifndef SECOND + #define SECOND 0 +#endif +#ifndef NANOSECOND + #define NANOSECOND 0 +#endif + + + +#ifndef PARALLEL + #define PARALLEL 1 + #define LOCK(mut) + #define UNLOCK(mut) +#else /*PARALLEL defined*/ + #define LOCK(mutex_var) pthread_mutex_lock(&mutex_var); + #define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var); +#endif + + + +#define INCREMENT(variable)\ + LOCK(mut_##variable); \ + ++variable;\ + UNLOCK(mut_##variable); + + +pthread_mutex_t mut_count_pass_global; +pthread_mutex_t mut_count_pass_local; +pthread_mutex_t mut_count_fail_global; +pthread_mutex_t mut_count_fail_local; + + + +struct failed_lists{ + char *name; + struct failed_lists *next; +} *failed_l = NULL; + +void append_failed_list(const char *name_failed){ + static struct failed_lists *failed_static = NULL; + if(failed_static == NULL){ + failed_l = malloc(sizeof(struct failed_lists)); + failed_l->name = malloc(strlen(name_failed)); + strcpy(failed_l->name, name_failed); + failed_l->next = NULL; + failed_static = failed_l; + } + else{ + struct failed_lists *tmp = malloc(sizeof(struct failed_lists)); + tmp->name = malloc(strlen(name_failed)); + strcpy(tmp->name, name_failed); + tmp->next = NULL; + failed_static->next = tmp; + failed_static = tmp; + } +} + + +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start){ + return (time_stop.tv_sec - time_start.tv_sec) + 1.0e-9 * (time_stop.tv_nsec - time_start.tv_nsec); +} + +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start){ + return 1.0e3 * (time_stop.tv_sec - time_start.tv_sec) + 1.0e-3 * (time_stop.tv_nsec - time_start.tv_nsec); +} + +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start){ + return 1.0e9 * (time_stop.tv_sec - time_start.tv_sec) + (time_stop.tv_nsec - time_start.tv_nsec); +} + + +size_t count_tests = 0; + +size_t count_pass_global = 0; +size_t count_pass_local = 0; + +size_t count_fail_global = 0; +size_t count_fail_local = 0; + + +struct func *f_beging=NULL; + +/* + * Tname format name is TEST_name_f____NUM, we extract NUM here + * to have hash_table of the count when parallel test! + */ +size_t extract_num_test__f(char *name_f){ + size_t len = strlen(name_f); + size_t val = 0, p = 1; + for(size_t i= len-1; i>=0; --i){ + if(name_f[i]=='_') break; + else if(name_f[i] >= '0' && name_f[i] <= '9'){ + val += p * (name_f[i]-'0'); + } + } + return val; +} + + +#define EXPECTED_EXPECT_F(expect, not_expect) \ +bool expected_##expect##_f(bool val){ \ + if(val == expect) { \ + INCREMENT(count_pass_local); /*++count_pass_local*/ \ + return true; \ + }else { \ + INCREMENT(count_fail_local); /*++count_fail_local*/ \ + return false; \ + } \ +} + +EXPECTED_EXPECT_F(true,false) +EXPECTED_EXPECT_F(false,true) + +#define EXPECTED_EQ_TYPE(type) \ +bool expected_eq_##type(type var1, type var2){ \ + if(COMPARE_N_##type(&var1, &var2) == 0){ \ + INCREMENT(count_pass_local); /*++count_pass_local*/ \ + return true; \ + }else { \ + INCREMENT(count_fail_local); /*++count_fail_local*/ \ + return false; \ + } \ +} + + +EXPECTED_EQ_TYPE(TYPE_CHAR) +EXPECTED_EQ_TYPE(TYPE_U_CHAR) +EXPECTED_EQ_TYPE(TYPE_INT) +EXPECTED_EQ_TYPE(TYPE_U_INT) +EXPECTED_EQ_TYPE(TYPE_L_INT) +EXPECTED_EQ_TYPE(TYPE_U_L_INT) +EXPECTED_EQ_TYPE(TYPE_SIZE_T) +EXPECTED_EQ_TYPE(TYPE_FLOAT) +EXPECTED_EQ_TYPE(TYPE_DOUBLE) +EXPECTED_EQ_TYPE(TYPE_L_DOUBLE) +EXPECTED_EQ_TYPE(TYPE_STRING) + + + +void +append_func(void (*run)(void), char *name){ + static struct func *f_static = NULL; + if(f_beging == NULL){ + f_beging = malloc(sizeof(struct func)); + f_static = f_beging; + f_static->name = malloc(strlen(name)); + strcpy(f_static->name,name); + f_static->run = run; + f_static->next = NULL; + } + else{ + struct func *tmp = malloc(sizeof(struct func)); + tmp->run = run; + tmp->name = malloc(strlen(name)); + strcpy(tmp->name,name); + tmp->next = NULL; + f_static->next = tmp; + f_static = tmp; + } + ++count_tests; +} + +void begin_execute_func(char *fun_ame, struct timespec *start_t){ + clock_gettime(CLOCK_REALTIME, start_t); + PRINT_HK_C(GREEN_K,HK_RN," %s\n", fun_ame); + count_pass_local = 0; + count_fail_local = 0; +} + +#define PRINT_TIMESTAMP_STAT(color)\ + if(SECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf s)\n\n",count_pass_local,fun_ame, diff_timespec_seconds(end_t, start_t));\ + else if(NANOSECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%ld ns)\n\n",count_pass_local,fun_ame, diff_timespec_nanoseconds(end_t, start_t));\ + else PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf ms)\n\n",count_pass_local,fun_ame, diff_timespec_milliseconds(end_t, start_t)); + +void end_execute_func(char *fun_ame, struct timespec start_t){ + struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); + if(count_fail_local){ + INCREMENT(count_fail_global); /*++count_fail_global*/ + append_failed_list(fun_ame); + PRINT_HK_C(RED_K, HK_FL, " %lu tests failed from %s\n",count_fail_local,fun_ame); + PRINT_TIMESTAMP_STAT(RED_K); + } + else + { + INCREMENT(count_pass_global); /*++count_pass_global*/ + PRINT_TIMESTAMP_STAT(GREEN_K); + } +} + +void head_run(size_t nbtest, struct timespec *start_t){ + clock_gettime(CLOCK_REALTIME, start_t); + PRINT_HK_C(GREEN_K, HK_EQ," Running %lu tests.\n",nbtest); +} + +void list_failed_test(struct failed_lists *failed_lst){ + PRINT_HK_C(RED_K, HK_FL," %s\n",failed_lst->name); + if(failed_lst->next) list_failed_test(failed_lst->next); +} + + +void +stat_end_run(size_t ntst, struct timespec start_t){ + struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); + + if(SECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%lf s total)\n",ntst, diff_timespec_seconds(end_t, start_t)); + else if(NANOSECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%ld ns total)\n",ntst, diff_timespec_nanoseconds(end_t, start_t)); + else PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%lf ms total)\n",ntst, diff_timespec_milliseconds(end_t, start_t)); + + PRINT_HK_C(GREEN_K, HK_PS," %lu tests\n", count_pass_global); + if(failed_l != NULL){ + PRINT_HK_C(RED_K, HK_FL," %lu tests, listed below:\n",count_fail_global); + list_failed_test(failed_l); + } +} + +bool is_in_array(size_t *array, size_t sz, size_t num){ + bool found = false; + for(size_t i = 0; i < sz; ++i){ + if(array[i] == num){ + found = true; + break; + } + } + return found; +} + +void execute_all(struct func *fun){ + struct func *tmp = fun; + struct timespec start_t; + //PRINT_HK_C(GREEN_K, HK_EQ," Running %lu tests.\n",count_tests); + while(tmp){ + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + tmp = tmp->next; + } +} + +void execute_one_test(struct func *fun, size_t num){ + size_t cur = 0; + struct timespec start_t; + struct func *tmp = fun; + while(tmp){ + if(cur++ == num){ + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + } + tmp = tmp->next; + } +} + + +void execute_some_tests_ordered(struct func *fun, size_t cnt, size_t *array ) +{ + struct timespec start_t; + struct func *tmp = fun; + size_t cur = 0, index = 0; + + while(tmp){ + if((cur < cnt) && (index++ == array[cur])){ + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + ++cur; + } + tmp = tmp->next; + } +} + +void +run_some_tests(size_t cnt, ...) +{ + struct timespec start_t; + head_run(cnt, &start_t); + va_list args; + va_start(args, cnt); + for(size_t i=0; i < cnt; ++i){ + execute_one_test(f_beging, va_arg(args, size_t)); + } + va_end(args); + stat_end_run(cnt, start_t); +} + +void +run_some_tests_ordered(size_t cnt, ... ) +{ + struct timespec start_t; + head_run(cnt, &start_t); + va_list args; + va_start(args, cnt); + size_t *array=malloc(cnt*sizeof(size_t)); + for(size_t i=0; i < cnt; ++i){ + array[i] = va_arg(args, size_t); + } + + execute_some_tests_ordered(f_beging, cnt, array); + va_end(args); + stat_end_run(cnt, start_t); +} + + + + +void execute_all_tests_exept(struct func *fun, size_t cnt, size_t *array ) +{ + struct timespec start_t; + struct func *tmp = fun; + size_t cur = 0; + while(tmp){ + if(!is_in_array(array, cnt, cur++)){ + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + } + tmp = tmp->next; + } +} + +void +run_all_tests_exept(size_t cnt, ... ) +{ + struct timespec start_t; + if(count_tests >= cnt) + head_run(count_tests - cnt, &start_t); + va_list args; + va_start(args, cnt); + size_t *array=malloc(cnt*sizeof(size_t)); + for(size_t i=0; i < cnt; ++i){ + array[i] = va_arg(args, size_t); + } + + execute_all_tests_exept(f_beging, cnt, array); + va_end(args); + if(count_tests >= cnt) + stat_end_run(count_tests - cnt, start_t); +} + + +void +run_all_tests() +{ + struct timespec start_t; + head_run(count_tests, &start_t); + execute_all(f_beging); + stat_end_run(count_tests, start_t); +} + +/* + * + */ + + +void execute_div_test(struct func *fun, size_t num){ + size_t cur = 0; + struct timespec start_t; + struct func *tmp = fun; + while(tmp){ + if(cur %PARALLEL == num){ + PRINT_DEBUG("thread N° %ld, cur = %ld , cur%PARA = %ld , funcname = %s \n", num,cur, cur%PARALLEL, tmp->name); + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + } + tmp = tmp->next; + ++cur; + } +} + +void* +run_all_div_tests(void *id) +{ + size_t id_th=*(size_t*)id; + struct timespec start_t; + head_run(count_tests/PARALLEL, &start_t); + execute_div_test(f_beging, id_th); + stat_end_run(count_tests/PARALLEL, start_t); +} + +void run_parallel_tests() +{ + pthread_mutex_init(&mut_count_pass_global, NULL); + pthread_mutex_init(&mut_count_pass_local, NULL); + pthread_mutex_init(&mut_count_fail_global, NULL); + pthread_mutex_init(&mut_count_fail_local, NULL); + + pthread_t *thrd = malloc(PARALLEL * sizeof(pthread_t)); + size_t *id_th = malloc( PARALLEL * sizeof(size_t)); + + for(size_t i = 0; i < PARALLEL; ++i){ + id_th[i]=i; + pthread_create(&thrd[i], NULL, run_all_div_tests, (void*)&id_th[i]); + } + + for(size_t i=0; inext; + free(ttmp); + } +} +/* + * to purge func list! + * optionnal but good practice + */ +void +purge_tests() +{ + struct func *tmp = f_beging; + clear_all_func(&tmp); + PRINT_DEBUG("%s\n","purge done"); +} + diff --git a/src/test_t/is_good.c b/src/test_t/is_good.c index 703ba0a..27e7c64 100644 --- a/src/test_t/is_good.c +++ b/src/test_t/is_good.c @@ -1,6 +1,8 @@ #include #include #include + +// for sleep ! #ifdef __linux__ #include #elif _WIN32 @@ -89,24 +91,37 @@ TEST(expect){ int a = 5; int b = 6; EXPECT_EQ(a,b); + //SKIP(); + SKIP("on skip eq string\n"); EXPECT_EQ_TYPE_STRING("hello","hello"); float f1 = 1.00019999, f2=1.00019999; EXPECT_EQ_TYPE_FLOAT(f1,f2); - //EXPECT_EQ_TYPE_FLOAT(f1, 1.0001); } -//END_TEST(size_permutation) +TEST(){ + printf("no test, only print\n"); +} -//INIT() +TEST(){ + printf("no test, only print\n"); +} +TEST(){ + printf("no test, only print\n"); +} + + +TEST(){ + printf("no test, only print\n"); +} int main(){ - //p_fonction_l=malloc(sizeof(p_fonction_l)); - //init_test(); - run_all_tests(); + //run_all_tests(); + run_all_tests_parallel(5); + //purge_tests(); //run_some_tests(8, 1, 2, 2, 3, 3, 0, 4, 1); //run_some_tests(8, 5, 7, 1, 1, 1, 1, 1, 1); //run_some_tests_one_by_one(3, 1, 2, 2); diff --git a/src/test_t/test_t.c b/src/test_t/test_t.c index 87bb88d..a1fb10e 100644 --- a/src/test_t/test_t.c +++ b/src/test_t/test_t.c @@ -1,6 +1,6 @@ #include "src/test_t/test_t.h" - +/* #define DEFAULT_K "\033[0m" //Resets the text to default color #define GREEN_K "\033[0;32m" #define RED_K "\033[0;31m" @@ -14,7 +14,11 @@ #define HK_FL "[ FAILED ]" #define HK_PS "[ PASSED ]" +*/ +/* + * by default display in millisecond + */ #ifndef SECOND #define SECOND 0 #endif @@ -23,116 +27,254 @@ #endif +#if 0 +#ifndef PARALLEL + #define PARALLEL 1 + #define LOCK(mut) + #define UNLOCK(mut) +#else /*PARALLEL defined*/ + #define LOCK(mutex_var) pthread_mutex_lock(&mutex_var); + #define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var); +#endif +#endif /* 0 */ + + #define LOCK(mutex_var) pthread_mutex_lock(&mutex_var); + #define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var); + +#define INCREMENT(variable)\ + do{\ + if(is_parallel){\ + LOCK(mut_##variable); \ + ++variable;\ + UNLOCK(mut_##variable);\ + }\ + else ++variable;\ + }while(0); + -//#define INCR_PASS_CNT ++count_passed_local; -//#define INCR_FAIL_CNT ++count_failed_local; /* -#define INCR_PASS_CNT ++count_passed; ++count_passed_local; -#define INCR_FAIL_CNT ++count_failed; ++count_failed_local; -*/ + * struct to store tests failed + */ + struct failed_lists{ char *name; struct failed_lists *next; -} *failed_l = NULL; +}; -void append_failed_list(const char *name_failed){ - static struct failed_lists *failed_static = NULL; - if(failed_static == NULL){ - failed_l = malloc(sizeof(struct failed_lists)); - failed_l->name = malloc(strlen(name_failed)); - strcpy(failed_l->name, name_failed); - failed_l->next = NULL; - failed_static = failed_l; + +void append_failed_list(struct failed_lists **fn_failed_list ,const char *name_failed){ + + if(*fn_failed_list){ + + struct failed_lists *tmp_failed_l = *fn_failed_list, *rec_tmp; + + while(tmp_failed_l){ + rec_tmp = tmp_failed_l; + tmp_failed_l = tmp_failed_l->next; + } + tmp_failed_l = malloc(sizeof(struct failed_lists)); + tmp_failed_l->name = malloc(strlen(name_failed)); + strcpy(tmp_failed_l->name, name_failed); + tmp_failed_l->next = NULL; + rec_tmp->next = tmp_failed_l; + } else{ - struct failed_lists *tmp = malloc(sizeof(struct failed_lists)); - tmp->name = malloc(strlen(name_failed)); - strcpy(tmp->name, name_failed); - tmp->next = NULL; - failed_static->next = tmp; - failed_static = tmp; + *fn_failed_list = malloc(sizeof(struct failed_lists)); + (*fn_failed_list)->name = malloc(strlen(name_failed)); + strcpy((*fn_failed_list)->name, name_failed); + (*fn_failed_list)->next = NULL; } + +} + +/* + * print all TESTs failed + */ + +void list_failed_test(struct failed_lists *test_failed){ + struct failed_lists *failed_lst = test_failed; + while(failed_lst){ + PRINT_HK_C(RED_K, HK_FL," %s\n",failed_lst->name); + failed_lst = failed_lst->next; + //if(failed_lst->next) list_failed_test(failed_lst->next); + } + PRINT_HK_C(DEFAULT_K, HK_EQ,"%s\n",""); } -double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start){ - return (time_stop.tv_sec - time_start.tv_sec) + 1.0e-9 * (time_stop.tv_nsec - time_start.tv_nsec); -} -double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start){ - return 1.0e3 * (time_stop.tv_sec - time_start.tv_sec) + 1.0e-3 * (time_stop.tv_nsec - time_start.tv_nsec); -} -long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start){ - return 1.0e9 * (time_stop.tv_sec - time_start.tv_sec) + (time_stop.tv_nsec - time_start.tv_nsec); -} +/* + * global variables not exported + * only exist in test_t.c + */ +bool is_parallel = 0; size_t count_tests = 0; -size_t count_passed = 0; -size_t count_passed_local = 0; - -size_t count_failed = 0; -size_t count_failed_local = 0; +size_t count_pass_global = 0; +size_t count_pass_local = 0; -struct func f_beging; +size_t count_fail_global = 0; +size_t count_fail_local = 0; + +/* + * count in local test + * using array [count_test] global variable + */ +size_t *count_pass_test = NULL; +size_t *count_fail_test = NULL; + +/* + * number of threads + */ +size_t parallel_nb = 0; + +/* + * count on each thread [PARALLEL] + */ +size_t *count_pass_thread = NULL; +size_t *count_fail_thread = NULL; + +size_t *id_thread_self = NULL; + +/* + * the first instance of the func struct, + * it containis the first test + */ + +struct func *f_beging = NULL; +/* + * current test : used by parallel tests + */ +struct func *current_fn = NULL; + +/* + * list of all failed tests + */ +struct failed_lists *failed_l = NULL; -void vprintf_colored(char *color, char *format, ...) { - va_list args; - printf("%s",color); - va_start(args, format); - vprintf(format, args); - va_end(args); - printf(DEFAULT_K); +/* + * list of failed test on each thread + */ +struct failed_lists **thread_test_failed_l = NULL; + +/* + * mutex to add global failed test + */ +pthread_mutex_t mut_global_list_fail; +/* + * mutex to have current test to do + */ +pthread_mutex_t mut_current_test; + + +pthread_mutex_t mut_count_pass_global; +pthread_mutex_t mut_count_fail_global; +pthread_mutex_t mut_count_pass_local; +pthread_mutex_t mut_count_fail_local; +/* + * end of the global variables of test_t.c + */ + + +size_t id_of_thread_executed(size_t id_from_self){ + for(size_t i=0; i=0; --i){ + PRINT_DEBUG(" name_f[%ld] = %c\n",i,name_f[i]); + if(name_f[i] >= '0' && name_f[i] <= '9'){ + val += p * (name_f[i]-'0'); + p *= 10; + } + else break; + } + return val; } -#define EXPECTED_EXPECT_FROM(expect, not_expect) \ -bool expected_##expect##_f(bool val, const char * var_name, const char *func_name){ \ + +#define INCREMENT_EXPECT(expect,name)\ + do{\ + size_t num_test=extract_num_test__f(name);\ + ++count_## expect ##_test[num_test];\ + PRINT_DEBUG("INCREMENT cout_%s_test[%ld] = %ld\n",#expect, num_test,count_## expect ##_test[num_test]); \ + /*PRINT_DEBUG(" cout_%s_test[%ld] = %ld , count_%s_thread[%ld] = %ld\n",#expect, num_test,count_## expect ##_test[num_test]); \ + size_t num_thread= id_of_thread_executed(pthread_self());\ + ++count_## expect ##_thread[num_thread];\ + PRINT_DEBUG(" cout_%s_thread[%ld] = %ld , count_%s_thread[%ld] = %ld\n",#expect, num_thread,count_## expect ##_thread[num_thread]);*/ \ + }while(0); + + +#define EXPECTED_EXPECT_F(expect/*, not_expect*/) \ + \ +bool expected_##expect##_f(bool val){ \ if(val == expect) { \ - ++count_passed_local; /*INCR_PASS_CNT;*/ \ - printHK_color(GREEN_K,HK_TR," 1 test passed from %s \n\n",func_name); \ + INCREMENT(count_pass_local); /*++count_pass_local*/ \ return true; \ }else { \ - ++count_failed_local; /*INCR_FAIL_CNT;*/ \ - printHK_color(RED_K,HK_TR," 1 test failed from %s \n",func_name); \ - /*append_failed_list(func_name);*/ \ - printf("Value of: %s\nActual: %s\nExpected: %s\n\n", var_name, #not_expect, #expect); \ + INCREMENT(count_fail_local); /*++count_fail_local*/ \ return false; \ } \ -} +} \ +bool expected_##expect##_f_name(bool val, const char * name){ \ + if(val == expect) { \ + INCREMENT_EXPECT(pass,name);\ + return true; \ + }else { \ + INCREMENT_EXPECT(fail,name);\ + return false; \ + } \ +} \ -EXPECTED_EXPECT_FROM(true,false) -EXPECTED_EXPECT_FROM(false,true) -#define EXPECTED_EQ_TYPE(type)\ -bool expected_eq_##type(type var1, type var2, \ - const char *var1_name, const char *var2_name, const char *func_name){ \ - if(COMPARE_N_##type(&var1, &var2) == 0){ \ - ++count_passed_local; /*INCR_PASS_CNT;*/ \ - printHK_color(GREEN_K,HK_TR," 1 test passed from %s \n\n",func_name); \ - return true; \ - }else { \ - ++count_failed_local; /*INCR_FAIL_CNT;*/ \ - /*append_failed_list(func_name);*/ \ - printHK_color(RED_K,HK_TR," 1 test failed from %s \n",func_name); \ - printf("Expected equality of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n" \ - ,var1_name, type##_TO_STR(var1), var2_name, type##_TO_STR(var2)); \ - return false; \ - } \ +EXPECTED_EXPECT_F(true) +EXPECTED_EXPECT_F(false) +/* +EXPECTED_EXPECT_F(true,false) +EXPECTED_EXPECT_F(false,true) +*/ + +#define EXPECTED_EQ_TYPE(type) \ + \ +bool expected_eq_##type(type var1, type var2){ \ + if(COMPARE_N_##type(&var1, &var2) == 0){ \ + INCREMENT(count_pass_local); /*++count_pass_local*/ \ + return true; \ + }else { \ + INCREMENT(count_fail_local); /*++count_fail_local*/ \ + return false; \ + } \ +} \ +bool expected_eq_name_##type(type var1, type var2,const char * name){ \ + if(COMPARE_N_##type(&var1, &var2) == 0){ \ + INCREMENT_EXPECT(pass,name);\ + return true; \ + }else { \ + INCREMENT_EXPECT(fail,name);\ + return false; \ + } \ } + EXPECTED_EQ_TYPE(TYPE_CHAR) EXPECTED_EQ_TYPE(TYPE_U_CHAR) EXPECTED_EQ_TYPE(TYPE_INT) @@ -150,8 +292,9 @@ EXPECTED_EQ_TYPE(TYPE_STRING) void append_func(void (*run)(void), char *name){ static struct func *f_static = NULL; - if(f_static == NULL){ - f_static = &f_beging; + if(f_beging == NULL){ + f_beging = malloc(sizeof(struct func)); + f_static = f_beging; f_static->name = malloc(strlen(name)); strcpy(f_static->name,name); f_static->run = run; @@ -171,58 +314,55 @@ append_func(void (*run)(void), char *name){ void begin_execute_func(char *fun_ame, struct timespec *start_t){ clock_gettime(CLOCK_REALTIME, start_t); - vprintf_colored(GREEN_K,HK_RN); - printf(" %s\n", fun_ame); - count_passed_local = 0; - count_failed_local = 0; + PRINT_HK_C(GREEN_K,HK_RN," %s\n", fun_ame); + count_pass_local = 0; + count_fail_local = 0; } #define PRINT_TIMESTAMP_STAT(color)\ - if(SECOND) printHK_color(color,HK_DN," %lu tests passed from %s (%lf s)\n\n",count_passed_local,fun_ame, diff_timespec_seconds(end_t, start_t));\ - else if(NANOSECOND) printHK_color(color,HK_DN," %lu tests passed from %s (%ld ns)\n\n",count_passed_local,fun_ame, diff_timespec_nanoseconds(end_t, start_t));\ - else printHK_color(color,HK_DN," %lu tests passed from %s (%lf ms)\n\n",count_passed_local,fun_ame, diff_timespec_milliseconds(end_t, start_t)); + if(SECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf s)\n\n",count_pass_local,fun_ame, diff_timespec_seconds(end_t, start_t));\ + else if(NANOSECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%ld ns)\n\n",count_pass_local,fun_ame, diff_timespec_nanoseconds(end_t, start_t));\ + else PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf ms)\n\n",count_pass_local,fun_ame, diff_timespec_milliseconds(end_t, start_t)); void end_execute_func(char *fun_ame, struct timespec start_t){ struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); - if(count_failed_local){ - ++count_failed; - append_failed_list(fun_ame); - printHK_color(RED_K, HK_FL, " %lu tests failed from %s\n",count_failed_local,fun_ame); + if(count_fail_local){ + INCREMENT(count_fail_global); /*++count_fail_global*/ + append_failed_list(&failed_l, fun_ame); + PRINT_HK_C(RED_K, HK_FL, " %lu tests failed from %s\n",count_fail_local,fun_ame); PRINT_TIMESTAMP_STAT(RED_K); } else { - ++count_passed; + INCREMENT(count_pass_global); /*++count_pass_global*/ PRINT_TIMESTAMP_STAT(GREEN_K); } } - +/* + * print on the top of test + */ void head_run(size_t nbtest, struct timespec *start_t){ clock_gettime(CLOCK_REALTIME, start_t); - printHK_color(GREEN_K, HK_EQ," Running %lu tests.\n",nbtest); + PRINT_HK_C(GREEN_K, HK_EQ," Running %lu tests.\n",nbtest); } -void list_failed_test(struct failed_lists *failed_lst){ - printHK_color(RED_K, HK_FL," %s\n",failed_lst->name); - if(failed_lst->next) list_failed_test(failed_lst->next); -} - - +/* + * printing on the end of test + */ void stat_end_run(size_t ntst, struct timespec start_t){ struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); - if(SECOND) printHK_color(GREEN_K, HK_EQ," %lu tests ran. (%lf s total)\n",ntst, diff_timespec_seconds(end_t, start_t)); - else if(NANOSECOND) printHK_color(GREEN_K, HK_EQ," %lu tests ran. (%ld ns total)\n",ntst, diff_timespec_nanoseconds(end_t, start_t)); - else printHK_color(GREEN_K, HK_EQ," %lu tests ran. (%lf ms total)\n",ntst, diff_timespec_milliseconds(end_t, start_t)); + if(SECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%lf s total)\n",ntst, diff_timespec_seconds(end_t, start_t)); + else if(NANOSECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%ld ns total)\n",ntst, diff_timespec_nanoseconds(end_t, start_t)); + else PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran. (%lf ms total)\n",ntst, diff_timespec_milliseconds(end_t, start_t)); - printHK_color(GREEN_K, HK_PS," %lu tests\n", count_passed); + PRINT_HK_C(GREEN_K, HK_PS," %lu tests\n", count_pass_global); if(failed_l != NULL){ - printHK_color(RED_K, HK_FL," %lu tests, listed below:\n",count_failed); + PRINT_HK_C(RED_K, HK_FL," %lu tests, listed below:\n",count_fail_global); list_failed_test(failed_l); } } - bool is_in_array(size_t *array, size_t sz, size_t num){ bool found = false; for(size_t i = 0; i < sz; ++i){ @@ -237,7 +377,7 @@ bool is_in_array(size_t *array, size_t sz, size_t num){ void execute_all(struct func *fun){ struct func *tmp = fun; struct timespec start_t; - //printHK_color(GREEN_K, HK_EQ," Running %lu tests.\n",count_tests); + //PRINT_HK_C(GREEN_K, HK_EQ," Running %lu tests.\n",count_tests); while(tmp){ begin_execute_func(tmp->name, &start_t); tmp->run(); @@ -252,9 +392,9 @@ void execute_one_test(struct func *fun, size_t num){ struct func *tmp = fun; while(tmp){ if(cur++ == num){ - begin_execute_func(fun->name, &start_t); - fun->run(); - end_execute_func(fun->name, start_t); + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); } tmp = tmp->next; } @@ -286,7 +426,7 @@ run_some_tests(size_t cnt, ...) va_list args; va_start(args, cnt); for(size_t i=0; i < cnt; ++i){ - execute_one_test(&f_beging, va_arg(args, size_t)); + execute_one_test(f_beging, va_arg(args, size_t)); } va_end(args); stat_end_run(cnt, start_t); @@ -304,7 +444,7 @@ run_some_tests_ordered(size_t cnt, ... ) array[i] = va_arg(args, size_t); } - execute_some_tests_ordered(&f_beging, cnt, array); + execute_some_tests_ordered(f_beging, cnt, array); va_end(args); stat_end_run(cnt, start_t); } @@ -340,7 +480,7 @@ run_all_tests_exept(size_t cnt, ... ) array[i] = va_arg(args, size_t); } - execute_all_tests_exept(&f_beging, cnt, array); + execute_all_tests_exept(f_beging, cnt, array); va_end(args); if(count_tests >= cnt) stat_end_run(count_tests - cnt, start_t); @@ -352,18 +492,271 @@ run_all_tests() { struct timespec start_t; head_run(count_tests, &start_t); - execute_all(&f_beging); + execute_all(f_beging); stat_end_run(count_tests, start_t); } +#if 0 +/* + * parallel run tests / div section + */ +void execute_div_test(struct func *fun, size_t num){ + size_t cur = 0; + struct timespec start_t; + struct func *tmp = fun; + while(tmp){ + if(cur %PARALLEL == num){ + PRINT_DEBUG("thread [%ld], cur = %ld , cur mod PARA = %ld , funcname = %s \n", num,cur, cur%PARALLEL, tmp->name); + begin_execute_func(tmp->name, &start_t); + tmp->run(); + end_execute_func(tmp->name, start_t); + } + tmp = tmp->next; + ++cur; + } +} + +void* +run_all_div_tests(void *id) +{ + size_t id_th=*(size_t*)id; + struct timespec start_t; + head_run(count_tests/PARALLEL, &start_t); + execute_div_test(f_beging, id_th); + stat_end_run(count_tests/PARALLEL, start_t); +} +#endif +/* + * begin end parallel tests + */ +/* + * print on the top of all test (parallel case) + */ +void head_all_parallel_run(struct timespec *start_t){ + clock_gettime(CLOCK_REALTIME, start_t); + PRINT_HK_C(GREEN_K, HK_EQ," Running tests on %ld threads\n", parallel_nb); +} + +/* + * print on the top of test in parallel + */ +void head_parallel_run(struct timespec *start_t, size_t id_thrd){ + clock_gettime(CLOCK_REALTIME, start_t); + PRINT_HK_C(GREEN_K, HK_EQ," Running tests on thread[%ld] ========== ==threadID== %ld \n", id_thrd,pthread_self()); + count_pass_thread[id_thrd] = 0; + count_fail_thread[id_thrd] = 0; +} + +/* + * printing stat of each thread tests + */ +void +stat_end_parallel_run(size_t ntst, struct timespec start_t, size_t id_thrd){ + struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); + + if(SECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on thread[%ld]. (%lf s total) \n",ntst, id_thrd, diff_timespec_seconds(end_t, start_t)); + else if(NANOSECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on thread[%ld]. (%ld ns total)\n",ntst, id_thrd, diff_timespec_nanoseconds(end_t, start_t)); + else PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on thread[%ld]. (%lf ms total)\n",ntst, id_thrd, diff_timespec_milliseconds(end_t, start_t)); + + PRINT_HK_C(GREEN_K, HK_PS," %lu tests\n", count_pass_test[id_thrd]); + if(thread_test_failed_l[id_thrd] != NULL){ + PRINT_HK_C(RED_K, HK_FL," %lu tests, listed below:\n",count_fail_test[id_thrd]); + list_failed_test(thread_test_failed_l[id_thrd]); + } +} +/* + * stat of all tests on all threads + */ + +void +stat_end_all_parallel_run(size_t ntst, struct timespec start_t){ + struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); + + //PRINT_HK_C(DEFAULT_K, HK_EQ," %s: all parallel tests done\n\n",__FILE__); + + if(SECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on %ld threads. (%lf s total) \n",ntst, parallel_nb, diff_timespec_seconds(end_t, start_t)); + else if(NANOSECOND) PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on %ld threads. (%ld ns total)\n",ntst, parallel_nb, diff_timespec_nanoseconds(end_t, start_t)); + else PRINT_HK_C(GREEN_K, HK_EQ," %lu tests ran on %ld threads. (%lf ms total)\n",ntst, parallel_nb, diff_timespec_milliseconds(end_t, start_t)); + + PRINT_HK_C(GREEN_K, HK_PS," %lu tests\n", count_pass_global); + if(failed_l != NULL){ + PRINT_HK_C(RED_K, HK_FL," %lu tests, listed below:\n",count_fail_global); + list_failed_test(failed_l); + } +} + + + +void begin_execute_func_parallel(char *fun_ame, struct timespec *start_t, size_t id_thrd){ + clock_gettime(CLOCK_REALTIME, start_t); + PRINT_HK_C(GREEN_K,HK_RN," %s on thread[%ld]\n", fun_ame, id_thrd); +} + +#define PRINT_TIMESTAMP_STAT_PARALLEL(color)\ + if(SECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf s), on thread[%ld]\n\n",count_pass_test[num_test],fun_ame, diff_timespec_seconds(end_t, start_t),id_thrd);\ + else if(NANOSECOND) PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%ld ns), on thread[%ld]\n\n",count_pass_test[num_test],fun_ame, diff_timespec_nanoseconds(end_t, start_t),id_thrd);\ + else PRINT_HK_C(color,HK_DN," %lu tests passed from %s (%lf ms), on thread[%ld]\n\n",count_pass_test[num_test],fun_ame, diff_timespec_milliseconds(end_t, start_t),id_thrd); + +void end_execute_func_parallel(char *fun_ame, struct timespec start_t, size_t id_thrd){ + struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t); + size_t num_test = extract_num_test__f(fun_ame); + PRINT_DEBUG(" ... thread[%ld], count_fail_test[%ld] = %ld ... %s\n", id_thrd, num_test, count_fail_test[num_test],fun_ame); + if(count_fail_test[num_test]){ + INCREMENT(count_fail_global); /*++count_fail_global*/ + append_failed_list(&thread_test_failed_l[id_thrd], fun_ame); + ++count_fail_thread[id_thrd]; + LOCK(mut_global_list_fail); + append_failed_list(&failed_l, fun_ame); + UNLOCK(mut_global_list_fail); + PRINT_HK_C(RED_K, HK_FL, " %lu tests failed from %s on thread[%ld], %ld tests failed on thread[%ld]\n",count_fail_test[num_test],fun_ame, id_thrd,count_fail_thread[id_thrd],id_thrd); + PRINT_TIMESTAMP_STAT_PARALLEL(RED_K); + } + else + { + ++count_pass_thread[id_thrd]; + INCREMENT(count_pass_global); /*++count_pass_global*/ + PRINT_TIMESTAMP_STAT_PARALLEL(GREEN_K); + } +} + + +void execute_test_parallel(size_t id_thrd){ + + struct timespec start_t; + struct func *tmp; + + do{ + LOCK(mut_current_test); + tmp = current_fn; + if(tmp){ + current_fn = tmp->next; + UNLOCK(mut_current_test); + PRINT_DEBUG(" *** thread[%ld], func_name = %s *** \n", id_thrd, tmp->name); + begin_execute_func_parallel(tmp->name, &start_t, id_thrd); + tmp->run(); + end_execute_func_parallel(tmp->name, start_t, id_thrd); + } + else{ + UNLOCK(mut_current_test); + } + }while(tmp); +} + +void* +run_parallel_tests(void *id) +{ + size_t id_th=*(size_t*)id; + id_thread_self[id_th] = pthread_self(); + struct timespec start_t; + head_parallel_run(&start_t, id_th); + execute_test_parallel(id_th); + stat_end_parallel_run(count_fail_thread[id_th]+count_pass_thread[id_th], start_t, id_th); +} + +/* + * initialisation + */ +void +init_parallel_test_() +{ + is_parallel = 1; + count_pass_test = malloc(count_tests * sizeof(size_t)); + count_fail_test = malloc(count_tests * sizeof(size_t)); + for(size_t i=0; inext)); - free(*fun); - *fun = NULL; - } + struct func *tmp = *fun, *ttmp; + while(tmp != NULL){ + ttmp = tmp; + tmp = tmp->next; + free(ttmp); + } +} +/* + * to purge func list! + * optionnal but good practice + */ +__attribute__((destructor)) +void +purge_tests() +{ + struct func *tmp = f_beging; + clear_all_func(&tmp); + PRINT_DEBUG("%s\n","purge done"); } diff --git a/src/test_t/test_t.h b/src/test_t/test_t.h index d95a820..55191e1 100644 --- a/src/test_t/test_t.h +++ b/src/test_t/test_t.h @@ -6,39 +6,106 @@ #include #include //#include +#include +//#include #include "src/tools_t/tools_t.h" +#define DEFAULT_K "\033[0m" //Resets the text to default color +#define GREEN_K "\033[0;32m" +#define RED_K "\033[0;31m" + +#ifdef HK + #define HK_EQ "[==========]" + #define HK_TR "[----------]" + #define HK_RN "[RUN ]" + #define HK_DN "[ DONE]" + #define HK_OK "[ OK ]" + #define HK_FL "[ FAILED ]" + #define HK_PS "[ PASSED ]" + #define HK_SK "[ SKIP ]" +#else + #define HK_EQ "==========" + #define HK_TR "----------" + #define HK_RN "====== RUN" + #define HK_DN "===== DONE" + #define HK_OK "======= OK" + #define HK_FL "===== FAIL" + #define HK_PS "===== PASS" + #define HK_SK "===== SKIP" +#endif + +/* +// F_OUT file (stream) to log +#ifndef F_OUT + #define F_OUT stdout +#endif +*/ + +#ifndef NOT_COLORED + #define NOT_COLORED 0 +#endif + +#if 0 +#ifndef PARALLEL + #define PARALLEL 1 + #define LOCK(mut) + #define UNLOCK(mut) +#else /*PARALLEL defined*/ + #define LOCK(mutex_var) pthread_mutex_lock(&mutex_var); + #define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var); + #define is_parallel 1 +#endif +#endif + +#define LOCK(mutex_var) pthread_mutex_lock(&mutex_var); +#define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var); + + +/* + * print [ HK_NAME ] with color + */ +#define PRINT_HK_C(color,hk,format,...)\ + do{ if(!NOT_COLORED) fprintf(F_OUT, color hk DEFAULT_K format, __VA_ARGS__); \ + else fprintf(F_OUT, hk format, __VA_ARGS__); } while(0) \ + +/* + * to skip the bloc test function + */ +#define SKIP(msg)\ + PRINT_HK_C(GREEN_K, HK_SK," %s\n",#msg);\ + PRINT_LOC("%s\n\n"," Skiped"); return; + struct func { char *name; void (*run)(void); struct func *next; }; -//void begin_f(); -//struct func f_beging; - -void vprintf_colored(char *color, char * format, ...); +extern bool is_parallel; void run_all_tests(); void execute_all(struct func *fun); void append_func(void (*run)(void), char *name); -void clear_all_func(); +//__attribute__((destructor)) void purge_tests(); void run_some_tests(size_t cnt, ... ); void run_all_tests_exept(size_t cnt, ... ); void run_some_tests_ordered(size_t cnt, ... ); +void run_all_tests_parallel(size_t parallel); -bool expected_true_f(bool val, const char* var_name, const char * func_name); -bool expected_false_f(bool val, const char* var_name, const char * func_name); +bool expected_true_f(bool val); +bool expected_false_f(bool val); +bool expected_true_f_name(bool val, const char *name); +bool expected_false_f_name(bool val, const char *name); #define GEN_EXPECTED_EQ_TYPE_FUNC(type)\ - bool expected_eq_##type(type var1, type var2, \ - const char *var1_name, const char *var2_name, const char *func_name); \ + bool expected_eq_##type(type var1, type var2);\ + bool expected_eq_name_##type(type var1, type var2, const char *name); GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_CHAR) GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_U_CHAR) @@ -52,39 +119,108 @@ GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_DOUBLE) GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_L_DOUBLE) GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_STRING) -#define EXPECT_EQ_TYPE_CHAR(var1, var2) expected_eq_TYPE_CHAR(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_U_CHAR(var1, var2) expected_eq_TYPE_U_CHAR(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_INT(var1, var2) expected_eq_TYPE_INT(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_U_INT(var1, var2) expected_eq_TYPE_U_INT(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_L_INT(var1, var2) expected_eq_TYPE_L_INT(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) expected_eq_TYPE_U_L_INT(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) expected_eq_TYPE_SIZE_T(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_FLOAT(var1, var2) expected_eq_TYPE_FLOAT(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_DOUBLE(var1, var2) expected_eq_TYPE_DOUBLE(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_L_DOUBLE(var1, var2) expected_eq_TYPE_L_DOUBLE(var1, var2, #var1, #var2, __func__) ; -#define EXPECT_EQ_TYPE_STRING(var1, var2) expected_eq_TYPE_STRING(var1, var2, #var1, #var2, __func__) ; + /** + * is_assert : 0 for EXPECT and 1 for ASSERT + */ +#define HANDLE_EXPECT_ASSERT(type,var1,var2,is_assert) \ +do{ \ + if(is_parallel==0){\ + if(expected_eq_##type(var1, var2)){ \ + PRINT_HK_C(GREEN_K,HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nExpected equality of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(RED_K,HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }else { \ + if(expected_eq_name_##type(var1, var2, __func__)){ \ + PRINT_HK_C(GREEN_K,HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nExpected equality of these values:\n %s\n\tWhich is: %s\n %s\n\tWhich is: %s\n\n"\ + ,#var1, type##_TO_STR(var1), #var2, type##_TO_STR(var2)); \ + PRINT_HK_C(RED_K,HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ +}while(0); -#define EXPECT_EQ(var1, var2) expected_eq_TYPE_L_INT(var1, var2, #var1, #var2, __func__) ; + +// ============== EXPECT =================== + +#define EXPECT_EQ_TYPE_CHAR(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_CHAR,var1, var2, 0) +#define EXPECT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_CHAR,var1, var2, 0) +#define EXPECT_EQ_TYPE_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_INT,var1, var2, 0) +#define EXPECT_EQ_TYPE_U_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_INT,var1, var2, 0) +#define EXPECT_EQ_TYPE_L_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_INT,var1, var2, 0) +#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_L_INT,var1, var2, 0) +#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_SIZE_T,var1, var2, 0) +#define EXPECT_EQ_TYPE_FLOAT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_FLOAT,var1, var2, 0) +#define EXPECT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_DOUBLE,var1, var2, 0) +#define EXPECT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_DOUBLE,var1, var2, 0) +#define EXPECT_EQ_TYPE_STRING(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_STRING,var1, var2, 0) + +#define EXPECT_EQ(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_INT,var1, var2, 0) -#define ASSERT_EQ_TYPE_CHAR(var1, var2) do{ if(expected_eq_TYPE_CHAR(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_U_CHAR(var1, var2) do{ if(expected_eq_TYPE_U_CHAR(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_INT(var1, var2) do{ if(expected_eq_TYPE_INT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_U_INT(var1, var2) do{ if(expected_eq_TYPE_U_INT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_L_INT(var1, var2) do{ if(expected_eq_TYPE_L_INT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_U_L_INT(var1, var2) do{ if(expected_eq_TYPE_U_L_INT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_SIZE_T(var1, var2) do{ if(expected_eq_TYPE_SIZE_T(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_FLOAT(var1, var2) do{ if(expected_eq_TYPE_FLOAT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_DOUBLE(var1, var2) do{ if(expected_eq_TYPE_DOUBLE(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_L_DOUBLE(var1, var2) do{ if(expected_eq_TYPE_L_DOUBLE(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) -#define ASSERT_EQ_TYPE_STRING(var1, var2) do{ if(expected_eq_TYPE_STRING(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) +// ============== ASERT ===================== -#define ASSERT_EQ(var1, var2) do{ if(expected_eq_TYPE_L_INT(var1, var2, #var1, #var2, __func__) == false) return ;} while(0) +#define ASSERT_EQ_TYPE_CHAR(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_CHAR,var1, var2, 1) +#define ASSERT_EQ_TYPE_U_CHAR(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_CHAR,var1, var2, 1) +#define ASSERT_EQ_TYPE_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_INT,var1, var2, 1) +#define ASSERT_EQ_TYPE_U_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_INT,var1, var2, 1) +#define ASSERT_EQ_TYPE_L_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_INT,var1, var2, 1) +#define ASSERT_EQ_TYPE_U_L_INT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_U_L_INT,var1, var2, 1) +#define ASSERT_EQ_TYPE_SIZE_T(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_SIZE_T,var1, var2, 1) +#define ASSERT_EQ_TYPE_FLOAT(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_FLOAT,var1, var2, 1) +#define ASSERT_EQ_TYPE_DOUBLE(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_DOUBLE,var1, var2, 1) +#define ASSERT_EQ_TYPE_L_DOUBLE(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_DOUBLE,var1, var2, 1) +#define ASSERT_EQ_TYPE_STRING(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_STRING,var1, var2, 1) + +#define ASSERT_EQ(var1, var2) HANDLE_EXPECT_ASSERT(TYPE_L_INT,var1, var2, 1) + +/* + * ============== bool =================== + * + */ + +#define HANDLE_EXPECT_NOT_EXPECT_ASSERT(expect,not_expect,var1,is_assert) \ +do{ \ + if(is_parallel==0){\ + if(expected_##expect##_f(var1)){ \ + PRINT_HK_C(GREEN_K,HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\ + PRINT_HK_C(RED_K,HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ + else{\ + if(expected_##expect##_f_name(var1, __func__)){ \ + PRINT_HK_C(GREEN_K,HK_TR," 1 test passed from %s \n\n",__func__); \ + } \ + else{ \ + PRINT_LOC("Failure\nValue of: %s\nActual: %s\nExpected: %s\n\n", #var1, #not_expect, #expect);\ + PRINT_HK_C(RED_K,HK_TR," 1 test failed from %s \n",__func__); \ + if(is_assert) return; \ + } \ + }\ +}while(0); + + +#define EXPECT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 0) +#define EXPECT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 0) + +#define ASSERT_TRUE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(true, false, var1, 1) +#define ASSERT_FALSE(var1) HANDLE_EXPECT_NOT_EXPECT_ASSERT(false, true, var1, 1) #define CONCAT(x,y) x ## y -#define STRFY(x) # x +#define STRFY(x) # x #define test_label test @@ -97,26 +233,27 @@ GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_STRING) void CONCAT(test_##name_f##____,count)(void) #define FTEST__(count, name_f) \ - void CONCAT(name_f##___,count)(void); \ + void CONCAT(TEST_##name_f##____,count)(void); \ __attribute__((constructor)) \ void CONCAT(append_test_##name_f,count)(void){ \ - append_func(CONCAT(name_f##___,count),STRFY(name_f test count)); \ + append_func(CONCAT(TEST_##name_f##____,count),STRFY(TEST(name_f): test N° count )); \ } \ - void CONCAT(name_f##___,count)(void) + void CONCAT(TEST_##name_f##____,count)(void) -#define TEST(name_f)\ +//#define TEST(name_f)\ FTEST_(__COUNTER__,name_f) -//#define TEST(name_f) \ +#define TEST(name_f) \ FTEST__(__COUNTER__,name_f) +/* #define ASSERT_TRUE(val)\ - if(expected_true_f(val,#val,__func__) == false) return; + if(expected_true_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;} #define ASSERT_FALSE(val)\ - if(expected_false_f(val,#val,__func__) == false) return; - + if(expected_false_f(val,#val,__func__) == false) {error_print("%s\n\n","Failure"); return;} +*/ diff --git a/src/tools_t/tools_t.c b/src/tools_t/tools_t.c index 0630370..043af7b 100644 --- a/src/tools_t/tools_t.c +++ b/src/tools_t/tools_t.c @@ -58,7 +58,7 @@ TYPE_STRING TYPE_STRING_TO_STR(TYPE_STRING var){ #define GENERATE_FUNCTION_NUMERIC(type)\ int COMPARE_N_##type(const void *a, const void *b){ \ type diff = (*(type*)a - *(type*)b)*PRECISION_##type; \ - debug_print(" diff = %s a=%s b=%s\n",type##_TO_STR(diff),type##_TO_STR(*(type*)a), type##_TO_STR(*(type*)b));\ + PRINT_DEBUG(" diff = %s a=%s b=%s \n",type##_TO_STR(diff),type##_TO_STR(*(type*)a), type##_TO_STR(*(type*)b));\ if ((diff < 1) && (diff > -1) ) return 0; \ return diff; \ } \ @@ -135,5 +135,20 @@ GENERATE_FUNCTION_ALL(TYPE_L_DOUBLE) GENERATE_FUNCTION_ALL(TYPE_STRING) +/* + * time section + */ + +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start){ + return (time_stop.tv_sec - time_start.tv_sec) + 1.0e-9 * (time_stop.tv_nsec - time_start.tv_nsec); +} + +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start){ + return 1.0e3 * (time_stop.tv_sec - time_start.tv_sec) + 1.0e-3 * (time_stop.tv_nsec - time_start.tv_nsec); +} + +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start){ + return 1.0e9 * (time_stop.tv_sec - time_start.tv_sec) + (time_stop.tv_nsec - time_start.tv_nsec); +} diff --git a/src/tools_t/tools_t.h b/src/tools_t/tools_t.h index 05fb420..c7397e7 100644 --- a/src/tools_t/tools_t.h +++ b/src/tools_t/tools_t.h @@ -12,6 +12,15 @@ #define DEBUG 0 #endif +// F_OUT file (stream) to log +#ifndef F_OUT + #define F_OUT stdout +#endif +// F_ERR file (stream) to log +#ifndef F_ERR + #define F_ERR stderr +#endif + /* #ifndef SECOND #define SECOND 0 @@ -29,6 +38,23 @@ long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_s do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, __VA_ARGS__); } while (0) +#define PRINT_DEBUG(fmt, ...) \ + do { if (DEBUG) fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); } while (0) + + +#define error_print(fmt, ...) \ + fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_ERROR(fmt, ...) \ + fprintf(F_ERR, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + +#define PRINT_LOC(fmt, ...) \ + fprintf(F_OUT, "%s:%d:%s(): " fmt, __FILE__, \ + __LINE__, __func__, __VA_ARGS__); + #define TYPE_CHAR char @@ -71,5 +97,16 @@ GENERATE_ALL(TYPE_DOUBLE) GENERATE_ALL(TYPE_L_DOUBLE) GENERATE_ALL(TYPE_STRING) + +/* + * time calucl + */ +double diff_timespec_seconds(struct timespec time_stop, struct timespec time_start); + +double diff_timespec_milliseconds(struct timespec time_stop, struct timespec time_start); + +long diff_timespec_nanoseconds(struct timespec time_stop, struct timespec time_start); + + #endif /*__TOOLS_T_C_H__*/