fakefs_test.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938
  1. // Copyright (C) 2018 The Syncthing Authors.
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  5. // You can obtain one at https://mozilla.org/MPL/2.0/.
  6. package fs
  7. import (
  8. "bytes"
  9. "fmt"
  10. "io"
  11. "os"
  12. "path"
  13. "path/filepath"
  14. "runtime"
  15. "sort"
  16. "testing"
  17. "time"
  18. )
  19. func TestFakeFS(t *testing.T) {
  20. // Test some basic aspects of the fakeFS
  21. fs := newFakeFilesystem("/foo/bar/baz")
  22. // MkdirAll
  23. err := fs.MkdirAll("dira/dirb", 0755)
  24. if err != nil {
  25. t.Fatal(err)
  26. }
  27. _, err = fs.Stat("dira/dirb")
  28. if err != nil {
  29. t.Fatal(err)
  30. }
  31. // Mkdir
  32. err = fs.Mkdir("dira/dirb/dirc", 0755)
  33. if err != nil {
  34. t.Fatal(err)
  35. }
  36. _, err = fs.Stat("dira/dirb/dirc")
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. // Create
  41. fd, err := fs.Create("/dira/dirb/test")
  42. if err != nil {
  43. t.Fatal(err)
  44. }
  45. // Write
  46. _, err = fd.Write([]byte("hello"))
  47. if err != nil {
  48. t.Fatal(err)
  49. }
  50. // Stat on fd
  51. info, err := fd.Stat()
  52. if err != nil {
  53. t.Fatal(err)
  54. }
  55. if info.Name() != "test" {
  56. t.Error("wrong name:", info.Name())
  57. }
  58. if info.Size() != 5 {
  59. t.Error("wrong size:", info.Size())
  60. }
  61. // Stat on fs
  62. info, err = fs.Stat("dira/dirb/test")
  63. if err != nil {
  64. t.Fatal(err)
  65. }
  66. if info.Name() != "test" {
  67. t.Error("wrong name:", info.Name())
  68. }
  69. if info.Size() != 5 {
  70. t.Error("wrong size:", info.Size())
  71. }
  72. // Seek
  73. _, err = fd.Seek(1, io.SeekStart)
  74. if err != nil {
  75. t.Fatal(err)
  76. }
  77. // Read
  78. bs0, err := io.ReadAll(fd)
  79. if err != nil {
  80. t.Fatal(err)
  81. }
  82. if len(bs0) != 4 {
  83. t.Error("wrong number of bytes:", len(bs0))
  84. }
  85. // Read again, same data hopefully
  86. _, err = fd.Seek(0, io.SeekStart)
  87. if err != nil {
  88. t.Fatal(err)
  89. }
  90. bs1, err := io.ReadAll(fd)
  91. if err != nil {
  92. t.Fatal(err)
  93. }
  94. if !bytes.Equal(bs0, bs1[1:]) {
  95. t.Error("wrong data")
  96. }
  97. // Create symlink
  98. if err := fs.CreateSymlink("foo", "dira/dirb/symlink"); err != nil {
  99. t.Fatal(err)
  100. }
  101. if str, err := fs.ReadSymlink("dira/dirb/symlink"); err != nil {
  102. t.Fatal(err)
  103. } else if str != "foo" {
  104. t.Error("Wrong symlink destination", str)
  105. }
  106. // Chown
  107. if err := fs.Lchown("dira", 1234, 5678); err != nil {
  108. t.Fatal(err)
  109. }
  110. if info, err := fs.Lstat("dira"); err != nil {
  111. t.Fatal(err)
  112. } else if info.Owner() != 1234 || info.Group() != 5678 {
  113. t.Error("Wrong owner/group")
  114. }
  115. }
  116. func testFakeFSRead(t *testing.T, fs Filesystem) {
  117. // Test some basic aspects of the fakeFS
  118. // Create
  119. fd, _ := fs.Create("test")
  120. defer fd.Close()
  121. fd.Truncate(3 * 1 << randomBlockShift)
  122. // Read
  123. fd.Seek(0, io.SeekStart)
  124. bs0, err := io.ReadAll(fd)
  125. if err != nil {
  126. t.Fatal(err)
  127. }
  128. if len(bs0) != 3*1<<randomBlockShift {
  129. t.Error("wrong number of bytes:", len(bs0))
  130. }
  131. // Read again, starting at an odd offset
  132. fd.Seek(0, io.SeekStart)
  133. buf0 := make([]byte, 12345)
  134. n, _ := fd.Read(buf0)
  135. if n != len(buf0) {
  136. t.Fatal("short read")
  137. }
  138. buf1, err := io.ReadAll(fd)
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. if len(buf1) != 3*1<<randomBlockShift-len(buf0) {
  143. t.Error("wrong number of bytes:", len(buf1))
  144. }
  145. bs1 := append(buf0, buf1...)
  146. if !bytes.Equal(bs0, bs1) {
  147. t.Error("data mismatch")
  148. }
  149. // Read large block with ReadAt
  150. bs2 := make([]byte, 3*1<<randomBlockShift)
  151. _, err = fd.ReadAt(bs2, 0)
  152. if err != nil {
  153. t.Fatal(err)
  154. }
  155. if !bytes.Equal(bs0, bs2) {
  156. t.Error("data mismatch")
  157. }
  158. }
  159. type testFS struct {
  160. name string
  161. fs Filesystem
  162. }
  163. type test struct {
  164. name string
  165. impl func(t *testing.T, fs Filesystem)
  166. }
  167. func TestFakeFSCaseSensitive(t *testing.T) {
  168. var tests = []test{
  169. {"Read", testFakeFSRead},
  170. {"OpenFile", testFakeFSOpenFile},
  171. {"RemoveAll", testFakeFSRemoveAll},
  172. {"Remove", testFakeFSRemove},
  173. {"Rename", testFakeFSRename},
  174. {"Mkdir", testFakeFSMkdir},
  175. {"SameFile", testFakeFSSameFile},
  176. {"DirNames", testDirNames},
  177. {"FileName", testFakeFSFileName},
  178. }
  179. var filesystems = []testFS{
  180. {"fakeFS", newFakeFilesystem("/foo")},
  181. }
  182. testDir, sensitive := createTestDir(t)
  183. defer removeTestDir(t, testDir)
  184. if sensitive {
  185. filesystems = append(filesystems, testFS{runtime.GOOS, newBasicFilesystem(testDir)})
  186. }
  187. runTests(t, tests, filesystems)
  188. }
  189. func TestFakeFSCaseInsensitive(t *testing.T) {
  190. var tests = []test{
  191. {"Read", testFakeFSRead},
  192. {"OpenFile", testFakeFSOpenFile},
  193. {"RemoveAll", testFakeFSRemoveAll},
  194. {"Remove", testFakeFSRemove},
  195. {"Mkdir", testFakeFSMkdir},
  196. {"SameFile", testFakeFSSameFile},
  197. {"DirNames", testDirNames},
  198. {"FileName", testFakeFSFileName},
  199. {"GeneralInsens", testFakeFSCaseInsensitive},
  200. {"MkdirAllInsens", testFakeFSCaseInsensitiveMkdirAll},
  201. {"StatInsens", testFakeFSStatInsens},
  202. {"RenameInsens", testFakeFSRenameInsensitive},
  203. {"MkdirInsens", testFakeFSMkdirInsens},
  204. {"OpenFileInsens", testFakeFSOpenFileInsens},
  205. {"RemoveAllInsens", testFakeFSRemoveAllInsens},
  206. {"RemoveInsens", testFakeFSRemoveInsens},
  207. {"SameFileInsens", testFakeFSSameFileInsens},
  208. {"CreateInsens", testFakeFSCreateInsens},
  209. {"FileNameInsens", testFakeFSFileNameInsens},
  210. }
  211. var filesystems = []testFS{
  212. {"fakeFS", newFakeFilesystem("/foobar?insens=true")},
  213. }
  214. testDir, sensitive := createTestDir(t)
  215. defer removeTestDir(t, testDir)
  216. if !sensitive {
  217. filesystems = append(filesystems, testFS{runtime.GOOS, newBasicFilesystem(testDir)})
  218. }
  219. runTests(t, tests, filesystems)
  220. }
  221. func createTestDir(t *testing.T) (string, bool) {
  222. t.Helper()
  223. testDir, err := os.MkdirTemp("", "")
  224. if err != nil {
  225. t.Fatalf("could not create temporary dir for testing: %s", err)
  226. }
  227. if fd, err := os.Create(filepath.Join(testDir, ".stfolder")); err != nil {
  228. t.Fatalf("could not create .stfolder: %s", err)
  229. } else {
  230. fd.Close()
  231. }
  232. var sensitive bool
  233. if f, err := os.Open(filepath.Join(testDir, ".STfolder")); err != nil {
  234. sensitive = true
  235. } else {
  236. defer f.Close()
  237. }
  238. return testDir, sensitive
  239. }
  240. func removeTestDir(t *testing.T, testDir string) {
  241. t.Helper()
  242. if err := os.RemoveAll(testDir); err != nil {
  243. t.Fatalf("could not remove test directory: %s", err)
  244. }
  245. }
  246. func runTests(t *testing.T, tests []test, filesystems []testFS) {
  247. for _, filesystem := range filesystems {
  248. for _, test := range tests {
  249. name := fmt.Sprintf("%s_%s", test.name, filesystem.name)
  250. t.Run(name, func(t *testing.T) {
  251. test.impl(t, filesystem.fs)
  252. if err := cleanup(filesystem.fs); err != nil {
  253. t.Errorf("cleanup failed: %s", err)
  254. }
  255. })
  256. }
  257. }
  258. }
  259. func testFakeFSCaseInsensitive(t *testing.T, fs Filesystem) {
  260. bs1 := []byte("test")
  261. err := fs.Mkdir("/fUbar", 0755)
  262. if err != nil {
  263. t.Fatal(err)
  264. }
  265. fd1, err := fs.Create("fuBAR/SISYPHOS")
  266. if err != nil {
  267. t.Fatalf("could not create file: %s", err)
  268. }
  269. defer fd1.Close()
  270. _, err = fd1.Write(bs1)
  271. if err != nil {
  272. t.Fatal(err)
  273. }
  274. // Try reading from the same file with different filenames
  275. fd2, err := fs.Open("Fubar/Sisyphos")
  276. if err != nil {
  277. t.Fatalf("could not open file by its case-differing filename: %s", err)
  278. }
  279. defer fd2.Close()
  280. if _, err := fd2.Seek(0, io.SeekStart); err != nil {
  281. t.Fatal(err)
  282. }
  283. bs2, err := io.ReadAll(fd2)
  284. if err != nil {
  285. t.Fatal(err)
  286. }
  287. if len(bs1) != len(bs2) {
  288. t.Errorf("wrong number of bytes, expected %d, got %d", len(bs1), len(bs2))
  289. }
  290. }
  291. func testFakeFSCaseInsensitiveMkdirAll(t *testing.T, fs Filesystem) {
  292. err := fs.MkdirAll("/fOO/Bar/bAz", 0755)
  293. if err != nil {
  294. t.Fatal(err)
  295. }
  296. fd, err := fs.OpenFile("/foo/BaR/BaZ/tESt", os.O_CREATE, 0644)
  297. if err != nil {
  298. t.Fatal(err)
  299. }
  300. if err = fd.Close(); err != nil {
  301. t.Fatal(err)
  302. }
  303. if err = fs.Rename("/FOO/BAR/baz/tesT", "/foo/baR/BAZ/Qux"); err != nil {
  304. t.Fatal(err)
  305. }
  306. }
  307. func testDirNames(t *testing.T, fs Filesystem) {
  308. filenames := []string{"fOO", "Bar", "baz"}
  309. for _, filename := range filenames {
  310. if fd, err := fs.Create("/" + filename); err != nil {
  311. t.Errorf("Could not create %s: %s", filename, err)
  312. } else {
  313. fd.Close()
  314. }
  315. }
  316. assertDir(t, fs, "/", filenames)
  317. }
  318. func assertDir(t *testing.T, fs Filesystem, directory string, filenames []string) {
  319. t.Helper()
  320. got, err := fs.DirNames(directory)
  321. if err != nil {
  322. t.Fatal(err)
  323. }
  324. if path.Clean(directory) == "/" {
  325. filenames = append(filenames, ".stfolder")
  326. }
  327. sort.Strings(filenames)
  328. sort.Strings(got)
  329. if len(filenames) != len(got) {
  330. t.Errorf("want %s, got %s", filenames, got)
  331. return
  332. }
  333. for i := range filenames {
  334. if filenames[i] != got[i] {
  335. t.Errorf("want %s, got %s", filenames, got)
  336. return
  337. }
  338. }
  339. }
  340. func testFakeFSStatInsens(t *testing.T, fs Filesystem) {
  341. // this is to test that neither fs.Stat nor fd.Stat change the filename
  342. // both in directory and in previous Stat results
  343. fd1, err := fs.Create("aAa")
  344. if err != nil {
  345. t.Fatal(err)
  346. }
  347. defer fd1.Close()
  348. info1, err := fs.Stat("AAA")
  349. if err != nil {
  350. t.Fatal(err)
  351. }
  352. if _, err = fs.Stat("AaA"); err != nil {
  353. t.Fatal(err)
  354. }
  355. info2, err := fd1.Stat()
  356. if err != nil {
  357. t.Fatal(err)
  358. }
  359. fd2, err := fs.Open("aaa")
  360. if err != nil {
  361. t.Fatal(err)
  362. }
  363. defer fd2.Close()
  364. if _, err = fd2.Stat(); err != nil {
  365. t.Fatal(err)
  366. }
  367. if info1.Name() != "AAA" {
  368. t.Errorf("want AAA, got %s", info1.Name())
  369. }
  370. if info2.Name() != "aAa" {
  371. t.Errorf("want aAa, got %s", info2.Name())
  372. }
  373. assertDir(t, fs, "/", []string{"aAa"})
  374. }
  375. func testFakeFSFileName(t *testing.T, fs Filesystem) {
  376. var testCases = []struct {
  377. create string
  378. open string
  379. }{
  380. {"bar", "bar"},
  381. }
  382. for _, testCase := range testCases {
  383. if fd, err := fs.Create(testCase.create); err != nil {
  384. t.Fatal(err)
  385. } else {
  386. fd.Close()
  387. }
  388. fd, err := fs.Open(testCase.open)
  389. if err != nil {
  390. t.Fatal(err)
  391. }
  392. defer fd.Close()
  393. if got := fd.Name(); got != testCase.open {
  394. t.Errorf("want %s, got %s", testCase.open, got)
  395. }
  396. }
  397. }
  398. func testFakeFSFileNameInsens(t *testing.T, fs Filesystem) {
  399. var testCases = []struct {
  400. create string
  401. open string
  402. }{
  403. {"BaZ", "bAz"},
  404. }
  405. for _, testCase := range testCases {
  406. fd, err := fs.Create(testCase.create)
  407. if err != nil {
  408. t.Fatal(err)
  409. }
  410. fd.Close()
  411. fd, err = fs.Open(testCase.open)
  412. if err != nil {
  413. t.Fatal(err)
  414. }
  415. defer fd.Close()
  416. if got := fd.Name(); got != testCase.open {
  417. t.Errorf("want %s, got %s", testCase.open, got)
  418. }
  419. }
  420. }
  421. func testFakeFSRename(t *testing.T, fs Filesystem) {
  422. if err := fs.MkdirAll("/foo/bar/baz", 0755); err != nil {
  423. t.Fatal(err)
  424. }
  425. fd, err := fs.Create("/foo/bar/baz/qux")
  426. if err != nil {
  427. t.Fatal(err)
  428. }
  429. fd.Close()
  430. if err := fs.Rename("/foo/bar/baz/qux", "/foo/notthere/qux"); err == nil {
  431. t.Errorf("rename to non-existent dir gave no error")
  432. }
  433. if err := fs.MkdirAll("/baz/bar/foo", 0755); err != nil {
  434. t.Fatal(err)
  435. }
  436. if err := fs.Rename("/foo/bar/baz/qux", "/baz/bar/foo/qux"); err != nil {
  437. t.Fatal(err)
  438. }
  439. var dirs = []struct {
  440. dir string
  441. files []string
  442. }{
  443. {dir: "/", files: []string{"foo", "baz"}},
  444. {dir: "/foo", files: []string{"bar"}},
  445. {dir: "/foo/bar/baz", files: []string{}},
  446. {dir: "/baz/bar/foo", files: []string{"qux"}},
  447. }
  448. for _, dir := range dirs {
  449. assertDir(t, fs, dir.dir, dir.files)
  450. }
  451. if err := fs.Rename("/baz/bar/foo", "/baz/bar/FOO"); err != nil {
  452. t.Fatal(err)
  453. }
  454. assertDir(t, fs, "/baz/bar", []string{"FOO"})
  455. assertDir(t, fs, "/baz/bar/FOO", []string{"qux"})
  456. }
  457. func testFakeFSRenameInsensitive(t *testing.T, fs Filesystem) {
  458. if err := fs.MkdirAll("/baz/bar/foo", 0755); err != nil {
  459. t.Fatal(err)
  460. }
  461. if err := fs.MkdirAll("/foO/baR/baZ", 0755); err != nil {
  462. t.Fatal(err)
  463. }
  464. fd, err := fs.Create("/BAZ/BAR/FOO/QUX")
  465. if err != nil {
  466. t.Fatal(err)
  467. }
  468. fd.Close()
  469. if err := fs.Rename("/Baz/bAr/foO/QuX", "/Foo/Bar/Baz/qUUx"); err != nil {
  470. t.Fatal(err)
  471. }
  472. var dirs = []struct {
  473. dir string
  474. files []string
  475. }{
  476. {dir: "/", files: []string{"foO", "baz"}},
  477. {dir: "/foo", files: []string{"baR"}},
  478. {dir: "/foo/bar/baz", files: []string{"qUUx"}},
  479. {dir: "/baz/bar/foo", files: []string{}},
  480. }
  481. for _, dir := range dirs {
  482. assertDir(t, fs, dir.dir, dir.files)
  483. }
  484. // not checking on darwin due to https://github.com/golang/go/issues/35222
  485. if runtime.GOOS != "darwin" {
  486. if err := fs.Rename("/foo/bar/BAZ", "/FOO/BAR/bAz"); err != nil {
  487. t.Errorf("Could not perform in-place case-only directory rename: %s", err)
  488. }
  489. assertDir(t, fs, "/foo/bar", []string{"bAz"})
  490. assertDir(t, fs, "/fOO/bAr/baz", []string{"qUUx"})
  491. }
  492. if err := fs.Rename("foo/bar/baz/quux", "foo/bar/BaZ/Quux"); err != nil {
  493. t.Errorf("File rename failed: %s", err)
  494. }
  495. assertDir(t, fs, "/FOO/BAR/BAZ", []string{"Quux"})
  496. }
  497. func testFakeFSMkdir(t *testing.T, fs Filesystem) {
  498. if err := fs.Mkdir("/foo", 0755); err != nil {
  499. t.Fatal(err)
  500. }
  501. if _, err := fs.Stat("/foo"); err != nil {
  502. t.Fatal(err)
  503. }
  504. if err := fs.Mkdir("/foo", 0755); err == nil {
  505. t.Errorf("got no error while creating existing directory")
  506. }
  507. }
  508. func testFakeFSMkdirInsens(t *testing.T, fs Filesystem) {
  509. if err := fs.Mkdir("/foo", 0755); err != nil {
  510. t.Fatal(err)
  511. }
  512. if _, err := fs.Stat("/Foo"); err != nil {
  513. t.Fatal(err)
  514. }
  515. if err := fs.Mkdir("/FOO", 0755); err == nil {
  516. t.Errorf("got no error while creating existing directory")
  517. }
  518. }
  519. func testFakeFSOpenFile(t *testing.T, fs Filesystem) {
  520. fd, err := fs.OpenFile("foobar", os.O_RDONLY, 0664)
  521. if err == nil {
  522. fd.Close()
  523. t.Fatalf("got no error opening a non-existing file")
  524. }
  525. fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE, 0664)
  526. if err != nil {
  527. t.Fatal(err)
  528. }
  529. fd.Close()
  530. fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0664)
  531. if err == nil {
  532. fd.Close()
  533. t.Fatalf("created an existing file while told not to")
  534. }
  535. fd, err = fs.OpenFile("foobar", os.O_RDWR|os.O_CREATE, 0664)
  536. if err != nil {
  537. t.Fatal(err)
  538. }
  539. fd.Close()
  540. fd, err = fs.OpenFile("foobar", os.O_RDWR, 0664)
  541. if err != nil {
  542. t.Fatal(err)
  543. }
  544. fd.Close()
  545. }
  546. func testFakeFSOpenFileInsens(t *testing.T, fs Filesystem) {
  547. fd, err := fs.OpenFile("FooBar", os.O_RDONLY, 0664)
  548. if err == nil {
  549. fd.Close()
  550. t.Fatalf("got no error opening a non-existing file")
  551. }
  552. fd, err = fs.OpenFile("fOObar", os.O_RDWR|os.O_CREATE, 0664)
  553. if err != nil {
  554. t.Fatal(err)
  555. }
  556. fd.Close()
  557. fd, err = fs.OpenFile("fOoBaR", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0664)
  558. if err == nil {
  559. fd.Close()
  560. t.Fatalf("created an existing file while told not to")
  561. }
  562. fd, err = fs.OpenFile("FoObAr", os.O_RDWR|os.O_CREATE, 0664)
  563. if err != nil {
  564. t.Fatal(err)
  565. }
  566. fd.Close()
  567. fd, err = fs.OpenFile("FOOBAR", os.O_RDWR, 0664)
  568. if err != nil {
  569. t.Fatal(err)
  570. }
  571. fd.Close()
  572. }
  573. func testFakeFSRemoveAll(t *testing.T, fs Filesystem) {
  574. if err := fs.Mkdir("/foo", 0755); err != nil {
  575. t.Fatal(err)
  576. }
  577. filenames := []string{"bar", "baz", "qux"}
  578. for _, filename := range filenames {
  579. fd, err := fs.Create("/foo/" + filename)
  580. if err != nil {
  581. t.Fatalf("Could not create %s: %s", filename, err)
  582. } else {
  583. fd.Close()
  584. }
  585. }
  586. if err := fs.RemoveAll("/foo"); err != nil {
  587. t.Fatal(err)
  588. }
  589. if _, err := fs.Stat("/foo"); err == nil {
  590. t.Errorf("this should be an error, as file doesn not exist anymore")
  591. }
  592. if err := fs.RemoveAll("/foo/bar"); err != nil {
  593. t.Errorf("real systems don't return error here")
  594. }
  595. }
  596. func testFakeFSRemoveAllInsens(t *testing.T, fs Filesystem) {
  597. if err := fs.Mkdir("/Foo", 0755); err != nil {
  598. t.Fatal(err)
  599. }
  600. filenames := []string{"bar", "baz", "qux"}
  601. for _, filename := range filenames {
  602. fd, err := fs.Create("/FOO/" + filename)
  603. if err != nil {
  604. t.Fatalf("Could not create %s: %s", filename, err)
  605. }
  606. fd.Close()
  607. }
  608. if err := fs.RemoveAll("/fOo"); err != nil {
  609. t.Errorf("Could not remove dir: %s", err)
  610. }
  611. if _, err := fs.Stat("/foo"); err == nil {
  612. t.Errorf("this should be an error, as file doesn not exist anymore")
  613. }
  614. if err := fs.RemoveAll("/foO/bAr"); err != nil {
  615. t.Errorf("real systems don't return error here")
  616. }
  617. }
  618. func testFakeFSRemove(t *testing.T, fs Filesystem) {
  619. if err := fs.Mkdir("/Foo", 0755); err != nil {
  620. t.Fatal(err)
  621. }
  622. fd, err := fs.Create("/Foo/Bar")
  623. if err != nil {
  624. t.Fatal(err)
  625. } else {
  626. fd.Close()
  627. }
  628. if err := fs.Remove("/Foo"); err == nil {
  629. t.Errorf("not empty, should give error")
  630. }
  631. if err := fs.Remove("/Foo/Bar"); err != nil {
  632. t.Fatal(err)
  633. }
  634. if err := fs.Remove("/Foo"); err != nil {
  635. t.Fatal(err)
  636. }
  637. }
  638. func testFakeFSRemoveInsens(t *testing.T, fs Filesystem) {
  639. if err := fs.Mkdir("/Foo", 0755); err != nil {
  640. t.Fatal(err)
  641. }
  642. fd, err := fs.Create("/Foo/Bar")
  643. if err != nil {
  644. t.Fatal(err)
  645. }
  646. fd.Close()
  647. if err := fs.Remove("/FOO"); err == nil {
  648. t.Errorf("not empty, should give error")
  649. }
  650. if err := fs.Remove("/Foo/BaR"); err != nil {
  651. t.Fatal(err)
  652. }
  653. if err := fs.Remove("/FoO"); err != nil {
  654. t.Fatal(err)
  655. }
  656. }
  657. func testFakeFSSameFile(t *testing.T, fs Filesystem) {
  658. if err := fs.Mkdir("/Foo", 0755); err != nil {
  659. t.Fatal(err)
  660. }
  661. filenames := []string{"Bar", "Baz", "/Foo/Bar"}
  662. for _, filename := range filenames {
  663. if fd, err := fs.Create(filename); err != nil {
  664. t.Fatalf("Could not create %s: %s", filename, err)
  665. } else {
  666. fd.Close()
  667. if runtime.GOOS == "windows" {
  668. time.Sleep(1 * time.Millisecond)
  669. }
  670. }
  671. }
  672. testCases := []struct {
  673. f1 string
  674. f2 string
  675. want bool
  676. }{
  677. {"Bar", "Baz", false},
  678. {"Bar", "/Foo/Bar", false},
  679. {"Bar", "Bar", true},
  680. }
  681. for _, test := range testCases {
  682. assertSameFile(t, fs, test.f1, test.f2, test.want)
  683. }
  684. }
  685. func testFakeFSSameFileInsens(t *testing.T, fs Filesystem) {
  686. if err := fs.Mkdir("/Foo", 0755); err != nil {
  687. t.Fatal(err)
  688. }
  689. filenames := []string{"Bar", "Baz"}
  690. for _, filename := range filenames {
  691. fd, err := fs.Create(filename)
  692. if err != nil {
  693. t.Errorf("Could not create %s: %s", filename, err)
  694. }
  695. fd.Close()
  696. }
  697. testCases := []struct {
  698. f1 string
  699. f2 string
  700. want bool
  701. }{
  702. {"bAr", "baZ", false},
  703. {"baz", "BAZ", true},
  704. }
  705. for _, test := range testCases {
  706. assertSameFile(t, fs, test.f1, test.f2, test.want)
  707. }
  708. }
  709. func assertSameFile(t *testing.T, fs Filesystem, f1, f2 string, want bool) {
  710. t.Helper()
  711. fi1, err := fs.Stat(f1)
  712. if err != nil {
  713. t.Fatal(err)
  714. }
  715. fi2, err := fs.Stat(f2)
  716. if err != nil {
  717. t.Fatal(err)
  718. }
  719. got := fs.SameFile(fi1, fi2)
  720. if got != want {
  721. t.Errorf("for \"%s\" and \"%s\" want SameFile %v, got %v", f1, f2, want, got)
  722. }
  723. }
  724. func testFakeFSCreateInsens(t *testing.T, fs Filesystem) {
  725. fd1, err := fs.Create("FOO")
  726. if err != nil {
  727. t.Fatal(err)
  728. }
  729. defer fd1.Close()
  730. fd2, err := fs.Create("fOo")
  731. if err != nil {
  732. t.Fatal(err)
  733. }
  734. defer fd2.Close()
  735. if fd1.Name() != "FOO" {
  736. t.Errorf("name of the file created as \"FOO\" is %s", fd1.Name())
  737. }
  738. if fd2.Name() != "fOo" {
  739. t.Errorf("name of created file \"fOo\" is %s", fd2.Name())
  740. }
  741. // one would expect DirNames to show the last wrapperType, but in fact it shows
  742. // the original one
  743. assertDir(t, fs, "/", []string{"FOO"})
  744. }
  745. func TestReadWriteContent(t *testing.T) {
  746. fs := newFakeFilesystem("foo?content=true")
  747. fd, err := fs.Create("file")
  748. if err != nil {
  749. t.Fatal(err)
  750. }
  751. if _, err := fd.Write([]byte("foo")); err != nil {
  752. t.Fatal(err)
  753. }
  754. if _, err := fd.WriteAt([]byte("bar"), 5); err != nil {
  755. t.Fatal(err)
  756. }
  757. expected := []byte("foo\x00\x00bar")
  758. buf := make([]byte, len(expected)-1)
  759. n, err := fd.ReadAt(buf, 1) // note offset one byte
  760. if err != nil {
  761. t.Fatal(err)
  762. }
  763. if n != len(expected)-1 {
  764. t.Fatal("wrong number of bytes read")
  765. }
  766. if !bytes.Equal(buf[:n], expected[1:]) {
  767. fmt.Printf("%d %q\n", n, buf[:n])
  768. t.Error("wrong data in file")
  769. }
  770. }
  771. func cleanup(fs Filesystem) error {
  772. filenames, _ := fs.DirNames("/")
  773. for _, filename := range filenames {
  774. if filename != ".stfolder" {
  775. if err := fs.RemoveAll(filename); err != nil {
  776. return err
  777. }
  778. }
  779. }
  780. return nil
  781. }