@@ -530,97 +530,137 @@ func TestSymlinks(t *testing.T) {
530530 var fs absfs.SymlinkFileSystem
531531 fs = boltfs
532532
533- testdata := [][]string {
534-
535- // abs path
536- {"/foo/bar/baz/" , "/foo/baz" }, // /foo/bar/baz -> /foo/baz
537- {"/foo/baz/" }, // /foo/baz
533+ type Test struct {
534+ Label string
535+ Path string
536+ Readlink string
537+ Error string
538+ }
538539
539- // rel path
540- {"/foo/bar/bat/" , "../../bat" }, // /foo/bar/baz -> /foo/baz
541- {"/foo/bat/" },
540+ testdata := []Test {
541+ {
542+ Label : "abs path" ,
543+ Path : "/foo/bar/baz" ,
544+ Readlink : "/foo/baz" ,
545+ Error : "" ,
546+ },
547+ {
548+ Label : "rel path" ,
549+ Path : "/foo/bar/bat" ,
550+ Readlink : "../../bat" ,
551+ Error : "" ,
552+ },
553+ {
554+ Label : "same dir" ,
555+ Path : "/bat" ,
556+ Readlink : "/foo" ,
557+ Error : "" ,
558+ },
559+ {
560+ Label : "broken" ,
561+ Path : "/broken" ,
562+ Readlink : "/nil" ,
563+ Error : "file does not exist" ,
564+ },
565+ {
566+ Label : "circular absolute" ,
567+ Path : "/circular/one/two/three" ,
568+ Readlink : "/circular/one" ,
569+ Error : "" ,
570+ },
571+ {
572+ Label : "circular relative" ,
573+ Path : "/circular/one/two/four" ,
574+ Readlink : "../.." ,
575+ Error : "" ,
576+ },
577+ }
542578
543- // same dir
544- {"/bat/" , "/foo" }, // /bat -> /foo
579+ t .Run ("symlinks" , func (t * testing.T ) {
580+ //Path to test map to make testing a little easier
581+ linkmap := make (map [string ]Test )
545582
546- // broken
547- {"/broken/" , "/nil" }, // /broken ->
583+ // build directory structure, with all symlink targets
584+ for _ , test := range testdata {
585+ linkmap [test .Path ] = test
548586
549- // circular absolute
550- { "/circular/one/two/three/" , "/circular/one" }, // /broken -> /nil
587+ // folders in which files will be created
588+ fs . MkdirAll ( filepath . Dir ( test . Path ), 0700 )
551589
552- // circular relative
553- {"/circular/one/two/four/" , "../../" }, // /broken -> /nil
590+ link := test .Readlink
591+ if ! filepath .IsAbs (test .Readlink ) {
592+ link = filepath .Join (test .Path , test .Readlink )
593+ }
554594
555- }
595+ // folders that symlinks will link to
596+ fs .MkdirAll (link , 0700 )
556597
557- t .Run ("symlinks" , func (t * testing.T ) {
558- for _ , pathset := range testdata {
559- dir := filepath .Clean (pathset [0 ])
560- if len (pathset ) > 1 {
561- fs .MkdirAll (filepath .Clean (pathset [1 ]), 0700 )
562- dir = filepath .Dir (dir )
563- }
564- err := fs .MkdirAll (dir , 0700 )
565- if err != nil {
566- t .Logf ("%s (error: %v)\n " , dir , err )
567- t .Error (err )
568- }
569598 }
570- for _ , pathset := range testdata {
571- if len (pathset ) != 2 {
572- continue
573- }
574- source := filepath .Clean (pathset [1 ])
575- link := filepath .Clean (pathset [0 ])
576599
577- // t.Logf("Symlink %q %q\n", source, link)
578- err := boltfs .Symlink (source , link )
600+ // make symlinks
601+ for _ , test := range testdata {
602+
603+ // The result of "fs.Readlink" is esssentally the same as the `source`
604+ // value in a copy, so `test.Readlink` is the 'source', and
605+ // `test.Path` is a symbolic link to it (a.k.a the 'target')
606+ err := boltfs .Symlink (test .Readlink , test .Path )
579607 if err != nil {
580- t .Log ( err )
608+ t .Fatalf ( "should not error: %s" , err )
581609 }
582610 }
583611
612+ // remove the broken link target to break the link
584613 err := fs .Remove ("/nil" )
585614 if err != nil {
586615 t .Error (err )
587616 }
588617
589- i := 0
618+ // `count` and `limit` are to prevent infinite walks if implementation fails
619+ // to stop on symlinks as defined by `filepath.Walk`.
620+ var count , limit int
621+ limit = 100
622+
590623 err = boltfs .Walk ("/" , func (path string , info os.FileInfo , err error ) error {
624+ t .Log (path )
591625 link := ""
592626 if info .Mode ()& os .ModeSymlink != 0 {
593627 link , err = fs .Readlink (path )
594628 if err != nil {
595629 return err
596630 }
597- link = "-> " + link
631+ }
632+ if linkmap [path ].Readlink != link {
633+ t .Errorf ("expected symlink %q -> %q" , path , linkmap [path ])
598634 }
599635
600- // t.Logf("%s %s %s\n", info.Mode(), path, link)
601636 stat , err := fs .Stat (path )
602- if err != nil {
603- // t.Logf("fs.Stat err=%s", err)
637+ if len (linkmap [path ].Error ) == 0 {
638+ if err != nil {
639+ t .Errorf ("unexpected error %s" , err )
640+ }
641+ } else {
642+ if err == nil {
643+ t .Errorf ("expected error missing %s" , linkmap [path ].Error )
644+ }
604645 }
646+
605647 if stat != nil {
606- // t.Logf("Stat: %s %q %s", stat.Mode(), stat.Name(), link)
648+ t .Logf (" Stat: %s %q %s" , stat .Mode (), stat .Name (), link )
607649 } else {
608- // t.Logf("Stat: <nil>")
650+ t .Logf ("Stat: <nil>" )
609651 }
610652
611653 lstat , err := fs .Lstat (path )
612654 if err != nil {
613655 t .Errorf ("fs.Lstat error=%s" , err )
614656 }
615- _ = lstat
616- // if lstat != nil {
617- // t.Logf("Lstat: %s %q %s\n", lstat.Mode(), lstat.Name(), link)
618- // } else {
619- // t.Logf("Lstat: <nil>\n")
620- // }
621- // fmt.Printf("Lstat: %s %q %s\n\n", lstat.Mode(), lstat.Name(), link)
622- i ++
623- if i > 100 {
657+ if lstat != nil {
658+ t .Logf ("Lstat: %s %q %s\n " , lstat .Mode (), lstat .Name (), link )
659+ } else {
660+ t .Logf ("Lstat: <nil>\n " )
661+ }
662+ count ++
663+ if count > limit {
624664 return errors .New ("too deep" )
625665 }
626666 return nil
@@ -646,10 +686,3 @@ func TestSymlinks(t *testing.T) {
646686 }
647687
648688}
649-
650- // func (fs *FileSystem) Symlink(oldname, newname string) error
651- // func (fs *FileSystem) Readlink(name string) (string, error)
652- // func (fs *FileSystem) Lstat(name string) (os.FileInfo, error)
653- // func (fs *FileSystem) Lchown(name string, uid, gid int) error
654-
655- // func (fs *FileSystem) FastWalk(name string, fn func(string, os.FileMode) error) error
0 commit comments