项目文件夹

文件
wehub-resource-sync 75f3dd141c
CodeQL / Analyze (go) (push) Has been cancelled
CodeQL / Analyze (actions) (push) Has been cancelled
CodeQL / Analyze (javascript-typescript) (push) Has been cancelled
CI and Release / lint-frontend (push) Has been cancelled
CI and Release / dockerfile-scan (push) Has been cancelled
CI and Release / test-frontend (push) Has been cancelled
CI and Release / lint-verification-agent (push) Has been cancelled
CI and Release / test-verification-agent (push) Has been cancelled
CI and Release / e2e-verification-agent (push) Has been cancelled
CI and Release / test-backend (push) Has been cancelled
CI and Release / build-dev-image (push) Has been cancelled
CI and Release / push-dev-image (push) Has been cancelled
CI and Release / build-image (push) Has been cancelled
CI and Release / build-verification-image (push) Has been cancelled
CI and Release / determine-version (push) Has been cancelled
CI and Release / push-image (push) Has been cancelled
CI and Release / push-verification-image (12) (push) Has been cancelled
CI and Release / lint-backend (push) Has been cancelled
CI and Release / push-verification-image (17) (push) Has been cancelled
CI and Release / push-verification-image (18) (push) Has been cancelled
CI and Release / release (push) Has been cancelled
CI and Release / publish-helm-chart (push) Has been cancelled
CI and Release / push-verification-image (13) (push) Has been cancelled
CI and Release / push-verification-image (14) (push) Has been cancelled
CI and Release / push-verification-image (15) (push) Has been cancelled
CI and Release / push-verification-image (16) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:11:07 +08:00

351 行
9.5 KiB
Go

package backups_config_physical
import (
"testing"
"github.com/stretchr/testify/assert"
backups_core_enums "databasus-backend/internal/features/backups/backups/core/enums"
postgresql_physical "databasus-backend/internal/features/databases/databases/postgresql/physical"
"databasus-backend/internal/features/intervals"
)
func dailyAt(hhmm string) intervals.Interval {
return intervals.Interval{
Type: intervals.IntervalDaily,
TimeOfDay: new(hhmm),
}
}
func hourly() intervals.Interval {
return intervals.Interval{Type: intervals.IntervalHourly}
}
func weeklyMondayAt(hhmm string) intervals.Interval {
return intervals.Interval{
Type: intervals.IntervalWeekly,
Weekday: new(1),
TimeOfDay: new(hhmm),
}
}
func validFullOnlyConfig() *PhysicalBackupConfig {
return &PhysicalBackupConfig{
IsBackupsEnabled: true,
FullBackupInterval: dailyAt("02:00"),
Retention: RetentionFullBackups,
FullBackupsRetention: FullBackupsRetention{
Policy: FullBackupsRetentionPolicyGfs,
GfsDays: 7,
},
Encryption: backups_core_enums.BackupEncryptionNone,
PostgresqlPhysical: &postgresql_physical.PostgresqlPhysicalDatabase{
BackupType: postgresql_physical.BackupTypeFullOnly,
},
}
}
func validFullIncrementalConfig() *PhysicalBackupConfig {
return &PhysicalBackupConfig{
IsBackupsEnabled: true,
FullBackupInterval: weeklyMondayAt("02:00"),
IncrementalBackupInterval: dailyAt("02:00"),
Retention: RetentionChains,
ChainsRetention: ChainsRetention{Count: 3},
Encryption: backups_core_enums.BackupEncryptionNone,
PostgresqlPhysical: &postgresql_physical.PostgresqlPhysicalDatabase{
BackupType: postgresql_physical.BackupTypeFullAndIncremental,
},
}
}
func validFullIncrementalWalStreamConfig() *PhysicalBackupConfig {
return &PhysicalBackupConfig{
IsBackupsEnabled: true,
FullBackupInterval: weeklyMondayAt("02:00"),
IncrementalBackupInterval: dailyAt("02:00"),
Retention: RetentionChains,
ChainsRetention: ChainsRetention{Count: 3},
WalLagThresholdBytes: 16 * 1024 * 1024,
Encryption: backups_core_enums.BackupEncryptionNone,
PostgresqlPhysical: &postgresql_physical.PostgresqlPhysicalDatabase{
BackupType: postgresql_physical.BackupTypeFullIncrementalAndWalStream,
},
}
}
func Test_Validate_RejectsBlankFullBackupInterval(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupInterval = intervals.Interval{}
assert.Error(t, c.Validate())
}
func Test_Validate_RejectsUnknownEncryption(t *testing.T) {
c := validFullOnlyConfig()
c.Encryption = "GIBBERISH"
assert.Error(t, c.Validate())
}
func Test_Validate_RejectsNegativeWalLagThreshold(t *testing.T) {
c := validFullIncrementalWalStreamConfig()
c.WalLagThresholdBytes = -1
assert.Error(t, c.Validate())
}
func Test_Validate_FullOnly_RejectsIncrementalIntervalSet(t *testing.T) {
c := validFullOnlyConfig()
c.IncrementalBackupInterval = hourly()
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "incremental")
}
func Test_Validate_FullOnly_AcceptsFullBackupsLastN(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyLastN,
Count: 5,
}
assert.NoError(t, c.Validate())
}
func Test_Validate_FullOnly_AcceptsFullBackupsGfs(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyGfs,
GfsDays: 7,
}
assert.NoError(t, c.Validate())
}
func Test_Validate_FullOnly_RejectsChainsRetention(t *testing.T) {
c := validFullOnlyConfig()
c.Retention = RetentionChains
c.ChainsRetention = ChainsRetention{Count: 3}
c.FullBackupsRetention = FullBackupsRetention{}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "FULL_ONLY")
}
func Test_Validate_FullOnly_RejectsChainsAndFullBackupsRetention(t *testing.T) {
c := validFullOnlyConfig()
c.Retention = RetentionChainsAndFullBackups
c.ChainsRetention = ChainsRetention{Count: 3}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "FULL_ONLY")
}
func Test_Validate_FullOnly_RejectsWalLagThresholdSet(t *testing.T) {
c := validFullOnlyConfig()
c.WalLagThresholdBytes = 1024
assert.Error(t, c.Validate())
}
func Test_Validate_FullIncremental_RejectsBlankIncrementalInterval(t *testing.T) {
c := validFullIncrementalConfig()
c.IncrementalBackupInterval = intervals.Interval{}
assert.Error(t, c.Validate())
}
func Test_Validate_FullIncremental_RejectsIncrementalCadenceEqualToFull(t *testing.T) {
c := validFullIncrementalConfig()
c.FullBackupInterval = dailyAt("02:00")
c.IncrementalBackupInterval = dailyAt("12:00")
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "more frequent")
}
func Test_Validate_FullIncremental_RejectsIncrementalCadenceLargerThanFull(t *testing.T) {
c := validFullIncrementalConfig()
c.FullBackupInterval = hourly()
c.IncrementalBackupInterval = dailyAt("02:00")
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "more frequent")
}
func Test_Validate_FullIncremental_AcceptsChainsRetention(t *testing.T) {
c := validFullIncrementalConfig()
c.Retention = RetentionChains
c.ChainsRetention = ChainsRetention{Count: 3}
c.FullBackupsRetention = FullBackupsRetention{}
assert.NoError(t, c.Validate())
}
func Test_Validate_FullIncremental_AcceptsChainsAndFullBackupsRetention(t *testing.T) {
c := validFullIncrementalConfig()
c.Retention = RetentionChainsAndFullBackups
c.ChainsRetention = ChainsRetention{Count: 3}
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyGfs,
GfsWeeks: 4,
}
assert.NoError(t, c.Validate())
}
func Test_Validate_FullIncremental_RejectsFullBackupsOnlyRetention(t *testing.T) {
c := validFullIncrementalConfig()
c.Retention = RetentionFullBackups
c.ChainsRetention = ChainsRetention{}
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyLastN,
Count: 5,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "CHAINS")
}
func Test_Validate_FullIncremental_RejectsWalLagThresholdSet(t *testing.T) {
c := validFullIncrementalConfig()
c.WalLagThresholdBytes = 1024
assert.Error(t, c.Validate())
}
func Test_Validate_RejectsChainsRetentionWithZeroCount(t *testing.T) {
c := validFullIncrementalConfig()
c.Retention = RetentionChains
c.ChainsRetention = ChainsRetention{Count: 0}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "chains_retention.count")
}
func Test_Validate_RejectsChainsRetentionWithFullBackupsFieldsSet(t *testing.T) {
c := validFullIncrementalConfig()
c.Retention = RetentionChains
c.ChainsRetention = ChainsRetention{Count: 3}
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyLastN,
Count: 5,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "full_backups_retention")
}
func Test_Validate_RejectsFullBackupsLastNWithZeroCount(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyLastN,
Count: 0,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "count > 0")
}
func Test_Validate_RejectsFullBackupsLastNWithGfsBucketsSet(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyLastN,
Count: 5,
GfsDays: 3,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "GFS buckets")
}
func Test_Validate_RejectsFullBackupsGfsWithAllZeroBuckets(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyGfs,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "bucket")
}
func Test_Validate_RejectsFullBackupsGfsWithCountSet(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: FullBackupsRetentionPolicyGfs,
Count: 3,
GfsDays: 7,
}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "count")
}
func Test_Validate_RejectsFullBackupsRetentionWithChainsCountSet(t *testing.T) {
c := validFullOnlyConfig()
c.ChainsRetention = ChainsRetention{Count: 3}
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "chains_retention")
}
func Test_Validate_RejectsUnknownRetention(t *testing.T) {
c := validFullOnlyConfig()
c.Retention = "GIBBERISH"
assert.Error(t, c.Validate())
}
func Test_Validate_RejectsUnknownFullBackupsPolicy(t *testing.T) {
c := validFullOnlyConfig()
c.FullBackupsRetention = FullBackupsRetention{
Policy: "GIBBERISH",
GfsDays: 7,
}
assert.Error(t, c.Validate())
}
func Test_Validate_FullIncrementalWalStream_RejectsZeroWalLagThreshold(t *testing.T) {
c := validFullIncrementalWalStreamConfig()
c.WalLagThresholdBytes = 0
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "wal lag threshold")
}
func Test_Validate_FullIncrementalWalStream_AcceptsValidConfig(t *testing.T) {
assert.NoError(t, validFullIncrementalWalStreamConfig().Validate())
}
func Test_Validate_RejectsUnknownBackupType(t *testing.T) {
c := validFullOnlyConfig()
c.PostgresqlPhysical.BackupType = "GIBBERISH"
assert.Error(t, c.Validate())
}
func Test_Validate_RejectsMissingPostgresqlPhysicalPreload(t *testing.T) {
c := validFullOnlyConfig()
c.PostgresqlPhysical = nil
err := c.Validate()
assert.Error(t, err)
assert.Contains(t, err.Error(), "preloaded")
}