mirror of
https://github.com/restic/restic.git
synced 2024-09-12 05:58:36 +02:00
Since backend.ID is always a slice of constant length, use an array instead of a slice. Mostly, arrays behave as slices, except that an array cannot be nil, so use `*backend.ID` insteaf of `backend.ID` in places where the absence of an ID is possible (e.g. for the Subtree of a Node, which may not present when the node is a file node). This change allows to directly use backend.ID as the the key for a map, so that arbitrary data structures (e.g. a Set implemented as a map[backend.ID]struct{}) can easily be formed.
87 lines
1.8 KiB
Go
87 lines
1.8 KiB
Go
package restic_test
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/restic/restic"
|
|
"github.com/restic/restic/pipe"
|
|
. "github.com/restic/restic/test"
|
|
)
|
|
|
|
func TestWalkTree(t *testing.T) {
|
|
repo := SetupRepo()
|
|
defer TeardownRepo(repo)
|
|
|
|
dirs, err := filepath.Glob(TestWalkerPath)
|
|
OK(t, err)
|
|
|
|
// archive a few files
|
|
arch := restic.NewArchiver(repo)
|
|
sn, _, err := arch.Snapshot(nil, dirs, nil)
|
|
OK(t, err)
|
|
|
|
// flush repo, write all packs
|
|
OK(t, repo.Flush())
|
|
|
|
done := make(chan struct{})
|
|
|
|
// start tree walker
|
|
treeJobs := make(chan restic.WalkTreeJob)
|
|
go restic.WalkTree(repo, *sn.Tree, done, treeJobs)
|
|
|
|
// start filesystem walker
|
|
fsJobs := make(chan pipe.Job)
|
|
resCh := make(chan pipe.Result, 1)
|
|
|
|
f := func(string, os.FileInfo) bool {
|
|
return true
|
|
}
|
|
go pipe.Walk(dirs, f, done, fsJobs, resCh)
|
|
|
|
for {
|
|
// receive fs job
|
|
fsJob, fsChOpen := <-fsJobs
|
|
Assert(t, !fsChOpen || fsJob != nil,
|
|
"received nil job from filesystem: %v %v", fsJob, fsChOpen)
|
|
if fsJob != nil {
|
|
OK(t, fsJob.Error())
|
|
}
|
|
|
|
var path string
|
|
fsEntries := 1
|
|
switch j := fsJob.(type) {
|
|
case pipe.Dir:
|
|
path = j.Path()
|
|
fsEntries = len(j.Entries)
|
|
case pipe.Entry:
|
|
path = j.Path()
|
|
}
|
|
|
|
// receive tree job
|
|
treeJob, treeChOpen := <-treeJobs
|
|
treeEntries := 1
|
|
|
|
OK(t, treeJob.Error)
|
|
|
|
if treeJob.Tree != nil {
|
|
treeEntries = len(treeJob.Tree.Nodes)
|
|
}
|
|
|
|
Assert(t, fsChOpen == treeChOpen,
|
|
"one channel closed too early: fsChOpen %v, treeChOpen %v",
|
|
fsChOpen, treeChOpen)
|
|
|
|
if !fsChOpen || !treeChOpen {
|
|
break
|
|
}
|
|
|
|
Assert(t, filepath.Base(path) == filepath.Base(treeJob.Path),
|
|
"paths do not match: %q != %q", filepath.Base(path), filepath.Base(treeJob.Path))
|
|
|
|
Assert(t, fsEntries == treeEntries,
|
|
"wrong number of entries: %v != %v", fsEntries, treeEntries)
|
|
}
|
|
}
|