forked from TrueCloudLab/restic
1d2277b4c3
This also includes two derived options `--from-insecure-no-password` used for commands that require specifying a source repository. And `--new-insecure-no-password` for the `key add` and `key passwd` commands. Specifying `--insecure-no-password` disabled the password prompt and immediately uses an empty password. Passing a password via CLI option or environment variable at the same time is an error.
157 lines
4.8 KiB
Go
157 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
rtest "github.com/restic/restic/internal/test"
|
|
)
|
|
|
|
func testRunCopy(t testing.TB, srcGopts GlobalOptions, dstGopts GlobalOptions) {
|
|
gopts := srcGopts
|
|
gopts.Repo = dstGopts.Repo
|
|
gopts.password = dstGopts.password
|
|
gopts.InsecureNoPassword = dstGopts.InsecureNoPassword
|
|
copyOpts := CopyOptions{
|
|
secondaryRepoOptions: secondaryRepoOptions{
|
|
Repo: srcGopts.Repo,
|
|
password: srcGopts.password,
|
|
InsecureNoPassword: srcGopts.InsecureNoPassword,
|
|
},
|
|
}
|
|
|
|
rtest.OK(t, runCopy(context.TODO(), copyOpts, gopts, nil))
|
|
}
|
|
|
|
func TestCopy(t *testing.T) {
|
|
env, cleanup := withTestEnvironment(t)
|
|
defer cleanup()
|
|
env2, cleanup2 := withTestEnvironment(t)
|
|
defer cleanup2()
|
|
|
|
testSetupBackupData(t, env)
|
|
opts := BackupOptions{}
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, opts, env.gopts)
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "2")}, opts, env.gopts)
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
|
testRunCheck(t, env.gopts)
|
|
|
|
testRunInit(t, env2.gopts)
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
|
|
snapshotIDs := testListSnapshots(t, env.gopts, 3)
|
|
copiedSnapshotIDs := testListSnapshots(t, env2.gopts, 3)
|
|
|
|
// Check that the copies size seems reasonable
|
|
stat := dirStats(env.repo)
|
|
stat2 := dirStats(env2.repo)
|
|
sizeDiff := int64(stat.size) - int64(stat2.size)
|
|
if sizeDiff < 0 {
|
|
sizeDiff = -sizeDiff
|
|
}
|
|
rtest.Assert(t, sizeDiff < int64(stat.size)/50, "expected less than 2%% size difference: %v vs. %v",
|
|
stat.size, stat2.size)
|
|
|
|
// Check integrity of the copy
|
|
testRunCheck(t, env2.gopts)
|
|
|
|
// Check that the copied snapshots have the same tree contents as the old ones (= identical tree hash)
|
|
origRestores := make(map[string]struct{})
|
|
for i, snapshotID := range snapshotIDs {
|
|
restoredir := filepath.Join(env.base, fmt.Sprintf("restore%d", i))
|
|
origRestores[restoredir] = struct{}{}
|
|
testRunRestore(t, env.gopts, restoredir, snapshotID)
|
|
}
|
|
for i, snapshotID := range copiedSnapshotIDs {
|
|
restoredir := filepath.Join(env2.base, fmt.Sprintf("restore%d", i))
|
|
testRunRestore(t, env2.gopts, restoredir, snapshotID)
|
|
foundMatch := false
|
|
for cmpdir := range origRestores {
|
|
diff := directoriesContentsDiff(restoredir, cmpdir)
|
|
if diff == "" {
|
|
delete(origRestores, cmpdir)
|
|
foundMatch = true
|
|
}
|
|
}
|
|
|
|
rtest.Assert(t, foundMatch, "found no counterpart for snapshot %v", snapshotID)
|
|
}
|
|
|
|
rtest.Assert(t, len(origRestores) == 0, "found not copied snapshots")
|
|
}
|
|
|
|
func TestCopyIncremental(t *testing.T) {
|
|
env, cleanup := withTestEnvironment(t)
|
|
defer cleanup()
|
|
env2, cleanup2 := withTestEnvironment(t)
|
|
defer cleanup2()
|
|
|
|
testSetupBackupData(t, env)
|
|
opts := BackupOptions{}
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, opts, env.gopts)
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "2")}, opts, env.gopts)
|
|
testRunCheck(t, env.gopts)
|
|
|
|
testRunInit(t, env2.gopts)
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
|
|
testListSnapshots(t, env.gopts, 2)
|
|
testListSnapshots(t, env2.gopts, 2)
|
|
|
|
// Check that the copies size seems reasonable
|
|
testRunCheck(t, env2.gopts)
|
|
|
|
// check that no snapshots are copied, as there are no new ones
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
testRunCheck(t, env2.gopts)
|
|
testListSnapshots(t, env2.gopts, 2)
|
|
|
|
// check that only new snapshots are copied
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9", "3")}, opts, env.gopts)
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
testRunCheck(t, env2.gopts)
|
|
testListSnapshots(t, env.gopts, 3)
|
|
testListSnapshots(t, env2.gopts, 3)
|
|
|
|
// also test the reverse direction
|
|
testRunCopy(t, env2.gopts, env.gopts)
|
|
testRunCheck(t, env.gopts)
|
|
testListSnapshots(t, env.gopts, 3)
|
|
}
|
|
|
|
func TestCopyUnstableJSON(t *testing.T) {
|
|
env, cleanup := withTestEnvironment(t)
|
|
defer cleanup()
|
|
env2, cleanup2 := withTestEnvironment(t)
|
|
defer cleanup2()
|
|
|
|
// contains a symlink created using `ln -s '../i/'$'\355\246\361''d/samba' broken-symlink`
|
|
datafile := filepath.Join("testdata", "copy-unstable-json.tar.gz")
|
|
rtest.SetupTarTestFixture(t, env.base, datafile)
|
|
|
|
testRunInit(t, env2.gopts)
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
testRunCheck(t, env2.gopts)
|
|
testListSnapshots(t, env2.gopts, 1)
|
|
}
|
|
|
|
func TestCopyToEmptyPassword(t *testing.T) {
|
|
env, cleanup := withTestEnvironment(t)
|
|
defer cleanup()
|
|
env2, cleanup2 := withTestEnvironment(t)
|
|
defer cleanup2()
|
|
env2.gopts.password = ""
|
|
env2.gopts.InsecureNoPassword = true
|
|
|
|
testSetupBackupData(t, env)
|
|
testRunBackup(t, "", []string{filepath.Join(env.testdata, "0", "0", "9")}, BackupOptions{}, env.gopts)
|
|
|
|
testRunInit(t, env2.gopts)
|
|
testRunCopy(t, env.gopts, env2.gopts)
|
|
|
|
testListSnapshots(t, env.gopts, 1)
|
|
testListSnapshots(t, env2.gopts, 1)
|
|
testRunCheck(t, env2.gopts)
|
|
}
|