github.com/gozelle/afero@v0.0.0-20230510083704-09e2ff18f19e/afero_test.go (about)

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