Makes validator integration test more robust - adds extra tracking

This commit is contained in:
Marcin Czenko 2024-10-17 06:42:13 +02:00
parent bfb82ad2c1
commit cd077b2710
No known key found for this signature in database
GPG Key ID: 33DEA0C8E30937C0
2 changed files with 81 additions and 21 deletions

View File

@ -1,5 +1,7 @@
from std/times import inMilliseconds, initDuration, inSeconds, fromUnix from std/times import inMilliseconds, initDuration, inSeconds, fromUnix
import std/strformat
import pkg/codex/logutils import pkg/codex/logutils
import pkg/questionable/results
import ../contracts/time import ../contracts/time
import ../contracts/deployment import ../contracts/deployment
import ../codex/helpers import ../codex/helpers
@ -12,10 +14,30 @@ export logutils
logScope: logScope:
topics = "integration test validation" topics = "integration test validation"
template eventuallyS*(expression: untyped, timeout=10, step = 5): bool =
bind Moment, now, seconds
proc eventuallyS: Future[bool] {.async.} =
let endTime = Moment.now() + timeout.seconds
var i = 0
while not expression:
inc i
echo (i*step).seconds
if endTime < Moment.now():
return false
await sleepAsync(step.seconds)
return true
await eventuallyS()
marketplacesuite "Validation": marketplacesuite "Validation":
let nodes = 3 let nodes = 3
let tolerance = 1 let tolerance = 1
let proofProbability = 1 let proofProbability = 1
when defined(windows):
let providerUrl = "ws://localhost:8545"
else:
let providerUrl = "http://localhost:8545"
test "validator marks proofs as missing when using validation groups", NodeConfigs( test "validator marks proofs as missing when using validation groups", NodeConfigs(
# Uncomment to start Hardhat automatically, typically so logs can be inspected locally # Uncomment to start Hardhat automatically, typically so logs can be inspected locally
@ -24,7 +46,7 @@ marketplacesuite "Validation":
clients: clients:
CodexConfigs.init(nodes=1) CodexConfigs.init(nodes=1)
.withEthProvider("http://localhost:8545") .withEthProvider(providerUrl)
# .debug() # uncomment to enable console log output # .debug() # uncomment to enable console log output
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
.withLogTopics("purchases", "onchain") .withLogTopics("purchases", "onchain")
@ -33,7 +55,7 @@ marketplacesuite "Validation":
providers: providers:
CodexConfigs.init(nodes=1) CodexConfigs.init(nodes=1)
.withSimulateProofFailures(idx=0, failEveryNProofs=1) .withSimulateProofFailures(idx=0, failEveryNProofs=1)
.withEthProvider("http://localhost:8545") .withEthProvider(providerUrl)
# .debug() # uncomment to enable console log output # .debug() # uncomment to enable console log output
# .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log # .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .withLogTopics("sales", "onchain") # .withLogTopics("sales", "onchain")
@ -41,6 +63,7 @@ marketplacesuite "Validation":
validators: validators:
CodexConfigs.init(nodes=2) CodexConfigs.init(nodes=2)
.withEthProvider(providerUrl)
.withValidationGroups(groups = 2) .withValidationGroups(groups = 2)
.withValidationGroupIndex(idx = 0, groupIndex = 0) .withValidationGroupIndex(idx = 0, groupIndex = 0)
.withValidationGroupIndex(idx = 1, groupIndex = 1) .withValidationGroupIndex(idx = 1, groupIndex = 1)
@ -53,6 +76,11 @@ marketplacesuite "Validation":
let expiry = 5.periods let expiry = 5.periods
let duration = expiry + 10.periods let duration = expiry + 10.periods
echo fmt"{providerUrl = }"
# for a good start
discard await ethProvider.send("evm_mine")
var currentTime = await ethProvider.currentTime() var currentTime = await ethProvider.currentTime()
let requestEndTime = currentTime.truncate(uint64) + duration let requestEndTime = currentTime.truncate(uint64) + duration
@ -76,8 +104,22 @@ marketplacesuite "Validation":
debug "validation suite", purchaseId = purchaseId.toHex, requestId = requestId debug "validation suite", purchaseId = purchaseId.toHex, requestId = requestId
check eventually(client0.purchaseStateIs(purchaseId, "started"), echo fmt"expiry = {(expiry + 60).int.seconds}"
timeout = expiry.int * 1000)
check eventuallyS(client0.purchaseStateIs(purchaseId, "started"),
timeout = (expiry + 60).int, step = 5)
# if purchase state is not "started", it does not make sense to continue
without purchaseState =? client0.getPurchase(purchaseId).?state:
fail()
debug "validation suite", purchaseState = purchaseState
echo fmt"{purchaseState = }"
if purchaseState != "started":
fail()
discard await ethProvider.send("evm_mine")
currentTime = await ethProvider.currentTime() currentTime = await ethProvider.currentTime()
let secondsTillRequestEnd = (requestEndTime - currentTime.truncate(uint64)).int let secondsTillRequestEnd = (requestEndTime - currentTime.truncate(uint64)).int
@ -91,8 +133,8 @@ marketplacesuite "Validation":
# NOTICE: We actually have to wait for the "errored" state, because # NOTICE: We actually have to wait for the "errored" state, because
# immediately after withdrawing the funds the purchasing state machine # immediately after withdrawing the funds the purchasing state machine
# transitions to the "errored" state. # transitions to the "errored" state.
check eventually(client0.purchaseStateIs(purchaseId, "errored"), check eventuallyS(client0.purchaseStateIs(purchaseId, "errored"),
timeout = (secondsTillRequestEnd + 60) * 1000) timeout = secondsTillRequestEnd + 60, step = 5)
test "validator uses historical state to mark missing proofs", NodeConfigs( test "validator uses historical state to mark missing proofs", NodeConfigs(
# Uncomment to start Hardhat automatically, typically so logs can be inspected locally # Uncomment to start Hardhat automatically, typically so logs can be inspected locally
@ -101,7 +143,7 @@ marketplacesuite "Validation":
clients: clients:
CodexConfigs.init(nodes=1) CodexConfigs.init(nodes=1)
.withEthProvider("http://localhost:8545") .withEthProvider(providerUrl)
# .debug() # uncomment to enable console log output # .debug() # uncomment to enable console log output
.withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
.withLogTopics("purchases", "onchain") .withLogTopics("purchases", "onchain")
@ -109,8 +151,8 @@ marketplacesuite "Validation":
providers: providers:
CodexConfigs.init(nodes=1) CodexConfigs.init(nodes=1)
.withEthProvider(providerUrl)
.withSimulateProofFailures(idx=0, failEveryNProofs=1) .withSimulateProofFailures(idx=0, failEveryNProofs=1)
.withEthProvider("http://localhost:8545")
# .debug() # uncomment to enable console log output # .debug() # uncomment to enable console log output
# .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log # .withLogFile() # uncomment to output log file to tests/integration/logs/<start_datetime> <suite_name>/<test_name>/<node_role>_<node_idx>.log
# .withLogTopics("sales", "onchain") # .withLogTopics("sales", "onchain")
@ -120,6 +162,11 @@ marketplacesuite "Validation":
let expiry = 5.periods let expiry = 5.periods
let duration = expiry + 10.periods let duration = expiry + 10.periods
echo fmt"{providerUrl = }"
# for a good start
discard await ethProvider.send("evm_mine")
var currentTime = await ethProvider.currentTime() var currentTime = await ethProvider.currentTime()
let requestEndTime = currentTime.truncate(uint64) + duration let requestEndTime = currentTime.truncate(uint64) + duration
@ -143,14 +190,27 @@ marketplacesuite "Validation":
debug "validation suite", purchaseId = purchaseId.toHex, requestId = requestId debug "validation suite", purchaseId = purchaseId.toHex, requestId = requestId
check eventually(client0.purchaseStateIs(purchaseId, "started"), echo fmt"expiry = {(expiry + 60).int.seconds}"
timeout = expiry.int * 1000)
check eventuallyS(client0.purchaseStateIs(purchaseId, "started"),
timeout = (expiry + 60).int, step = 5)
# if purchase state is not "started", it does not make sense to continue
without purchaseState =? client0.getPurchase(purchaseId).?state:
fail()
debug "validation suite", purchaseState = purchaseState
echo fmt"{purchaseState = }"
if purchaseState != "started":
fail()
# just to make sure we have a mined block that separates us # just to make sure we have a mined block that separates us
# from the block containing the last SlotFilled event # from the block containing the last SlotFilled event
discard await ethProvider.send("evm_mine") discard await ethProvider.send("evm_mine")
var validators = CodexConfigs.init(nodes=2) var validators = CodexConfigs.init(nodes=2)
.withEthProvider(providerUrl)
.withValidationGroups(groups = 2) .withValidationGroups(groups = 2)
.withValidationGroupIndex(idx = 0, groupIndex = 0) .withValidationGroupIndex(idx = 0, groupIndex = 0)
.withValidationGroupIndex(idx = 1, groupIndex = 1) .withValidationGroupIndex(idx = 1, groupIndex = 1)
@ -178,5 +238,5 @@ marketplacesuite "Validation":
# NOTICE: We actually have to wait for the "errored" state, because # NOTICE: We actually have to wait for the "errored" state, because
# immediately after withdrawing the funds the purchasing state machine # immediately after withdrawing the funds the purchasing state machine
# transitions to the "errored" state. # transitions to the "errored" state.
check eventually(client0.purchaseStateIs(purchaseId, "errored"), check eventuallyS(client0.purchaseStateIs(purchaseId, "errored"),
timeout = (secondsTillRequestEnd + 60) * 1000) timeout = secondsTillRequestEnd + 60, step = 5)

View File

@ -1,12 +1,12 @@
import ./integration/testcli # import ./integration/testcli
import ./integration/testrestapi # import ./integration/testrestapi
import ./integration/testupdownload # import ./integration/testupdownload
import ./integration/testsales # import ./integration/testsales
import ./integration/testpurchasing # import ./integration/testpurchasing
import ./integration/testblockexpiration # import ./integration/testblockexpiration
import ./integration/testmarketplace # import ./integration/testmarketplace
import ./integration/testproofs # import ./integration/testproofs
import ./integration/testvalidator import ./integration/testvalidator
import ./integration/testecbug # import ./integration/testecbug
{.warning[UnusedImport]:off.} {.warning[UnusedImport]:off.}