Skip to content

Commit 623908a

Browse files
CoderZhienvestcc
andauthored
unit test for block preparer (#4613)
--------- Co-authored-by: envestcc <[email protected]>
1 parent 589ab65 commit 623908a

File tree

2 files changed

+120
-3
lines changed

2 files changed

+120
-3
lines changed

state/factory/blockpreparer.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,12 @@ func (d *blockPreparer) PrepareOrWait(ctx context.Context, prevHash []byte, time
4545
}
4646

4747
d.mu.Lock()
48-
res := d.results[hash.Hash256(prevHash)][timestamp.UnixNano()]
49-
d.mu.Unlock()
50-
return res.blk, res.err
48+
defer d.mu.Unlock()
49+
if blks, ok := d.results[hash.BytesToHash256(prevHash)]; ok && blks[timestamp.UnixNano()] != nil {
50+
res := blks[timestamp.UnixNano()]
51+
return res.blk, res.err
52+
}
53+
return nil, errors.New("mint result not found")
5154
}
5255

5356
func (d *blockPreparer) prepare(prevHash []byte, timestamp time.Time, mintFn func() (*block.Block, error)) chan struct{} {
@@ -80,6 +83,7 @@ func (d *blockPreparer) prepare(prevHash []byte, timestamp time.Time, mintFn fun
8083
func (d *blockPreparer) ReceiveBlock(blk *block.Block) error {
8184
d.mu.Lock()
8285
delete(d.tasks, blk.PrevHash())
86+
delete(d.results, blk.PrevHash())
8387
d.mu.Unlock()
8488
return nil
8589
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package factory
2+
3+
import (
4+
"context"
5+
"sync"
6+
"testing"
7+
"time"
8+
9+
"github.com/iotexproject/go-pkgs/hash"
10+
"github.com/pkg/errors"
11+
"github.com/stretchr/testify/require"
12+
13+
"github.com/iotexproject/iotex-core/v2/action"
14+
"github.com/iotexproject/iotex-core/v2/blockchain/block"
15+
"github.com/iotexproject/iotex-core/v2/test/identityset"
16+
)
17+
18+
func TestBlockPreparer_PrepareOrWait(t *testing.T) {
19+
preparer := newBlockPreparer()
20+
prevHash := hash.Hash256b([]byte("previousHash"))
21+
timestamp := time.Now()
22+
mockBlk := &block.Block{}
23+
called := false
24+
25+
// Mock mint function
26+
mintFn := func() (*block.Block, error) {
27+
if called {
28+
return nil, errors.New("block already minted")
29+
}
30+
called = true
31+
return mockBlk, nil
32+
}
33+
mintFn2 := func() (*block.Block, error) {
34+
return &block.Block{
35+
Body: block.Body{
36+
Actions: []*action.SealedEnvelope{},
37+
},
38+
}, nil
39+
}
40+
41+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
42+
defer cancel()
43+
44+
wg := sync.WaitGroup{}
45+
wg.Add(2)
46+
go func() {
47+
blk1, err := preparer.PrepareOrWait(ctx, prevHash[:], timestamp, mintFn)
48+
require.NoError(t, err)
49+
require.Equal(t, mockBlk, blk1)
50+
wg.Done()
51+
}()
52+
go func() {
53+
blk2, err := preparer.PrepareOrWait(ctx, prevHash[:], timestamp.Add(time.Second), mintFn2)
54+
require.NoError(t, err)
55+
require.NotEqual(t, mockBlk, blk2)
56+
wg.Done()
57+
}()
58+
blk, err := preparer.PrepareOrWait(ctx, prevHash[:], timestamp, mintFn)
59+
require.NoError(t, err)
60+
require.Equal(t, mockBlk, blk)
61+
wg.Wait()
62+
}
63+
64+
func TestBlockPreparer_PrepareOrWait_Timeout(t *testing.T) {
65+
preparer := newBlockPreparer()
66+
prevHash := hash.Hash256b([]byte("previousHash"))
67+
timestamp := time.Now()
68+
69+
// Mock mint function that takes too long
70+
mintFn := func() (*block.Block, error) {
71+
time.Sleep(2 * time.Second)
72+
return &block.Block{}, nil
73+
}
74+
75+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
76+
defer cancel()
77+
78+
blk, err := preparer.PrepareOrWait(ctx, prevHash[:], timestamp, mintFn)
79+
require.Error(t, err)
80+
require.Nil(t, blk)
81+
}
82+
83+
func TestBlockPreparer_ReceiveBlock(t *testing.T) {
84+
preparer := newBlockPreparer()
85+
prevHash := hash.Hash256b([]byte("previousHash"))
86+
timestamp := time.Now()
87+
88+
// Mock mint function
89+
mintFn := func() (*block.Block, error) {
90+
builder := &block.TestingBuilder{}
91+
blk, err := builder.SetPrevBlockHash(prevHash).SignAndBuild(identityset.PrivateKey(0))
92+
return &blk, err
93+
}
94+
95+
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
96+
defer cancel()
97+
98+
blk, err := preparer.PrepareOrWait(ctx, prevHash[:], timestamp, mintFn)
99+
require.NoError(t, err)
100+
101+
emptyblk := &block.Block{}
102+
require.NoError(t, preparer.ReceiveBlock(emptyblk))
103+
_, ok := preparer.tasks[prevHash]
104+
require.True(t, ok)
105+
_, ok = preparer.results[prevHash]
106+
require.True(t, ok)
107+
108+
require.NoError(t, preparer.ReceiveBlock(blk))
109+
_, ok = preparer.tasks[prevHash]
110+
require.False(t, ok)
111+
_, ok = preparer.results[prevHash]
112+
require.False(t, ok)
113+
}

0 commit comments

Comments
 (0)