2022-06-12 10:26:26 +02:00
|
|
|
package filestore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2022-07-03 20:28:50 +02:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
2022-06-12 10:26:26 +02:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestMemoryBackend(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
2022-07-03 20:28:50 +02:00
|
|
|
t.Run("it is a valid backend", func(t *testing.T) {
|
|
|
|
m := new(MemoryBackend)
|
|
|
|
ValidateBackend(t, m)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("read then write a file", func(t *testing.T) {
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestOSBackend(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
t.Run("it is a valid backend", func(t *testing.T) {
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
m := NewOSBackend(tmpDir)
|
|
|
|
|
|
|
|
ValidateBackend(t, m)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("it returns an error if the directory cannot be created", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
|
|
|
|
tmpDir := t.TempDir()
|
|
|
|
fullpath := filepath.Join(tmpDir, "foo")
|
|
|
|
m := NewOSBackend(fullpath)
|
|
|
|
|
|
|
|
err := os.WriteFile(fullpath, []byte(filecontent), 0o600)
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
wc, err := m.Create("foo")
|
|
|
|
assert.Error(err)
|
|
|
|
assert.Nil(wc)
|
|
|
|
})
|
2022-06-12 10:26:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//revive:disable:cognitive-complexity
|
|
|
|
func ValidateBackend(t *testing.T, b Backend) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
filecontent := []byte("file content")
|
|
|
|
|
2022-07-03 20:28:50 +02:00
|
|
|
setupBackend(t, b)
|
|
|
|
|
2022-06-12 10:26:26 +02:00
|
|
|
t.Run("validate Sub", func(t *testing.T) {
|
|
|
|
t.Run("it must not be nil", func(t *testing.T) {
|
|
|
|
s := b.Sub("foo")
|
|
|
|
require.NotNil(t, s, "Sub must not return a nil value")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("validate Create", func(t *testing.T) {
|
|
|
|
t.Run("it must create a file if it does not exist", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
|
|
|
|
precondFileNotExists(t, b, "create-1")
|
|
|
|
|
|
|
|
wc, err := b.Create("create-1")
|
|
|
|
assert.NoError(err, "Create must not return an error in case of success")
|
|
|
|
assert.NotNil(wc, "Create must return a non nil value in case of success")
|
|
|
|
|
2022-07-03 20:28:50 +02:00
|
|
|
_, err = wc.Write(filecontent)
|
|
|
|
assert.NoError(err)
|
|
|
|
|
2022-06-12 10:26:26 +02:00
|
|
|
wc.Close()
|
|
|
|
|
|
|
|
assert.True(b.Exists("create-1"), "The file must exist after "+
|
|
|
|
"Create has been successfully called")
|
2022-07-03 20:28:50 +02:00
|
|
|
|
|
|
|
rc, err := b.Open("create-1")
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
newcontent, err := io.ReadAll(rc)
|
|
|
|
assert.NoError(err)
|
|
|
|
assert.Equal(filecontent, newcontent, "The content of the created "+
|
|
|
|
"file must be correct")
|
2022-06-12 10:26:26 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("it should replace a file if it exists", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
|
|
|
|
precondFileExists(t, b, "create-2")
|
|
|
|
|
|
|
|
wc, err := b.Create("create-2")
|
|
|
|
assert.NoError(err, "Create must not return an error if the file "+
|
|
|
|
"already exists")
|
|
|
|
|
|
|
|
_, err = wc.Write(filecontent)
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
wc.Close()
|
|
|
|
|
|
|
|
rc, err := b.Open("create-2")
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
newcontent, err := io.ReadAll(rc)
|
|
|
|
assert.NoError(err)
|
|
|
|
assert.NotEqual([]byte("hello world"), newcontent, "Create should "+
|
|
|
|
"overwrite the file when it already existed")
|
2022-07-03 20:28:50 +02:00
|
|
|
assert.Equal(filecontent, newcontent, "Create should "+
|
|
|
|
"overwrite the file when it already existed")
|
2022-06-12 10:26:26 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("when the file cannot be created", func(t *testing.T) {
|
|
|
|
t.Skip("do not know how to implement that!")
|
|
|
|
// maybe we should require that a directory already exists in the backend
|
|
|
|
assert := require.New(t)
|
|
|
|
|
|
|
|
wc, err := b.Create("create-3")
|
|
|
|
assert.NoError(err)
|
|
|
|
assert.Nil(wc, "the file access must be nil if Create returns an error")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("validate Open", func(t *testing.T) {
|
|
|
|
t.Run("it should return an open file if it exists", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
precondFileExists(t, b, "open-1")
|
|
|
|
|
|
|
|
rc, err := b.Open("open-1")
|
|
|
|
assert.NoError(err, "Open must not return an error when successful")
|
|
|
|
assert.NotNil(rc, "Open must not return a nil value when successful")
|
|
|
|
|
|
|
|
rc.Close()
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("when the file does not exist", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
precondFileNotExists(t, b, "open-2")
|
|
|
|
|
|
|
|
rc, err := b.Open("open-2")
|
|
|
|
assert.Error(err, "Open must return an error when the file does not exist")
|
|
|
|
assert.Nil(rc, "Open must return a nil value when the file does not exist")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("when the file cannot be opened", func(t *testing.T) {
|
|
|
|
t.Skip("do not know how to implement that test!")
|
|
|
|
precondFileExists(t, b, "open-3")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("validate Delete", func(t *testing.T) {
|
|
|
|
t.Run("it should remove a file if it exists", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
precondFileExists(t, b, "delete-1")
|
|
|
|
|
|
|
|
err := b.Delete("delete-1")
|
|
|
|
assert.NoError(err, "Delete must not return an error in case of success")
|
|
|
|
|
|
|
|
assert.False(b.Exists("delete-1"), "File must not exist anymore "+
|
|
|
|
"after a successful delete")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("when the file does not exist", func(t *testing.T) {
|
|
|
|
assert := require.New(t)
|
|
|
|
precondFileNotExists(t, b, "delete-2")
|
|
|
|
|
|
|
|
err := b.Delete("delete-2")
|
|
|
|
assert.NoError(err, "Delete must not return an error if the file "+
|
|
|
|
"does not exist")
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("when the file cannot be deleted", func(t *testing.T) {
|
|
|
|
t.Skip("don't know ho to test that!")
|
|
|
|
assert := require.New(t)
|
|
|
|
precondFileExists(t, b, "delete-3")
|
|
|
|
|
|
|
|
err := b.Delete("delete-3")
|
|
|
|
assert.Error(err, "Delete must return an error when the file "+
|
|
|
|
"cannot be deleted")
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("validate Exists", func(t *testing.T) {
|
|
|
|
t.Run("it should return true if the file exists", func(t *testing.T) {
|
|
|
|
wc, err := b.Create("exists1")
|
|
|
|
require.NoError(t, err)
|
|
|
|
require.NotNil(t, wc)
|
|
|
|
|
|
|
|
_, err = wc.Write(filecontent)
|
|
|
|
wc.Close()
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
require.True(t, b.Exists("exists1"))
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("it should return false if the file does not exist", func(t *testing.T) {
|
|
|
|
require.False(t, b.Exists("exists2"))
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-07-03 20:28:50 +02:00
|
|
|
func setupBackend(t *testing.T, b Backend) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
assert := require.New(t)
|
|
|
|
|
|
|
|
wc, err := b.Create("create-2")
|
|
|
|
assert.NoError(err)
|
|
|
|
defer wc.Close()
|
|
|
|
_, err = wc.Write([]byte("hello world"))
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
wc, err = b.Create("open-1")
|
|
|
|
assert.NoError(err)
|
|
|
|
defer wc.Close()
|
|
|
|
_, err = wc.Write([]byte(filecontent))
|
|
|
|
assert.NoError(err)
|
|
|
|
|
|
|
|
wc, err = b.Create("delete-1")
|
|
|
|
assert.NoError(err)
|
|
|
|
defer wc.Close()
|
|
|
|
_, err = wc.Write([]byte(filecontent))
|
|
|
|
assert.NoError(err)
|
|
|
|
}
|
|
|
|
|
2022-06-12 10:26:26 +02:00
|
|
|
func precondFileExists(t *testing.T, b Backend, name string) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
require.True(t, b.Exists(name), "PRECOND: file %q must exist for this test",
|
|
|
|
name)
|
|
|
|
}
|
|
|
|
|
|
|
|
func precondFileNotExists(t *testing.T, b Backend, name string) {
|
|
|
|
t.Helper()
|
|
|
|
|
|
|
|
require.False(t, b.Exists(name), "PRECOND: file %q must not exist for this test",
|
|
|
|
name)
|
|
|
|
}
|