lotus/storage/paths/index_locks_test.go

173 lines
4.7 KiB
Go
Raw Normal View History

package paths
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/require"
2020-09-07 03:49:10 +00:00
"github.com/filecoin-project/go-state-types/abi"
2020-09-30 17:32:19 +00:00
"github.com/filecoin-project/lotus/storage/sealer/storiface"
)
var aSector = abi.SectorID{
Miner: 2,
Number: 9000,
}
func TestCanLock(t *testing.T) {
lk := sectorLock{
2020-09-06 16:54:00 +00:00
r: [storiface.FileTypes]uint{},
w: storiface.FTNone,
}
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
require.Equal(t, true, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
2020-09-06 16:54:00 +00:00
ftAll := storiface.FTUnsealed | storiface.FTSealed | storiface.FTCache
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(ftAll, storiface.FTNone))
require.Equal(t, true, lk.canLock(storiface.FTNone, ftAll))
lk.r[0] = 1 // unsealed read taken
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
require.Equal(t, false, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(ftAll, storiface.FTNone))
require.Equal(t, false, lk.canLock(storiface.FTNone, ftAll))
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(storiface.FTNone, storiface.FTSealed|storiface.FTCache))
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTSealed|storiface.FTCache))
lk.r[0] = 0
2020-09-06 16:54:00 +00:00
lk.w = storiface.FTSealed
2020-09-06 16:54:00 +00:00
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
require.Equal(t, true, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
2020-09-06 16:54:00 +00:00
require.Equal(t, false, lk.canLock(storiface.FTSealed, storiface.FTNone))
require.Equal(t, false, lk.canLock(storiface.FTNone, storiface.FTSealed))
2020-09-06 16:54:00 +00:00
require.Equal(t, false, lk.canLock(ftAll, storiface.FTNone))
require.Equal(t, false, lk.canLock(storiface.FTNone, ftAll))
}
func TestIndexLocksSeq(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
ilk := &indexLocks{
locks: map[abi.SectorID]*sectorLock{},
}
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
2020-06-03 20:00:34 +00:00
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTUnsealed, storiface.FTNone))
cancel()
2020-06-03 20:00:34 +00:00
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
}
func TestIndexLocksBlockOn(t *testing.T) {
2020-09-06 16:54:00 +00:00
test := func(r1 storiface.SectorFileType, w1 storiface.SectorFileType, r2 storiface.SectorFileType, w2 storiface.SectorFileType) func(t *testing.T) {
return func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
ilk := &indexLocks{
locks: map[abi.SectorID]*sectorLock{},
}
require.NoError(t, ilk.StorageLock(ctx, aSector, r1, w1))
sch := make(chan struct{})
go func() {
ctx, cancel := context.WithCancel(context.Background())
sch <- struct{}{}
require.NoError(t, ilk.StorageLock(ctx, aSector, r2, w2))
cancel()
sch <- struct{}{}
}()
<-sch
select {
case <-sch:
t.Fatal("that shouldn't happen")
case <-time.After(40 * time.Millisecond):
}
cancel()
select {
case <-sch:
case <-time.After(time.Second):
t.Fatal("timed out")
}
}
}
2020-09-06 16:54:00 +00:00
t.Run("readBlocksWrite", test(storiface.FTUnsealed, storiface.FTNone, storiface.FTNone, storiface.FTUnsealed))
t.Run("writeBlocksRead", test(storiface.FTNone, storiface.FTUnsealed, storiface.FTUnsealed, storiface.FTNone))
t.Run("writeBlocksWrite", test(storiface.FTNone, storiface.FTUnsealed, storiface.FTNone, storiface.FTUnsealed))
}
func TestIndexLocksBlockWonR(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
ilk := &indexLocks{
locks: map[abi.SectorID]*sectorLock{},
}
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTUnsealed, storiface.FTNone))
sch := make(chan struct{})
go func() {
ctx, cancel := context.WithCancel(context.Background())
sch <- struct{}{}
2020-09-06 16:54:00 +00:00
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
cancel()
sch <- struct{}{}
}()
<-sch
select {
case <-sch:
t.Fatal("that shouldn't happen")
case <-time.After(40 * time.Millisecond):
}
cancel()
select {
case <-sch:
case <-time.After(time.Second):
t.Fatal("timed out")
}
}