diff --git a/ci/run-first-frame-is-sid-test.sh b/ci/run-first-frame-is-sid-test.sh index 33405205c053fe24576dcf1b428a6a79c2aeae28..13934eb23ae6b847ca289e2b679d076f2c89dfb8 100755 --- a/ci/run-first-frame-is-sid-test.sh +++ b/ci/run-first-frame-is-sid-test.sh @@ -2,7 +2,55 @@ ### This test assures that for all DTX modes, decoding a bitstream that starts with an SID frame does not crash the decoder or cause a sanitizer error -set -euxo pipefail +set -euo pipefail + +collect_failed_logs() { + local console_output="$1" + local log_dir="${2:-logs}" + local output_dir="${3:-failed_logs}" + local temp_failures=$(mktemp) + + if [ ! -f "$console_output" ]; then + echo "Error: Console output file '$console_output' not found" >&2 + rm -f "$temp_failures" + return 1 + fi + + mkdir -p "$output_dir" + + # Extract filenames from failed enc/dec chains from the console log + # turn off fail on non-zero exit code to not fail on grep not matching any line (which is the case if everything is ok) + set +e + grep -iE '(encoding|decoding).*failed|failed.*(encoding|decoding)' "$console_output" | + grep -oE '[^[:space:]]+\.(192|wav|pcm)' | + while IFS= read -r filepath; do + # need basename wihtou suffix only for matching + filename=$(basename "$filepath") + filename_no_ext="${filename%.*}" + echo "$filename_no_ext" + done | sort -u >"$temp_failures" + set -e + + # Copy matching log files to output directory + if [ -s "$temp_failures" ]; then + echo "Copying log files for failed tasks to $output_dir..." + while IFS= read -r basename_pattern; do + # Find log files starting with this basename + while IFS= read -r logfile; do + cp -v "$logfile" "$output_dir/" + done < <(find "$log_dir" -type f -name "${basename_pattern}*") + done <"$temp_failures" + + echo "Done." + else + echo "No failures detected in $console_output" + fi + + # Cleanup + rm -f "$temp_failures" + + return 0 +} # build encoder without sanitizers for faster runtime make clean @@ -31,17 +79,14 @@ exit_code_msan_no_stereo=0 exit_code_msan_stereo=0 echo "-------------- 1. Encoder + Msan decoder -------------- " echo "-------------- 1.1 all DTX modes except stereo -------------- " -scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_no_stereo -U 0:20 $common_args || exit_code_msan_no_stereo=$? +scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_no_stereo -U 0:20 $common_args 2>&1 | tee "console_log_msan.txt" || exit_code_msan_no_stereo=$? echo "-------------- 1.2 stereo DTX modes -------------- " -scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_stereo -U 40:60 $common_args || exit_code_msan_stereo=$? -# archive encoder logs separately -mkdir logs_enc logs_dec_msan -mv CLANG1/logs/*.enc.txt logs_enc/ -mv CLANG1/logs/*.dec*.txt logs_dec_msan/ +scripts/IvasBuildAndRunChecks.py --checks CLANG1 -m $modes_stereo -U 40:60 $common_args 2>&1 | tee -a "console_log_msan.txt" || exit_code_msan_stereo=$? # sanity check: ensure that we have DTX frames in the cut bitstreams +# only need to do this once here as encoder is not run again after this grep_exit_code=0 -grep -r "Extracted 0 frames!" logs_enc/ || grep_exit_code=$? +grep -r "Extracted 0 frames!" CLANG1/logs/ || grep_exit_code=$? if [ $grep_exit_code -ne 1 ]; then echo "Some bitstreams did not contain any SID frame!" echo -e "Check the input signals and/or the VAD performance!\n" @@ -49,22 +94,35 @@ if [ $grep_exit_code -ne 1 ]; then exit 1 fi -# ASAN and USAN can be done in one go and decoder only +# ASAN and USAN can be done decoder only # copy encoder output from CLANG1 dir mkdir CLANG2 CLANG3 cp -r CLANG1/enc CLANG2/enc cp -r CLANG1/enc CLANG3/enc -# In this run, we can do all the dtx modes together - we only run the decoder, so no cutting of input files needed +# In the next runs, we can do all the dtx modes together - we only run the decoder, so no cutting of input files needed # the script does no put the cut length into the bitstream name, so the decoder can find the existing bitstreams this way modes_all=$(scripts/runIvasCodec.py -l | grep dtx) -exit_code_asan_usan=0 -echo "-------------- 2. Asan + Usan decoder (all in one go) -------------- " -scripts/IvasBuildAndRunChecks.py --checks CLANG2 CLANG3 --decoder_only -m $modes_all $common_args || exit_code_asan_usan=$? -mv CLANG2/logs logs_dec_asan -mv CLANG3/logs logs_dec_usan +exit_code_asan=0 +echo "-------------- 2. Asan decoder -------------- " +scripts/IvasBuildAndRunChecks.py --checks CLANG2 --decoder_only -m $modes_all $common_args 2>&1 | tee "console_log_asan.txt" || exit_code_asan=$? + +exit_code_usan=0 +echo "-------------- 3. Usan decoder -------------- " +scripts/IvasBuildAndRunChecks.py --checks CLANG3 --decoder_only -m $modes_all $common_args 2>&1 | tee "console_log_usan.txt" || exit_code_usan=$? -if [ $exit_code_msan_no_stereo -ne 0 ] || [ $exit_code_msan_stereo -ne 0 ] || [ $exit_code_asan_usan -ne 0 ]; then +echo "-------------- 4. Collect logs -------------- " + +# everything went as expected, now collect logs +collect_failed_logs console_log_msan.txt CLANG1/logs logs/msan +collect_failed_logs console_log_asan.txt CLANG2/logs logs/asan +collect_failed_logs console_log_usan.txt CLANG3/logs logs/usan + +echo "-------------- 5. Check for errors -------------- " +if [ $exit_code_msan_no_stereo -ne 0 ] || [ $exit_code_msan_stereo -ne 0 ] || [ $exit_code_asan -ne 0 ] || [ $exit_code_usan -ne 0 ]; then echo "There was either a crash or a sanitizer error encountered when decoding a bitstream that starts with an SID. Check the artifacts for the logfiles." exit 1 fi + +echo "No errors occured." +exit 0