github.com/drud/ddev@v1.21.5-alpha1.0.20230226034409-94fcc4b94453/pkg/fileutil/files_test.go (about) 1 package fileutil_test 2 3 import ( 4 "fmt" 5 "github.com/stretchr/testify/require" 6 "os" 7 "path/filepath" 8 "runtime" 9 "testing" 10 11 "github.com/drud/ddev/pkg/fileutil" 12 "github.com/drud/ddev/pkg/testcommon" 13 asrt "github.com/stretchr/testify/assert" 14 ) 15 16 var testFileLocation = "testdata/regular_file" 17 18 // TestCopyDir tests copying a directory. 19 func TestCopyDir(t *testing.T) { 20 assert := asrt.New(t) 21 sourceDir := testcommon.CreateTmpDir("TestCopyDir_source") 22 targetDir := testcommon.CreateTmpDir("TestCopyDir_target") 23 24 subdir := filepath.Join(sourceDir, "some_content") 25 err := os.Mkdir(subdir, 0755) 26 assert.NoError(err) 27 28 // test source not a directory 29 err = fileutil.CopyDir(testFileLocation, sourceDir) 30 assert.Error(err) 31 if err != nil { 32 assert.Contains(err.Error(), fmt.Sprintf("CopyDir: source directory %s is not a directory", filepath.Join(testFileLocation))) 33 } 34 35 // test destination exists 36 err = fileutil.CopyDir(sourceDir, targetDir) 37 assert.Error(err) 38 if err != nil { 39 assert.Contains(err.Error(), fmt.Sprintf("CopyDir: destination %s already exists", filepath.Join(targetDir))) 40 } 41 err = os.RemoveAll(subdir) 42 assert.NoError(err) 43 44 // copy a directory and validate that we find files elsewhere 45 err = os.RemoveAll(targetDir) 46 assert.NoError(err) 47 48 file, err := os.Create(filepath.Join(sourceDir, "touch1.txt")) 49 assert.NoError(err) 50 _ = file.Close() 51 file, err = os.Create(filepath.Join(sourceDir, "touch2.txt")) 52 assert.NoError(err) 53 _ = file.Close() 54 55 err = fileutil.CopyDir(sourceDir, targetDir) 56 assert.NoError(err) 57 assert.True(fileutil.FileExists(filepath.Join(targetDir, "touch1.txt"))) 58 assert.True(fileutil.FileExists(filepath.Join(targetDir, "touch2.txt"))) 59 60 err = os.RemoveAll(sourceDir) 61 assert.NoError(err) 62 err = os.RemoveAll(targetDir) 63 assert.NoError(err) 64 65 } 66 67 // TestCopyFile tests copying a file. 68 func TestCopyFile(t *testing.T) { 69 assert := asrt.New(t) 70 tmpTargetDir := testcommon.CreateTmpDir("TestCopyFile") 71 tmpTargetFile := filepath.Join(tmpTargetDir, filepath.Base(testFileLocation)) 72 73 err := fileutil.CopyFile(testFileLocation, tmpTargetFile) 74 assert.NoError(err) 75 76 file, err := os.Stat(tmpTargetFile) 77 assert.NoError(err) 78 79 if err != nil { 80 assert.False(file.IsDir()) 81 } 82 err = os.RemoveAll(tmpTargetDir) 83 assert.NoError(err) 84 } 85 86 // TestPurgeDirectory tests removal of directory contents without removing 87 // the directory itself. 88 func TestPurgeDirectory(t *testing.T) { 89 assert := asrt.New(t) 90 tmpPurgeDir := testcommon.CreateTmpDir("TestPurgeDirectory") 91 tmpPurgeFile := filepath.Join(tmpPurgeDir, "regular_file") 92 tmpPurgeSubFile := filepath.Join(tmpPurgeDir, "subdir", "regular_file") 93 94 err := fileutil.CopyFile(testFileLocation, tmpPurgeFile) 95 assert.NoError(err) 96 97 err = os.Mkdir(filepath.Join(tmpPurgeDir, "subdir"), 0755) 98 assert.NoError(err) 99 100 err = fileutil.CopyFile(testFileLocation, tmpPurgeSubFile) 101 assert.NoError(err) 102 103 err = os.Chmod(tmpPurgeSubFile, 0444) 104 assert.NoError(err) 105 106 err = fileutil.PurgeDirectory(tmpPurgeDir) 107 assert.NoError(err) 108 109 assert.True(fileutil.FileExists(tmpPurgeDir)) 110 assert.False(fileutil.FileExists(tmpPurgeFile)) 111 assert.False(fileutil.FileExists(tmpPurgeSubFile)) 112 } 113 114 // TestFgrepStringInFile tests the FgrepStringInFile utility function. 115 func TestFgrepStringInFile(t *testing.T) { 116 assert := asrt.New(t) 117 result, err := fileutil.FgrepStringInFile("testdata/fgrep_has_positive_contents.txt", "some needle we're looking for") 118 assert.NoError(err) 119 assert.True(result) 120 result, err = fileutil.FgrepStringInFile("testdata/fgrep_negative_contents.txt", "some needle we're looking for") 121 assert.NoError(err) 122 assert.False(result) 123 } 124 125 // TestListFilesInDir makes sure the files we have in testfiles are properly enumerated 126 func TestListFilesInDir(t *testing.T) { 127 assert := asrt.New(t) 128 129 fileList, err := fileutil.ListFilesInDir("testdata/testfiles/") 130 assert.NoError(err) 131 assert.True(len(fileList) == 2) 132 assert.Contains(fileList[0], "one.txt") 133 assert.Contains(fileList[1], "two.txt") 134 } 135 136 // TestReplaceStringInFile tests the ReplaceStringInFile utility function. 137 func TestReplaceStringInFile(t *testing.T) { 138 assert := asrt.New(t) 139 tmp, err := os.MkdirTemp("", "") 140 assert.NoError(err) 141 newFilePath := filepath.Join(tmp, "newfile.txt") 142 err = fileutil.ReplaceStringInFile("some needle we're looking for", "specialJUNKPattern", "testdata/fgrep_has_positive_contents.txt", newFilePath) 143 assert.NoError(err) 144 found, err := fileutil.FgrepStringInFile(newFilePath, "specialJUNKPattern") 145 assert.NoError(err) 146 assert.True(found) 147 } 148 149 // TestFindSimulatedXsymSymlinks tests FindSimulatedXsymSymlinks 150 func TestFindSimulatedXsymSymlinks(t *testing.T) { 151 assert := asrt.New(t) 152 testDir, _ := os.Getwd() 153 targetDir := filepath.Join(testDir, "testdata", "symlinks") 154 links, err := fileutil.FindSimulatedXsymSymlinks(targetDir) 155 assert.NoError(err) 156 assert.Len(links, 8) 157 } 158 159 // TestReplaceSimulatedXsymSymlinks tries a number of symlinks to make 160 // sure we can parse and replace symlinks. 161 func TestReplaceSimulatedXsymSymlinks(t *testing.T) { 162 testDir, _ := os.Getwd() 163 assert := asrt.New(t) 164 if runtime.GOOS == "windows" && !fileutil.CanCreateSymlinks() { 165 t.Skip("Skipping on Windows because test machine can't create symlnks") 166 } 167 sourceDir := filepath.Join(testDir, "testdata", "symlinks") 168 targetDir := testcommon.CreateTmpDir("TestReplaceSimulated") 169 //nolint: errcheck 170 defer os.RemoveAll(targetDir) 171 err := os.Chdir(targetDir) 172 assert.NoError(err) 173 174 // Make sure we leave the testDir as we found it.. 175 //nolint: errcheck 176 defer os.Chdir(testDir) 177 // CopyDir skips real symlinks, but we only care about simulated ones, so it's OK 178 err = fileutil.CopyDir(sourceDir, filepath.Join(targetDir, "symlinks")) 179 assert.NoError(err) 180 links, err := fileutil.FindSimulatedXsymSymlinks(targetDir) 181 assert.NoError(err) 182 assert.Len(links, 8) 183 err = fileutil.ReplaceSimulatedXsymSymlinks(links) 184 assert.NoError(err) 185 186 for _, link := range links { 187 fi, err := os.Stat(link.LinkLocation) 188 assert.NoError(err) 189 linkFi, err := os.Lstat(link.LinkLocation) 190 assert.NoError(err) 191 if err == nil && fi != nil && !fi.IsDir() { 192 // Read the symlink as a file. It should resolve with the actual content of target 193 contents, err := os.ReadFile(link.LinkLocation) 194 assert.NoError(err) 195 expectedContent := "textfile " + filepath.Base(link.LinkTarget) + "\n" 196 assert.Equal(expectedContent, string(contents)) 197 } 198 // Now stat the link and make sure it's a link and points where it should 199 if linkFi.Mode()&os.ModeSymlink != 0 { 200 targetFile, err := os.Readlink(link.LinkLocation) 201 assert.NoError(err) 202 assert.Equal(link.LinkTarget, targetFile) 203 _ = targetFile 204 } 205 } 206 207 } 208 209 // TestIsSameFile tests the IsSameFile utility function. 210 func TestIsSameFile(t *testing.T) { 211 assert := asrt.New(t) 212 213 tmpDir, err := testcommon.OsTempDir() 214 assert.NoError(err) 215 216 dirSymlink, err := filepath.Abs(filepath.Join(tmpDir, fileutil.RandomFilenameBase())) 217 require.NoError(t, err) 218 testdataAbsolute, err := filepath.Abs("testdata") 219 require.NoError(t, err) 220 err = os.Symlink(testdataAbsolute, dirSymlink) 221 assert.NoError(err) 222 //nolint: errcheck 223 defer os.Remove(dirSymlink) 224 225 // At this point, dirSymLink and "testdata" should be equivalent 226 isSame, err := fileutil.IsSameFile("testdata", dirSymlink) 227 assert.NoError(err) 228 assert.True(isSame) 229 // Test with files that are equivalent (through symlink) 230 isSame, err = fileutil.IsSameFile("testdata/testfiles/one.txt", filepath.Join(dirSymlink, "testfiles", "one.txt")) 231 assert.NoError(err) 232 assert.True(isSame) 233 234 // Test files that are *not* equivalent. 235 isSame, err = fileutil.IsSameFile("testdata/testfiles/one.txt", "testdata/testfiles/two.txt") 236 assert.NoError(err) 237 assert.False(isSame) 238 }