OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / spf13 / afero / afero_test.go
1 // Copyright © 2014 Steve Francia <spf@spf13.com>.
2 // Copyright 2009 The Go Authors. All rights reserved.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package afero
16
17 import (
18         "bytes"
19         "fmt"
20         "io"
21         "io/ioutil"
22         "os"
23         "path/filepath"
24         "runtime"
25         "strings"
26         "syscall"
27         "testing"
28 )
29
30 var testName = "test.txt"
31 var Fss = []Fs{&MemMapFs{}, &OsFs{}}
32
33 var testRegistry map[Fs][]string = make(map[Fs][]string)
34
35 func testDir(fs Fs) string {
36         name, err := TempDir(fs, "", "afero")
37         if err != nil {
38                 panic(fmt.Sprint("unable to work with test dir", err))
39         }
40         testRegistry[fs] = append(testRegistry[fs], name)
41
42         return name
43 }
44
45 func tmpFile(fs Fs) File {
46         x, err := TempFile(fs, "", "afero")
47
48         if err != nil {
49                 panic(fmt.Sprint("unable to work with temp file", err))
50         }
51
52         testRegistry[fs] = append(testRegistry[fs], x.Name())
53
54         return x
55 }
56
57 //Read with length 0 should not return EOF.
58 func TestRead0(t *testing.T) {
59         for _, fs := range Fss {
60                 f := tmpFile(fs)
61                 defer f.Close()
62                 f.WriteString("Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
63
64                 var b []byte
65                 // b := make([]byte, 0)
66                 n, err := f.Read(b)
67                 if n != 0 || err != nil {
68                         t.Errorf("%v: Read(0) = %d, %v, want 0, nil", fs.Name(), n, err)
69                 }
70                 f.Seek(0, 0)
71                 b = make([]byte, 100)
72                 n, err = f.Read(b)
73                 if n <= 0 || err != nil {
74                         t.Errorf("%v: Read(100) = %d, %v, want >0, nil", fs.Name(), n, err)
75                 }
76         }
77 }
78
79 func TestOpenFile(t *testing.T) {
80         defer removeAllTestFiles(t)
81         for _, fs := range Fss {
82                 tmp := testDir(fs)
83                 path := filepath.Join(tmp, testName)
84
85                 f, err := fs.OpenFile(path, os.O_RDWR|os.O_CREATE, 0600)
86                 if err != nil {
87                         t.Error(fs.Name(), "OpenFile (O_CREATE) failed:", err)
88                         continue
89                 }
90                 io.WriteString(f, "initial")
91                 f.Close()
92
93                 f, err = fs.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0600)
94                 if err != nil {
95                         t.Error(fs.Name(), "OpenFile (O_APPEND) failed:", err)
96                         continue
97                 }
98                 io.WriteString(f, "|append")
99                 f.Close()
100
101                 f, err = fs.OpenFile(path, os.O_RDONLY, 0600)
102                 contents, _ := ioutil.ReadAll(f)
103                 expectedContents := "initial|append"
104                 if string(contents) != expectedContents {
105                         t.Errorf("%v: appending, expected '%v', got: '%v'", fs.Name(), expectedContents, string(contents))
106                 }
107                 f.Close()
108
109                 f, err = fs.OpenFile(path, os.O_RDWR|os.O_TRUNC, 0600)
110                 if err != nil {
111                         t.Error(fs.Name(), "OpenFile (O_TRUNC) failed:", err)
112                         continue
113                 }
114                 contents, _ = ioutil.ReadAll(f)
115                 if string(contents) != "" {
116                         t.Errorf("%v: expected truncated file, got: '%v'", fs.Name(), string(contents))
117                 }
118                 f.Close()
119         }
120 }
121
122 func TestCreate(t *testing.T) {
123         defer removeAllTestFiles(t)
124         for _, fs := range Fss {
125                 tmp := testDir(fs)
126                 path := filepath.Join(tmp, testName)
127
128                 f, err := fs.Create(path)
129                 if err != nil {
130                         t.Error(fs.Name(), "Create failed:", err)
131                         f.Close()
132                         continue
133                 }
134                 io.WriteString(f, "initial")
135                 f.Close()
136
137                 f, err = fs.Create(path)
138                 if err != nil {
139                         t.Error(fs.Name(), "Create failed:", err)
140                         f.Close()
141                         continue
142                 }
143                 secondContent := "second create"
144                 io.WriteString(f, secondContent)
145                 f.Close()
146
147                 f, err = fs.Open(path)
148                 if err != nil {
149                         t.Error(fs.Name(), "Open failed:", err)
150                         f.Close()
151                         continue
152                 }
153                 buf, err := ReadAll(f)
154                 if err != nil {
155                         t.Error(fs.Name(), "ReadAll failed:", err)
156                         f.Close()
157                         continue
158                 }
159                 if string(buf) != secondContent {
160                         t.Error(fs.Name(), "Content should be", "\""+secondContent+"\" but is \""+string(buf)+"\"")
161                         f.Close()
162                         continue
163                 }
164                 f.Close()
165         }
166 }
167
168 func TestMemFileRead(t *testing.T) {
169         f := tmpFile(new(MemMapFs))
170         // f := MemFileCreate("testfile")
171         f.WriteString("abcd")
172         f.Seek(0, 0)
173         b := make([]byte, 8)
174         n, err := f.Read(b)
175         if n != 4 {
176                 t.Errorf("didn't read all bytes: %v %v %v", n, err, b)
177         }
178         if err != nil {
179                 t.Errorf("err is not nil: %v %v %v", n, err, b)
180         }
181         n, err = f.Read(b)
182         if n != 0 {
183                 t.Errorf("read more bytes: %v %v %v", n, err, b)
184         }
185         if err != io.EOF {
186                 t.Errorf("error is not EOF: %v %v %v", n, err, b)
187         }
188 }
189
190 func TestRename(t *testing.T) {
191         defer removeAllTestFiles(t)
192         for _, fs := range Fss {
193                 tDir := testDir(fs)
194                 from := filepath.Join(tDir, "/renamefrom")
195                 to := filepath.Join(tDir, "/renameto")
196                 exists := filepath.Join(tDir, "/renameexists")
197                 file, err := fs.Create(from)
198                 if err != nil {
199                         t.Fatalf("%s: open %q failed: %v", fs.Name(), to, err)
200                 }
201                 if err = file.Close(); err != nil {
202                         t.Errorf("%s: close %q failed: %v", fs.Name(), to, err)
203                 }
204                 file, err = fs.Create(exists)
205                 if err != nil {
206                         t.Fatalf("%s: open %q failed: %v", fs.Name(), to, err)
207                 }
208                 if err = file.Close(); err != nil {
209                         t.Errorf("%s: close %q failed: %v", fs.Name(), to, err)
210                 }
211                 err = fs.Rename(from, to)
212                 if err != nil {
213                         t.Fatalf("%s: rename %q, %q failed: %v", fs.Name(), to, from, err)
214                 }
215                 file, err = fs.Create(from)
216                 if err != nil {
217                         t.Fatalf("%s: open %q failed: %v", fs.Name(), to, err)
218                 }
219                 if err = file.Close(); err != nil {
220                         t.Errorf("%s: close %q failed: %v", fs.Name(), to, err)
221                 }
222                 err = fs.Rename(from, exists)
223                 if err != nil {
224                         t.Errorf("%s: rename %q, %q failed: %v", fs.Name(), exists, from, err)
225                 }
226                 names, err := readDirNames(fs, tDir)
227                 if err != nil {
228                         t.Errorf("%s: readDirNames error: %v", fs.Name(), err)
229                 }
230                 found := false
231                 for _, e := range names {
232                         if e == "renamefrom" {
233                                 t.Error("File is still called renamefrom")
234                         }
235                         if e == "renameto" {
236                                 found = true
237                         }
238                 }
239                 if !found {
240                         t.Error("File was not renamed to renameto")
241                 }
242
243                 _, err = fs.Stat(to)
244                 if err != nil {
245                         t.Errorf("%s: stat %q failed: %v", fs.Name(), to, err)
246                 }
247         }
248 }
249
250 func TestRemove(t *testing.T) {
251         for _, fs := range Fss {
252
253                 x, err := TempFile(fs, "", "afero")
254                 if err != nil {
255                         t.Error(fmt.Sprint("unable to work with temp file", err))
256                 }
257
258                 path := x.Name()
259                 x.Close()
260
261                 tDir := filepath.Dir(path)
262
263                 err = fs.Remove(path)
264                 if err != nil {
265                         t.Errorf("%v: Remove() failed: %v", fs.Name(), err)
266                         continue
267                 }
268
269                 _, err = fs.Stat(path)
270                 if !os.IsNotExist(err) {
271                         t.Errorf("%v: Remove() didn't remove file", fs.Name())
272                         continue
273                 }
274
275                 // Deleting non-existent file should raise error
276                 err = fs.Remove(path)
277                 if !os.IsNotExist(err) {
278                         t.Errorf("%v: Remove() didn't raise error for non-existent file", fs.Name())
279                 }
280
281                 f, err := fs.Open(tDir)
282                 if err != nil {
283                         t.Error("TestDir should still exist:", err)
284                 }
285
286                 names, err := f.Readdirnames(-1)
287                 if err != nil {
288                         t.Error("Readdirnames failed:", err)
289                 }
290
291                 for _, e := range names {
292                         if e == testName {
293                                 t.Error("File was not removed from parent directory")
294                         }
295                 }
296         }
297 }
298
299 func TestTruncate(t *testing.T) {
300         defer removeAllTestFiles(t)
301         for _, fs := range Fss {
302                 f := tmpFile(fs)
303                 defer f.Close()
304
305                 checkSize(t, f, 0)
306                 f.Write([]byte("hello, world\n"))
307                 checkSize(t, f, 13)
308                 f.Truncate(10)
309                 checkSize(t, f, 10)
310                 f.Truncate(1024)
311                 checkSize(t, f, 1024)
312                 f.Truncate(0)
313                 checkSize(t, f, 0)
314                 _, err := f.Write([]byte("surprise!"))
315                 if err == nil {
316                         checkSize(t, f, 13+9) // wrote at offset past where hello, world was.
317                 }
318         }
319 }
320
321 func TestSeek(t *testing.T) {
322         defer removeAllTestFiles(t)
323         for _, fs := range Fss {
324                 f := tmpFile(fs)
325                 defer f.Close()
326
327                 const data = "hello, world\n"
328                 io.WriteString(f, data)
329
330                 type test struct {
331                         in     int64
332                         whence int
333                         out    int64
334                 }
335                 var tests = []test{
336                         {0, 1, int64(len(data))},
337                         {0, 0, 0},
338                         {5, 0, 5},
339                         {0, 2, int64(len(data))},
340                         {0, 0, 0},
341                         {-1, 2, int64(len(data)) - 1},
342                         {1 << 33, 0, 1 << 33},
343                         {1 << 33, 2, 1<<33 + int64(len(data))},
344                 }
345                 for i, tt := range tests {
346                         off, err := f.Seek(tt.in, tt.whence)
347                         if off != tt.out || err != nil {
348                                 if e, ok := err.(*os.PathError); ok && e.Err == syscall.EINVAL && tt.out > 1<<32 {
349                                         // Reiserfs rejects the big seeks.
350                                         // http://code.google.com/p/go/issues/detail?id=91
351                                         break
352                                 }
353                                 t.Errorf("#%d: Seek(%v, %v) = %v, %v want %v, nil", i, tt.in, tt.whence, off, err, tt.out)
354                         }
355                 }
356         }
357 }
358
359 func TestReadAt(t *testing.T) {
360         defer removeAllTestFiles(t)
361         for _, fs := range Fss {
362                 f := tmpFile(fs)
363                 defer f.Close()
364
365                 const data = "hello, world\n"
366                 io.WriteString(f, data)
367
368                 b := make([]byte, 5)
369                 n, err := f.ReadAt(b, 7)
370                 if err != nil || n != len(b) {
371                         t.Fatalf("ReadAt 7: %d, %v", n, err)
372                 }
373                 if string(b) != "world" {
374                         t.Fatalf("ReadAt 7: have %q want %q", string(b), "world")
375                 }
376         }
377 }
378
379 func TestWriteAt(t *testing.T) {
380         defer removeAllTestFiles(t)
381         for _, fs := range Fss {
382                 f := tmpFile(fs)
383                 defer f.Close()
384
385                 const data = "hello, world\n"
386                 io.WriteString(f, data)
387
388                 n, err := f.WriteAt([]byte("WORLD"), 7)
389                 if err != nil || n != 5 {
390                         t.Fatalf("WriteAt 7: %d, %v", n, err)
391                 }
392
393                 f2, err := fs.Open(f.Name())
394                 if err != nil {
395                         t.Fatalf("%v: ReadFile %s: %v", fs.Name(), f.Name(), err)
396                 }
397                 defer f2.Close()
398                 buf := new(bytes.Buffer)
399                 buf.ReadFrom(f2)
400                 b := buf.Bytes()
401                 if string(b) != "hello, WORLD\n" {
402                         t.Fatalf("after write: have %q want %q", string(b), "hello, WORLD\n")
403                 }
404
405         }
406 }
407
408 func setupTestDir(t *testing.T, fs Fs) string {
409         path := testDir(fs)
410         return setupTestFiles(t, fs, path)
411 }
412
413 func setupTestDirRoot(t *testing.T, fs Fs) string {
414         path := testDir(fs)
415         setupTestFiles(t, fs, path)
416         return path
417 }
418
419 func setupTestDirReusePath(t *testing.T, fs Fs, path string) string {
420         testRegistry[fs] = append(testRegistry[fs], path)
421         return setupTestFiles(t, fs, path)
422 }
423
424 func setupTestFiles(t *testing.T, fs Fs, path string) string {
425         testSubDir := filepath.Join(path, "more", "subdirectories", "for", "testing", "we")
426         err := fs.MkdirAll(testSubDir, 0700)
427         if err != nil && !os.IsExist(err) {
428                 t.Fatal(err)
429         }
430
431         f, err := fs.Create(filepath.Join(testSubDir, "testfile1"))
432         if err != nil {
433                 t.Fatal(err)
434         }
435         f.WriteString("Testfile 1 content")
436         f.Close()
437
438         f, err = fs.Create(filepath.Join(testSubDir, "testfile2"))
439         if err != nil {
440                 t.Fatal(err)
441         }
442         f.WriteString("Testfile 2 content")
443         f.Close()
444
445         f, err = fs.Create(filepath.Join(testSubDir, "testfile3"))
446         if err != nil {
447                 t.Fatal(err)
448         }
449         f.WriteString("Testfile 3 content")
450         f.Close()
451
452         f, err = fs.Create(filepath.Join(testSubDir, "testfile4"))
453         if err != nil {
454                 t.Fatal(err)
455         }
456         f.WriteString("Testfile 4 content")
457         f.Close()
458         return testSubDir
459 }
460
461 func TestReaddirnames(t *testing.T) {
462         defer removeAllTestFiles(t)
463         for _, fs := range Fss {
464                 testSubDir := setupTestDir(t, fs)
465                 tDir := filepath.Dir(testSubDir)
466
467                 root, err := fs.Open(tDir)
468                 if err != nil {
469                         t.Fatal(fs.Name(), tDir, err)
470                 }
471                 defer root.Close()
472
473                 namesRoot, err := root.Readdirnames(-1)
474                 if err != nil {
475                         t.Fatal(fs.Name(), namesRoot, err)
476                 }
477
478                 sub, err := fs.Open(testSubDir)
479                 if err != nil {
480                         t.Fatal(err)
481                 }
482                 defer sub.Close()
483
484                 namesSub, err := sub.Readdirnames(-1)
485                 if err != nil {
486                         t.Fatal(fs.Name(), namesSub, err)
487                 }
488
489                 findNames(fs, t, tDir, testSubDir, namesRoot, namesSub)
490         }
491 }
492
493 func TestReaddirSimple(t *testing.T) {
494         defer removeAllTestFiles(t)
495         for _, fs := range Fss {
496                 testSubDir := setupTestDir(t, fs)
497                 tDir := filepath.Dir(testSubDir)
498
499                 root, err := fs.Open(tDir)
500                 if err != nil {
501                         t.Fatal(err)
502                 }
503                 defer root.Close()
504
505                 rootInfo, err := root.Readdir(1)
506                 if err != nil {
507                         t.Log(myFileInfo(rootInfo))
508                         t.Error(err)
509                 }
510
511                 rootInfo, err = root.Readdir(5)
512                 if err != io.EOF {
513                         t.Log(myFileInfo(rootInfo))
514                         t.Error(err)
515                 }
516
517                 sub, err := fs.Open(testSubDir)
518                 if err != nil {
519                         t.Fatal(err)
520                 }
521                 defer sub.Close()
522
523                 subInfo, err := sub.Readdir(5)
524                 if err != nil {
525                         t.Log(myFileInfo(subInfo))
526                         t.Error(err)
527                 }
528         }
529 }
530
531 func TestReaddir(t *testing.T) {
532         defer removeAllTestFiles(t)
533         for num := 0; num < 6; num++ {
534                 outputs := make([]string, len(Fss))
535                 infos := make([]string, len(Fss))
536                 for i, fs := range Fss {
537                         testSubDir := setupTestDir(t, fs)
538                         //tDir := filepath.Dir(testSubDir)
539                         root, err := fs.Open(testSubDir)
540                         if err != nil {
541                                 t.Fatal(err)
542                         }
543                         defer root.Close()
544
545                         for j := 0; j < 6; j++ {
546                                 info, err := root.Readdir(num)
547                                 outputs[i] += fmt.Sprintf("%v  Error: %v\n", myFileInfo(info), err)
548                                 infos[i] += fmt.Sprintln(len(info), err)
549                         }
550                 }
551
552                 fail := false
553                 for i, o := range infos {
554                         if i == 0 {
555                                 continue
556                         }
557                         if o != infos[i-1] {
558                                 fail = true
559                                 break
560                         }
561                 }
562                 if fail {
563                         t.Log("Readdir outputs not equal for Readdir(", num, ")")
564                         for i, o := range outputs {
565                                 t.Log(Fss[i].Name())
566                                 t.Log(o)
567                         }
568                         t.Fail()
569                 }
570         }
571 }
572
573 type myFileInfo []os.FileInfo
574
575 func (m myFileInfo) String() string {
576         out := "Fileinfos:\n"
577         for _, e := range m {
578                 out += "  " + e.Name() + "\n"
579         }
580         return out
581 }
582
583 func TestReaddirAll(t *testing.T) {
584         defer removeAllTestFiles(t)
585         for _, fs := range Fss {
586                 testSubDir := setupTestDir(t, fs)
587                 tDir := filepath.Dir(testSubDir)
588
589                 root, err := fs.Open(tDir)
590                 if err != nil {
591                         t.Fatal(err)
592                 }
593                 defer root.Close()
594
595                 rootInfo, err := root.Readdir(-1)
596                 if err != nil {
597                         t.Fatal(err)
598                 }
599                 var namesRoot = []string{}
600                 for _, e := range rootInfo {
601                         namesRoot = append(namesRoot, e.Name())
602                 }
603
604                 sub, err := fs.Open(testSubDir)
605                 if err != nil {
606                         t.Fatal(err)
607                 }
608                 defer sub.Close()
609
610                 subInfo, err := sub.Readdir(-1)
611                 if err != nil {
612                         t.Fatal(err)
613                 }
614                 var namesSub = []string{}
615                 for _, e := range subInfo {
616                         namesSub = append(namesSub, e.Name())
617                 }
618
619                 findNames(fs, t, tDir, testSubDir, namesRoot, namesSub)
620         }
621 }
622
623 func findNames(fs Fs, t *testing.T, tDir, testSubDir string, root, sub []string) {
624         var foundRoot bool
625         for _, e := range root {
626                 f, err := fs.Open(filepath.Join(tDir, e))
627                 if err != nil {
628                         t.Error("Open", filepath.Join(tDir, e), ":", err)
629                 }
630                 defer f.Close()
631
632                 if equal(e, "we") {
633                         foundRoot = true
634                 }
635         }
636         if !foundRoot {
637                 t.Logf("Names root: %v", root)
638                 t.Logf("Names sub: %v", sub)
639                 t.Error("Didn't find subdirectory we")
640         }
641
642         var found1, found2 bool
643         for _, e := range sub {
644                 f, err := fs.Open(filepath.Join(testSubDir, e))
645                 if err != nil {
646                         t.Error("Open", filepath.Join(testSubDir, e), ":", err)
647                 }
648                 defer f.Close()
649
650                 if equal(e, "testfile1") {
651                         found1 = true
652                 }
653                 if equal(e, "testfile2") {
654                         found2 = true
655                 }
656         }
657
658         if !found1 {
659                 t.Logf("Names root: %v", root)
660                 t.Logf("Names sub: %v", sub)
661                 t.Error("Didn't find testfile1")
662         }
663         if !found2 {
664                 t.Logf("Names root: %v", root)
665                 t.Logf("Names sub: %v", sub)
666                 t.Error("Didn't find testfile2")
667         }
668 }
669
670 func removeAllTestFiles(t *testing.T) {
671         for fs, list := range testRegistry {
672                 for _, path := range list {
673                         if err := fs.RemoveAll(path); err != nil {
674                                 t.Error(fs.Name(), err)
675                         }
676                 }
677         }
678         testRegistry = make(map[Fs][]string)
679 }
680
681 func equal(name1, name2 string) (r bool) {
682         switch runtime.GOOS {
683         case "windows":
684                 r = strings.ToLower(name1) == strings.ToLower(name2)
685         default:
686                 r = name1 == name2
687         }
688         return
689 }
690
691 func checkSize(t *testing.T, f File, size int64) {
692         dir, err := f.Stat()
693         if err != nil {
694                 t.Fatalf("Stat %q (looking for size %d): %s", f.Name(), size, err)
695         }
696         if dir.Size() != size {
697                 t.Errorf("Stat %q: size %d want %d", f.Name(), dir.Size(), size)
698         }
699 }