forked from TrueCloudLab/restic
restore: test restore only changed parts functionality
This commit is contained in:
parent
3ec28ff853
commit
1eccd6504b
2 changed files with 125 additions and 0 deletions
|
@ -10,6 +10,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -929,6 +930,13 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||||
"dirtest/file": "content: file2\n",
|
"dirtest/file": "content: file2\n",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Overwrite: OverwriteIfChanged,
|
||||||
|
Files: map[string]string{
|
||||||
|
"foo": "content: new\n",
|
||||||
|
"dirtest/file": "content: file2\n",
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Overwrite: OverwriteIfNewer,
|
Overwrite: OverwriteIfNewer,
|
||||||
Files: map[string]string{
|
Files: map[string]string{
|
||||||
|
@ -982,3 +990,88 @@ func TestRestorerOverwriteBehavior(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRestoreModified(t *testing.T) {
|
||||||
|
// overwrite files between snapshots and also change their filesize
|
||||||
|
snapshots := []Snapshot{
|
||||||
|
{
|
||||||
|
Nodes: map[string]Node{
|
||||||
|
"foo": File{Data: "content: foo\n", ModTime: time.Now()},
|
||||||
|
"bar": File{Data: "content: a\n", ModTime: time.Now()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Nodes: map[string]Node{
|
||||||
|
"foo": File{Data: "content: a\n", ModTime: time.Now()},
|
||||||
|
"bar": File{Data: "content: bar\n", ModTime: time.Now()},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := repository.TestRepository(t)
|
||||||
|
tempdir := filepath.Join(rtest.TempDir(t), "target")
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
for _, snapshot := range snapshots {
|
||||||
|
sn, id := saveSnapshot(t, repo, snapshot, noopGetGenericAttributes)
|
||||||
|
t.Logf("snapshot saved as %v", id.Str())
|
||||||
|
|
||||||
|
res := NewRestorer(repo, sn, Options{Overwrite: OverwriteIfChanged})
|
||||||
|
rtest.OK(t, res.RestoreTo(ctx, tempdir))
|
||||||
|
n, err := res.VerifyFiles(ctx, tempdir)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.Equals(t, 2, n, "unexpected number of verified files")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRestoreIfChanged(t *testing.T) {
|
||||||
|
origData := "content: foo\n"
|
||||||
|
modData := "content: bar\n"
|
||||||
|
rtest.Equals(t, len(modData), len(origData), "broken testcase")
|
||||||
|
snapshot := Snapshot{
|
||||||
|
Nodes: map[string]Node{
|
||||||
|
"foo": File{Data: origData, ModTime: time.Now()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := repository.TestRepository(t)
|
||||||
|
tempdir := filepath.Join(rtest.TempDir(t), "target")
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
sn, id := saveSnapshot(t, repo, snapshot, noopGetGenericAttributes)
|
||||||
|
t.Logf("snapshot saved as %v", id.Str())
|
||||||
|
|
||||||
|
res := NewRestorer(repo, sn, Options{})
|
||||||
|
rtest.OK(t, res.RestoreTo(ctx, tempdir))
|
||||||
|
|
||||||
|
// modify file but maintain size and timestamp
|
||||||
|
path := filepath.Join(tempdir, "foo")
|
||||||
|
f, err := os.OpenFile(path, os.O_RDWR, 0)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
fi, err := f.Stat()
|
||||||
|
rtest.OK(t, err)
|
||||||
|
_, err = f.Write([]byte(modData))
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.OK(t, f.Close())
|
||||||
|
var utimes = [...]syscall.Timespec{
|
||||||
|
syscall.NsecToTimespec(fi.ModTime().UnixNano()),
|
||||||
|
syscall.NsecToTimespec(fi.ModTime().UnixNano()),
|
||||||
|
}
|
||||||
|
rtest.OK(t, syscall.UtimesNano(path, utimes[:]))
|
||||||
|
|
||||||
|
for _, overwrite := range []OverwriteBehavior{OverwriteIfChanged, OverwriteAlways} {
|
||||||
|
res = NewRestorer(repo, sn, Options{Overwrite: overwrite})
|
||||||
|
rtest.OK(t, res.RestoreTo(ctx, tempdir))
|
||||||
|
data, err := os.ReadFile(path)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
if overwrite == OverwriteAlways {
|
||||||
|
// restore should notice the changed file content
|
||||||
|
rtest.Equals(t, origData, string(data), "expected original file content")
|
||||||
|
} else {
|
||||||
|
// restore should not have noticed the changed file content
|
||||||
|
rtest.Equals(t, modData, string(data), "expeced modified file content")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ package restorer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
@ -118,3 +119,34 @@ func TestRestorerProgressBar(t *testing.T) {
|
||||||
AllBytesSkipped: 0,
|
AllBytesSkipped: 0,
|
||||||
}, mock.s)
|
}, mock.s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRestorePermissions(t *testing.T) {
|
||||||
|
snapshot := Snapshot{
|
||||||
|
Nodes: map[string]Node{
|
||||||
|
"foo": File{Data: "content: foo\n", Mode: 0o600, ModTime: time.Now()},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
repo := repository.TestRepository(t)
|
||||||
|
tempdir := filepath.Join(rtest.TempDir(t), "target")
|
||||||
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
sn, id := saveSnapshot(t, repo, snapshot, noopGetGenericAttributes)
|
||||||
|
t.Logf("snapshot saved as %v", id.Str())
|
||||||
|
|
||||||
|
res := NewRestorer(repo, sn, Options{})
|
||||||
|
rtest.OK(t, res.RestoreTo(ctx, tempdir))
|
||||||
|
|
||||||
|
for _, overwrite := range []OverwriteBehavior{OverwriteIfChanged, OverwriteAlways} {
|
||||||
|
// tamper with permissions
|
||||||
|
path := filepath.Join(tempdir, "foo")
|
||||||
|
rtest.OK(t, os.Chmod(path, 0o700))
|
||||||
|
|
||||||
|
res = NewRestorer(repo, sn, Options{Overwrite: overwrite})
|
||||||
|
rtest.OK(t, res.RestoreTo(ctx, tempdir))
|
||||||
|
fi, err := os.Stat(path)
|
||||||
|
rtest.OK(t, err)
|
||||||
|
rtest.Equals(t, fs.FileMode(0o600), fi.Mode().Perm(), "unexpected permissions")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue