-
-
Save raxelo/fc05f867e237a91a73363f144bc478bc to your computer and use it in GitHub Desktop.
#!/bin/bash | |
TEST_DIR="./test" | |
RUNNABLE="./principal" | |
if [ "$1" == "--valgrind" ] | |
then | |
RUNNABLE="timeout --preserve-status 4 valgrind --error-exitcode=52 -q --leak-check=full $RUNNABLE" | |
fi | |
if ! [ -d "$TEST_DIR" ] | |
then | |
echo "❌ No pudo encontrarse el directorio './test'. Terminando script." | |
exit | |
fi | |
if ! [[ -f "./principal" ]] | |
then | |
echo "❌ No pudo encontrarse el ejecutable './principal'. Terminando script." | |
exit | |
fi | |
if ! [[ -x "./principal" ]] | |
then | |
echo "❌ './principal' no es un archivo ejecutable. Terminando script." | |
exit | |
fi | |
correctAmount=0 | |
incorrectAmount=0 | |
for TEST_INPUT_NAME in ./test/*.in; do | |
TEST_NAME="$(echo "$TEST_INPUT_NAME" | cut -d"/" -f3 | cut -d "." -f1)" # for example: "mapping" | |
TEST_OUTPUT_FILE="${TEST_DIR}/${TEST_NAME}.sal" # for example: "./test/mapping.sal" | |
TEST_EXPECTED_OUTPUT_FILE="${TEST_DIR}/${TEST_NAME}.out" # for example: "./test/mapping.out" | |
$RUNNABLE < "$TEST_INPUT_NAME" > "$TEST_OUTPUT_FILE" | |
exitcode="$?" | |
if [ "$exitcode" -eq 52 ] | |
then | |
echo "❌ $TEST_NAME MAL!" | |
echo "❌ Posible error con el manejo de memoria encontrado mientras ejecutamos el test \"$TEST_INPUT_NAME\"! (leer output de valgrind)" | |
exit | |
elif [ "$exitcode" -ne 0 ] | |
then | |
echo "❌ $TEST_NAME MAL!" | |
echo "❌ El programa terminó con el exit code $exitcode mientras ejecutaba el test \"$TEST_INPUT_NAME\"" | |
exit | |
fi | |
output="."$(echo "$fileName" | cut -d "." -f2)".out" | |
diff=$(diff -y --suppress-common-lines "$TEST_EXPECTED_OUTPUT_FILE" "$TEST_OUTPUT_FILE") | |
if [ -z "$diff" ] | |
then | |
echo "✅ $TEST_NAME OK!" | |
((correctAmount+=1)) | |
fi | |
if [ -n "$diff" ] | |
then | |
echo -e "\n" | |
echo "❌ $TEST_NAME MAL!" | |
((incorrectAmount+=1)) | |
echo "Mostrando salida esperada (izquierda) y salida obtenida (derecha):" | |
echo "$diff" | |
echo "" | |
fi | |
done | |
echo "" | |
if [ "$1" == "--valgrind" ] | |
then | |
echo "❗ Test de memoria con valgrind realizado." | |
else | |
echo "❗ Para realizar el test de memoria con valgrind, ejecuta el script de la siguiente manera:" | |
echo "❗ './tester.sh --valgrind'" | |
fi | |
echo "" | |
echo "Tests aprobados: $correctAmount" | |
echo "Tests reprobados: $incorrectAmount" | |
echo "" | |
echo "Autor: github.com/raxelo ✨" |
¿No tendría sentido ponerle un 'make' al principio? Así se puede probar todo directamente dentro del script, sin necesidad de compilar el programa fuera de él.
Con ponerle make en la segunda línea ya quedaría pronto.
Mejor sería que en el caso de que haya errores de compilación, no corra los tests. Esto lo podemos verificar con el exit code de make. Es bastante simple, se chequea con un if.
Le ponés:
TEST_DIR="./test"
if make; then
correctAmount=0
(...)
y al final:
(...)
echo "Tests aprobados: $correctAmount"
echo "Tests reprobados: $incorrectAmount"
fi
Y queda pronto. Con esto, si compila corre los tests, y si no muestra los errores que da make y finaliza el script. Para mí esto es bastante útil, ya que te ahorra el paso previo de compilar y podés hacer todo dentro del mismo script.
¿No tendría sentido ponerle un 'make' al principio? Así se puede probar todo directamente dentro del script, sin necesidad de compilar el programa fuera de él.
Con ponerle make en la segunda línea ya quedaría pronto.
Esto acoplaría la responsabilidad al script de contar con make, lo cual no veo necesario, la única responsabilidad del script es probar los casos, además de esta manera si el usuario desea compilar por otras vías (cmake por ejemplo) le da mayor libertad.
Mejor sería que en el caso de que haya errores de compilación, no corra los tests. Esto lo podemos verificar con el exit code de make. Es bastante simple, se chequea con un if.
Le ponés:
TEST_DIR="./test" if make; then correctAmount=0 (...)
y al final:
(...) echo "Tests aprobados: $correctAmount" echo "Tests reprobados: $incorrectAmount" fi
Y queda pronto. Con esto, si compila corre los tests, y si no muestra los errores que da make y finaliza el script. Para mí esto es bastante útil, ya que te ahorra el paso previo de compilar y podés hacer todo dentro del mismo script.
Una solución que veo mejor es que en caso de no encontrar el programa, o en caso de toparse con un exit code distinto de 0 en el programa, deje de correr los tests, ya que como comenté anteriormente, acoplar la responsabilidad de compilar al script lo veo como algo desfavorable.
Realicé los siguientes cambios para mejorar la calidad del script ✨
- Mejorar el formato del script
- Agregar shebang para especificar que debe correrse con bash
- Se detiene si no encuentra directorio
test
- Se detiene si no encuentra el ejecutable
principal
- Se detiene si no recibe un
exit code
igual a0
al ejecutar el programa
¿No tendría sentido ponerle un 'make' al principio? Así se puede probar todo directamente dentro del script, sin necesidad de compilar el programa fuera de él.
Con ponerle make en la segunda línea ya quedaría pronto.Esto acoplaría la responsabilidad al script de contar con make, lo cual no veo necesario, la única responsabilidad del script es probar los casos, además de esta manera si el usuario desea compilar por otras vías (cmake por ejemplo) le da mayor libertad.
No hay que olvidarse del público y el caso particular para el que está dirigido este script. Los estudiantes de P2 en general, sin contar casos muy específicos y pocos, compilan con make y calculo que les vendría más cómodo hacer todo de una. No me parece disparatado suponer que los usuarios que ejecutan este script ya tienen make instalado, pues es justamente lo que se usa para compilar en esta tarea. Si alguien quiere usar cmake, es libre de hacerlo. Pero no es lo que se pide ni es la utilidad con la que se compilará al momento de la entrega.
No está demás destacar que en las tareas de Programación 1 el script de test compilaba y corría los tests consecutivamente, y desde mi punto de vista era sumamente útil y provechoso. Podías hacer un cambio pequeño y ya compilar y correr todos los tests con un solo comando.
Mejor sería que en el caso de que haya errores de compilación, no corra los tests. Esto lo podemos verificar con el exit code de make. Es bastante simple, se chequea con un if.
Le ponés:TEST_DIR="./test" if make; then correctAmount=0 (...)
y al final:
(...) echo "Tests aprobados: $correctAmount" echo "Tests reprobados: $incorrectAmount" fi
Y queda pronto. Con esto, si compila corre los tests, y si no muestra los errores que da make y finaliza el script. Para mí esto es bastante útil, ya que te ahorra el paso previo de compilar y podés hacer todo dentro del mismo script.
Una solución que veo mejor es que en caso de no encontrar el programa, o en caso de toparse con un exit code distinto de 0 en el programa, deje de correr los tests, ya que como comenté anteriormente, acoplar la responsabilidad de compilar al script lo veo como algo desfavorable.
Con las instrucciones que sugerí, si hay un error en make no se ejecutan los casos de prueba. Esto incluye que no esté el programa, haya un error de compilación o cualquier otro. El exit code 0 solo se da cuando compila exitosamente, por lo que en cualquier otro caso no ejecutaría ningún test, y solamente mostraría el output dado por make, donde se especifica cuál fue el error.
Igualmente, muy buen script! No quiero parecer mala onda jajaja, es solo que me pareció un aporte que no vendría mal.
Estoy de acuerdo con lo que decís, me parece que el debate aporta y está perfecto, lo veo como algo muy bueno 😃
Yo pienso que ambos enfoques son válidos, aunque mi enfoque favorito es desacoplar las responsabilidades y así darle mayor libertad al usuario (compilen manualmente, con make o cmake el resultado es el mismo).
Gracias tu feedback ✌
✨ Ahora permite realizar pruebas con valgrind si se ejecuta el script con --valgrind
El script debe ser ejecutado en mismo directorio donde se encuentra
principal
(el ejecutable) y el subdirectoriotest
.