aboutsummaryrefslogtreecommitdiff
path: root/src/os
diff options
context:
space:
mode:
authorxieyuschen <xieyuschen@gmail.com>2024-09-30 13:53:09 +0800
committerGopher Robot <gobot@golang.org>2024-10-04 14:46:36 +0000
commiteae89f37db1ba00db7b1e6955cb7090541cb4103 (patch)
treee5de2629fc739a3168b0bdba169026bb0411a2e5 /src/os
parent726d898c92ed0159f283f324478d00f15419f476 (diff)
downloadgo-eae89f37db1ba00db7b1e6955cb7090541cb4103.tar.xz
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>
Diffstat (limited to 'src/os')
-rw-r--r--src/os/os_test.go124
-rwxr-xr-x[-rw-r--r--]src/os/testdata/dirfs/dir/x0
2 files changed, 91 insertions, 33 deletions
diff --git a/src/os/os_test.go b/src/os/os_test.go
index ad024b6fd0..122dfb5a66 100644
--- a/src/os/os_test.go
+++ b/src/os/os_test.go
@@ -3317,24 +3317,7 @@ func TestCopyFS(t *testing.T) {
if err := fstest.TestFS(tmpFsys, "a", "b", "dir/x"); err != nil {
t.Fatal("TestFS:", err)
}
- if err := fs.WalkDir(fsys, ".", func(path string, d fs.DirEntry, err error) error {
- 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 {
+ if err := verifyCopyFS(t, fsys, tmpFsys); err != nil {
t.Fatal("comparing two directories:", err)
}
@@ -3363,34 +3346,109 @@ func TestCopyFS(t *testing.T) {
if err := fstest.TestFS(tmpFsys, "william", "carl", "daVinci", "einstein", "dir/newton"); err != nil {
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 {
+ t.Fatal("comparing two directories:", err)
+ }
+
+ // Test whether CopyFS disallows copying for memory filesystem when there is any
+ // existing file in the destination directory.
+ if err := CopyFS(tmpDir, fsys); !errors.Is(err, fs.ErrExist) {
+ t.Errorf("CopyFS should have failed and returned error when there is"+
+ "any existing file in the destination directory (in memory filesystem), "+
+ "got: %v, expected any error that indicates <file exists>", err)
+ }
+}
+
+// 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
}
- data, err := fs.ReadFile(fsys, path)
+ fInfo, err := originFS.Open(path)
if err != nil {
return err
}
- newData, err := fs.ReadFile(tmpFsys, path)
+ 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 errors.New("file " + path + " contents differ")
+ return fmt.Errorf("file %q content is %s, want %s", path, newData, data)
}
- return nil
- }); err != nil {
- t.Fatal("comparing two directories:", err)
- }
- // Test whether CopyFS disallows copying for memory filesystem when there is any
- // existing file in the destination directory.
- if err := CopyFS(tmpDir, fsys); !errors.Is(err, fs.ErrExist) {
- t.Errorf("CopyFS should have failed and returned error when there is"+
- "any existing file in the destination directory (in memory filesystem), "+
- "got: %v, expected any error that indicates <file exists>", err)
- }
+ 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) {
diff --git a/src/os/testdata/dirfs/dir/x b/src/os/testdata/dirfs/dir/x
index e69de29bb2..e69de29bb2 100644..100755
--- a/src/os/testdata/dirfs/dir/x
+++ b/src/os/testdata/dirfs/dir/x