test: US-08 DWN sync tests pass 50/50 — fix sync performance
- Make dwn.sync endpoint async: spawns background task, returns immediately - Add 90s overall timeout to sync_with_peers via tokio::time::timeout - Deduplicate peer onion addresses before syncing - Batch message pushes (50 per request) instead of one-at-a-time over Tor - Add 15s connect_timeout to Tor SOCKS5 client - Cap local message query to 200 messages per sync - Fix DWN HTTP handler to process ALL messages in batch (was only first) - Add recordId deduplication in handler to prevent duplicate imports - Update test script to poll dwn.status for sync completion Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -514,6 +514,162 @@ for tid in test_items:
|
||||
done
|
||||
done
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# US-08: DWN Sync
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
echo ""
|
||||
echo "# --- US-08: DWN Sync ---"
|
||||
|
||||
TEST_PROTOCOL="https://archipelago.test/cross-node-$(date +%s)"
|
||||
|
||||
# Helper: trigger sync and wait for completion (polls dwn.status)
|
||||
trigger_sync_and_wait() {
|
||||
local host="$1" session="$2" csrf="$3" max_wait="${4:-120}"
|
||||
|
||||
# Trigger sync (returns immediately with "syncing")
|
||||
curl -s --max-time 10 -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session}; csrf_token=${csrf}" \
|
||||
-H "X-CSRF-Token: ${csrf}" \
|
||||
-d '{"method":"dwn.sync"}' \
|
||||
"http://${host}:5678/rpc/v1" >/dev/null 2>&1
|
||||
|
||||
# Poll until sync completes or times out
|
||||
local elapsed=0
|
||||
while [[ $elapsed -lt $max_wait ]]; do
|
||||
sleep 5
|
||||
elapsed=$((elapsed + 5))
|
||||
local status_result
|
||||
status_result=$(curl -s --max-time 5 -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session}; csrf_token=${csrf}" \
|
||||
-H "X-CSRF-Token: ${csrf}" \
|
||||
-d '{"method":"dwn.status"}' \
|
||||
"http://${host}:5678/rpc/v1" 2>/dev/null)
|
||||
local sync_st
|
||||
sync_st=$(echo "$status_result" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('result',{}).get('sync_status','unknown'))" 2>/dev/null || echo "unknown")
|
||||
if [[ "$sync_st" != "syncing" ]]; then
|
||||
echo "$sync_st"
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
echo "timeout"
|
||||
return 1
|
||||
}
|
||||
|
||||
for i in $(seq 1 "$ITERATIONS"); do
|
||||
# Get auth for both nodes
|
||||
session_header_a=$(get_session "$NODE_A")
|
||||
session_a=$(echo "$session_header_a" | sed -n 's/.*session=\([^;]*\).*/\1/p')
|
||||
csrf_a=$(echo "$session_header_a" | sed -n 's/.*csrf_token=\([^;]*\).*/\1/p')
|
||||
|
||||
session_header_b=$(get_session "$NODE_B")
|
||||
session_b=$(echo "$session_header_b" | sed -n 's/.*session=\([^;]*\).*/\1/p')
|
||||
csrf_b=$(echo "$session_header_b" | sed -n 's/.*csrf_token=\([^;]*\).*/\1/p')
|
||||
|
||||
iter_protocol="${TEST_PROTOCOL}-${i}"
|
||||
|
||||
# Check 1: Register protocol on .228
|
||||
reg_result=$(curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session_a}; csrf_token=${csrf_a}" \
|
||||
-H "X-CSRF-Token: ${csrf_a}" \
|
||||
-d "{\"method\":\"dwn.register-protocol\",\"params\":{\"protocol\":\"${iter_protocol}\",\"published\":true}}" \
|
||||
"http://${NODE_A}:5678/rpc/v1" 2>/dev/null)
|
||||
reg_ok=$(echo "$reg_result" | python3 -c "import sys,json; d=json.load(sys.stdin); print('ok' if d.get('result',{}).get('registered') else 'no')" 2>/dev/null || echo "error")
|
||||
if [[ "$reg_ok" == "ok" ]]; then
|
||||
tap_ok "US08-A-register-protocol-${i}"
|
||||
else
|
||||
tap_fail "US08-A-register-protocol-${i}" "register failed: ${reg_result:0:80}"
|
||||
fi
|
||||
|
||||
# Check 2: Write 3 messages on .228
|
||||
write_ok=0
|
||||
for msg_i in 1 2 3; do
|
||||
w_result=$(curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session_a}; csrf_token=${csrf_a}" \
|
||||
-H "X-CSRF-Token: ${csrf_a}" \
|
||||
-d "{\"method\":\"dwn.write-message\",\"params\":{\"author\":\"did:key:test228\",\"protocol\":\"${iter_protocol}\",\"schema\":\"test/msg\",\"dataFormat\":\"application/json\",\"data\":{\"seq\":${msg_i},\"iter\":${i}}}}" \
|
||||
"http://${NODE_A}:5678/rpc/v1" 2>/dev/null)
|
||||
written=$(echo "$w_result" | python3 -c "import sys,json; d=json.load(sys.stdin); print('ok' if d.get('result',{}).get('written') else 'no')" 2>/dev/null || echo "error")
|
||||
[[ "$written" == "ok" ]] && write_ok=$((write_ok + 1))
|
||||
done
|
||||
if [[ "$write_ok" -eq 3 ]]; then
|
||||
tap_ok "US08-A-write-messages-${i} # wrote=3"
|
||||
else
|
||||
tap_fail "US08-A-write-messages-${i}" "Only ${write_ok}/3 messages written"
|
||||
fi
|
||||
|
||||
# Check 3: Trigger DWN sync on .228 and wait for completion
|
||||
sync_status=$(trigger_sync_and_wait "$NODE_A" "$session_a" "$csrf_a" 120)
|
||||
if [[ "$sync_status" == "synced" || "$sync_status" == "idle" ]]; then
|
||||
tap_ok "US08-A-sync-${i}"
|
||||
else
|
||||
tap_fail "US08-A-sync-${i}" "sync status: ${sync_status}"
|
||||
fi
|
||||
|
||||
# Trigger sync on .198 to pull messages and wait
|
||||
trigger_sync_and_wait "$NODE_B" "$session_b" "$csrf_b" 120 >/dev/null 2>&1
|
||||
|
||||
# Check 4: Query messages on .198 — should have the 3 from .228
|
||||
query_result=$(curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session_b}; csrf_token=${csrf_b}" \
|
||||
-H "X-CSRF-Token: ${csrf_b}" \
|
||||
-d "{\"method\":\"dwn.query-messages\",\"params\":{\"protocol\":\"${iter_protocol}\"}}" \
|
||||
"http://${NODE_B}:5678/rpc/v1" 2>/dev/null)
|
||||
msg_count=$(echo "$query_result" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('result',{}).get('count',0))" 2>/dev/null || echo "0")
|
||||
if [[ "$msg_count" -ge 3 ]]; then
|
||||
tap_ok "US08-B-received-messages-${i} # count=${msg_count}"
|
||||
else
|
||||
tap_fail "US08-B-received-messages-${i}" "Only ${msg_count}/3 messages synced to .198"
|
||||
fi
|
||||
|
||||
# Check 5: Write on .198, sync, verify on .228 (reverse direction)
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session_b}; csrf_token=${csrf_b}" \
|
||||
-H "X-CSRF-Token: ${csrf_b}" \
|
||||
-d "{\"method\":\"dwn.write-message\",\"params\":{\"author\":\"did:key:test198\",\"protocol\":\"${iter_protocol}\",\"schema\":\"test/msg\",\"dataFormat\":\"application/json\",\"data\":{\"from\":\"198\",\"iter\":${i}}}}" \
|
||||
"http://${NODE_B}:5678/rpc/v1" >/dev/null 2>&1
|
||||
|
||||
# Sync .198 → .228
|
||||
trigger_sync_and_wait "$NODE_B" "$session_b" "$csrf_b" 120 >/dev/null 2>&1
|
||||
|
||||
# Pull on .228
|
||||
trigger_sync_and_wait "$NODE_A" "$session_a" "$csrf_a" 120 >/dev/null 2>&1
|
||||
|
||||
# Check 6: Query on .228 — should have 3 from .228 + synced from .198
|
||||
query_result_a=$(curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${session_a}; csrf_token=${csrf_a}" \
|
||||
-H "X-CSRF-Token: ${csrf_a}" \
|
||||
-d "{\"method\":\"dwn.query-messages\",\"params\":{\"protocol\":\"${iter_protocol}\"}}" \
|
||||
"http://${NODE_A}:5678/rpc/v1" 2>/dev/null)
|
||||
msg_count_a=$(echo "$query_result_a" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('result',{}).get('count',0))" 2>/dev/null || echo "0")
|
||||
if [[ "$msg_count_a" -ge 4 ]]; then
|
||||
tap_ok "US08-A-bidirectional-${i} # count=${msg_count_a}"
|
||||
else
|
||||
tap_fail "US08-A-bidirectional-${i}" "Expected >=4 messages on .228, got ${msg_count_a}"
|
||||
fi
|
||||
done
|
||||
|
||||
# Clean up test protocols
|
||||
for node in "$NODE_A" "$NODE_B"; do
|
||||
session_header=$(get_session "$node")
|
||||
sv=$(echo "$session_header" | sed -n 's/.*session=\([^;]*\).*/\1/p')
|
||||
cv=$(echo "$session_header" | sed -n 's/.*csrf_token=\([^;]*\).*/\1/p')
|
||||
for ci in $(seq 1 "$ITERATIONS"); do
|
||||
curl -s -X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Cookie: session=${sv}; csrf_token=${cv}" \
|
||||
-H "X-CSRF-Token: ${cv}" \
|
||||
-d "{\"method\":\"dwn.remove-protocol\",\"params\":{\"protocol\":\"${TEST_PROTOCOL}-${ci}\"}}" \
|
||||
"http://${node}:5678/rpc/v1" >/dev/null 2>&1
|
||||
done
|
||||
done
|
||||
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
# US-09: NIP-07 Signing
|
||||
# ═══════════════════════════════════════════════════════════════════════════
|
||||
|
||||
Reference in New Issue
Block a user