OSDN Git Service

new repo
[bytom/vapor.git] / vendor / github.com / spf13 / afero / memmap_test.go
1 package afero
2
3 import (
4         "fmt"
5         "os"
6         "path/filepath"
7         "runtime"
8         "testing"
9         "time"
10 )
11
12 func TestNormalizePath(t *testing.T) {
13         type test struct {
14                 input    string
15                 expected string
16         }
17
18         data := []test{
19                 {".", FilePathSeparator},
20                 {"./", FilePathSeparator},
21                 {"..", FilePathSeparator},
22                 {"../", FilePathSeparator},
23                 {"./..", FilePathSeparator},
24                 {"./../", FilePathSeparator},
25         }
26
27         for i, d := range data {
28                 cpath := normalizePath(d.input)
29                 if d.expected != cpath {
30                         t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, cpath)
31                 }
32         }
33 }
34
35 func TestPathErrors(t *testing.T) {
36         path := filepath.Join(".", "some", "path")
37         path2 := filepath.Join(".", "different", "path")
38         fs := NewMemMapFs()
39         perm := os.FileMode(0755)
40
41         // relevant functions:
42         // func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
43         // func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error
44         // func (m *MemMapFs) Create(name string) (File, error)
45         // func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error
46         // func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error
47         // func (m *MemMapFs) Open(name string) (File, error)
48         // func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
49         // func (m *MemMapFs) Remove(name string) error
50         // func (m *MemMapFs) Rename(oldname, newname string) error
51         // func (m *MemMapFs) Stat(name string) (os.FileInfo, error)
52
53         err := fs.Chmod(path, perm)
54         checkPathError(t, err, "Chmod")
55
56         err = fs.Chtimes(path, time.Now(), time.Now())
57         checkPathError(t, err, "Chtimes")
58
59         // fs.Create doesn't return an error
60
61         err = fs.Mkdir(path2, perm)
62         if err != nil {
63                 t.Error(err)
64         }
65         err = fs.Mkdir(path2, perm)
66         checkPathError(t, err, "Mkdir")
67
68         err = fs.MkdirAll(path2, perm)
69         if err != nil {
70                 t.Error("MkdirAll:", err)
71         }
72
73         _, err = fs.Open(path)
74         checkPathError(t, err, "Open")
75
76         _, err = fs.OpenFile(path, os.O_RDWR, perm)
77         checkPathError(t, err, "OpenFile")
78
79         err = fs.Remove(path)
80         checkPathError(t, err, "Remove")
81
82         err = fs.RemoveAll(path)
83         if err != nil {
84                 t.Error("RemoveAll:", err)
85         }
86
87         err = fs.Rename(path, path2)
88         checkPathError(t, err, "Rename")
89
90         _, err = fs.Stat(path)
91         checkPathError(t, err, "Stat")
92 }
93
94 func checkPathError(t *testing.T, err error, op string) {
95         pathErr, ok := err.(*os.PathError)
96         if !ok {
97                 t.Error(op+":", err, "is not a os.PathError")
98                 return
99         }
100         _, ok = pathErr.Err.(*os.PathError)
101         if ok {
102                 t.Error(op+":", err, "contains another os.PathError")
103         }
104 }
105
106 // Ensure Permissions are set on OpenFile/Mkdir/MkdirAll
107 func TestPermSet(t *testing.T) {
108         const fileName = "/myFileTest"
109         const dirPath = "/myDirTest"
110         const dirPathAll = "/my/path/to/dir"
111
112         const fileMode = os.FileMode(0765)
113         // directories will also have the directory bit set
114         const dirMode = fileMode | os.ModeDir
115
116         fs := NewMemMapFs()
117
118         // Test Openfile
119         f, err := fs.OpenFile(fileName, os.O_CREATE, fileMode)
120         if err != nil {
121                 t.Errorf("OpenFile Create failed: %s", err)
122                 return
123         }
124         f.Close()
125
126         s, err := fs.Stat(fileName)
127         if err != nil {
128                 t.Errorf("Stat failed: %s", err)
129                 return
130         }
131         if s.Mode().String() != fileMode.String() {
132                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), fileMode.String())
133                 return
134         }
135
136         // Test Mkdir
137         err = fs.Mkdir(dirPath, dirMode)
138         if err != nil {
139                 t.Errorf("MkDir Create failed: %s", err)
140                 return
141         }
142         s, err = fs.Stat(dirPath)
143         if err != nil {
144                 t.Errorf("Stat failed: %s", err)
145                 return
146         }
147         // sets File
148         if s.Mode().String() != dirMode.String() {
149                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
150                 return
151         }
152
153         // Test MkdirAll
154         err = fs.MkdirAll(dirPathAll, dirMode)
155         if err != nil {
156                 t.Errorf("MkDir Create failed: %s", err)
157                 return
158         }
159         s, err = fs.Stat(dirPathAll)
160         if err != nil {
161                 t.Errorf("Stat failed: %s", err)
162                 return
163         }
164         if s.Mode().String() != dirMode.String() {
165                 t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
166                 return
167         }
168 }
169
170 // Fails if multiple file objects use the same file.at counter in MemMapFs
171 func TestMultipleOpenFiles(t *testing.T) {
172         defer removeAllTestFiles(t)
173         const fileName = "afero-demo2.txt"
174
175         var data = make([][]byte, len(Fss))
176
177         for i, fs := range Fss {
178                 dir := testDir(fs)
179                 path := filepath.Join(dir, fileName)
180                 fh1, err := fs.Create(path)
181                 if err != nil {
182                         t.Error("fs.Create failed: " + err.Error())
183                 }
184                 _, err = fh1.Write([]byte("test"))
185                 if err != nil {
186                         t.Error("fh.Write failed: " + err.Error())
187                 }
188                 _, err = fh1.Seek(0, os.SEEK_SET)
189                 if err != nil {
190                         t.Error(err)
191                 }
192
193                 fh2, err := fs.OpenFile(path, os.O_RDWR, 0777)
194                 if err != nil {
195                         t.Error("fs.OpenFile failed: " + err.Error())
196                 }
197                 _, err = fh2.Seek(0, os.SEEK_END)
198                 if err != nil {
199                         t.Error(err)
200                 }
201                 _, err = fh2.Write([]byte("data"))
202                 if err != nil {
203                         t.Error(err)
204                 }
205                 err = fh2.Close()
206                 if err != nil {
207                         t.Error(err)
208                 }
209
210                 _, err = fh1.Write([]byte("data"))
211                 if err != nil {
212                         t.Error(err)
213                 }
214                 err = fh1.Close()
215                 if err != nil {
216                         t.Error(err)
217                 }
218                 // the file now should contain "datadata"
219                 data[i], err = ReadFile(fs, path)
220                 if err != nil {
221                         t.Error(err)
222                 }
223         }
224
225         for i, fs := range Fss {
226                 if i == 0 {
227                         continue
228                 }
229                 if string(data[0]) != string(data[i]) {
230                         t.Errorf("%s and %s don't behave the same\n"+
231                                 "%s: \"%s\"\n%s: \"%s\"\n",
232                                 Fss[0].Name(), fs.Name(), Fss[0].Name(), data[0], fs.Name(), data[i])
233                 }
234         }
235 }
236
237 // Test if file.Write() fails when opened as read only
238 func TestReadOnly(t *testing.T) {
239         defer removeAllTestFiles(t)
240         const fileName = "afero-demo.txt"
241
242         for _, fs := range Fss {
243                 dir := testDir(fs)
244                 path := filepath.Join(dir, fileName)
245
246                 f, err := fs.Create(path)
247                 if err != nil {
248                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
249                 }
250                 _, err = f.Write([]byte("test"))
251                 if err != nil {
252                         t.Error(fs.Name()+":", "Write failed: "+err.Error())
253                 }
254                 f.Close()
255
256                 f, err = fs.Open(path)
257                 if err != nil {
258                         t.Error("fs.Open failed: " + err.Error())
259                 }
260                 _, err = f.Write([]byte("data"))
261                 if err == nil {
262                         t.Error(fs.Name()+":", "No write error")
263                 }
264                 f.Close()
265
266                 f, err = fs.OpenFile(path, os.O_RDONLY, 0644)
267                 if err != nil {
268                         t.Error("fs.Open failed: " + err.Error())
269                 }
270                 _, err = f.Write([]byte("data"))
271                 if err == nil {
272                         t.Error(fs.Name()+":", "No write error")
273                 }
274                 f.Close()
275         }
276 }
277
278 func TestWriteCloseTime(t *testing.T) {
279         defer removeAllTestFiles(t)
280         const fileName = "afero-demo.txt"
281
282         for _, fs := range Fss {
283                 dir := testDir(fs)
284                 path := filepath.Join(dir, fileName)
285
286                 f, err := fs.Create(path)
287                 if err != nil {
288                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
289                 }
290                 f.Close()
291
292                 f, err = fs.Create(path)
293                 if err != nil {
294                         t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
295                 }
296                 fi, err := f.Stat()
297                 if err != nil {
298                         t.Error(fs.Name()+":", "Stat failed: "+err.Error())
299                 }
300                 timeBefore := fi.ModTime()
301
302                 // sorry for the delay, but we have to make sure time advances,
303                 // also on non Un*x systems...
304                 switch runtime.GOOS {
305                 case "windows":
306                         time.Sleep(2 * time.Second)
307                 case "darwin":
308                         time.Sleep(1 * time.Second)
309                 default: // depending on the FS, this may work with < 1 second, on my old ext3 it does not
310                         time.Sleep(1 * time.Second)
311                 }
312
313                 _, err = f.Write([]byte("test"))
314                 if err != nil {
315                         t.Error(fs.Name()+":", "Write failed: "+err.Error())
316                 }
317                 f.Close()
318                 fi, err = fs.Stat(path)
319                 if err != nil {
320                         t.Error(fs.Name()+":", "fs.Stat failed: "+err.Error())
321                 }
322                 if fi.ModTime().Equal(timeBefore) {
323                         t.Error(fs.Name()+":", "ModTime was not set on Close()")
324                 }
325         }
326 }
327
328 // This test should be run with the race detector on:
329 // go test -race -v -timeout 10s -run TestRacingDeleteAndClose
330 func TestRacingDeleteAndClose(t *testing.T) {
331         fs := NewMemMapFs()
332         pathname := "testfile"
333         f, err := fs.Create(pathname)
334         if err != nil {
335                 t.Fatal(err)
336         }
337
338         in := make(chan bool)
339
340         go func() {
341                 <-in
342                 f.Close()
343         }()
344         go func() {
345                 <-in
346                 fs.Remove(pathname)
347         }()
348         close(in)
349 }
350
351 // This test should be run with the race detector on:
352 // go test -run TestMemFsDataRace -race
353 func TestMemFsDataRace(t *testing.T) {
354         const dir = "test_dir"
355         fs := NewMemMapFs()
356
357         if err := fs.MkdirAll(dir, 0777); err != nil {
358                 t.Fatal(err)
359         }
360
361         const n = 1000
362         done := make(chan struct{})
363
364         go func() {
365                 defer close(done)
366                 for i := 0; i < n; i++ {
367                         fname := filepath.Join(dir, fmt.Sprintf("%d.txt", i))
368                         if err := WriteFile(fs, fname, []byte(""), 0777); err != nil {
369                                 panic(err)
370                         }
371                         if err := fs.Remove(fname); err != nil {
372                                 panic(err)
373                         }
374                 }
375         }()
376
377 loop:
378         for {
379                 select {
380                 case <-done:
381                         break loop
382                 default:
383                         _, err := ReadDir(fs, dir)
384                         if err != nil {
385                                 t.Fatal(err)
386                         }
387                 }
388         }
389 }
390
391 func TestMemFsDirMode(t *testing.T) {
392         fs := NewMemMapFs()
393         err := fs.Mkdir("/testDir1", 0644)
394         if err != nil {
395                 t.Error(err)
396         }
397         err = fs.MkdirAll("/sub/testDir2", 0644)
398         if err != nil {
399                 t.Error(err)
400         }
401         info, err := fs.Stat("/testDir1")
402         if err != nil {
403                 t.Error(err)
404         }
405         if !info.IsDir() {
406                 t.Error("should be a directory")
407         }
408         if !info.Mode().IsDir() {
409                 t.Error("FileMode is not directory")
410         }
411         info, err = fs.Stat("/sub/testDir2")
412         if err != nil {
413                 t.Error(err)
414         }
415         if !info.IsDir() {
416                 t.Error("should be a directory")
417         }
418         if !info.Mode().IsDir() {
419                 t.Error("FileMode is not directory")
420         }
421 }