mirror of
https://github.com/logos-storage/logos-storage-nim.git
synced 2026-01-10 17:33:09 +00:00
- test harness chronicles logs to log file - test process stdout and stderr to log file for each integration test file Note: does not work when DEBUG=1 is not present in make command
146 lines
5.3 KiB
Nim
146 lines
5.3 KiB
Nim
import std/terminal
|
||
import pkg/chronos
|
||
import pkg/codex/logutils
|
||
import ./integration/testmanager
|
||
|
||
{.warning[UnusedImport]: off.}
|
||
|
||
const TestConfigs =
|
||
@[
|
||
IntegrationTestConfig.init("./integration/testcli", startHardhat = true),
|
||
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),
|
||
IntegrationTestConfig.init(
|
||
"./integration/testrestapivalidation", startHardhat = true
|
||
),
|
||
]
|
||
|
||
# Echoes stderr if there's a test failure (eg test failed, compilation error)
|
||
# or error (eg test manager error)
|
||
const DebugTestHarness {.booldefine.} = false
|
||
# 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
|
||
const DebugCodexNodes {.booldefine.} = false
|
||
# 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
|
||
# Timeout duration (in minutes) for EACH integration test file.
|
||
const TestTimeout {.intdefine.} = 60
|
||
|
||
const EnableParallelTests {.booldefine.} = true
|
||
|
||
proc setupLogging(logFile: string, debugTestHarness: bool) =
|
||
when defaultChroniclesStream.outputs.type.arity != 3:
|
||
raiseAssert "Logging configuration options not enabled in the current build"
|
||
else:
|
||
proc writeAndFlush(f: File, msg: LogOutputStr) =
|
||
try:
|
||
f.write(msg)
|
||
f.flushFile()
|
||
except IOError as err:
|
||
logLoggingFailure(cstring(msg), err)
|
||
|
||
proc noOutput(logLevel: LogLevel, msg: LogOutputStr) =
|
||
discard
|
||
|
||
proc stdoutFlush(logLevel: LogLevel, msg: LogOutputStr) =
|
||
writeAndFlush(stdout, msg)
|
||
|
||
proc fileFlush(logLevel: LogLevel, msg: LogOutputStr) =
|
||
try:
|
||
logFile.appendFile(stripAnsi(msg))
|
||
except IOError as error:
|
||
fatal "Failed to write to log file", error = error.msg # error = error.ioErrorMsg
|
||
raiseAssert "Could not write to test manager log file: " & error.msg
|
||
|
||
defaultChroniclesStream.outputs[0].writer = stdoutFlush
|
||
defaultChroniclesStream.outputs[1].writer = noOutput
|
||
if debugTestHarness:
|
||
defaultChroniclesStream.outputs[2].writer = fileFlush
|
||
else:
|
||
defaultChroniclesStream.outputs[2].writer = noOutput
|
||
|
||
proc run(): Future[bool] {.async: (raises: []).} =
|
||
let startTime = now().format("yyyy-MM-dd'_'HH:mm:ss")
|
||
let logsDir =
|
||
currentSourcePath.parentDir() / "integration" / "logs" /
|
||
sanitize(startTime & "__IntegrationTests")
|
||
try:
|
||
if DebugTestHarness or DebugHardhat or DebugCodexNodes:
|
||
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"
|
||
#!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
|
||
|
||
setupLogging(TestManager.logFile(logsDir), DebugTestHarness)
|
||
|
||
let manager = TestManager.new(
|
||
configs = TestConfigs,
|
||
logsDir,
|
||
DebugTestHarness,
|
||
DebugHardhat,
|
||
DebugCodexNodes,
|
||
ShowContinuousStatusUpdates,
|
||
TestTimeout.minutes,
|
||
)
|
||
try:
|
||
trace "starting test manager"
|
||
await manager.start()
|
||
except TestManagerError as e:
|
||
error "Failed to run test manager", error = e.msg
|
||
return false
|
||
except CancelledError:
|
||
return false
|
||
finally:
|
||
trace "Stopping test manager"
|
||
await manager.stop()
|
||
trace "Test manager stopped"
|
||
|
||
without wasSuccessful =? manager.allTestsPassed, error:
|
||
raiseAssert "Failed to get test status: " & error.msg
|
||
|
||
return wasSuccessful
|
||
|
||
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
|