【目的】
模块化编程设计中,对于模块提供的一些API接口,可能会在不同case下重复使用,case不同而调用顺序不同,或者说运行实例不同。为了增加代码的可视化和对象化设计,减少重复编码,这里使用数组来预定义api执行流程,以及哪些api接口单线程执行,哪些api接口多线程执行,多线程执行的插入点与等待点。
【环境】
x86的64位dos环境下执行C代码。
【方案】
给定的API接口,需要对其验证,不同case场合有不同的调用顺序与并发测试。
这里给不同case预定义API的调用以及多线程执行。
1、定义API函数的执行单元类型:
typedef struct lib_funcs
{
enum{
TLIB_INIT = 0,
TLIB_OPEN,
TLIB_SET_PARAMS,
TLIB_GET_PARAMS,
TLIB_PROCESS,
TLIB_CLOSE,
TWAV_COMPARE,
TLIB_EXIT,
TLIB_PTHREAD,
TLIB_TOPO_FIX,
TLIB_PARAM_FIX,
}func_type;
void *func_real;
const char *func_name;
dparams params[PARAM_MAX];
}LIB_FUNCS;
其中func_type是根据API函数来定义的枚举类型,在switch_case中使用;
func_real是API的函数地址;
func_name是API函数名;
params是API参数。
2、定义不同case下的API执行顺序:
static case_info CASES[] =
{
/* ONE PTHREAD ALONE */
{
.case_name = "case_01",
.wave_name = "case_01",
.case_type = CASE_ONE_PROC,
.case_cnts = 1,
.case_enable = 1,
.run_seqs = RUN_MAIN,
.main_func = {
{
.func_type = TLIB_INIT,
.func_real = lib_handle_init,
.func_name = "lib_hande_init"
},
{
.func_type = TLIB_OPEN,
.func_real = lib_handle_open,
.func_name = "lib_hande_open"
},
{
.func_type = TLIB_TOPO_FIX,
.func_real = acbd_topo_fix,
.func_name = "acdb_topo_fix one",
.params[0] = {.pam0=6, .pam1=0xeeee},
.params[1] = {.pam0=7, .pam1=0xffff},
},
{
.func_type = TLIB_PARAM_FIX,
.func_real = acbd_param_fix,
.func_name = "acdb_param_fix one",
.params[0] = {.pam0=3, .pam1=0xff},
.params[1] = {.pam0=4, .pam1=0xee},
.params[2] = {.pam0=5, .pam1=0xaa},
},
{
.func_type = TLIB_SET_PARAMS,
.func_real = acbd_param_set,
.func_name = "acdb_param_set"
},
{
.func_type = TLIB_GET_PARAMS,
.func_real = acbd_topo_param_get,
.func_name = "acdb_topo_param_get"
},
{
.func_type = TLIB_PROCESS,
.func_real = lib_handle_process,
.func_name = "lib_hande_process"
},
{
.func_type = TWAV_COMPARE,
.func_real = wave_compare,
.func_name = "wave_compare"
},
{
.func_type = TLIB_CLOSE,
.func_real = lib_handle_close,
.func_name = "lib_hande_close"
},
{
.func_type = TLIB_EXIT,
.func_real = lib_handle_remove,
.func_name = "lib_hande_remove"
},
},
},
/* MUL PTHREAD ALONE */
{
.case_name = "case_02",
.wave_name = "cs2_p",
.case_type = CASE_ONE_PROC,
.case_cnts = 1,
.pthread_cnts = 10,
.case_enable = 0,
.run_seqs = RUN_MAIN,
.main_func = {
{
.func_type = TLIB_PTHREAD,
.func_real = DEF_FUN_ADDS,
.func_name = "lib_hande_pthread"
},
},
.subs_func = {
{
.func_type = TLIB_INIT,
.func_real = lib_handle_init,
.func_name = "lib_hande_init"
},
{
.func_type = TLIB_OPEN,
.func_real = lib_handle_open,
.func_name = "lib_hande_open"
},
{
.func_type = TLIB_SET_PARAMS,
.func_real = acbd_param_set,
.func_name = "acdb_param_set"
},
/*
{
.func_type = TLIB_GET_PARAMS,
.func_real = acbd_topo_param_get,
.func_name = "acdb_topo_param_get"
},
*/
{
.func_type = TLIB_PROCESS,
.func_real = lib_handle_process,
.func_name = "lib_hande_process"
},
{
.func_type = TWAV_COMPARE,
.func_real = wave_compare,
.func_name = "wave_compare"
},
{
.func_type = TLIB_CLOSE,
.func_real = lib_handle_close,
.func_name = "lib_hande_close"
},
{
.func_type = TLIB_EXIT,
.func_real = lib_handle_remove,
.func_name = "lib_hande_remove"
},
},
},
/* ONE PTHREAD START AND MTL PTHREAD TO PROCESS */
{
.case_name = "case_03",
.wave_name = "cs3_p",
.case_type = CASE_ONE_PROC,
.case_cnts = 1,
.pthread_cnts = 50,
.case_enable = 0,
.run_seqs = RUN_MAIN,
.main_func ={
{
.func_type = TLIB_INIT,
.func_real = lib_handle_init,
.func_name = "lib_hande_init"
},
{
.func_type = TLIB_OPEN,
.func_real = lib_handle_open,
.func_name = "lib_hande_open"
},
{
.func_type = TLIB_SET_PARAMS,
.func_real = acbd_param_set,
.func_name = "acdb_param_set"
},
/*
{
.func_type = TLIB_GET_PARAMS,
.func_real = acbd_topo_param_get,
.func_name = "acdb_topo_param_get"
},
*/
{
.func_type = TLIB_PTHREAD,
.func_real = DEF_FUN_ADDS,
.func_name = "lib_hande_pthread"
},
{
.func_type = TLIB_CLOSE,
.func_real = lib_handle_close,
.func_name = "lib_hande_close"
},
{
.func_type = TLIB_EXIT,
.func_real = lib_handle_remove,
.func_name = "lib_hande_remove"
},
},
.subs_func = {
{
.func_type = TLIB_PROCESS,
.func_real = lib_handle_process,
.func_name = "lib_hande_process"
},
{
.func_type = TWAV_COMPARE,
.func_real = wave_compare,
.func_name = "wave_compare"
},
},
},
这里定义了3个case场景:
case[0] = "单线程";
case[1] = "多线程";
case[2] = "竞争多线程";(init、open等单线程,process等操作多线程)
.main_func = 单线程中执行的API;
.subs_func = 多线程中执行的API;
list出的API顺序代表了其执行的顺序,TLIB_PTHREAD表示多线程插入与等待点。
【扩展】
在一些自动化测试等场合,该方法避免了测试人员的代码重编写。其实可以把这些case做成xml等形式的配置文件,用户体验会更加友好。
x86的多进程与linux的多进程有很大区别,linux的进程创建后可以直接执行代码段代码,而x86的进程创建需要执行exe文件路径,所以x86下的多进程就没有纳入case。
具体代码见如下链接:https://download.csdn.net/download/luwei860123/12270114