Files
Charon/backend/internal/services/backup_service_wave7_test.go
2026-03-04 18:34:49 +00:00

98 lines
2.8 KiB
Go

package services
import (
"archive/zip"
"bytes"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/require"
)
func writeLargeZipEntry(t *testing.T, writer *zip.Writer, name string, sizeBytes int64) {
t.Helper()
entry, err := writer.Create(name)
require.NoError(t, err)
chunk := bytes.Repeat([]byte{0}, 1024*1024)
remaining := sizeBytes
for remaining > 0 {
toWrite := int64(len(chunk))
if remaining < toWrite {
toWrite = remaining
}
_, err := entry.Write(chunk[:toWrite])
require.NoError(t, err)
remaining -= toWrite
}
}
func TestBackupServiceWave7_CreateBackup_SnapshotFailureForNonSQLiteDB(t *testing.T) {
tmpDir := t.TempDir()
backupDir := filepath.Join(tmpDir, "backups")
require.NoError(t, os.MkdirAll(backupDir, 0o700))
dbPath := filepath.Join(tmpDir, "charon.db")
require.NoError(t, os.WriteFile(dbPath, []byte("not-a-sqlite-db"), 0o600))
svc := &BackupService{
DataDir: tmpDir,
BackupDir: backupDir,
DatabaseName: "charon.db",
}
_, err := svc.CreateBackup()
require.Error(t, err)
require.Contains(t, err.Error(), "create sqlite snapshot before backup")
}
func TestBackupServiceWave7_ExtractDatabaseFromBackup_DBEntryOverLimit(t *testing.T) {
tmpDir := t.TempDir()
zipPath := filepath.Join(tmpDir, "db-over-limit.zip")
zipFile, err := os.Create(zipPath) // #nosec G304 -- path is derived from t.TempDir()
require.NoError(t, err)
writer := zip.NewWriter(zipFile)
writeLargeZipEntry(t, writer, "charon.db", int64(101*1024*1024))
require.NoError(t, writer.Close())
require.NoError(t, zipFile.Close())
svc := &BackupService{DatabaseName: "charon.db"}
_, err = svc.extractDatabaseFromBackup(zipPath)
require.Error(t, err)
require.Contains(t, err.Error(), "extract database entry from backup archive")
require.Contains(t, err.Error(), "decompression limit")
}
func TestBackupServiceWave7_ExtractDatabaseFromBackup_WALEntryOverLimit(t *testing.T) {
tmpDir := t.TempDir()
dbPath := filepath.Join(tmpDir, "charon.db")
createSQLiteTestDB(t, dbPath)
zipPath := filepath.Join(tmpDir, "wal-over-limit.zip")
zipFile, err := os.Create(zipPath) // #nosec G304 -- path is derived from t.TempDir()
require.NoError(t, err)
writer := zip.NewWriter(zipFile)
dbBytes, err := os.ReadFile(dbPath) // #nosec G304 -- path is derived from t.TempDir()
require.NoError(t, err)
dbEntry, err := writer.Create("charon.db")
require.NoError(t, err)
_, err = dbEntry.Write(dbBytes)
require.NoError(t, err)
writeLargeZipEntry(t, writer, "charon.db-wal", int64(101*1024*1024))
require.NoError(t, writer.Close())
require.NoError(t, zipFile.Close())
svc := &BackupService{DatabaseName: "charon.db"}
_, err = svc.extractDatabaseFromBackup(zipPath)
require.Error(t, err)
require.Contains(t, err.Error(), "extract wal entry from backup archive")
require.Contains(t, err.Error(), "decompression limit")
}