fileutils_test.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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 !errors.Is(err, os.ErrNotExist) {
  149. t.Errorf("Expected an os.ErrNotExist, got: %v", err)
  150. }
  151. if symLinkedPath != "" {
  152. t.Fatalf("expected empty path, but '%s' was returned", symLinkedPath)
  153. }
  154. }
  155. // Reading a symlink to a file must fail
  156. func TestReadSymlinkedDirectoryToFile(t *testing.T) {
  157. // TODO Windows: Port this test
  158. if runtime.GOOS == "windows" {
  159. t.Skip("Needs porting to Windows")
  160. }
  161. var err error
  162. var file *os.File
  163. // #nosec G303
  164. if file, err = os.Create("/tmp/testReadSymlinkToFile"); err != nil {
  165. t.Fatalf("failed to create file: %s", err)
  166. }
  167. _ = file.Close()
  168. if err = os.Symlink("/tmp/testReadSymlinkToFile", "/tmp/fileLinkTest"); err != nil {
  169. t.Errorf("failed to create symlink: %s", err)
  170. }
  171. symlinkedPath, err := ReadSymlinkedDirectory("/tmp/fileLinkTest")
  172. if err == nil {
  173. t.Errorf("ReadSymlinkedDirectory on a symlink to a file should've failed")
  174. }
  175. if !strings.HasPrefix(err.Error(), "canonical path points to a file") {
  176. t.Errorf("unexpected error: %v", err)
  177. }
  178. if symlinkedPath != "" {
  179. t.Errorf("path should've been empty: %s", symlinkedPath)
  180. }
  181. if err = os.Remove("/tmp/testReadSymlinkToFile"); err != nil {
  182. t.Errorf("failed to remove file: %s", err)
  183. }
  184. if err = os.Remove("/tmp/fileLinkTest"); err != nil {
  185. t.Errorf("failed to remove symlink: %s", err)
  186. }
  187. }
  188. func TestCreateIfNotExistsDir(t *testing.T) {
  189. folderToCreate := filepath.Join(t.TempDir(), "tocreate")
  190. if err := CreateIfNotExists(folderToCreate, true); err != nil {
  191. t.Fatal(err)
  192. }
  193. fileinfo, err := os.Stat(folderToCreate)
  194. if err != nil {
  195. t.Fatalf("Should have create a folder, got %v", err)
  196. }
  197. if !fileinfo.IsDir() {
  198. t.Errorf("Should have been a dir, seems it's not")
  199. }
  200. }
  201. func TestCreateIfNotExistsFile(t *testing.T) {
  202. fileToCreate := filepath.Join(t.TempDir(), "file/to/create")
  203. if err := CreateIfNotExists(fileToCreate, false); err != nil {
  204. t.Error(err)
  205. }
  206. fileinfo, err := os.Stat(fileToCreate)
  207. if err != nil {
  208. t.Fatalf("Should have create a file, got %v", err)
  209. }
  210. if fileinfo.IsDir() {
  211. t.Errorf("Should have been a file, seems it's not")
  212. }
  213. }
  214. func BenchmarkGetTotalUsedFds(b *testing.B) {
  215. b.ReportAllocs()
  216. for i := 0; i < b.N; i++ {
  217. _ = GetTotalUsedFds()
  218. }
  219. }