github.com/MRtecno98/afero@v1.9.3/memmap_test.go (about)

     1  package afero
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"os"
     7  	"path/filepath"
     8  	"runtime"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  func TestNormalizePath(t *testing.T) {
    14  	type test struct {
    15  		input    string
    16  		expected string
    17  	}
    18  
    19  	data := []test{
    20  		{".", FilePathSeparator},
    21  		{"./", FilePathSeparator},
    22  		{"..", FilePathSeparator},
    23  		{"../", FilePathSeparator},
    24  		{"./..", FilePathSeparator},
    25  		{"./../", FilePathSeparator},
    26  	}
    27  
    28  	for i, d := range data {
    29  		cpath := normalizePath(d.input)
    30  		if d.expected != cpath {
    31  			t.Errorf("Test %d failed. Expected %q got %q", i, d.expected, cpath)
    32  		}
    33  	}
    34  }
    35  
    36  func TestPathErrors(t *testing.T) {
    37  	path := filepath.Join(".", "some", "path")
    38  	path2 := filepath.Join(".", "different", "path")
    39  	fs := NewMemMapFs()
    40  	perm := os.FileMode(0755)
    41  	uid := 1000
    42  	gid := 1000
    43  
    44  	// relevant functions:
    45  	// func (m *MemMapFs) Chmod(name string, mode os.FileMode) error
    46  	// func (m *MemMapFs) Chtimes(name string, atime time.Time, mtime time.Time) error
    47  	// func (m *MemMapFs) Create(name string) (File, error)
    48  	// func (m *MemMapFs) Mkdir(name string, perm os.FileMode) error
    49  	// func (m *MemMapFs) MkdirAll(path string, perm os.FileMode) error
    50  	// func (m *MemMapFs) Open(name string) (File, error)
    51  	// func (m *MemMapFs) OpenFile(name string, flag int, perm os.FileMode) (File, error)
    52  	// func (m *MemMapFs) Remove(name string) error
    53  	// func (m *MemMapFs) Rename(oldname, newname string) error
    54  	// func (m *MemMapFs) Stat(name string) (os.FileInfo, error)
    55  
    56  	err := fs.Chmod(path, perm)
    57  	checkPathError(t, err, "Chmod")
    58  
    59  	err = fs.Chown(path, uid, gid)
    60  	checkPathError(t, err, "Chown")
    61  
    62  	err = fs.Chtimes(path, time.Now(), time.Now())
    63  	checkPathError(t, err, "Chtimes")
    64  
    65  	// fs.Create doesn't return an error
    66  
    67  	err = fs.Mkdir(path2, perm)
    68  	if err != nil {
    69  		t.Error(err)
    70  	}
    71  	err = fs.Mkdir(path2, perm)
    72  	checkPathError(t, err, "Mkdir")
    73  
    74  	err = fs.MkdirAll(path2, perm)
    75  	if err != nil {
    76  		t.Error("MkdirAll:", err)
    77  	}
    78  
    79  	_, err = fs.Open(path)
    80  	checkPathError(t, err, "Open")
    81  
    82  	_, err = fs.OpenFile(path, os.O_RDWR, perm)
    83  	checkPathError(t, err, "OpenFile")
    84  
    85  	err = fs.Remove(path)
    86  	checkPathError(t, err, "Remove")
    87  
    88  	err = fs.RemoveAll(path)
    89  	if err != nil {
    90  		t.Error("RemoveAll:", err)
    91  	}
    92  
    93  	err = fs.Rename(path, path2)
    94  	checkPathError(t, err, "Rename")
    95  
    96  	_, err = fs.Stat(path)
    97  	checkPathError(t, err, "Stat")
    98  }
    99  
   100  func checkPathError(t *testing.T, err error, op string) {
   101  	pathErr, ok := err.(*os.PathError)
   102  	if !ok {
   103  		t.Error(op+":", err, "is not a os.PathError")
   104  		return
   105  	}
   106  	_, ok = pathErr.Err.(*os.PathError)
   107  	if ok {
   108  		t.Error(op+":", err, "contains another os.PathError")
   109  	}
   110  }
   111  
   112  // Ensure os.O_EXCL is correctly handled.
   113  func TestOpenFileExcl(t *testing.T) {
   114  	const fileName = "/myFileTest"
   115  	const fileMode = os.FileMode(0765)
   116  
   117  	fs := NewMemMapFs()
   118  
   119  	// First creation should succeed.
   120  	f, err := fs.OpenFile(fileName, os.O_CREATE|os.O_EXCL, fileMode)
   121  	if err != nil {
   122  		t.Errorf("OpenFile Create Excl failed: %s", err)
   123  		return
   124  	}
   125  	f.Close()
   126  
   127  	// Second creation should fail.
   128  	_, err = fs.OpenFile(fileName, os.O_CREATE|os.O_EXCL, fileMode)
   129  	if err == nil {
   130  		t.Errorf("OpenFile Create Excl should have failed, but it didn't")
   131  	}
   132  	checkPathError(t, err, "Open")
   133  }
   134  
   135  // Ensure Permissions are set on OpenFile/Mkdir/MkdirAll
   136  func TestPermSet(t *testing.T) {
   137  	const fileName = "/myFileTest"
   138  	const dirPath = "/myDirTest"
   139  	const dirPathAll = "/my/path/to/dir"
   140  
   141  	const fileMode = os.FileMode(0765)
   142  	// directories will also have the directory bit set
   143  	const dirMode = fileMode | os.ModeDir
   144  
   145  	fs := NewMemMapFs()
   146  
   147  	// Test Openfile
   148  	f, err := fs.OpenFile(fileName, os.O_CREATE, fileMode)
   149  	if err != nil {
   150  		t.Errorf("OpenFile Create failed: %s", err)
   151  		return
   152  	}
   153  	f.Close()
   154  
   155  	s, err := fs.Stat(fileName)
   156  	if err != nil {
   157  		t.Errorf("Stat failed: %s", err)
   158  		return
   159  	}
   160  	if s.Mode().String() != fileMode.String() {
   161  		t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), fileMode.String())
   162  		return
   163  	}
   164  
   165  	// Test Mkdir
   166  	err = fs.Mkdir(dirPath, dirMode)
   167  	if err != nil {
   168  		t.Errorf("MkDir Create failed: %s", err)
   169  		return
   170  	}
   171  	s, err = fs.Stat(dirPath)
   172  	if err != nil {
   173  		t.Errorf("Stat failed: %s", err)
   174  		return
   175  	}
   176  	// sets File
   177  	if s.Mode().String() != dirMode.String() {
   178  		t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
   179  		return
   180  	}
   181  
   182  	// Test MkdirAll
   183  	err = fs.MkdirAll(dirPathAll, dirMode)
   184  	if err != nil {
   185  		t.Errorf("MkDir Create failed: %s", err)
   186  		return
   187  	}
   188  	s, err = fs.Stat(dirPathAll)
   189  	if err != nil {
   190  		t.Errorf("Stat failed: %s", err)
   191  		return
   192  	}
   193  	if s.Mode().String() != dirMode.String() {
   194  		t.Errorf("Permissions Incorrect: %s != %s", s.Mode().String(), dirMode.String())
   195  		return
   196  	}
   197  }
   198  
   199  // Fails if multiple file objects use the same file.at counter in MemMapFs
   200  func TestMultipleOpenFiles(t *testing.T) {
   201  	defer removeAllTestFiles(t)
   202  	const fileName = "afero-demo2.txt"
   203  
   204  	var data = make([][]byte, len(Fss))
   205  
   206  	for i, fs := range Fss {
   207  		dir := testDir(fs)
   208  		path := filepath.Join(dir, fileName)
   209  		fh1, err := fs.Create(path)
   210  		if err != nil {
   211  			t.Error("fs.Create failed: " + err.Error())
   212  		}
   213  		_, err = fh1.Write([]byte("test"))
   214  		if err != nil {
   215  			t.Error("fh.Write failed: " + err.Error())
   216  		}
   217  		_, err = fh1.Seek(0, io.SeekStart)
   218  		if err != nil {
   219  			t.Error(err)
   220  		}
   221  
   222  		fh2, err := fs.OpenFile(path, os.O_RDWR, 0777)
   223  		if err != nil {
   224  			t.Error("fs.OpenFile failed: " + err.Error())
   225  		}
   226  		_, err = fh2.Seek(0, os.SEEK_END)
   227  		if err != nil {
   228  			t.Error(err)
   229  		}
   230  		_, err = fh2.Write([]byte("data"))
   231  		if err != nil {
   232  			t.Error(err)
   233  		}
   234  		err = fh2.Close()
   235  		if err != nil {
   236  			t.Error(err)
   237  		}
   238  
   239  		_, err = fh1.Write([]byte("data"))
   240  		if err != nil {
   241  			t.Error(err)
   242  		}
   243  		err = fh1.Close()
   244  		if err != nil {
   245  			t.Error(err)
   246  		}
   247  		// the file now should contain "datadata"
   248  		data[i], err = ReadFile(fs, path)
   249  		if err != nil {
   250  			t.Error(err)
   251  		}
   252  	}
   253  
   254  	for i, fs := range Fss {
   255  		if i == 0 {
   256  			continue
   257  		}
   258  		if string(data[0]) != string(data[i]) {
   259  			t.Errorf("%s and %s don't behave the same\n"+
   260  				"%s: \"%s\"\n%s: \"%s\"\n",
   261  				Fss[0].Name(), fs.Name(), Fss[0].Name(), data[0], fs.Name(), data[i])
   262  		}
   263  	}
   264  }
   265  
   266  // Test if file.Write() fails when opened as read only
   267  func TestReadOnly(t *testing.T) {
   268  	defer removeAllTestFiles(t)
   269  	const fileName = "afero-demo.txt"
   270  
   271  	for _, fs := range Fss {
   272  		dir := testDir(fs)
   273  		path := filepath.Join(dir, fileName)
   274  
   275  		f, err := fs.Create(path)
   276  		if err != nil {
   277  			t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
   278  		}
   279  		_, err = f.Write([]byte("test"))
   280  		if err != nil {
   281  			t.Error(fs.Name()+":", "Write failed: "+err.Error())
   282  		}
   283  		f.Close()
   284  
   285  		f, err = fs.Open(path)
   286  		if err != nil {
   287  			t.Error("fs.Open failed: " + err.Error())
   288  		}
   289  		_, err = f.Write([]byte("data"))
   290  		if err == nil {
   291  			t.Error(fs.Name()+":", "No write error")
   292  		}
   293  		f.Close()
   294  
   295  		f, err = fs.OpenFile(path, os.O_RDONLY, 0644)
   296  		if err != nil {
   297  			t.Error("fs.Open failed: " + err.Error())
   298  		}
   299  		_, err = f.Write([]byte("data"))
   300  		if err == nil {
   301  			t.Error(fs.Name()+":", "No write error")
   302  		}
   303  		f.Close()
   304  	}
   305  }
   306  
   307  func TestWriteCloseTime(t *testing.T) {
   308  	defer removeAllTestFiles(t)
   309  	const fileName = "afero-demo.txt"
   310  
   311  	for _, fs := range Fss {
   312  		dir := testDir(fs)
   313  		path := filepath.Join(dir, fileName)
   314  
   315  		f, err := fs.Create(path)
   316  		if err != nil {
   317  			t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
   318  		}
   319  		f.Close()
   320  
   321  		f, err = fs.Create(path)
   322  		if err != nil {
   323  			t.Error(fs.Name()+":", "fs.Create failed: "+err.Error())
   324  		}
   325  		fi, err := f.Stat()
   326  		if err != nil {
   327  			t.Error(fs.Name()+":", "Stat failed: "+err.Error())
   328  		}
   329  		timeBefore := fi.ModTime()
   330  
   331  		// sorry for the delay, but we have to make sure time advances,
   332  		// also on non Un*x systems...
   333  		switch runtime.GOOS {
   334  		case "windows":
   335  			time.Sleep(2 * time.Second)
   336  		case "darwin":
   337  			time.Sleep(1 * time.Second)
   338  		default: // depending on the FS, this may work with < 1 second, on my old ext3 it does not
   339  			time.Sleep(1 * time.Second)
   340  		}
   341  
   342  		_, err = f.Write([]byte("test"))
   343  		if err != nil {
   344  			t.Error(fs.Name()+":", "Write failed: "+err.Error())
   345  		}
   346  		f.Close()
   347  		fi, err = fs.Stat(path)
   348  		if err != nil {
   349  			t.Error(fs.Name()+":", "fs.Stat failed: "+err.Error())
   350  		}
   351  		if fi.ModTime().Equal(timeBefore) {
   352  			t.Error(fs.Name()+":", "ModTime was not set on Close()")
   353  		}
   354  	}
   355  }
   356  
   357  // This test should be run with the race detector on:
   358  // go test -race -v -timeout 10s -run TestRacingDeleteAndClose
   359  func TestRacingDeleteAndClose(t *testing.T) {
   360  	fs := NewMemMapFs()
   361  	pathname := "testfile"
   362  	f, err := fs.Create(pathname)
   363  	if err != nil {
   364  		t.Fatal(err)
   365  	}
   366  
   367  	in := make(chan bool)
   368  
   369  	go func() {
   370  		<-in
   371  		f.Close()
   372  	}()
   373  	go func() {
   374  		<-in
   375  		fs.Remove(pathname)
   376  	}()
   377  	close(in)
   378  }
   379  
   380  // This test should be run with the race detector on:
   381  // go test -run TestMemFsDataRace -race
   382  func TestMemFsDataRace(t *testing.T) {
   383  	const dir = "test_dir"
   384  	fs := NewMemMapFs()
   385  
   386  	if err := fs.MkdirAll(dir, 0777); err != nil {
   387  		t.Fatal(err)
   388  	}
   389  
   390  	const n = 1000
   391  	done := make(chan struct{})
   392  
   393  	go func() {
   394  		defer close(done)
   395  		for i := 0; i < n; i++ {
   396  			fname := filepath.Join(dir, fmt.Sprintf("%d.txt", i))
   397  			if err := WriteFile(fs, fname, []byte(""), 0777); err != nil {
   398  				panic(err)
   399  			}
   400  			if err := fs.Remove(fname); err != nil {
   401  				panic(err)
   402  			}
   403  		}
   404  	}()
   405  
   406  loop:
   407  	for {
   408  		select {
   409  		case <-done:
   410  			break loop
   411  		default:
   412  			_, err := ReadDir(fs, dir)
   413  			if err != nil {
   414  				t.Fatal(err)
   415  			}
   416  		}
   417  	}
   418  }
   419  
   420  // root is a directory
   421  func TestMemFsRootDirMode(t *testing.T) {
   422  	t.Parallel()
   423  
   424  	fs := NewMemMapFs()
   425  	info, err := fs.Stat("/")
   426  	if err != nil {
   427  		t.Fatal(err)
   428  	}
   429  	if !info.IsDir() {
   430  		t.Error("should be a directory")
   431  	}
   432  	if !info.Mode().IsDir() {
   433  		t.Errorf("FileMode is not directory, is %s", info.Mode().String())
   434  	}
   435  }
   436  
   437  // MkdirAll creates intermediate directories with correct mode
   438  func TestMemFsMkdirAllMode(t *testing.T) {
   439  	t.Parallel()
   440  
   441  	fs := NewMemMapFs()
   442  	err := fs.MkdirAll("/a/b/c", 0755)
   443  	if err != nil {
   444  		t.Fatal(err)
   445  	}
   446  	info, err := fs.Stat("/a")
   447  	if err != nil {
   448  		t.Fatal(err)
   449  	}
   450  	if !info.Mode().IsDir() {
   451  		t.Error("/a: mode is not directory")
   452  	}
   453  	if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
   454  		t.Errorf("/a: mod time not set, got %s", info.ModTime())
   455  	}
   456  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   457  		t.Errorf("/a: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
   458  	}
   459  	info, err = fs.Stat("/a/b")
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  	if !info.Mode().IsDir() {
   464  		t.Error("/a/b: mode is not directory")
   465  	}
   466  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   467  		t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
   468  	}
   469  	if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
   470  		t.Errorf("/a/b: mod time not set, got %s", info.ModTime())
   471  	}
   472  	info, err = fs.Stat("/a/b/c")
   473  	if err != nil {
   474  		t.Fatal(err)
   475  	}
   476  	if !info.Mode().IsDir() {
   477  		t.Error("/a/b/c: mode is not directory")
   478  	}
   479  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   480  		t.Errorf("/a/b/c: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
   481  	}
   482  	if !info.ModTime().After(time.Now().Add(-1 * time.Hour)) {
   483  		t.Errorf("/a/b/c: mod time not set, got %s", info.ModTime())
   484  	}
   485  }
   486  
   487  // MkdirAll does not change permissions of already-existing directories
   488  func TestMemFsMkdirAllNoClobber(t *testing.T) {
   489  	t.Parallel()
   490  
   491  	fs := NewMemMapFs()
   492  	err := fs.MkdirAll("/a/b/c", 0755)
   493  	if err != nil {
   494  		t.Fatal(err)
   495  	}
   496  	info, err := fs.Stat("/a/b")
   497  	if err != nil {
   498  		t.Fatal(err)
   499  	}
   500  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   501  		t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
   502  	}
   503  	err = fs.MkdirAll("/a/b/c/d/e/f", 0710)
   504  	// '/a/b' is unchanged
   505  	if err != nil {
   506  		t.Fatal(err)
   507  	}
   508  	info, err = fs.Stat("/a/b")
   509  	if err != nil {
   510  		t.Fatal(err)
   511  	}
   512  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   513  		t.Errorf("/a/b: wrong permissions, expected drwxr-xr-x, got %s", info.Mode())
   514  	}
   515  	// new directories created with proper permissions
   516  	info, err = fs.Stat("/a/b/c/d")
   517  	if err != nil {
   518  		t.Fatal(err)
   519  	}
   520  	if info.Mode() != os.FileMode(os.ModeDir|0710) {
   521  		t.Errorf("/a/b/c/d: wrong permissions, expected drwx--x---, got %s", info.Mode())
   522  	}
   523  	info, err = fs.Stat("/a/b/c/d/e")
   524  	if err != nil {
   525  		t.Fatal(err)
   526  	}
   527  	if info.Mode() != os.FileMode(os.ModeDir|0710) {
   528  		t.Errorf("/a/b/c/d/e: wrong permissions, expected drwx--x---, got %s", info.Mode())
   529  	}
   530  	info, err = fs.Stat("/a/b/c/d/e/f")
   531  	if err != nil {
   532  		t.Fatal(err)
   533  	}
   534  	if info.Mode() != os.FileMode(os.ModeDir|0710) {
   535  		t.Errorf("/a/b/c/d/e/f: wrong permissions, expected drwx--x---, got %s", info.Mode())
   536  	}
   537  }
   538  
   539  func TestMemFsDirMode(t *testing.T) {
   540  	fs := NewMemMapFs()
   541  	err := fs.Mkdir("/testDir1", 0644)
   542  	if err != nil {
   543  		t.Error(err)
   544  	}
   545  	err = fs.MkdirAll("/sub/testDir2", 0644)
   546  	if err != nil {
   547  		t.Error(err)
   548  	}
   549  	info, err := fs.Stat("/testDir1")
   550  	if err != nil {
   551  		t.Error(err)
   552  	}
   553  	if !info.IsDir() {
   554  		t.Error("should be a directory")
   555  	}
   556  	if !info.Mode().IsDir() {
   557  		t.Error("FileMode is not directory")
   558  	}
   559  	info, err = fs.Stat("/sub/testDir2")
   560  	if err != nil {
   561  		t.Error(err)
   562  	}
   563  	if !info.IsDir() {
   564  		t.Error("should be a directory")
   565  	}
   566  	if !info.Mode().IsDir() {
   567  		t.Error("FileMode is not directory")
   568  	}
   569  }
   570  
   571  func TestMemFsUnexpectedEOF(t *testing.T) {
   572  	t.Parallel()
   573  
   574  	fs := NewMemMapFs()
   575  
   576  	if err := WriteFile(fs, "file.txt", []byte("abc"), 0777); err != nil {
   577  		t.Fatal(err)
   578  	}
   579  
   580  	f, err := fs.Open("file.txt")
   581  	if err != nil {
   582  		t.Fatal(err)
   583  	}
   584  	defer f.Close()
   585  
   586  	// Seek beyond the end.
   587  	_, err = f.Seek(512, 0)
   588  	if err != nil {
   589  		t.Fatal(err)
   590  	}
   591  
   592  	buff := make([]byte, 256)
   593  	_, err = io.ReadAtLeast(f, buff, 256)
   594  
   595  	if err != io.ErrUnexpectedEOF {
   596  		t.Fatal("Expected ErrUnexpectedEOF")
   597  	}
   598  }
   599  
   600  func TestMemFsChmod(t *testing.T) {
   601  	t.Parallel()
   602  
   603  	fs := NewMemMapFs()
   604  	const file = "hello"
   605  	if err := fs.Mkdir(file, 0700); err != nil {
   606  		t.Fatal(err)
   607  	}
   608  
   609  	info, err := fs.Stat(file)
   610  	if err != nil {
   611  		t.Fatal(err)
   612  	}
   613  	if info.Mode().String() != "drwx------" {
   614  		t.Fatal("mkdir failed to create a directory: mode =", info.Mode())
   615  	}
   616  
   617  	err = fs.Chmod(file, 0)
   618  	if err != nil {
   619  		t.Error("Failed to run chmod:", err)
   620  	}
   621  
   622  	info, err = fs.Stat(file)
   623  	if err != nil {
   624  		t.Fatal(err)
   625  	}
   626  	if info.Mode().String() != "d---------" {
   627  		t.Error("chmod should not change file type. New mode =", info.Mode())
   628  	}
   629  }
   630  
   631  // can't use Mkdir to get around which permissions we're allowed to set
   632  func TestMemFsMkdirModeIllegal(t *testing.T) {
   633  	t.Parallel()
   634  
   635  	fs := NewMemMapFs()
   636  	err := fs.Mkdir("/a", os.ModeSocket|0755)
   637  	if err != nil {
   638  		t.Fatal(err)
   639  	}
   640  	info, err := fs.Stat("/a")
   641  	if err != nil {
   642  		t.Fatal(err)
   643  	}
   644  	if info.Mode() != os.FileMode(os.ModeDir|0755) {
   645  		t.Fatalf("should not be able to use Mkdir to set illegal mode: %s", info.Mode().String())
   646  	}
   647  }
   648  
   649  // can't use OpenFile to get around which permissions we're allowed to set
   650  func TestMemFsOpenFileModeIllegal(t *testing.T) {
   651  	t.Parallel()
   652  
   653  	fs := NewMemMapFs()
   654  	file, err := fs.OpenFile("/a", os.O_CREATE, os.ModeSymlink|0644)
   655  	if err != nil {
   656  		t.Fatal(err)
   657  	}
   658  	defer file.Close()
   659  	info, err := fs.Stat("/a")
   660  	if err != nil {
   661  		t.Fatal(err)
   662  	}
   663  	if info.Mode() != os.FileMode(0644) {
   664  		t.Fatalf("should not be able to use OpenFile to set illegal mode: %s", info.Mode().String())
   665  	}
   666  }
   667  
   668  // LstatIfPossible should always return false, since MemMapFs does not
   669  // support symlinks.
   670  func TestMemFsLstatIfPossible(t *testing.T) {
   671  	t.Parallel()
   672  
   673  	fs := NewMemMapFs()
   674  
   675  	// We assert that fs implements Lstater
   676  	fsAsserted, ok := fs.(Lstater)
   677  	if !ok {
   678  		t.Fatalf("The filesytem does not implement Lstater")
   679  	}
   680  
   681  	file, err := fs.OpenFile("/a.txt", os.O_CREATE, 0o644)
   682  	if err != nil {
   683  		t.Fatalf("Error when opening file: %v", err)
   684  	}
   685  	defer file.Close()
   686  
   687  	_, lstatCalled, err := fsAsserted.LstatIfPossible("/a.txt")
   688  	if err != nil {
   689  		t.Fatalf("Function returned err: %v", err)
   690  	}
   691  	if lstatCalled {
   692  		t.Fatalf("Function indicated lstat was called. This should never be true.")
   693  	}
   694  }