feat: Start adding unit tests

This commit is contained in:
Felix Pojtinger
2022-01-08 19:40:12 +01:00
parent 8fa82effb8
commit a15c7e7cac
4 changed files with 267 additions and 2 deletions

View File

@@ -12,6 +12,12 @@ jobs:
strategy:
matrix:
target:
- id: test
src: .
os: golang:bullseye
flags: ""
cmd: ./Hydrunfile test
dst: out/*
- id: go
src: .
os: golang:bullseye

View File

@@ -2,6 +2,17 @@
set -e
# Test
if [ "$1" = "test" ]; then
# Generate dependencies
make depend
# Run tests
make test
exit 0
fi
# Go
if [ "$1" = "go" ]; then
# Install native dependencies
@@ -19,8 +30,6 @@ if [ "$1" = "go" ]; then
CGO_ENABLED=0 bagop -j "$(nproc)" -b stfs -x '(android/*|ios/*|aix/*|plan9/*|illumos/*|dragonfly/*|netbsd/*|openbsd/*|solaris/*|freebsd/(386|arm)|js/wasm|linux/(mips|ppc64|riscv64)|windows/(arm|386))' -p 'make build/stfs DST=$DST' -d out
exit 0
exit 0
fi
# gccgo

View File

@@ -31,6 +31,10 @@ $(addprefix uninstall/,$(obj)):
$(addprefix run/,$(obj)):
$(subst run/,,$@) $(ARGS)
# Test
test:
go test ./...
# Clean
clean:
rm -rf out internal/db

246
pkg/fs/filesystem_test.go Normal file
View File

@@ -0,0 +1,246 @@
package fs
import (
"os"
"path/filepath"
"reflect"
"testing"
"github.com/pojntfx/stfs/internal/logging"
"github.com/pojntfx/stfs/pkg/cache"
"github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/operations"
"github.com/pojntfx/stfs/pkg/persisters"
"github.com/pojntfx/stfs/pkg/tape"
"github.com/spf13/afero"
)
func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) {
tmp, err := os.MkdirTemp(os.TempDir(), "stfs-test-*")
if err != nil {
return nil, nil, err
}
drive := filepath.Join(tmp, "drive.tar")
recordSize := 20
metadata := filepath.Join(tmp, "metadata.sqlite")
writeCache := filepath.Join(tmp, "write-cache")
osfsDir := filepath.Join(tmp, "osfs")
tm := tape.NewTapeManager(
drive,
recordSize,
false,
)
metadataPersister := persisters.NewMetadataPersister(metadata)
if err := metadataPersister.Open(); err != nil {
return nil, nil, err
}
l := logging.NewJSONLogger(4)
metadataConfig := config.MetadataConfig{
Metadata: metadataPersister,
}
pipeConfig := config.PipeConfig{
Compression: config.NoneKey,
Encryption: config.NoneKey,
Signature: config.NoneKey,
RecordSize: recordSize,
}
backendConfig := config.BackendConfig{
GetWriter: tm.GetWriter,
CloseWriter: tm.Close,
GetReader: tm.GetReader,
CloseReader: tm.Close,
GetDrive: tm.GetDrive,
CloseDrive: tm.Close,
}
readCryptoConfig := config.CryptoConfig{}
readOps := operations.NewOperations(
backendConfig,
metadataConfig,
pipeConfig,
readCryptoConfig,
func(event *config.HeaderEvent) {
l.Debug("Header read", event)
},
)
writeOps := operations.NewOperations(
backendConfig,
metadataConfig,
pipeConfig,
config.CryptoConfig{},
func(event *config.HeaderEvent) {
l.Debug("Header write", event)
},
)
stfs := NewSTFS(
readOps,
writeOps,
config.MetadataConfig{
Metadata: metadataPersister,
},
config.CompressionLevelFastest,
func() (cache.WriteCache, func() error, error) {
return cache.NewCacheWrite(
writeCache,
config.WriteCacheTypeFile,
)
},
false,
false,
func(hdr *config.Header) {
l.Trace("Header transform", hdr)
},
l,
)
root, err := stfs.Initialize("/", os.ModePerm)
if err != nil {
return nil, nil, err
}
fs, err := cache.NewCacheFilesystem(
stfs,
root,
config.NoneKey,
0,
"",
)
if err != nil {
return nil, nil, err
}
if err := os.MkdirAll(osfsDir, os.ModePerm); err != nil {
return nil, nil, err
}
return []afero.Fs{
fs,
afero.NewBasePathFs(afero.NewOsFs(), osfsDir),
},
func() error {
return os.RemoveAll(tmp)
},
nil
}
func getTestNameForFs(testName string, fsName string) string {
return testName + " (" + fsName + ")"
}
func TestSTFS_Name(t *testing.T) {
filesystems, cleanup, err := createTestFss()
if err != nil {
panic(err)
}
defer cleanup()
tests := []struct {
name string
f []afero.Fs
want string
}{
{
"Returns correct file system name",
[]afero.Fs{filesystems[1]},
"BasePathFs",
},
{
"Returns correct file system name",
[]afero.Fs{filesystems[0]},
"STFS",
},
}
for _, tt := range tests {
for _, f := range tt.f {
t.Run(getTestNameForFs(tt.name, f.Name()), func(t *testing.T) {
if got := f.Name(); got != tt.want {
t.Errorf("%v.Name() = %v, want %v", f.Name(), got, tt.want)
}
})
}
}
}
func TestSTFS_Create(t *testing.T) {
type args struct {
name string
}
tests := []struct {
name string
args args
wantErr bool
}{
{
"Can create /test.txt",
args{"/test.txt"},
false,
},
// FIXME: STFS can create file in non-existent directory, which should not be possible
// {
// "Can not create /nonexistent/test.txt",
// args{"/nonexistent/test.txt"},
// true,
// },
// FIXME: STFS can create `/` file even if / exists
// {
// "Can create /",
// args{"/"},
// true,
// },
}
for _, tt := range tests {
filesystems, cleanup, err := createTestFss()
if err != nil {
panic(err)
}
defer cleanup()
for _, f := range filesystems {
t.Run(getTestNameForFs(tt.name, f.Name()), func(t *testing.T) {
file, err := f.Create(tt.args.name)
if (err != nil) != tt.wantErr {
t.Errorf("%v.Create() error = %v, wantErr %v", f.Name(), err, tt.wantErr)
return
}
want, err := f.Stat(tt.args.name)
if err != nil {
t.Errorf("%v.Stat() error = %v, wantErr %v", f.Name(), err, tt.wantErr)
return
}
got, err := f.Stat(file.Name())
if err != nil {
t.Errorf("%v.Stat() error = %v, wantErr %v", f.Name(), err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, want) {
t.Errorf("%v.Create().Name() = %v, want %v", f.Name(), got, want)
return
}
})
}
}
}