98 lines
2.8 KiB
Go
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")
|
|
}
|