@@ -0,0 +1,262 @@ |
| | 1 | +#!/bin/bash |
| | 2 | +# ===================================== |
| | 3 | +# macOS ARM64 Specific Pool Validation |
| | 4 | +# Tests flang-new compiler workarounds with memory pooling |
| | 5 | +# ===================================== |
| | 6 | +# ONLY run this on macOS ARM64 with flang-new |
| | 7 | + |
| | 8 | +set -e |
| | 9 | + |
| | 10 | +# Colors |
| | 11 | +RED='\033[0;31m' |
| | 12 | +GREEN='\033[0;32m' |
| | 13 | +YELLOW='\033[1;33m' |
| | 14 | +BLUE='\033[0;34m' |
| | 15 | +NC='\033[0m' |
| | 16 | + |
| | 17 | +PASSED=0 |
| | 18 | +FAILED=0 |
| | 19 | +WARNINGS=0 |
| | 20 | + |
| | 21 | +pass() { |
| | 22 | + printf "${GREEN}✓${NC} %s\n" "$1" |
| | 23 | + PASSED=$((PASSED + 1)) |
| | 24 | +} |
| | 25 | + |
| | 26 | +fail() { |
| | 27 | + printf "${RED}✗${NC} %s\n" "$1" |
| | 28 | + [ -n "$2" ] && printf " ${RED}→${NC} %s\n" "$2" |
| | 29 | + FAILED=$((FAILED + 1)) |
| | 30 | +} |
| | 31 | + |
| | 32 | +warn() { |
| | 33 | + printf "${YELLOW}⚠${NC} %s\n" "$1" |
| | 34 | + [ -n "$2" ] && printf " ${YELLOW}→${NC} %s\n" "$2" |
| | 35 | + WARNINGS=$((WARNINGS + 1)) |
| | 36 | +} |
| | 37 | + |
| | 38 | +section() { |
| | 39 | + printf "\n${BLUE}━━━ %s ━━━${NC}\n" "$1" |
| | 40 | +} |
| | 41 | + |
| | 42 | +# Platform check |
| | 43 | +if [ "$(uname -s)" != "Darwin" ]; then |
| | 44 | + echo "${YELLOW}⚠️ Not running on Darwin - skipping macOS tests${NC}" |
| | 45 | + exit 0 |
| | 46 | +fi |
| | 47 | + |
| | 48 | +if [ "$(uname -m)" != "arm64" ]; then |
| | 49 | + echo "${YELLOW}⚠️ Not running on ARM64 - skipping macOS ARM64 tests${NC}" |
| | 50 | + exit 0 |
| | 51 | +fi |
| | 52 | + |
| | 53 | +# Find fortsh binary |
| | 54 | +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) |
| | 55 | +FORTSH_BIN="${SCRIPT_DIR}/../bin/fortsh" |
| | 56 | + |
| | 57 | +if [ ! -x "$FORTSH_BIN" ]; then |
| | 58 | + echo "${RED}✗ fortsh binary not found at $FORTSH_BIN${NC}" |
| | 59 | + exit 1 |
| | 60 | +fi |
| | 61 | + |
| | 62 | +echo "${BLUE}════════════════════════════════════════════════════════${NC}" |
| | 63 | +echo "${BLUE} macOS ARM64 Memory Pool Validation (flang-new)${NC}" |
| | 64 | +echo "${BLUE}════════════════════════════════════════════════════════${NC}" |
| | 65 | + |
| | 66 | +# ===================================== |
| | 67 | +# FLANG-NEW COMPILER CONSTRAINT CHECKS |
| | 68 | +# ===================================== |
| | 69 | +section "flang-new Compiler Constraints" |
| | 70 | + |
| | 71 | +# Test 1: 127-byte command limit with pooled strings |
| | 72 | +OUTPUT=$("$FORTSH_BIN" -c 'X="0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567"; echo ${#X}' 2>&1) |
| | 73 | +if [ "$OUTPUT" = "127" ]; then |
| | 74 | + pass "127-byte string limit enforced correctly" |
| | 75 | +elif [ "$OUTPUT" -gt 127 ]; then |
| | 76 | + fail "String exceeded 127-byte limit" "Got $OUTPUT bytes (flang-new will crash!)" |
| | 77 | +else |
| | 78 | + pass "String within limit ($OUTPUT bytes)" |
| | 79 | +fi |
| | 80 | + |
| | 81 | +# Test 2: Fixed-length buffer behavior |
| | 82 | +OUTPUT=$("$FORTSH_BIN" -c 'A="test"; B="$A"; echo "$B"' 2>&1) |
| | 83 | +if [ "$OUTPUT" = "test" ]; then |
| | 84 | + pass "Fixed-length buffer assignment works" |
| | 85 | +else |
| | 86 | + fail "Fixed-length buffer broken" "Expected 'test', got '$OUTPUT'" |
| | 87 | +fi |
| | 88 | + |
| | 89 | +# Test 3: Substring operations with pooled memory |
| | 90 | +OUTPUT=$("$FORTSH_BIN" -c 'STR="hello_world"; SUB="${STR:0:5}"; echo "$SUB"' 2>&1) |
| | 91 | +if [ "$OUTPUT" = "hello" ]; then |
| | 92 | + pass "Substring operations with pooled strings" |
| | 93 | +else |
| | 94 | + fail "Substring operation failed" "Expected 'hello', got '$OUTPUT'" |
| | 95 | +fi |
| | 96 | + |
| | 97 | +# Test 4: No block construct crashes (verify workaround) |
| | 98 | +OUTPUT=$("$FORTSH_BIN" -c 'for i in 1 2 3; do X="loop_$i"; echo "$X"; done' 2>&1 | wc -l) |
| | 99 | +if [ "$OUTPUT" -eq 3 ]; then |
| | 100 | + pass "Loop constructs work (block workaround active)" |
| | 101 | +else |
| | 102 | + fail "Loop construct failed" "Expected 3 lines, got $OUTPUT" |
| | 103 | +fi |
| | 104 | + |
| | 105 | +# ===================================== |
| | 106 | +# POINTER SAFETY WITH POOLING |
| | 107 | +# ===================================== |
| | 108 | +section "Pointer Substring Safety (Zero-Copy Pooling)" |
| | 109 | + |
| | 110 | +# Test 5: Verify pointer substrings don't cause crashes |
| | 111 | +"$FORTSH_BIN" -c 'A="test1"; B="test2"; C="test3"; echo "$A $B $C"' 2>&1 | grep -q "test1 test2 test3" && \ |
| | 112 | + pass "Multiple pointer substrings stable" || \ |
| | 113 | + fail "Pointer substring instability detected" |
| | 114 | + |
| | 115 | +# Test 6: Rapid pointer allocation/deallocation |
| | 116 | +OUTPUT=$("$FORTSH_BIN" -c 'for i in $(seq 1 50); do X="str_$i"; done; echo "done"' 2>&1) |
| | 117 | +if [ "$OUTPUT" = "done" ]; then |
| | 118 | + pass "Rapid pointer churn doesn't crash" |
| | 119 | +else |
| | 120 | + fail "Pointer churn caused failure" |
| | 121 | +fi |
| | 122 | + |
| | 123 | +# Test 7: Nested parameter expansion with pooled pointers |
| | 124 | +OUTPUT=$("$FORTSH_BIN" -c 'PATH="/usr/local/bin/test.sh"; FILE="${PATH##*/}"; EXT="${FILE##*.}"; echo "$EXT"' 2>&1) |
| | 125 | +if [ "$OUTPUT" = "sh" ]; then |
| | 126 | + pass "Nested expansions with pooled pointers" |
| | 127 | +else |
| | 128 | + fail "Nested expansion broken" "Expected 'sh', got '$OUTPUT'" |
| | 129 | +fi |
| | 130 | + |
| | 131 | +# ===================================== |
| | 132 | +# BUCKET ALLOCATION SPECIFIC TO MACOS |
| | 133 | +# ===================================== |
| | 134 | +section "Pool Bucket Constraints" |
| | 135 | + |
| | 136 | +# Test 8: Small bucket (64 bytes) - common on macOS due to 127-byte limit |
| | 137 | +"$FORTSH_BIN" -c 'SMALL="12345678901234567890123456789012345678901234567890123456789"; echo ${#SMALL}' 2>&1 | grep -q "^59$" && \ |
| | 138 | + pass "64-byte bucket allocation (common case)" || \ |
| | 139 | + fail "Small bucket allocation failed" |
| | 140 | + |
| | 141 | +# Test 9: Max pooled size before direct allocation |
| | 142 | +# With 127-byte limit, test if large pools are even reachable |
| | 143 | +OUTPUT=$("$FORTSH_BIN" -c 'BIG=$(printf "%.0sX" {1..120}); echo ${#BIG}' 2>&1) |
| | 144 | +if [ "$OUTPUT" -eq 120 ]; then |
| | 145 | + pass "Large pool bucket accessible" |
| | 146 | +else |
| | 147 | + warn "Large pools may be unreachable" "Only got $OUTPUT bytes" |
| | 148 | +fi |
| | 149 | + |
| | 150 | +# ===================================== |
| | 151 | +# ALLOCATABLE STRING WORKAROUNDS |
| | 152 | +# ===================================== |
| | 153 | +section "Allocatable String Workarounds" |
| | 154 | + |
| | 155 | +# Test 10: Character-by-character copy workaround |
| | 156 | +OUTPUT=$("$FORTSH_BIN" -c 'SRC="abc"; DST="$SRC"; echo "$DST"' 2>&1) |
| | 157 | +if [ "$OUTPUT" = "abc" ]; then |
| | 158 | + pass "Char-by-char copy workaround active" |
| | 159 | +else |
| | 160 | + fail "Copy workaround broken" |
| | 161 | +fi |
| | 162 | + |
| | 163 | +# Test 11: Avoid substring temporaries |
| | 164 | +"$FORTSH_BIN" -c 'X="temporary"; Y="${X}"; unset X; echo "$Y"' 2>&1 | grep -q "temporary" && \ |
| | 165 | + pass "Substring temporary avoidance works" || \ |
| | 166 | + fail "Substring temporaries causing issues" |
| | 167 | + |
| | 168 | +# ===================================== |
| | 169 | +# TERMINAL I/O WITH POOLING |
| | 170 | +# ===================================== |
| | 171 | +section "Terminal I/O Integration" |
| | 172 | + |
| | 173 | +# Test 12: Raw mode with pooled buffers (critical for readline) |
| | 174 | +echo "echo pooled_readline_test" | "$FORTSH_BIN" 2>&1 | grep -q "pooled_readline_test" && \ |
| | 175 | + pass "Readline with pooled buffers works" || \ |
| | 176 | + fail "Readline pooling broken" |
| | 177 | + |
| | 178 | +# Test 13: Terminal size detection doesn't crash (flang-new TIOCGWINSZ issue) |
| | 179 | +OUTPUT=$("$FORTSH_BIN" -c 'echo test' 2>&1) |
| | 180 | +if [ "$OUTPUT" = "test" ]; then |
| | 181 | + pass "Terminal size detection safe" |
| | 182 | +else |
| | 183 | + warn "Terminal detection may have issues" |
| | 184 | +fi |
| | 185 | + |
| | 186 | +# ===================================== |
| | 187 | +# MEMORY PRESSURE TESTS |
| | 188 | +# ===================================== |
| | 189 | +section "Memory Pressure (macOS Specific)" |
| | 190 | + |
| | 191 | +# Test 14: Pool expansion under pressure |
| | 192 | +cat > /tmp/macos_stress_$$.sh << 'EOF' |
| | 193 | +i=0 |
| | 194 | +while [ $i -lt 200 ]; do |
| | 195 | + VAR="stress_test_string_number_$i" |
| | 196 | + COPY="$VAR" |
| | 197 | + i=$((i + 1)) |
| | 198 | +done |
| | 199 | +echo "completed" |
| | 200 | +EOF |
| | 201 | + |
| | 202 | +OUTPUT=$("$FORTSH_BIN" < /tmp/macos_stress_$$.sh 2>&1 | tail -1) |
| | 203 | +rm -f /tmp/macos_stress_$$.sh |
| | 204 | +if [ "$OUTPUT" = "completed" ]; then |
| | 205 | + pass "Pool expansion under pressure" |
| | 206 | +else |
| | 207 | + fail "Memory pressure test failed" |
| | 208 | +fi |
| | 209 | + |
| | 210 | +# Test 15: Fragmentation handling |
| | 211 | +"$FORTSH_BIN" -c 'A="aaaa"; B="bbbbbbbb"; C="cc"; D="dddddddddddddddd"; echo "$A$B$C$D"' 2>&1 | \ |
| | 212 | + grep -q "aaaabbbbbbbbccdddddddddddddddd" && \ |
| | 213 | + pass "Fragmentation across buckets handled" || \ |
| | 214 | + fail "Fragmentation issues detected" |
| | 215 | + |
| | 216 | +# ===================================== |
| | 217 | +# CRITICAL SAFETY CHECKS |
| | 218 | +# ===================================== |
| | 219 | +section "Critical Safety Checks" |
| | 220 | + |
| | 221 | +# Test 16: No heap corruption indicators |
| | 222 | +"$FORTSH_BIN" -c 'echo "corruption_test"; X="test"; echo "$X"' 2>&1 | grep -q "test" && \ |
| | 223 | + pass "No obvious heap corruption" || \ |
| | 224 | + fail "Potential heap corruption detected" |
| | 225 | + |
| | 226 | +# Test 17: No stack overflow with pooled locals |
| | 227 | +"$FORTSH_BIN" -c 'A=1; B=2; C=3; D=4; E=5; F=6; G=7; H=8; echo "$A$B$C$D$E$F$G$H"' 2>&1 | \ |
| | 228 | + grep -q "12345678" && \ |
| | 229 | + pass "Stack handling with pooled locals" || \ |
| | 230 | + fail "Stack issues with multiple pooled vars" |
| | 231 | + |
| | 232 | +# Test 18: Signal handling doesn't corrupt pool |
| | 233 | +"$FORTSH_BIN" -c 'trap "echo trapped" INT; echo "signal_test"' 2>&1 | grep -q "signal_test" && \ |
| | 234 | + pass "Signal handlers don't corrupt pool" || \ |
| | 235 | + warn "Signal handling may affect pool" |
| | 236 | + |
| | 237 | +# ===================================== |
| | 238 | +# SUMMARY |
| | 239 | +# ===================================== |
| | 240 | +section "Summary" |
| | 241 | + |
| | 242 | +TOTAL=$((PASSED + FAILED + WARNINGS)) |
| | 243 | +printf "\n${BLUE}Results:${NC}\n" |
| | 244 | +printf "${GREEN}Passed: %3d${NC}\n" "$PASSED" |
| | 245 | +printf "${RED}Failed: %3d${NC}\n" "$FAILED" |
| | 246 | +printf "${YELLOW}Warnings: %3d${NC}\n" "$WARNINGS" |
| | 247 | +printf "━━━━━━━━━━━━━━━\n" |
| | 248 | +printf "Total: %3d\n\n" "$TOTAL" |
| | 249 | + |
| | 250 | +if [ "$FAILED" -eq 0 ]; then |
| | 251 | + printf "${GREEN}✅ macOS ARM64 pool validation PASSED${NC}\n" |
| | 252 | + printf "String pooling is safe with flang-new on Apple Silicon.\n" |
| | 253 | + exit 0 |
| | 254 | +elif [ "$FAILED" -le 2 ]; then |
| | 255 | + printf "${YELLOW}⚠️ macOS ARM64 pool validation MOSTLY PASSED${NC}\n" |
| | 256 | + printf "Minor issues detected but pooling appears functional.\n" |
| | 257 | + exit 0 |
| | 258 | +else |
| | 259 | + printf "${RED}❌ macOS ARM64 pool validation FAILED${NC}\n" |
| | 260 | + printf "Pooling has issues on Apple Silicon - investigation required.\n" |
| | 261 | + exit 1 |
| | 262 | +fi |