storj/storage/filestore/store_test.go

229 lines
4.8 KiB
Go
Raw Normal View History

2019-01-24 20:15:10 +00:00
// Copyright (C) 2019 Storj Labs, Inc.
2018-09-28 07:59:27 +01:00
// See LICENSE for copying information.
package filestore_test
import (
"errors"
"io"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
"storj.io/storj/internal/testcontext"
2018-09-28 07:59:27 +01:00
"storj.io/storj/storage"
"storj.io/storj/storage/filestore"
)
func randomValue() []byte {
var id [32]byte
_, _ = rand.Read(id[:])
return id[:]
2018-09-28 07:59:27 +01:00
}
func TestStoreLoad(t *testing.T) {
const blobSize = 8 << 10
const repeatCount = 16
ctx := testcontext.New(t)
defer ctx.Cleanup()
2018-09-28 07:59:27 +01:00
store, err := filestore.NewAt(ctx.Dir("store"))
require.NoError(t, err)
2018-09-28 07:59:27 +01:00
data := make([]byte, blobSize)
temp := make([]byte, len(data))
_, _ = rand.Read(data)
refs := []storage.BlobRef{}
2018-09-28 07:59:27 +01:00
namespace := randomValue()
2018-09-28 07:59:27 +01:00
// store without size
for i := 0; i < repeatCount; i++ {
ref := storage.BlobRef{
Namespace: namespace,
Key: randomValue(),
2018-09-28 07:59:27 +01:00
}
refs = append(refs, ref)
writer, err := store.Create(ctx, ref, -1)
require.NoError(t, err)
n, err := writer.Write(data)
require.NoError(t, err)
require.Equal(t, n, len(data))
require.NoError(t, writer.Commit(ctx))
// after committing we should be able to call cancel without an error
require.NoError(t, writer.Cancel(ctx))
// two commits should fail
require.Error(t, writer.Commit(ctx))
2018-09-28 07:59:27 +01:00
}
namespace = randomValue()
2018-09-28 07:59:27 +01:00
// store with size
for i := 0; i < repeatCount; i++ {
ref := storage.BlobRef{
Namespace: namespace,
Key: randomValue(),
2018-09-28 07:59:27 +01:00
}
refs = append(refs, ref)
writer, err := store.Create(ctx, ref, int64(len(data)))
require.NoError(t, err)
n, err := writer.Write(data)
require.NoError(t, err)
require.Equal(t, n, len(data))
require.NoError(t, writer.Commit(ctx))
2018-09-28 07:59:27 +01:00
}
namespace = randomValue()
2018-09-28 07:59:27 +01:00
// store with larger size
{
ref := storage.BlobRef{
Namespace: namespace,
Key: randomValue(),
2018-09-28 07:59:27 +01:00
}
refs = append(refs, ref)
writer, err := store.Create(ctx, ref, int64(len(data)*2))
require.NoError(t, err)
n, err := writer.Write(data)
require.NoError(t, err)
require.Equal(t, n, len(data))
require.NoError(t, writer.Commit(ctx))
2018-09-28 07:59:27 +01:00
}
namespace = randomValue()
2018-09-28 07:59:27 +01:00
// store with error
{
ref := storage.BlobRef{
Namespace: namespace,
Key: randomValue(),
2018-09-28 07:59:27 +01:00
}
writer, err := store.Create(ctx, ref, -1)
require.NoError(t, err)
n, err := writer.Write(data)
require.NoError(t, err)
require.Equal(t, n, len(data))
require.NoError(t, writer.Cancel(ctx))
// commit after cancel should return an error
require.Error(t, writer.Commit(ctx))
_, err = store.Open(ctx, ref)
require.Error(t, err)
2018-09-28 07:59:27 +01:00
}
// try reading all the blobs
for _, ref := range refs {
reader, err := store.Open(ctx, ref)
require.NoError(t, err)
2018-09-28 07:59:27 +01:00
size, err := reader.Size()
require.NoError(t, err)
require.Equal(t, size, int64(len(data)))
2018-09-28 07:59:27 +01:00
_, err = io.ReadFull(reader, temp)
require.NoError(t, err)
2018-09-28 07:59:27 +01:00
require.NoError(t, reader.Close())
require.Equal(t, data, temp)
2018-09-28 07:59:27 +01:00
}
// delete the blobs
for _, ref := range refs {
2018-09-28 07:59:27 +01:00
err := store.Delete(ctx, ref)
require.NoError(t, err)
2018-09-28 07:59:27 +01:00
}
// try reading all the blobs
for _, ref := range refs {
_, err := store.Open(ctx, ref)
require.Error(t, err)
2018-09-28 07:59:27 +01:00
}
}
func TestDeleteWhileReading(t *testing.T) {
const blobSize = 8 << 10
const repeatCount = 16
2018-09-28 07:59:27 +01:00
ctx := testcontext.New(t)
defer ctx.Cleanup()
2018-09-28 07:59:27 +01:00
store, err := filestore.NewAt(ctx.Dir("store"))
require.NoError(t, err)
2018-09-28 07:59:27 +01:00
data := make([]byte, blobSize)
_, _ = rand.Read(data)
ref := storage.BlobRef{
Namespace: []byte{0},
Key: []byte{1},
2018-09-28 07:59:27 +01:00
}
writer, err := store.Create(ctx, ref, -1)
require.NoError(t, err)
_, err = writer.Write(data)
require.NoError(t, err)
// loading uncommitted file should fail
_, err = store.Open(ctx, ref)
require.Error(t, err, "loading uncommitted file should fail")
// commit the file
err = writer.Commit(ctx)
require.NoError(t, err, "commit the file")
// open a reader
reader, err := store.Open(ctx, ref)
require.NoError(t, err, "open a reader")
2018-09-28 07:59:27 +01:00
// double close, just in case
defer func() { _ = reader.Close() }()
2018-09-28 07:59:27 +01:00
// delete while reading
err = store.Delete(ctx, ref)
require.NoError(t, err, "delete while reading")
2018-09-28 07:59:27 +01:00
// opening deleted file should fail
_, err = store.Open(ctx, ref)
require.Error(t, err, "opening deleted file should fail")
2018-09-28 07:59:27 +01:00
// read all content
result, err := ioutil.ReadAll(reader)
require.NoError(t, err, "read all content")
2018-09-28 07:59:27 +01:00
// finally close reader
err = reader.Close()
require.NoError(t, err)
// should be able to read the full content
require.Equal(t, data, result)
// collect trash
_ = store.GarbageCollect(ctx)
2018-09-28 07:59:27 +01:00
// flaky test, for checking whether files have been actually deleted from disk
err = filepath.Walk(ctx.Dir("store"), func(path string, info os.FileInfo, err error) error {
2018-09-28 07:59:27 +01:00
if info.IsDir() {
return nil
}
return errors.New("found file " + path)
})
if err != nil {
t.Fatal(err)
}
}