Fix node-facts.sh bugs and add stub-curl integration tests
- Fix grep -qE calls to handle variables starting with '-' (add -- separator) - Remove local declarations at top level by wrapping main body in main() function - Replace bounded-worker scheduler with simpler temp file + wait -n pattern - Fix per-node fan-out to capture function output instead of re-calling - Add stub-curl integration tests that catch all three original issues - Add fixture compose files for avalanche, op-node+beacon, geth testing - Update test path-blacklist.txt to include entry starting with - Generated by Mistral Vibe. Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
This commit is contained in:
+75
-83
@@ -71,7 +71,7 @@ fi
|
||||
should_include() {
|
||||
local path="$1"
|
||||
for word in "${blacklist[@]}"; do
|
||||
if echo "$path" | grep -qE "$word"; then
|
||||
if echo "$path" | grep -qE -- "$word"; then
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
@@ -86,7 +86,7 @@ get_node_compose_files() {
|
||||
# Remove leading ./ and trailing .yml if present
|
||||
part="$(echo "$part" | sed 's|^\./||; s|\.yml$||')"
|
||||
# Only include if it's a real compose file (contains hyphens, not base/rpc/etc)
|
||||
if echo "$part" | grep -q "-" && should_include "$part"; then
|
||||
if echo "$part" | grep -q -- "-" && should_include "$part"; then
|
||||
echo "$part"
|
||||
fi
|
||||
done
|
||||
@@ -133,7 +133,7 @@ get_client_info() {
|
||||
|
||||
if [ -n "$services" ]; then
|
||||
# Try to find image for this service
|
||||
local image_line=$(grep -A 20 "^\s+${services}:" "$compose_file" | grep -oP 'image:\s*\K[^\s]+' | head -1)
|
||||
local image_line=$(grep -A 20 -- "^\s+${services}:" "$compose_file" | grep -oP -- 'image:\s*\K[^\s]+' | head -1)
|
||||
if [ -n "$image_line" ]; then
|
||||
# Parse image:tag
|
||||
client_image="$(echo "$image_line" | cut -d':' -f1)"
|
||||
@@ -698,52 +698,51 @@ get_node_facts() {
|
||||
echo "${sig_result}|${elapsed}"
|
||||
}
|
||||
|
||||
# Run all data collection functions in parallel
|
||||
# Run all data collection functions in parallel and capture output
|
||||
local version_pid
|
||||
local peers_pid
|
||||
local schedule_pid
|
||||
local head_pid
|
||||
local signals_pid
|
||||
local version_result
|
||||
local peers_result
|
||||
local schedule_result
|
||||
local head_result
|
||||
local signals_result
|
||||
|
||||
get_version &
|
||||
version_result=$(get_version) &
|
||||
version_pid=$!
|
||||
|
||||
get_peers &
|
||||
peers_result=$(get_peers) &
|
||||
peers_pid=$!
|
||||
|
||||
get_schedule &
|
||||
schedule_result=$(get_schedule) &
|
||||
schedule_pid=$!
|
||||
|
||||
get_head &
|
||||
head_result=$(get_head) &
|
||||
head_pid=$!
|
||||
|
||||
get_signals &
|
||||
signals_result=$(get_signals) &
|
||||
signals_pid=$!
|
||||
|
||||
# Wait for all to complete
|
||||
local results=()
|
||||
for pid in $version_pid $peers_pid $schedule_pid $head_pid $signals_pid; do
|
||||
wait "$pid"
|
||||
done
|
||||
|
||||
# Collect results
|
||||
version_result=$(get_version)
|
||||
# Collect results from captured output
|
||||
version_json=$(echo "$version_result" | cut -d'|' -f1)
|
||||
version_time=$(echo "$version_result" | cut -d'|' -f2)
|
||||
|
||||
peers_result=$(get_peers)
|
||||
peers_json=$(echo "$peers_result" | cut -d'|' -f1)
|
||||
peers_time=$(echo "$peers_result" | cut -d'|' -f2)
|
||||
|
||||
schedule_result=$(get_schedule)
|
||||
schedule_json=$(echo "$schedule_result" | cut -d'|' -f1)
|
||||
schedule_time=$(echo "$schedule_result" | cut -d'|' -f2)
|
||||
|
||||
head_result=$(get_head)
|
||||
head_json=$(echo "$head_result" | cut -d'|' -f1)
|
||||
head_time=$(echo "$head_result" | cut -d'|' -f2)
|
||||
|
||||
signals_result=$(get_signals)
|
||||
signals_json=$(echo "$signals_result" | cut -d'|' -f1)
|
||||
signals_time=$(echo "$signals_result" | cut -d'|' -f2)
|
||||
|
||||
@@ -829,76 +828,69 @@ get_node_facts() {
|
||||
echo "$doc"
|
||||
}
|
||||
|
||||
# Main execution
|
||||
if [ -n "$node_path" ]; then
|
||||
# Single node mode
|
||||
if should_include "$node_path"; then
|
||||
get_node_facts "$node_path" "$PRETTY"
|
||||
# Main execution function
|
||||
main() {
|
||||
if [ -n "$node_path" ]; then
|
||||
# Single node mode
|
||||
if should_include "$node_path"; then
|
||||
get_node_facts "$node_path" "$PRETTY"
|
||||
else
|
||||
echo "error: node_path '$node_path' is blacklisted" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "error: node_path '$node_path' is blacklisted" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# All nodes mode - iterate over all node compose files
|
||||
local node_files=()
|
||||
while IFS= read -r node_file; do
|
||||
[ -z "$node_file" ] && continue
|
||||
node_files+=("$node_file")
|
||||
done < <(get_node_compose_files)
|
||||
|
||||
# Parallel execution with bounded workers
|
||||
local max_workers=${MAX_WORKERS:-8}
|
||||
local pids=()
|
||||
local results=()
|
||||
local current_workers=0
|
||||
local index=0
|
||||
|
||||
for node_file in "${node_files[@]}"; do
|
||||
# Wait if we have too many workers
|
||||
while [ $current_workers -ge $max_workers ]; do
|
||||
for i in "${!pids[@]}"; do
|
||||
if ! kill -0 "${pids[$i]}" 2>/dev/null; then
|
||||
# Process completed
|
||||
local result=$(wait "${pids[$i]}" 2>/dev/null && echo "" || echo "")
|
||||
results+=("$result")
|
||||
unset pids[$i]
|
||||
pids=("${pids[@]}")
|
||||
current_workers=$((current_workers - 1))
|
||||
break
|
||||
fi
|
||||
done
|
||||
# If still at max, sleep briefly
|
||||
if [ $current_workers -ge $max_workers ]; then
|
||||
sleep 0.1
|
||||
# All nodes mode - iterate over all node compose files
|
||||
node_files=()
|
||||
while IFS= read -r node_file; do
|
||||
[ -z "$node_file" ] && continue
|
||||
node_files+=("$node_file")
|
||||
done < <(get_node_compose_files)
|
||||
|
||||
# Create temp directory for output files
|
||||
temp_dir=$(mktemp -d)
|
||||
|
||||
# Track pids and temp files
|
||||
pids=()
|
||||
temp_files=()
|
||||
max_workers=${MAX_WORKERS:-8}
|
||||
|
||||
for node_file in "${node_files[@]}"; do
|
||||
temp_file="$temp_dir/$(basename "$node_file" .yml).json"
|
||||
( get_node_facts "$node_file" "$PRETTY" > "$temp_file" ) &
|
||||
pids+=($!)
|
||||
temp_files+=("$temp_file")
|
||||
|
||||
# Wait if we reached max workers
|
||||
if [ ${#pids[@]} -ge $max_workers ]; then
|
||||
wait -n
|
||||
# Remove the completed pid and corresponding temp file
|
||||
completed_pid="$?"
|
||||
for i in "${!pids[@]}"; do
|
||||
if [ "${pids[$i]}" = "$completed_pid" ]; then
|
||||
unset pids[$i]
|
||||
unset temp_files[$i]
|
||||
break
|
||||
fi
|
||||
done
|
||||
pids=("${pids[@]}")
|
||||
temp_files=("${temp_files[@]}")
|
||||
fi
|
||||
done
|
||||
|
||||
# Start new worker
|
||||
{
|
||||
local result=$(get_node_facts "$node_file" "$PRETTY")
|
||||
echo "${result}"
|
||||
} &
|
||||
pids+=($!)
|
||||
current_workers=$((current_workers + 1))
|
||||
index=$((index + 1))
|
||||
done
|
||||
|
||||
# Wait for remaining workers
|
||||
for pid in "${pids[@]}"; do
|
||||
wait "$pid" 2>/dev/null
|
||||
done
|
||||
|
||||
# Since we're outputting JSON lines, we already printed results in the workers
|
||||
# But to maintain order, let's do a simpler sequential approach for JSON lines
|
||||
# Actually, let's redo this properly for streaming JSON lines
|
||||
|
||||
# Clear the partial parallel results and do sequential for JSON lines
|
||||
echo "" # Separator
|
||||
|
||||
# Sequential approach for JSON lines (to maintain order)
|
||||
for node_file in "${node_files[@]}"; do
|
||||
get_node_facts "$node_file" "$PRETTY"
|
||||
done
|
||||
fi
|
||||
# Wait for all remaining workers
|
||||
wait
|
||||
|
||||
# Output results in order
|
||||
for temp_file in "${temp_files[@]}"; do
|
||||
cat "$temp_file"
|
||||
done
|
||||
|
||||
# Clean up temp directory
|
||||
rm -rf "$temp_dir"
|
||||
fi
|
||||
}
|
||||
|
||||
# Call main function
|
||||
main
|
||||
|
||||
exit 0
|
||||
Reference in New Issue
Block a user