172 lines
4.7 KiB
Go
172 lines
4.7 KiB
Go
package stores
|
|
|
|
import (
|
|
"context"
|
|
"github.com/filecoin-project/lotus/extern/sector-storage/storiface"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
|
)
|
|
|
|
var aSector = abi.SectorID{
|
|
Miner: 2,
|
|
Number: 9000,
|
|
}
|
|
|
|
func TestCanLock(t *testing.T) {
|
|
lk := sectorLock{
|
|
r: [storiface.FileTypes]uint{},
|
|
w: storiface.FTNone,
|
|
}
|
|
|
|
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
|
|
require.Equal(t, true, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
|
|
|
|
ftAll := storiface.FTUnsealed | storiface.FTSealed | storiface.FTCache
|
|
|
|
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
|
|
|
|
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
|
|
require.Equal(t, false, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
|
|
|
|
require.Equal(t, true, lk.canLock(ftAll, storiface.FTNone))
|
|
require.Equal(t, false, lk.canLock(storiface.FTNone, ftAll))
|
|
|
|
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
|
|
|
|
lk.w = storiface.FTSealed
|
|
|
|
require.Equal(t, true, lk.canLock(storiface.FTUnsealed, storiface.FTNone))
|
|
require.Equal(t, true, lk.canLock(storiface.FTNone, storiface.FTUnsealed))
|
|
|
|
require.Equal(t, false, lk.canLock(storiface.FTSealed, storiface.FTNone))
|
|
require.Equal(t, false, lk.canLock(storiface.FTNone, storiface.FTSealed))
|
|
|
|
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{},
|
|
}
|
|
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
|
|
cancel()
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
|
|
cancel()
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
|
|
cancel()
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTUnsealed, storiface.FTNone))
|
|
cancel()
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
|
|
cancel()
|
|
|
|
ctx, cancel = context.WithTimeout(context.Background(), time.Second)
|
|
require.NoError(t, ilk.StorageLock(ctx, aSector, storiface.FTNone, storiface.FTUnsealed))
|
|
cancel()
|
|
}
|
|
|
|
func TestIndexLocksBlockOn(t *testing.T) {
|
|
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")
|
|
}
|
|
}
|
|
}
|
|
|
|
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{},
|
|
}
|
|
|
|
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{}{}
|
|
|
|
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")
|
|
}
|
|
}
|