-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathtest_examples.sh
More file actions
executable file
·129 lines (112 loc) · 3.51 KB
/
Copy pathtest_examples.sh
File metadata and controls
executable file
·129 lines (112 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#!/bin/bash
# Test all example notebooks via curl against a running Sabela container.
# Usage: ./test_examples.sh [port] [timeout_per_notebook]
PORT=${1:-3003}
TIMEOUT=${2:-300}
BASE="http://localhost:$PORT"
PASS=0
FAIL=0
FAILURES=""
examples=(
"examples/sparkline.md"
"examples/plotting.md"
"examples/matplotlib-demo.md"
"examples/lean-proofs.md"
"examples/tutorial-lean-integration.md"
"examples/tutorial-python-integration.md"
"examples/typed-ml-pipeline.md"
"examples/verified-crypto.md"
"examples/verified-eda.md"
"examples/widgets.md"
)
for nb in "${examples[@]}"; do
echo "=== Testing: $nb ==="
# Reset session between notebooks
curl -s --max-time 10 -X POST "$BASE/api/reset" > /dev/null 2>&1
# Load notebook
LOAD=$(curl -s --max-time 15 "$BASE/api/load" \
-H 'Content-Type: application/json' \
-d "{\"lrPath\":\"$nb\"}" 2>&1)
NCELLS=$(echo "$LOAD" | python3 -c "
import sys,json
try:
nb=json.load(sys.stdin)
code=[c for c in nb['nbCells'] if c['cellType']=='CodeCell']
print(len(code))
except:
print('ERR')
" 2>/dev/null)
if [ "$NCELLS" = "ERR" ] || [ -z "$NCELLS" ]; then
echo " FAIL: Could not load notebook"
FAIL=$((FAIL+1))
FAILURES="$FAILURES\n $nb: load failed"
continue
fi
echo " Loaded: $NCELLS code cells"
# Wait for executionDone via SSE stream (load already triggers run-all)
EVENTS_FILE=$(mktemp)
curl -sN --max-time "$TIMEOUT" "$BASE/api/events" > "$EVENTS_FILE" 2>&1 &
SSE_PID=$!
# Wait for executionDone event or timeout
ELAPSED=0
DONE=false
while [ $ELAPSED -lt $TIMEOUT ]; do
sleep 3
ELAPSED=$((ELAPSED + 3))
if grep -q '"executionDone"' "$EVENTS_FILE" 2>/dev/null; then
DONE=true
break
fi
if grep -q '"crashed"' "$EVENTS_FILE" 2>/dev/null; then
DONE=true
break
fi
# Progress: count cellResult events
RESULTS=$(grep -c '"cellResult"' "$EVENTS_FILE" 2>/dev/null || echo 0)
echo -ne " [$ELAPSED s] $RESULTS/$NCELLS cells done\r"
done
echo ""
kill $SSE_PID 2>/dev/null
wait $SSE_PID 2>/dev/null
# Analyze final notebook state (accounts for reruns overwriting earlier errors)
CRASHED=$(grep -c '"crashed"' "$EVENTS_FILE" 2>/dev/null || echo 0)
RESULT_COUNT=$(grep -c '"cellResult"' "$EVENTS_FILE" 2>/dev/null || echo 0)
CELL_ERRORS=$(curl -s --max-time 10 "$BASE/api/notebook" 2>/dev/null | python3 -c "
import sys,json
nb=json.load(sys.stdin)
errors=[]
for c in nb['nbCells']:
if c['cellType']=='CodeCell' and c.get('cellError'):
errors.append(f'cell {c[\"cellId\"]}: {c[\"cellError\"][:120]}')
for e in errors:
print(e)
" 2>/dev/null)
ERR_COUNT=$(echo "$CELL_ERRORS" | grep -c . 2>/dev/null || echo 0)
[ -z "$CELL_ERRORS" ] && ERR_COUNT=0
echo " Cells completed: $RESULT_COUNT/$NCELLS"
if [ "$CRASHED" -gt 0 ]; then
echo " RESULT: CRASH"
FAIL=$((FAIL+1))
FAILURES="$FAILURES\n $nb: kernel crashed"
elif [ "$ERR_COUNT" -gt 0 ]; then
echo " Cell errors:"
echo "$CELL_ERRORS" | sed 's/^/ /'
echo " RESULT: ERRORS ($ERR_COUNT)"
FAIL=$((FAIL+1))
FAILURES="$FAILURES\n $nb: $ERR_COUNT cell error(s)"
elif [ "$DONE" = true ]; then
echo " RESULT: PASS"
PASS=$((PASS+1))
else
echo " RESULT: TIMEOUT (${TIMEOUT}s)"
FAIL=$((FAIL+1))
FAILURES="$FAILURES\n $nb: timed out after ${TIMEOUT}s"
fi
rm -f "$EVENTS_FILE"
echo ""
done
echo "=============================="
echo "SUMMARY: $PASS passed, $FAIL failed out of ${#examples[@]}"
if [ -n "$FAILURES" ]; then
echo -e "Failures:$FAILURES"
fi