2 ############################################################
4 # author: devenkong(18151155@qq.com)
6 ############################################################
7 # Copyright (C) 2022- Free Software Foundation, Inc.
8 # This configure script is free software; the Free Software
9 # Foundation gives unlimited permission to copy, distribute
11 ############################################################
13 # scripttest is a program used to running test script one
14 # by one in testing dir. it's used to test script, or do some
15 # integerated testing work for binary program.
16 # the hi-light of this program is that, every test item
17 # orgnized by catalog id, tester can specify id or count number
18 # or id range to running test script.
19 # another point is that, it manage failed item, tester can
20 # test the failed item only. it's usefull for developer.
21 # it's usefull for script module/shlib unit trst, and program
22 # integerated testing, and soft-pkg test before install, and
23 # loop-back test after some feature append or bug fixed.
25 ############################################################
28 # @ nest testing, and check if the corresponding testing tmp dir is correct.
29 # @ test unit for scripttest will be updated.
30 # @ copy test unit from shlib-lite for paramter -bes.
31 # @ some place will generate misc files should not be become.
35 -O , --output-dir=<output_dir> 指定测试时的临时文件目录。默认值为~/用户目录下的
37 -f , --force 指定测试信息的目录。默认值为当前目录下的testing
39 -y , --sync 根据测试信息描述文件,生成测试目录及测试脚本等文
40 =[sync_to_dir] 件,用于用户编写各种测试用例。
41 # todo:输出文件目录异常。暂时disable该功能。
42 # tbd:使用同步输出为-g参数,-y用于sync-back
48 # - @ 使用-O参数设置测试的tmp目录路径。
49 # - @ 同一个project不同目录下的测试。
50 # @ 一些参数可使用环境变量设置,而不在命令行参数设置。环境变量改成大写字母。
51 # @ 遍历testcase目录,同步比对func_list,差异项进行创建或存放到trash目录
52 # @ taskloader运行一个测试项的脚本
54 # @ 代码中IFS的设置的代码,或许会使命令行字符串解析不正确。通常命令行使用空格将命令行字符串
55 # 分成一个数组。IFS设置成非' '后,命令行解析就异常了。
58 # @ 需要添加测试的单位时间.例如标准测试例子测试时间为N秒,其它测试时间都以标准测试时间为单位.
60 # 以一个单独的参数进行测试,保存到参数中。
62 # @ 设置默认的函数定义为export,include一次,sub-process可以不include。但是一些环境变量无法使用-g参数,所以这样的
64 # @ -F参数运行时,测试项只有所在目录的id,没有full-id。需要根据测试cataid获取不同level的desc字符串显示。
67 # @ log test output to log file, that can be reviewd by tester, if use -r -q paramter.
68 # @ append -r -q attribute to -a option.
69 # @ append time cost display switch option. when test for scripttest it self, it will display
70 # different cpu cost, and leading to report test err.
71 # @ seperate diff result to L2R and R2L, and use different color for prefix '<' or '>'.
74 # @ add testing.shlib, append dbgout_hdr(), it is used to output testing content hint with two lines and
77 # @ append test count when -n is specified.
79 # @ default is test in range. -F test for failed list, -a for all items, -A for all items continously.
81 # @ accessing of /var/log/dbgoutlog directory is permission denied. write a program, create dir under public
82 # dir like /var/log/dbgoutlog. dir name is the program name of request process.
98 #include strsyntax.shlib
100 #include catalog.shlib
102 #dsource imifile.shlib
105 #loadini scripttest.ini
106 #loadimi scripttest.imi
109 ##############################
110 # section: public comment info
111 ##############################
115 ##############################
116 # section: variable define
117 ##############################
121 # time cost of a standard testing example, the time unit is ms.
122 # the basic testing example is running on cpu that have performence
123 # between 100MHz and 5GHz. and the shortest test time is 10ms, the max
125 # if it is running on a best cpu at 5GHz, it must longer then 0.01s.
126 # and it also should be shorter then 5s with a 100MHz cpu.
127 # cpu performence is not only decided by frequent. so a 5GHz cpu maybe
128 # more then 5GHz instruction per-second. so, the best cpu maybe 5*50
129 # times then lowest cpu.
130 # let the example testing code cost 0.02s with best cpu, and it will
131 # cost about 5s with lowest cpu.
132 # if one test script cost 0.2s on the best cpu, and save as 10 unit
133 # times. when this script is tested on a middle cpu, UNIT_TEST_MS is
134 # 500ms, it will cost 5s, and it will be displayed on testing info.
135 # if the cpu performence is better then it, it would not display on
143 TESTING_TMP_DIR
=~
/.testing
/$
(basename $0)/
156 readonly FCR2L
="${FCCYAN}"
157 readonly FCL2R
="${FCCYAN}${CREV}"
159 verbos_pfx
=" ${INFOCOLOR}+$CNORMAL "
162 # do not delete this comment, it is used for var define code intert.
164 # args-var-define-begin
165 # args-var-define-end
170 # @ the description string can not contain char of "'".
175 # desc-str for scripttest
176 # @ every paramter desc-str-line start with 'param'.
177 # @ every colum start with '|', and seperated by blanks.
178 # @ '|blank' means a blank line dispalyed in helper.
179 # @ follow with a '' quoated string is the option category string.
180 # @ comment '#' in desc-str is also supported, and can be used to
181 # disable some option have not been implemented.
182 # @ desc-str can be in multiple var. and some of them maybe re-used
183 # for other program by 'source xxx --loadshlib'.
185 scripttest_desc_str
="
186 |prog $0 '应用测试程序。用于对指定目录下的一系列测试脚本运行测试,并输出测试结果。如未指定测试目录参数,以当前目录下的testing目录作为默认测试信息目录,并进行测试。'
188 |blank 'Design File Auto Gen Paramters:'
189 |param |-l |--list |--- |= |%<list_test_list> |&<args_list_item> |'list items and dirs under testing dir.'
190 |param |-S |--save |--- |=<save_desc_file> |%<save_desc_file> |&<args_save_catalog> |'generate catalog from testing dir. if the catalog file is exist, just display desc info only. append -f option to recover an original catalog file. '
191 # -y参数存在bug,不添加到程序功能中。
192 |param |-y |--sync |--- |=[sync_to_dir] |%<sync_to_dir> |&<args_sync_to_dir> |'generate 根据测试信息描述文件,生成测试目录及测试脚本等文件,用于用户编写各种测试用例。'
195 |blank 'General Testing Paramters:'
196 |param |-n |--num |--- |=<test_cnt_num> |%<test_cnt_num> |& |'running N test items continously.'
197 |param |-L |--failed-begin |--- |= |%<failed_begin> |& |'从failed列表中的第一项开始测试。'
198 |param |-F |--failed |--- |= |%<failed_test> |&<args_failed_test> |'test the failed items listed by -a option. it\x27s equal to -L -r -q option.'
199 |param |-r |--ignor-err |--- |= |%<test_ignor_err> |& |'ignor testing error, and running continously.'
200 |param |-a |--all |---all |= |%<test_all> |& |'test for all.'
201 |param |-A |-- |--- |= |%<continouse_all> |&<args_all> |'test for all with -r -q option.'
204 |blank 'Testing Range Paramters:'
205 |param |-t |--test |--- |=<test_id> |%<test_id> |&<args_test_id> |'test a specified item by test item id.'
206 |'the id can be a dir id, that means test the items under the dir. if no id specified, it will test from the beginning id of normal testing.'
207 |param |-b |--begin |--- |=<begin_test_id> |%<begin_test_id> |& |'begin id of testing range.'
208 |param |-e |--end |--- |=<end_test_id> |%<end_test_id> |& |'end id of the testing range.'
209 |param |-x |--exclude |--- |=<exclude_id> |%<exclude_id> |&<args_exclude> |'exclude id that should not be tested.'
210 |param |-R |--rollup |--- |= |%<test_id_rollup> |& |'rollup begin id, if the corresponding item is ok.'
211 |param |-B |--rollback |--- |= |%<test_id_rollback> |& |'rollback begin id to the previous value. it is not simplly decrease the count of id, it will check the test item file first.'
212 |param |-s |--set |--- |= |%<set_test_info> |& |'save the range setted by -b and -e and -x option.'
213 |param |-c |--clean |--- |= |%<clean> |&<args_clean> |'clean testing temp dir.'
216 |blank 'Testing Output Info Paramters:'
217 |param |-u |--update |--- |= |%<update_test_file> |& |'if the current test item is ok, save stdout output to test item as the standard output content.'
218 |param |-v |--verbose |--- |= |%<verbose> |&<args_verbose> |'output the test script outputed with \'+ \' prefix. it is the detail output info for testing.'
219 |param |-q |--quiet |--- |= |%<quiet> |& |'disable comparation string output. but it is not conflect with -v option. use -v -q means output detail string info instead of comparation string.'
222 |blank 'Misc Paramters:'
223 |param |-f |--force |--- |= |%<test_force> |& |'force operation option. it\'s a general option combine with other options.'
224 |param |-j |--multi-task |--- |=<multi_task> |%<multi_task> |& |'multi-task running. set the parall num of tasks.'
229 |blank 'Other Paramters:'
230 |param |-d |--dir |--- |=<test_dir> |%<test_dir> |& |'指定测试信息的目录。默认值为当前目录下的testing目录。'
231 |param |-O |--output-dir |--- |=<output_dir> |%<output_dir> |& |'指定测试时的临时文件目录。默认值为~/用户目录下的.testing目录。'
232 |param |-p |--print-vars |--- |= |%<print_vars> |&<args_print_vars> |'输出参数定义的变量信息。'
233 |param |-m |--mono |--- |= |%<mono> |&<args_mono> |'输出非彩色的字符串信息。'
234 |param |-g |--logfile |--- |= |%<test_logfile> |&<test_logfile> |'测试failed时,不输出差异信息。'
237 |blank 'Version & Helper & Debug:'
238 |param |-V |--version |--- |= |%<version_info> |&<args_version> |'output version info of the program.'
239 |param |-h |-- |--- |= |%<h_info> |&<args_h_info> |'simplly helper doc only for option.'
240 |param |- |--help |--- |= |%<help_info> |&<args_help_info> |'this helper doc.'
241 |param |- |--debug |--- |= |%<test_debug> |&<args_test_debug> |'debug info for arguments dispatch. add the option follow with cmd.'
245 readonly PROG
=`basename $0`
248 # this comment is used for version id auto update.
255 readonly VER_DATE
=20220101
258 readonly eval_PROG_VERSION
="v${V1}.${V2}\${V3:+\".$V3\"}\${VEXT:+\"$VEXT\"}\${VER_DATE:+\"-$VER_DATE\"}"
259 PROG_VERSION
="`eval echo $eval_PROG_VERSION`
260 Copyright (C) 2022- Free Software Foundation, Inc.
261 This configure script is free software; the Free Software
262 Foundation gives unlimited permission to copy, distribute
265 Writen by deven(devenkong@126.com).
268 PROG_BANNER
="$PROG $PROG_VERSION"
269 PROG_SYNTAX
="Usage: $PROG -[lS:n:LFrat:b:e:x:RBscuvd:O:qpmVhfj:g]"
270 PROG_DESC
=" this is a test-suite program to orgnize a lot of test item script. as a direct structure on file system, and execute them. when testing error,it show differece betwin current output content and the correct output content, which saved in the item files.
271 this prog can be used as a unit testing tool, and also can be used as a functional testing tool, to running the program (set) testing before installization, and check if it can be running in current enviroument.
272 i use this util to execute loop-back testing that i tested before. it will save time to test some repeated problem in detail. if i write a new feature for a program, i will check if the new code would make original code error.
273 some of the option description is writen by chinese char, it is used to test utf-8 char dispaly when it works in words bundary truncate feature."
277 @ test soft-pkg before installation:
280 this cmd run a full test continously without faild hint string. it is the same as a loop-back testing for soft-pkg.
282 @ for program loop-back testing:
285 this cmd run a full test continously without faild hint string.
288 test the failed items listed in full testing. fix them one by one.
290 @ for function feature unit testing:
292 scripttest -b 1.1 -e 1.5 -x 1.3 -s
293 this cmd set the test range between 1.1 and 1.5, and exclude 1.3. save the info to testing temp dir. it will effect on next test work.
295 scripttest -n 1 -v -q
296 for unit testing, it test one item, dispaly full output string, disable comparation string output. it is equal to run test script with corresponding feature.
299 if the testing is ok, save test script output string as a standard file. it will effactive on next testing.
303 fmt_usage
="$PROG_BANNER
311 ##############################
312 # section: private function
313 ##############################
318 # testcase目录下测试程序的调用,及输出比较。
322 # fsyntax: test_item <id> <script_name> <desc_str>
323 # fdesc: one item testing.
332 local tmp_vch_output
=
334 script_name
="$1.$2.sh"
337 # paramter validation judgement.
338 if [[ ! -f $script_name ]]; then
339 err
"err: file $script_name is not exist.\n"
343 if [[ -z "$test_desc" ]]; then
344 err
"err: descript string is missing.\n"
348 if [[ ! -f $script_name.
"$test_desc".txt
]]; then
349 err
"err: file $script_name.$test_desc.txt is not exist.\n"
353 # item testing string output.
354 # info "$CHIGHL$IFCCOLOR$TPREFIX[item] $1 $2 \"$3\" ... "
355 info
"$CHIGHL$IFCCOLOR$TPREFIX[item] $1.\"$3\" ... "
358 # copy test item file to temp dir, it keeps every testing
359 # file can not be modified by test script.
361 rm "$TESTING_TMP_DIR/$1.$2/" -rf
362 mkdir
-p "$TESTING_TMP_DIR/$1.$2/"{,scripts
}
363 cp "$1".
* "$TESTING_TMP_DIR/$1.$2/" -rf
364 cp -rf scripts
/"$1".
* "$TESTING_TMP_DIR/$1.$2"/scripts
/ 2> /dev
/null
365 # XXX: here should be modified, if the scripts dir is very large,
366 # it will copy every times for every test script.
367 cp -rf scripts
/* "$TESTING_TMP_DIR/$1.$2"/scripts
/ 2> /dev
/null
368 cp -rf scripts
/testing
/ "$TESTING_TMP_DIR/$1.$2"/scripts
/ 2> /dev
/null
369 cd "$TESTING_TMP_DIR/$1.$2"
371 chmod +x
*.sh
scripts
/* 2> /dev
/null
373 # dispaly testing time cost if this item would cost more then 5 seconds.
374 if [[ -f $1.
$2.
time.txt
]]; then
375 exetime
=`head -n 2 $1.$2.time.txt`
376 tmp
=${exetime##$'\nreal '}
378 [[ -z $tmp ]] && err
"err: the syntax of test time info is not correct.\n"
379 exetime
=${exetime##*m}
380 exetime
=${exetime%.*}
381 exetime
=$
(( tmp
* 60 + exetime
))
382 # dispaly only longer then 5 seconds.
383 [[ -n $exetime && $exetime -gt 5 ]] && info
"(time:${exetime}s) "
387 # here, re-direct output of test script, include stdout and stderr.
388 # using ttyout to force string output when debug this code, event if
389 # the stdout and stderr is re-directed.
391 # ttyout dbgout_ttydev=$dbgout_ttydev
393 # set output stream pipe.
394 tmp_vch_output
=$vch_progstdout
395 [[ $output_disable_list =~
"info" ]] && tmp_vch_output
=$vch_null
399 if [[ $verbose == "enable" ]]; then
401 # time语句的code-block,stdout调试信息输出使用stderr,time语句输出到stderr,设置stderr输出为time.txt
402 # time语句内的code-block,stderr输出到stdout
403 # 这样,time的stderr输出到time.txt文件,time之内的code-block输出到vch_dbgout(stderr)
407 info
"\n${INFOCOLOR} + ###############################################${CNORMAL}\n" ;
408 { { .
/$script_name; echo; } 2>&1 |
tee log.txt
; } |
{ IFS
=$
'\n'; while read -r line
; do echo -ne "$verbos_pfx$line\n"; done } ;
409 info
"${INFOCOLOR} + ###############################################${CNORMAL}\n" ;
411 } >&$tmp_vch_output 2>time.txt
415 # ttyout "testing\n";
416 # info "\n###############################################\n" ;
417 # ttyout "testing\n";
418 # # 输出测试脚本的stdout和stderr到管道,管道的调试信息使用tee在控制台stdout输出,并保存到日志文件
419 # ( ./$script_name 2>&1 ) | tee log.txt;
420 # info "###############################################\n" ;
421 # ttyout "testing\n";
422 # ) 2>&1 # | { IFS=$'\n'; while read -r line; do echo "$verbos_pfx$line"; done } >&$vch_dbgout #2> /dev/null
423 # ) 2> time.txt #2>&1
425 # an echo cmd append at the end of test script.
426 # script output string though pipe, but there must be a '\n' at the end
427 # of string, or it will not be displayed on screen.
428 ( time ( ( .
/$script_name; echo; ) > log.txt
2>&1 ) ) 2> time.txt
#2>&1
431 # append to log file.
432 if [[ ! $logout_disable_list =~
"info" ]]; then
433 echo -ne "$INFO_PFX$@$NEWLINE_SFX" |
tee -a $f_logout >&$vch_progstdout
435 echo "$tmp" >> $f_logout
437 done < <(cat log.txt
)
441 # cp log.txt $PWD/log/
442 diff log.txt
"$script_name.$test_desc".txt
> diff.txt
443 if [[ -z "`head -n 5 diff.txt`" ]]; then
444 info
"$CHIGHL$INFOCOLOR[ ok ]$CNORMAL\n"
447 # 如果有failed record,进行记录。
448 sed -i $TESTING_TMP_DIR/testing_failed_list.txt
-e "/^$(catalog_id_get TEST)$/d" 2>/dev
/null
450 info
"$CHIGHL$EFCCOLOR[failed]$CNORMAL\n"
451 if [[ $quiet != "enable" ]]; then
452 info
"testing result difference from correct output.\n"
453 info
"stdout > testout\n"
454 info
"###############################################\n"
459 info
-ne "${FCL2R}>${CNORMAL}${data:1}\n"
462 info
-ne "${FCR2L}<${CNORMAL}${data:1}\n"
469 # dbgout_cmd cat diff.txt # >&2
470 # 将测试failed项的日志保存到log目录,便于测试后的查看。
471 info
"###############################################\n"
476 sed -i $TESTING_TMP_DIR/testing_failed_list.txt
-e "/^$(catalog_id_get TEST)$/d" 2>/dev
/null
477 catalog_id_get TEST
>> $TESTING_TMP_DIR/testing_failed_list.txt
481 if [[ $update_test_file == "enable" ]]; then
482 cp "$TESTING_TMP_DIR/$1.$2"/log.txt
"$script_name.$test_desc".txt
483 exetime
=`head -n 2 $TESTING_TMP_DIR/$1.$2/time.txt`
485 tmp
=${tmp##`echo -ne "\nreal "`} # }
486 exetime
=${exetime##*m}
487 exetime
=${exetime%.*}
488 exetime
=$
(( tmp
* 60 + exetime
))
489 [[ -n $exetime && $exetime -gt 5 ]] && cp "$TESTING_TMP_DIR/$1.$2"/time.txt
"$1.$2".
time.txt
493 rm "$TESTING_TMP_DIR/$1.$2/" -rf
499 # test_unit <test_dir>
509 test_cnt
=`test_list_curr_content "$test_dirs" |
510 ( while read line; do
512 catalog_id_step_to TEST "${tmp[1]}"
515 catalog_id_compare TEST "${tmp[1]}"
517 # dbgoutd "chk_ret=$chk_ret\n"
532 TPREFIX="$(printf '%*s' $(( $TEST_DIR_DEPTH * 4 + 4)) ' ')"
533 #dbgoutd "TEST_DIR_DEPTH=$TEST_DIR_DEPTH\n"
535 test_cnt=$(( test_cnt + 1 ))
537 test_item "${tmp[1]}" "${tmp[3]}" "${tmp[2]}"
539 if [[ $? != 0 ]]; then
540 err_cnt=$(( err_cnt + 1 ))
541 err_continue_cnt=$(( err_continue_cnt + 1 ))
542 if [[ $test_ignor_err != "enable" ]]; then
543 err "err interrupt ...\n"
547 [[ $err_continue_cnt -ge 10 ]] && ret=1
550 if [[ $err_continue_cnt != 0 ]]; then
555 if [[ -n $test_cnt_num && $test_cnt -ge $test_cnt_num ]]; then
559 # curr_test_id[$saved_test_id]="${tmp[1]}"
560 # TEST_DIR_DEPTH=$(( TEST_DIR_DEPTH - 1 ))
561 # TPREFIX=$(printf "%*s" $(( $TEST_DIR_DEPTH * 4)) " ")
563 [[ $ret == 1 ]] && break
565 "module" | "unit" | "dir" )
566 if [[ -n $test_cnt_num && $test_cnt -gt $test_cnt_num ]]; then
571 catalog_id_step_into TEST "${tmp[1]}"
573 TPREFIX="$(printf '%*s' $(( $TEST_DIR_DEPTH * 4)) ' ')"
575 info "$CHIGHL$FCCOLOR$TPREFIX[${tmp[0]}] ${tmp[1]}.\"${tmp[2]}\" begin testing ...$CNORMAL\n"
577 test_unit "${tmp[1]}.${tmp[3]}.${tmp[2]}.${tmp[0]}"
580 catalog_id_step_out TEST "${tmp[1]}"
582 TPREFIX=$(printf "%*s" $(( $TEST_DIR_DEPTH * 4)) " ")
583 [[ $ret != 0 ]] && break
589 [[ $chk_ret == 3 ]] && break
590 done; echo $test_cnt $err_cnt $err_continue_cnt $TEST_CID_STATE $TEST_DIR_DEPTH ; return $ret ); return $?`
592 # while语句由于|pipe操作符,以一个sub-process运行,所以使用return和exit都只是从sub-process中退出。
593 # sub-proc中的环境变量test_cnt在return之前echo,在循环结束时echo,以stdout赋值给外部的test_cnt。
596 test_cnt
=( $test_cnt )
597 err_cnt
=${test_cnt[1]}
598 err_continue_cnt
=${test_cnt[2]}
599 catalog_id_set_init_state TEST
"${test_cnt[3]}"
601 TEST_DIR_DEPTH
=${test_cnt[4]}
605 [[ $err_continue_cnt -ge 10 ]] && info
"连续10个测试项failed,暂停测试。\n" && ret
=1
611 readonly skip_file_pfx
="="
613 # 列出指定目录下的测试内容,包括模块、单元、目录、测试项
614 # test_list_content <path>
615 test_list_curr_content
()
621 test_list_depth
=$
((test_list_depth
++))
630 # 忽略.txt文件,在处理.sh文件时再进行处理
631 [[ $file =~
".txt" ]] && continue
633 # 以小数点分隔,包含3个字符串的为测试脚本
634 # 包含3个字符串的为测试模块/单元/目录
642 # [[ ${tmp[1]} =~ "^[:digital:]" ]] && continue
644 if [[ ${tmp[0]:0:1} == $skip_file_pfx ]]; then
645 # ignor this file with "=" pfx.
646 dbgoutd
"'$file' is ignored.\n"
647 elif [[ ${#tmp[@]} == 5 ]]; then
648 test_desc
=`ls -d -1 "$file.*.txt"`
649 [[ -z "$test_desc" ]] && echo "err: 123aaa txt description file not found for $file." >&2 && return 1
650 test_desc
="${test_desc#$file\.}"
651 test_desc
="${test_desc%\.txt}"
652 script_name
=${tmp[1]}
653 elif [[ ${#tmp[@]} == 4 ]]; then
656 echo "\"${tmp[3]}\" \"${tmp[0]}\" \"${tmp[2]}\" \"${tmp[1]}\""
659 echo "\"${tmp[3]}\" \"${tmp[0]}\" \"${tmp[2]}\" \"${tmp[1]}\""
662 echo "\"${tmp[3]}\" \"${tmp[0]}\" \"${tmp[2]}\" \"${tmp[1]}\""
665 elif [[ ${#tmp[@]} == 3 ]]; then
666 if [[ "${tmp[2]}" == "sh" ]]; then
667 test_desc
=`eval ls -d -1 "$file.*.txt"`
669 [[ -z $test_desc ]] && echo "err: txt descript file not found for $file." >&2 && return 1
670 test_desc
=${test_desc#$file\.}
671 test_desc
=${test_desc%\.txt}
673 echo "\"item\" \"${tmp[0]}\" \"$test_desc\" \"${tmp[1]}\""
676 done < <(eval ls -1 "$tmp" |
sort -n)
678 test_list_depth
=$
((test_list_depth--
))
683 # test_list_full_content <test_dir>
684 test_list_full_content
()
690 test_list_curr_content
$test_dirs |
701 test_dir_level
=$
(( test_dir_level
+ 1 ))
702 TPREFIX
=`printf "%*s" $(( $test_dir_level * 4)) " "`
704 echo -ne "$TPREFIX[item] ${tmp[1]} ${tmp[3]} \"${tmp[2]}\"\n"
706 test_dir_level
=$
(( test_dir_level
- 1 ))
707 TPREFIX
=`printf "%*s" $(( $test_dir_level * 4)) " "`
710 "module" |
"unit" |
"dir" )
711 test_dir_level
=$
(( test_dir_level
+ 1 ))
712 TPREFIX
=`printf "%*s" $(( $test_dir_level * 4)) " "`
714 echo -ne "$TPREFIX[${tmp[0]}] ${tmp[1]} ${tmp[3]} \"${tmp[2]}\"\n"
716 test_list_full_content
"${tmp[1]}.${tmp[3]}.${tmp[2]}.${tmp[0]}"
718 test_dir_level
=$
(( test_dir_level
- 1 ))
719 TPREFIX
=`printf "%*s" $(( $test_dir_level * 4)) " "`
726 # replace tab with blank string.
743 # output dir under srcpkg.
755 # 根据node的名称,id-position,desc,ntype进行顺序的comp(不包含cont的node),并设置{new}/{del}{modify}的tag。同时将对应的修改的node保存到new/del/modify.tmp文件。
756 # 在new catalog文件之中,匹配org文件之中的new/del/modify的node,是否有相同/相近的node,以fullcataid的{=>}表示,并添加{mov}的tag。
757 # 对于modify的node,比对NCATAID,NTYPE,NNAME,NDESC,输出{=>}修改信息
761 # # 对于node的new/del/modify/mov进行文件操作
767 # # on dir enter/exit
769 # + NCATAID=>NFULLCATAID
771 # + NTYPE=>SRC_TYPE if NODE_TYPE=srcdir
772 # + NTYPE=>ITEM_TYPE if NODE_TYPE=item
774 # + NFEXT=>DIR_TYPE=>DIR_TYPE_LIST,
775 # + NFEXT=>FILE_EXT_LIST
776 # # for one output dir,
777 # + DIR_TYPE+SRC_TYPE=>SRC_DIR_TYPE
778 # + OUTPUT_SUBDIR_FMT[$DIR_TYPE]=>
779 # OUTPUT_SUBDIR(dir under SRCPKG_DIR)
780 # + OUTPUT_${SRC_TYPE^^}_SUBDIR_FMT[$DIR_TYPE]=>
781 # OUTPUT_${SRC_TYPE^^}_SUBDIR(dir under OUTPUT_SUBDIR)
782 # + NODE_DIR_FMT[$DIR_TYPE]=>
783 # NODE_DIR(dir name if NODE_TYPE=dir,append to CATALOG_DIRS)
784 # + NODE_ITEMDIR_FMT[$DIR_TYPE]=>
785 # NODE_ITEMDIR(ITEM dir if needed/defined)
786 # + NODE_${SRC_TYPE^^}_ITEMDIR_FMT[$DIR_TYPE]=>
787 # NODE_ITEMDIR(if NODE_ITEMDIR is not exist)
788 # + NODE_DIR=>CATALOG_DIRS(if NODE_TYPE=dir)
790 # OUTPUT_${SRC_TYPE^^}_SUBDIR+
792 # OUTPUT_DIR_FMT[$DIR_TYPE]=>
794 # # for one file in one output dir of a node。
795 # + FILE_EXT_LIST=>FEXT
796 # + FNAME_FMT[$FEXT]+
797 # NODE_ITEMDIR=>FNAME,
798 # + FNAME_REGEX[$FEXT],
799 # + NXXX_REGEX[$FEXT],
800 # + FNAME=>FNAME_LIST(used for existing chk & gen)
801 # # 参数backup,使用{=>}修改之后的再输出参数,进行org=>new的输出chk,并mv
802 # # 如果未包含修改flag,使用org的参数chk,并输出文件。
808 # 遍历node,对于包含cont的item node,解析后的信息(包含uniq-id一家文件路径)保存到设计文件。
810 # 包含cont的item node,这些node需要输出code对于。先进行chk,输出需要进行new/del/modify/mov操作的操作信息和文件列表。
816 # OUTPUT_DIR, output dir.
817 # CATA_DIR, catalog in dir.
818 # NODE_DIR, dir for node if needed.
820 # NFULLCATAID, $(echo ${NCATAID[@]} | tr ' ' '.')
821 # NODE_TYPE: srcdir/ignrdir/dir/item/cont, default is srcdir.
822 # SRC_TYPE, if NODE_TYPE == srcdir, it is bin/shlib/lib/src/example.
823 # ITEM_TYPE, if NODE_TYPE == item, it is equal to NTYPE. it's used to get item cfg-info.
826 # DIR_TYPE_LIST, output dirs for current node.
827 # FILE_NAME_LIST[]/NODE_FILES[], file list in one node under one kind of output dir.
828 # @ one output dir in a node.
829 # DIR_TYPE, it's used in defination of NFTYPE. srcdir/docdir/designdir/testdir.
830 # SRC_DIR_TYPE, src dir name for defination in imi (catalog::${SRC_DIR_TYPE}::).
831 # "$SRC_TYPE$DIR_TYPE"
832 # SUBDIR, current SRC_DIR_TYPE output dir prefix.
837 # G_OUTPUT_SUBDIR[docdir]="doc/UM.md.zh_CN"
838 # G_OUTPUT_SUBDIR[designdir]="doc/design"
839 # G_OUTPUT_SUBDIR[testdir]="testing"
840 # G_OUTPUT_SUBDIR[srcdir]="src" # lib/bin/shlib
842 # G_NODE_DIR_FMT[]='@{NCATAID}.@{NNAME}'
843 # G_OUTPUT_DIR_FMT[]='@{SRCPKG_DIR}/@{SUBDIR}/@{LAYEDDIR}/@(NODEDIR)'
844 # G_FILE_NAME_FMT[]='@{NFULLCATAID}.@{NNAME}.@{NFEXT}.md'
846 # G_FILE_EXT_LIST[], generated in various item node.
855 DIR_TYPE_LIST
="${line%::*}"$
'\n'
856 FILE_EXT_LIST
=( ${line#*::} )
857 for DIR_TYPE
in ${line%::*}; do
858 SRC_DIR_TYPE
=${SRC_TYPE}${DIR_TYPE}
859 SUBDIR
="$(attr_get catalog::${DIR_TYPE}::SUBDIR)"
860 OUTPUT_DIR_FMT
="$(attr_get catalog::${DIR_TYPE}::OUTPUT_DIR_FMT)"
861 STR_FMT
="$(attr_get catalog::${DIR_TYPE}::STR_FMT)"
864 for ext
in $FILE_EXT_LIST; do
865 STR_FMT
="$(attr_get catalog::$ext::STR_FMT)"
867 FILE_NAME_LIST
[$DIR_TYPE]+="touch $(STR)"$
'\n'
874 # get info from $NCATAID $NTYPE $NNAME $NDESC
882 # NTYPE => node-type, src-type
884 if [[ "$NTYPE" =~ dir$
]]; then
885 # NULL/src/lib/bin/shlib/ex
886 SRC_TYPE
="${NTYPE%dir}"
889 [[ "$NTYPE" == 'ignr' ]] && retur
1
890 elif [[ "$NTYPE" =~ ^cont
]]; then
891 # keep SRC_TYPE processed before.
902 DIR_TYPE_LIST
="${line%::*}"$
'\n'
903 FILE_EXT_LIST
=( ${line#*::} )
904 for DIR_TYPE
in ${line%::*}; do
905 SRC_DIR_TYPE
=${SRC_TYPE}${DIR_TYPE}
906 SUBDIR
="$(attr_get catalog::designdir::SUBDIR)"
907 OUTPUT_DIR_FMT
="$(attr_get catalog::designdir::OUTPUT_DIR_FMT)"
908 STR_FMT
="$(attr_get catalog::designdir::STR_FMT)"
911 for ext
in $FILE_EXT_LIST; do
912 STR_FMT
="$(attr_get catalog::$ext::STR_FMT)"
914 FILE_NAME_LIST
[$DIR_TYPE]+="touch $(STR)"$
'\n'
920 for DIR_TYPE
in $DIR_TYPE_LIST; do
921 # switch dir content.
922 ${OUTPUT_DIR[$DIR_TYPE]}
930 eval "${FILE_NAME_LIST[$DIR_TYPE]}"
942 GetNodeOutputFileList
()
947 CreateOutputFileInList
()
961 if [[ -n $lastdir ]]; then
962 [[ ! -d $lastdir ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
964 # info "cd $lastdir\n"
972 if [[ "${lastdir##*.}" =~
"txt" ]]; then
973 # [[ -n $lastdir ]] && info "item $lastdir\n"
974 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
976 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
979 for (( i
=cnt
/tabcnt
; i
< lastcnt
/tabcnt
; i
++ )); do
987 if [[ "${lastdir##*.}" =~
"txt" ]]; then
988 # [[ -n $lastdir ]] && info "item $lastdir\n"
989 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
991 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
996 # design file analyzing.
1006 #GetNodeOutputFileList
1007 #CreateOutputFileInList
1009 # 根据缩进字符数判断所需创建的目录结构
1010 if [[ $cnt -gt $lastcnt ]]; then
1012 elif [[ $cnt -eq $lastcnt ]]; then
1019 # case $NODE_TYPE in
1021 # lastdir="$id.$name.$desc.$type"
1024 # lastdir="$id.$name.sh.$desc.txt"
1029 # warn "unkown type [$type] ($line)\n"
1034 "module" |
"unit" |
"dir" )
1035 # printf "%*s" $((tab*4)) " "
1036 # info "$id.$name.$type\n"
1037 lastdir
="$id.$name.$desc.$type"
1040 # printf "%*s" $((tab*4)) " "
1041 # info "$id.$name.sh.$desc.txt\n"
1043 lastdir
="$id.$name.sh.$desc.txt"
1046 warn
"unkown type [$type] ($line)\n"
1054 line
=`echo $line | tr '.' ' ' | tr -s "[\t| ]"`
1056 # TBD: this operation should use str2var() to get variables.
1068 TEST_STR_CATANODE_SRCDIR_1
='<1> [srcdir] TestDir1 "test dir 1"'
1069 TEST_STR_CATANODE_SRCDIR_1_FMT
='<@{NCATAID}> [@{NTYPE}] @{NNAME} "@{NDESC}"'
1070 TEST_STR_CATANODE_SRCDIR_1_VAR
='NCATAID=1; NTYPE=srcdir; NNAME=TestDir1; NDESC=test dir 1; '
1073 # design file analyzing.
1081 # get data in var by node format
1082 STR_FMT
="$(attr_get catalog::catanode::STR_FMT)"
1083 echo STR_FMT
="$STR_FMT"
1088 # PAIRCHARS='<>[]""'
1089 # STR_FMT="${TEST_STR_CATANODE_SRCDIR_1_FMT}"
1090 # str2var @TEST_STR_CATANODE_SRCDIR_1
1093 # if [[ $NCATAID =~ .*[\{](.*)=>(.*)[\}].* ]]; then
1097 declare -p NTYPE NCATAID NNAME NDESC
1099 catalog_id_get CATALOG
1101 # 根据缩进字符数判断所需创建的目录结构
1102 if [[ $cnt -gt $lastcnt ]]; then
1103 catalog_id_step_into CATALOG
"$id"
1105 elif [[ $cnt -eq $lastcnt ]]; then
1106 catalog_id_step_to CATALOG
"$id"
1110 catalog_id_step_out CATALOG
"$id"
1116 OnEndofCataNodeProc
()
1119 if [[ $cnt -gt $lastcnt ]]; then
1120 if [[ -n "$lastdir" ]]; then
1121 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1123 # info "cd $lastdir\n"
1125 elif [[ $cnt -eq $lastcnt ]]; then
1126 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1127 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1129 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1132 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1133 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1135 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1137 for (( i
=cnt
/tabcnt
; i
< lastcnt
/tabcnt
; i
++ )); do
1145 # design file analyzing.
1148 catalog_each_line
()
1152 local tabcnt
= # blank count equals to a tab.
1153 local tabstr
= # a string equals to a tab.
1154 local tab
= # number of tabs in line post-stage.
1156 while read -r line
; do
1157 [[ $verbose == "enable" ]] && info
"line=$line\n"
1158 [[ ! $line =~
"[" ||
${line:0:1} =~ ^
[[:blank
:]]*\
# ]] && continue
1161 # get tab and blank count as catalog level number.
1167 eval "cnt=\"\${cnt//$'\t'/$TAB_BLANK_STR}\""
1168 # cnt=`echo "$cnt" | wc -c`
1171 lastcnt
=${lastcnt:-"$cnt"}
1173 # value in the first line to be the size unit in current file.
1174 [[ -z $tabcnt ]] && tabcnt
=$
(( cnt-1
)) && tabstr
=`printf "%*s" $((tab*tabcnt)) " "`
1175 [[ $tabcnt == 0 ]] && tabcnt
=4 && tabstr
=`printf "%*s" $((tab*4)) " "`
1176 tab
=$
(( cnt
/${tabcnt:-'4'} ))
1178 # get full cataid paramter.
1181 # analyze string to node variable.
1182 # NCATAID, NTYPE, NNAME, NDESC
1188 testcase_framework_gen_new
()
1196 cataid_create CATALOG
1197 catalog_id_set_init_state CATALOG
"inner"
1199 # attr_create catalog::catanode::STR_FMT='<@{NCATAID}>@{ALIAN}[@{NTYPE}]@{ALIAN}@{NNAME}@{ALIAN}[@{NDESC}]'
1200 attr_create catalog
::catanode
::STR_FMT
='<@{NCATAID}>@{ALIAN}[@{NTYPE}]@{ALIAN}@{NNAME}@{ALIAN}[@{NDESC}]'
1202 tmp
=${tmp:-"funclist.txt"}
1203 if [[ ! -e $tmp ]]; then
1204 err
"function list file '$tmp' is not exist.\n"
1208 cp "$tmp" "$TESTING_TMP_DIR/"
1209 tmp
=$TESTING_TMP_DIR/`basename $tmp`
1212 # analyze catalog file.
1213 catalog_each_line
"$tmp"
1217 # 描述文件中第一个有效行的空格数或tab数为缩进字符串的单位,用于计算目录层数。
1220 testcase_framework_gen
()
1235 # 使用' '时 read读取数据,' '用于分隔。
1241 tmp
=${tmp:-"funclist.txt"}
1242 if [[ ! -e $tmp ]]; then
1243 err
"function list file '$tmp' is not exist.\n"
1247 cp "$tmp" "$TESTING_TMP_DIR/"
1248 tmp
=$TESTING_TMP_DIR/`basename $tmp`
1250 while read -r line
; do
1251 [[ $verbose == "enable" ]] && info
"line=$line\n"
1252 [[ ! $line =~
"[" ||
${line:0:1} == '#' ]] && continue
1254 # 使用第一个有效行的空格数为tabcnt
1259 tmp
=`echo "$tmp" | wc -c`
1261 lastcnt
=${cnt:-"$((tmp-1))"}
1263 [[ -z $tabcnt ]] && tabcnt
=$
(( tmp-1
)) && tabstr
=`printf "%*s" $((tab*tabcnt)) " "`
1264 [[ $tabcnt == 0 ]] && tabcnt
=4 && tabstr
=`printf "%*s" $((tab*4)) " "`
1265 tab
=$
(( cnt
/${tabcnt:-'4'} ))
1268 line
=`echo $line | tr '.' ' ' | tr -s "[\t| ]"`
1281 # 根据缩进字符数判断所需创建的目录结构
1282 if [[ $cnt -gt $lastcnt ]]; then
1283 if [[ -n $lastdir ]]; then
1284 [[ ! -d $lastdir ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1286 # info "cd $lastdir\n"
1288 elif [[ $cnt -eq $lastcnt ]]; then
1289 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1290 # [[ -n $lastdir ]] && info "item $lastdir\n"
1291 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1293 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1296 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1297 # [[ -n $lastdir ]] && info "item $lastdir\n"
1298 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1300 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1302 for (( i
=cnt
/tabcnt
; i
< lastcnt
/tabcnt
; i
++ )); do
1309 "module" |
"unit" |
"dir" )
1310 # printf "%*s" $((tab*4)) " "
1311 # info "$id.$name.$type\n"
1312 lastdir
="$id.$name.$desc.$type"
1315 # printf "%*s" $((tab*4)) " "
1316 # info "$id.$name.sh.$desc.txt\n"
1318 lastdir
="$id.$name.sh.$desc.txt"
1321 warn
"unkown type [$type] ($line)\n"
1328 if [[ $cnt -gt $lastcnt ]]; then
1329 if [[ -n "$lastdir" ]]; then
1330 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1332 # info "cd $lastdir\n"
1334 elif [[ $cnt -eq $lastcnt ]]; then
1335 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1336 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1338 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1341 if [[ "${lastdir##*.}" =~
"txt" ]]; then
1342 [[ ! -e "$lastdir" ]] && info
"create item ($lastdir)\n" && touch "$lastdir" && touch "${lastdir%.sh*}.sh"
1344 [[ ! -d "$lastdir" ]] && info
"create dir ($lastdir)\n" && mkdir
-p "$lastdir"
1346 for (( i
=cnt
/tabcnt
; i
< lastcnt
/tabcnt
; i
++ )); do
1356 # fsyntax: testing_paths_init [<base-tmp-dir>]
1358 testing_paths_init
()
1361 # 测试目录使用-d参数对应的test_dir环境变量
1363 # 默认为当前路径下的testing目录。
1365 if [[ -n $test_dir ]]; then
1366 if [[ -d $test_dir ]]; then
1369 err
"err: parameter -d specified a invalid path $test_dir\n"
1374 if [[ ! -d $test_path ]]; then
1378 [[ ! -d $test_path ]] && err
"err: testcase dir is not exist.\n" && exit
1380 mkdir
-p "$test_path"
1387 # 目录名称添加testcase路径的cksum,避免同一个软件包不同目录时,
1390 TESTING_TMP_DIR
=$
(basename $0)-$TESTING_TMP_DIR
1391 if [[ -n $1 ]]; then
1392 TESTING_TMP_DIR
="$1/"
1393 [[ -d $1 ]] && TESTING_TMP_DIR
=~
/.testing
/ && warn
"directoy specified \"$1\" is not existing, use default directrory \"$TESTING_TMP_DIR\" instead.\n"
1395 TESTING_TMP_DIR
=~
/.testing
/
1398 mkdir
-p "$TESTING_TMP_DIR"
1399 cd "$TESTING_TMP_DIR"
1400 TESTING_TMP_DIR
=$PWD
1403 TESTING_TMP_DIR
=$TESTING_TMP_DIR/$
(basename $0)-$
(echo $test_path |
cksum - | cut
-d ' ' -f1)
1405 mkdir
-p "$TESTING_TMP_DIR"
1409 # fsyntax: testing_catalog_id_init
1410 # fdesc: range id init is a general feature programs. this function can be used in
1413 testing_catalog_id_init
()
1420 local tmp_exclude_id
="$exclude_id"
1421 local tmp_begin_test_id
="$begin_test_id"
1422 local tmp_end_test_id
="$end_test_id"
1424 [[ -e $TESTING_TMP_DIR/test_id.txt
]] && source $TESTING_TMP_DIR/test_id.txt
1425 [[ -n $tmp_exclude_id && $tmp_exclude_id =~
[^\
] ]] && exclude_id
="$tmp_exclude_id"
1426 [[ -n $tmp_begin_test_id ]] && begin_test_id
="$tmp_begin_test_id"
1427 [[ -n $tmp_end_test_id ]] && end_test_id
="$tmp_end_test_id"
1428 unset tmp_exclude_id
1429 unset tmp_begin_test_id
1430 unset tmp_end_test_id
1434 # 以testing目录中保存的起止id、参数设置、failed测试项的
1437 if [[ $failed_begin == "enable" && -f $TESTING_TMP_DIR/testing_failed_list.txt
]]; then
1438 tmp
=$
(head -n 1 $TESTING_TMP_DIR/testing_failed_list.txt
)
1439 [[ -n $tmp ]] && begin_test_id
=$tmp
1442 if [[ $test_all == "enable" ]]; then
1445 # test_ignor_err="enable"
1447 exclude_id
=$
(echo "${exclude_id}" |
tr ' ' '\n' |
sort - |
uniq)
1448 exclude_id
=" $(echo "${exclude_id}" | tr "$
'\n'" ' ') "
1452 catalog_id_set_init_state TEST
"inner"
1453 if [[ -n $end_test_id ]]; then
1454 catalog_id_set_end_id TEST end_test_id
1457 if [[ -n $begin_test_id ]]; then
1458 catalog_id_set_begin_id TEST begin_test_id
1460 # 如果有begin-id,默认起始状态为 lower
1461 catalog_id_set_init_state TEST
"lower"
1464 # dbgoutd "TEST_CID_STATE=${TEST_CID_STATE[@]}\n"
1465 # dbgoutd "TEST_CID_BEGIN=${TEST_CID_BEGIN[@]}\n"
1466 # dbgoutd "TEST_CID_END=${TEST_CID_END[@]}\n"
1468 if [[ $test_all == "enable" ]]; then
1472 catalog_id_set_begin_id TEST begin_test_id
1473 catalog_id_set_end_id TEST end_test_id
1475 # 如果有begin-id,默认起始状态为 lower
1476 catalog_id_set_init_state TEST
"inner"
1480 catalog_id_begin_end_chk TEST
1483 if [[ $test_id_rollup == "enable" ]]; then
1484 [[ -z $begin_test_id ]] && echo "请使用-b参数指定起始测试编号" && exit
1486 catalog_id_rollup_in_dir TEST begin_test_id
$test_path
1488 [[ $ret != 0 ]] && exit
1490 begin_test_id
=${TEST_CID_BEGIN[@]}
1491 begin_test_id
=${begin_test_id// /.}
1492 set_test_info
="enable"
1496 if [[ $test_id_rollback == "enable" ]]; then
1497 [[ -z $begin_test_id ]] && echo "请使用-b参数指定起始测试编号" && exit
1499 catalog_id_rollback_in_dir TEST begin_test_id
$test_path
1500 [[ $?
!= 0 ]] && exit
1502 begin_test_id
=${TEST_CID_BEGIN[@]}
1503 begin_test_id
=${begin_test_id// /.}
1504 set_test_info
="enable"
1508 if [[ $set_test_info == "enable" ]]; then
1509 [[ -z $begin_test_id && -z $end_test_id && -z $exclude_id && ! $exclude_id =~
[^\
] ]] && echo "请使用-x-b-e参数指定起止测试编号和exclude-id" && exit
1511 info
"begin test_id: ${begin_test_id[@]}\n"
1512 info
"end test_id: ${end_test_id[@]}\n"
1513 info
"exclude test_id: '$exclude_id'\n"
1516 mkdir
-p "$TESTING_TMP_DIR"
1517 echo "# [paramters]" > $TESTING_TMP_DIR/test_id.txt
1518 [[ -n $begin_test_id ]] && echo "begin_test_id=${begin_test_id}" >> $TESTING_TMP_DIR/test_id.txt
1519 [[ -n $end_test_id ]] && echo "end_test_id=${end_test_id}" >> $TESTING_TMP_DIR/test_id.txt
1520 [[ -n $exclude_id && $exclude_id =~
[^\
] ]] && echo "exclude_id='`echo ${exclude_id}`'" >> $TESTING_TMP_DIR/test_id.txt
1522 info
"test id saved!\n"
1524 # 测试id保存时,不进行测试,便于testcase中测试起止id编号
1528 # dispaly test id range.
1529 if [[ -n ${begin_test_id[@]} ||
-n ${end_test_id[@]} ]]; then
1530 info
"Test from <${begin_test_id[@]}> to <${end_test_id[@]}>.\n"
1531 [[ -n $exclude_id ]] && info
"Except: ${exclude_id}\n"
1533 info
"Full item testing.\n"
1534 [[ $exclude_id =~
[^\
] ]] && info
"Except: ${exclude_id}\n"
1536 [[ -n ${test_cnt_num} ]] && info
"Test item count: ${test_cnt_num}\n"
1541 if [[ $err_cnt != 0 ]]; then
1542 info
"$EFCCOLOR($FCGREEN$test_cnt$EFCCOLOR) items is tested,Error count is ($FCGREEN$err_cnt$EFCCOLOR)$CNORMAL\n"
1544 info
"$FCGREEN($test_cnt) items is tested,Error count is ($err_cnt)$CNORMAL\n"
1549 # option action function list.
1560 if [[ $test_force == "enable" ]]; then
1561 test_list_full_content
$test_path
1563 test_list_full_content
$test_path |
more
1571 args_save_catalog
()
1573 info
"generate catalog from testing dir!\n"
1575 [[ -z $1 ]] && return
1584 # 描述文件中第一个有效行的空格数或tab数为缩进字符串的单位,用于计算目录层数。
1592 info
"generate testing dir framework from catalog!\n"
1594 [[ -z $tmp ||
! -f $tmp ]] && tmp
=$3
1599 [[ ! -f $tmp ]] && tmp
="$test_path/funclist.txt"
1600 [[ ! -f $tmp ]] && err
"err: file ($tmp) does not exist.\n" && exit
1602 path
=$
(basename $tmp)
1610 # 比较已有的testcase目录与func_list,对差异部分进行更新。
1612 testcase_framework_gen_new
$path
1618 # todo:-F参数的-n未添加,以及err_cnt信息
1626 local curr_path
=$PWD
1629 catalog_id_set_begin_id TEST
""
1630 catalog_id_set_end_id TEST
""
1636 catalog_id_init TEST
1638 info
"failed item testing!\n"
1640 # dbgout_cmd cat $TESTING_TMP_DIR/testing_failed_list.txt
1642 [[ ! -f $TESTING_TMP_DIR/testing_failed_list.txt
]] && warn
"testing failed recode is not exist.\n" && exit
1644 while read test_id
; do
1645 [[ -z $test_id ]] && continue
1646 args_test_id
$test_id "continue"
1648 if [[ $test_ignor_err != "enable" ]]; then
1649 err
"err interrupt ...\n"
1653 done < $TESTING_TMP_DIR/testing_failed_list.txt
1655 if [[ -e $TESTING_TMP_DIR/testing_failed_list.txt
]]; then
1656 cat $TESTING_TMP_DIR/testing_failed_list.txt |
sort -n |
uniq > ~
/testing_failed_list.txt
1657 mv ~
/testing_failed_list.txt
$TESTING_TMP_DIR/testing_failed_list.txt
1668 declare -g -x test_all
="enable"
1669 declare -g -x test_ignor_err
="enable"
1670 declare -g -x quiet
="enable"
1682 local curr_path
=$PWD
1685 catalog_id_set_begin_id TEST
""
1686 catalog_id_set_end_id TEST
""
1692 catalog_id_init TEST
1695 [[ ! ( -n $2 && "$2" == "continue" ) ]] && info
"test specified item($test_id).!\n"
1697 [[ "$1" =~
[^
0-9.
] ]] && test_id
=$3
1698 [[ "$test_id" =~
[^
0-9.
] ]] && err
"test id($test_id) is not correct.\n" && exit
1702 test_id
=( $test_id )
1708 for (( i
=0; i
<cnt
; i
++ )); do
1709 [[ -z ${test_id[$i]} ]] && err
"err: test_id[$i] does not invalid.\n" && exit
1711 tmp
="`find $id.* -maxdepth 1 -type d 2>/dev/null`"
1714 if [[ -d $tmp ]]; then
1717 catalog_id_step_into TEST
"$id"
1720 tmp
=( `ls -1 "$id".*.sh 2>/dev/null` )
1722 [[ -e ${tmp[0]} ]] && break
1723 warn
"test id '$1' is not a valid id.\n"
1728 # use the script code to retest for loop back testing.
1729 if [[ $i == $cnt ]]; then
1734 [[ -z $2 ||
"$2" == "continue" ]] && exit
1739 # todo:这里可以改为测试一个unit
1740 [[ -z $tmp ]] && err
"err: test id ($1) does not specify a valide test item file.\n" && exit
1742 tmp
=`ls -d "$id".*.txt`
1743 [[ -z $tmp ]] && err
"err: test id ($i) does not contain a corresponding txt description file.\n" && exit
1750 catalog_id_step_to TEST
"${tmp[0]}"
1752 test_item
"${tmp[0]}" "${tmp[1]}" "${tmp[3]}"
1755 [[ ! ( -n $2 && "$2" == "continue" ) ]] && exit
1762 info
"clean testing temp dir!\n"
1784 info
"printf vars in scripttest!\n"
1806 echo "$PROG_VERSION"
1815 echo -ne "Options:\n"
1817 echo -ne "\nuse '$PROG --help' for more details.\n"
1825 [[ -z $term_width ]] && term_width
=80
1827 echo -ne "${PROG_SYNTAX}\n\n"
1828 echo -ne "$PROG_BANNER\n"
1829 echo -ne "$PROG_DESC\n" |
fold -b -s -w $term_width - 2>/dev
/null
1830 echo -ne "\nOptions:\n"
1832 echo -ne "$PROG_OTHER_DESC"
1838 # 显示调试信息,这里显示desc-str解析和参数解析后的环境变量信息。
1852 # program arguments resolve.
1853 # it invoke opt_desc_str_dispatch and prog_opt_proc seperatly,
1854 # instead of prog_opt_dispatch, for multiple desc-str.
1856 # 初始化测试的tmp目录路径,设置testcase的目录
1858 # prog_opt_dispatch "$@"
1859 opt_desc_str_dispatch scripttest_desc_str
1860 opt_desc_str_dispatch another_desc_str
1866 init_dbglogout
2 testing
20000
1867 # set_output_prefix info ""
1871 # running action list function for options after init.
1872 # the paramter for init will be effact, then execute the
1877 testing_paths_init
$output_dir
1878 if [[ $clean == "enable" ]]; then
1879 info
"re-init tmp dir.\n"
1880 rm "$TESTING_TMP_DIR" -rf
1884 # 使用测试目录中的begin-id和end-id
1885 catalog_id_init TEST
1886 testing_catalog_id_init
1889 # test the specified dir.
1891 info
"begin testing ... \n"
1892 test_unit
"$test_path"
1893 if [[ -e $TESTING_TMP_DIR/testing_failed_list.txt
]]; then
1894 cat $TESTING_TMP_DIR/testing_failed_list.txt |
sort -n |
uniq > ~
/testing_failed_list.txt
1895 mv ~
/testing_failed_list.txt
$TESTING_TMP_DIR/testing_failed_list.txt
1897 info
"end testing ...\n"
1900 # testing result info
1905 ##############################
1906 # section: public function
1907 ##############################
1911 # fdesc: the wrap of main(), and it append init code of some feature.
1915 if [[ "$@" =~
"--debug" ]]; then
1916 declare -g DBGOUTD_OUTPUT
=1
1918 # does not need to shift args if the --debug option is not the
1919 # first option. it will be ignore in process.
1923 if [[ $1 != "--loadshlib" ]]; then
1931 unset DBGOUTD_OUTPUT
1933 ##############################
1934 # section: file tail
1935 ##############################
1943 [[ -z $1 ||
-z $z ||
! -f $1 ]] && err
"err: file ($1) does not exist.\n" && exit
1945 test_list_depth
=$
((test_list_depth
++))
1947 # dbgoutd "curr content $1\n"
1950 # 忽略.txt文件,在处理.sh文件时再进行处理
1951 [[ ! -d $file ]] && continue
1956 foreach_dir
$PWD/$file $item_proc
1957 done < <(ls "$1" |
sort -n)
1959 test_list_depth
=$
((test_list_depth--
))
1969 [[ -z $1 ||
-z $z ||
! -f $1 ]] && err
"err: file ($1) does not exist.\n" && exit
1971 test_list_depth
=$
((test_list_depth
++))
1973 # dbgoutd "curr content $1\n"
1976 # 忽略.txt文件,在处理.sh文件时再进行处理
1977 [[ -d $file ]] && continue
1982 foreach_dir
$PWD/$file $item_proc
1983 done < <(ls "$1" |
sort -n)
1985 test_list_depth
=$
((test_list_depth--
))