refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
import std/os
|
|
|
|
|
|
import std/strformat
|
2025-01-16 11:52:02 +11:00
|
|
|
|
import std/terminal
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
from std/times import format, now
|
|
|
|
|
|
import std/terminal
|
|
|
|
|
|
import std/typetraits
|
2024-12-20 16:23:40 +11:00
|
|
|
|
import pkg/chronos
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
import pkg/codex/conf
|
2024-12-20 16:23:40 +11:00
|
|
|
|
import pkg/codex/logutils
|
|
|
|
|
|
import ./integration/testmanager
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
import ./integration/utils
|
2022-05-18 14:31:45 +02:00
|
|
|
|
|
2023-03-09 12:23:45 +01:00
|
|
|
|
{.warning[UnusedImport]: off.}
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
{.push raises: [].}
|
2024-12-20 16:23:40 +11:00
|
|
|
|
|
|
|
|
|
|
const TestConfigs =
|
|
|
|
|
|
@[
|
2025-01-13 14:39:07 +11:00
|
|
|
|
IntegrationTestConfig.init("./integration/testcli", startHardhat = true),
|
2025-01-16 11:52:02 +11:00
|
|
|
|
IntegrationTestConfig.init("./integration/testrestapi", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testupdownload", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testsales", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testpurchasing", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testblockexpiration", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testmarketplace", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testproofs", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testvalidator", startHardhat = true),
|
|
|
|
|
|
IntegrationTestConfig.init("./integration/testecbug", startHardhat = true),
|
2025-01-13 14:39:07 +11:00
|
|
|
|
IntegrationTestConfig.init(
|
2025-01-16 11:52:02 +11:00
|
|
|
|
"./integration/testrestapivalidation", startHardhat = true
|
|
|
|
|
|
),
|
2024-12-20 16:23:40 +11:00
|
|
|
|
]
|
|
|
|
|
|
|
2025-01-22 17:55:31 +11:00
|
|
|
|
# Echoes stdout from Hardhat process
|
|
|
|
|
|
const DebugHardhat {.booldefine.} = false
|
|
|
|
|
|
# Echoes stdout from the integration test file process. Codex process logs can
|
|
|
|
|
|
# also be output if a test uses a multinodesuite, requires CodexConfig.debug
|
|
|
|
|
|
# to be enabled
|
2025-02-05 18:31:40 +11:00
|
|
|
|
const DebugCodexNodes {.booldefine.} = false
|
2025-01-22 17:55:31 +11:00
|
|
|
|
# Shows test status updates at time intervals. Useful for running locally with
|
|
|
|
|
|
# active terminal interaction. Set to false for unattended runs, eg CI.
|
|
|
|
|
|
const ShowContinuousStatusUpdates {.booldefine.} = false
|
2025-03-05 15:16:07 +11:00
|
|
|
|
# Timeout duration (in minutes) for EACH integration test file.
|
2025-01-22 17:55:31 +11:00
|
|
|
|
const TestTimeout {.intdefine.} = 60
|
2025-01-16 11:52:02 +11:00
|
|
|
|
|
2025-02-03 19:04:24 +11:00
|
|
|
|
const EnableParallelTests {.booldefine.} = true
|
|
|
|
|
|
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
proc setupLogging(logFile: string) =
|
|
|
|
|
|
try:
|
|
|
|
|
|
let success = defaultChroniclesStream.outputs[0].open(logFile, fmAppend)
|
|
|
|
|
|
doAssert success, "Failed to open log file: " & logFile
|
|
|
|
|
|
except IOError, OSError:
|
|
|
|
|
|
let error = getCurrentException()
|
|
|
|
|
|
fatal "Failed to open log file", error = error.msg
|
|
|
|
|
|
raiseAssert "Could not open test manager log file: " & error.msg
|
2025-03-05 15:16:07 +11:00
|
|
|
|
|
2025-02-28 22:42:01 +11:00
|
|
|
|
proc run(): Future[bool] {.async: (raises: []).} =
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
let startTime = now().format("yyyy-MM-dd'_'HH-mm-ss")
|
2025-03-05 15:16:07 +11:00
|
|
|
|
let logsDir =
|
|
|
|
|
|
currentSourcePath.parentDir() / "integration" / "logs" /
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
sanitize(startTime & "-IntegrationTests")
|
2025-03-05 15:16:07 +11:00
|
|
|
|
try:
|
2025-03-06 17:40:48 +11:00
|
|
|
|
createDir(logsDir)
|
|
|
|
|
|
#!fmt: off
|
|
|
|
|
|
styledEcho bgWhite, fgBlack, styleBright,
|
|
|
|
|
|
"\n\n ",
|
|
|
|
|
|
styleUnderscore,
|
|
|
|
|
|
"ℹ️ LOGS AVAILABLE ℹ️\n\n",
|
|
|
|
|
|
resetStyle, bgWhite, fgBlack, styleBright,
|
|
|
|
|
|
""" Logs for this run will be available at:""",
|
|
|
|
|
|
resetStyle, bgWhite, fgBlack,
|
|
|
|
|
|
&"\n\n {logsDir}\n\n",
|
|
|
|
|
|
resetStyle, bgWhite, fgBlack, styleBright,
|
|
|
|
|
|
" NOTE: For CI runs, logs will be attached as artefacts\n"
|
2025-03-05 15:16:07 +11:00
|
|
|
|
#!fmt: on
|
|
|
|
|
|
except IOError as e:
|
|
|
|
|
|
raiseAssert "Failed to create log directory and echo log message: " & e.msg
|
|
|
|
|
|
except OSError as e:
|
|
|
|
|
|
raiseAssert "Failed to create log directory and echo log message: " & e.msg
|
|
|
|
|
|
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
setupLogging(TestManager.logFile(logsDir))
|
2025-03-05 15:16:07 +11:00
|
|
|
|
|
2024-12-20 16:23:40 +11:00
|
|
|
|
let manager = TestManager.new(
|
refactor: debug and logging
- Move test manager values to config object
- Increase codex port separation (between api and disc ports) in an attempt to prevent overlap across tests (ie Test1: api=8000(tcp), disc=9000(udp), and Test2: api=9000(tcp), disc=10000(udp))
- print stderr when exitcode == 1 if there's < 3 lines of stdout
- Logging:
- Always write test manager harness chronicles logs to file, ie testmanager.chronicles.log in the root of the `integration/logs/<run name>` dir
- Always write individual test stdout to file, ie `<test file name>.stdout.log` in the root of the `integration/logs/<run name>/<test file name>` dir
- On error, print stderr to screen and write stderr to file. Or on failure, if stdout is sufficiently short, write stderr to screen and file in `integration/logs/<run name>/<test file name>/<test file name>.stderr.log`
- When debugging, ie DebugCodexNodes == true
- Removes DebugTestHarness from controlling anything other than printing chronicles output from the testmanager to the terminal
- Now, if DebugCodexNodes is set to true:
- Codex node (chronicles) output for multinodesuite tests is logged to file, eg `integration/logs/<run name>/<test file name>/<test name>/<role>_<idx>.log`
- Codex chronicles output is logged to stdout, which also written to file (see above)
2025-03-06 15:49:08 +11:00
|
|
|
|
config = TestManagerConfig(
|
|
|
|
|
|
debugHardhat: DebugHardhat,
|
|
|
|
|
|
debugCodexNodes: DebugCodexNodes,
|
|
|
|
|
|
showContinuousStatusUpdates: ShowContinuousStatusUpdates,
|
|
|
|
|
|
logsDir: logsDir,
|
|
|
|
|
|
testTimeout: TestTimeout.minutes,
|
|
|
|
|
|
),
|
|
|
|
|
|
testConfigs = TestConfigs,
|
2024-12-20 16:23:40 +11:00
|
|
|
|
)
|
|
|
|
|
|
try:
|
|
|
|
|
|
trace "starting test manager"
|
|
|
|
|
|
await manager.start()
|
2025-02-28 22:42:01 +11:00
|
|
|
|
except TestManagerError as e:
|
|
|
|
|
|
error "Failed to run test manager", error = e.msg
|
|
|
|
|
|
return false
|
|
|
|
|
|
except CancelledError:
|
2025-03-04 13:11:38 +11:00
|
|
|
|
return false
|
2024-12-20 16:23:40 +11:00
|
|
|
|
finally:
|
2025-03-04 13:11:38 +11:00
|
|
|
|
trace "Stopping test manager"
|
|
|
|
|
|
await manager.stop()
|
|
|
|
|
|
trace "Test manager stopped"
|
2024-12-20 16:23:40 +11:00
|
|
|
|
|
2025-01-28 20:49:12 +11:00
|
|
|
|
without wasSuccessful =? manager.allTestsPassed, error:
|
2025-01-28 18:58:43 +11:00
|
|
|
|
raiseAssert "Failed to get test status: " & error.msg
|
|
|
|
|
|
|
2025-02-28 22:42:01 +11:00
|
|
|
|
return wasSuccessful
|
2025-01-28 18:58:43 +11:00
|
|
|
|
|
2025-03-04 13:11:38 +11:00
|
|
|
|
when isMainModule:
|
|
|
|
|
|
when EnableParallelTests:
|
|
|
|
|
|
let wasSuccessful = waitFor run()
|
|
|
|
|
|
if wasSuccessful:
|
|
|
|
|
|
quit(QuitSuccess)
|
|
|
|
|
|
else:
|
|
|
|
|
|
quit(QuitFailure) # indicate with a non-zero exit code that the tests failed
|
|
|
|
|
|
else:
|
|
|
|
|
|
# run tests serially
|
|
|
|
|
|
import ./integration/testcli
|
|
|
|
|
|
import ./integration/testrestapi
|
|
|
|
|
|
import ./integration/testupdownload
|
|
|
|
|
|
import ./integration/testsales
|
|
|
|
|
|
import ./integration/testpurchasing
|
|
|
|
|
|
import ./integration/testblockexpiration
|
|
|
|
|
|
import ./integration/testmarketplace
|
|
|
|
|
|
import ./integration/testproofs
|
|
|
|
|
|
import ./integration/testvalidator
|
|
|
|
|
|
import ./integration/testecbug
|