diff --git a/tests/integration/codexprocess.nim b/tests/integration/codexprocess.nim index ce633434..4e707549 100644 --- a/tests/integration/codexprocess.nim +++ b/tests/integration/codexprocess.nim @@ -5,6 +5,7 @@ import pkg/chronicles import pkg/chronos/asyncproc import pkg/ethers import pkg/libp2p +import pkg/stew/io2 import std/os import std/strutils import codex/conf @@ -40,6 +41,16 @@ method outputLineEndings(node: CodexProcess): string = method onOutputLineCaptured(node: CodexProcess, line: string) = discard +method logFileContains*(node: CodexProcess, text: string): bool = + let config = CodexConf.load(cmdLine = node.arguments, quitOnFailure = false) + without logFile =? config.logFile.?string: + raiseAssert "codex node does have a --log-file option set (use .withLogFile())" + + without logContents =? logFile.readAllChars: + raiseAssert "failed to open codex log file, aborting" + + return logContents.contains(text) + proc dataDir(node: CodexProcess): string = let config = CodexConf.load(cmdLine = node.arguments, quitOnFailure = false) return config.dataDir.string @@ -73,4 +84,4 @@ method stop*(node: CodexProcess) {.async.} = node.client = none CodexClient method removeDataDir*(node: CodexProcess) = - removeDir(node.dataDir) + os.removeDir(node.dataDir) diff --git a/tests/integration/hardhatprocess.nim b/tests/integration/hardhatprocess.nim index 0e88aa78..84cf4132 100644 --- a/tests/integration/hardhatprocess.nim +++ b/tests/integration/hardhatprocess.nim @@ -40,6 +40,25 @@ method processOptions(node: HardhatProcess): set[AsyncProcessOption] = method outputLineEndings(node: HardhatProcess): string = return "\n" +method logFileContains*(hardhat: HardhatProcess, text: string): bool = + without fileHandle =? hardhat.logFile: + raiseAssert "failed to open hardhat log file, aborting" + + without fileSize =? fileHandle.getFileSize: + raiseAssert "failed to get current hardhat log file size, aborting" + + if checkFileSize(fileSize).isErr: + raiseAssert "file size too big for nim indexing" + + var data = "" + data.setLen(fileSize) + + without bytesRead =? readFile(fileHandle, + data.toOpenArray(0, len(data) - 1)): + raiseAssert "unable to read hardhat log, aborting" + + return data.contains(text) + proc openLogFile(node: HardhatProcess, logFilePath: string): IoHandle = let logFileHandle = openFile( logFilePath, diff --git a/tests/integration/multinodes.nim b/tests/integration/multinodes.nim index 1ad16a38..97277beb 100644 --- a/tests/integration/multinodes.nim +++ b/tests/integration/multinodes.nim @@ -222,6 +222,26 @@ template multinodesuite*(name: string, body: untyped) = return await newCodexProcess(validatorIdx, config, Role.Validator) + + proc searchLogs(role: Role, text: string): seq[bool] = + var hits: seq[bool] = @[] + if role == Role.Hardhat: + return @[hardhat().logFileContains(text)] + elif role == Role.Client: + for client in clients(): + hits.add client.logFileContains(text) + else: + for provider in providers(): + hits.add provider.logFileContains(text) + + return hits + + proc logsContain(role: Role, text: string): bool = + return searchLogs(role, text).allIt(it) + + proc logsDoNotContain(role: Role, text: string): bool = + return searchLogs(role, text).allIt(not it) + proc teardownImpl() {.async.} = for nodes in @[validators(), clients(), providers()]: for node in nodes: diff --git a/tests/integration/nodeconfig.nim b/tests/integration/nodeconfig.nim deleted file mode 100644 index d6adb80f..00000000 --- a/tests/integration/nodeconfig.nim +++ /dev/null @@ -1,34 +0,0 @@ -import pkg/chronicles -import pkg/questionable - -export chronicles - -type - NodeConfig* = ref object of RootObj - logFile*: bool - logLevel*: ?LogLevel - debugEnabled*: bool - -proc debug*[T: NodeConfig](config: T, enabled = true): T = - ## output log in stdout - var startConfig = config - startConfig.debugEnabled = enabled - return startConfig - -proc withLogFile*[T: NodeConfig]( - config: T, - logToFile: bool = true -): T = - - var startConfig = config - startConfig.logFile = logToFile - return startConfig - -proc withLogLevel*[T: NodeConfig]( - config: NodeConfig, - level: LogLevel -): T = - - var startConfig = config - startConfig.logLevel = some level - return startConfig diff --git a/tests/integration/nodeprocess.nim b/tests/integration/nodeprocess.nim index 61947c20..d8367c14 100644 --- a/tests/integration/nodeprocess.nim +++ b/tests/integration/nodeprocess.nim @@ -44,6 +44,9 @@ method outputLineEndings(node: NodeProcess): string {.base.} = method onOutputLineCaptured(node: NodeProcess, line: string) {.base.} = raiseAssert "not implemented" +method logFileContains*(hardhat: NodeProcess): bool {.base.} = + raiseAssert "not implemented" + method start*(node: NodeProcess) {.base, async.} = logScope: nodeName = node.name diff --git a/tests/integration/testslotreservations.nim b/tests/integration/testslotreservations.nim new file mode 100644 index 00000000..9fb54f2f --- /dev/null +++ b/tests/integration/testslotreservations.nim @@ -0,0 +1,79 @@ +import pkg/stew/byteutils +import pkg/codex/units +import ../examples +import ../contracts/time +import ../contracts/deployment +import ./marketplacesuite +import ./nodeconfigs +import ./hardhatconfig + +marketplacesuite "Slot reservations": + + test "nonce does not go too high when reserving slots", + NodeConfigs( + # Uncomment to start Hardhat automatically, typically so logs can be inspected locally + hardhat: HardhatConfig() + .withLogFile() + .some, + + clients: + CodexConfigs.init(nodes=1) + # .debug() # uncomment to enable console log output.debug() + .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log + .withLogTopics("node", "erasure", "marketplace") + .some, + + providers: + CodexConfigs.init(nodes=6) + # .debug() # uncomment to enable console log output + .withLogFile() # uncomment to output log file to tests/integration/logs/ //_.log + .withLogTopics("node", "marketplace", "sales", "reservations", "proving", "ethers", "statemachine") + .some, + ): + let reward = 400.u256 + let duration = 50.periods + let collateral = 200.u256 + let expiry = 30.periods + let data = await RandomChunker.example(blocks=8) + let client = clients()[0] + let clientApi = client.client + + # provider makes storage available + for i in 0..