diff --git a/itest/litd_node.go b/itest/litd_node.go index 36c12cc2..6c3f3728 100644 --- a/itest/litd_node.go +++ b/itest/litd_node.go @@ -1428,7 +1428,20 @@ func (hn *HarnessNode) Stop() error { select { case <-hn.processExit: case <-time.After(lntest.DefaultTimeout * 2): - return fmt.Errorf("process did not exit") + if hn.cmd != nil && hn.cmd.Process != nil { + if err := hn.cmd.Process.Kill(); err != nil && + !errors.Is(err, os.ErrProcessDone) { + + return fmt.Errorf("process did not exit and "+ + "could not be killed: %w", err) + } + } + + select { + case <-hn.processExit: + case <-time.After(lntest.DefaultTimeout): + return fmt.Errorf("process did not exit") + } } close(hn.quit) diff --git a/itest/network_harness.go b/itest/network_harness.go index 7be3d5a6..903873d3 100644 --- a/itest/network_harness.go +++ b/itest/network_harness.go @@ -73,6 +73,10 @@ type NetworkHarness struct { // to main process. lndErrorChan chan error + // lndErrorChanClosed is set to true once lndErrorChan has been closed, + // guarded by mtx to prevent double-close. + lndErrorChanClosed bool + mtx sync.Mutex } @@ -131,6 +135,12 @@ func (n *NetworkHarness) SetUp(t *testing.T, testCase string, lndArgs []string, grpclog.SetLoggerV2(fakeLogger) n.currentTestCase = testCase + t.Cleanup(func() { + tearDownErr := n.TearDown() + n.Stop() + require.NoError(t, tearDownErr) + }) + // Start our mock Loop/Pool server first. mockServerAddr := fmt.Sprintf( node.ListenerFormat, port.NextAvailablePort(), @@ -257,11 +267,6 @@ out: } } - t.Cleanup(func() { - require.NoError(t, n.TearDown()) - n.Stop() - }) - n.EnsureConnected(t, n.Alice, n.Bob) logLine := "STARTING ============ %v ============\n" @@ -274,20 +279,36 @@ out: // TearDown tears down all active nodes within the test lightning network. func (n *NetworkHarness) TearDown() error { + var tearDownErr error + for _, node := range n.activeNodes { if err := n.ShutdownNode(node); err != nil { - return err + if tearDownErr == nil { + tearDownErr = err + } } } - return nil + return tearDownErr } // Stop stops the test harness. func (n *NetworkHarness) Stop() { - close(n.lndErrorChan) + if n.server != nil { + n.server.Stop() + } - n.autopilotServer.Stop() + if n.autopilotServer != nil { + n.autopilotServer.Stop() + } + + n.mtx.Lock() + defer n.mtx.Unlock() + + if !n.lndErrorChanClosed { + close(n.lndErrorChan) + n.lndErrorChanClosed = true + } } func (n *NetworkHarness) litArgs() []string { diff --git a/itest/server_harness.go b/itest/server_harness.go index 0634fdd2..2a205da4 100644 --- a/itest/server_harness.go +++ b/itest/server_harness.go @@ -49,7 +49,9 @@ func NewServerHarness(serverHost string) *ServerHarness { // Stop stops the mock Loop/Pool server. func (s *ServerHarness) Stop() { - s.mockServer.Stop() + if s.mockServer != nil { + s.mockServer.Stop() + } s.wg.Wait() }