M3: add unit tests for config resolution and cryptsetup helpers
Tests cover: alias resolution (exact match, device path match, unknown, empty methods default), AliasFor lookup, Load with missing/valid YAML, MapperName generation, and token plugin directory detection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
128
internal/config/config_test.go
Normal file
128
internal/config/config_test.go
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestResolveDevice_ExactAlias(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
Devices: map[string]DeviceConfig{
|
||||||
|
"backup": {UUID: "abc-123", Methods: []string{"fido2", "passphrase"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r := cfg.ResolveDevice("backup")
|
||||||
|
if r.UUID != "abc-123" {
|
||||||
|
t.Errorf("UUID = %q, want %q", r.UUID, "abc-123")
|
||||||
|
}
|
||||||
|
if len(r.Methods) != 2 || r.Methods[0] != "fido2" {
|
||||||
|
t.Errorf("Methods = %v, want [fido2 passphrase]", r.Methods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveDevice_DevicePathMatch(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
Devices: map[string]DeviceConfig{
|
||||||
|
"sda1": {UUID: "abc-123", Methods: []string{"passphrase"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r := cfg.ResolveDevice("/dev/sda1")
|
||||||
|
if r.UUID != "abc-123" {
|
||||||
|
t.Errorf("UUID = %q, want %q", r.UUID, "abc-123")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveDevice_UnknownReturnsDefaults(t *testing.T) {
|
||||||
|
cfg := &Config{Devices: map[string]DeviceConfig{}}
|
||||||
|
r := cfg.ResolveDevice("nonexistent")
|
||||||
|
if r.UUID != "" {
|
||||||
|
t.Errorf("UUID = %q, want empty", r.UUID)
|
||||||
|
}
|
||||||
|
if len(r.Methods) != 1 || r.Methods[0] != "passphrase" {
|
||||||
|
t.Errorf("Methods = %v, want [passphrase]", r.Methods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResolveDevice_EmptyMethodsDefaultsToPassphrase(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
Devices: map[string]DeviceConfig{
|
||||||
|
"backup": {UUID: "abc-123"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
r := cfg.ResolveDevice("backup")
|
||||||
|
if len(r.Methods) != 1 || r.Methods[0] != "passphrase" {
|
||||||
|
t.Errorf("Methods = %v, want [passphrase]", r.Methods)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAliasFor_Found(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
Devices: map[string]DeviceConfig{
|
||||||
|
"backup": {UUID: "abc-123"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if alias := cfg.AliasFor("abc-123"); alias != "backup" {
|
||||||
|
t.Errorf("AliasFor = %q, want %q", alias, "backup")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAliasFor_NotFound(t *testing.T) {
|
||||||
|
cfg := &Config{
|
||||||
|
Devices: map[string]DeviceConfig{
|
||||||
|
"backup": {UUID: "abc-123"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if alias := cfg.AliasFor("unknown"); alias != "" {
|
||||||
|
t.Errorf("AliasFor = %q, want empty", alias)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoad_MissingFile(t *testing.T) {
|
||||||
|
// Point XDG_CONFIG_HOME to a temp dir with no config.
|
||||||
|
tmp := t.TempDir()
|
||||||
|
t.Setenv("XDG_CONFIG_HOME", tmp)
|
||||||
|
|
||||||
|
cfg := Load()
|
||||||
|
if cfg == nil {
|
||||||
|
t.Fatal("Load returned nil")
|
||||||
|
}
|
||||||
|
if len(cfg.Devices) != 0 {
|
||||||
|
t.Errorf("Devices = %v, want empty", cfg.Devices)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoad_ValidYAML(t *testing.T) {
|
||||||
|
tmp := t.TempDir()
|
||||||
|
dir := filepath.Join(tmp, "arca")
|
||||||
|
os.MkdirAll(dir, 0o755)
|
||||||
|
os.WriteFile(filepath.Join(dir, "config.yaml"), []byte(`
|
||||||
|
devices:
|
||||||
|
backup:
|
||||||
|
uuid: "abc-123"
|
||||||
|
mountpoint: "/mnt/backup"
|
||||||
|
methods:
|
||||||
|
- fido2
|
||||||
|
- passphrase
|
||||||
|
keyfile: "/path/to/key"
|
||||||
|
`), 0o644)
|
||||||
|
t.Setenv("XDG_CONFIG_HOME", tmp)
|
||||||
|
|
||||||
|
cfg := Load()
|
||||||
|
dev, ok := cfg.Devices["backup"]
|
||||||
|
if !ok {
|
||||||
|
t.Fatal("device 'backup' not found in config")
|
||||||
|
}
|
||||||
|
if dev.UUID != "abc-123" {
|
||||||
|
t.Errorf("UUID = %q, want %q", dev.UUID, "abc-123")
|
||||||
|
}
|
||||||
|
if dev.Mountpoint != "/mnt/backup" {
|
||||||
|
t.Errorf("Mountpoint = %q, want %q", dev.Mountpoint, "/mnt/backup")
|
||||||
|
}
|
||||||
|
if len(dev.Methods) != 2 {
|
||||||
|
t.Errorf("Methods = %v, want 2 entries", dev.Methods)
|
||||||
|
}
|
||||||
|
if dev.Keyfile != "/path/to/key" {
|
||||||
|
t.Errorf("Keyfile = %q, want %q", dev.Keyfile, "/path/to/key")
|
||||||
|
}
|
||||||
|
}
|
||||||
48
internal/cryptsetup/cryptsetup_test.go
Normal file
48
internal/cryptsetup/cryptsetup_test.go
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
package cryptsetup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMapperName(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"/dev/sda1", "arca-sda1"},
|
||||||
|
{"/dev/nvme0n1p2", "arca-nvme0n1p2"},
|
||||||
|
{"/dev/dm-0", "arca-dm-0"},
|
||||||
|
{"sda1", "arca-sda1"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
got := MapperName(tt.input)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("MapperName(%q) = %q, want %q", tt.input, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasTokenPlugins_WithPlugins(t *testing.T) {
|
||||||
|
tmp := t.TempDir()
|
||||||
|
os.WriteFile(filepath.Join(tmp, "libcryptsetup-token-systemd-fido2.so"), []byte("fake"), 0o644)
|
||||||
|
|
||||||
|
if !hasTokenPlugins(tmp) {
|
||||||
|
t.Error("hasTokenPlugins returned false for dir with plugin")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasTokenPlugins_EmptyDir(t *testing.T) {
|
||||||
|
tmp := t.TempDir()
|
||||||
|
|
||||||
|
if hasTokenPlugins(tmp) {
|
||||||
|
t.Error("hasTokenPlugins returned true for empty dir")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHasTokenPlugins_NonexistentDir(t *testing.T) {
|
||||||
|
if hasTokenPlugins("/nonexistent/path") {
|
||||||
|
t.Error("hasTokenPlugins returned true for nonexistent dir")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user