github.com/urjitbhatia/afero@v1.1.0/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  	"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  }