@@ -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 |