Borg/pkg/trix/trix_test.go

238 lines
5.3 KiB
Go

package trix
import (
"testing"
"github.com/Snider/Borg/pkg/datanode"
)
func TestDeriveKey(t *testing.T) {
// Test key length
key := DeriveKey("password")
if len(key) != 32 {
t.Errorf("DeriveKey() returned key of length %d, want 32", len(key))
}
// Same password should produce same key
key2 := DeriveKey("password")
for i := range key {
if key[i] != key2[i] {
t.Error("DeriveKey() not deterministic")
break
}
}
// Different password should produce different key
key3 := DeriveKey("different")
same := true
for i := range key {
if key[i] != key3[i] {
same = false
break
}
}
if same {
t.Error("DeriveKey() produced same key for different passwords")
}
}
func TestToTrix(t *testing.T) {
t.Run("without password", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrix(dn, "")
if err != nil {
t.Fatalf("ToTrix() error = %v", err)
}
// Verify magic number
if len(data) < 4 || string(data[:4]) != "TRIX" {
t.Errorf("Expected magic 'TRIX', got '%s'", string(data[:4]))
}
})
t.Run("with password", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrix(dn, "secret")
if err != nil {
t.Fatalf("ToTrix() error = %v", err)
}
// Verify magic number
if len(data) < 4 || string(data[:4]) != "TRIX" {
t.Errorf("Expected magic 'TRIX', got '%s'", string(data[:4]))
}
})
}
func TestFromTrix(t *testing.T) {
t.Run("without password round-trip", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrix(dn, "")
if err != nil {
t.Fatalf("ToTrix() error = %v", err)
}
restored, err := FromTrix(data, "")
if err != nil {
t.Fatalf("FromTrix() error = %v", err)
}
// Verify file exists
file, err := restored.Open("test.txt")
if err != nil {
t.Fatalf("Failed to open test.txt: %v", err)
}
defer file.Close()
})
t.Run("with password returns error", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrix(dn, "")
if err != nil {
t.Fatalf("ToTrix() error = %v", err)
}
// FromTrix with password should return error (decryption disabled)
_, err = FromTrix(data, "password")
if err == nil {
t.Error("Expected error when providing password to FromTrix")
}
})
t.Run("invalid data", func(t *testing.T) {
_, err := FromTrix([]byte("invalid"), "")
if err == nil {
t.Error("Expected error for invalid data")
}
})
}
func TestToTrixChaCha(t *testing.T) {
t.Run("success", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrixChaCha(dn, "password")
if err != nil {
t.Fatalf("ToTrixChaCha() error = %v", err)
}
// Verify magic number
if len(data) < 4 || string(data[:4]) != "TRIX" {
t.Errorf("Expected magic 'TRIX', got '%s'", string(data[:4]))
}
})
t.Run("empty password", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
_, err := ToTrixChaCha(dn, "")
if err != ErrPasswordRequired {
t.Errorf("Expected ErrPasswordRequired, got %v", err)
}
})
}
func TestFromTrixChaCha(t *testing.T) {
t.Run("round-trip", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
dn.AddData("subdir/nested.txt", []byte("Nested content"))
password := "testpassword123"
// Encrypt
data, err := ToTrixChaCha(dn, password)
if err != nil {
t.Fatalf("ToTrixChaCha() error = %v", err)
}
// Decrypt
restored, err := FromTrixChaCha(data, password)
if err != nil {
t.Fatalf("FromTrixChaCha() error = %v", err)
}
// Verify files exist
file, err := restored.Open("test.txt")
if err != nil {
t.Fatalf("Failed to open test.txt: %v", err)
}
file.Close()
file, err = restored.Open("subdir/nested.txt")
if err != nil {
t.Fatalf("Failed to open subdir/nested.txt: %v", err)
}
file.Close()
})
t.Run("empty password", func(t *testing.T) {
_, err := FromTrixChaCha([]byte("data"), "")
if err != ErrPasswordRequired {
t.Errorf("Expected ErrPasswordRequired, got %v", err)
}
})
t.Run("wrong password", func(t *testing.T) {
dn := datanode.New()
dn.AddData("test.txt", []byte("Hello, World!"))
data, err := ToTrixChaCha(dn, "correct")
if err != nil {
t.Fatalf("ToTrixChaCha() error = %v", err)
}
_, err = FromTrixChaCha(data, "wrong")
if err == nil {
t.Error("Expected error with wrong password")
}
})
t.Run("invalid data", func(t *testing.T) {
_, err := FromTrixChaCha([]byte("invalid"), "password")
if err == nil {
t.Error("Expected error for invalid data")
}
})
}
func TestToTrixChaChaWithLargeData(t *testing.T) {
dn := datanode.New()
// Add large file
largeData := make([]byte, 1024*1024) // 1MB
for i := range largeData {
largeData[i] = byte(i % 256)
}
dn.AddData("large.bin", largeData)
password := "largetest"
// Encrypt
data, err := ToTrixChaCha(dn, password)
if err != nil {
t.Fatalf("ToTrixChaCha() error = %v", err)
}
// Decrypt
restored, err := FromTrixChaCha(data, password)
if err != nil {
t.Fatalf("FromTrixChaCha() error = %v", err)
}
// Verify file exists
_, err = restored.Open("large.bin")
if err != nil {
t.Fatalf("Failed to open large.bin: %v", err)
}
}