fortrangoingonforty/fortsh / e525327

Browse files

Add comprehensive test harness with documentation

Authored by espadonne
SHA
e525327f1db6ced259224a87aef2987fbf3b0217
Parents
ea925e4
Tree
9004f13

3 changed files

StatusFile+-
A tests/TEST_HARNESS.md 208 0
A tests/run_all_tests.sh 297 0
M tests/run_posix_tests.sh 3 0
tests/TEST_HARNESS.mdadded
@@ -0,0 +1,208 @@
1
+# Fortsh Test Harness Documentation
2
+
3
+## Overview
4
+
5
+The fortsh test suite includes comprehensive POSIX compliance tests, memory pool tests, and interactive tests organized into a structured test harness.
6
+
7
+## Test Runners
8
+
9
+### `run_all_tests.sh` - Comprehensive Test Runner (NEW)
10
+
11
+The primary test runner that provides categorized test execution with detailed reporting.
12
+
13
+**Usage:**
14
+```bash
15
+./run_all_tests.sh [OPTIONS]
16
+```
17
+
18
+**Options:**
19
+- `--posix-only` - Run only POSIX compliance tests (default)
20
+- `--memory-only` - Run only memory pool tests
21
+- `--all` - Run both POSIX and memory pool tests
22
+- `--quick` - Run only fast POSIX tests (skip coverage/untested suites)
23
+- `--verbose` - Show detailed output from each test
24
+- `--stop-on-fail` - Stop running tests after first failure
25
+- `--help` - Show help message
26
+
27
+**Examples:**
28
+```bash
29
+# Quick POSIX compliance check (recommended for development)
30
+./run_all_tests.sh --quick
31
+
32
+# Full POSIX compliance suite
33
+./run_all_tests.sh --posix-only
34
+
35
+# Everything (POSIX + memory pool tests)
36
+./run_all_tests.sh --all
37
+
38
+# Verbose mode with stop on first failure
39
+./run_all_tests.sh --verbose --stop-on-fail
40
+```
41
+
42
+**Output Features:**
43
+- Color-coded test results
44
+- Individual test counts aggregated across all suites
45
+- Suite-level pass/fail tracking
46
+- Detailed summary with pass rates
47
+- Shows last 20 lines of output on failure (non-verbose mode)
48
+
49
+### `run_posix_tests.sh` - POSIX-Only Runner
50
+
51
+Simplified runner that executes all 8 POSIX compliance test suites.
52
+
53
+**Usage:**
54
+```bash
55
+./run_posix_tests.sh
56
+```
57
+
58
+This runner includes all POSIX test suites:
59
+- `posix_compliance_test.sh` - Core POSIX features
60
+- `posix_compliance_extended.sh` - Extended POSIX features
61
+- `posix_compliance_builtins.sh` - Builtin commands
62
+- `posix_compliance_advanced.sh` - Advanced shell features
63
+- `posix_compliance_gaps.sh` - Gap coverage tests
64
+- `posix_compliance_jobcontrol.sh` - Job control features
65
+- `posix_compliance_coverage.sh` - Additional coverage tests
66
+- `posix_compliance_untested.sh` - Previously untested features
67
+
68
+## Test Categories
69
+
70
+### POSIX Compliance Tests
71
+
72
+**Core Tests (Fast):**
73
+- `posix_compliance_test.sh` - Basic POSIX shell features
74
+- `posix_compliance_extended.sh` - Extended command line parsing
75
+- `posix_compliance_builtins.sh` - All builtin commands (52 tests)
76
+- `posix_compliance_advanced.sh` - Advanced features (arithmetic, arrays, etc.)
77
+- `posix_compliance_gaps.sh` - Edge cases and gap coverage (178 tests)
78
+- `posix_compliance_jobcontrol.sh` - Background jobs, fg/bg (33 tests, 7 skipped)
79
+
80
+**Extended Tests (Slower):**
81
+- `posix_compliance_coverage.sh` - Comprehensive coverage tests (99 tests)
82
+- `posix_compliance_untested.sh` - Recently added feature tests (45 tests)
83
+
84
+### Memory Pool Tests
85
+
86
+- `memory_pool_test_bench.sh` - Comprehensive memory pool testing
87
+- `memory_pool_validation.sh` - Memory pool validation
88
+- `macos_arm64_pool_checks.sh` - macOS ARM64 specific tests
89
+
90
+### Interactive Tests
91
+
92
+These tests require manual interaction and are not run automatically:
93
+- `terminal_integration_tests.sh`
94
+- `terminal_interactive_tests.sh`
95
+- `test_interactive_comprehensive.sh`
96
+- `test_interactive.sh`
97
+- `test_readline_integration.sh`
98
+
99
+## Test Results Format
100
+
101
+Most test suites output results in this format:
102
+
103
+```
104
+==========================================
105
+TEST NAME
106
+==========================================
107
+✓ PASS: test description
108
+✗ FAIL: test description
109
+
110
+==========================================
111
+SUMMARY
112
+==========================================
113
+Passed:  X
114
+Failed:  Y
115
+Skipped: Z
116
+Total:   N
117
+==========================================
118
+Pass rate: XX%
119
+```
120
+
121
+The test harness parses this output to aggregate statistics across all suites.
122
+
123
+## Current Test Status
124
+
125
+As of the last run:
126
+
127
+**Quick Mode (6 suites):**
128
+- Test Suites: 6/6 passed (100%)
129
+- Individual Tests: 52+ passed
130
+
131
+**Full POSIX Mode (8 suites):**
132
+- Test Suites: 6/8 passed (75%)
133
+- Known failures in:
134
+  - `posix_compliance_coverage.sh` - 1 failure out of 99 tests
135
+  - `posix_compliance_untested.sh` - 1 failure out of 45 tests
136
+
137
+## Environment Variables
138
+
139
+- `FORTSH_BIN` - Path to fortsh binary (auto-detected if not set)
140
+- `VERBOSE` - Set to 1 to enable verbose output in individual test scripts
141
+
142
+## Exit Codes
143
+
144
+- `0` - All tests passed
145
+- `1` - Some tests failed
146
+- `2` - Invalid arguments (run_all_tests.sh only)
147
+
148
+## Development Workflow
149
+
150
+**During development:**
151
+```bash
152
+# Quick check after making changes
153
+./run_all_tests.sh --quick
154
+
155
+# If quick tests pass, run full suite
156
+./run_all_tests.sh --posix-only
157
+```
158
+
159
+**Before committing:**
160
+```bash
161
+# Run full POSIX suite
162
+./run_all_tests.sh --posix-only
163
+
164
+# Optionally run memory pool tests if you changed memory-related code
165
+./run_all_tests.sh --all
166
+```
167
+
168
+**Debugging failures:**
169
+```bash
170
+# Run with verbose output and stop on first failure
171
+./run_all_tests.sh --verbose --stop-on-fail
172
+
173
+# Or run individual test suite directly
174
+./posix_compliance_builtins.sh
175
+```
176
+
177
+## Adding New Tests
178
+
179
+1. Create a new test script following the naming convention:
180
+   - POSIX: `posix_compliance_*.sh`
181
+   - Memory: `memory_pool_*.sh`
182
+   - Interactive: `test_interactive_*.sh`
183
+
184
+2. Ensure your script:
185
+   - Is executable (`chmod +x`)
186
+   - Uses `$FORTSH_BIN` environment variable
187
+   - Outputs summary in the standard format (see above)
188
+   - Exits with 0 on success, non-zero on failure
189
+
190
+3. Add the test to appropriate category in `run_all_tests.sh`:
191
+   - `POSIX_CORE_TESTS` for fast POSIX tests
192
+   - `POSIX_SLOW_TESTS` for slower/comprehensive tests
193
+   - `MEMORY_TESTS` for memory pool tests
194
+
195
+4. Optionally add to `run_posix_tests.sh` if it's a POSIX compliance test
196
+
197
+## Continuous Integration
198
+
199
+The test harness is designed for CI integration:
200
+
201
+```bash
202
+# In CI pipeline
203
+make clean && make -j8
204
+cd tests
205
+./run_all_tests.sh --quick --stop-on-fail
206
+```
207
+
208
+The `--stop-on-fail` flag ensures CI fails fast on first error, saving resources.
tests/run_all_tests.shadded
@@ -0,0 +1,297 @@
1
+#!/bin/bash
2
+# =====================================
3
+# Fortsh Comprehensive Test Runner
4
+# =====================================
5
+# Runs all test suites with categorization and detailed reporting
6
+# Usage: ./run_all_tests.sh [OPTIONS]
7
+#
8
+# Options:
9
+#   --posix-only     Run only POSIX compliance tests
10
+#   --memory-only    Run only memory pool tests
11
+#   --quick          Run only fast POSIX tests (skip coverage, untested)
12
+#   --verbose        Show detailed output from each test
13
+#   --stop-on-fail   Stop running tests after first failure
14
+#   --help           Show this help message
15
+#
16
+# Exit codes:
17
+#   0: All tests passed
18
+#   1: Some tests failed
19
+#   2: Invalid arguments
20
+
21
+set -e
22
+
23
+# Colors
24
+RED='\033[0;31m'
25
+GREEN='\033[0;32m'
26
+YELLOW='\033[1;33m'
27
+BLUE='\033[0;34m'
28
+CYAN='\033[0;36m'
29
+BOLD='\033[1m'
30
+NC='\033[0m'
31
+
32
+# Configuration
33
+VERBOSE=0
34
+STOP_ON_FAIL=0
35
+RUN_POSIX=1
36
+RUN_MEMORY=0
37
+RUN_INTERACTIVE=0
38
+SKIP_SLOW=0
39
+
40
+# Parse arguments
41
+for arg in "$@"; do
42
+    case "$arg" in
43
+        --posix-only)
44
+            RUN_POSIX=1
45
+            RUN_MEMORY=0
46
+            RUN_INTERACTIVE=0
47
+            ;;
48
+        --memory-only)
49
+            RUN_POSIX=0
50
+            RUN_MEMORY=1
51
+            RUN_INTERACTIVE=0
52
+            ;;
53
+        --quick)
54
+            SKIP_SLOW=1
55
+            ;;
56
+        --verbose|-v)
57
+            VERBOSE=1
58
+            ;;
59
+        --stop-on-fail)
60
+            STOP_ON_FAIL=1
61
+            ;;
62
+        --all)
63
+            RUN_POSIX=1
64
+            RUN_MEMORY=1
65
+            RUN_INTERACTIVE=0  # Interactive tests require manual interaction
66
+            ;;
67
+        --help|-h)
68
+            head -n 20 "$0" | grep '^#' | sed 's/^# \?//'
69
+            exit 0
70
+            ;;
71
+        *)
72
+            printf "${RED}Error: Unknown option: %s${NC}\n" "$arg" >&2
73
+            printf "Use --help for usage information\n" >&2
74
+            exit 2
75
+            ;;
76
+    esac
77
+done
78
+
79
+# Get script directory
80
+SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
81
+
82
+# Find fortsh binary
83
+if [ -n "$FORTSH_BIN" ] && [ -x "$FORTSH_BIN" ]; then
84
+    FORTSH_PATH="$FORTSH_BIN"
85
+elif [ -x "$SCRIPT_DIR/../bin/fortsh" ]; then
86
+    FORTSH_PATH="$SCRIPT_DIR/../bin/fortsh"
87
+elif [ -x "./bin/fortsh" ]; then
88
+    FORTSH_PATH="./bin/fortsh"
89
+else
90
+    printf "${RED}ERROR: fortsh binary not found!${NC}\n"
91
+    printf "Please build fortsh first with 'make' or set FORTSH_BIN\n"
92
+    exit 1
93
+fi
94
+
95
+export FORTSH_BIN="$FORTSH_PATH"
96
+
97
+# Define test categories
98
+POSIX_CORE_TESTS="
99
+posix_compliance_test.sh
100
+posix_compliance_extended.sh
101
+posix_compliance_builtins.sh
102
+posix_compliance_advanced.sh
103
+posix_compliance_gaps.sh
104
+posix_compliance_jobcontrol.sh
105
+"
106
+
107
+POSIX_SLOW_TESTS="
108
+posix_compliance_coverage.sh
109
+posix_compliance_untested.sh
110
+"
111
+
112
+MEMORY_TESTS="
113
+memory_pool_test_bench.sh
114
+memory_pool_validation.sh
115
+macos_arm64_pool_checks.sh
116
+"
117
+
118
+# Counters
119
+TOTAL_SUITES=0
120
+PASSED_SUITES=0
121
+FAILED_SUITES=0
122
+SKIPPED_SUITES=0
123
+TOTAL_TESTS_PASSED=0
124
+TOTAL_TESTS_FAILED=0
125
+TOTAL_TESTS_SKIPPED=0
126
+
127
+# Array to store failed suite names
128
+FAILED_SUITE_NAMES=""
129
+
130
+# Function to run a test suite
131
+run_test_suite() {
132
+    local suite="$1"
133
+    local category="$2"
134
+    local suite_path="$SCRIPT_DIR/$suite"
135
+
136
+    if [ ! -f "$suite_path" ]; then
137
+        printf "${YELLOW}⊘ SKIP${NC}: %s (not found)\n" "$suite"
138
+        SKIPPED_SUITES=$((SKIPPED_SUITES + 1))
139
+        return 0
140
+    fi
141
+
142
+    if [ ! -x "$suite_path" ]; then
143
+        printf "${YELLOW}⊘ SKIP${NC}: %s (not executable)\n" "$suite"
144
+        SKIPPED_SUITES=$((SKIPPED_SUITES + 1))
145
+        return 0
146
+    fi
147
+
148
+    TOTAL_SUITES=$((TOTAL_SUITES + 1))
149
+
150
+    printf "${BLUE}========================================\n"
151
+    printf "Running: ${BOLD}%s${NC}${BLUE} [%s]\n" "$suite" "$category"
152
+    printf "========================================${NC}\n"
153
+
154
+    # Run the test suite and capture output
155
+    local output
156
+    local exit_code
157
+
158
+    if [ "$VERBOSE" -eq 1 ]; then
159
+        "$suite_path"
160
+        exit_code=$?
161
+    else
162
+        output=$("$suite_path" 2>&1)
163
+        exit_code=$?
164
+    fi
165
+
166
+    # Parse test results from output if not verbose
167
+    if [ "$VERBOSE" -eq 0 ]; then
168
+        # Try to extract test counts from summary
169
+        local passed=$(echo "$output" | grep -i "^Passed:" | tail -1 | awk '{print $2}')
170
+        local failed=$(echo "$output" | grep -i "^Failed:" | tail -1 | awk '{print $2}')
171
+        local skipped=$(echo "$output" | grep -i "^Skipped:" | tail -1 | awk '{print $2}')
172
+
173
+        # Accumulate test counts
174
+        if [ -n "$passed" ]; then
175
+            TOTAL_TESTS_PASSED=$((TOTAL_TESTS_PASSED + passed))
176
+        fi
177
+        if [ -n "$failed" ]; then
178
+            TOTAL_TESTS_FAILED=$((TOTAL_TESTS_FAILED + failed))
179
+        fi
180
+        if [ -n "$skipped" ]; then
181
+            TOTAL_TESTS_SKIPPED=$((TOTAL_TESTS_SKIPPED + skipped))
182
+        fi
183
+
184
+        # Show summary line
185
+        if [ -n "$passed" ] || [ -n "$failed" ]; then
186
+            printf "  Tests: "
187
+            [ -n "$passed" ] && printf "${GREEN}%d passed${NC}" "$passed"
188
+            [ -n "$failed" ] && [ "$failed" -gt 0 ] && printf " ${RED}%d failed${NC}" "$failed"
189
+            [ -n "$skipped" ] && [ "$skipped" -gt 0 ] && printf " ${YELLOW}%d skipped${NC}" "$skipped"
190
+            printf "\n"
191
+        fi
192
+    fi
193
+
194
+    # Check exit code
195
+    if [ "$exit_code" -eq 0 ]; then
196
+        printf "${GREEN}✓ PASSED${NC}: %s\n\n" "$suite"
197
+        PASSED_SUITES=$((PASSED_SUITES + 1))
198
+        return 0
199
+    else
200
+        printf "${RED}✗ FAILED${NC}: %s\n\n" "$suite"
201
+        FAILED_SUITES=$((FAILED_SUITES + 1))
202
+        FAILED_SUITE_NAMES="${FAILED_SUITE_NAMES}  - ${suite}\n"
203
+
204
+        # Show last 20 lines of output on failure if not verbose
205
+        if [ "$VERBOSE" -eq 0 ]; then
206
+            printf "${YELLOW}Last 20 lines of output:${NC}\n"
207
+            echo "$output" | tail -20
208
+            printf "\n"
209
+        fi
210
+
211
+        if [ "$STOP_ON_FAIL" -eq 1 ]; then
212
+            printf "${RED}Stopping due to --stop-on-fail${NC}\n"
213
+            exit 1
214
+        fi
215
+        return 1
216
+    fi
217
+}
218
+
219
+# Print header
220
+printf "${CYAN}╔════════════════════════════════════════╗\n"
221
+printf "║   Fortsh Comprehensive Test Suite     ║\n"
222
+printf "╚════════════════════════════════════════╝${NC}\n"
223
+printf "fortsh binary: ${GREEN}%s${NC}\n" "$FORTSH_BIN"
224
+printf "Test directory: %s\n" "$SCRIPT_DIR"
225
+printf "\n"
226
+
227
+# Run POSIX tests
228
+if [ "$RUN_POSIX" -eq 1 ]; then
229
+    printf "${CYAN}${BOLD}══════════════════════════════════════════\n"
230
+    printf "POSIX COMPLIANCE TESTS\n"
231
+    printf "══════════════════════════════════════════${NC}\n\n"
232
+
233
+    for suite in $POSIX_CORE_TESTS; do
234
+        run_test_suite "$suite" "POSIX"
235
+    done
236
+
237
+    if [ "$SKIP_SLOW" -eq 0 ]; then
238
+        for suite in $POSIX_SLOW_TESTS; do
239
+            run_test_suite "$suite" "POSIX-Extended"
240
+        done
241
+    fi
242
+fi
243
+
244
+# Run memory pool tests
245
+if [ "$RUN_MEMORY" -eq 1 ]; then
246
+    printf "${CYAN}${BOLD}══════════════════════════════════════════\n"
247
+    printf "MEMORY POOL TESTS\n"
248
+    printf "══════════════════════════════════════════${NC}\n\n"
249
+
250
+    for suite in $MEMORY_TESTS; do
251
+        run_test_suite "$suite" "Memory"
252
+    done
253
+fi
254
+
255
+# Print final summary
256
+printf "${CYAN}${BOLD}╔════════════════════════════════════════╗\n"
257
+printf "║          FINAL TEST SUMMARY            ║\n"
258
+printf "╚════════════════════════════════════════╝${NC}\n\n"
259
+
260
+printf "${BOLD}Test Suites:${NC}\n"
261
+printf "  Total:   %d\n" "$TOTAL_SUITES"
262
+printf "  ${GREEN}Passed:  %d${NC}\n" "$PASSED_SUITES"
263
+printf "  ${RED}Failed:  %d${NC}\n" "$FAILED_SUITES"
264
+if [ "$SKIPPED_SUITES" -gt 0 ]; then
265
+    printf "  ${YELLOW}Skipped: %d${NC}\n" "$SKIPPED_SUITES"
266
+fi
267
+
268
+printf "\n${BOLD}Individual Tests:${NC}\n"
269
+printf "  ${GREEN}Passed:  %d${NC}\n" "$TOTAL_TESTS_PASSED"
270
+printf "  ${RED}Failed:  %d${NC}\n" "$TOTAL_TESTS_FAILED"
271
+if [ "$TOTAL_TESTS_SKIPPED" -gt 0 ]; then
272
+    printf "  ${YELLOW}Skipped: %d${NC}\n" "$TOTAL_TESTS_SKIPPED"
273
+fi
274
+
275
+# Calculate totals
276
+TOTAL_INDIVIDUAL=$((TOTAL_TESTS_PASSED + TOTAL_TESTS_FAILED + TOTAL_TESTS_SKIPPED))
277
+if [ "$TOTAL_INDIVIDUAL" -gt 0 ]; then
278
+    PASS_RATE=$((TOTAL_TESTS_PASSED * 100 / TOTAL_INDIVIDUAL))
279
+    printf "  Pass rate: ${BOLD}%d%%${NC}\n" "$PASS_RATE"
280
+fi
281
+
282
+# List failed suites if any
283
+if [ "$FAILED_SUITES" -gt 0 ]; then
284
+    printf "\n${RED}${BOLD}Failed test suites:${NC}\n"
285
+    printf "%b" "$FAILED_SUITE_NAMES"
286
+fi
287
+
288
+printf "\n${CYAN}════════════════════════════════════════${NC}\n"
289
+
290
+# Exit with appropriate code
291
+if [ "$FAILED_SUITES" -eq 0 ] && [ "$TOTAL_SUITES" -gt 0 ]; then
292
+    printf "${GREEN}${BOLD}✓ ALL TEST SUITES PASSED!${NC}\n"
293
+    exit 0
294
+else
295
+    printf "${RED}${BOLD}✗ SOME TEST SUITES FAILED${NC}\n"
296
+    exit 1
297
+fi
tests/run_posix_tests.shmodified
@@ -51,6 +51,9 @@ posix_compliance_extended.sh
51
 posix_compliance_builtins.sh
51
 posix_compliance_builtins.sh
52
 posix_compliance_advanced.sh
52
 posix_compliance_advanced.sh
53
 posix_compliance_gaps.sh
53
 posix_compliance_gaps.sh
54
+posix_compliance_jobcontrol.sh
55
+posix_compliance_coverage.sh
56
+posix_compliance_untested.sh
54
 "
57
 "
55
 
58
 
56
 # Print header
59
 # Print header