path_test.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. // Copyright 2009 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package os_test
  5. import (
  6. "io/ioutil"
  7. . "os"
  8. "path/filepath"
  9. "runtime"
  10. "syscall"
  11. "testing"
  12. )
  13. func TestMkdirAll(t *testing.T) {
  14. tmpDir := TempDir()
  15. path := tmpDir + "/_TestMkdirAll_/dir/./dir2"
  16. err := MkdirAll(path, 0777)
  17. if err != nil {
  18. t.Fatalf("MkdirAll %q: %s", path, err)
  19. }
  20. defer RemoveAll(tmpDir + "/_TestMkdirAll_")
  21. // Already exists, should succeed.
  22. err = MkdirAll(path, 0777)
  23. if err != nil {
  24. t.Fatalf("MkdirAll %q (second time): %s", path, err)
  25. }
  26. // Make file.
  27. fpath := path + "/file"
  28. f, err := Create(fpath)
  29. if err != nil {
  30. t.Fatalf("create %q: %s", fpath, err)
  31. }
  32. defer f.Close()
  33. // Can't make directory named after file.
  34. err = MkdirAll(fpath, 0777)
  35. if err == nil {
  36. t.Fatalf("MkdirAll %q: no error", fpath)
  37. }
  38. perr, ok := err.(*PathError)
  39. if !ok {
  40. t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
  41. }
  42. if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
  43. t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
  44. }
  45. // Can't make subdirectory of file.
  46. ffpath := fpath + "/subdir"
  47. err = MkdirAll(ffpath, 0777)
  48. if err == nil {
  49. t.Fatalf("MkdirAll %q: no error", ffpath)
  50. }
  51. perr, ok = err.(*PathError)
  52. if !ok {
  53. t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
  54. }
  55. if filepath.Clean(perr.Path) != filepath.Clean(fpath) {
  56. t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, filepath.Clean(perr.Path), filepath.Clean(fpath))
  57. }
  58. if runtime.GOOS == "windows" {
  59. path := tmpDir + `\_TestMkdirAll_\dir\.\dir2\`
  60. err := MkdirAll(path, 0777)
  61. if err != nil {
  62. t.Fatalf("MkdirAll %q: %s", path, err)
  63. }
  64. }
  65. }
  66. func TestRemoveAll(t *testing.T) {
  67. tmpDir := TempDir()
  68. // Work directory.
  69. path := tmpDir + "/_TestRemoveAll_"
  70. fpath := path + "/file"
  71. dpath := path + "/dir"
  72. // Make directory with 1 file and remove.
  73. if err := MkdirAll(path, 0777); err != nil {
  74. t.Fatalf("MkdirAll %q: %s", path, err)
  75. }
  76. fd, err := Create(fpath)
  77. if err != nil {
  78. t.Fatalf("create %q: %s", fpath, err)
  79. }
  80. fd.Close()
  81. if err = RemoveAll(path); err != nil {
  82. t.Fatalf("RemoveAll %q (first): %s", path, err)
  83. }
  84. if _, err = Lstat(path); err == nil {
  85. t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
  86. }
  87. // Make directory with file and subdirectory and remove.
  88. if err = MkdirAll(dpath, 0777); err != nil {
  89. t.Fatalf("MkdirAll %q: %s", dpath, err)
  90. }
  91. fd, err = Create(fpath)
  92. if err != nil {
  93. t.Fatalf("create %q: %s", fpath, err)
  94. }
  95. fd.Close()
  96. fd, err = Create(dpath + "/file")
  97. if err != nil {
  98. t.Fatalf("create %q: %s", fpath, err)
  99. }
  100. fd.Close()
  101. if err = RemoveAll(path); err != nil {
  102. t.Fatalf("RemoveAll %q (second): %s", path, err)
  103. }
  104. if _, err := Lstat(path); err == nil {
  105. t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
  106. }
  107. // Determine if we should run the following test.
  108. testit := true
  109. if runtime.GOOS == "windows" {
  110. // Chmod is not supported under windows.
  111. testit = false
  112. } else {
  113. // Test fails as root.
  114. testit = Getuid() != 0
  115. }
  116. if testit {
  117. // Make directory with file and subdirectory and trigger error.
  118. if err = MkdirAll(dpath, 0777); err != nil {
  119. t.Fatalf("MkdirAll %q: %s", dpath, err)
  120. }
  121. for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
  122. fd, err = Create(s)
  123. if err != nil {
  124. t.Fatalf("create %q: %s", s, err)
  125. }
  126. fd.Close()
  127. }
  128. if err = Chmod(dpath, 0); err != nil {
  129. t.Fatalf("Chmod %q 0: %s", dpath, err)
  130. }
  131. // No error checking here: either RemoveAll
  132. // will or won't be able to remove dpath;
  133. // either way we want to see if it removes fpath
  134. // and path/zzz. Reasons why RemoveAll might
  135. // succeed in removing dpath as well include:
  136. // * running as root
  137. // * running on a file system without permissions (FAT)
  138. RemoveAll(path)
  139. Chmod(dpath, 0777)
  140. for _, s := range []string{fpath, path + "/zzz"} {
  141. if _, err = Lstat(s); err == nil {
  142. t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
  143. }
  144. }
  145. }
  146. if err = RemoveAll(path); err != nil {
  147. t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
  148. }
  149. if _, err = Lstat(path); err == nil {
  150. t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
  151. }
  152. }
  153. func TestMkdirAllWithSymlink(t *testing.T) {
  154. switch runtime.GOOS {
  155. case "nacl", "plan9":
  156. t.Skipf("skipping on %s", runtime.GOOS)
  157. case "windows":
  158. if !supportsSymlinks {
  159. t.Skipf("skipping on %s", runtime.GOOS)
  160. }
  161. }
  162. tmpDir, err := ioutil.TempDir("", "TestMkdirAllWithSymlink-")
  163. if err != nil {
  164. t.Fatal(err)
  165. }
  166. defer RemoveAll(tmpDir)
  167. dir := tmpDir + "/dir"
  168. err = Mkdir(dir, 0755)
  169. if err != nil {
  170. t.Fatalf("Mkdir %s: %s", dir, err)
  171. }
  172. link := tmpDir + "/link"
  173. err = Symlink("dir", link)
  174. if err != nil {
  175. t.Fatalf("Symlink %s: %s", link, err)
  176. }
  177. path := link + "/foo"
  178. err = MkdirAll(path, 0755)
  179. if err != nil {
  180. t.Errorf("MkdirAll %q: %s", path, err)
  181. }
  182. }
  183. func TestMkdirAllAtSlash(t *testing.T) {
  184. switch runtime.GOOS {
  185. case "android", "plan9", "windows":
  186. t.Skipf("skipping on %s", runtime.GOOS)
  187. }
  188. RemoveAll("/_go_os_test")
  189. err := MkdirAll("/_go_os_test/dir", 0777)
  190. if err != nil {
  191. pathErr, ok := err.(*PathError)
  192. // common for users not to be able to write to /
  193. if ok && pathErr.Err == syscall.EACCES {
  194. return
  195. }
  196. t.Fatalf(`MkdirAll "/_go_os_test/dir": %v`, err)
  197. }
  198. RemoveAll("/_go_os_test")
  199. }