本文提供了一種在UVM驗證過程中,常用的用例自動化回歸的腳本。該自動化腳本基于nohup命令實現,包括后臺提交測試用例、檢測任務進程狀態及回歸測試報告分析等功能。
一、nohup是什么
nohup 是一個在 Unix 和 Linux 系統中使用的命令,用于運行另一個命令時忽略掛斷(HUP)信號。這意味著你可以使用 nohup 來啟動一個應用程序或腳本,并確保它在你關閉終端或者注銷后繼續運行。nohup具備以下幾個顯著的使用優勢,尤其適用于需要長時間運行的任務或后臺服務,主要優勢如下:
持續運行:使用 nohup 啟動的進程即使在用戶注銷或者終端關閉之后也能繼續運行。這對于需要長時間執行的任務非常有用,比如數據處理、文件傳輸、服務器監控等。
輸出重定向:默認情況下,nohup 會將命令的標準輸出和標準錯誤輸出重定向到一個名為 nohup.out 的文件中。這有助于保存程序的輸出日志,方便后續查看。當然,你也可以手動指定輸出文件的位置,以便更好地管理日志文件。
資源利用:通過將任務放到后臺運行,可以釋放你的終端用于其他任務,提高工作效率。同時,這也意味著系統資源能夠被更有效地分配和使用,尤其是在多任務環境下。
簡化任務管理:對于需要定期執行的腳本或任務,結合 nohup 使用可以簡化任務管理和調度過程。無需復雜的守護進程設置,即可實現簡單可靠的后臺任務執行方案。
使用 nohup 的基本語法是:
nohup your_command &
這里 your_command 是你希望執行的命令,末尾的 & 符號表示將該命令放到后臺執行。默認情況下,nohup 會將命令的輸出重定向到一個名為 nohup.out 的文件中,除非你另外指定了輸出文件。如下命令,后臺運行python腳本,將輸出文件指定到output.log
nohup python your_command.py > output.log 2>&1 &
二、腳本實現過程
腳本的實現過程分為四部分,分別為回歸列表讀取、后臺提交測試任務、定期檢測后臺任務狀態、回歸測試報告分析,回歸腳本使用shell語言實現。
(一) 讀取回歸列表
shell腳本讀取regression_list.f文件,將回歸用例及用例參數存儲下來,供后續提交任務部分使用。如下代碼,讀取regression_list.f文件,將每行測試用例存放在line中,并進行打印輸出。
num_tc=0
while read line;
do
#read regression_list.f and print tc
let "num_tc=num_tc+1"
echo "$num_tc.$line"
done < regression_list.f
(二) 后臺提交測試測任務
將regression_list.f中的測試任務逐行進行后臺提交,同時記錄測試任務的ID編號,便于后續檢測任務狀態。
id=0
while read line;
do
#run tc
((id++))
nohup ./run_sim $line &
echo "$id" | tee -a job_id
done < regression_list.f
提交任務2min后,使用jobs -l $id命令查看后臺該任務的運行狀態,如果任務正在運行中,則返回“Running”;如果任務結束則返回“Done”或“”;如果任務返回“error”,則任務出現問題,打印warning信息,提醒用戶關注用例的編譯結果。
for id in $(cat ${1});
do
while true
do
sleep 2m
job_info=$(jobs -l $id 2>/dev/null)
job_status=$(echo "$job_info" | awk '{print $3}')
echo "Job $id status: $job_status"
if [[ "$job_status" == @("Running"|"Done") ]];
then
break;
elif [[ $job_status == @("error") ]]
then
echo " !!!!!!!!!!!!!!!!!!!!! WARINING !!!!!!!!!!!!!!!!!!!!!!!!!"
echo " Job is Failed, Please check Compile and Elab!!!"
fi
done
done < job_id
rm -rf job_id
(三) 定期檢測后臺任務狀態
將任務id從job_id文件中逐行讀出,將其放入數組job_list[]中。后續輪詢檢查job_list數組中的任務狀態,如果任務已結束,則將其從數組中剔除,直至所有任務結束,跳出輪詢檢測,進入到下一過程。
while read line;
do
job_list[line_cnt]=$line;
let "line_cnt=line_cnt+1"
done < job_id
rm -rf job_id
echo ${job_list[*]}
while true
do
echo ${job_list[*]}
for i in "${job_list[@]}"
do
sleep 30s
job_info=$(jobs -l %"$i" 2>/dev/null)
job_status=$(echo "$job_info" | awk '{print $3}')
echo "Job1 $i status: $job_status"
if [[ $job_status == @("error"|"Done"|"") ]];
then
let "job_cmp_cnt=job_cmp_cnt+1";
unset 'job_list[(($i-1))]'
fi
done
echo "job_cmp_cnt = $job_cmp_cnt"
echo "line_cnt = $line_cnt"
if [ "$job_cmp_cnt" -eq "$line_cnt" ]
then
break;
fi
done
(四) 分析回歸測試報告
用例結束后,將所有測試用例的報告整合為一份log文件,讀取log文件,尋找testcase_success或testcase_fail標識。統計用例總數、通過用例個數、失敗用例個數與異常結束用例個數,以表格的形式打印出來,方便用例查看結果。
ls ./logfiles/*.log > total_loglist.txt
while read line;
do
if [ "$(find $line -type f -exec grep -l "testcase_success" {} \;)" ]
then
let "PASSCOUNT=PASSCOUNT+1"
echo "$line Test passed"
elif [ "$(find $line -type f -exec grep -l "testcase_failed" {} \;)" ]
then
let "FAILCOUNT=FAILCOUNT+1"
echo "$line !!!--TEST FAILED---!!!"
else
let "NOBANNERCNT=NOBANNERCNT+1"
echo "No Banner for test $line"
fi
done < total_loglist.txt
echo "---------------------------------------------------------------------";
echo "************* VCS Regression Dashboard ************"
echo "---------------------------------------------------------------------";
echo "|Total No of Tests |Tests Passed| Tests Fail | Tests without banner |"
printf "| %3s | %3s | %3s | %3s |\n" "$FILECOUNT" "$PASSCOUNT" "$FAILCOUNT" "$NOBANNERCNT"
echo "---------------------------------------------------------------------";
三、改進與優化
需要添加一些異常場景的處理,提高回歸腳本的健壯性。例如某條用例死循環,無法結束的情況。當前只能通過手動kill進程的方式將其停止,后續可在腳本中添加TIMEOUT檢測,超時后自動殺死任務,彈出回歸測試報告。
每日定時開啟回歸測試,并且在腳本中添加自動update庫上最新代碼的命令。可以避開服務器的使用高峰,同時也可以避免人為忘記回歸的情況。