1
0
mirror of https://github.com/golang/go synced 2024-11-14 23:00:29 -07:00

os: check permissions of CopyFS copied files

CopyFS stipulates the permissions of the created files,
we should test them in the unit test.

* chmod x for testdata/x to test CopyFS for executable

* check the files permissions to ensure CopyFS follows the stipulated
  convention

Change-Id: Id13a8ad920ad0c1ff4b801dec3bfa6869cb3101f
Reviewed-on: https://go-review.googlesource.com/c/go/+/616615
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
xieyuschen 2024-09-30 13:53:09 +08:00 committed by Gopher Robot
parent 726d898c92
commit eae89f37db
2 changed files with 94 additions and 36 deletions

View File

@ -3317,24 +3317,7 @@ func TestCopyFS(t *testing.T) {
if err := fstest.TestFS(tmpFsys, "a", "b", "dir/x"); err != nil { if err := fstest.TestFS(tmpFsys, "a", "b", "dir/x"); err != nil {
t.Fatal("TestFS:", err) t.Fatal("TestFS:", err)
} }
if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { if err := verifyCopyFS(t, fsys, tmpFsys); err != nil {
if d.IsDir() {
return nil
}
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
newData, err := fs.ReadFile(tmpFsys, path)
if err != nil {
return err
}
if !bytes.Equal(data, newData) {
return errors.New("file " + path + " contents differ")
}
return nil
}); err != nil {
t.Fatal("comparing two directories:", err) t.Fatal("comparing two directories:", err)
} }
@ -3363,24 +3346,7 @@ func TestCopyFS(t *testing.T) {
if err := fstest.TestFS(tmpFsys, "william", "carl", "daVinci", "einstein", "dir/newton"); err != nil { if err := fstest.TestFS(tmpFsys, "william", "carl", "daVinci", "einstein", "dir/newton"); err != nil {
t.Fatal("TestFS:", err) t.Fatal("TestFS:", err)
} }
if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error { if err := verifyCopyFS(t, fsys, tmpFsys); err != nil {
if d.IsDir() {
return nil
}
data, err := fs.ReadFile(fsys, path)
if err != nil {
return err
}
newData, err := fs.ReadFile(tmpFsys, path)
if err != nil {
return err
}
if !bytes.Equal(data, newData) {
return errors.New("file " + path + " contents differ")
}
return nil
}); err != nil {
t.Fatal("comparing two directories:", err) t.Fatal("comparing two directories:", err)
} }
@ -3393,6 +3359,98 @@ func TestCopyFS(t *testing.T) {
} }
} }
// verifyCopyFS checks the content and permission of each file inside copied FS to ensure
// the copied files satisfy the convention stipulated in CopyFS.
func verifyCopyFS(t *testing.T, originFS, copiedFS fs.FS) error {
testDir := filepath.Join(t.TempDir(), "test")
// umask doesn't apply to the wasip and windows and there is no general way to get masked perm,
// so create a dir and a file to compare the permission after umask if any
if err := Mkdir(testDir, ModePerm); err != nil {
return fmt.Errorf("mkdir %q failed: %v", testDir, err)
}
dirStat, err := Stat(testDir)
if err != nil {
return fmt.Errorf("stat dir %q failed: %v", testDir, err)
}
wantDirMode := dirStat.Mode()
f, err := Create(filepath.Join(testDir, "tmp"))
if err != nil {
return fmt.Errorf("open %q failed: %v", filepath.Join(testDir, "tmp"), err)
}
defer f.Close()
wantFileRWStat, err := f.Stat()
if err != nil {
return fmt.Errorf("stat file %q failed: %v", f.Name(), err)
}
return fs.WalkDir(originFS, ".", func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
// the dir . is not the dir created by CopyFS so skip checking its permission
if d.Name() == "." {
return nil
}
dinfo, err := fs.Stat(copiedFS, path)
if err != nil {
return err
}
if dinfo.Mode() != wantDirMode {
return fmt.Errorf("dir %q mode is %v, want %v",
d.Name(), dinfo.Mode(), wantDirMode)
}
return nil
}
fInfo, err := originFS.Open(path)
if err != nil {
return err
}
defer fInfo.Close()
copiedInfo, err := copiedFS.Open(path)
if err != nil {
return err
}
defer copiedInfo.Close()
// verify the file contents are the same
data, err := io.ReadAll(fInfo)
if err != nil {
return err
}
newData, err := io.ReadAll(copiedInfo)
if err != nil {
return err
}
if !bytes.Equal(data, newData) {
return fmt.Errorf("file %q content is %s, want %s", path, newData, data)
}
fStat, err := fInfo.Stat()
if err != nil {
return err
}
copiedStat, err := copiedInfo.Stat()
if err != nil {
return err
}
// check whether the execute permission is inherited from original FS
if copiedStat.Mode()&0111 != fStat.Mode()&0111 {
return fmt.Errorf("file %q execute mode is %v, want %v",
path, copiedStat.Mode()&0111, fStat.Mode()&0111)
}
rwMode := copiedStat.Mode() &^ 0111 // unset the executable permission from file mode
if rwMode != wantFileRWStat.Mode() {
return fmt.Errorf("file %q rw mode is %v, want %v",
path, rwMode, wantFileRWStat.Mode())
}
return nil
})
}
func TestCopyFSWithSymlinks(t *testing.T) { func TestCopyFSWithSymlinks(t *testing.T) {
// Test it with absolute and relative symlinks that point inside and outside the tree. // Test it with absolute and relative symlinks that point inside and outside the tree.
testenv.MustHaveSymlink(t) testenv.MustHaveSymlink(t)

0
src/os/testdata/dirfs/dir/x vendored Normal file → Executable file
View File