feat: Start adding parameterized tests

This commit is contained in:
Felicitas Pojtinger
2022-01-09 00:19:44 +01:00
parent f3657dc189
commit 53ed060dbf
2 changed files with 264 additions and 93 deletions

View File

@@ -33,7 +33,7 @@ $(addprefix run/,$(obj)):
# Test # Test
test: test:
go test ./... go test ./... -parallel $(shell nproc)
# Clean # Clean
clean: clean:

View File

@@ -1,31 +1,151 @@
package fs package fs
import ( import (
"fmt"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
"testing" "testing"
"time"
"github.com/pojntfx/stfs/internal/logging" "github.com/pojntfx/stfs/examples"
"github.com/pojntfx/stfs/pkg/cache" "github.com/pojntfx/stfs/pkg/cache"
"github.com/pojntfx/stfs/pkg/config" "github.com/pojntfx/stfs/pkg/config"
"github.com/pojntfx/stfs/pkg/keys"
"github.com/pojntfx/stfs/pkg/operations" "github.com/pojntfx/stfs/pkg/operations"
"github.com/pojntfx/stfs/pkg/persisters" "github.com/pojntfx/stfs/pkg/persisters"
"github.com/pojntfx/stfs/pkg/tape" "github.com/pojntfx/stfs/pkg/tape"
"github.com/pojntfx/stfs/pkg/utility"
"github.com/spf13/afero" "github.com/spf13/afero"
) )
func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) { const (
tmp, err := os.MkdirTemp(os.TempDir(), "stfs-test-*") verbose = true
if err != nil { signaturePassword = "testSignaturePassword"
return nil, nil, err encryptionPassword = "testEncryptionPassword"
)
var (
recordSizes = []int{20, 60, 120}
fileSystemCacheDurations = []time.Duration{time.Minute, time.Hour}
stfsConfigs = []stfsConfig{}
)
func init() {
// TODO: Generate encryption and signature keys here and re-use them
// for _, signature := range config.KnownSignatureFormats {
// for _, encryption := range config.KnownEncryptionFormats {
for _, compression := range config.KnownCompressionFormats {
for _, compressionLevel := range config.KnownCompressionLevels {
for _, writeCacheType := range config.KnownWriteCacheTypes {
for _, fileSystemCacheType := range config.KnownFileSystemCacheTypes {
for _, fileSystemCacheDuration := range fileSystemCacheDurations {
for _, recordSize := range recordSizes {
stfsConfigs = append(stfsConfigs, stfsConfig{
recordSize,
false,
config.NoneKey, // encryption,
config.NoneKey, // signature,
compression,
compressionLevel,
writeCacheType,
fileSystemCacheType,
fileSystemCacheDuration,
})
}
}
}
}
}
}
// }
// }
}
func createSTFS(
drive string,
metadata string,
recordSize int,
readOnly bool,
verbose bool,
signature string,
signaturePassword string,
encryption string,
encryptionPassword string,
compression string,
compressionLevel string,
writeCache string,
writeCacheDir string,
fileSystemCache string,
fileSystemCacheDir string,
fileSystemCacheDuration time.Duration,
) (afero.Fs, error) {
signaturePrivkey := []byte{}
signaturePubkey := []byte{}
if signature != config.NoneKey {
var err error
signaturePrivkey, signaturePubkey, err = utility.Keygen(
config.PipeConfig{
Signature: signature,
Encryption: config.NoneKey,
},
config.PasswordConfig{
Password: signaturePassword,
},
)
if err != nil {
return nil, err
}
} }
drive := filepath.Join(tmp, "drive.tar") signatureRecipient, err := keys.ParseSignerRecipient(signature, signaturePubkey)
recordSize := 20 if err != nil {
metadata := filepath.Join(tmp, "metadata.sqlite") return nil, err
writeCache := filepath.Join(tmp, "write-cache") }
osfsDir := filepath.Join(tmp, "osfs")
signatureIdentity, err := keys.ParseSignerIdentity(signature, signaturePrivkey, signaturePassword)
if err != nil {
return nil, err
}
encryptionPrivkey := []byte{}
encryptionPubkey := []byte{}
if encryption != config.NoneKey {
encryptionPrivkey, encryptionPubkey, err = utility.Keygen(
config.PipeConfig{
Signature: config.NoneKey,
Encryption: encryption,
},
config.PasswordConfig{
Password: encryptionPassword,
},
)
if err != nil {
return nil, err
}
}
encryptionRecipient, err := keys.ParseRecipient(encryption, encryptionPubkey)
if err != nil {
return nil, err
}
encryptionIdentity, err := keys.ParseIdentity(encryption, encryptionPrivkey, encryptionPassword)
if err != nil {
return nil, err
}
tm := tape.NewTapeManager( tm := tape.NewTapeManager(
drive, drive,
@@ -35,18 +155,20 @@ func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) {
metadataPersister := persisters.NewMetadataPersister(metadata) metadataPersister := persisters.NewMetadataPersister(metadata)
if err := metadataPersister.Open(); err != nil { if err := metadataPersister.Open(); err != nil {
return nil, nil, err return nil, err
} }
l := logging.NewJSONLogger(4) jsonLogger := &examples.Logger{
Verbose: verbose,
}
metadataConfig := config.MetadataConfig{ metadataConfig := config.MetadataConfig{
Metadata: metadataPersister, Metadata: metadataPersister,
} }
pipeConfig := config.PipeConfig{ pipeConfig := config.PipeConfig{
Compression: config.NoneKey, Compression: compression,
Encryption: config.NoneKey, Encryption: encryption,
Signature: config.NoneKey, Signature: signature,
RecordSize: recordSize, RecordSize: recordSize,
} }
backendConfig := config.BackendConfig{ backendConfig := config.BackendConfig{
@@ -59,7 +181,11 @@ func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) {
GetDrive: tm.GetDrive, GetDrive: tm.GetDrive,
CloseDrive: tm.Close, CloseDrive: tm.Close,
} }
readCryptoConfig := config.CryptoConfig{} readCryptoConfig := config.CryptoConfig{
Recipient: signatureRecipient,
Identity: encryptionIdentity,
Password: encryptionPassword,
}
readOps := operations.NewOperations( readOps := operations.NewOperations(
backendConfig, backendConfig,
@@ -69,18 +195,23 @@ func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) {
readCryptoConfig, readCryptoConfig,
func(event *config.HeaderEvent) { func(event *config.HeaderEvent) {
l.Debug("Header read", event) jsonLogger.Debug("Header read", event)
}, },
) )
writeOps := operations.NewOperations( writeOps := operations.NewOperations(
backendConfig, backendConfig,
metadataConfig, metadataConfig,
pipeConfig, pipeConfig,
config.CryptoConfig{}, config.CryptoConfig{
Recipient: encryptionRecipient,
Identity: signatureIdentity,
Password: signaturePassword,
},
func(event *config.HeaderEvent) { func(event *config.HeaderEvent) {
l.Debug("Header write", event) jsonLogger.Debug("Header write", event)
}, },
) )
@@ -92,88 +223,136 @@ func createTestFss() (filesystems []afero.Fs, cleanup func() error, err error) {
Metadata: metadataPersister, Metadata: metadataPersister,
}, },
config.CompressionLevelFastest, compressionLevel,
func() (cache.WriteCache, func() error, error) { func() (cache.WriteCache, func() error, error) {
return cache.NewCacheWrite( return cache.NewCacheWrite(
writeCacheDir,
writeCache, writeCache,
config.WriteCacheTypeFile,
) )
}, },
false, false,
false, readOnly,
func(hdr *config.Header) { func(hdr *config.Header) {
l.Trace("Header transform", hdr) jsonLogger.Trace("Header transform", hdr)
}, },
l, jsonLogger,
) )
root, err := stfs.Initialize("/", os.ModePerm) root, err := stfs.Initialize("/", os.ModePerm)
if err != nil { if err != nil {
return nil, nil, err return nil, err
} }
fs, err := cache.NewCacheFilesystem( return cache.NewCacheFilesystem(
stfs, stfs,
root, root,
config.NoneKey, fileSystemCache,
0, fileSystemCacheDuration,
"", fileSystemCacheDir,
) )
}
type stfsConfig struct {
recordSize int
readOnly bool
signature string
encryption string
compression string
compressionLevel string
writeCache string
fileSystemCache string
fileSystemCacheDuration time.Duration
}
type fsConfig struct {
stfsConfig stfsConfig
fs afero.Fs
}
func createFss() ([]fsConfig, func() error, error) {
fss := []fsConfig{}
tmp, err := os.MkdirTemp(os.TempDir(), "stfs-test-*")
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
osfsDir := filepath.Join(tmp, "osfs")
if err := os.MkdirAll(osfsDir, os.ModePerm); err != nil { if err := os.MkdirAll(osfsDir, os.ModePerm); err != nil {
return nil, nil, err return nil, nil, err
} }
return []afero.Fs{ fss = append(fss, fsConfig{stfsConfig{}, afero.NewBasePathFs(afero.NewOsFs(), osfsDir)})
fs,
afero.NewBasePathFs(afero.NewOsFs(), osfsDir), for _, config := range stfsConfigs {
}, tmp, err := os.MkdirTemp(os.TempDir(), "stfs-test-*")
if err != nil {
return nil, nil, err
}
drive := filepath.Join(tmp, "drive.tar")
metadata := filepath.Join(tmp, "metadata.sqlite")
writeCacheDir := filepath.Join(tmp, "write-cache")
fileSystemCacheDir := filepath.Join(tmp, "filesystem-cache")
stfs, err := createSTFS(
drive,
metadata,
config.recordSize,
config.readOnly,
verbose,
config.signature,
signaturePassword,
config.encryption,
encryptionPassword,
config.compression,
config.compressionLevel,
config.writeCache,
writeCacheDir,
config.fileSystemCache,
fileSystemCacheDir,
config.fileSystemCacheDuration,
)
if err != nil {
return nil, nil, err
}
fss = append(fss, fsConfig{config, stfs})
}
return fss,
func() error { func() error {
return os.RemoveAll(tmp) return os.RemoveAll(tmp)
}, },
nil nil
} }
func getTestNameForFs(testName string, fsName string) string { func runForAllFss(t *testing.T, name string, action func(t *testing.T, fs fsConfig)) {
return testName + " (" + fsName + ")" fss, cleanup, err := createFss()
}
func TestSTFS_Name(t *testing.T) {
filesystems, cleanup, err := createTestFss()
if err != nil { if err != nil {
panic(err) panic(err)
} }
defer cleanup() defer cleanup()
tests := []struct { for _, fs := range fss {
name string t.Run(fmt.Sprintf(`%v for filesystem with config %v and name %v`, name, fs.stfsConfig, fs.fs.Name()), func(t *testing.T) {
f []afero.Fs t.Parallel()
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 { action(t, fs)
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)
}
})
}
} }
} }
@@ -206,41 +385,33 @@ func TestSTFS_Create(t *testing.T) {
} }
for _, tt := range tests { for _, tt := range tests {
filesystems, cleanup, err := createTestFss() runForAllFss(t, tt.name, func(t *testing.T, fs fsConfig) {
if err != nil { file, err := fs.fs.Create(tt.args.name)
panic(err) if (err != nil) != tt.wantErr {
} t.Errorf("%v.Create() error = %v, wantErr %v", fs.fs.Name(), err, tt.wantErr)
defer cleanup()
for _, f := range filesystems { return
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 := fs.fs.Stat(tt.args.name)
} if err != nil {
t.Errorf("%v.Stat() error = %v, wantErr %v", fs.fs.Name(), err, tt.wantErr)
want, err := f.Stat(tt.args.name) return
if err != nil { }
t.Errorf("%v.Stat() error = %v, wantErr %v", f.Name(), err, tt.wantErr)
return got, err := fs.fs.Stat(file.Name())
} if err != nil {
t.Errorf("%v.Stat() error = %v, wantErr %v", fs.fs.Name(), err, tt.wantErr)
got, err := f.Stat(file.Name()) return
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", fs.fs.Name(), got, want)
if !reflect.DeepEqual(got, want) { return
t.Errorf("%v.Create().Name() = %v, want %v", f.Name(), got, want) }
})
return
}
})
}
} }
} }