Skip to content

Commit cd70c84

Browse files
authored
reuse test helper and fix start-stop error (#191)
1 parent edbc71d commit cd70c84

File tree

6 files changed

+62
-85
lines changed

6 files changed

+62
-85
lines changed

store/init_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ func TestInitStore_NoReinit(t *testing.T) {
2020

2121
suite := headertest.NewTestSuite(t)
2222
head := suite.Head()
23-
exchange := local.NewExchange(NewTestStore(ctx, t, head))
2423

2524
ds := sync.MutexWrap(datastore.NewMapDatastore())
25+
exchange := local.NewExchange(NewTestStore(t, ctx, ds, head))
2626
store, err := NewStore[*headertest.DummyHeader](ds)
2727
require.NoError(t, err)
2828

29-
err = Init[*headertest.DummyHeader](ctx, store, exchange, head.Hash())
29+
err = Init(ctx, store, exchange, head.Hash())
3030
assert.NoError(t, err)
3131

3232
err = store.Start(ctx)

store/store.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,21 +64,6 @@ func NewStore[H header.Header[H]](ds datastore.Batching, opts ...Option) (*Store
6464
return newStore[H](ds, opts...)
6565
}
6666

67-
// NewStoreWithHead initiates a new Store and forcefully sets a given trusted header as head.
68-
func NewStoreWithHead[H header.Header[H]](
69-
ctx context.Context,
70-
ds datastore.Batching,
71-
head H,
72-
opts ...Option,
73-
) (*Store[H], error) {
74-
store, err := newStore[H](ds, opts...)
75-
if err != nil {
76-
return nil, err
77-
}
78-
79-
return store, store.Init(ctx, head)
80-
}
81-
8267
func newStore[H header.Header[H]](ds datastore.Batching, opts ...Option) (*Store[H], error) {
8368
params := DefaultParameters()
8469
for _, opt := range opts {
@@ -142,6 +127,13 @@ func (s *Store[H]) Init(ctx context.Context, initial H) error {
142127
}
143128

144129
func (s *Store[H]) Start(context.Context) error {
130+
// closed s.writesDn means that store was stopped before, recreate chan.
131+
select {
132+
case <-s.writesDn:
133+
s.writesDn = make(chan struct{})
134+
default:
135+
}
136+
145137
go s.flushLoop()
146138
return nil
147139
}

store/store_test.go

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@ func TestStore(t *testing.T) {
2020
suite := headertest.NewTestSuite(t)
2121

2222
ds := sync.MutexWrap(datastore.NewMapDatastore())
23-
store, err := NewStoreWithHead(ctx, ds, suite.Head())
24-
require.NoError(t, err)
25-
26-
err = store.Start(ctx)
27-
require.NoError(t, err)
23+
store := NewTestStore(t, ctx, ds, suite.Head())
2824

2925
head, err := store.Head(ctx)
3026
require.NoError(t, err)
@@ -81,9 +77,6 @@ func TestStore(t *testing.T) {
8177

8278
// check that the store can be successfully started after previous stop
8379
// with all data being flushed.
84-
store, err = NewStore[*headertest.DummyHeader](ds)
85-
require.NoError(t, err)
86-
8780
err = store.Start(ctx)
8881
require.NoError(t, err)
8982

@@ -94,9 +87,6 @@ func TestStore(t *testing.T) {
9487
out, err = store.getRangeByHeight(ctx, 1, 13)
9588
require.NoError(t, err)
9689
assert.Len(t, out, 12)
97-
98-
err = store.Stop(ctx)
99-
require.NoError(t, err)
10090
}
10191

10292
// TestStore_GetRangeByHeight_ExpectedRange
@@ -107,11 +97,7 @@ func TestStore_GetRangeByHeight_ExpectedRange(t *testing.T) {
10797
suite := headertest.NewTestSuite(t)
10898

10999
ds := sync.MutexWrap(datastore.NewMapDatastore())
110-
store, err := NewStoreWithHead(ctx, ds, suite.Head())
111-
require.NoError(t, err)
112-
113-
err = store.Start(ctx)
114-
require.NoError(t, err)
100+
store := NewTestStore(t, ctx, ds, suite.Head())
115101

116102
head, err := store.Head(ctx)
117103
require.NoError(t, err)
@@ -143,11 +129,7 @@ func TestStore_Append_BadHeader(t *testing.T) {
143129
suite := headertest.NewTestSuite(t)
144130

145131
ds := sync.MutexWrap(datastore.NewMapDatastore())
146-
store, err := NewStoreWithHead(ctx, ds, suite.Head())
147-
require.NoError(t, err)
148-
149-
err = store.Start(ctx)
150-
require.NoError(t, err)
132+
store := NewTestStore(t, ctx, ds, suite.Head())
151133

152134
head, err := store.Head(ctx)
153135
require.NoError(t, err)
@@ -168,11 +150,7 @@ func TestStore_GetRange(t *testing.T) {
168150
suite := headertest.NewTestSuite(t)
169151

170152
ds := sync.MutexWrap(datastore.NewMapDatastore())
171-
store, err := NewStoreWithHead(ctx, ds, suite.Head())
172-
require.NoError(t, err)
173-
174-
err = store.Start(ctx)
175-
require.NoError(t, err)
153+
store := NewTestStore(t, ctx, ds, suite.Head())
176154

177155
head, err := store.Head(ctx)
178156
require.NoError(t, err)
@@ -216,6 +194,9 @@ func TestStore_GetRange(t *testing.T) {
216194

217195
for _, tt := range tests {
218196
t.Run(tt.name, func(t *testing.T) {
197+
ctx, cancel := context.WithTimeout(ctx, time.Second)
198+
defer cancel()
199+
219200
firstHeaderInRangeHeight := tt.from
220201
lastHeaderInRangeHeight := tt.to - 1
221202
to := lastHeaderInRangeHeight + 1
@@ -245,15 +226,12 @@ func TestStorePendingCacheMiss(t *testing.T) {
245226

246227
ds := sync.MutexWrap(datastore.NewMapDatastore())
247228

248-
store, err := NewStoreWithHead(ctx, ds, suite.Head(),
229+
store := NewTestStore(t, ctx, ds, suite.Head(),
249230
WithWriteBatchSize(100),
250231
WithStoreCacheSize(100),
251232
)
252-
require.NoError(t, err)
253233

254-
err = store.Start(ctx)
255-
require.NoError(t, err)
256-
err = store.Append(ctx, suite.GenDummyHeaders(100)...)
234+
err := store.Append(ctx, suite.GenDummyHeaders(100)...)
257235
require.NoError(t, err)
258236

259237
err = store.Append(ctx, suite.GenDummyHeaders(50)...)

store/testing.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,27 @@ import (
55
"testing"
66

77
"github.com/ipfs/go-datastore"
8-
"github.com/ipfs/go-datastore/sync"
98
"github.com/stretchr/testify/require"
109

11-
"github.com/celestiaorg/go-header"
1210
"github.com/celestiaorg/go-header/headertest"
1311
)
1412

1513
// NewTestStore creates initialized and started in memory header Store which is useful for testing.
16-
func NewTestStore(ctx context.Context, t *testing.T, head *headertest.DummyHeader) header.Store[*headertest.DummyHeader] {
17-
store, err := NewStoreWithHead(ctx, sync.MutexWrap(datastore.NewMapDatastore()), head)
18-
require.NoError(t, err)
14+
func NewTestStore(tb testing.TB, ctx context.Context,
15+
ds datastore.Batching, head *headertest.DummyHeader, opts ...Option,
16+
) *Store[*headertest.DummyHeader] {
17+
store, err := NewStore[*headertest.DummyHeader](ds, opts...)
18+
require.NoError(tb, err)
19+
20+
err = store.Init(ctx, head)
21+
require.NoError(tb, err)
1922

2023
err = store.Start(ctx)
21-
require.NoError(t, err)
24+
require.NoError(tb, err)
2225

23-
t.Cleanup(func() {
26+
tb.Cleanup(func() {
2427
err := store.Stop(ctx)
25-
require.NoError(t, err)
28+
require.NoError(tb, err)
2629
})
2730
return store
2831
}

sync/sync_head_test.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@ import (
77
"testing"
88
"time"
99

10-
"github.com/ipfs/go-datastore"
11-
sync2 "github.com/ipfs/go-datastore/sync"
1210
"github.com/stretchr/testify/assert"
1311
"github.com/stretchr/testify/require"
1412

1513
"github.com/celestiaorg/go-header"
1614
"github.com/celestiaorg/go-header/headertest"
1715
"github.com/celestiaorg/go-header/local"
18-
"github.com/celestiaorg/go-header/store"
1916
)
2017

2118
func TestSyncer_incomingNetworkHeadRaces(t *testing.T) {
@@ -61,11 +58,10 @@ func TestSyncer_HeadWithTrustedHead(t *testing.T) {
6158
suite := headertest.NewTestSuite(t)
6259
head := suite.Head()
6360

64-
localStore := store.NewTestStore(ctx, t, head)
61+
localStore := newTestStore(t, ctx, head)
62+
remoteStore := newTestStore(t, ctx, head)
6563

66-
remoteStore, err := store.NewStoreWithHead(ctx, sync2.MutexWrap(datastore.NewMapDatastore()), head)
67-
require.NoError(t, err)
68-
err = remoteStore.Append(ctx, suite.GenDummyHeaders(100)...)
64+
err := remoteStore.Append(ctx, suite.GenDummyHeaders(100)...)
6965
require.NoError(t, err)
7066

7167
// create a wrappedGetter to track exchange interactions

sync/sync_test.go

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"testing"
66
"time"
77

8+
"github.com/ipfs/go-datastore"
9+
"github.com/ipfs/go-datastore/sync"
810
"github.com/stretchr/testify/assert"
911
"github.com/stretchr/testify/require"
1012

@@ -21,15 +23,15 @@ func TestSyncSimpleRequestingHead(t *testing.T) {
2123
suite := headertest.NewTestSuite(t)
2224
head := suite.Head()
2325

24-
remoteStore := store.NewTestStore(ctx, t, head)
26+
remoteStore := newTestStore(t, ctx, head)
2527
err := remoteStore.Append(ctx, suite.GenDummyHeaders(100)...)
2628
require.NoError(t, err)
2729

2830
_, err = remoteStore.GetByHeight(ctx, 100)
2931
require.NoError(t, err)
3032

31-
localStore := store.NewTestStore(ctx, t, head)
32-
syncer, err := NewSyncer[*headertest.DummyHeader](
33+
localStore := newTestStore(t, ctx, head)
34+
syncer, err := NewSyncer(
3335
local.NewExchange(remoteStore),
3436
localStore,
3537
headertest.NewDummySubscriber(),
@@ -67,9 +69,9 @@ func TestDoSyncFullRangeFromExternalPeer(t *testing.T) {
6769
suite := headertest.NewTestSuite(t)
6870
head := suite.Head()
6971

70-
remoteStore := store.NewTestStore(ctx, t, head)
71-
localStore := store.NewTestStore(ctx, t, head)
72-
syncer, err := NewSyncer[*headertest.DummyHeader](
72+
remoteStore := newTestStore(t, ctx, head)
73+
localStore := newTestStore(t, ctx, head)
74+
syncer, err := NewSyncer(
7375
local.NewExchange(remoteStore),
7476
localStore,
7577
headertest.NewDummySubscriber(),
@@ -106,9 +108,9 @@ func TestSyncCatchUp(t *testing.T) {
106108
suite := headertest.NewTestSuite(t)
107109
head := suite.Head()
108110

109-
remoteStore := store.NewTestStore(ctx, t, head)
110-
localStore := store.NewTestStore(ctx, t, head)
111-
syncer, err := NewSyncer[*headertest.DummyHeader](
111+
remoteStore := newTestStore(t, ctx, head)
112+
localStore := newTestStore(t, ctx, head)
113+
syncer, err := NewSyncer(
112114
local.NewExchange(remoteStore),
113115
localStore,
114116
headertest.NewDummySubscriber(),
@@ -157,9 +159,9 @@ func TestSyncPendingRangesWithMisses(t *testing.T) {
157159
suite := headertest.NewTestSuite(t)
158160
head := suite.Head()
159161

160-
remoteStore := store.NewTestStore(ctx, t, head)
161-
localStore := store.NewTestStore(ctx, t, head)
162-
syncer, err := NewSyncer[*headertest.DummyHeader](
162+
remoteStore := newTestStore(t, ctx, head)
163+
localStore := newTestStore(t, ctx, head)
164+
syncer, err := NewSyncer(
163165
local.NewExchange(remoteStore),
164166
localStore,
165167
headertest.NewDummySubscriber(),
@@ -224,9 +226,9 @@ func TestSyncer_FindHeadersReturnsCorrectRange(t *testing.T) {
224226
suite := headertest.NewTestSuite(t)
225227
head := suite.Head()
226228

227-
remoteStore := store.NewTestStore(ctx, t, head)
228-
localStore := store.NewTestStore(ctx, t, head)
229-
syncer, err := NewSyncer[*headertest.DummyHeader](
229+
remoteStore := newTestStore(t, ctx, head)
230+
localStore := newTestStore(t, ctx, head)
231+
syncer, err := NewSyncer(
230232
local.NewExchange(remoteStore),
231233
localStore,
232234
headertest.NewDummySubscriber(),
@@ -260,9 +262,9 @@ func TestSyncerIncomingDuplicate(t *testing.T) {
260262
suite := headertest.NewTestSuite(t)
261263
head := suite.Head()
262264

263-
remoteStore := store.NewTestStore(ctx, t, head)
264-
localStore := store.NewTestStore(ctx, t, head)
265-
syncer, err := NewSyncer[*headertest.DummyHeader](
265+
remoteStore := newTestStore(t, ctx, head)
266+
localStore := newTestStore(t, ctx, head)
267+
syncer, err := NewSyncer(
266268
&delayedGetter[*headertest.DummyHeader]{Getter: local.NewExchange(remoteStore)},
267269
localStore,
268270
headertest.NewDummySubscriber(),
@@ -301,12 +303,12 @@ func TestSync_InvalidSyncTarget(t *testing.T) {
301303
head := suite.Head()
302304

303305
// create a local store which is initialised at genesis height
304-
localStore := store.NewTestStore(ctx, t, head)
306+
localStore := newTestStore(t, ctx, head)
305307
// create a peer which is already on height 100
306-
remoteStore := headertest.NewStore[*headertest.DummyHeader](t, suite, 100)
308+
remoteStore := headertest.NewStore(t, suite, 100)
307309

308-
syncer, err := NewSyncer[*headertest.DummyHeader](
309-
local.NewExchange[*headertest.DummyHeader](remoteStore),
310+
syncer, err := NewSyncer(
311+
local.NewExchange(remoteStore),
310312
localStore,
311313
headertest.NewDummySubscriber(),
312314
WithBlockTime(time.Nanosecond),
@@ -396,3 +398,9 @@ func (d *delayedGetter[H]) GetRangeByHeight(ctx context.Context, from H, to uint
396398
return nil, ctx.Err()
397399
}
398400
}
401+
402+
// newTestStore creates initialized and started in memory header Store which is useful for testing.
403+
func newTestStore(tb testing.TB, ctx context.Context, head *headertest.DummyHeader) header.Store[*headertest.DummyHeader] {
404+
ds := sync.MutexWrap(datastore.NewMapDatastore())
405+
return store.NewTestStore(tb, ctx, ds, head)
406+
}

0 commit comments

Comments
 (0)