本文整理汇总了Golang中github.com/cmars/replican-sync/replican/treegen.New函数的典型用法代码示例。如果您正苦于以下问题:Golang New函数的具体用法?Golang New怎么用?Golang New使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了New函数的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: DoTestPatchRenameFileSameDir
func DoTestPatchRenameFileSameDir(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo", tg.F("bar", tg.B(42, 65537)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo", tg.F("baz", tg.B(42, 65537)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
assert.Equal(t, 1, len(patchPlan.Cmds))
rename, isRename := patchPlan.Cmds[0].(*Transfer)
assert.T(t, isRename)
assert.T(t, strings.HasSuffix(rename.From.Resolve(), filepath.Join("foo", "baz")))
assert.T(t, strings.HasSuffix(rename.To.Resolve(), filepath.Join("foo", "bar")))
}
示例2: DoTestPatchDepConflict
func DoTestPatchDepConflict(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.D("gloo",
tg.F("bloo", tg.B(99, 8192), tg.B(100, 10000)),
tg.D("groo",
tg.D("snoo",
tg.F("bar", tg.B(42, 65537))))))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.F("gloo", tg.B(99, 10000)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
assertNoRelocs(t, dstpath)
}
示例3: TestPatchPreserveKeeps
func TestPatchPreserveKeeps(t *testing.T) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.F("bar", tg.B(6806, 65536)),
tg.F("blop", tg.B(6806, 65536)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcStore, err := fs.NewLocalStore(srcpath)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.F("baz", tg.B(6806, 65536)),
tg.F("blop", tg.B(6806, 65536)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstStore, err := fs.NewLocalStore(dstpath)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
info, err := os.Stat(filepath.Join(dstpath, "foo", "bar"))
assert.T(t, err == nil && info != nil)
info, err = os.Stat(filepath.Join(dstpath, "foo", "blop"))
assert.T(t, err == nil && info != nil)
}
示例4: DoTestPatchAdd
func DoTestPatchAdd(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
files := []treegen.Generated{}
for i := 0; i < 10; i++ {
files = append(files, tg.F("", tg.B(int64(42*i), int64(500000*i))))
}
treeSpec := tg.D("foo", tg.D("bar", files...))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(filepath.Join(srcpath, "foo"), srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo", tg.D("bar"), tg.D("baz"))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(filepath.Join(dstpath, "foo"), dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
for _, cmd := range patchPlan.Cmds {
_, isSfd := cmd.(*SrcFileDownload)
assert.T(t, isSfd)
}
}
示例5: TestMatchAppend
// Test the matcher on a case where the source file has the same
// prefix as destination, but has been appended to.
func TestMatchAppend(t *testing.T) {
tg := treegen.New()
treeSpec := tg.F("bar", tg.B(42, 65537), tg.B(43, 65537))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
// Try indexing root dir as a file
srcFile, err := fs.IndexFile(srcpath)
assert.Tf(t, err != nil, "%v", err)
// Ok, for real this time
srcFile, err = fs.IndexFile(filepath.Join(srcpath, "bar"))
assert.Tf(t, err == nil, "%v", err)
assert.Equal(t, 17, len(srcFile.Blocks))
tg = treegen.New()
treeSpec = tg.F("bar", tg.B(42, 65537))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstFile, err := fs.IndexFile(filepath.Join(dstpath, "bar"))
assert.Equal(t, 9, len(dstFile.Blocks))
match, err := MatchFile(srcFile, filepath.Join(dstpath, "bar"))
assert.T(t, err == nil, "%v", err)
assert.Equal(t, 8, len(match.BlockMatches))
notMatched := match.NotMatched()
assert.Equal(t, 1, len(notMatched))
assert.Equal(t, int64(65536), notMatched[0].From)
assert.Equal(t, int64(65537+65537), notMatched[0].To)
}
示例6: TestPatchRenameScope
func TestPatchRenameScope(t *testing.T) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.F("bar", tg.B(6806, 65536)),
tg.F("baz", tg.B(6806, 65536)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcStore, err := fs.NewLocalStore(srcpath)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.F("baz", tg.B(6806, 65536)),
tg.F("blop", tg.B(6806, 65536)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstStore, err := fs.NewLocalStore(dstpath)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
srcDir, err := fs.IndexDir(srcpath)
assert.T(t, err == nil)
dstDir, err := fs.IndexDir(dstpath)
assert.T(t, err == nil)
assert.Equal(t, srcDir.Strong(), dstDir.Strong())
}
示例7: DoTestPatchFileAppend
func DoTestPatchFileAppend(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo", tg.F("bar", tg.B(42, 65537), tg.B(43, 65537)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo", tg.F("bar", tg.B(42, 65537)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
complete := false
for i, cmd := range patchPlan.Cmds {
switch {
case i == 0:
localTemp, isTemp := cmd.(*LocalTemp)
assert.T(t, isTemp)
assert.Equal(t, filepath.Join(dstpath, "foo", "bar"), localTemp.Path.Resolve())
case i >= 1 && i <= 8:
ltc, isLtc := cmd.(*LocalTempCopy)
assert.Tf(t, isLtc, "cmd %d", i)
assert.Equal(t, ltc.LocalOffset, ltc.TempOffset)
assert.Equal(t, int64(fs.BLOCKSIZE), ltc.Length)
assert.Equal(t, int64(0), ltc.LocalOffset%int64(fs.BLOCKSIZE))
case i == 9:
stc, isStc := cmd.(*SrcTempCopy)
assert.T(t, isStc)
assert.Equal(t, int64(65538), stc.Length)
case i == 10:
_, isRwt := cmd.(*ReplaceWithTemp)
assert.T(t, isRwt)
complete = true
case i > 10:
t.Fatalf("too many commands")
}
}
assert.T(t, complete, "missing expected number of commands")
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
srcRoot, errors := fs.IndexDir(srcpath, fs.NewMemRepo())
assert.Equalf(t, 0, len(errors), "%v", errors)
dstRoot, errors := fs.IndexDir(dstpath, fs.NewMemRepo())
assert.Equalf(t, 0, len(errors), "%v", errors)
assert.Equal(t, srcRoot.Info().Strong, dstRoot.Info().Strong)
}
示例8: TestClean
func TestClean(t *testing.T) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.D("bar",
tg.D("aleph",
tg.F("A", tg.B(42, 65537)),
tg.F("a", tg.B(42, 65537)))))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcStore, err := fs.NewLocalStore(srcpath)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.D("bar",
tg.D("aleph",
tg.F("A", tg.B(42, 65537)),
tg.F("a", tg.B(42, 65537))),
tg.D("beth",
tg.F("B", tg.B(43, 65537)),
tg.F("b", tg.B(43, 65537))),
tg.D("jimmy",
tg.F("G", tg.B(44, 65537)),
tg.F("g", tg.B(44, 65537)))),
tg.D("baz",
tg.D("uno",
tg.F("1", tg.B(1, 65537)),
tg.F("I", tg.B(1, 65537))),
tg.D("dos",
tg.F("2", tg.B(11, 65537)),
tg.F("II", tg.B(11, 65537))),
tg.D("tres",
tg.F("3", tg.B(111, 65537)),
tg.F("III", tg.B(111, 65537)))))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstStore, err := fs.NewLocalStore(dstpath)
assert.T(t, err == nil)
onePath := dstStore.Resolve(filepath.Join("foo", "baz", "uno", "1"))
_, err = os.Stat(onePath)
assert.Tf(t, err == nil, "%v", err)
patchPlan := NewPatchPlan(srcStore, dstStore)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil, "%v", failedCmd)
assert.Tf(t, err == nil, "%v", err)
errors := make(chan error, 10)
patchPlan.Clean(errors)
close(errors)
for err := range errors {
assert.Tf(t, err == nil, "%v", err)
}
onePath = dstStore.Resolve(filepath.Join("foo", "baz", "uno", "1"))
_, err = os.Stat(onePath)
assert.Tf(t, err != nil, "%v", err)
}
示例9: DoTestSetModeNew
func DoTestSetModeNew(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.D("bar",
tg.D("aleph",
tg.F("A", tg.B(42, 65537)),
tg.F("a", tg.B(42, 65537)))))
srcpath := treegen.TestTree(t, treeSpec)
os.Chmod(filepath.Join(srcpath, "foo", "bar", "aleph", "A"), 0765)
os.Chmod(filepath.Join(srcpath, "foo", "bar"), 0711)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo")
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil, "%v", failedCmd)
assert.Tf(t, err == nil, "%v", err)
errors := make(chan os.Error)
go func() {
patchPlan.Clean(errors)
close(errors)
}()
for err := range errors {
assert.Tf(t, err == nil, "%v", err)
}
errors = make(chan os.Error)
go func() {
patchPlan.SetMode(errors)
close(errors)
}()
for err := range errors {
assert.Tf(t, err == nil, "%v", err)
}
fileinfo, err := os.Stat(filepath.Join(dstpath, "foo", "bar", "aleph", "A"))
assert.T(t, fileinfo != nil)
assert.Equal(t, uint32(0765), fileinfo.Permission())
fileinfo, err = os.Stat(filepath.Join(dstpath, "foo", "bar"))
assert.T(t, fileinfo != nil)
assert.Equal(t, uint32(0711), fileinfo.Permission())
}
示例10: DoTestPatchRelocConflict
func DoTestPatchRelocConflict(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.D("gloo",
tg.F("bloo", tg.B(99, 99)),
tg.D("groo",
tg.D("snoo",
tg.F("bar", tg.B(42, 65537))))))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.F("gloo", tg.B(99, 99)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
assert.Equal(t, 3, len(patchPlan.Cmds))
for i, cmd := range patchPlan.Cmds {
switch i {
case 0:
conflict, is := cmd.(*Conflict)
assert.T(t, is)
assert.T(t, strings.HasSuffix(conflict.Path.RelPath, filepath.Join("foo", "gloo")))
case 1:
copy, is := cmd.(*Transfer)
assert.T(t, is)
assert.T(t, strings.HasSuffix(copy.From.Resolve(), filepath.Join("foo", "gloo")))
assert.T(t, strings.HasSuffix(copy.To.Resolve(), filepath.Join("foo", "gloo", "bloo")))
case 2:
copy, is := cmd.(*SrcFileDownload)
assert.T(t, is)
assert.Equal(t, "764b5f659f70e69d4a87fe6ed138af40be36c514", copy.SrcFile.Info().Strong)
}
}
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
assertNoRelocs(t, dstpath)
}
示例11: DoTestPatchRenameScope
func DoTestPatchRenameScope(t *testing.T, mkrepo repoMaker) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.F("bar", tg.B(6806, 65536)),
tg.F("baz", tg.B(6806, 65536)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcRepo := mkrepo(t)
defer srcRepo.Close()
srcStore, err := fs.NewLocalStore(srcpath, srcRepo)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo",
tg.F("baz", tg.B(6806, 65536)),
tg.F("blop", tg.B(6806, 65536)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstRepo := mkrepo(t)
defer dstRepo.Close()
dstStore, err := fs.NewLocalStore(dstpath, dstRepo)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
// The actual content of dst after the patch depends on
// which file the repo chooses when matching foo/bar
// to baz or blop in dst.
//
// If blop matches, it will get renamed to bar and the trees will
// become identical. However if baz matches, blop will be left in place.
srcDir, errors := fs.IndexDir(srcpath, fs.NewMemRepo())
assert.Equalf(t, 0, len(errors), "%v", errors)
dstDir, errors := fs.IndexDir(dstpath, fs.NewMemRepo())
assert.Equalf(t, 0, len(errors), "%v", errors)
for _, path := range []string{"foo/bar", "foo/baz"} {
srcNode, has := fs.Lookup(srcDir, path)
assert.T(t, has)
dstNode, has := fs.Lookup(dstDir, path)
assert.T(t, has)
assert.Equal(t,
srcNode.(fs.File).Info().Strong,
dstNode.(fs.File).Info().Strong)
}
}
示例12: TestPatchFileTruncate
// Test the patch planner on a case where the source file is a shorter,
// truncated version of the destination.
// Execute the patch plan and check both resulting trees are identical.
func TestPatchFileTruncate(t *testing.T) {
tg := treegen.New()
treeSpec := tg.D("foo", tg.F("bar", tg.B(42, 65537)))
srcpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(srcpath)
srcStore, err := fs.NewLocalStore(srcpath)
assert.T(t, err == nil)
tg = treegen.New()
treeSpec = tg.D("foo", tg.F("bar", tg.B(42, 65537), tg.B(43, 65537)))
dstpath := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(dstpath)
dstStore, err := fs.NewLocalStore(dstpath)
assert.T(t, err == nil)
patchPlan := NewPatchPlan(srcStore, dstStore)
// printPlan(patchPlan)
complete := false
for i, cmd := range patchPlan.Cmds {
switch {
case i == 0:
localTemp, isTemp := cmd.(*LocalTemp)
assert.T(t, isTemp)
assert.Equal(t, filepath.Join(dstpath, "foo", "bar"), localTemp.Path.Resolve())
case i >= 1 && i <= 8:
ltc, isLtc := cmd.(*LocalTempCopy)
assert.Tf(t, isLtc, "cmd %d", i)
assert.Equal(t, ltc.LocalOffset, ltc.TempOffset)
assert.Equal(t, int64(fs.BLOCKSIZE), ltc.Length)
assert.Equal(t, int64(0), ltc.LocalOffset%int64(fs.BLOCKSIZE))
case i == 9:
stc, isStc := cmd.(*SrcTempCopy)
assert.T(t, isStc)
assert.Equal(t, int64(1), stc.Length)
complete = true
case i > 10:
t.Fatalf("too many commands")
}
}
assert.T(t, complete, "missing expected number of commands")
failedCmd, err := patchPlan.Exec()
assert.Tf(t, failedCmd == nil && err == nil, "%v: %v", failedCmd, err)
srcRoot, _ := fs.IndexDir(srcpath)
dstRoot, _ := fs.IndexDir(dstpath)
assert.Equal(t, srcRoot.Strong(), dstRoot.Strong())
}
示例13: DoTestStoreRelPath
func DoTestStoreRelPath(t *testing.T, repo fs.NodeRepo) {
tg := treegen.New()
treeSpec := tg.D("foo", tg.F("bar", tg.B(42, 65537)))
path := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(path)
store, err := fs.NewLocalStore(path, repo)
assert.T(t, err == nil)
relFoo := store.RelPath(filepath.Join(path, "foo"))
assert.Equalf(t, "foo", relFoo, "'%v': not a foo", relFoo)
// Relocate bar
newBar, err := store.Relocate(filepath.Join(filepath.Join(path, "foo"), "bar"))
assert.T(t, err == nil)
// new bar's parent should still be foo
newBarParent, _ := filepath.Split(newBar)
newBarParent = strings.TrimRight(newBarParent, "/\\")
// old bar should not exist
_, err = os.Stat(filepath.Join(filepath.Join(path, "foo"), "bar"))
assert.T(t, err != nil)
foobar := filepath.Join("foo", "bar")
assert.Equal(t, newBar, store.Resolve(foobar), "reloc path %s != resolve foo/bar %s",
newBar, store.Resolve(foobar))
}
示例14: DoTestDirDescent
func DoTestDirDescent(t *testing.T, repo fs.NodeRepo) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.F("baobab", tg.B(91, 65537)),
tg.D("bar",
tg.D("aleph",
tg.F("a", tg.B(42, 65537)))),
tg.F("bar3003", tg.B(777, 65537)))
path := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(path)
dir, errors := fs.IndexDir(path, repo)
assert.Equalf(t, 0, len(errors), "%v", errors)
for _, fpath := range []string{
filepath.Join("foo", "baobab"),
filepath.Join("foo", "bar", "aleph", "a"),
filepath.Join("foo", "bar3003")} {
node, found := fs.Lookup(dir, fpath)
assert.Tf(t, found, "not found: %s", fpath)
_, isFile := node.(fs.File)
assert.T(t, isFile)
}
node, found := fs.Lookup(dir, filepath.Join("foo", "bar"))
assert.T(t, found)
_, isDir := node.(fs.Dir)
assert.T(t, isDir)
}
示例15: TestDirDescent
func TestDirDescent(t *testing.T) {
tg := treegen.New()
treeSpec := tg.D("foo",
tg.F("baobab", tg.B(91, 65537)),
tg.D("bar",
tg.D("aleph",
tg.F("a", tg.B(42, 65537)))),
tg.F("bar3003", tg.B(777, 65537)))
path := treegen.TestTree(t, treeSpec)
defer os.RemoveAll(path)
dir, err := IndexDir(path)
assert.T(t, err == nil)
for _, fpath := range []string{
filepath.Join("foo", "baobab"),
filepath.Join("foo", "bar", "aleph", "a"),
filepath.Join("foo", "bar3003")} {
node, found := dir.Resolve(fpath)
assert.Tf(t, found, "not found: %s", fpath)
_, isFile := node.(*File)
assert.T(t, isFile)
}
node, found := dir.Resolve(filepath.Join("foo", "bar"))
assert.T(t, found)
_, isDir := node.(*Dir)
assert.T(t, isDir)
}