mirror of https://github.com/restic/restic.git
Test pipe walker for invalid paths
It was discovered that when restic is instructed to save `/`, the tree structures in the repository contain an invalid node. When saving the dir `/home/user`, the following structure is created: snapshot -> tree nodes: ["user"] [...] When the root directory `/` is saved, the structure is as follows: snapshot -> tree nodes: ["/"] [...] This behavior is caused by the walker in pipe.go sending a node with the name "." to the archiver, so this commit adds a test for invalid node names.
This commit is contained in:
parent
0535490618
commit
604c27f001
|
@ -4,6 +4,7 @@ import (
|
|||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -421,6 +422,7 @@ func TestPipelineWalkerMultiple(t *testing.T) {
|
|||
}
|
||||
|
||||
paths, err := filepath.Glob(filepath.Join(TestWalkerPath, "*"))
|
||||
OK(t, err)
|
||||
|
||||
before, err := statPath(TestWalkerPath)
|
||||
OK(t, err)
|
||||
|
@ -491,3 +493,95 @@ func TestPipelineWalkerMultiple(t *testing.T) {
|
|||
|
||||
Assert(t, before == after, "stats do not match, expected %v, got %v", before, after)
|
||||
}
|
||||
|
||||
func dirsInPath(path string) int {
|
||||
if path == "/" || path == "." || path == "" {
|
||||
return 0
|
||||
}
|
||||
|
||||
n := 0
|
||||
for dir := path; dir != "/" && dir != "."; dir = filepath.Dir(dir) {
|
||||
n++
|
||||
}
|
||||
|
||||
return n
|
||||
}
|
||||
|
||||
func TestPipeWalkerRoot(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skipf("not running TestPipeWalkerRoot on %s", runtime.GOOS)
|
||||
return
|
||||
}
|
||||
|
||||
cwd, err := os.Getwd()
|
||||
OK(t, err)
|
||||
|
||||
testPaths := []string{
|
||||
string(filepath.Separator),
|
||||
".",
|
||||
cwd,
|
||||
}
|
||||
|
||||
for _, path := range testPaths {
|
||||
testPipeWalkerRootWithPath(path, t)
|
||||
}
|
||||
}
|
||||
|
||||
func testPipeWalkerRootWithPath(path string, t *testing.T) {
|
||||
pattern := filepath.Join(path, "*")
|
||||
rootPaths, err := filepath.Glob(pattern)
|
||||
OK(t, err)
|
||||
|
||||
for i, p := range rootPaths {
|
||||
rootPaths[i], err = filepath.Rel(path, p)
|
||||
OK(t, err)
|
||||
}
|
||||
|
||||
t.Logf("paths in %v (pattern %q) expanded to %v items", path, pattern, len(rootPaths))
|
||||
|
||||
done := make(chan struct{})
|
||||
defer close(done)
|
||||
|
||||
jobCh := make(chan pipe.Job)
|
||||
var jobs []pipe.Job
|
||||
|
||||
worker := func(wg *sync.WaitGroup) {
|
||||
defer wg.Done()
|
||||
for job := range jobCh {
|
||||
jobs = append(jobs, job)
|
||||
}
|
||||
}
|
||||
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go worker(&wg)
|
||||
|
||||
filter := func(p string, fi os.FileInfo) bool {
|
||||
p, err := filepath.Rel(path, p)
|
||||
OK(t, err)
|
||||
return dirsInPath(p) <= 1
|
||||
}
|
||||
|
||||
resCh := make(chan pipe.Result, 1)
|
||||
pipe.Walk([]string{path}, filter, done, jobCh, resCh)
|
||||
|
||||
wg.Wait()
|
||||
|
||||
t.Logf("received %d jobs", len(jobs))
|
||||
|
||||
for i, job := range jobs[:len(jobs)-1] {
|
||||
path := job.Path()
|
||||
if path == "." || path == ".." || path == string(filepath.Separator) {
|
||||
t.Errorf("job %v has invalid path %q", i, path)
|
||||
}
|
||||
}
|
||||
|
||||
lastPath := jobs[len(jobs)-1].Path()
|
||||
if lastPath != "" {
|
||||
t.Errorf("last job has non-empty path %q", lastPath)
|
||||
}
|
||||
|
||||
if len(jobs) < len(rootPaths) {
|
||||
t.Errorf("want at least %v jobs, got %v for path %v\n", len(rootPaths), len(jobs), path)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue