filestore/backend_test.go

243 lines
6.1 KiB
Go
Raw Permalink Normal View History

package filestore
import (
"io"
2022-07-03 20:28:50 +02:00
"os"
"path/filepath"
"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)
})
}
//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)
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)
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")
})
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")
})
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)
}
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)
}