Files
cyphernode/proxy_docker/app/tests/test-watches.sh

267 lines
12 KiB
Bash
Executable File

#!/bin/bash
. ./colors.sh
. ./mine.sh
# This needs to be run in regtest
# You need jq installed for these tests to run correctly
# This will test:
#
# - getnewaddress
# - watch
# - getactivewatches
# - unwatch
# - watchtxid
# - unwatchtxid
# - spend
#
trace() {
if [ "${1}" -le "${TRACING}" ]; then
echo -e "$(date -u +%FT%TZ) ${2}" 1>&2
fi
}
start_test_container() {
docker run -d --rm -t --name tests-watches --network=cyphernodenet alpine
}
stop_test_container() {
trace 1 "\n\n[stop_test_container] ${BCyan}Stopping existing containers if they are running...${Color_Off}\n"
# docker stop tests-watches
local containers=$(docker ps -q -f "name=tests-watches")
if [ -n "${containers}" ]; then
docker stop ${containers}
fi
}
exec_in_test_container() {
docker exec -it tests-watches "$@"
}
test_watches() {
# Watch addresses and a txid
# 1. Call getnewaddress twice with label1 and label2
# 2. Call watch on the address with label1
# 3. Call watch on the address with label2
# 4. Call getactivewatches, search for addresses with label1 and label2
# 6. unwatch label2
# 7. Call getactivewatches, check that label2 is not there
# 9. Start a callback server for label1 watch 0-conf webhook
# 10. Call spend, to the address with label1 (triggers 0-conf webhook)
# 11. Wait for label1's 0-conf webhook
# 12. Call watchtxid on spent txid with 3-conf webhook
# 13. Start a callback servers for 1-conf txid watch webhook
# 14. Generate a block (triggers 1-conf webhook)
# 15. Wait for 1-conf webhook
# 16. Start a callback servers for 3-conf txid watch webhook
# 17. Generate 2 blocks (triggers 3-conf webhook)
# 18. Wait for 3-conf webhook
# 20. Call getactivewatches, make sure label1 and label2 are not there
local label1="label$RANDOM"
local label2="label$RANDOM"
local callbackurl0conf1="tests-watches:1111/callbackurl0conf1"
local callbackurl1conf1="tests-watches:1112/callbackurl1conf1"
local callbackurl1conftxid="tests-watches:1113/callbackurl1conftxid"
local callbackurl3conftxid="tests-watches:1114/callbackurl3conftxid"
local address
local address1
local address2
local txid
local data
local response
trace 1 "\n\n[test_watches] ${BCyan}Let's test \"watch addresses and a txid\" features!...${Color_Off}\n"
# 1. Call getnewaddress twice with label1 and label2
trace 2 "\n\n[test_watches] ${BCyan}1. getnewaddress...${Color_Off}\n"
data='{"label":"'${label1}'"}'
trace 3 "[test_watches] data=${data}"
response=$(exec_in_test_container curl -d "${data}" proxy:8888/getnewaddress)
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 1. getnewaddress 1 failed: ${data}! ${Color_Off}\n"
return 10
fi
address1=$(echo "$response" | jq -r ".address")
trace 3 "[test_watches] address1=${address1}"
data='{"label":"'${label2}'"}'
trace 3 "[test_watches] data=${data}"
response=$(exec_in_test_container curl -d "${data}" proxy:8888/getnewaddress)
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 1. getnewaddress 2 failed: ${data}! ${Color_Off}\n"
return 15
fi
address2=$(echo "$response" | jq -r ".address")
trace 3 "[test_watches] address2=${address2}"
# 2. Call watch on the address with label1
trace 2 "\n\n[test_watches] ${BCyan}2. watch 1...${Color_Off}\n"
local data='{"address":"'${address1}'","unconfirmedCallbackURL":"'${callbackurl0conf1}'","confirmedCallbackURL":"'${callbackurl1conf1}'","label":"watch_'${label1}'"}'
trace 3 "[test_watches] data=${data}"
response=$(exec_in_test_container curl -d "${data}" proxy:8888/watch)
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 2. watch 1 failed: ${data}! ${Color_Off}\n"
return 20
fi
# 3. Call watch on the address with label2
trace 2 "\n\n[test_watches] ${BCyan}3. watch 2...${Color_Off}\n"
local data='{"address":"'${address2}'","unconfirmedCallbackURL":"dummy","confirmedCallbackURL":"dummy","label":"watch_'${label2}'"}'
trace 3 "[test_watches] data=${data}"
response=$(exec_in_test_container curl -d "${data}" proxy:8888/watch)
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 3. watch 2 failed: ${data}! ${Color_Off}\n"
return 25
fi
# 4. Call getactivewatches, search for addresses with label1 and label2
trace 2 "\n\n[test_watches] ${BCyan}4. Call getactivewatches, search for addresses with label1 and label2...${Color_Off}\n"
response=$(exec_in_test_container curl proxy:8888/getactivewatches)
# trace 3 "[test_watches] response=${response}"
address=$(echo "${response}" | jq -r ".watches | map(select(.label == \"watch_${label1}\"))[0].address")
trace 3 "[test_watches] address=${address}"
if [ "${address}" != "${address1}" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 4. Call getactivewatches, search for address with label1: \"${address}\" != \"${address1}\"! ${Color_Off}\n"
return 30
fi
address=$(echo "${response}" | jq -r ".watches | map(select(.label == \"watch_${label2}\"))[0].address")
trace 3 "[test_watches] address=${address}"
if [ "${address}" != "${address2}" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 4. Call getactivewatches, search for address with label2: \"${address}\" != \"${address2}\"! ${Color_Off}\n"
return 35
fi
# 6. unwatch label2
trace 2 "\n\n[test_watches] ${BCyan}6. unwatch label2...${Color_Off}\n"
response=$(exec_in_test_container curl proxy:8888/unwatch/${address2})
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 6. unwatch label2 failed: ${data}! ${Color_Off}\n"
return 40
fi
# 7. Call getactivewatches, check that label2 is not there
trace 2 "\n\n[test_watches] ${BCyan}7. Call getactivewatches, check that label2 is not there...${Color_Off}\n"
response=$(exec_in_test_container curl proxy:8888/getactivewatches)
# trace 3 "[test_watches] response=${response}"
address=$(echo "${response}" | jq -r ".watches | map(select(.label == \"watch_${label2}\"))[0].address")
trace 3 "[test_watches] address=${address}"
if [ "${address}" = "${address2}" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 4. Call getactivewatches, found address2: \"${address}\" = \"${address2}\"! ${Color_Off}\n"
return 50
fi
# 9. Start a callback server for label1 watch 0-conf webhook
# 10. Call spend, to the address with label1 (triggers 0-conf webhook)
# 11. Wait for label1's 0-conf webhook
trace 2 "\n\n[test_watches] ${BCyan}10. Send coins to address1...${Color_Off}\n"
start_callback_server 1111
# Let's use the bitcoin node directly to better simulate an external spend
txid=$(docker exec -it $(docker ps -q -f "name=cyphernode.bitcoin") bitcoin-cli -rpcwallet=spending01.dat sendtoaddress ${address1} 0.0001 | tr -d "\r\n")
# txid=$(exec_in_test_container curl -d '{"address":"'${address1}'","amount":0.001}' proxy:8888/spend | jq -r ".txid")
trace 3 "[test_watches] txid=${txid}"
trace 3 "[test_watches] Waiting for 0-conf callback on address1..."
wait
# 12. Call watchtxid on spent txid with 3-conf webhook
trace 2 "\n\n[test_watches] ${BCyan}12. Call watchtxid on spent txid with 3-conf webhook...${Color_Off}\n"
# BODY {"txid":"b081ca7724386f549cf0c16f71db6affeb52ff7a0d9b606fb2e5c43faffd3387","confirmedCallbackURL":"192.168.111.233:1111/callback1conf","xconfCallbackURL":"192.168.111.233:1111/callbackXconf","nbxconf":6}
local data='{"txid":"'${txid}'","confirmedCallbackURL":"'${callbackurl1conftxid}'","xconfCallbackURL":"'${callbackurl3conftxid}'","nbxconf":3}'
trace 3 "[test_watches] data=${data}"
response=$(exec_in_test_container curl -d "${data}" proxy:8888/watchtxid)
trace 3 "[test_watches] response=${response}"
data=$(echo "${response}" | jq -re ".error")
if [ "${?}" -eq "0" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 12. Call watchtxid on spent txid with 3-conf webhook failed: ${data}! ${Color_Off}\n"
return 60
fi
# 13. Start a callback servers for 1-conf txid watch webhook
trace 2 "\n\n[test_watches] ${BCyan}13. Start a callback servers for 1-conf txid watch webhook...${Color_Off}\n"
start_callback_server 1112
start_callback_server 1113
# 14. Generate a block (triggers 1-conf webhook)
trace 3 "[test_manage_missed_1_conf] Mine a new block..."
mine
# 15. Wait for 1-conf webhook
trace 3 "[test_watches] Waiting for 1-conf callbacks on address1 and txid..."
wait
# 16. Start a callback servers for 3-conf txid watch webhook
trace 2 "\n\n[test_watches] ${BCyan}16. Start a callback servers for 3-conf txid watch webhook...${Color_Off}\n"
start_callback_server 1114
# 17. Generate 2 blocks (triggers 3-conf webhook)
trace 3 "[test_watches] Mine 2 new blocks..."
mine 2
# 18. Wait for 3-conf webhook
trace 3 "[test_watches] Waiting for 3-conf callback on txid..."
wait
# 20. Call getactivewatches, make sure label1 and label2 are not there
trace 2 "\n\n[test_watches] ${BCyan}20. Call getactivewatches, make sure label1 and label2 are not there...${Color_Off}\n"
response=$(exec_in_test_container curl proxy:8888/getactivewatches)
# trace 3 "[test_watches] response=${response}"
address=$(echo "${response}" | jq -r ".watches | map(select(.label == \"watch_${label1}\"))[0].address")
trace 3 "[test_watches] address=${address}"
if [ "${address}" = "${address1}" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 4. Call getactivewatches, found address1: \"${address}\" = \"${address1}\"! ${Color_Off}\n"
return 70
fi
address=$(echo "${response}" | jq -r ".watches | map(select(.label == \"watch_${label2}\"))[0].address")
trace 3 "[test_watches] address=${address}"
if [ "${address}" = "${address2}" ]; then
trace 1 "\n\n[test_watches] ${On_Red}${BBlack} 4. Call getactivewatches, found address2: \"${address}\" = \"${address2}\"! ${Color_Off}\n"
return 75
fi
trace 1 "\n\n[test_watches] ${On_IGreen}${BBlack} ALL GOOD! Yayyyy! ${Color_Off}\n"
}
start_callback_server() {
trace 1 "[start_callback_server] ${BCyan}Let's start the callback servers!...${Color_Off}"
local port=${1:-1111}
docker exec -t tests-watches sh -c "nc -vlp${port} -e sh -c 'echo -en \"HTTP/1.1 200 OK\\\\r\\\\n\\\\r\\\\n\" ; echo -en \"\\033[40m\\033[0;37m\" >&2 ; date >&2 ; timeout 1 tee /dev/tty | cat ; echo -e \"\033[0m\" >&2'" &
}
TRACING=3
stop_test_container
start_test_container
trace 1 "\n\n[test_watches] ${BCyan}Installing needed packages...${Color_Off}\n"
exec_in_test_container apk add --update curl
test_watches
trace 1 "\n\n[test_watches] ${BCyan}Tearing down...${Color_Off}\n"
wait
stop_test_container
trace 1 "\n\n[test_watches] ${BCyan}See ya!${Color_Off}\n"