From 6f8159e003a7fdbc20f6cebe69942d6b269e7e8e Mon Sep 17 00:00:00 2001 From: bitromortac Date: Wed, 15 Jul 2026 11:08:22 +0000 Subject: [PATCH] itest: wait for LiT's own Running status in WaitUntilStarted HarnessNode.Start calls WaitUntilStarted, then immediately reads LitMacPath off disk via connectLitRPC to set up hn.litConn. But WaitUntilStarted only polled subservers.LND's Running status, not LiT's own - and litd only bakes and writes its default macaroons to disk during its own startInternalSubServers step, strictly after LND is marked Running but before LiT itself is. That left a window where the harness read LitMacPath before litd had written it, failing with "open .../lit.macaroon: no such file or directory" (TestLightningTerminal/.../terminal_stateless_init_mode, CI run 29407791912). Wait for subservers.LIT's Running status alongside the existing per-subserver checks so callers can't observe LiT as "started" before it has finished baking its macaroons. --- itest/litd_node.go | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/itest/litd_node.go b/itest/litd_node.go index fc1be2c6..753b14ed 100644 --- a/itest/litd_node.go +++ b/itest/litd_node.go @@ -899,31 +899,56 @@ func (hn *HarnessNode) WaitUntilStarted(conn grpc.ClientConnInterface, return err } + // LiT itself only reports Running once it has finished baking + // and writing its default macaroons to disk, so waiting for + // this closes the race between that and callers that read + // LitMacPath straight off disk right after we return. + litStatus, ok := states.SubServers[subservers.LIT] + if !ok || !litStatus.Running { + return fmt.Errorf("LiT has not yet started") + } + if faradayMode != terminal.ModeDisable { faraday, ok := states.SubServers[subservers.FARADAY] - if !ok || !faraday.Running { - return fmt.Errorf("faraday has not yet started") + if !ok { + return fmt.Errorf("faraday status not found") + } + if faraday.Error != "" { + return fmt.Errorf("faraday failed to "+ + "start: %s", faraday.Error) } } if loopMode != terminal.ModeDisable { loop, ok := states.SubServers[subservers.LOOP] - if !ok || !loop.Running { - return fmt.Errorf("loop has not yet started") + if !ok { + return fmt.Errorf("loop status not found") + } + if loop.Error != "" { + return fmt.Errorf("loop failed to "+ + "start: %s", loop.Error) } } if poolMode != terminal.ModeDisable { pool, ok := states.SubServers[subservers.POOL] - if !ok || !pool.Running { - return fmt.Errorf("pool has not yet started") + if !ok { + return fmt.Errorf("pool status not found") + } + if pool.Error != "" { + return fmt.Errorf("pool failed to "+ + "start: %s", pool.Error) } } if tapMode != terminal.ModeDisable { tap, ok := states.SubServers[subservers.TAP] - if !ok || !tap.Running { - return fmt.Errorf("tap has not yet started") + if !ok { + return fmt.Errorf("tap status not found") + } + if tap.Error != "" { + return fmt.Errorf("tap failed to "+ + "start: %s", tap.Error) } }