storj/satellite/metainfo/expireddeletion/expireddeletion_test.go

120 lines
3.6 KiB
Go
Raw Normal View History

// Copyright (C) 2020 Storj Labs, Inc.
// See LICENSE for copying information.
package expireddeletion_test
import (
"context"
"strconv"
"testing"
"time"
"github.com/stretchr/testify/require"
"go.uber.org/zap"
"storj.io/common/memory"
"storj.io/common/pb"
"storj.io/common/testcontext"
"storj.io/common/testrand"
"storj.io/storj/private/testplanet"
"storj.io/storj/satellite"
"storj.io/storj/storage"
)
// TestExpiredDeletion does the following:
// * Set up a network with one storagenode
// * Upload three segments
// * Run the expired segment chore
// * Verify that all three segments still exist
// * Expire one of the segments
// * Run the expired segment chore
// * Verify that two segments still exist and the expired one has been deleted
func TestExpiredDeletion(t *testing.T) {
testplanet.Run(t, testplanet.Config{
SatelliteCount: 1, StorageNodeCount: 1, UplinkCount: 1,
Reconfigure: testplanet.Reconfigure{
Satellite: func(log *zap.Logger, index int, config *satellite.Config) {
config.ExpiredDeletion.Interval = 500 * time.Millisecond
},
},
}, func(t *testing.T, ctx *testcontext.Context, planet *testplanet.Planet) {
satellite := planet.Satellites[0]
upl := planet.Uplinks[0]
expiredChore := satellite.Core.ExpiredDeletion.Chore
// Upload three objects
for i := 0; i < 4; i++ {
// 0 and 1 inline, 2 and 3 remote
testData := testrand.Bytes(8 * memory.KiB)
if i <= 1 {
testData = testrand.Bytes(1 * memory.KiB)
}
err := upl.Upload(ctx, satellite, "testbucket", "test/path/"+strconv.Itoa(i), testData)
require.NoError(t, err)
}
// Wait for next iteration of expired cleanup to finish
expiredChore.Loop.Restart()
expiredChore.Loop.TriggerWait()
// Verify that all four objects exist in metainfo
var expiredInline storage.ListItem
var expiredRemote storage.ListItem
i := 0
err := satellite.Metainfo.Database.Iterate(ctx, storage.IterateOptions{Recurse: true},
func(ctx context.Context, it storage.Iterator) error {
var item storage.ListItem
for it.Next(ctx, &item) {
if i == 1 {
expiredInline = item
} else if i == 3 {
expiredRemote = item
}
i++
}
return nil
})
require.NoError(t, err)
require.EqualValues(t, i, 4)
// Expire one inline segment and one remote segment
pointer := &pb.Pointer{}
err = pb.Unmarshal(expiredInline.Value, pointer)
require.NoError(t, err)
pointer.ExpirationDate = time.Now().Add(-24 * time.Hour)
newPointerBytes, err := pb.Marshal(pointer)
require.NoError(t, err)
err = satellite.Metainfo.Database.CompareAndSwap(ctx, expiredInline.Key, expiredInline.Value, newPointerBytes)
require.NoError(t, err)
err = pb.Unmarshal(expiredRemote.Value, pointer)
require.NoError(t, err)
pointer.ExpirationDate = time.Now().Add(-24 * time.Hour)
newPointerBytes, err = pb.Marshal(pointer)
require.NoError(t, err)
err = satellite.Metainfo.Database.CompareAndSwap(ctx, expiredRemote.Key, expiredRemote.Value, newPointerBytes)
require.NoError(t, err)
// Wait for next iteration of expired cleanup to finish
expiredChore.Loop.Restart()
expiredChore.Loop.TriggerWait()
// Verify that only two objects exist in metainfo
// And that the expired ones do not exist
i = 0
err = satellite.Metainfo.Database.Iterate(ctx, storage.IterateOptions{Recurse: true},
func(ctx context.Context, it storage.Iterator) error {
var item storage.ListItem
for it.Next(ctx, &item) {
require.False(t, item.Key.Equal(expiredInline.Key))
require.False(t, item.Key.Equal(expiredRemote.Key))
i++
}
return nil
})
require.NoError(t, err)
require.EqualValues(t, i, 2)
})
}