1- package fsutil_test
1+ package fsutil
22
33import (
4+ "io/fs"
45 "os"
56 "path/filepath"
67 "testing"
78
89 "github.com/stretchr/testify/require"
9-
10- "github.com/operator-framework/operator-controller/internal/fsutil"
1110)
1211
1312func TestEnsureEmptyDirectory (t * testing.T ) {
@@ -16,7 +15,7 @@ func TestEnsureEmptyDirectory(t *testing.T) {
1615 dirPerms := os .FileMode (0755 )
1716
1817 t .Log ("Ensure directory is created with the correct perms if it does not already exist" )
19- require .NoError (t , fsutil . EnsureEmptyDirectory (dirPath , dirPerms ))
18+ require .NoError (t , EnsureEmptyDirectory (dirPath , dirPerms ))
2019
2120 stat , err := os .Stat (dirPath )
2221 require .NoError (t , err )
@@ -25,15 +24,16 @@ func TestEnsureEmptyDirectory(t *testing.T) {
2524
2625 t .Log ("Create a file inside directory" )
2726 file := filepath .Join (dirPath , "file1" )
28- // nolint:gosec
29- require .NoError (t , os .WriteFile (file , []byte ("test" ), 0640 ))
27+ // write file as read-only to verify EnsureEmptyDirectory can still delete it.
28+ require .NoError (t , os .WriteFile (file , []byte ("test" ), 0400 ))
3029
3130 t .Log ("Create a sub-directory inside directory" )
3231 subDir := filepath .Join (dirPath , "subdir" )
33- require .NoError (t , os .Mkdir (subDir , dirPerms ))
32+ // write subDir as read-execute-only to verify EnsureEmptyDirectory can still delete it.
33+ require .NoError (t , os .Mkdir (subDir , 0500 ))
3434
3535 t .Log ("Call EnsureEmptyDirectory against directory with different permissions" )
36- require .NoError (t , fsutil . EnsureEmptyDirectory (dirPath , 0640 ))
36+ require .NoError (t , EnsureEmptyDirectory (dirPath , 0640 ))
3737
3838 t .Log ("Ensure directory is now empty" )
3939 entries , err := os .ReadDir (dirPath )
@@ -45,3 +45,97 @@ func TestEnsureEmptyDirectory(t *testing.T) {
4545 require .NoError (t , err )
4646 require .Equal (t , dirPerms , stat .Mode ().Perm ())
4747}
48+
49+ func TestSetReadOnlyRecursive (t * testing.T ) {
50+ tempDir := t .TempDir ()
51+ targetFilePath := filepath .Join (tempDir , "target" )
52+ nestedDir := filepath .Join (tempDir , "nested" )
53+ filePath := filepath .Join (nestedDir , "testfile" )
54+ symlinkPath := filepath .Join (nestedDir , "symlink" )
55+
56+ t .Log ("Create symlink target file outside directory with its own permissions" )
57+ // nolint:gosec
58+ require .NoError (t , os .WriteFile (targetFilePath , []byte ("something" ), 0644 ))
59+
60+ t .Log ("Create a nested directory structure that contains a file and sym. link" )
61+ require .NoError (t , os .Mkdir (nestedDir , ownerWritableDirMode ))
62+ require .NoError (t , os .WriteFile (filePath , []byte ("test" ), ownerWritableFileMode ))
63+ require .NoError (t , os .Symlink (targetFilePath , symlinkPath ))
64+
65+ t .Log ("Set directory structure as read-only" )
66+ require .NoError (t , SetReadOnlyRecursive (nestedDir ))
67+
68+ t .Log ("Check file permissions" )
69+ stat , err := os .Stat (filePath )
70+ require .NoError (t , err )
71+ require .Equal (t , ownerReadOnlyFileMode , stat .Mode ().Perm ())
72+
73+ t .Log ("Check directory permissions" )
74+ nestedStat , err := os .Stat (nestedDir )
75+ require .NoError (t , err )
76+ require .Equal (t , ownerReadOnlyDirMode , nestedStat .Mode ().Perm ())
77+
78+ t .Log ("Check symlink target file permissions - should not be affected" )
79+ stat , err = os .Stat (targetFilePath )
80+ require .NoError (t , err )
81+ require .Equal (t , fs .FileMode (0644 ), stat .Mode ().Perm ())
82+
83+ t .Log ("Make directory writable to enable test clean-up" )
84+ require .NoError (t , SetWritableRecursive (tempDir ))
85+ }
86+
87+ func TestSetWritableRecursive (t * testing.T ) {
88+ tempDir := t .TempDir ()
89+ targetFilePath := filepath .Join (tempDir , "target" )
90+ nestedDir := filepath .Join (tempDir , "nested" )
91+ filePath := filepath .Join (nestedDir , "testfile" )
92+ symlinkPath := filepath .Join (nestedDir , "symlink" )
93+
94+ t .Log ("Create symlink target file outside directory with its own permissions" )
95+ // nolint:gosec
96+ require .NoError (t , os .WriteFile (targetFilePath , []byte ("something" ), 0644 ))
97+
98+ t .Log ("Create a nested directory (writable) structure that contains a file (read-only) and sym. link" )
99+ require .NoError (t , os .Mkdir (nestedDir , ownerWritableDirMode ))
100+ require .NoError (t , os .WriteFile (filePath , []byte ("test" ), ownerReadOnlyFileMode ))
101+ require .NoError (t , os .Symlink (targetFilePath , symlinkPath ))
102+
103+ t .Log ("Make directory read-only" )
104+ require .NoError (t , os .Chmod (nestedDir , ownerReadOnlyDirMode ))
105+
106+ t .Log ("Call SetWritableRecursive" )
107+ require .NoError (t , SetWritableRecursive (nestedDir ))
108+
109+ t .Log ("Check file is writable" )
110+ stat , err := os .Stat (filePath )
111+ require .NoError (t , err )
112+ require .Equal (t , ownerWritableFileMode , stat .Mode ().Perm ())
113+
114+ t .Log ("Check directory is writable" )
115+ nestedStat , err := os .Stat (nestedDir )
116+ require .NoError (t , err )
117+ require .Equal (t , ownerWritableDirMode , nestedStat .Mode ().Perm ())
118+
119+ t .Log ("Check symlink target file permissions - should not be affected" )
120+ stat , err = os .Stat (targetFilePath )
121+ require .NoError (t , err )
122+ require .Equal (t , fs .FileMode (0644 ), stat .Mode ().Perm ())
123+ }
124+
125+ func TestDeleteReadOnlyRecursive (t * testing.T ) {
126+ tempDir := t .TempDir ()
127+ nestedDir := filepath .Join (tempDir , "nested" )
128+ filePath := filepath .Join (nestedDir , "testfile" )
129+
130+ t .Log ("Create a nested read-only directory structure that contains a file and sym. link" )
131+ require .NoError (t , os .Mkdir (nestedDir , ownerWritableDirMode ))
132+ require .NoError (t , os .WriteFile (filePath , []byte ("test" ), ownerReadOnlyFileMode ))
133+ require .NoError (t , os .Chmod (nestedDir , ownerReadOnlyDirMode ))
134+
135+ t .Log ("Set directory structure as read-only via DeleteReadOnlyRecursive" )
136+ require .NoError (t , DeleteReadOnlyRecursive (nestedDir ))
137+
138+ t .Log ("Ensure directory was deleted" )
139+ _ , err := os .Stat (nestedDir )
140+ require .ErrorIs (t , err , os .ErrNotExist )
141+ }
0 commit comments