Skip to content

Commit c4b5f6a

Browse files
authored
Simplify current instance assertion and add test status utility (#817)
Use `Progress` to assert the current instance and add utility to print change across test F3 nodes useful for debugging.
1 parent 3507ce2 commit c4b5f6a

File tree

1 file changed

+70
-7
lines changed

1 file changed

+70
-7
lines changed

f3_test.go

Lines changed: 70 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,15 @@ package f3_test
33
import (
44
"context"
55
"fmt"
6+
"os"
67
"path/filepath"
8+
"reflect"
79
"sync/atomic"
810
"testing"
911
"time"
1012

1113
"github.com/filecoin-project/go-f3"
14+
"github.com/filecoin-project/go-f3/certs"
1215
"github.com/filecoin-project/go-f3/gpbft"
1316
"github.com/filecoin-project/go-f3/internal/clock"
1417
"github.com/filecoin-project/go-f3/internal/consensus"
@@ -89,14 +92,17 @@ func TestF3WithLookback(t *testing.T) {
8992
func TestF3PauseResumeCatchup(t *testing.T) {
9093
env := newTestEnvironment(t).withNodes(3).start()
9194

95+
if _, set := os.LookupEnv("GO_TEST_DEBUG"); set {
96+
env.logStatus()
97+
}
98+
9299
env.waitForInstanceNumber(1, 30*time.Second, true)
93100

94101
// Pausing two nodes should pause the network.
95102
env.pauseNode(1)
96103
env.pauseNode(2)
97104

98105
// Wait until node 0 stops receiving new instances
99-
env.clock.Add(1 * time.Second)
100106
env.waitForCondition(func() bool {
101107
oldInstance := env.nodes[0].currentGpbftInstance()
102108
env.clock.Add(10 * env.manifest.EC.Period)
@@ -324,12 +330,8 @@ type testNode struct {
324330
}
325331

326332
func (n *testNode) currentGpbftInstance() uint64 {
327-
c, err := n.f3.GetLatestCert(n.e.testCtx)
328-
require.NoError(n.e.t, err)
329-
if c == nil {
330-
return n.e.manifest.InitialInstance
331-
}
332-
return c.GPBFTInstance + 1
333+
require.NotNil(n.e.t, n.f3)
334+
return n.f3.Progress().ID
333335
}
334336

335337
func (n *testNode) init() *f3.F3 {
@@ -385,6 +387,43 @@ func (n *testNode) resume() {
385387
require.NoError(n.e.t, n.f3.Resume(n.e.testCtx))
386388
}
387389

390+
type testNodeStatus struct {
391+
id int
392+
initialised bool
393+
running bool
394+
progress gpbft.Instant
395+
latestCert *certs.FinalityCertificate
396+
}
397+
398+
func (s testNodeStatus) String() string {
399+
switch {
400+
case !s.initialised:
401+
return fmt.Sprint("node ", s.id, ": uninitialised")
402+
case !s.running:
403+
return fmt.Sprint("node ", s.id, ": paused")
404+
case s.latestCert == nil:
405+
return fmt.Sprint("node ", s.id, ": at", s.progress, " with no finality certs")
406+
default:
407+
return fmt.Sprint("node ", s.id, ": at ", s.progress, ", finalized epoch ", s.latestCert.ECChain.Head().Epoch, " {", s.latestCert.GPBFTInstance, "}")
408+
}
409+
}
410+
411+
func (n *testNode) status() testNodeStatus {
412+
var current testNodeStatus
413+
current.id = n.id
414+
if n.f3 != nil {
415+
current.initialised = true
416+
current.running = n.f3.IsRunning()
417+
current.progress = n.f3.Progress()
418+
if current.running {
419+
cert, err := n.f3.GetLatestCert(n.e.testCtx)
420+
require.NoError(n.e.t, err)
421+
current.latestCert = cert
422+
}
423+
}
424+
return current
425+
}
426+
388427
type testEnv struct {
389428
t *testing.T
390429
errgrp *errgroup.Group
@@ -691,6 +730,30 @@ func (e *testEnv) injectDatastoreFailures(i int, fn func(op string) error) {
691730
e.nodes[i].dsErrFunc = fn
692731
}
693732

733+
func (e *testEnv) logStatus() {
734+
e.t.Helper()
735+
736+
ctx, cancel := context.WithCancel(e.testCtx)
737+
e.t.Cleanup(cancel)
738+
739+
go func() {
740+
latest := make([]testNodeStatus, len(e.nodes))
741+
for ctx.Err() == nil {
742+
for i, n := range e.nodes {
743+
current := n.status()
744+
if len(latest) == i {
745+
latest = append(latest, testNodeStatus{})
746+
}
747+
if !reflect.DeepEqual(current, latest[i]) {
748+
latest[i] = current
749+
e.t.Log(current.String())
750+
}
751+
}
752+
time.Sleep(5 * time.Millisecond)
753+
}
754+
}()
755+
}
756+
694757
// TODO: This code is copy-pasta from cmd/f3/run.go, consider taking it out into a shared testing lib.
695758
// We could do the same to the F3 test instantiation
696759
func runMessageSubscription(ctx context.Context, module *f3.F3, actorID gpbft.ActorID, signer gpbft.Signer) error {

0 commit comments

Comments
 (0)