package test import ( "os" . "gopkg.in/check.v1" . "gopkg.in/src-d/go-billy.v4" "gopkg.in/src-d/go-billy.v4/util" ) // ChrootSuite is a convenient test suite to validate any implementation of // billy.Chroot type ChrootSuite struct { FS interface { Basic Chroot } } func (s *ChrootSuite) TestCreateWithChroot(c *C) { fs, _ := s.FS.Chroot("foo") f, err := fs.Create("bar") c.Assert(err, IsNil) c.Assert(f.Close(), IsNil) c.Assert(f.Name(), Equals, "bar") f, err = s.FS.Open("foo/bar") c.Assert(err, IsNil) c.Assert(f.Name(), Equals, s.FS.Join("foo", "bar")) c.Assert(f.Close(), IsNil) } func (s *ChrootSuite) TestOpenWithChroot(c *C) { fs, _ := s.FS.Chroot("foo") f, err := fs.Create("bar") c.Assert(err, IsNil) c.Assert(f.Close(), IsNil) c.Assert(f.Name(), Equals, "bar") f, err = fs.Open("bar") c.Assert(err, IsNil) c.Assert(f.Name(), Equals, "bar") c.Assert(f.Close(), IsNil) } func (s *ChrootSuite) TestOpenOutOffBoundary(c *C) { err := util.WriteFile(s.FS, "bar", nil, 0644) c.Assert(err, IsNil) fs, _ := s.FS.Chroot("foo") f, err := fs.Open("../bar") c.Assert(err, Equals, ErrCrossedBoundary) c.Assert(f, IsNil) } func (s *ChrootSuite) TestStatOutOffBoundary(c *C) { err := util.WriteFile(s.FS, "bar", nil, 0644) c.Assert(err, IsNil) fs, _ := s.FS.Chroot("foo") f, err := fs.Stat("../bar") c.Assert(err, Equals, ErrCrossedBoundary) c.Assert(f, IsNil) } func (s *ChrootSuite) TestStatWithChroot(c *C) { files := []string{"foo", "bar", "qux/baz", "qux/qux"} for _, name := range files { err := util.WriteFile(s.FS, name, nil, 0644) c.Assert(err, IsNil) } // Some implementations detect directories based on a prefix // for all files; it's easy to miss path separator handling there. fi, err := s.FS.Stat("qu") c.Assert(os.IsNotExist(err), Equals, true, Commentf("error: %s", err)) c.Assert(fi, IsNil) fi, err = s.FS.Stat("qux") c.Assert(err, IsNil) c.Assert(fi.Name(), Equals, "qux") c.Assert(fi.IsDir(), Equals, true) qux, _ := s.FS.Chroot("qux") fi, err = qux.Stat("baz") c.Assert(err, IsNil) c.Assert(fi.Name(), Equals, "baz") c.Assert(fi.IsDir(), Equals, false) fi, err = qux.Stat("/baz") c.Assert(err, IsNil) c.Assert(fi.Name(), Equals, "baz") c.Assert(fi.IsDir(), Equals, false) } func (s *ChrootSuite) TestRenameOutOffBoundary(c *C) { err := util.WriteFile(s.FS, "foo/foo", nil, 0644) c.Assert(err, IsNil) err = util.WriteFile(s.FS, "bar", nil, 0644) c.Assert(err, IsNil) fs, _ := s.FS.Chroot("foo") err = fs.Rename("../bar", "foo") c.Assert(err, Equals, ErrCrossedBoundary) err = fs.Rename("foo", "../bar") c.Assert(err, Equals, ErrCrossedBoundary) } func (s *ChrootSuite) TestRemoveOutOffBoundary(c *C) { err := util.WriteFile(s.FS, "bar", nil, 0644) c.Assert(err, IsNil) fs, _ := s.FS.Chroot("foo") err = fs.Remove("../bar") c.Assert(err, Equals, ErrCrossedBoundary) } func (s *FilesystemSuite) TestRoot(c *C) { c.Assert(s.FS.Root(), Not(Equals), "") }