nDPI/tests/do.sh.in
Petr c35a5ca087
shell: reformatted, fixed inspections, typos (#2506)
Reformatted shell scripts according to [ShellCheck](https://github.com/koalaman/shellcheck/).

I. Most common changes:
1. https://github.com/koalaman/shellcheck/wiki/SC2086
	`$var` → `"$var"`
	Note: this isn't always necessary and I've been careful not to substitute where it wasn't necessary in meaning.
2. https://github.com/koalaman/shellcheck/wiki/SC2006
	`` `command` `` → `$(command)`
3. https://github.com/koalaman/shellcheck/wiki/SC2004
	`$(( $a + $b ))` → `$(( a + b ))`
4. https://github.com/koalaman/shellcheck/wiki/SC2164
	`cd "$dir"` → `cd "$dir" || exit 1`
5. https://github.com/koalaman/shellcheck/wiki/SC2166
	`[ check1 -o check2 ]` → `[ check1 ] || [ check2 ]`
6. https://github.com/koalaman/shellcheck/wiki/SC2002
	`cat "${file}" | wc -c` → `< "${file}" wc -c`
	Note: this looks a bit uglier but works faster.

II. Some special changes:
1. In file `utils/common.sh`:
	https://github.com/koalaman/shellcheck/wiki/SC2112
	This script is interpreted by `sh`, not by `bash`, but uses the keyword `function`.
	So I replaced `#!/usr/bin/env sh` to `#!/usr/bin/env bash`.
2. After that I thought of replacing all shebangs to `#!/usr/bin/env bash` for consistency and cross-platform compatibility, especially since most of the files already use bash.
3. But in cases when it was `#!/bin/sh -e` or `#!/bin/bash -eu` another problem appears:
	https://github.com/koalaman/shellcheck/wiki/SC2096
	So I decided to make all shebangs look uniform:
	```
	#!/usr/bin/env bash
	set -e (or set -eu) (if needed)
	```
4. In file `tests/ossfuzz.sh`:
	https://github.com/koalaman/shellcheck/wiki/SC2162
	`read i` → `read -r i`
	Note: I think that there is no need in special treatment for backslashes, but I could be wrong.
5. In file `tests/do.sh.in`:
	https://github.com/koalaman/shellcheck/wiki/SC2035
	`ls *.*cap*` → `ls -- *.*cap*`
6. In file `utils/verify_dist_tarball.sh`:
	https://github.com/koalaman/shellcheck/wiki/SC2268
	`[ "x${TARBALL}" = x ]` → `[ -z "${TARBALL}" ]`
7. In file `utils/check_symbols.sh`:
	https://github.com/koalaman/shellcheck/wiki/SC2221
	`'[ndpi_utils.o]'|'[ndpi_memory.o]'|'[roaring.o]')` → `'[ndpi_utils.o]'|'[ndpi_memory.o]')`
8. In file `autogen.sh`:
	https://github.com/koalaman/shellcheck/wiki/SC2145
	`echo "./configure $@"` → `echo "./configure $*"`
	https://github.com/koalaman/shellcheck/wiki/SC2068
	`./configure $@` → `./configure "$@"`

III. `LIST6_MERGED` and `LIST_MERGED6`
	There were typos with this variables in files `utils/aws_ip_addresses_download.sh`, `utils/aws_ip_addresses_download.sh` and `utils/microsoft_ip_addresses_download.sh` where variable `LIST6_MERGED` was defined, but `LIST_MERGED6` was removed by `rm`.
	I changed all `LIST_MERGED6` to `LIST6_MERGED`.

Not all changes are absolutely necessary, but some may save you from future bugs.
2024-07-18 17:32:49 +02:00

262 lines
7.6 KiB
Bash
Executable file

#!/usr/bin/env bash
#
# Use (to override results)
#
# NDPI_FORCE_UPDATING_UTESTS_RESULTS=1 ./do.sh
#
# To run tests in parallel: (you need **GNU** `parallel` program)
#
# NDPI_FORCE_PARALLEL_UTESTS=1 ./do.sh
cd "$(dirname "${0}")" || exit 1
FUZZY_TESTING_ENABLED=@BUILD_FUZZTARGETS@
if [ "${NDPI_DISABLE_FUZZY}" = "1" ]; then
FUZZY_TESTING_ENABLED=0
fi
FORCE_UPDATING_UTESTS_RESULTS=0
if [ "${NDPI_FORCE_UPDATING_UTESTS_RESULTS}" = "1" ]; then
FORCE_UPDATING_UTESTS_RESULTS=1
fi
FORCE_PARALLEL_UTESTS=0
if [ "${NDPI_FORCE_PARALLEL_UTESTS}" = "1" ]; then
FORCE_PARALLEL_UTESTS=1
fi
SKIP_PARALLEL_BAR=0
if [ "${NDPI_SKIP_PARALLEL_BAR}" = "1" ]; then
SKIP_PARALLEL_BAR=1
fi
#Remember: valgrind and *SAN are incompatible!
CMD_PREFIX="${CMD_PREFIX}"
if [ "${NDPI_TESTS_WINE}" = "1" ]; then
CMD_PREFIX="wine"
elif [ "${NDPI_TESTS_VALGRIND}" = "1" ]; then
CMD_PREFIX="valgrind -q --leak-check=full"
fi
CMD_DIFF="$(which diff)"
CMD_WDIFF="$(which wdiff)"
CMD_COLORDIFF="$(which colordiff)"
EXE_SUFFIX=@EXE_SUFFIX@
GPROF_ENABLED=@GPROF_ENABLED@
PCRE2_ENABLED=@PCRE2_ENABLED@
PCRE_PCAPS="WebattackRCE.pcap"
NBPF_ENABLED=@NBPF_ENABLED@
NBPF_PCAPS="h323-overflow.pcap"
GLOBAL_CONTEXT_ENABLED=@GLOBAL_CONTEXT_ENABLED@
GLOBAL_CONTEXT_CFGS="caches_global"
READER="${CMD_PREFIX} ../../../example/ndpiReader${EXE_SUFFIX} --cfg=filename.config,../../../example/config.txt -A -p ../../../example/protos.txt -c ../../../example/categories.txt -r ../../../example/risky_domains.txt -j ../../../example/ja3_fingerprints.csv -S ../../../example/sha1_fingerprints.csv -G ../../../lists -q -K JSON -k /dev/null -t -v 2"
#These exports are used in parallel mode
export CMD_DIFF
export CMD_WDIFF
export CMD_COLORDIFF
export PCRE2_ENABLED
export PCRE_PCAPS
export NBPF_ENABLED
export NBPF_PCAPS
export READER
export FORCE_UPDATING_UTESTS_RESULTS
export FORCE_PARALLEL_UTESTS
RC=0
if [ ! -x "../example/ndpiReader${EXE_SUFFIX}" ]; then
echo "$0: Missing ../example/ndpiReader${EXE_SUFFIX}"
echo "$0: Run ./configure and make first"
exit 1
fi
#For parallel tests you need `parallel` from GNU, not from `moreutils` package!
#On Ubuntu, for example, you might need to explicitly run `apt install parallel`
if [ $FORCE_PARALLEL_UTESTS -eq 1 ]; then
if ! parallel -V | grep -qoE 'GNU parallel'; then
echo "$0: To run the test in parallel mode you need **GNU** 'parallel'"
echo "$0: Try something like 'apt install parallel'"
exit 1
fi
fi
if [ ${GPROF_ENABLED} -eq 1 ]; then
GPROF="${GPROF:-$(which pprof)}"
if [ ! -x "${GPROF}" ]; then
echo "$0: ${GPROF} not found or not executable"
exit 1
fi
echo "$0: Using pprof executable ${GPROF}"
echo "$0: Please make sure that you use google-pprof and not gperftools"
echo "$0: See https://github.com/google/pprof"
else
GPROF=false
fi
fuzzy_testing() {
if [ -f ../fuzz/fuzz_ndpi_reader ]; then
cp ../example/protos.txt .
cp ../example/categories.txt .
cp ../example/risky_domains.txt .
cp ../example/ja3_fingerprints.csv .
cp ../example/sha1_fingerprints.csv .
../fuzz/fuzz_ndpi_reader -dict=../fuzz/dictionary.dict -max_total_time="${MAX_TOTAL_TIME:-592}" -print_pcs=1 -workers="${FUZZY_WORKERS:-0}" -jobs="${FUZZY_JOBS:-0}" cfgs/default/pcap/
rm -f protos.txt categories.txt risky_domains.txt ja3_fingerprints.csv sha1_fingerprints.csv
fi
}
run_single_pcap()
{
f=$1
if [ ! -f "./pcap/$f" ]; then
return 0
fi
SKIP_PCAP=0;
if [ $PCRE2_ENABLED -eq 0 ]; then
for p in $PCRE_PCAPS; do
if [ "$f" = "$p" ]; then
SKIP_PCAP=1
break
fi
done
fi
if [ $NBPF_ENABLED -eq 0 ]; then
for p in $NBPF_PCAPS; do
if [ "$f" = "$p" ]; then
SKIP_PCAP=1
break
fi
done
fi
if [ $SKIP_PCAP -eq 1 ]; then
if [ $FORCE_PARALLEL_UTESTS -eq 1 ]; then
printf "SKIPPED\n"
else
printf "%-48s\tSKIPPED\n" "$f"
fi
return 0
fi
CMD="$READER -i pcap/$f -w /tmp/reader.$$.out $READER_EXTRA_PARAM"
CPUPROFILE=./result/$f.cprof HEAPPROFILE=./result/$f $CMD
CMD_RET=$?
if [ $CMD_RET -eq 0 ] && [ -f /tmp/reader.$$.out ]; then
# create result files if not present
if [ ! -f "result/$f.out" ]; then
cp /tmp/reader.$$.out "result/$f.out"
fi
NUM_DIFF=$(${CMD_DIFF} "result/$f.out" /tmp/reader.$$.out | wc -l)
else
if [ $FORCE_PARALLEL_UTESTS -eq 1 ]; then
printf "ERROR (ndpiReader${EXE_SUFFIX} exit code: ${CMD_RET})\n"
else
printf "%-48s\tERROR (ndpiReader${EXE_SUFFIX} exit code: ${CMD_RET})\n" "$f"
FAILURES+=("$f") #TODO: find a way to update this variable also in parallel mode
fi
return 1
fi
if [ "$NUM_DIFF" -eq 0 ]; then
if [ $FORCE_PARALLEL_UTESTS -eq 0 ]; then
printf "%-48s\tOK\n" "$f"
fi
return 0
else
if [ $FORCE_PARALLEL_UTESTS -eq 1 ]; then
printf "ERROR\n"
else
printf "%-48s\tERROR\n" "$f"
FAILURES+=("$f") #TODO: find a way to update this variable also in parallel mode
fi
echo "$CMD [old vs new]"
${CMD_DIFF} "result/$f.out" /tmp/reader.$$.out
if [ ! -z "${CMD_COLORDIFF}" ] && [ ! -z "${CMD_WDIFF}" ]; then
${CMD_WDIFF} -n -3 "result/$f.out" /tmp/reader.$$.out | sort | uniq | ${CMD_COLORDIFF}
fi
if [ $FORCE_UPDATING_UTESTS_RESULTS -eq 1 ]; then
cp /tmp/reader.$$.out "result/$f.out"
fi
fi
/bin/rm -f /tmp/reader.$$.out
return 1
}
export -f run_single_pcap
check_results() {
if [ $FORCE_PARALLEL_UTESTS -eq 1 ]; then
if [ $SKIP_PARALLEL_BAR -eq 1 ]; then
parallel --tag "run_single_pcap" ::: $PCAPS
else
parallel --bar --tag "run_single_pcap" ::: $PCAPS
fi
RET=$? #Number of failed job up to 100
RC=$(( RC + RET ))
else
for f in $PCAPS; do
run_single_pcap "$f"
RET=$?
RC=$(( RC + RET ))
done
fi
if [ ${GPROF_ENABLED} -eq 1 ]; then
GPROF_ARGS='-nodecount 100 -nodefraction 0 -symbolize=fastlocal'
${GPROF} -top ${GPROF_ARGS} ../../../example/ndpiReader${EXE_SUFFIX} ./result/*.cprof || exit 1
${GPROF} -png -output ./result/cpu_profile.png ${GPROF_ARGS} ../../../example/ndpiReader${EXE_SUFFIX} ./result/*.cprof || exit 1
${GPROF} -top ${GPROF_ARGS} -sample_index=alloc_space ../../../example/ndpiReader${EXE_SUFFIX} ./result/*.heap || exit 1
${GPROF} -png -output ./result/heap_profile.png ${GPROF_ARGS} -sample_index=alloc_space ../../../example/ndpiReader${EXE_SUFFIX} ./result/*.heap || exit 1
fi
}
if [ $FUZZY_TESTING_ENABLED -eq 1 ]; then
fuzzy_testing
fi
for d in $(find ./cfgs/* -type d -maxdepth 0 2>/dev/null) ; do
SKIP_CFG=0
if [ $GLOBAL_CONTEXT_ENABLED -eq 0 ]; then
for c in $GLOBAL_CONTEXT_CFGS; do
if [ "$c" = "$(basename "$d")" ]; then
SKIP_CFG=1
break
fi
done
fi
if [ $SKIP_CFG -eq 1 ]; then
printf "Configuration \"$(basename "$d")\" %-18s\tSKIPPED\n"
continue
fi
cd ./cfgs/"$(basename "$d")" || exit 1
if [ "$#" -ne 0 ]; then
PCAPS=$*
else
PCAPS=$(cd pcap || exit 1; /bin/ls -- *.*cap*)
fi
FAILURES=()
READER_EXTRA_PARAM=""
[ -f config.txt ] && READER_EXTRA_PARAM=$(< config.txt)
export READER_EXTRA_PARAM
echo "Run configuration \"$(basename "$d")\" [$READER_EXTRA_PARAM]"
check_results
test ${#FAILURES} -ne 0 && printf '%s: %s\n' "${0}" "${RC} pcap(s) failed"
test ${#FAILURES} -ne 0 && echo "Failed: " "${FAILURES[@]}"
cd ../../
done
exit $RC