1package test 2 3import ( 4 "io/ioutil" 5 "os" 6 7 . "gopkg.in/check.v1" 8 . "gopkg.in/src-d/go-billy.v3" 9 "gopkg.in/src-d/go-billy.v3/util" 10) 11 12// SymlinkSuite is a convenient test suite to validate any implementation of 13// billy.Symlink 14type SymlinkSuite struct { 15 FS interface { 16 Basic 17 Symlink 18 } 19} 20 21func (s *SymlinkSuite) TestSymlink(c *C) { 22 err := util.WriteFile(s.FS, "file", nil, 0644) 23 c.Assert(err, IsNil) 24 25 err = s.FS.Symlink("file", "link") 26 c.Assert(err, IsNil) 27 28 fi, err := s.FS.Stat("link") 29 c.Assert(err, IsNil) 30 c.Assert(fi.Name(), Equals, "link") 31} 32 33func (s *SymlinkSuite) TestSymlinkCrossDirs(c *C) { 34 err := util.WriteFile(s.FS, "foo/file", nil, 0644) 35 c.Assert(err, IsNil) 36 37 err = s.FS.Symlink("../foo/file", "bar/link") 38 c.Assert(err, IsNil) 39 40 fi, err := s.FS.Stat("bar/link") 41 c.Assert(err, IsNil) 42 c.Assert(fi.Name(), Equals, "link") 43} 44 45func (s *SymlinkSuite) TestSymlinkNested(c *C) { 46 err := util.WriteFile(s.FS, "file", []byte("hello world!"), 0644) 47 c.Assert(err, IsNil) 48 49 err = s.FS.Symlink("file", "linkA") 50 c.Assert(err, IsNil) 51 52 err = s.FS.Symlink("linkA", "linkB") 53 c.Assert(err, IsNil) 54 55 fi, err := s.FS.Stat("linkB") 56 c.Assert(err, IsNil) 57 c.Assert(fi.Name(), Equals, "linkB") 58 c.Assert(fi.Size(), Equals, int64(12)) 59} 60 61func (s *SymlinkSuite) TestSymlinkWithNonExistentdTarget(c *C) { 62 err := s.FS.Symlink("file", "link") 63 c.Assert(err, IsNil) 64 65 _, err = s.FS.Stat("link") 66 c.Assert(os.IsNotExist(err), Equals, true) 67} 68 69func (s *SymlinkSuite) TestSymlinkWithExistingLink(c *C) { 70 err := util.WriteFile(s.FS, "link", nil, 0644) 71 c.Assert(err, IsNil) 72 73 err = s.FS.Symlink("file", "link") 74 c.Assert(err, Not(IsNil)) 75} 76 77func (s *SymlinkSuite) TestOpenWithSymlinkToRelativePath(c *C) { 78 err := util.WriteFile(s.FS, "dir/file", []byte("foo"), 0644) 79 c.Assert(err, IsNil) 80 81 err = s.FS.Symlink("file", "dir/link") 82 c.Assert(err, IsNil) 83 84 f, err := s.FS.Open("dir/link") 85 c.Assert(err, IsNil) 86 87 all, err := ioutil.ReadAll(f) 88 c.Assert(err, IsNil) 89 c.Assert(string(all), Equals, "foo") 90 c.Assert(f.Close(), IsNil) 91} 92 93func (s *SymlinkSuite) TestOpenWithSymlinkToAbsolutePath(c *C) { 94 err := util.WriteFile(s.FS, "dir/file", []byte("foo"), 0644) 95 c.Assert(err, IsNil) 96 97 err = s.FS.Symlink("/dir/file", "dir/link") 98 c.Assert(err, IsNil) 99 100 f, err := s.FS.Open("dir/link") 101 c.Assert(err, IsNil) 102 103 all, err := ioutil.ReadAll(f) 104 c.Assert(err, IsNil) 105 c.Assert(string(all), Equals, "foo") 106 c.Assert(f.Close(), IsNil) 107} 108 109func (s *SymlinkSuite) TestReadlink(c *C) { 110 err := util.WriteFile(s.FS, "file", nil, 0644) 111 c.Assert(err, IsNil) 112 113 _, err = s.FS.Readlink("file") 114 c.Assert(err, Not(IsNil)) 115} 116 117func (s *SymlinkSuite) TestReadlinkWithRelativePath(c *C) { 118 err := util.WriteFile(s.FS, "dir/file", nil, 0644) 119 c.Assert(err, IsNil) 120 121 err = s.FS.Symlink("file", "dir/link") 122 c.Assert(err, IsNil) 123 124 oldname, err := s.FS.Readlink("dir/link") 125 c.Assert(err, IsNil) 126 c.Assert(oldname, Equals, "file") 127} 128 129func (s *SymlinkSuite) TestReadlinkWithAbsolutePath(c *C) { 130 err := util.WriteFile(s.FS, "dir/file", nil, 0644) 131 c.Assert(err, IsNil) 132 133 err = s.FS.Symlink("/dir/file", "dir/link") 134 c.Assert(err, IsNil) 135 136 oldname, err := s.FS.Readlink("dir/link") 137 c.Assert(err, IsNil) 138 c.Assert(oldname, Equals, expectedSymlinkTarget) 139} 140 141func (s *SymlinkSuite) TestReadlinkWithNonExistentTarget(c *C) { 142 err := s.FS.Symlink("file", "link") 143 c.Assert(err, IsNil) 144 145 oldname, err := s.FS.Readlink("link") 146 c.Assert(err, IsNil) 147 c.Assert(oldname, Equals, "file") 148} 149 150func (s *SymlinkSuite) TestReadlinkWithNonExistentLink(c *C) { 151 _, err := s.FS.Readlink("link") 152 c.Assert(os.IsNotExist(err), Equals, true) 153} 154 155func (s *SymlinkSuite) TestStatLink(c *C) { 156 util.WriteFile(s.FS, "foo/bar", []byte("foo"), customMode) 157 s.FS.Symlink("bar", "foo/qux") 158 159 fi, err := s.FS.Stat("foo/qux") 160 c.Assert(err, IsNil) 161 c.Assert(fi.Name(), Equals, "qux") 162 c.Assert(fi.Size(), Equals, int64(3)) 163 c.Assert(fi.Mode(), Equals, customMode) 164 c.Assert(fi.ModTime().IsZero(), Equals, false) 165 c.Assert(fi.IsDir(), Equals, false) 166} 167 168func (s *SymlinkSuite) TestLstat(c *C) { 169 util.WriteFile(s.FS, "foo/bar", []byte("foo"), customMode) 170 171 fi, err := s.FS.Lstat("foo/bar") 172 c.Assert(err, IsNil) 173 c.Assert(fi.Name(), Equals, "bar") 174 c.Assert(fi.Size(), Equals, int64(3)) 175 c.Assert(fi.Mode()&os.ModeSymlink != 0, Equals, false) 176 c.Assert(fi.ModTime().IsZero(), Equals, false) 177 c.Assert(fi.IsDir(), Equals, false) 178} 179 180func (s *SymlinkSuite) TestLstatLink(c *C) { 181 util.WriteFile(s.FS, "foo/bar", []byte("fosddddaaao"), customMode) 182 s.FS.Symlink("bar", "foo/qux") 183 184 fi, err := s.FS.Lstat("foo/qux") 185 c.Assert(err, IsNil) 186 c.Assert(fi.Name(), Equals, "qux") 187 c.Assert(fi.Mode()&os.ModeSymlink != 0, Equals, true) 188 c.Assert(fi.ModTime().IsZero(), Equals, false) 189 c.Assert(fi.IsDir(), Equals, false) 190} 191 192func (s *SymlinkSuite) TestRenameWithSymlink(c *C) { 193 err := s.FS.Symlink("file", "link") 194 c.Assert(err, IsNil) 195 196 err = s.FS.Rename("link", "newlink") 197 c.Assert(err, IsNil) 198 199 _, err = s.FS.Readlink("newlink") 200 c.Assert(err, IsNil) 201} 202 203func (s *SymlinkSuite) TestRemoveWithSymlink(c *C) { 204 err := util.WriteFile(s.FS, "file", []byte("foo"), 0644) 205 c.Assert(err, IsNil) 206 207 err = s.FS.Symlink("file", "link") 208 c.Assert(err, IsNil) 209 210 err = s.FS.Remove("link") 211 c.Assert(err, IsNil) 212 213 _, err = s.FS.Readlink("link") 214 c.Assert(os.IsNotExist(err), Equals, true) 215 216 _, err = s.FS.Stat("link") 217 c.Assert(os.IsNotExist(err), Equals, true) 218 219 _, err = s.FS.Stat("file") 220 c.Assert(err, IsNil) 221} 222