diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b018c083d..ec145f50e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -286,8 +286,9 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v2 + if: ${{ failure() }} with: - name: logs + name: logs-itest-${{ job.id }} path: lntest/itest/**/*.log retention-days: 5 @@ -325,8 +326,9 @@ jobs: - name: Upload Artifact uses: actions/upload-artifact@v2 + if: ${{ failure() }} with: - name: logs + name: logs-itest-windows path: lntest/itest/**/*.log retention-days: 5 diff --git a/docs/release-notes/release-notes-0.14.0.md b/docs/release-notes/release-notes-0.14.0.md index ca7c873c0..2ec002693 100644 --- a/docs/release-notes/release-notes-0.14.0.md +++ b/docs/release-notes/release-notes-0.14.0.md @@ -340,6 +340,9 @@ you. * [Replace reference to protobuf library with OSV](https://github.com/lightningnetwork/lnd/pull/5759) +* [Only upload itest logs on failure, fix more + flakes](https://github.com/lightningnetwork/lnd/pull/5833). + ## Database * [Ensure single writer for legacy diff --git a/lntest/itest/lnd_rest_api_test.go b/lntest/itest/lnd_rest_api_test.go index 33e5601a1..eac605800 100644 --- a/lntest/itest/lnd_rest_api_test.go +++ b/lntest/itest/lnd_rest_api_test.go @@ -451,11 +451,15 @@ func wsTestCaseBiDirectionalSubscription(ht *harnessTest, // We want to read messages over and over again. We just accept any // channels that are opened. + defer close(done) go func() { for { _, msg, err := conn.ReadMessage() if err != nil { - errChan <- err + select { + case errChan <- err: + case <-done: + } return } @@ -464,7 +468,11 @@ func wsTestCaseBiDirectionalSubscription(ht *harnessTest, // get rid of here. msgStr := string(msg) if !strings.Contains(msgStr, "\"result\":") { - errChan <- fmt.Errorf("invalid msg: %s", msgStr) + select { + case errChan <- fmt.Errorf("invalid msg: %s", + msgStr): + case <-done: + } return } msgStr = resultPattern.ReplaceAllString(msgStr, "${1}") @@ -474,7 +482,10 @@ func wsTestCaseBiDirectionalSubscription(ht *harnessTest, protoMsg := &lnrpc.ChannelAcceptRequest{} err = jsonpb.UnmarshalString(msgStr, protoMsg) if err != nil { - errChan <- err + select { + case errChan <- err: + case <-done: + } return } @@ -485,14 +496,20 @@ func wsTestCaseBiDirectionalSubscription(ht *harnessTest, } resMsg, err := jsonMarshaler.MarshalToString(res) if err != nil { - errChan <- err + select { + case errChan <- err: + case <-done: + } return } err = conn.WriteMessage( websocket.TextMessage, []byte(resMsg), ) if err != nil { - errChan <- err + select { + case errChan <- err: + case <-done: + } return } @@ -531,7 +548,6 @@ func wsTestCaseBiDirectionalSubscription(ht *harnessTest, ht.t.Fatalf("Timeout before message was received") } } - close(done) } func wsTestPingPongTimeout(ht *harnessTest, net *lntest.NetworkHarness) { diff --git a/lntest/itest/lnd_rpc_middleware_interceptor_test.go b/lntest/itest/lnd_rpc_middleware_interceptor_test.go index e2381a40d..54e0b8db6 100644 --- a/lntest/itest/lnd_rpc_middleware_interceptor_test.go +++ b/lntest/itest/lnd_rpc_middleware_interceptor_test.go @@ -403,7 +403,9 @@ func middlewareMandatoryTest(t *testing.T, node *lntest.HarnessNode, // test case. So we need to do the wait and client setup manually here. conn, err := node.ConnectRPC(true) require.NoError(t, err) - err = node.WaitUntilStarted(conn, defaultTimeout) + err = node.WaitUntilStateReached( + conn, defaultTimeout, lnrpc.WalletState_RPC_ACTIVE, + ) require.NoError(t, err) node.LightningClient = lnrpc.NewLightningClient(conn) diff --git a/lntest/node.go b/lntest/node.go index 2957e2c65..f164ad070 100644 --- a/lntest/node.go +++ b/lntest/node.go @@ -887,6 +887,27 @@ func (hn *HarnessNode) start(lndBinary string, lndError chan<- error, func (hn *HarnessNode) WaitUntilStarted(conn grpc.ClientConnInterface, timeout time.Duration) error { + return hn.waitForState(conn, timeout, func(s lnrpc.WalletState) bool { + return s != lnrpc.WalletState_WAITING_TO_START + }) +} + +// WaitUntilStateReached waits until the given wallet state (or one of the +// states following it) has been reached. +func (hn *HarnessNode) WaitUntilStateReached(conn grpc.ClientConnInterface, + timeout time.Duration, desiredState lnrpc.WalletState) error { + + return hn.waitForState(conn, timeout, func(s lnrpc.WalletState) bool { + return s >= desiredState + }) +} + +// waitForState waits until the current node state fulfills the given +// predicate. +func (hn *HarnessNode) waitForState(conn grpc.ClientConnInterface, + timeout time.Duration, + predicate func(state lnrpc.WalletState) bool) error { + stateClient := lnrpc.NewStateClient(conn) ctx, cancel := context.WithCancel(context.Background()) defer cancel() @@ -908,7 +929,7 @@ func (hn *HarnessNode) WaitUntilStarted(conn grpc.ClientConnInterface, return } - if resp.State != lnrpc.WalletState_WAITING_TO_START { + if predicate(resp.State) { close(started) return }