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:
2026-10-06 07:22:51 +00:00
parent d57d19276e
commit fe22be322e
7 changed files with 367 additions and 83 deletions
+127
View File
@@ -0,0 +1,127 @@
#!/bin/bash
# Simple stub curl for node-facts.sh testing
# Returns minimal valid JSON responses
# Extract the URL (last http/https argument)
URL=""
METHOD=""
for arg in "$@"; do
if [[ "$arg" == http* || "$arg" == https* ]]; then
URL="$arg"
fi
# Look for method in JSON data arguments
if echo "$arg" | grep -q "method"; then
METHOD=$(echo "$arg" | sed -n 's/.*"method":"\([^"]*\)".*/\1/p' | head -1)
[ -n "$METHOD" ] && break
fi
done
# If method not found in data args, try to extract from the URL
if [ -z "$METHOD" ]; then
# Extract method from URL path for REST endpoints
case "$URL" in
*eth/v1/node/version*) METHOD="eth/v1/node/version" ;;
*eth/v1/node/peers*) METHOD="eth/v1/node/peers" ;;
*eth/v1/config/spec*) METHOD="eth/v1/config/spec" ;;
*eth/v1/node/syncing*) METHOD="eth/v1/node/syncing" ;;
*eth/v1/node/head*) METHOD="eth/v1/node/head" ;;
*optimism_version*) METHOD="optimism_version" ;;
*opp2p_peers*) METHOD="opp2p_peers" ;;
*optimism_rollupConfig*) METHOD="optimism_rollupConfig" ;;
*optimism_syncStatus*) METHOD="optimism_syncStatus" ;;
esac
fi
# Respond based on URL and method
case "$URL" in
*avalanche-mainnet-go*)
case "$METHOD" in
info.getNodeVersion)
echo '{"jsonrpc":"2.0","result":{"version":"avalanche/1.10.0","databaseVersion":"1.0.0"},"id":1}'
;;
info.peers)
echo '{"jsonrpc":"2.0","result":[{"version":"avalanche/1.10.0"},{"version":"avalanche/1.9.0"}],"id":1}'
;;
info.upgrades)
echo '{"jsonrpc":"2.0","result":{"apricotPhase1Time":4200000},"id":1}'
;;
*)
# For /ext/info without method, return version info
if [[ "$URL" == *"/ext/info"* ]]; then
echo '{"jsonrpc":"2.0","result":{"version":"avalanche/1.10.0","databaseVersion":"1.0.0"},"id":1}'
else
echo '{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":1}'
fi
;;
esac
;;
*ethereum-mainnet-lighthouse* | *beacon* | *lighthouse*)
case "$METHOD" in
eth/v1/node/version*)
echo '{"version":"Lighthouse/v5.3.0"}'
;;
eth/v1/node/peers*)
echo '{"data":[]}'
;;
eth/v1/config/spec*)
echo '{"data":{}}'
;;
eth/v1/node/syncing*)
echo '{"data":{"head_slot":"100","syncing":false}}'
;;
eth/v1/node/head*)
echo '{"data":{"slot":"100","timestamp":"2026-10-06T12:00:00Z"}}'
;;
*)
echo '{"message":"Not found"}'
;;
esac
;;
*op-base-mainnet* | *op-node* | *kona*)
case "$METHOD" in
optimism_version* | */node*)
echo '{"result":"v1.19.0"}'
;;
opp2p_peers*)
echo '{"result":[]}'
;;
optimism_rollupConfig*)
echo '{"result":{}}'
;;
optimism_syncStatus*)
echo '{"result":{"current_block_number":"100","syncing":false}}'
;;
*)
echo '{"message":"Not found"}'
;;
esac
;;
*ethereum-mainnet-geth* | *geth*)
case "$METHOD" in
web3_clientVersion)
echo '{"jsonrpc":"2.0","result":"Geth/v1.13.0-stable","id":1}'
;;
admin_peers)
echo '{"jsonrpc":"2.0","result":[{"clientId":"Geth/v1.13.0"},{"clientId":"Geth/v1.12.0"}],"id":1}'
;;
eth_blockNumber)
echo '{"jsonrpc":"2.0","result":"0x64","id":1}'
;;
eth_getBlockByNumber)
echo '{"jsonrpc":"2.0","result":{"timestamp":"0x65a6b3d4","number":"0x64"},"id":1}'
;;
eth_syncing)
echo '{"jsonrpc":"2.0","result":false,"id":1}'
;;
*)
echo '{"jsonrpc":"2.0","error":{"code":-32601,"message":"Method not found"},"id":1}'
;;
esac
;;
*)
echo '{"jsonrpc":"2.0","error":{"code":-32601,"message":"Unknown endpoint"},"id":1}'
;;
esac
exit 0