#! /bin/bash # Last edited on 2024-07-05 16:59:53 by stolfi # Usage: "run_python_test.sh [ -noshow ] {MODULE}..." # # Runs "{TSTDIR}/{MODULE}_TST.py" with the proper {PYTHONPATH}, and # sends the standard output (if not empty) to # "{OUTDIR}/{MODULE}_TST.txt" # # The {TSTDIR} will be either "testes" or "tests" in the current # directory, or the same in "../../tst/main/". The {OUTDIR} will be # "{TSTDIR}/out" or "{TSTDIR}/saida", whichever exists. if [[ "/$1" == "/-noshow" ]]; then show=0; shift else show=1 fi modules=( "$@" ); shift # opref="tests/out/${modulo}" ofile="${opref}.html" while [[ ( $PWD =~ .*/tests ) || ( $PWD =~ .*/src ) ]]; do cd .. ; done # Extensions of output files: outexts=( html txt eps dat gcode gcd png pgm ppm ) PYTHONPATH=".:testes:tests" PYTHONPATH="${PYTHONPATH}:..:..:../testes:../tests" PYTHONPATH="${PYTHONPATH}:../../tst/main:../../tst/main/testes:../../tst/main/tests" PYTHONPATH="${PYTHONPATH}:../../../tst/main:../../../tst/main/testes:../../../tst/main/tests" PYTHONPATH="${PYTHONPATH}:/usr/lib/python3.6/site-packages/sos/plugins" function find_file() { # Looks for {fname} in some standard places; returns {fname} if not found. # The {type} should be "f" for regular files, "d" for directories. type="$1"; shift fname="$1"; shift for dir in . .. ../../tst/main ../../../tst/main ; do for tsub in . testes tests ; do cand="${dir}/${tsub}/${fname}" if [[ "${type}" == "f" ]]; then if [[ -f ${cand} ]]; then echo "${cand}"; exit; fi elif [[ "${type}" == "d" ]]; then if [[ -d ${cand} ]]; then echo "${cand}"; exit; fi else echo "** invalid type = \"${type}\"" 1>&2; exit 1 fi done done echo ${fname} } # Find the output directory: OUT_dir="`find_file d saida`" if [[ ! ( -d ${OUT_dir} ) ]]; then OUT_dir="`find_file d out`" fi if [[ ! ( -d ${OUT_dir} ) ]]; then echo "** no directory \"out\" or \"saida\" found" 1>&2; exit 1 fi echo "output directory \"${OUT_dir}\"" 1>&2 # Remove output files of other runs: for ext in ${outexts[@]} ; do rm -fv ${OUT_dir}/*.${ext} done # ( cd tests && if [[ ! ( -r images ) ]]; then ln -s ../images; fi ) # ( cd tests && if [[ ! ( -r Makefile ) ]]; then ln -s ../Makefile; fi ) for module in "${modules[@]}" ; do echo "=== testing module ${module} =============================" 1>&2 TST_fname="${module}_TST.py" TST_file="`find_file f ${TST_fname}`" echo "running \"${TST_file}\"" 1>&2 if [[ ! ( -s ${TST_file} ) ]]; then echo "** file ${TST_file} not found or empty" 1>&2; exit 1 fi DEF_fname="${module}.py" DEF_file="`find_file f ${DEF_fname}`" echo "interface \"${DEF_file}\"" 1>&2 if [[ ! ( -s ${DEF_file} ) ]]; then echo "** file ${DEF_file} not found or empty" 1>&2; exit 1 fi # Check for functions that are not being tested: funcs_file="${OUT_dir}/.funcs" uses_file="${OUT_dir}/.uses" missing_file="${OUT_dir}/.missing" commented_file="${OUT_dir}/.commented" egrep -e '^def ' ${DEF_file} \ | sed \ -e 's/^def *//g' \ -e 's/[ ]*[\\(].*$//g' \ | sort \ > ${funcs_file} find_python_uses.sh ${TST_file} ${module} > ${uses_file} bool 1-2 ${funcs_file} ${uses_file} > ${missing_file} if [[ -s ${missing_file} ]]; then echo "!! warning: these functions are not called explicitly by the test program:" 1>&2 cat ${missing_file} | sed -e 's:^: :g' 1>&2 fi cat ${TST_file} | egrep -e '^[#]+ *test' > ${commented_file} if [[ -s ${commented_file} ]]; then echo "!! warning: these lines in the test program are commented out:" 1>&2 cat ${commented_file} | sed -e 's:^: :g' 1>&2 fi # Remove output files of previous runs: OUT_pref="${OUT_dir}/${module}" # Run the test program, save output: OUT_txt="${OUT_pref}.txt" # Text output. export PYTHONPATH="${PYTHONPATH}" ; \ time python3 ${TST_file} > ${OUT_txt} exstatus=$? echo "status = ${exstatus}" 1>&2 # Remove empty output files: for ext in ${outexts[@]} ; do for ff in ${OUT_pref}*.${ext}; do if [[ ( -e ${ff} ) && ( ! ( -s ${ff} ) ) ]]; then if [[ "${ff}" != "${OUT_txt}" ]]; then echo "!! ${ff} is empty" 1>&2 fi rm -fv ${ff} fi done done if [[ ( ${exstatus} -eq 0 ) && ( $show -ne 0 ) ]]; then # Show PDF outputs, if any: for OUT_pdf in ${OUT_pref}*.pdf; do if [[ -s ${OUT_pdf} ]]; then evince ${OUT_pdf} fi done # Plot graphs, if any: touch ${OUT_pref}_BOGUS.dat # Damn shell... for OUT_dat in ${OUT_pref}*.dat; do # Name of the plot is the first underscore-delimited word after module name: plotname="${OUT_dat}" plotname="${plotname##*/}" plotname="${plotname/${module}_/}" plotname="${plotname%%.dat}" plotname="${plotname%%_*}" if [[ "/${plotname}" != "/BOGUS" ]]; then gscript="plot_${module}_${plotname}.sh" # Name of gnuplot output file: OUT_plot_png="${OUT_dat/.dat/.png}" if [[ ! ( -s ${OUT_dat} ) ]]; then echo "** data file ${OUT_dat} is empty or missing" 1>&2 elif [[ ! ( -s ${gscript} ) ]]; then echo "** plot script ${gscript} not found" 1>&2 else ${gscript} ${OUT_dat} > ${OUT_plot_png} fi fi done fi echo "=== done testing ${module} ===========================" done