fileutils_test.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package fileutils // import "github.com/docker/docker/pkg/fileutils"
  2. import (
  3. "errors"
  4. "os"
  5. "path"
  6. "path/filepath"
  7. "runtime"
  8. "strings"
  9. "testing"
  10. )
  11. // CopyFile with invalid src
  12. func TestCopyFileWithInvalidSrc(t *testing.T) {
  13. tempDir := t.TempDir()
  14. bytes, err := CopyFile(filepath.Join(tempDir, "/invalid/file/path"), path.Join(t.TempDir(), "dest"))
  15. if err == nil {
  16. t.Error("Should have fail to copy an invalid src file")
  17. }
  18. if !errors.Is(err, os.ErrNotExist) {
  19. t.Errorf("Expected an os.ErrNotExist, got: %v", err)
  20. }
  21. if bytes != 0 {
  22. t.Errorf("Should have written 0 bytes, got: %d", bytes)
  23. }
  24. }
  25. // CopyFile with invalid dest
  26. func TestCopyFileWithInvalidDest(t *testing.T) {
  27. tempFolder := t.TempDir()
  28. src := path.Join(tempFolder, "file")
  29. err := os.WriteFile(src, []byte("content"), 0o740)
  30. if err != nil {
  31. t.Fatal(err)
  32. }
  33. bytes, err := CopyFile(src, path.Join(tempFolder, "/invalid/dest/path"))
  34. if err == nil {
  35. t.Error("Should have fail to copy an invalid src file")
  36. }
  37. if !errors.Is(err, os.ErrNotExist) {
  38. t.Errorf("Expected an os.ErrNotExist, got: %v", err)
  39. }
  40. if bytes != 0 {
  41. t.Errorf("Should have written 0 bytes, got: %d", bytes)
  42. }
  43. }
  44. // CopyFile with same src and dest
  45. func TestCopyFileWithSameSrcAndDest(t *testing.T) {
  46. file := path.Join(t.TempDir(), "file")
  47. err := os.WriteFile(file, []byte("content"), 0o740)
  48. if err != nil {
  49. t.Fatal(err)
  50. }
  51. bytes, err := CopyFile(file, file)
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. if bytes != 0 {
  56. t.Fatal("Should have written 0 bytes as it is the same file.")
  57. }
  58. }
  59. // CopyFile with same src and dest but path is different and not clean
  60. func TestCopyFileWithSameSrcAndDestWithPathNameDifferent(t *testing.T) {
  61. testFolder := path.Join(t.TempDir(), "test")
  62. err := os.Mkdir(testFolder, 0o740)
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. file := path.Join(testFolder, "file")
  67. sameFile := testFolder + "/../test/file"
  68. err = os.WriteFile(file, []byte("content"), 0o740)
  69. if err != nil {
  70. t.Fatal(err)
  71. }
  72. bytes, err := CopyFile(file, sameFile)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. if bytes != 0 {
  77. t.Fatal("Should have written 0 bytes as it is the same file.")
  78. }
  79. }
  80. func TestCopyFile(t *testing.T) {
  81. tempFolder := t.TempDir()
  82. src := path.Join(tempFolder, "src")
  83. dest := path.Join(tempFolder, "dest")
  84. err := os.WriteFile(src, []byte("content"), 0o777)
  85. if err != nil {
  86. t.Error(err)
  87. }
  88. err = os.WriteFile(dest, []byte("destContent"), 0o777)
  89. if err != nil {
  90. t.Error(err)
  91. }
  92. bytes, err := CopyFile(src, dest)
  93. if err != nil {
  94. t.Fatal(err)
  95. }
  96. if bytes != 7 {
  97. t.Fatalf("Should have written %d bytes but wrote %d", 7, bytes)
  98. }
  99. actual, err := os.ReadFile(dest)
  100. if err != nil {
  101. t.Fatal(err)
  102. }
  103. if string(actual) != "content" {
  104. t.Fatalf("Dest content was '%s', expected '%s'", string(actual), "content")
  105. }
  106. }
  107. // Reading a symlink to a directory must return the directory
  108. func TestReadSymlinkedDirectoryExistingDirectory(t *testing.T) {
  109. // TODO Windows: Port this test
  110. if runtime.GOOS == "windows" {
  111. t.Skip("Needs porting to Windows")
  112. }
  113. // On macOS, tmp itself is symlinked, so resolve this one upfront;
  114. // see https://github.com/golang/go/issues/56259
  115. tmpDir, err := filepath.EvalSymlinks(t.TempDir())
  116. if err != nil {
  117. t.Fatal(err)
  118. }
  119. srcPath := filepath.Join(tmpDir, "/testReadSymlinkToExistingDirectory")
  120. dstPath := filepath.Join(tmpDir, "/dirLinkTest")
  121. if err = os.Mkdir(srcPath, 0o777); err != nil {
  122. t.Errorf("failed to create directory: %s", err)
  123. }
  124. if err = os.Symlink(srcPath, dstPath); err != nil {
  125. t.Errorf("failed to create symlink: %s", err)
  126. }
  127. var symlinkedPath string
  128. if symlinkedPath, err = ReadSymlinkedDirectory(dstPath); err != nil {
  129. t.Fatalf("failed to read symlink to directory: %s", err)
  130. }
  131. if symlinkedPath != srcPath {
  132. t.Fatalf("symlink returned unexpected directory: %s", symlinkedPath)
  133. }
  134. if err = os.Remove(srcPath); err != nil {
  135. t.Errorf("failed to remove temporary directory: %s", err)
  136. }
  137. if err = os.Remove(dstPath); err != nil {
  138. t.Errorf("failed to remove symlink: %s", err)
  139. }
  140. }
  141. // Reading a non-existing symlink must fail
  142. func TestReadSymlinkedDirectoryNonExistingSymlink(t *testing.T) {
  143. tmpDir := t.TempDir()
  144. symLinkedPath, err := ReadSymlinkedDirectory(path.Join(tmpDir, "/Non/ExistingPath"))
  145. if err == nil {
  146. t.Errorf("error expected for non-existing symlink")
  147. }
  148. if symLinkedPath != "" {
  149. t.Fatalf("expected empty path, but '%s' was returned", symLinkedPath)
  150. }
  151. }
  152. // Reading a symlink to a file must fail
  153. func TestReadSymlinkedDirectoryToFile(t *testing.T) {
  154. // TODO Windows: Port this test
  155. if runtime.GOOS == "windows" {
  156. t.Skip("Needs porting to Windows")
  157. }
  158. var err error
  159. var file *os.File
  160. // #nosec G303
  161. if file, err = os.Create("/tmp/testReadSymlinkToFile"); err != nil {
  162. t.Fatalf("failed to create file: %s", err)
  163. }
  164. _ = file.Close()
  165. if err = os.Symlink("/tmp/testReadSymlinkToFile", "/tmp/fileLinkTest"); err != nil {
  166. t.Errorf("failed to create symlink: %s", err)
  167. }
  168. symlinkedPath, err := ReadSymlinkedDirectory("/tmp/fileLinkTest")
  169. if err == nil {
  170. t.Errorf("ReadSymlinkedDirectory on a symlink to a file should've failed")
  171. }
  172. if !strings.HasPrefix(err.Error(), "canonical path points to a file") {
  173. t.Errorf("unexpected error: %v", err)
  174. }
  175. if symlinkedPath != "" {
  176. t.Errorf("path should've been empty: %s", symlinkedPath)
  177. }
  178. if err = os.Remove("/tmp/testReadSymlinkToFile"); err != nil {
  179. t.Errorf("failed to remove file: %s", err)
  180. }
  181. if err = os.Remove("/tmp/fileLinkTest"); err != nil {
  182. t.Errorf("failed to remove symlink: %s", err)
  183. }
  184. }
  185. func TestCreateIfNotExistsDir(t *testing.T) {
  186. folderToCreate := filepath.Join(t.TempDir(), "tocreate")
  187. if err := CreateIfNotExists(folderToCreate, true); err != nil {
  188. t.Fatal(err)
  189. }
  190. fileinfo, err := os.Stat(folderToCreate)
  191. if err != nil {
  192. t.Fatalf("Should have create a folder, got %v", err)
  193. }
  194. if !fileinfo.IsDir() {
  195. t.Errorf("Should have been a dir, seems it's not")
  196. }
  197. }
  198. func TestCreateIfNotExistsFile(t *testing.T) {
  199. fileToCreate := filepath.Join(t.TempDir(), "file/to/create")
  200. if err := CreateIfNotExists(fileToCreate, false); err != nil {
  201. t.Error(err)
  202. }
  203. fileinfo, err := os.Stat(fileToCreate)
  204. if err != nil {
  205. t.Fatalf("Should have create a file, got %v", err)
  206. }
  207. if fileinfo.IsDir() {
  208. t.Errorf("Should have been a file, seems it's not")
  209. }
  210. }