Files
galaxy-game/pkg/repo/fs/fs_test.go
T
2025-09-23 22:02:21 +03:00

182 lines
4.9 KiB
Go

package fs
import (
"os"
"path/filepath"
"strings"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNewFileStorageSuccess(t *testing.T) {
root, cleanup := createWorkDir(t)
defer cleanup()
_, err := NewFileStorage(root)
assert.NoError(t, err)
}
func TestLock(t *testing.T) {
root, cleanup := createWorkDir(t)
defer cleanup()
fs, err := NewFileStorage(root)
assert.NoError(t, err, "create file storage")
unlock, err := fs.Lock()
assert.NoError(t, err, "acquire lock")
exists, err := fileExists(filepath.Join(root, lockFile))
assert.NoError(t, err, "check that the lock file should exist")
assert.True(t, exists, "lock file must exists")
err = unlock()
assert.NoError(t, err, "unlocking existing lock")
exists, err = fileExists(filepath.Join(root, lockFile))
assert.NoError(t, err, "check that the lock file does not exist")
assert.False(t, exists, "lock file must be removed")
}
func TestWrite(t *testing.T) {
root, cleanup := createWorkDir(t)
defer cleanup()
fs, err := NewFileStorage(root)
assert.NoError(t, err, "create file storage: %s", err)
unlock, err := fs.Lock()
assert.NoError(t, err, "acquire lock: %s", err)
dirName := "some-dir"
if err := os.Mkdir(filepath.Join(root, dirName), os.ModePerm); err != nil {
t.Fatal(err)
}
for _, tc := range []struct {
path string
err string
}{
{path: "file-1.ext"},
{path: "/dir/file-2.ext"},
{path: "dir/subdir/file-3.ext"},
{path: lockFile, err: "write to the lock file"},
{path: dirName, err: "wrong type"},
{path: "/" + dirName, err: "wrong type"},
} {
t.Run(tc.path, func(t *testing.T) {
sd := &sampleData{[]byte{0, 1, 2, 3}}
err = fs.Write(tc.path, sd)
if tc.err == "" {
if err != nil {
assert.Fail(t, "not expecting an error", "write to file %s: %s", tc.path, err)
} else {
exists, err := fileExists(filepath.Join(root, tc.path))
assert.NoError(t, err, "check is written file exists")
assert.True(t, exists, "the written file should exist")
}
} else if tc.err != "" {
if err == nil {
assert.Fail(t, "expecting an error, got none", "write to file %s", tc.path)
} else {
assert.True(t, strings.Contains(err.Error(), tc.err), "expect: %q got: %q", tc.err, err.Error())
}
}
})
}
err = unlock()
assert.NoError(t, err, "unlocking existing lock")
}
func TestRead(t *testing.T) {
root, cleanup := createWorkDir(t)
defer cleanup()
fs, err := NewFileStorage(root)
assert.NoError(t, err, "create file storage: %s", err)
dirName := "some-dir"
if err := os.Mkdir(filepath.Join(root, dirName), os.ModePerm); err != nil {
t.Fatal(err)
}
fileName := "some-file.ext"
if err := os.WriteFile(filepath.Join(root, fileName), []byte{1, 2, 3, 4}, os.ModePerm); err != nil {
t.Fatal(err)
}
for _, tc := range []struct {
path string
lock bool
err string
}{
{path: fileName},
{path: "/" + fileName},
{path: fileName, lock: true, err: "lock must be released"},
{path: lockFile, err: "read from the lock file"},
{path: "dir/subdir/file-3.ext", err: "no such file"},
{path: lockFile, err: "read from the lock file"},
{path: dirName, err: "is a directory"},
} {
t.Run(tc.path, func(t *testing.T) {
if tc.lock {
unlock, err := fs.Lock()
if err != nil {
t.Fatalf("acquire lock: %s", err)
}
defer func() {
if err := unlock(); err != nil {
t.Fatalf("release lock: %s", err)
}
}()
}
sd := new(sampleData)
err = fs.Read(tc.path, sd)
if tc.err == "" {
if err != nil {
assert.Fail(t, "read: not expecting an error, got: "+err.Error())
} else {
exists, err := fileExists(filepath.Join(root, tc.path))
assert.NoError(t, err, "check is written file exists")
assert.True(t, exists, "the written file should exist")
}
} else if tc.err != "" {
if err == nil {
assert.Fail(t, "read: expecting an error, got none")
} else {
assert.True(t, strings.Contains(err.Error(), tc.err), "expect: %q got: %q", tc.err, err.Error())
}
}
})
}
}
func TestWriteErrorWithoutLock(t *testing.T) {
root, cleanup := createWorkDir(t)
defer cleanup()
fs, err := NewFileStorage(root)
assert.NoError(t, err, "create file storage")
sd := &sampleData{[]byte{0, 1, 2, 3}}
err = fs.Write("some/path", sd)
assert.Error(t, err, "should return error when no lock acquired")
assert.True(t, strings.Contains(err.Error(), "lock must be acquired"), "should return missing lock error")
}
func TestNewFileStorageErrorNotExists(t *testing.T) {
_, err := NewFileStorage(filepath.Join(os.TempDir(), "non-existent-dir"))
assert.Error(t, err)
}
func TestNewFileStorageErrorNotADirectory(t *testing.T) {
f, err := os.CreateTemp("", "fs-test-file")
if err != nil {
t.Fatal(err)
}
if err := f.Close(); err != nil {
t.Fatal(err)
}
_, err = NewFileStorage(f.Name())
assert.Error(t, err)
if err := os.Remove(f.Name()); err != nil {
t.Fatal(err)
}
}
func TestNewFileStorageErrorNoAccess(t *testing.T) {
_, err := NewFileStorage(nonWritableDir)
assert.Error(t, err)
}