You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fs.go 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package test
  2. import (
  3. "os"
  4. . "gopkg.in/check.v1"
  5. . "gopkg.in/src-d/go-billy.v4"
  6. "gopkg.in/src-d/go-billy.v4/util"
  7. )
  8. // FilesystemSuite is a convenient test suite to validate any implementation of
  9. // billy.Filesystem
  10. type FilesystemSuite struct {
  11. FS Filesystem
  12. BasicSuite
  13. DirSuite
  14. SymlinkSuite
  15. TempFileSuite
  16. ChrootSuite
  17. }
  18. // NewFilesystemSuite returns a new FilesystemSuite based on the given fs.
  19. func NewFilesystemSuite(fs Filesystem) FilesystemSuite {
  20. s := FilesystemSuite{FS: fs}
  21. s.BasicSuite.FS = s.FS
  22. s.DirSuite.FS = s.FS
  23. s.SymlinkSuite.FS = s.FS
  24. s.TempFileSuite.FS = s.FS
  25. s.ChrootSuite.FS = s.FS
  26. return s
  27. }
  28. func (s *FilesystemSuite) TestSymlinkToDir(c *C) {
  29. err := s.FS.MkdirAll("dir", 0755)
  30. c.Assert(err, IsNil)
  31. err = s.FS.Symlink("dir", "link")
  32. c.Assert(err, IsNil)
  33. fi, err := s.FS.Stat("link")
  34. c.Assert(err, IsNil)
  35. c.Assert(fi.Name(), Equals, "link")
  36. c.Assert(fi.IsDir(), Equals, true)
  37. }
  38. func (s *FilesystemSuite) TestSymlinkReadDir(c *C) {
  39. err := util.WriteFile(s.FS, "dir/file", []byte("foo"), 0644)
  40. c.Assert(err, IsNil)
  41. err = s.FS.Symlink("dir", "link")
  42. c.Assert(err, IsNil)
  43. info, err := s.FS.ReadDir("link")
  44. c.Assert(err, IsNil)
  45. c.Assert(info, HasLen, 1)
  46. c.Assert(info[0].Size(), Equals, int64(3))
  47. c.Assert(info[0].IsDir(), Equals, false)
  48. c.Assert(info[0].Name(), Equals, "file")
  49. }
  50. func (s *FilesystemSuite) TestCreateWithExistantDir(c *C) {
  51. err := s.FS.MkdirAll("foo", 0644)
  52. c.Assert(err, IsNil)
  53. f, err := s.FS.Create("foo")
  54. c.Assert(err, NotNil)
  55. c.Assert(f, IsNil)
  56. }
  57. func (s *ChrootSuite) TestReadDirWithChroot(c *C) {
  58. files := []string{"foo", "bar", "qux/baz", "qux/qux"}
  59. for _, name := range files {
  60. err := util.WriteFile(s.FS, name, nil, 0644)
  61. c.Assert(err, IsNil)
  62. }
  63. qux, _ := s.FS.Chroot("/qux")
  64. info, err := qux.(Filesystem).ReadDir("/")
  65. c.Assert(err, IsNil)
  66. c.Assert(info, HasLen, 2)
  67. }
  68. func (s *FilesystemSuite) TestSymlinkWithChrootBasic(c *C) {
  69. qux, _ := s.FS.Chroot("/qux")
  70. err := util.WriteFile(qux, "file", nil, 0644)
  71. c.Assert(err, IsNil)
  72. err = qux.(Filesystem).Symlink("file", "link")
  73. c.Assert(err, IsNil)
  74. fi, err := qux.Stat("link")
  75. c.Assert(err, IsNil)
  76. c.Assert(fi.Name(), Equals, "link")
  77. fi, err = s.FS.Stat("qux/link")
  78. c.Assert(err, IsNil)
  79. c.Assert(fi.Name(), Equals, "link")
  80. }
  81. func (s *FilesystemSuite) TestSymlinkWithChrootCrossBounders(c *C) {
  82. qux, _ := s.FS.Chroot("/qux")
  83. util.WriteFile(s.FS, "file", []byte("foo"), customMode)
  84. err := qux.Symlink("../../file", "qux/link")
  85. c.Assert(err, Equals, nil)
  86. fi, err := qux.Stat("qux/link")
  87. c.Assert(fi, NotNil)
  88. c.Assert(err, Equals, nil)
  89. }
  90. func (s *FilesystemSuite) TestReadDirWithLink(c *C) {
  91. util.WriteFile(s.FS, "foo/bar", []byte("foo"), customMode)
  92. s.FS.Symlink("bar", "foo/qux")
  93. info, err := s.FS.ReadDir("/foo")
  94. c.Assert(err, IsNil)
  95. c.Assert(info, HasLen, 2)
  96. }
  97. func (s *FilesystemSuite) TestRemoveAllNonExistent(c *C) {
  98. c.Assert(util.RemoveAll(s.FS, "non-existent"), IsNil)
  99. }
  100. func (s *FilesystemSuite) TestRemoveAllEmptyDir(c *C) {
  101. c.Assert(s.FS.MkdirAll("empty", os.FileMode(0755)), IsNil)
  102. c.Assert(util.RemoveAll(s.FS, "empty"), IsNil)
  103. _, err := s.FS.Stat("empty")
  104. c.Assert(err, NotNil)
  105. c.Assert(os.IsNotExist(err), Equals, true)
  106. }
  107. func (s *FilesystemSuite) TestRemoveAll(c *C) {
  108. fnames := []string{
  109. "foo/1",
  110. "foo/2",
  111. "foo/bar/1",
  112. "foo/bar/2",
  113. "foo/bar/baz/1",
  114. "foo/bar/baz/qux/1",
  115. "foo/bar/baz/qux/2",
  116. "foo/bar/baz/qux/3",
  117. }
  118. for _, fname := range fnames {
  119. err := util.WriteFile(s.FS, fname, nil, 0644)
  120. c.Assert(err, IsNil)
  121. }
  122. c.Assert(util.RemoveAll(s.FS, "foo"), IsNil)
  123. for _, fname := range fnames {
  124. _, err := s.FS.Stat(fname)
  125. comment := Commentf("not removed: %s %s", fname, err)
  126. c.Assert(os.IsNotExist(err), Equals, true, comment)
  127. }
  128. }
  129. func (s *FilesystemSuite) TestRemoveAllRelative(c *C) {
  130. fnames := []string{
  131. "foo/1",
  132. "foo/2",
  133. "foo/bar/1",
  134. "foo/bar/2",
  135. "foo/bar/baz/1",
  136. "foo/bar/baz/qux/1",
  137. "foo/bar/baz/qux/2",
  138. "foo/bar/baz/qux/3",
  139. }
  140. for _, fname := range fnames {
  141. err := util.WriteFile(s.FS, fname, nil, 0644)
  142. c.Assert(err, IsNil)
  143. }
  144. c.Assert(util.RemoveAll(s.FS, "foo/bar/.."), IsNil)
  145. for _, fname := range fnames {
  146. _, err := s.FS.Stat(fname)
  147. comment := Commentf("not removed: %s %s", fname, err)
  148. c.Assert(os.IsNotExist(err), Equals, true, comment)
  149. }
  150. }
  151. func (s *FilesystemSuite) TestReadDir(c *C) {
  152. err := s.FS.MkdirAll("qux", 0644)
  153. c.Assert(err, IsNil)
  154. files := []string{"foo", "bar", "qux/baz", "qux/qux"}
  155. for _, name := range files {
  156. err := util.WriteFile(s.FS, name, nil, 0644)
  157. c.Assert(err, IsNil)
  158. }
  159. info, err := s.FS.ReadDir("/")
  160. c.Assert(err, IsNil)
  161. c.Assert(info, HasLen, 3)
  162. info, err = s.FS.ReadDir("/qux")
  163. c.Assert(err, IsNil)
  164. c.Assert(info, HasLen, 2)
  165. }