stop hardhat and show logs

# Conflicts:
#	tests/integration/hardhatprocess.nim
This commit is contained in:
Eric 2025-01-14 14:56:30 +11:00
parent 95021aaa71
commit 05c002c973
No known key found for this signature in database
2 changed files with 97 additions and 38 deletions

View File

@ -24,6 +24,12 @@ logScope:
type HardhatProcess* = ref object of NodeProcess type HardhatProcess* = ref object of NodeProcess
logFile: ?IoHandle logFile: ?IoHandle
type
OnOutputLineCaptured = proc(line: string) {.raises: [].}
HardhatProcess* = ref object of NodeProcess
logFile: ?IoHandle
onOutputLine: OnOutputLineCaptured
method workingDir(node: HardhatProcess): string = method workingDir(node: HardhatProcess): string =
return currentSourcePath() / ".." / ".." / ".." / "vendor" / "codex-contracts-eth" return currentSourcePath() / ".." / ".." / ".." / "vendor" / "codex-contracts-eth"
@ -111,6 +117,9 @@ method onOutputLineCaptured(node: HardhatProcess, line: string) =
logScope: logScope:
nodeName = node.name nodeName = node.name
if not node.onOutputLine.isNil:
node.onOutputLine(line)
without logFile =? node.logFile: without logFile =? node.logFile:
return return

View File

@ -49,7 +49,7 @@ type
testId: string # when used in datadir path, prevents data dir clashes testId: string # when used in datadir path, prevents data dir clashes
status: IntegrationTestStatus status: IntegrationTestStatus
TestManagerError = object of CatchableError TestManagerError* = object of CatchableError
Border {.pure.} = enum Border {.pure.} = enum
Left, Right Left, Right
@ -120,7 +120,8 @@ template styledEcho*(args: varargs[untyped]) =
try: try:
styledEcho args styledEcho args
except CatchableError as parent: except CatchableError as parent:
raiseTestManagerError "failed to print to terminal, error: " & parent.msg, parent # no need to re-raise this, as it'll eventually have to be logged only
error "failed to print to terminal", error = parent.msg
proc duration(manager: TestManager): Duration = proc duration(manager: TestManager): Duration =
manager.timeEnd - manager.timeStart manager.timeEnd - manager.timeStart
@ -130,11 +131,17 @@ proc duration(test: IntegrationTest): Duration =
proc startHardhat( proc startHardhat(
manager: TestManager, manager: TestManager,
config: IntegrationTestConfig): Future[int] {.async: (raises: [CancelledError, TestManagerError]).} = config: IntegrationTestConfig): Future[Hardhat] {.async: (raises: [CancelledError, TestManagerError]).} =
var args: seq[string] = @[] var args: seq[string] = @[]
var port: int var port: int
let hardhat = Hardhat.new()
manager.hardhats.add hardhat
proc onOutputLineCaptured(line: string) {.raises: [].} =
hardhat.output.add line
withLock(manager.hardhatPortLock): withLock(manager.hardhatPortLock):
port = await nextFreePort(manager.lastHardhatPort + 10) port = await nextFreePort(manager.lastHardhatPort + 10)
manager.lastHardhatPort = port manager.lastHardhatPort = port
@ -146,11 +153,13 @@ proc startHardhat(
try: try:
let node = await HardhatProcess.startNode( let node = await HardhatProcess.startNode(
args, args,
manager.debugHardhat, false,
"hardhat for '" & config.name & "'") "hardhat for '" & config.name & "'",
onOutputLineCaptured)
await node.waitUntilStarted() await node.waitUntilStarted()
manager.hardhats.add node hardhat.process = node
return port hardhat.port = port
return hardhat
except CancelledError as e: except CancelledError as e:
raise e raise e
except CatchableError as e: except CatchableError as e:
@ -158,7 +167,7 @@ proc startHardhat(
proc printResult( proc printResult(
test: IntegrationTest, test: IntegrationTest,
colour: ForegroundColor) {.raises: [TestManagerError].} = colour: ForegroundColor) =
styledEcho styleBright, colour, &"[{toUpper $test.status}] ", styledEcho styleBright, colour, &"[{toUpper $test.status}] ",
resetStyle, test.config.name, resetStyle, test.config.name,
@ -167,18 +176,21 @@ proc printResult(
proc printOutputMarker( proc printOutputMarker(
test: IntegrationTest, test: IntegrationTest,
position: MarkerPosition, position: MarkerPosition,
msg: string) {.raises: [TestManagerError].} = msg: string) =
let newLine = if position == MarkerPosition.Start: "\n" if position == MarkerPosition.Start:
else: "" echo ""
styledEcho styleBright, bgWhite, fgBlack, styledEcho styleBright, bgWhite, fgBlack,
&"{newLine}----- {toUpper $position} {test.config.name} {msg} -----" &"----- {toUpper $position} {test.config.name} {msg} -----"
if position == MarkerPosition.Finish:
echo ""
proc printResult( proc printResult(
test: IntegrationTest, test: IntegrationTest,
processOutput = false, processOutput = false,
testHarnessErrors = false) {.raises: [TestManagerError].} = testHarnessErrors = false) =
if test.status == IntegrationTestStatus.Error and if test.status == IntegrationTestStatus.Error and
error =? test.output.errorOption: error =? test.output.errorOption:
@ -218,16 +230,27 @@ proc printResult(
"codex node output (stdout)") "codex node output (stdout)")
test.printResult(fgGreen) test.printResult(fgGreen)
proc printSummary(test: IntegrationTest) {.raises: [TestManagerError].} = proc printSummary(test: IntegrationTest) =
test.printResult(processOutput = false, testHarnessErrors = false) test.printResult(processOutput = false, testHarnessErrors = false)
proc printStart(test: IntegrationTest) {.raises: [TestManagerError].} = proc printStart(test: IntegrationTest) =
styledEcho styleBright, fgMagenta, &"[Integration test started] ", resetStyle, test.config.name styledEcho styleBright, fgMagenta, &"[Integration test started] ", resetStyle, test.config.name
proc stopHardhat(
manager: TestManager,
test: IntegrationTest,
hardhat: Hardhat) {.async: (raises: [CancelledError, TestManagerError]).} =
try:
await hardhat.process.stop()
except CatchableError as parent:
raiseTestManagerError("failed to stop hardhat node", parent)
proc buildCommand( proc buildCommand(
manager: TestManager, manager: TestManager,
test: IntegrationTest, test: IntegrationTest,
hardhatPort: int): Future[string] {.async: (raises:[CancelledError, TestManagerError]).} = hardhatPort: ?int): Future[string] {.async: (raises:[CancelledError, TestManagerError]).} =
var apiPort, discPort: int var apiPort, discPort: int
withLock(manager.codexPortLock): withLock(manager.codexPortLock):
@ -246,6 +269,13 @@ proc buildCommand(
"-d:chronicles_default_output_device=stdout " & "-d:chronicles_default_output_device=stdout " &
"-d:chronicles_sinks=textlines" "-d:chronicles_sinks=textlines"
let strHardhatPort =
if not test.config.startHardhat: ""
else:
without port =? hardhatPort:
raiseTestManagerError "hardhatPort required when 'config.startHardhat' is true"
"-d:HardhatPort=" & $port
var testFile: string var testFile: string
try: try:
testFile = absolutePath( testFile = absolutePath(
@ -260,9 +290,7 @@ proc buildCommand(
return "nim c " & return "nim c " &
&"-d:CodexApiPort={apiPort} " & &"-d:CodexApiPort={apiPort} " &
&"-d:CodexDiscPort={discPort} " & &"-d:CodexDiscPort={discPort} " &
(if test.config.startHardhat: &"{strHardhatPort} " &
&"-d:HardhatPort={hardhatPort} "
else: "") &
&"-d:TestId={test.testId} " & &"-d:TestId={test.testId} " &
&"{logging} " & &"{logging} " &
"--verbosity:0 " & "--verbosity:0 " &
@ -281,7 +309,7 @@ proc buildCommand(
proc runTest( proc runTest(
manager: TestManager, manager: TestManager,
config: IntegrationTestConfig) {.async: (raises: [CancelledError, TestManagerError]).} = config: IntegrationTestConfig) {.async: (raises: [CancelledError]).} =
logScope: logScope:
config config
@ -293,34 +321,37 @@ proc runTest(
testId: $ uint16.example testId: $ uint16.example
) )
var hardhatPort = 0 test.timeStart = Moment.now()
if config.startHardhat: manager.tests.add test
try:
hardhatPort = await manager.startHardhat(config)
except TestManagerError as e:
e.msg = "Failed to start hardhat: " & e.msg
test.timeEnd = Moment.now()
test.status = IntegrationTestStatus.Error
test.output = CommandExResponse.failure(e)
let command = await manager.buildCommand(test, hardhatPort) var hardhat: Hardhat
var hardhatPort = int.none
var command: string
try:
if config.startHardhat:
hardhat = await manager.startHardhat(config)
hardhatPort = hardhat.port.some
command = await manager.buildCommand(test, hardhatPort)
except TestManagerError as e:
error "Failed to start hardhat and build command", error = e.msg
test.timeEnd = Moment.now()
test.status = IntegrationTestStatus.Error
test.output = CommandExResponse.failure(e)
test.printResult(processOutput = manager.debugCodexNodes,
testHarnessErrors = manager.debugTestHarness)
return
trace "Starting parallel integration test", command trace "Starting parallel integration test", command
test.printStart() test.printStart()
test.timeStart = Moment.now()
test.process = execCommandEx( test.process = execCommandEx(
command = command, command = command,
timeout = manager.testTimeout timeout = manager.testTimeout
) )
manager.tests.add test
try: try:
let output = await test.process # waits on waitForExit let output = await test.process # waits on waitForExit
test.output = success(output) test.output = success(output)
test.timeEnd = Moment.now()
info "Test completed", name = config.name, duration = test.timeEnd - test.timeStart
if output.status != 0: if output.status != 0:
test.status = IntegrationTestStatus.Failed test.status = IntegrationTestStatus.Failed
@ -349,8 +380,27 @@ proc runTest(
test.printResult(processOutput = manager.debugCodexNodes, test.printResult(processOutput = manager.debugCodexNodes,
testHarnessErrors = manager.debugTestHarness) testHarnessErrors = manager.debugTestHarness)
proc runTests(manager: TestManager) {.async: (raises: [CancelledError, TestManagerError]).} = if config.startHardhat and not hardhat.isNil:
var testFutures: seq[Future[void].Raising([CancelledError, TestManagerError])] try:
trace "Stopping hardhat", name = config.name
await manager.stopHardhat(test, hardhat)
except TestManagerError as e:
warn "Failed to stop hardhat node, continuing",
error = e.msg, test = test.config.name
if manager.debugHardhat:
test.printOutputMarker(MarkerPosition.Start, "Hardhat stdout")
for line in hardhat.output:
echo line
test.printOutputMarker(MarkerPosition.Finish, "Hardhat stdout")
manager.hardhats.keepItIf( it != hardhat )
test.timeEnd = Moment.now()
info "Test completed", name = config.name, duration = test.timeEnd - test.timeStart
proc runTests(manager: TestManager) {.async: (raises: [CancelledError]).} =
var testFutures: seq[Future[void].Raising([CancelledError])]
manager.timeStart = Moment.now() manager.timeStart = Moment.now()
@ -414,6 +464,6 @@ proc stop*(manager: TestManager) {.async: (raises: [CancelledError]).} =
for hardhat in manager.hardhats: for hardhat in manager.hardhats:
try: try:
await hardhat.stop() await hardhat.process.stop()
except CatchableError as e: except CatchableError as e:
trace "failed to stop hardhat node", error = e.msg trace "failed to stop hardhat node", error = e.msg