debug parallel tests, some change in the legacy tests
This commit is contained in:
@@ -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; i<PARALLEL; ++i){
|
||||||
|
pthread_join(thrd[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(id_th);
|
||||||
|
free(thrd);
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&mut_count_pass_global);
|
||||||
|
pthread_mutex_destroy(&mut_count_pass_local);
|
||||||
|
pthread_mutex_destroy(&mut_count_fail_global);
|
||||||
|
pthread_mutex_destroy(&mut_count_fail_local);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
clear_all_func(struct func **fun)
|
||||||
|
{
|
||||||
|
struct func *tmp = *fun, *ttmp;
|
||||||
|
while(tmp != NULL){
|
||||||
|
ttmp = tmp;
|
||||||
|
tmp = tmp->next;
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
+21
-6
@@ -1,6 +1,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
// for sleep !
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#elif _WIN32
|
#elif _WIN32
|
||||||
@@ -89,24 +91,37 @@ TEST(expect){
|
|||||||
int a = 5;
|
int a = 5;
|
||||||
int b = 6;
|
int b = 6;
|
||||||
EXPECT_EQ(a,b);
|
EXPECT_EQ(a,b);
|
||||||
|
//SKIP();
|
||||||
|
SKIP("on skip eq string\n");
|
||||||
EXPECT_EQ_TYPE_STRING("hello","hello");
|
EXPECT_EQ_TYPE_STRING("hello","hello");
|
||||||
float f1 = 1.00019999, f2=1.00019999;
|
float f1 = 1.00019999, f2=1.00019999;
|
||||||
EXPECT_EQ_TYPE_FLOAT(f1,f2);
|
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(){
|
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, 1, 2, 2, 3, 3, 0, 4, 1);
|
||||||
//run_some_tests(8, 5, 7, 1, 1, 1, 1, 1, 1);
|
//run_some_tests(8, 5, 7, 1, 1, 1, 1, 1, 1);
|
||||||
//run_some_tests_one_by_one(3, 1, 2, 2);
|
//run_some_tests_one_by_one(3, 1, 2, 2);
|
||||||
|
|||||||
+502
-109
@@ -1,6 +1,6 @@
|
|||||||
#include "src/test_t/test_t.h"
|
#include "src/test_t/test_t.h"
|
||||||
|
|
||||||
|
/*
|
||||||
#define DEFAULT_K "\033[0m" //Resets the text to default color
|
#define DEFAULT_K "\033[0m" //Resets the text to default color
|
||||||
#define GREEN_K "\033[0;32m"
|
#define GREEN_K "\033[0;32m"
|
||||||
#define RED_K "\033[0;31m"
|
#define RED_K "\033[0;31m"
|
||||||
@@ -14,7 +14,11 @@
|
|||||||
#define HK_FL "[ FAILED ]"
|
#define HK_FL "[ FAILED ]"
|
||||||
#define HK_PS "[ PASSED ]"
|
#define HK_PS "[ PASSED ]"
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* by default display in millisecond
|
||||||
|
*/
|
||||||
#ifndef SECOND
|
#ifndef SECOND
|
||||||
#define SECOND 0
|
#define SECOND 0
|
||||||
#endif
|
#endif
|
||||||
@@ -23,116 +27,254 @@
|
|||||||
#endif
|
#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;
|
* struct to store tests failed
|
||||||
#define INCR_FAIL_CNT ++count_failed; ++count_failed_local;
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct failed_lists{
|
struct failed_lists{
|
||||||
char *name;
|
char *name;
|
||||||
struct failed_lists *next;
|
struct failed_lists *next;
|
||||||
} *failed_l = NULL;
|
};
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
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{
|
else{
|
||||||
struct failed_lists *tmp = malloc(sizeof(struct failed_lists));
|
*fn_failed_list = malloc(sizeof(struct failed_lists));
|
||||||
tmp->name = malloc(strlen(name_failed));
|
(*fn_failed_list)->name = malloc(strlen(name_failed));
|
||||||
strcpy(tmp->name, name_failed);
|
strcpy((*fn_failed_list)->name, name_failed);
|
||||||
tmp->next = NULL;
|
(*fn_failed_list)->next = NULL;
|
||||||
failed_static->next = tmp;
|
|
||||||
failed_static = tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_tests = 0;
|
||||||
|
|
||||||
size_t count_passed = 0;
|
size_t count_pass_global = 0;
|
||||||
size_t count_passed_local = 0;
|
size_t count_pass_local = 0;
|
||||||
|
|
||||||
size_t count_failed = 0;
|
|
||||||
size_t count_failed_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;
|
* list of failed test on each thread
|
||||||
printf("%s",color);
|
*/
|
||||||
va_start(args, format);
|
struct failed_lists **thread_test_failed_l = NULL;
|
||||||
vprintf(format, args);
|
|
||||||
va_end(args);
|
/*
|
||||||
printf(DEFAULT_K);
|
* 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<parallel_nb; ++i){
|
||||||
|
if(id_thread_self[i] == id_from_self)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
PRINT_ERROR("something wrong on %s\n",__func__);
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void printHK_color(char *color, char *HK, char * format, ...){
|
|
||||||
printf("%s%s%s",color, HK, DEFAULT_K);
|
/*
|
||||||
va_list args;
|
* format name of TEST(name_f) is: TEST_name_f____NUM, we extract NUM here
|
||||||
va_start(args, format);
|
* to have hash_table of the count when parallel test!
|
||||||
vprintf(format, args);
|
*/
|
||||||
va_end(args);
|
size_t extract_num_test__f(const char *name_f){
|
||||||
|
size_t len = strlen(name_f);
|
||||||
|
size_t val = 0, p = 1;
|
||||||
|
for(size_t i= len-1; 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) { \
|
if(val == expect) { \
|
||||||
++count_passed_local; /*INCR_PASS_CNT;*/ \
|
INCREMENT(count_pass_local); /*++count_pass_local*/ \
|
||||||
printHK_color(GREEN_K,HK_TR," 1 test passed from %s \n\n",func_name); \
|
|
||||||
return true; \
|
return true; \
|
||||||
}else { \
|
}else { \
|
||||||
++count_failed_local; /*INCR_FAIL_CNT;*/ \
|
INCREMENT(count_fail_local); /*++count_fail_local*/ \
|
||||||
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); \
|
|
||||||
return false; \
|
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)
|
EXPECTED_EXPECT_F(true)
|
||||||
|
EXPECTED_EXPECT_F(false)
|
||||||
|
/*
|
||||||
|
EXPECTED_EXPECT_F(true,false)
|
||||||
|
EXPECTED_EXPECT_F(false,true)
|
||||||
|
*/
|
||||||
|
|
||||||
#define EXPECTED_EQ_TYPE(type) \
|
#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){ \
|
bool expected_eq_##type(type var1, type var2){ \
|
||||||
if(COMPARE_N_##type(&var1, &var2) == 0){ \
|
if(COMPARE_N_##type(&var1, &var2) == 0){ \
|
||||||
++count_passed_local; /*INCR_PASS_CNT;*/ \
|
INCREMENT(count_pass_local); /*++count_pass_local*/ \
|
||||||
printHK_color(GREEN_K,HK_TR," 1 test passed from %s \n\n",func_name); \
|
|
||||||
return true; \
|
return true; \
|
||||||
}else { \
|
}else { \
|
||||||
++count_failed_local; /*INCR_FAIL_CNT;*/ \
|
INCREMENT(count_fail_local); /*++count_fail_local*/ \
|
||||||
/*append_failed_list(func_name);*/ \
|
return false; \
|
||||||
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)); \
|
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; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
EXPECTED_EQ_TYPE(TYPE_CHAR)
|
EXPECTED_EQ_TYPE(TYPE_CHAR)
|
||||||
EXPECTED_EQ_TYPE(TYPE_U_CHAR)
|
EXPECTED_EQ_TYPE(TYPE_U_CHAR)
|
||||||
EXPECTED_EQ_TYPE(TYPE_INT)
|
EXPECTED_EQ_TYPE(TYPE_INT)
|
||||||
@@ -150,8 +292,9 @@ EXPECTED_EQ_TYPE(TYPE_STRING)
|
|||||||
void
|
void
|
||||||
append_func(void (*run)(void), char *name){
|
append_func(void (*run)(void), char *name){
|
||||||
static struct func *f_static = NULL;
|
static struct func *f_static = NULL;
|
||||||
if(f_static == NULL){
|
if(f_beging == NULL){
|
||||||
f_static = &f_beging;
|
f_beging = malloc(sizeof(struct func));
|
||||||
|
f_static = f_beging;
|
||||||
f_static->name = malloc(strlen(name));
|
f_static->name = malloc(strlen(name));
|
||||||
strcpy(f_static->name,name);
|
strcpy(f_static->name,name);
|
||||||
f_static->run = run;
|
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){
|
void begin_execute_func(char *fun_ame, struct timespec *start_t){
|
||||||
clock_gettime(CLOCK_REALTIME, start_t);
|
clock_gettime(CLOCK_REALTIME, start_t);
|
||||||
vprintf_colored(GREEN_K,HK_RN);
|
PRINT_HK_C(GREEN_K,HK_RN," %s\n", fun_ame);
|
||||||
printf(" %s\n", fun_ame);
|
count_pass_local = 0;
|
||||||
count_passed_local = 0;
|
count_fail_local = 0;
|
||||||
count_failed_local = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PRINT_TIMESTAMP_STAT(color)\
|
#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));\
|
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) 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 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 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));
|
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){
|
void end_execute_func(char *fun_ame, struct timespec start_t){
|
||||||
struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t);
|
struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_t);
|
||||||
if(count_failed_local){
|
if(count_fail_local){
|
||||||
++count_failed;
|
INCREMENT(count_fail_global); /*++count_fail_global*/
|
||||||
append_failed_list(fun_ame);
|
append_failed_list(&failed_l, fun_ame);
|
||||||
printHK_color(RED_K, HK_FL, " %lu tests failed from %s\n",count_failed_local,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);
|
PRINT_TIMESTAMP_STAT(RED_K);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
++count_passed;
|
INCREMENT(count_pass_global); /*++count_pass_global*/
|
||||||
PRINT_TIMESTAMP_STAT(GREEN_K);
|
PRINT_TIMESTAMP_STAT(GREEN_K);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* print on the top of test
|
||||||
|
*/
|
||||||
void head_run(size_t nbtest, struct timespec *start_t){
|
void head_run(size_t nbtest, struct timespec *start_t){
|
||||||
clock_gettime(CLOCK_REALTIME, 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);
|
* printing on the end of test
|
||||||
if(failed_lst->next) list_failed_test(failed_lst->next);
|
*/
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
stat_end_run(size_t ntst, struct timespec start_t){
|
stat_end_run(size_t ntst, struct timespec start_t){
|
||||||
struct timespec end_t; clock_gettime(CLOCK_REALTIME, &end_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));
|
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) printHK_color(GREEN_K, HK_EQ," %lu tests ran. (%ld ns total)\n",ntst, diff_timespec_nanoseconds(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 printHK_color(GREEN_K, HK_EQ," %lu tests ran. (%lf ms total)\n",ntst, diff_timespec_milliseconds(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){
|
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);
|
list_failed_test(failed_l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_in_array(size_t *array, size_t sz, size_t num){
|
bool is_in_array(size_t *array, size_t sz, size_t num){
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for(size_t i = 0; i < sz; ++i){
|
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){
|
void execute_all(struct func *fun){
|
||||||
struct func *tmp = fun;
|
struct func *tmp = fun;
|
||||||
struct timespec start_t;
|
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){
|
while(tmp){
|
||||||
begin_execute_func(tmp->name, &start_t);
|
begin_execute_func(tmp->name, &start_t);
|
||||||
tmp->run();
|
tmp->run();
|
||||||
@@ -252,9 +392,9 @@ void execute_one_test(struct func *fun, size_t num){
|
|||||||
struct func *tmp = fun;
|
struct func *tmp = fun;
|
||||||
while(tmp){
|
while(tmp){
|
||||||
if(cur++ == num){
|
if(cur++ == num){
|
||||||
begin_execute_func(fun->name, &start_t);
|
begin_execute_func(tmp->name, &start_t);
|
||||||
fun->run();
|
tmp->run();
|
||||||
end_execute_func(fun->name, start_t);
|
end_execute_func(tmp->name, start_t);
|
||||||
}
|
}
|
||||||
tmp = tmp->next;
|
tmp = tmp->next;
|
||||||
}
|
}
|
||||||
@@ -286,7 +426,7 @@ run_some_tests(size_t cnt, ...)
|
|||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, cnt);
|
va_start(args, cnt);
|
||||||
for(size_t i=0; i < cnt; ++i){
|
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);
|
va_end(args);
|
||||||
stat_end_run(cnt, start_t);
|
stat_end_run(cnt, start_t);
|
||||||
@@ -304,7 +444,7 @@ run_some_tests_ordered(size_t cnt, ... )
|
|||||||
array[i] = va_arg(args, size_t);
|
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);
|
va_end(args);
|
||||||
stat_end_run(cnt, start_t);
|
stat_end_run(cnt, start_t);
|
||||||
}
|
}
|
||||||
@@ -340,7 +480,7 @@ run_all_tests_exept(size_t cnt, ... )
|
|||||||
array[i] = va_arg(args, size_t);
|
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);
|
va_end(args);
|
||||||
if(count_tests >= cnt)
|
if(count_tests >= cnt)
|
||||||
stat_end_run(count_tests - cnt, start_t);
|
stat_end_run(count_tests - cnt, start_t);
|
||||||
@@ -352,18 +492,271 @@ run_all_tests()
|
|||||||
{
|
{
|
||||||
struct timespec start_t;
|
struct timespec start_t;
|
||||||
head_run(count_tests, &start_t);
|
head_run(count_tests, &start_t);
|
||||||
execute_all(&f_beging);
|
execute_all(f_beging);
|
||||||
stat_end_run(count_tests, start_t);
|
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; i<count_tests; ++i){
|
||||||
|
count_pass_test[i]=0;
|
||||||
|
count_fail_test[i]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
thread_test_failed_l = malloc(parallel_nb * sizeof(struct failed_lists*));
|
||||||
|
count_pass_thread = malloc(parallel_nb * sizeof(size_t));
|
||||||
|
count_fail_thread = malloc(parallel_nb * sizeof(size_t));
|
||||||
|
id_thread_self = malloc(parallel_nb * sizeof(size_t));
|
||||||
|
|
||||||
|
for(size_t i=0; i<parallel_nb; ++i){
|
||||||
|
thread_test_failed_l[i] = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_fn = f_beging;
|
||||||
|
|
||||||
|
pthread_mutex_init(&mut_global_list_fail, NULL);
|
||||||
|
pthread_mutex_init(&mut_current_test, NULL);
|
||||||
|
pthread_mutex_init(&mut_count_pass_global, NULL);
|
||||||
|
pthread_mutex_init(&mut_count_fail_global, NULL);
|
||||||
|
pthread_mutex_init(&mut_count_pass_local, NULL);
|
||||||
|
pthread_mutex_init(&mut_count_fail_local, NULL);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* finalisation, cleanup
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
final_parallel_test_()
|
||||||
|
{
|
||||||
|
free(count_pass_test);
|
||||||
|
free(count_fail_test);
|
||||||
|
|
||||||
|
free(thread_test_failed_l);
|
||||||
|
|
||||||
|
|
||||||
|
pthread_mutex_destroy(&mut_global_list_fail);
|
||||||
|
pthread_mutex_destroy(&mut_current_test);
|
||||||
|
pthread_mutex_destroy(&mut_count_pass_global);
|
||||||
|
pthread_mutex_destroy(&mut_count_fail_global);
|
||||||
|
pthread_mutex_destroy(&mut_count_pass_local);
|
||||||
|
pthread_mutex_destroy(&mut_count_fail_local);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_all_tests_parallel(size_t parallel)
|
||||||
|
{
|
||||||
|
parallel_nb = parallel;
|
||||||
|
|
||||||
|
struct timespec start_t;
|
||||||
|
head_all_parallel_run(&start_t);
|
||||||
|
|
||||||
|
init_parallel_test_();
|
||||||
|
|
||||||
|
pthread_t *thrd = malloc(parallel_nb * sizeof(pthread_t));
|
||||||
|
size_t *id_th = malloc( parallel_nb * sizeof(size_t));
|
||||||
|
|
||||||
|
for(size_t i = 0; i < parallel_nb; ++i){
|
||||||
|
id_th[i]=i;
|
||||||
|
pthread_create(&thrd[i], NULL, run_parallel_tests, (void*)&id_th[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i=0; i<parallel_nb; ++i){
|
||||||
|
pthread_join(thrd[i], NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
stat_end_all_parallel_run(count_tests, start_t );
|
||||||
|
|
||||||
|
free(id_th);
|
||||||
|
free(thrd);
|
||||||
|
|
||||||
|
final_parallel_test_();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
clear_all_func(struct func **fun)
|
clear_all_func(struct func **fun)
|
||||||
{
|
{
|
||||||
if(*fun != NULL)
|
struct func *tmp = *fun, *ttmp;
|
||||||
{
|
while(tmp != NULL){
|
||||||
clear_all_func(&((*fun)->next));
|
ttmp = tmp;
|
||||||
free(*fun);
|
tmp = tmp->next;
|
||||||
*fun = NULL;
|
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");
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
+179
-42
@@ -6,39 +6,106 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
//#include <time.h>
|
//#include <time.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
//#include <unistd.h>
|
||||||
|
|
||||||
#include "src/tools_t/tools_t.h"
|
#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 {
|
struct func {
|
||||||
char *name;
|
char *name;
|
||||||
void (*run)(void);
|
void (*run)(void);
|
||||||
struct func *next;
|
struct func *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
//void begin_f();
|
extern bool is_parallel;
|
||||||
//struct func f_beging;
|
|
||||||
|
|
||||||
void vprintf_colored(char *color, char * format, ...);
|
|
||||||
|
|
||||||
void run_all_tests();
|
void run_all_tests();
|
||||||
void execute_all(struct func *fun);
|
void execute_all(struct func *fun);
|
||||||
void append_func(void (*run)(void), char *name);
|
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_some_tests(size_t cnt, ... );
|
||||||
void run_all_tests_exept(size_t cnt, ... );
|
void run_all_tests_exept(size_t cnt, ... );
|
||||||
void run_some_tests_ordered(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_true_f(bool val);
|
||||||
bool expected_false_f(bool val, const char* var_name, const char * func_name);
|
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)\
|
#define GEN_EXPECTED_EQ_TYPE_FUNC(type)\
|
||||||
bool expected_eq_##type(type var1, type var2, \
|
bool expected_eq_##type(type var1, type var2);\
|
||||||
const char *var1_name, const char *var2_name, const char *func_name); \
|
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_CHAR)
|
||||||
GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_U_CHAR)
|
GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_U_CHAR)
|
||||||
@@ -52,35 +119,104 @@ GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_DOUBLE)
|
|||||||
GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_L_DOUBLE)
|
GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_L_DOUBLE)
|
||||||
GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_STRING)
|
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__) ;
|
* is_assert : 0 for EXPECT and 1 for ASSERT
|
||||||
#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 HANDLE_EXPECT_ASSERT(type,var1,var2,is_assert) \
|
||||||
#define EXPECT_EQ_TYPE_L_INT(var1, var2) expected_eq_TYPE_L_INT(var1, var2, #var1, #var2, __func__) ;
|
do{ \
|
||||||
#define EXPECT_EQ_TYPE_U_L_INT(var1, var2) expected_eq_TYPE_U_L_INT(var1, var2, #var1, #var2, __func__) ;
|
if(is_parallel==0){\
|
||||||
#define EXPECT_EQ_TYPE_SIZE_T(var1, var2) expected_eq_TYPE_SIZE_T(var1, var2, #var1, #var2, __func__) ;
|
if(expected_eq_##type(var1, var2)){ \
|
||||||
#define EXPECT_EQ_TYPE_FLOAT(var1, var2) expected_eq_TYPE_FLOAT(var1, var2, #var1, #var2, __func__) ;
|
PRINT_HK_C(GREEN_K,HK_TR," 1 test passed from %s \n\n",__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__) ;
|
else{ \
|
||||||
#define EXPECT_EQ_TYPE_STRING(var1, var2) expected_eq_TYPE_STRING(var1, var2, #var1, #var2, __func__) ;
|
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)
|
// ============== ASERT =====================
|
||||||
#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)
|
|
||||||
|
|
||||||
#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 CONCAT(x,y) x ## y
|
||||||
@@ -97,26 +233,27 @@ GEN_EXPECTED_EQ_TYPE_FUNC(TYPE_STRING)
|
|||||||
void CONCAT(test_##name_f##____,count)(void)
|
void CONCAT(test_##name_f##____,count)(void)
|
||||||
|
|
||||||
#define FTEST__(count, name_f) \
|
#define FTEST__(count, name_f) \
|
||||||
void CONCAT(name_f##___,count)(void); \
|
void CONCAT(TEST_##name_f##____,count)(void); \
|
||||||
__attribute__((constructor)) \
|
__attribute__((constructor)) \
|
||||||
void CONCAT(append_test_##name_f,count)(void){ \
|
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)\
|
|
||||||
FTEST_(__COUNTER__,name_f)
|
|
||||||
|
|
||||||
//#define TEST(name_f)\
|
//#define TEST(name_f)\
|
||||||
|
FTEST_(__COUNTER__,name_f)
|
||||||
|
|
||||||
|
#define TEST(name_f) \
|
||||||
FTEST__(__COUNTER__,name_f)
|
FTEST__(__COUNTER__,name_f)
|
||||||
|
|
||||||
|
/*
|
||||||
#define ASSERT_TRUE(val)\
|
#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)\
|
#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;}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+16
-1
@@ -58,7 +58,7 @@ TYPE_STRING TYPE_STRING_TO_STR(TYPE_STRING var){
|
|||||||
#define GENERATE_FUNCTION_NUMERIC(type)\
|
#define GENERATE_FUNCTION_NUMERIC(type)\
|
||||||
int COMPARE_N_##type(const void *a, const void *b){ \
|
int COMPARE_N_##type(const void *a, const void *b){ \
|
||||||
type diff = (*(type*)a - *(type*)b)*PRECISION_##type; \
|
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; \
|
if ((diff < 1) && (diff > -1) ) return 0; \
|
||||||
return diff; \
|
return diff; \
|
||||||
} \
|
} \
|
||||||
@@ -135,5 +135,20 @@ GENERATE_FUNCTION_ALL(TYPE_L_DOUBLE)
|
|||||||
GENERATE_FUNCTION_ALL(TYPE_STRING)
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,15 @@
|
|||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
#endif
|
#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
|
#ifndef SECOND
|
||||||
#define SECOND 0
|
#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__, \
|
do { if (DEBUG) fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \
|
||||||
__LINE__, __func__, __VA_ARGS__); } while (0)
|
__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
|
#define TYPE_CHAR char
|
||||||
@@ -71,5 +97,16 @@ GENERATE_ALL(TYPE_DOUBLE)
|
|||||||
GENERATE_ALL(TYPE_L_DOUBLE)
|
GENERATE_ALL(TYPE_L_DOUBLE)
|
||||||
GENERATE_ALL(TYPE_STRING)
|
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__*/
|
#endif /*__TOOLS_T_C_H__*/
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user