#!/usr/bin/env nu
use common.nu *
def main [] {
# 1. ensure http-nu is installed
if (which http-nu | is-empty) {
print "http-nu not found, installing..."
cargo install http-nu
}
# 2. setup ports and paths
let port = resolve-test-port 3006
let mock_port = resolve-test-mock-port 3008
let url = $"http://localhost:($port)"
let debug_port = resolve-test-debug-port ($port + 1)
let debug_url = $"http://localhost:($debug_port)"
let mock_url = $"http://localhost:($mock_port)"
let db_path = (mktemp -d -t hydrant_full_net.XXXXXX)
print $"testing full network crawler..."
print $"database path: ($db_path)"
# 3. start mock relay
print $"starting mock relay on ($mock_port)..."
let mock_pid = (
bash -c $"http-nu :($mock_port) tests/mock_relay.nu > ($db_path)/mock.log 2>&1 & echo $!"
| str trim
| into int
)
print $"mock relay pid: ($mock_pid)"
# give mock relay a moment
sleep 1sec
# 4. start hydrant in full network mode, firehose disabled
let binary = build-hydrant
let log_file = $"($db_path)/hydrant.log"
print $"starting hydrant - logs at ($log_file)..."
let hydrant_pid = (
with-env {
HYDRANT_DATABASE_PATH: ($db_path),
HYDRANT_FULL_NETWORK: "true",
HYDRANT_RELAY_HOST: ($mock_url),
HYDRANT_ENABLE_FIREHOSE: "false",
HYDRANT_ENABLE_BACKFILL: "false",
HYDRANT_API_BIND: $"127.0.0.1:($port)",
HYDRANT_ENABLE_DEBUG: "true", # for stats checking
HYDRANT_DEBUG_PORT: (resolve-test-debug-port ($port + 1) | into string),
HYDRANT_LOG_LEVEL: "debug",
HYDRANT_CURSOR_SAVE_INTERVAL: "1s" # faster save
} {
sh -c $"($binary) >($log_file) 2>&1 & echo $!" | str trim | into int
}
)
print $"hydrant started with pid: ($hydrant_pid)"
mut success = false
try {
if (wait-for-api $url) {
print "hydrant api is up."
# wait for crawler to run (it runs on startup)
print "waiting for crawler to fetch repos..."
# retry check for 30s
for i in 1..30 {
let stats = (http get $"($url)/stats").counts
let pending = ($stats.pending | into int)
let repos = ($stats.repos | default 0 | into int)
# six active repos span two pages; the inactive unknown repo is not queued
print $"[($i)/30] pending: ($pending), known_repos: ($repos)"
if $repos == 6 and $pending == 6 {
print "crawler successfully discovered repos!"
$success = true
break
}
sleep 1sec
}
if not $success {
print "timeout waiting for crawler."
}
# a completed pass clears its resume cursor so the next hourly pass starts over
print "verifying completed crawler cursor reset..."
let cursor_check = try {
# cursor key format is now: crawler_cursor|{relay_id_hash}
let cursor_iter = (http get $"($debug_url)/debug/iter?partition=cursors")
print $"cursors in db: ($cursor_iter | to json)"
let has_cursor = ($cursor_iter.items | any { |it| ($it.0 | str starts-with "crawler_cursor") })
if $has_cursor {
print "cursor still present after completed pass."
false
} else {
print "terminal cursor reset verified."
true
}
} catch {
print "failed to get cursor from debug endpoint"
false
}
if not $cursor_check { $success = false }
} else {
print "hydrant failed to start."
}
} catch { |e|
print $"test failed with error: ($e)"
}
# cleanup
print "stopping processes..."
try { kill $hydrant_pid }
try { kill $mock_pid }
if $success {
print "test passed!"
exit 0
} else {
print "test failed!"
print "hydrant logs:"
open $log_file | tail -n 20
print "mock logs:"
open $"($db_path)/mock.log"
exit 1
}
}