Simply autotest script

This commit is contained in:
Gabriel Ionita 2025-10-28 10:30:00 +01:00
parent 5eec86114a
commit 5bd9c404b3
Signed by: gabi
SSH Key Fingerprint: SHA256:mrbYmB/SGtDvT3etRoS6pDrMYWxR0/B5GSF6rR3qhhc

View File

@ -1,272 +1,23 @@
#!/bin/bash
# autotest.sh - Automated testing script for gwatch
# Tests various scenarios and validates behavior
set -e
GWATCH_TESTS="./build/gwatch_tests"
BUILD_DIR="./build"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Test counters
TESTS_PASSED=0
TESTS_FAILED=0
# Paths
GWATCH="./build/gwatch"
SAMPLE_PROGRAM="./sample_program"
SAMPLE_SOURCE="./sample_program.c"
# Helper function to print test results
print_result() {
local test_name="$1"
local result="$2"
if [ "$result" = "PASS" ]; then
echo -e "${GREEN}[PASS]${NC} $test_name"
((TESTS_PASSED++))
else
echo -e "${RED}[FAIL]${NC} $test_name"
((TESTS_FAILED++))
# Check if test suite is compiled, compile if needed
if [ ! -f "$GWATCH_TESTS" ]; then
if [ ! -d "$BUILD_DIR" ]; then
echo "Error: $BUILD_DIR directory not found"
exit 1
fi
}
# Helper function to run test
run_test() {
local test_name="$1"
echo -e "\n${YELLOW}Running:${NC} $test_name"
}
# Compile sample program
echo "=== Preparing Test Environment ==="
if [ ! -f "$SAMPLE_SOURCE" ]; then
echo "Error: $SAMPLE_SOURCE not found"
exit 1
cd "$BUILD_DIR"
cmake --preset debug .. && make gwatch_tests
if [ $? -ne 0 ]; then
echo "Error: Failed to compile test suite"
exit 1
fi
cd ..
fi
echo "Compiling sample program..."
gcc -g -O0 -o "$SAMPLE_PROGRAM" "$SAMPLE_SOURCE"
if [ $? -ne 0 ]; then
echo "Error: Failed to compile sample program"
exit 1
fi
echo "Sample program compiled successfully"
if [ ! -f "$GWATCH" ]; then
echo "Error: $GWATCH not found. Build the project first."
exit 1
fi
echo -e "\n=== Starting Tests ===\n"
# Test 1: Monitor global_int with successful writes
run_test "Test 1: Monitor global_int (4 bytes)"
OUTPUT=$(timeout 3 $GWATCH --var global_int --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
# timeout returns 124 if killed, but gwatch itself returns 0
if echo "$OUTPUT" | grep -q "global_int.*write.*0->42" && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 1" "PASS"
else
print_result "Test 1" "FAIL"
echo "Exit code: $EXIT_CODE"
fi
# Test 2: Monitor global_long (8 bytes)
run_test "Test 2: Monitor global_long (8 bytes)"
OUTPUT=$(timeout 3 $GWATCH --var global_long --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
if echo "$OUTPUT" | grep -q "global_long.*write.*1000->5000" && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 2" "PASS"
else
print_result "Test 2" "FAIL"
fi
# Test 3: Monitor global_uint (unsigned 4 bytes)
run_test "Test 3: Monitor global_uint (unsigned 4 bytes)"
OUTPUT=$(timeout 3 $GWATCH --var global_uint --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
if echo "$OUTPUT" | grep -q "global_uint.*write.*0->999" && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 3" "PASS"
else
print_result "Test 3" "FAIL"
fi
# Test 4: Nonexistent variable
run_test "Test 4: Nonexistent variable (should fail)"
OUTPUT=$($GWATCH --var nonexistent_var --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "not found"; then
print_result "Test 4" "PASS"
else
print_result "Test 4" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 5: Missing executable
run_test "Test 5: Missing executable (should fail)"
OUTPUT=$($GWATCH --var global_int --exec /nonexistent/file 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "Cannot open"; then
print_result "Test 5" "PASS"
else
print_result "Test 5" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 6: Missing arguments
run_test "Test 6: Missing required arguments (should fail)"
OUTPUT=$($GWATCH 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "required"; then
print_result "Test 6" "PASS"
else
print_result "Test 6" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 7: Help message
run_test "Test 7: Help message"
OUTPUT=$($GWATCH --help 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ] && echo "$OUTPUT" | grep -q "exec" && echo "$OUTPUT" | grep -q "var"; then
print_result "Test 7" "PASS"
else
print_result "Test 7" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 8: Command-line argument passing
run_test "Test 8: Command-line arguments to traced program"
OUTPUT=$(timeout 3 $GWATCH --var global_int --exec $SAMPLE_PROGRAM -- 777 2>&1)
EXIT_CODE=$?
if echo "$OUTPUT" | grep -q "777" && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 8" "PASS"
else
print_result "Test 8" "FAIL"
fi
# Test 9: Unsupported type (char - 1 byte)
run_test "Test 9: Unsupported type - char (1 byte, should fail)"
cat > /tmp/test_char_gwatch.c <<'EOF'
#include <stdio.h>
char global_char = 'A';
int main() {
global_char = 'B';
printf("Char: %c\n", global_char);
return 0;
}
EOF
gcc -g -O0 -o /tmp/test_char_gwatch /tmp/test_char_gwatch.c 2>/dev/null
OUTPUT=$($GWATCH --var global_char --exec /tmp/test_char_gwatch 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "unsupported size"; then
print_result "Test 9" "PASS"
else
print_result "Test 9" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 10: Unsupported type (short - 2 bytes)
run_test "Test 10: Unsupported type - short (2 bytes, should fail)"
cat > /tmp/test_short_gwatch.c <<'EOF'
#include <stdio.h>
short global_short = 10;
int main() {
global_short = 20;
printf("Short: %d\n", global_short);
return 0;
}
EOF
gcc -g -O0 -o /tmp/test_short_gwatch /tmp/test_short_gwatch.c 2>/dev/null
OUTPUT=$($GWATCH --var global_short --exec /tmp/test_short_gwatch 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "unsupported size"; then
print_result "Test 10" "PASS"
else
print_result "Test 10" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 11: Unsupported type (float)
run_test "Test 11: Unsupported type - float (should fail)"
cat > /tmp/test_float_gwatch.c <<'EOF'
#include <stdio.h>
float global_float = 3.14f;
int main() {
global_float = 6.28f;
printf("Float: %f\n", global_float);
return 0;
}
EOF
gcc -g -O0 -o /tmp/test_float_gwatch /tmp/test_float_gwatch.c 2>/dev/null
OUTPUT=$($GWATCH --var global_float --exec /tmp/test_float_gwatch 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -ne 0 ] && echo "$OUTPUT" | grep -q "not found or is not a supported integer type"; then
print_result "Test 11" "PASS"
else
print_result "Test 11" "FAIL"
echo "Exit code: $EXIT_CODE, Output: $OUTPUT"
fi
# Test 12: Output format validation (tab-delimited)
run_test "Test 12: Output format validation (tab-delimited)"
OUTPUT=$(timeout 3 $GWATCH --var global_int --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
# Check if output contains tabs between fields
if echo "$OUTPUT" | grep -P "global_int\twrite\t\d+->\d+" >/dev/null && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 12" "PASS"
else
print_result "Test 12" "FAIL"
fi
# Test 13: Multiple writes detection
run_test "Test 13: Multiple writes detection"
OUTPUT=$(timeout 3 $GWATCH --var global_int --exec $SAMPLE_PROGRAM 2>&1)
EXIT_CODE=$?
# Count number of write events (should be at least 5)
WRITE_COUNT=$(echo "$OUTPUT" | grep -c "global_int.*write" || true)
if [ "$WRITE_COUNT" -ge 5 ] && echo "$OUTPUT" | grep -q "Process exited"; then
print_result "Test 13" "PASS"
else
print_result "Test 13" "FAIL"
echo "Expected at least 5 writes, got $WRITE_COUNT"
fi
# Cleanup
rm -f /tmp/test_char_gwatch /tmp/test_char_gwatch.c
rm -f /tmp/test_short_gwatch /tmp/test_short_gwatch.c
rm -f /tmp/test_float_gwatch /tmp/test_float_gwatch.c
# Summary
echo -e "\n=== Test Summary ==="
echo -e "Tests passed: ${GREEN}$TESTS_PASSED${NC}"
echo -e "Tests failed: ${RED}$TESTS_FAILED${NC}"
echo -e "Total tests: $((TESTS_PASSED + TESTS_FAILED))"
if [ $TESTS_FAILED -eq 0 ]; then
echo -e "\n${GREEN}All tests passed!${NC}"
exit 0
else
echo -e "\n${RED}Some tests failed!${NC}"
exit 1
fi
$GWATCH_TESTS