#!/bin/bash
testcase_is_successful="yes"
testcase_error_output_mode="console"
test_error_log_dir="./error_log/"
testcase_success=0
testcase_fail=0
testcase_timeout=0
success_cases=()
fail_cases=()
timeout_cases=()
test_skip_status=222
current_arch=$(uname -m)
test_skip_cases=()
actual_skip_cases=()
actual_skip_nums=0
test_timeout_status=137
function read_skip_cases()
{
file=$1
while IFS= read -r line || [ -n "$line" ]; do
if [[ "$line" =~ ^# ]]; then
continue
fi
line=$(echo "$line" | xargs)
if [[ -z "$line" ]]; then
continue
fi
if [[ "$line" == *":"* ]]; then
testcase=$(echo "$line" |cut -d':' -f1)
arch=$(echo "$line" |cut -d':' -f2-)
if [ $arch == $current_arch ]; then
test_file=$(find ./ -type f \( -name "$testcase.sh" -o -name "$testcase.py" \))
test_skip_cases+=("$test_file")
fi
else
test_file=$(find ./ -type f \( -name "$line.sh" -o -name "$line.py" \))
test_skip_cases+=("$test_file")
fi
done < $file
}
function get_file_name_without_extension()
{
local file_path=$1
local filename=$(basename "$file_path")
local filename_no_ext="${filename%.*}"
echo "$filename_no_ext"
}
function do_test_file()
{
testfile="$1"
if echo "${test_skip_cases[@]}" | grep -qw "$testfile"; then
((++actual_skip_nums))
actual_skip_cases+=("$testfile")
return $test_skip_status
fi
extension="${testfile##*.}"
test_name="$(get_file_name_without_extension $testfile)"
if [ "$extension" == "sh" ]; then
dbus_output=$(systemctl start xalarmd 2>&1)
ret=$?
if [ $ret -eq 0 ]; then
systemctl stop xalarmd.socket xalarmd.service
fi
if [[ "$dbus_output" == *"Failed to connect to bus: Host is down"* ]]; then
((++actual_skip_nums))
actual_skip_cases+=("$testfile")
return $test_skip_status
fi
timeout --signal=KILL 300s sh $testfile > "${test_name}.log" 2>&1
elif [ "$extension" == "py" ]; then
pytest-3 $testfile > "${test_name}.log" 2>&1
fi
ret=$?
if [ $ret -eq 0 ]; then
((++testcase_success))
success_cases+=("$testfile")
rm -rf "${test_name}.log"
elif [ $ret -eq $test_timeout_status ]; then
testcase_is_successful="no"
((++testcase_timeout))
timeout_cases+=("$testfile")
if [ $testcase_error_output_mode == "console" ]; then
cat "${test_name}.log"
rm -rf "${test_name}.log"
else
mv "${test_name}.log" $test_error_log_dir"${test_name}.log"
fi
else
testcase_is_successful="no"
((++testcase_fail))
fail_cases+=("$testfile")
if [ $testcase_error_output_mode == "console" ]; then
cat "${test_name}.log"
rm -rf "${test_name}.log"
else
mv "${test_name}.log" $test_error_log_dir"${test_name}.log"
fi
fi
return $ret
}
function print_test_log_format()
{
current_test_index=$1
test_total_count=$2
test_case_file=$3
test_status_string=$4
test_cost_time=$5
if [ -n "$test_cost_time" ]; then
printf "%3d/%-3d %-60s %7s %.2fs\n" $current_test_index $test_total_count $(basename $test_case_file) $test_status_string $test_cost_time
else
printf "%3d/%-3d %-60s %7s\n" $current_test_index $test_total_count $(basename $test_case_file) $test_status_string
fi
}
function output_test_result_detail()
{
current_test_index=$1
test_total_count=$2
test_case_file=$3
test_status_code=$4
test_cost_time=$5
if [ $test_status_code -eq 0 ]; then
print_test_log_format $current_test_index $test_total_count $test_case_file "SUCCESS" $test_cost_time
elif [ $test_status_code -eq 137 ]; then
print_test_log_format $current_test_index $test_total_count $test_case_file "TIMEOUT" $test_cost_time
elif [ $test_status_code -eq $test_skip_status ]; then
print_test_log_format $current_test_index $test_total_count $test_case_file "SKIPPED" $test_cost_time
else
print_test_log_format $current_test_index $test_total_count $test_case_file " ERROR " $test_cost_time
fi
}
function do_all_test()
{
test_count=0
test_files=$(find test/ -type f \( -name "test_*.sh" -o -name "test_*.py" \))
test_total_count=$(echo "$test_files" | wc -l)
for testfile in $test_files
do
test_count=$((test_count+1))
print_test_log_format $test_count $test_total_count $testfile "RUNNING"
start_time_tmp=$(date +%s)
do_test_file $testfile
ret=$?
end_time_tmp=$(date +%s)
echo -en "\033[1A\033[K"
output_test_result_detail $test_count $test_total_count $testfile $ret $((end_time_tmp - start_time_tmp))
done
}
function do_one_test()
{
testfile=$1
print_test_log_format 1 1 $testfile "RUNNING"
start_time_tmp=$(date +%s)
do_test_file $testfile
ret=$?
end_time_tmp=$(date +%s)
echo -en "\033[1A\033[K"
output_test_result_detail 1 1 $testfile $ret $((end_time_tmp - start_time_tmp))
}
function output_unsuccessful_test_cases()
{
if [ $testcase_fail -gt 0 ]; then
printf "============== FAILED TEST ==============\n"
for file_name in "${fail_cases[@]}"; do
printf "$(basename $file_name)\n"
done
fi
if [ $testcase_timeout -gt 0 ]; then
printf "============== TIMEOUT TEST ==============\n"
for file_name in "${timeout_cases[@]}"; do
printf "$(basename $file_name)\n"
done
fi
if [ $actual_skip_nums -gt 0 ]; then
printf "============== SKIPPED TEST ==============\n"
for file_name in "${actual_skip_cases[@]}"; do
printf "$(basename $file_name)\n"
done
fi
}
function output_test_cases_result()
{
printf "============== TEST RESULT ==============\n"
printf "success: $testcase_success\n"
printf "skipped: $actual_skip_nums\n"
printf "timeout: $testcase_timeout\n"
printf "failed: $testcase_fail\n"
printf "total duration: ${total_time}s\n"
printf "=============== TEST END ================\n"
}
function do_test()
{
if [ "$2" == "file" ]; then
testcase_error_output_mode="file"
if [ ! -d "${test_error_log_dir}" ];then
mkdir ${test_error_log_dir}
fi
fi
read_skip_cases "testsuite_skip_list"
if [ "$1" == "all" ] || [ $# -eq 0 ]; then
start_time=$(date +%s)
do_all_test
end_time=$(date +%s)
total_time=$((end_time - start_time))
output_unsuccessful_test_cases
output_test_cases_result
else
test_file=$(find ./ -type f \( -name "$1.sh" -o -name "$1.py" \))
if [ ! -f "$test_file" ]; then
printf "testsuite $1 not exist, check whether the testname is corrent, we need to use $1 to match test/$1.py or test/$1.sh\n"
exit 1
else
do_one_test $test_file
fi
fi
find . -name "*.pyc" | xargs rm -rf
if [ "$testcase_is_successful" == "no" ]; then
printf "test failed!!!\n"
if [ $testcase_error_output_mode == "file" ]; then
printf "=============== ERROR INFO ==============\n"
printf "the execution log of the failed case refers to the following file:\n"
for file in "$test_error_log_dir"*; do
if [ -f "$file" ]; then
printf "%s\n" $file
fi
done
printf "=============== ERROR END ===============\n"
fi
exit 1
fi
}
do_test $1 $2