From b3b30db0a2a2bf831f0245e303b85c76dea8de45 Mon Sep 17 00:00:00 2001 From: Winfried Plappert Date: Thu, 6 Mar 2025 16:38:24 +0000 Subject: [PATCH] restic backup and restic prune: more / modified tests cmd_prune_integration_test: testing for the exact error message cmd_backup_integration_test: two additional backup test with repository size monitoring TestBackupRepoSizeMonitorOnFirstBackup(): limit first backup on size, check error message TestBackupRepoSizeMonitorOnSecondBackup(): do a normal first backup and then limit second backup, so size is already exceeded on start of backup: check for error message. --- cmd/restic/cmd_backup_integration_test.go | 54 +++++++++++++++++++++++ cmd/restic/cmd_prune_integration_test.go | 8 ++-- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/cmd/restic/cmd_backup_integration_test.go b/cmd/restic/cmd_backup_integration_test.go index 06d71e345..cb35bc0dd 100644 --- a/cmd/restic/cmd_backup_integration_test.go +++ b/cmd/restic/cmd_backup_integration_test.go @@ -2,6 +2,7 @@ package main import ( "context" + "crypto/rand" "fmt" "io" "os" @@ -10,6 +11,7 @@ import ( "testing" "time" + "github.com/restic/restic/internal/backend" "github.com/restic/restic/internal/fs" "github.com/restic/restic/internal/restic" rtest "github.com/restic/restic/internal/test" @@ -723,3 +725,55 @@ func TestBackupSkipIfUnchanged(t *testing.T) { testRunCheck(t, env.gopts) } + +func TestBackupRepoSizeMonitorOnFirstBackup(t *testing.T) { + env, cleanup := withTestEnvironment(t) + defer cleanup() + + datafile := filepath.Join("testdata", "backup-data.tar.gz") + testRunInit(t, env.gopts) + + rtest.SetupTarTestFixture(t, env.testdata, datafile) + opts := BackupOptions{RepoMaxSize: "50k"} + + // create and delete snapshot to create unused blobs + oldHook := env.gopts.backendTestHook + env.gopts.backendTestHook = func(r backend.Backend) (backend.Backend, error) { return newListMultipleBackend(r), nil } + defer func() { + env.gopts.backendTestHook = oldHook + }() + err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{env.testdata}, opts, env.gopts) + rtest.Assert(t, err != nil && err.Error() == "Fatal: backup incomplete, repository capacity exceeded", + "failed as %q", err) +} + +func TestBackupRepoSizeMonitorOnSecondBackup(t *testing.T) { + env, cleanup := withTestEnvironment(t) + defer cleanup() + + datafile := filepath.Join("testdata", "backup-data.tar.gz") + testRunInit(t, env.gopts) + + rtest.SetupTarTestFixture(t, env.testdata, datafile) + opts := BackupOptions{} + + // backup #1 + testRunBackup(t, filepath.Dir(env.testdata), []string{env.testdata}, opts, env.gopts) + testListSnapshots(t, env.gopts, 1) + + // insert new file into backup structure (8k) + createRandomDataFile(t, filepath.Join(env.testdata, "0", "0", "9", "rand.data")) + + // backup #2 + opts = BackupOptions{RepoMaxSize: "1k"} + err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{env.testdata}, opts, env.gopts) + rtest.Assert(t, err != nil && err.Error() == "Fatal: repository maximum size already exceeded", + "failed as %q", err) +} + +// make a random file, large enough to exceed backup size limit +func createRandomDataFile(t *testing.T, path string) { + randomData := make([]byte, 8*1024) + _, _ = rand.Read(randomData) + rtest.OK(t, os.WriteFile(path, randomData, 0600)) +} diff --git a/cmd/restic/cmd_prune_integration_test.go b/cmd/restic/cmd_prune_integration_test.go index 95b0c8e4a..77320622e 100644 --- a/cmd/restic/cmd_prune_integration_test.go +++ b/cmd/restic/cmd_prune_integration_test.go @@ -256,10 +256,10 @@ func TestPruneSizeMonitoring(t *testing.T) { env.gopts.backendTestHook = oldHook }() err := testRunBackupAssumeFailure(t, filepath.Dir(env.testdata), []string{env.testdata}, opts, env.gopts) - rtest.Assert(t, err != nil, "backup should have ended in failure '%v'", err) - firstSnapshot := testListSnapshots(t, env.gopts, 1)[0] - t.Logf("first snapshot %v", firstSnapshot) + rtest.Assert(t, err != nil && err.Error() == "Fatal: backup incomplete, repository capacity exceeded", + "failed as %q", err) + testListSnapshots(t, env.gopts, 1) testRunPrune(t, env.gopts, PruneOptions{MaxUnused: "0"}) - _ = testListSnapshots(t, env.gopts, 0) + testListSnapshots(t, env.gopts, 0) }