github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/consensus/recovery/recover_test.go (about) 1 package recovery 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/require" 7 8 "github.com/onflow/flow-go/consensus/hotstuff/model" 9 "github.com/onflow/flow-go/model/flow" 10 "github.com/onflow/flow-go/utils/unittest" 11 ) 12 13 func TestRecover(t *testing.T) { 14 finalized := unittest.BlockHeaderFixture() 15 blocks := unittest.ChainFixtureFrom(100, finalized) 16 pending := make([]*flow.Header, 0) 17 for _, b := range blocks { 18 pending = append(pending, b.Header) 19 } 20 21 // Recover with `pending` blocks and record what blocks are forwarded to `onProposal` 22 recovered := make([]*model.Proposal, 0) 23 scanner := func(block *model.Proposal) error { 24 recovered = append(recovered, block) 25 return nil 26 } 27 err := Recover(unittest.Logger(), pending, scanner) 28 require.NoError(t, err) 29 30 // should forward blocks in exact order, just converting flow.Header to pending block 31 require.Len(t, recovered, len(pending)) 32 for i, r := range recovered { 33 require.Equal(t, model.ProposalFromFlow(pending[i]), r) 34 } 35 } 36 37 func TestRecoverEmptyInput(t *testing.T) { 38 scanner := func(block *model.Proposal) error { 39 require.Fail(t, "no proposal expected") 40 return nil 41 } 42 err := Recover(unittest.Logger(), []*flow.Header{}, scanner) 43 require.NoError(t, err) 44 } 45 46 func TestCollector(t *testing.T) { 47 t.Run("empty retrieve", func(t *testing.T) { 48 c := NewCollector[string]() 49 require.Empty(t, c.Retrieve()) 50 }) 51 52 t.Run("append", func(t *testing.T) { 53 c := NewCollector[string]() 54 strings := []string{"a", "b", "c"} 55 appended := 0 56 for _, s := range strings { 57 c.Append(s) 58 appended++ 59 require.Equal(t, strings[:appended], c.Retrieve()) 60 } 61 }) 62 63 t.Run("append multiple", func(t *testing.T) { 64 c := NewCollector[string]() 65 strings := []string{"a", "b", "c", "d", "e"} 66 67 c.Append(strings[0], strings[1]) 68 require.Equal(t, strings[:2], c.Retrieve()) 69 70 c.Append(strings[2], strings[3], strings[4]) 71 require.Equal(t, strings, c.Retrieve()) 72 }) 73 74 t.Run("safely passed by value", func(t *testing.T) { 75 strings := []string{"a", "b"} 76 c := NewCollector[string]() 77 c.Append(strings[0]) 78 79 // pass by value 80 c2 := c 81 require.Equal(t, strings[:1], c2.Retrieve()) 82 83 // add to original; change could be reflected by c2: 84 c.Append(strings[1]) 85 require.Equal(t, strings, c2.Retrieve()) 86 }) 87 88 t.Run("append after retrieve", func(t *testing.T) { 89 c := NewCollector[string]() 90 strings := []string{"a", "b", "c", "d", "e"} 91 92 c.Append(strings[0], strings[1]) 93 retrieved := c.Retrieve() 94 require.Equal(t, strings[:2], retrieved) 95 96 // appending further elements shouldn't affect previously retrieved list 97 c.Append(strings[2], strings[3], strings[4]) 98 require.Equal(t, strings[:2], retrieved) 99 require.Equal(t, strings, c.Retrieve()) 100 }) 101 }