restruct repository to ytest, create shared library for ytest
This commit is contained in:
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
FMOCK_SRC=src/fmock/fmock.c
|
||||
FMOCK_O=$(FMOCK_SRC:.c=.o)
|
||||
|
||||
FTEST_SRC=../yftest/src/ftest/ftest.c
|
||||
FTEST_O=$(FTEST_SRC:.c=.o)
|
||||
|
||||
|
||||
all: $(FMOCK_O)
|
||||
|
||||
$(FMOCK_O): $(FMOCK_SRC) $(FTEST_O)
|
||||
$(CC) -o $@ -c $< $(CFLAGS)
|
||||
|
||||
|
||||
.PHONY: clean
|
||||
|
||||
clean:
|
||||
rm -f $(FMOCK_O)
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
#ifndef __MOCK_C_H__
|
||||
#define __MOCK_C_H__
|
||||
|
||||
#include "ftest/ftest.h"
|
||||
#include "tools_t/tools_t.h"
|
||||
|
||||
#define INFINITY -8
|
||||
#define INITSTATE -1
|
||||
#define DONOTHING 0
|
||||
|
||||
#define PRE_ID ___line_
|
||||
/*
|
||||
* list of each variable called
|
||||
* use str_print_current_variables attibute function pointer to record variable
|
||||
* so if STR_PRINT_CUR_VAR is not defined, this list is empty!
|
||||
*/
|
||||
struct list_current_variable{
|
||||
char *str_current_variables;
|
||||
struct list_current_variable *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* list to store info abou mock function
|
||||
*/
|
||||
struct func_mock_info_struct{
|
||||
long id;
|
||||
char *str_namefunc;
|
||||
char *str_conditions;
|
||||
char *str_caller;
|
||||
//char *str_current_variables;
|
||||
struct list_current_variable *l_current_var;
|
||||
int expect_call;/* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */
|
||||
long call;/* increment when call (try to executed) and 0 if not : init value */
|
||||
long failed_call;/* increment when condition not fill and 0 if not : init value */
|
||||
long init_times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
long times_left;/* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */
|
||||
struct func_mock_info_struct *next;
|
||||
};
|
||||
|
||||
/*
|
||||
* to list all mock responses of all mock functions in one list
|
||||
*/
|
||||
struct list_base_fmock{
|
||||
struct func_mock_info_struct *info_mock;
|
||||
struct list_base_fmock *next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
int parse_count_args_(char *input);
|
||||
void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock);
|
||||
void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock);
|
||||
void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var);
|
||||
|
||||
// if input == functioname___line_NBLINE return functioname, else it return the input
|
||||
//char* extract_name_func_mock(char *input);
|
||||
|
||||
extern struct func_mock_info_struct *f_mock_glist;
|
||||
extern struct list_base_fmock *g_list_base_fmock;
|
||||
|
||||
#if 0
|
||||
int expect_call; /* 1 if EXPECT_MOCK_CALL and 0 if WILL_MOCK_CALL */\
|
||||
long init_times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
long times_left; /* DONOTHING do nothing (pass to -> next), INFINITY every time; INITSTATE init; > 0 execute and decrement */\
|
||||
|
||||
#endif
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO__(tmp__mock, namefunction, pre_id, id) \
|
||||
(tmp__mock)->run = NULL;\
|
||||
(tmp__mock)->call_mock_condition = NULL;\
|
||||
/*(tmp__mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;*/\
|
||||
((tmp__mock)->info_mock)->expect_call = -1;\
|
||||
((tmp__mock)->info_mock)->call = 0;\
|
||||
((tmp__mock)->info_mock)->failed_call = 0;\
|
||||
((tmp__mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp__mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp__mock)->info_mock)->str_conditions = NULL;\
|
||||
((tmp__mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp__mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp__mock)->info_mock)->next = NULL;\
|
||||
/*(tmp__mock)->next = NULL;*/\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp__mock)->info_mock);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp__mock)->info_mock);
|
||||
|
||||
#define INIT_MOCK_INFO_IF_NO_(tmp_new_mock, namefunction, pre_id) \
|
||||
INIT_MOCK_INFO_IF_NO__(tmp_new_mock, namefunction, pre_id, __LINE__) \
|
||||
|
||||
#define MOCK_FUNC(returntype, namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
/*typedef returntype FUNC_type_ ## namefunction args_prototype_with_parenthesis ;*/\
|
||||
/*typedef args_prototype_with_parenthesis args_ ## namefunction;*/\
|
||||
struct list_mock_return_ ## namefunction{\
|
||||
returntype (*run) args_prototype_with_parenthesis;\
|
||||
int (*call_mock_condition) args_prototype_with_parenthesis ;/* to store condition */\
|
||||
char* (*str_print_current_variables) args_prototype_with_parenthesis ;/* to store current variables CREATE by macro STR_PRINT_CUR_VAR same arguments as MOCK_FUNC without returntype whoch is always char * */\
|
||||
struct func_mock_info_struct *info_mock;\
|
||||
struct list_mock_return_ ## namefunction *next;\
|
||||
} list_mo_ ## namefunction;\
|
||||
__attribute__((constructor)) void init_list_m_ ## namefunction(void){\
|
||||
list_mo_ ## namefunction.info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
(list_mo_ ## namefunction.info_mock)->times_left = INITSTATE;\
|
||||
(list_mo_ ## namefunction.info_mock)->init_times_left = INITSTATE;\
|
||||
list_mo_ ## namefunction.str_print_current_variables = NULL;\
|
||||
list_mo_ ## namefunction.next = NULL;\
|
||||
}\
|
||||
returntype namefunction args_prototype_with_parenthesis {\
|
||||
static size_t count_call_f=0;\
|
||||
++count_call_f;\
|
||||
PRINT_DEBUG(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>count call of %s: %ld\n",#namefunction,count_call_f);\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if( (tmp_mock->info_mock)->times_left == INITSTATE ){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],HK_TR," WARNING, %s, no EXPECT_MOCK_CALL or WILL_MOCK_CALL, but called %ld times.\n",#namefunction, count_call_f);\
|
||||
if(count_call_f==1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],HK_TR," For instance:\n"\
|
||||
"%s EXPECT_MOCK_CALL(%s,%s,%s,true,1){\n"\
|
||||
"%s\t %s ret;\n%s \t ...do something with %s;\n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s if call once and accept all args, the same args with WILL_MOCK_CALL \n\n",\
|
||||
HK_TR, #returntype, #namefunction,#args_prototype_with_parenthesis, HK_TR,#returntype, \
|
||||
HK_TR, #args_call_with_parenthesis, HK_TR, HK_TR, HK_TR ); \
|
||||
/*return (returntype)0;*/ \
|
||||
INIT_MOCK_INFO_IF_NO_(tmp_mock,namefunction, PRE_ID);\
|
||||
}/* to have log */\
|
||||
/*if(list_mo_ ## namefunction.next ) PRINT_ERROR(" %s .next SHOULD BE NULL\n",STRFY(list_mo_ ## namefunction));*/\
|
||||
}\
|
||||
while(tmp_mock->next && (tmp_mock->info_mock)->times_left == 0) {tmp_mock = tmp_mock->next ;}\
|
||||
++((tmp_mock->info_mock)->call);\
|
||||
if(tmp_mock->str_print_current_variables){\
|
||||
append_variable_current(&((tmp_mock->info_mock)->l_current_var), tmp_mock->str_print_current_variables args_call_with_parenthesis);\
|
||||
}\
|
||||
else if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],HK_TR," no printer variable function defined, to define it:\n"\
|
||||
"%s STR_PRINT_CUR_VAR(%s,%s,%s){\n"\
|
||||
"%s\t char* ret=malloc(256);/*for instance*/;\n"\
|
||||
"%s\t ... sprintf(ret,...., %s);/*for instance*/ \n"\
|
||||
"%s\t return ret;\n"\
|
||||
"%s }\n"\
|
||||
"%s same prototype as MOCK_FUNC whithout returntype which always char* i\n\n",\
|
||||
HK_TR, #namefunction,#args_prototype_with_parenthesis, #args_call_with_parenthesis, \
|
||||
HK_TR, HK_TR, #args_call_with_parenthesis, HK_TR, HK_TR, HK_TR ); \
|
||||
}\
|
||||
/*LOG("condition_func:%d\n", tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*EXPECT_EQ_TYPE_INT(1, tmp_mock->call_mock_condition args_call_with_parenthesis);*/ /*LOG("%s\n","failure condition");*/\
|
||||
/*if ((tmp_mock->info_mock)->times_left == 0)*/ /*no longer response, default return */ \
|
||||
/*return (returntype)0;*//* default return */\
|
||||
if( (tmp_mock->info_mock)->str_caller == NULL){ \
|
||||
if(count_call_f == 1){\
|
||||
PRINT_HK_C(colors_f[k_YELLOW],HK_TR," WARNING, no INIT_CALLER_MOCK; you can put it like this: \n"\
|
||||
"%s TEST(nametest){\n"\
|
||||
"%s\t INIT_CALLER_MOCK(%s); \n"\
|
||||
"%s\t %s%s; \n"\
|
||||
"%s }\n"\
|
||||
"%s i.e before calling %s in this TEST, to have explicit logs\n",\
|
||||
HK_TR, HK_TR, #namefunction, HK_TR,#namefunction,#args_call_with_parenthesis, HK_TR, HK_TR, #namefunction);} \
|
||||
/*return (returntype)0;*/ \
|
||||
}\
|
||||
else if (((tmp_mock->info_mock)->times_left != 0) && ((tmp_mock->info_mock)->times_left != INITSTATE )) {\
|
||||
size_t len0 = strlen((tmp_mock->info_mock)->str_conditions);\
|
||||
size_t len1 = strlen("when checking condition call: aa");\
|
||||
char *msg_call=malloc(len0 + len1 + strlen(__func__));\
|
||||
sprintf(msg_call,"when checking %s condition call: %s",__func__,(tmp_mock->info_mock)->str_conditions);\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,1, tmp_mock->call_mock_condition args_call_with_parenthesis, (tmp_mock->info_mock)->str_caller, msg_call); /*LOG("%s\n","failure condition");*/\
|
||||
free(msg_call);\
|
||||
}\
|
||||
/*if(0 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
PRINT_LOC("Failure, arguments not expected\ncondition ( %s ) not verified\n\n", (tmp_mock->info_mock)->str_conditions);\
|
||||
PRINT_HK_C(RED_K,HK_TR," 1 argument check failed from %s \n",__func__); \
|
||||
}*/\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'^',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if (((tmp_mock->info_mock)->times_left <= INFINITY) || ((tmp_mock->info_mock)->times_left > 0)){\
|
||||
--((tmp_mock->info_mock)->times_left);\
|
||||
PRINT_DEBUG(" %*c VALUES: mock function:%s, conditions:%s t_left:%ld, init_left:%ld| args:%s\n",8,'v',(tmp_mock->info_mock)->str_namefunc, (tmp_mock->info_mock)->str_conditions, (tmp_mock->info_mock)->times_left,(tmp_mock->info_mock)->init_times_left, #args_call_with_parenthesis);\
|
||||
if(1 == tmp_mock->call_mock_condition args_call_with_parenthesis){\
|
||||
return tmp_mock->run args_call_with_parenthesis;\
|
||||
}\
|
||||
else ++((tmp_mock->info_mock)->failed_call);\
|
||||
}\
|
||||
return (returntype)0;/* default return */\
|
||||
}
|
||||
|
||||
|
||||
char* extract_name_func_mock(char *input);
|
||||
|
||||
/*
|
||||
* used in mock functions to check the conditions
|
||||
*/
|
||||
#define EXPECT_EQ_IN_MOCKF(var1,var2, name_f_mocked)\
|
||||
do{ \
|
||||
if((list_mo_ ## name_f_mocked.info_mock)->str_caller) {\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,(list_mo_ ## name_f_mocked.info_mock)->str_caller,"mock test");\
|
||||
}\
|
||||
else\
|
||||
HANDLE_OP_EXPECT_NAME(EQ,TYPE_INT,var1,var2,__func__,"mock test");\
|
||||
}while(0)
|
||||
|
||||
|
||||
/*
|
||||
* to inject the name TEST caller in the mock attribute info, usefull in logs and stats
|
||||
*/
|
||||
#define INIT_CALLER_MOCK(namefunction)/* */\
|
||||
do{\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
while(tmp_mock){\
|
||||
(tmp_mock->info_mock)->str_caller=malloc(strlen(__func__));\
|
||||
strcpy((tmp_mock->info_mock)->str_caller,__func__);\
|
||||
tmp_mock = tmp_mock->next;\
|
||||
}\
|
||||
}while(0);
|
||||
|
||||
/*
|
||||
* to create/ define str_print_current_variables functions
|
||||
* prototype: char* str_print_current_variables (prototype of mock function)
|
||||
* the args of the macro are the same of MOCK_FUNC without the returntype which is always (char*).
|
||||
* It need to be defined after MOCK_FUNC but need to be before EXPECT_MOCK_CALL or WILL_MOCK_CALL
|
||||
*/
|
||||
|
||||
#define STR_PRINT_CUR_VAR(namefunction, args_prototype_with_parenthesis, args_call_with_parenthesis)\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis;\
|
||||
__attribute__((constructor)) void create_str_print_variables ## namefunction(){\
|
||||
list_mo_ ## namefunction .str_print_current_variables = str_print_variables ## namefunction;\
|
||||
}\
|
||||
char* str_print_variables ## namefunction args_prototype_with_parenthesis
|
||||
|
||||
|
||||
|
||||
|
||||
#define FILL_MOCK_INFO(tmp_new_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, is_init) \
|
||||
(tmp_new_mock)->run = CONCAT(run_ ## namefunction ## pre_id, id);\
|
||||
(tmp_new_mock)->call_mock_condition = CONCAT(namefunction ## _cond_, id);\
|
||||
if(!is_init)\
|
||||
(tmp_new_mock)->str_print_current_variables = list_mo_ ## namefunction .str_print_current_variables;\
|
||||
/*(tmp_new_mock)->info_mock = malloc(sizeof(struct func_mock_info_struct));*/\
|
||||
((tmp_new_mock)->info_mock)->expect_call = f_expect_call;\
|
||||
((tmp_new_mock)->info_mock)->call = 0;\
|
||||
((tmp_new_mock)->info_mock)->failed_call = 0;\
|
||||
((tmp_new_mock)->info_mock)->init_times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->times_left = repeat;\
|
||||
((tmp_new_mock)->info_mock)->str_namefunc = malloc(strlen(#namefunction) + 32 + strlen(#pre_id));\
|
||||
sprintf(((tmp_new_mock)->info_mock)->str_namefunc,"%s%s%d",#namefunction,#pre_id,id);\
|
||||
((tmp_new_mock)->info_mock)->str_conditions = malloc(strlen(#condition_on_args_expression));\
|
||||
strcpy(((tmp_new_mock)->info_mock)->str_conditions, #condition_on_args_expression);\
|
||||
((tmp_new_mock)->info_mock)->str_caller = NULL;\
|
||||
((tmp_new_mock)->info_mock)->l_current_var= NULL;\
|
||||
((tmp_new_mock)->info_mock)->next = NULL;\
|
||||
(tmp_new_mock)->next = NULL;\
|
||||
append_fmock_to_listmock(&f_mock_glist, (tmp_new_mock)->info_mock);
|
||||
|
||||
|
||||
#define ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
/*FUNC_type_ ## namefunction CONCAT(run_ ## namefunction ## pre_id , id);*/\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id , id) args_prototype_with_parenthesis; \
|
||||
int CONCAT(namefunction ## _cond_ , id) args_prototype_with_parenthesis {/*LOG("cond:%d\n",condition_on_args_expression);*/ return condition_on_args_expression;}\
|
||||
__attribute__((constructor)) void CONCAT(append_list_ ## namefunction , id)(void){\
|
||||
struct list_mock_return_ ## namefunction *tmp_mock = &list_mo_ ## namefunction;\
|
||||
if((tmp_mock->info_mock)->times_left == INITSTATE){/* init state */\
|
||||
FILL_MOCK_INFO(tmp_mock, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, true);\
|
||||
append_list_base_fmock( &g_list_base_fmock ,(tmp_mock->info_mock));\
|
||||
}\
|
||||
else{\
|
||||
while(tmp_mock->next) tmp_mock = tmp_mock->next;\
|
||||
tmp_mock->next = malloc(sizeof(list_mo_ ## namefunction));\
|
||||
(tmp_mock->next)->info_mock = malloc(sizeof(struct func_mock_info_struct));\
|
||||
FILL_MOCK_INFO(tmp_mock->next, namefunction, condition_on_args_expression , repeat, f_expect_call, pre_id, id, false);\
|
||||
/*(tmp_mock->info_mock)->next = (tmp_mock->next)->info_mock ;*/\
|
||||
}\
|
||||
}\
|
||||
returntype CONCAT(run_ ## namefunction ## pre_id, id) args_prototype_with_parenthesis
|
||||
|
||||
/*
|
||||
* have to define this below macro to rewrite the right macro identifier (PRE_ID)
|
||||
*/
|
||||
|
||||
#define ADD_RESPONSE(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
ADD_RESPONSE_(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression , repeat, f_expect_call, pre_id, id)\
|
||||
|
||||
|
||||
#define EXPECT_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 1, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
#define WILL_MOCK_CALL(returntype, namefunction, args_prototype_with_parenthesis, condition_on_args_expression ,repeat) \
|
||||
ADD_RESPONSE(returntype,namefunction, args_prototype_with_parenthesis, condition_on_args_expression, repeat, 0, PRE_ID, __LINE__)
|
||||
|
||||
|
||||
|
||||
#endif /* __MOCK_C_H__ */
|
||||
@@ -0,0 +1,319 @@
|
||||
#include "fmock/fmock.h"
|
||||
|
||||
/*
|
||||
* global variables
|
||||
*/
|
||||
|
||||
//char *colors_f[]={DEFAULT_K, RED_K, GREEN_K, YELLOW_K, BLUE_K, ""};
|
||||
|
||||
size_t count_f_mock_wished=0;
|
||||
pthread_mutex_t mut_count_f_mock_wished;
|
||||
|
||||
size_t count_f_mock=0;
|
||||
pthread_mutex_t mut_count_f_mock;
|
||||
|
||||
size_t count_expect_mock=0;
|
||||
pthread_mutex_t mut_count_expect_mock;
|
||||
|
||||
struct list_base_fmock *g_list_base_fmock=NULL;
|
||||
pthread_mutex_t mut_g_list_base_fmock;
|
||||
|
||||
#define LOCK(mutex_var) pthread_mutex_lock(&mutex_var);
|
||||
#define UNLOCK(mutex_var) pthread_mutex_unlock(&mutex_var);
|
||||
|
||||
|
||||
#define INCREMENT_(variable)\
|
||||
do{\
|
||||
LOCK(mut_##variable); \
|
||||
++variable;\
|
||||
UNLOCK(mut_##variable);\
|
||||
}while(0);
|
||||
|
||||
|
||||
/*
|
||||
* return the numbers of comas (,) +1 in the input string
|
||||
*/
|
||||
|
||||
|
||||
int parse_count_args_(char *input){
|
||||
int val=0;
|
||||
for(int i = 0; i< strlen(input); ++i){
|
||||
if(input[i]==',') ++val;
|
||||
}
|
||||
return val+1;
|
||||
}
|
||||
|
||||
/*
|
||||
* the begin only !
|
||||
*/
|
||||
void append_list_base_fmock(struct list_base_fmock **l_fmock, struct func_mock_info_struct *f_mock){
|
||||
INCREMENT_(count_f_mock);
|
||||
LOCK(mut_g_list_base_fmock);
|
||||
PRINT_DEBUG(" append_list_base_fmock %s",f_mock->str_namefunc);
|
||||
if(*l_fmock){
|
||||
struct list_base_fmock *tmp_l_n = *l_fmock;
|
||||
while(tmp_l_n->next) tmp_l_n = tmp_l_n->next;
|
||||
(tmp_l_n->next) = malloc(sizeof(struct list_base_fmock));
|
||||
(tmp_l_n->next)->info_mock = f_mock;
|
||||
(tmp_l_n->next)->next = NULL;
|
||||
}
|
||||
else{
|
||||
*l_fmock = malloc(sizeof(struct list_base_fmock));
|
||||
(*l_fmock)->info_mock = f_mock;
|
||||
}
|
||||
UNLOCK(mut_g_list_base_fmock);
|
||||
}
|
||||
|
||||
struct func_mock_info_struct *f_mock_glist = NULL;
|
||||
pthread_mutex_t mut_f_mock_glist;
|
||||
|
||||
void append_variable_current(struct list_current_variable **lcurrent_var, char *current_var){
|
||||
if(*lcurrent_var){
|
||||
PRINT_DEBUG("----- l_current_var not NULL, content: %s have to add %s\n",(*lcurrent_var)->str_current_variables, current_var);
|
||||
struct list_current_variable *tmp_lcv = *lcurrent_var;
|
||||
while(tmp_lcv->next) tmp_lcv = tmp_lcv->next;
|
||||
tmp_lcv->next = malloc(sizeof(struct list_current_variable));
|
||||
//(tmp_lcv->next)->str_current_variables = malloc(strlen(current_var));
|
||||
//strcpy((tmp_lcv->next)->str_current_variables,current_var);
|
||||
(tmp_lcv->next)->str_current_variables = current_var;
|
||||
(tmp_lcv->next)->next= NULL;
|
||||
|
||||
}
|
||||
else{
|
||||
PRINT_DEBUG("-- lcurrent_var %s\n","NULL");
|
||||
*lcurrent_var = malloc(sizeof(struct list_current_variable));
|
||||
//(*lcurrent_var)->str_current_variables = malloc(strlen(current_var));
|
||||
//strcpy((*lcurrent_var)->str_current_variables,current_var);
|
||||
(*lcurrent_var)->str_current_variables = current_var;
|
||||
(*lcurrent_var)->next = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void append_fmock_to_listmock(struct func_mock_info_struct **f_mock_list, struct func_mock_info_struct *f_mock){
|
||||
INCREMENT_(count_f_mock_wished);
|
||||
if(f_mock->expect_call) {
|
||||
INCREMENT_(count_expect_mock);
|
||||
}
|
||||
LOCK(mut_f_mock_glist);
|
||||
PRINT_DEBUG(" append_fmock_to_listmock %s",f_mock->str_namefunc);
|
||||
if(*f_mock_list){
|
||||
struct func_mock_info_struct *tmp_fmock_info = *f_mock_list;
|
||||
while(tmp_fmock_info->next) tmp_fmock_info = tmp_fmock_info->next;
|
||||
tmp_fmock_info->next = f_mock;
|
||||
}
|
||||
else{
|
||||
*f_mock_list = f_mock;
|
||||
}
|
||||
UNLOCK(mut_f_mock_glist);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define SSTRFY(x) STRFY(x)
|
||||
|
||||
char* extract_name_func_mock(char *input){
|
||||
char * ret=malloc(strlen(input));
|
||||
strcpy(ret,input);
|
||||
char * pre_id_ = SSTRFY(PRE_ID);
|
||||
size_t len_pre_id_ = strlen(pre_id_);
|
||||
for(size_t i=0; i<strlen(ret)-len_pre_id_; ++i){
|
||||
if(strncmp(ret+i,pre_id_,len_pre_id_) == 0){
|
||||
ret[i]='\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
__attribute__((constructor))
|
||||
void
|
||||
init_mock_c(){
|
||||
|
||||
pthread_mutex_init(&mut_g_list_base_fmock, NULL);
|
||||
pthread_mutex_init(&mut_f_mock_glist, NULL);
|
||||
pthread_mutex_init(&mut_count_f_mock_wished, NULL);
|
||||
pthread_mutex_init(&mut_count_f_mock, NULL);
|
||||
pthread_mutex_init(&mut_count_expect_mock, NULL);
|
||||
}
|
||||
|
||||
extern bool is_parallel_nb;
|
||||
|
||||
|
||||
|
||||
char * number_call_translate(long nb){
|
||||
char *ret=malloc(250);
|
||||
if(nb>1) sprintf(ret," to be called %ld times",nb);
|
||||
else if(nb == 1) sprintf(ret," to be called once");
|
||||
else if(nb == 0 ) sprintf(ret," not to be executed");
|
||||
else if(nb==INFINITY) sprintf(ret," to be called forever");
|
||||
else if(nb==INITSTATE) sprintf(ret," not expected");
|
||||
else sprintf(ret," nothing! it's negative:%ld", nb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char * strprint_caller_(char *input){
|
||||
if(input==NULL) { return "";}
|
||||
char *called_in=",\t called in ";
|
||||
char *ret = malloc(strlen(called_in)+strlen(input)+1);
|
||||
sprintf(ret,"%s%s",called_in,input);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define PRINT_VAR_CUR(mockinfo)\
|
||||
do{\
|
||||
PRINTF("\n%s list of variables when %s was called, with condition %s:\n\t\t",HK_EQ,mockinfo->str_namefunc,mockinfo->str_conditions);\
|
||||
size_t cal_cur=0;\
|
||||
struct list_current_variable *tmp_cur_v = mockinfo->l_current_var;\
|
||||
while(tmp_cur_v){\
|
||||
PRINTF(" call : %ld : variables : %s \n\t\t",++cal_cur, tmp_cur_v->str_current_variables);\
|
||||
tmp_cur_v = tmp_cur_v->next;\
|
||||
}\
|
||||
PRINTF("\n");\
|
||||
}while(0);
|
||||
|
||||
|
||||
|
||||
|
||||
__attribute__((destructor))
|
||||
void
|
||||
check_mock_excpected(){
|
||||
|
||||
signal(SIGSEGV, SIG_DFL); /* restore default behaviour , */
|
||||
|
||||
//int k_DEFAULT=0, k_GREEN=1, k_RED=2, k_YELLOW=3, k_BLUE=4, k_NOTHING;
|
||||
//if(unicolour) {
|
||||
//k_GREEN=k_NOTHING; k_RED=k_NOTHING; k_YELLOW=k_NOTHING; k_BLUE=k_NOTHING;
|
||||
//for(int i=0; i< Dk_NOTHING;++i) strcpy(colors_f[i]," ");
|
||||
//}
|
||||
|
||||
struct winsize w;
|
||||
ioctl(1, TIOCGWINSZ, &w);
|
||||
|
||||
char *reader=malloc(w.ws_col);
|
||||
strcpy(reader,"STAT OF MOCK FUNCTIONS");
|
||||
|
||||
fprintf(F_OUT,"%s\n\n%0*d\n %*s \n%0*d %s\n\n", colors_f[k_YELLOW] ,w.ws_col,0, (int)(w.ws_col+strlen(reader))/2, reader,w.ws_col,0, DEFAULT_K );
|
||||
|
||||
|
||||
is_parallel_nb = 0; /* no longer parallel here */
|
||||
struct func_mock_info_struct *tmock = f_mock_glist; //, *tfree;
|
||||
|
||||
/* global order of fmock , order of expect and will */
|
||||
while(tmock){
|
||||
PRINT_DEBUG("check mock function: %s\n",tmock->str_namefunc);
|
||||
//tfree=tmock;
|
||||
PRINT_DEBUG("**** STAT mock function:%s, conditions:%s t_left:%ld, init_left:%ld, failed_call:%ld\n",tmock->str_namefunc, tmock->str_conditions, tmock->times_left,tmock->init_times_left, tmock->failed_call);
|
||||
if(((tmock->expect_call) && (tmock->init_times_left == tmock->times_left)) || (tmock->failed_call)){
|
||||
if(tmock->l_current_var){
|
||||
PRINTF("%s%s %s%s %s: expect %s, it was called %ld times and failed %ld times, with condition %s\n",colors_f[k_RED],HK_FL,colors_f[k_YELLOW],tmock->str_namefunc,DEFAULT_K,
|
||||
number_call_translate(tmock->init_times_left),
|
||||
tmock->call/*tmock->failed_call + (tmock->init_times_left - tmock->times_left)*/,
|
||||
tmock->failed_call,
|
||||
tmock->str_conditions
|
||||
);
|
||||
PRINT_VAR_CUR(tmock);
|
||||
}
|
||||
else
|
||||
PRINTF("%s%s %s%s %s: expect %s, it was called %ld times and failed %ld times, with condition %s \n",colors_f[k_RED],HK_FL,colors_f[k_YELLOW],tmock->str_namefunc,DEFAULT_K,
|
||||
number_call_translate(tmock->init_times_left),
|
||||
tmock->call/*tmock->failed_call + (tmock->init_times_left - tmock->times_left)*/,
|
||||
tmock->failed_call,
|
||||
tmock->str_conditions
|
||||
);
|
||||
}
|
||||
tmock=tmock->next;
|
||||
//free(tfree);
|
||||
}
|
||||
|
||||
PRINTF("\n%s%s STAT MOCK : there are %ld mock functions, %ld wished responses, %ld expected responses, which are:\n\n",colors_f[k_GREEN],HK_EQ,count_f_mock, count_f_mock_wished, count_expect_mock);
|
||||
struct list_base_fmock *tmp_list_fm = g_list_base_fmock;
|
||||
struct func_mock_info_struct *tmp_inf_mock;
|
||||
/* list each fmock an each calls */
|
||||
while(tmp_list_fm){
|
||||
tmp_inf_mock = tmp_list_fm->info_mock;
|
||||
memset(reader,'=',w.ws_col);
|
||||
char *caller="";
|
||||
if(tmp_inf_mock->str_caller) caller = extract_func_edited_TEST_from_exec_func_name(tmp_inf_mock->str_caller);
|
||||
size_t len_caller = strlen(caller);
|
||||
|
||||
char *nameff=extract_name_func_mock(tmp_inf_mock->str_namefunc);
|
||||
size_t len_nameff=strlen(nameff);
|
||||
char *by_=" called by ";
|
||||
size_t len_by_=strlen(by_);
|
||||
size_t bg_rd=(w.ws_col -1 - len_nameff - len_caller - len_by_)/2;
|
||||
reader[bg_rd++]=' ';
|
||||
for(size_t i=0; i<len_nameff; ++i)
|
||||
reader[bg_rd+i]=nameff[i];
|
||||
if(len_caller){
|
||||
for(size_t i=0;i<len_by_;++i)
|
||||
reader[bg_rd+len_nameff+i]=by_[i];
|
||||
for(size_t i=0;i<len_caller;++i)
|
||||
reader[bg_rd+len_nameff+len_by_+i]=caller[i];
|
||||
reader[bg_rd+len_nameff+len_by_+len_caller]=' ';
|
||||
}
|
||||
else{
|
||||
reader[bg_rd+len_nameff]=' ';
|
||||
}
|
||||
PRINTF("%s%s%s\n\n",colors_f[k_BLUE],reader,DEFAULT_K );
|
||||
while(tmp_inf_mock){
|
||||
if(0==strncmp(tmp_inf_mock->str_namefunc,nameff, len_nameff)){
|
||||
if(tmp_inf_mock->expect_call==1){
|
||||
int success = !((tmp_inf_mock->init_times_left == tmp_inf_mock->times_left) || (tmp_inf_mock->failed_call));
|
||||
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t expect %s,\t called %ld times and failed %ld times %s,\t with condition: %s%s\n" ,
|
||||
colors_f[!unicolour*(k_RED - success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING * success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions, DEFAULT_K);
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t expect %s,\t called %ld times and failed %ld times %s,\t with condition: %s%s\n" ,
|
||||
colors_f[!unicolour*(k_RED - success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
}
|
||||
}else if(tmp_inf_mock->expect_call==0) {/* will expect */
|
||||
int success = !(tmp_inf_mock->failed_call);
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t will %s,\t called %ld times and failed %ld times %s,\t with condition: %s,%s\n" ,
|
||||
colors_f[!unicolour*(k_RED + success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t will %s,\t called %ld times and failed %ld times %s,\t with condition: %s %s\n" ,
|
||||
colors_f[!unicolour*(k_RED + success)],tab_hk_f[hk_FL-success],colors_f[k_NOTHING*success],tmp_inf_mock->str_namefunc, number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
tmp_inf_mock->failed_call, strprint_caller_(tmp_inf_mock->str_caller), tmp_inf_mock->str_conditions , DEFAULT_K);
|
||||
}
|
||||
}
|
||||
else if(tmp_inf_mock->expect_call==-1){
|
||||
if(tmp_inf_mock->l_current_var){
|
||||
PRINTF("%s%s%s %s\t %s,\t called %ld times, %s\n" ,
|
||||
colors_f[!unicolour*(k_RED)],tab_hk_f[hk_FL],colors_f[k_DEFAULT],tmp_inf_mock->str_namefunc,
|
||||
number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
strprint_caller_(tmp_inf_mock->str_caller) );
|
||||
PRINT_VAR_CUR(tmp_inf_mock);
|
||||
}else{
|
||||
PRINTF("%s%s%s %s\t %s,\t called %ld times, %s\n" ,
|
||||
colors_f[!unicolour*(k_RED)],tab_hk_f[hk_FL],colors_f[k_DEFAULT],tmp_inf_mock->str_namefunc,
|
||||
number_call_translate(tmp_inf_mock->init_times_left), tmp_inf_mock->call,
|
||||
strprint_caller_(tmp_inf_mock->str_caller));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
tmp_inf_mock = tmp_inf_mock->next;
|
||||
}
|
||||
PRINT_DEBUG(" end listing info mock of %s \n", nameff);
|
||||
tmp_list_fm = tmp_list_fm->next;
|
||||
}
|
||||
|
||||
PRINT_DEBUG("%s\n","info mock done!");
|
||||
|
||||
pthread_mutex_destroy(&mut_g_list_base_fmock);
|
||||
pthread_mutex_destroy(&mut_f_mock_glist);
|
||||
pthread_mutex_destroy(&mut_count_f_mock_wished);
|
||||
pthread_mutex_destroy(&mut_count_f_mock);
|
||||
pthread_mutex_destroy(&mut_count_expect_mock);
|
||||
PRINT_DEBUG("%s\n","pthread_mutex_destroy done!");
|
||||
PRINT_DEBUG("%s\n","check mock done!");
|
||||
}
|
||||
Reference in New Issue
Block a user