github.com/3JoB/vfs@v1.0.0/memfs/memfs_test.go (about)

     1  package memfs
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/3JoB/vfs"
    11  )
    12  
    13  func TestInterface(t *testing.T) {
    14  	_ = vfs.Filesystem(Create())
    15  }
    16  
    17  func TestCreate(t *testing.T) {
    18  	fs := Create()
    19  	// Create file with absolute path
    20  	{
    21  		f, err := fs.OpenFile("/testfile", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    22  		if err != nil {
    23  			t.Fatalf("Unexpected error creating file: %s", err)
    24  		}
    25  		if name := f.Name(); name != "/testfile" {
    26  			t.Errorf("Wrong name: %s", name)
    27  		}
    28  	}
    29  
    30  	// Create same file again
    31  	{
    32  		_, err := fs.OpenFile("/testfile", os.O_RDWR|os.O_CREATE, 0666)
    33  		if err != nil {
    34  			t.Fatalf("Unexpected error creating file: %s", err)
    35  		}
    36  	}
    37  
    38  	// Create same file again, but truncate it
    39  	{
    40  		_, err := fs.OpenFile("/testfile", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    41  		if err != nil {
    42  			t.Fatalf("Unexpected error creating file: %s", err)
    43  		}
    44  	}
    45  
    46  	// Create same file again with O_CREATE|O_EXCL, which is an error
    47  	{
    48  		_, err := fs.OpenFile("/testfile", os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
    49  		if err == nil {
    50  			t.Fatalf("Expected error creating file: %s", err)
    51  		}
    52  	}
    53  
    54  	// Create file with unkown parent
    55  	{
    56  		_, err := fs.OpenFile("/testfile/testfile", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    57  		if err == nil {
    58  			t.Errorf("Expected error creating file")
    59  		}
    60  	}
    61  
    62  	// Create file with relative path (workingDir == root)
    63  	{
    64  		f, err := fs.OpenFile("relFile", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
    65  		if err != nil {
    66  			t.Fatalf("Unexpected error creating file: %s", err)
    67  		}
    68  		if name := f.Name(); name != "/relFile" {
    69  			t.Errorf("Wrong name: %s", name)
    70  		}
    71  	}
    72  }
    73  
    74  func TestMkdirAbsRel(t *testing.T) {
    75  	fs := Create()
    76  
    77  	// Create dir with absolute path
    78  	{
    79  		err := fs.Mkdir("/usr", 0)
    80  		if err != nil {
    81  			t.Fatalf("Unexpected error creating directory: %s", err)
    82  		}
    83  	}
    84  
    85  	// Create dir with relative path
    86  	{
    87  		err := fs.Mkdir("home", 0)
    88  		if err != nil {
    89  			t.Fatalf("Unexpected error creating directory: %s", err)
    90  		}
    91  	}
    92  
    93  	// Create dir twice
    94  	{
    95  		err := fs.Mkdir("/home", 0)
    96  		if err == nil {
    97  			t.Fatalf("Expecting error creating directory: %s", "/home")
    98  		}
    99  	}
   100  }
   101  
   102  func TestMkdirTree(t *testing.T) {
   103  	fs := Create()
   104  
   105  	err := fs.Mkdir("/home", 0)
   106  	if err != nil {
   107  		t.Fatalf("Unexpected error creating directory /home: %s", err)
   108  	}
   109  
   110  	err = fs.Mkdir("/home/blang", 0)
   111  	if err != nil {
   112  		t.Fatalf("Unexpected error creating directory /home/blang: %s", err)
   113  	}
   114  
   115  	err = fs.Mkdir("/home/blang/goprojects", 0)
   116  	if err != nil {
   117  		t.Fatalf("Unexpected error creating directory /home/blang/goprojects: %s", err)
   118  	}
   119  
   120  	err = fs.Mkdir("/home/johndoe/goprojects", 0)
   121  	if err == nil {
   122  		t.Errorf("Expected error creating directory with non-existing parent")
   123  	}
   124  
   125  	// TODO: Subdir of file
   126  }
   127  
   128  func TestSymlink(t *testing.T) {
   129  	fs := Create()
   130  
   131  	if err := vfs.MkdirAll(fs, "/tmp", 0755); err != nil {
   132  		t.Fatal("Unable to create /tmp:", err)
   133  	}
   134  	if err := vfs.WriteFile(fs, "/tmp/teacup", []byte("i am a teacup"), 0644); err != nil {
   135  		t.Fatal("Unable to fill teacup:", err)
   136  	}
   137  	err := fs.Symlink("/tmp/teacup", "/tmp/cup")
   138  	if err != nil {
   139  		t.Fatal("Symlink failed:", err)
   140  	}
   141  	fluid, err := vfs.ReadFile(fs, "/tmp/cup")
   142  	if err != nil {
   143  		t.Fatal("Failed to read from /tmp/cup:", err)
   144  	}
   145  	if string(fluid) != "i am a teacup" {
   146  		t.Fatal("Wrong contents in cup. got:", string(fluid))
   147  	}
   148  }
   149  
   150  func TestDirectorySymlink(t *testing.T) {
   151  	fs := Create()
   152  
   153  	if err := vfs.MkdirAll(fs, "/foo/a/b", 0755); err != nil {
   154  		t.Fatal("Unable mkdir /foo/a/b:", err)
   155  	}
   156  
   157  	if err := vfs.WriteFile(fs, "/foo/a/b/c", []byte("I can \"c\" clearly now"), 0644); err != nil {
   158  		t.Fatal("Unable to write /foo/a/b/c:", err)
   159  	}
   160  
   161  	if err := fs.Symlink("/foo/a/b", "/foo/also_b"); err != nil {
   162  		t.Fatal("Unable to symlink /foo/also_b -> /foo/a/b:", err)
   163  	}
   164  
   165  	contents, err := vfs.ReadFile(fs, "/foo/also_b/c")
   166  	if err != nil {
   167  		t.Fatal("Unable to read /foo/also_b/c:", err)
   168  	}
   169  	if string(contents) != "I can \"c\" clearly now" {
   170  		t.Fatal("Unexpected contents read from c:", err)
   171  	}
   172  }
   173  
   174  func TestMultipleAndRelativeSymlinks(t *testing.T) {
   175  	fs := Create()
   176  	if err := vfs.MkdirAll(fs, "a/real_b/real_c", 0755); err != nil {
   177  		t.Fatal("Unable mkdir a/real_b/real_c:", err)
   178  	}
   179  
   180  	for _, fsEntry := range []struct {
   181  		name, link, content string
   182  	}{
   183  		{name: "a/b", link: "real_b"},
   184  		{name: "a/b/c", link: "real_c"},
   185  		{name: "a/b/c/real_d", content: "Lah dee dah"},
   186  		{name: "a/b/c/d", link: "real_d"},
   187  		{name: "a/d", link: "b/c/d"},
   188  	} {
   189  		if fsEntry.link != "" {
   190  			if err := fs.Symlink(fsEntry.link, fsEntry.name); err != nil {
   191  				t.Fatalf("Unable to symlink %s -> %s: %v", fsEntry.name, fsEntry.link, err)
   192  			}
   193  		} else if fsEntry.content != "" {
   194  			if err := vfs.WriteFile(fs, fsEntry.name, []byte(fsEntry.content), 0644); err != nil {
   195  				t.Fatalf("Unable to write %s: %v", fsEntry.name, err)
   196  			}
   197  		}
   198  	}
   199  
   200  	for _, fn := range []string{
   201  		"a/b/c/d",
   202  		"a/d",
   203  	} {
   204  		contents, err := vfs.ReadFile(fs, fn)
   205  		if err != nil {
   206  			t.Fatalf("Unable to read %s: %v", fn, err)
   207  		}
   208  		if string(contents) != "Lah dee dah" {
   209  			t.Fatalf("Unexpected contents read from %s: %v", fn, err)
   210  		}
   211  	}
   212  }
   213  
   214  func TestSymlinkIsNotADirectory(t *testing.T) {
   215  	fs := Create()
   216  	if err := vfs.MkdirAll(fs, "a/real_b/real_c", 0755); err != nil {
   217  		t.Fatal("Unable mkdir a/real_b/real_c:", err)
   218  	}
   219  	if err := fs.Symlink("broken", "a/b"); err != nil {
   220  		t.Fatal("Unable to symlink a/b -> broken:", err)
   221  	}
   222  	if err := vfs.WriteFile(fs, "a/b/c", []byte("Whatever"), 0644); !strings.Contains(err.Error(), vfs.ErrNotDirectory.Error()) {
   223  		t.Fatal("Expected an error when writing a/b/c:", err)
   224  	}
   225  }
   226  
   227  // TODO: overwrite/remove symlinks
   228  
   229  func TestReadDir(t *testing.T) {
   230  	fs := Create()
   231  	dirs := []string{"/home", "/home/linus", "/home/rob", "/home/pike", "/home/blang"}
   232  	expectNames := []string{"README.txt", "blang", "linus", "pike", "rob"}
   233  	for _, dir := range dirs {
   234  		err := fs.Mkdir(dir, 0777)
   235  		if err != nil {
   236  			t.Fatalf("Unexpected error creating directory %q: %s", dir, err)
   237  		}
   238  	}
   239  	f, err := fs.OpenFile("/home/README.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
   240  	if err != nil {
   241  		t.Fatalf("Unexpected error creating file: %s", err)
   242  	}
   243  	f.Close()
   244  
   245  	fis, err := fs.ReadDir("/home")
   246  	if err != nil {
   247  		t.Fatalf("Unexpected error readdir: %s", err)
   248  	}
   249  	if l := len(fis); l != len(expectNames) {
   250  		t.Errorf("Wrong size: %q (%d)", fis, l)
   251  	}
   252  	for i, n := range expectNames {
   253  		if fn := fis[i].Name(); fn != n {
   254  			t.Errorf("Expected name %q, got %q", n, fn)
   255  		}
   256  	}
   257  
   258  	// Readdir empty directory
   259  	if fis, err := fs.ReadDir("/home/blang"); err != nil {
   260  		t.Errorf("Error readdir(empty directory): %s", err)
   261  	} else if l := len(fis); l > 0 {
   262  		t.Errorf("Found entries in non-existing directory: %d", l)
   263  	}
   264  
   265  	// Readdir file
   266  	if _, err := fs.ReadDir("/home/README.txt"); err == nil {
   267  		t.Errorf("Expected error readdir(file)")
   268  	}
   269  
   270  	// Readdir subdir of file
   271  	if _, err := fs.ReadDir("/home/README.txt/info"); err == nil {
   272  		t.Errorf("Expected error readdir(subdir of file)")
   273  	}
   274  
   275  	// Readdir non existing directory
   276  	if _, err := fs.ReadDir("/usr"); err == nil {
   277  		t.Errorf("Expected error readdir(nofound)")
   278  	}
   279  }
   280  
   281  func TestRemove(t *testing.T) {
   282  	fs := Create()
   283  	err := fs.Mkdir("/tmp", 0777)
   284  	if err != nil {
   285  		t.Fatalf("Mkdir error: %s", err)
   286  	}
   287  	f, err := fs.OpenFile("/tmp/README.txt", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
   288  	if err != nil {
   289  		t.Fatalf("Create error: %s", err)
   290  	}
   291  	if _, err := f.Write([]byte("test")); err != nil {
   292  		t.Fatalf("Write error: %s", err)
   293  	}
   294  	f.Close()
   295  
   296  	// remove non existing file
   297  	if err := fs.Remove("/nonexisting.txt"); err == nil {
   298  		t.Errorf("Expected remove to fail")
   299  	}
   300  
   301  	// remove non existing file from an non existing directory
   302  	if err := fs.Remove("/nonexisting/nonexisting.txt"); err == nil {
   303  		t.Errorf("Expected remove to fail")
   304  	}
   305  
   306  	// remove created file
   307  	err = fs.Remove(f.Name())
   308  	if err != nil {
   309  		t.Errorf("Remove failed: %s", err)
   310  	}
   311  
   312  	if _, err = fs.OpenFile("/tmp/README.txt", os.O_RDWR, 0666); err == nil {
   313  		t.Errorf("Could open removed file!")
   314  	}
   315  
   316  	err = fs.Remove("/tmp")
   317  	if err != nil {
   318  		t.Errorf("Remove failed: %s", err)
   319  	}
   320  	if fis, err := fs.ReadDir("/"); err != nil {
   321  		t.Errorf("Readdir error: %s", err)
   322  	} else if len(fis) != 0 {
   323  		t.Errorf("Found files: %s", fis)
   324  	}
   325  }
   326  
   327  func TestReadWrite(t *testing.T) {
   328  	fs := Create()
   329  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666)
   330  	if err != nil {
   331  		t.Fatalf("Could not open file: %s", err)
   332  	}
   333  
   334  	// Write first dots
   335  	if n, err := f.Write([]byte(dots)); err != nil {
   336  		t.Errorf("Unexpected error: %s", err)
   337  	} else if n != len(dots) {
   338  		t.Errorf("Invalid write count: %d", n)
   339  	}
   340  
   341  	// Write abc
   342  	if n, err := f.Write([]byte(abc)); err != nil {
   343  		t.Errorf("Unexpected error: %s", err)
   344  	} else if n != len(abc) {
   345  		t.Errorf("Invalid write count: %d", n)
   346  	}
   347  
   348  	// Seek to beginning of file
   349  	if n, err := f.Seek(0, os.SEEK_SET); err != nil || n != 0 {
   350  		t.Errorf("Seek error: %d %s", n, err)
   351  	}
   352  
   353  	// Seek to end of file
   354  	if n, err := f.Seek(0, os.SEEK_END); err != nil || n != 32 {
   355  		t.Errorf("Seek error: %d %s", n, err)
   356  	}
   357  
   358  	// Write dots at end of file
   359  	if n, err := f.Write([]byte(dots)); err != nil {
   360  		t.Errorf("Unexpected error: %s", err)
   361  	} else if n != len(dots) {
   362  		t.Errorf("Invalid write count: %d", n)
   363  	}
   364  
   365  	// Seek to beginning of file
   366  	if n, err := f.Seek(0, os.SEEK_SET); err != nil || n != 0 {
   367  		t.Errorf("Seek error: %d %s", n, err)
   368  	}
   369  
   370  	p := make([]byte, len(dots)+len(abc)+len(dots))
   371  	if n, err := f.Read(p); err != nil || n != len(dots)+len(abc)+len(dots) {
   372  		t.Errorf("Read error: %d %s", n, err)
   373  	} else if s := string(p); s != dots+abc+dots {
   374  		t.Errorf("Invalid read: %s", s)
   375  	}
   376  }
   377  
   378  func TestOpen(t *testing.T) {
   379  	fs := Create()
   380  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666)
   381  	if err != nil {
   382  		t.Fatalf("OpenFile: %s", err)
   383  	}
   384  	if _, err = f.Write([]byte("test")); err != nil {
   385  		t.Fatalf("Write: %s", err)
   386  	}
   387  	f.Close()
   388  	f2, err := fs.Open("/readme.txt")
   389  	if err != nil {
   390  		t.Errorf("Open: %s", err)
   391  	}
   392  	if err := f2.Close();  err != nil {
   393  		t.Errorf("Close: %s", err)
   394  	}
   395  }
   396  
   397  func TestOpenRO(t *testing.T) {
   398  	fs := Create()
   399  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDONLY, 0666)
   400  	if err != nil {
   401  		t.Fatalf("Could not open file: %s", err)
   402  	}
   403  
   404  	// Write first dots
   405  	if _, err := f.Write([]byte(dots)); err == nil {
   406  		t.Fatalf("Expected write error")
   407  	}
   408  	f.Close()
   409  }
   410  
   411  func TestOpenWO(t *testing.T) {
   412  	fs := Create()
   413  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_WRONLY, 0666)
   414  	if err != nil {
   415  		t.Fatalf("Could not open file: %s", err)
   416  	}
   417  
   418  	// Write first dots
   419  	if n, err := f.Write([]byte(dots)); err != nil {
   420  		t.Errorf("Unexpected error: %s", err)
   421  	} else if n != len(dots) {
   422  		t.Errorf("Invalid write count: %d", n)
   423  	}
   424  
   425  	// Seek to beginning of file
   426  	if n, err := f.Seek(0, os.SEEK_SET); err != nil || n != 0 {
   427  		t.Errorf("Seek error: %d %s", n, err)
   428  	}
   429  
   430  	// Try reading
   431  	p := make([]byte, len(dots))
   432  	if n, err := f.Read(p); err == nil || n > 0 {
   433  		t.Errorf("Expected invalid read: %d %s", n, err)
   434  	}
   435  
   436  	f.Close()
   437  }
   438  
   439  func TestOpenAppend(t *testing.T) {
   440  	fs := Create()
   441  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666)
   442  	if err != nil {
   443  		t.Fatalf("Could not open file: %s", err)
   444  	}
   445  
   446  	// Write first dots
   447  	if n, err := f.Write([]byte(dots)); err != nil {
   448  		t.Errorf("Unexpected error: %s", err)
   449  	} else if n != len(dots) {
   450  		t.Errorf("Invalid write count: %d", n)
   451  	}
   452  	f.Close()
   453  
   454  	// Reopen file in append mode
   455  	f, err = fs.OpenFile("/readme.txt", os.O_APPEND|os.O_RDWR, 0666)
   456  	if err != nil {
   457  		t.Fatalf("Could not open file: %s", err)
   458  	}
   459  
   460  	// append dots
   461  	if n, err := f.Write([]byte(abc)); err != nil {
   462  		t.Errorf("Unexpected error: %s", err)
   463  	} else if n != len(abc) {
   464  		t.Errorf("Invalid write count: %d", n)
   465  	}
   466  
   467  	// Seek to beginning of file
   468  	if n, err := f.Seek(0, os.SEEK_SET); err != nil || n != 0 {
   469  		t.Errorf("Seek error: %d %s", n, err)
   470  	}
   471  
   472  	p := make([]byte, len(dots)+len(abc))
   473  	if n, err := f.Read(p); err != nil || n != len(dots)+len(abc) {
   474  		t.Errorf("Read error: %d %s", n, err)
   475  	} else if s := string(p); s != dots+abc {
   476  		t.Errorf("Invalid read: %s", s)
   477  	}
   478  	f.Close()
   479  }
   480  
   481  func TestTruncateToLength(t *testing.T) {
   482  	var params = []struct {
   483  		size int64
   484  		err  bool
   485  	}{
   486  		{size: -1, err: true},
   487  		{size: 0, err: false},
   488  		{size: int64(len(dots) - 1), err: false},
   489  		{size: int64(len(dots)), err: false},
   490  		{size: int64(len(dots) + 1), err: false},
   491  	}
   492  	for _, param := range params {
   493  		fs := Create()
   494  		f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666)
   495  		if err != nil {
   496  			t.Fatalf("Could not open file: %s", err)
   497  		}
   498  		if n, err := f.Write([]byte(dots)); err != nil {
   499  			t.Errorf("Unexpected error: %s", err)
   500  		} else if n != len(dots) {
   501  			t.Errorf("Invalid write count: %d", n)
   502  		}
   503  		f.Close()
   504  
   505  		newSize := param.size
   506  		err = f.Truncate(newSize)
   507  		if param.err {
   508  			if err == nil {
   509  				t.Errorf("Error expected truncating file to length %d", newSize)
   510  			}
   511  			return
   512  		} else if err != nil {
   513  			t.Errorf("Error truncating file: %s", err)
   514  		}
   515  
   516  		b, err := readFile(fs, "/readme.txt")
   517  		if err != nil {
   518  			t.Errorf("Error reading truncated file: %s", err)
   519  		}
   520  		if int64(len(b)) != newSize {
   521  			t.Errorf("File should be empty after truncation: %d", len(b))
   522  		}
   523  		if fi, err := fs.Stat("/readme.txt"); err != nil {
   524  			t.Errorf("Error stat file: %s", err)
   525  		} else if fi.Size() != newSize {
   526  			t.Errorf("Filesize should be %d after truncation", newSize)
   527  		}
   528  	}
   529  }
   530  
   531  func TestTruncateToZero(t *testing.T) {
   532  	const content = "read me"
   533  	fs := Create()
   534  	if _, err := writeFile(fs, "/readme.txt", os.O_CREATE|os.O_RDWR, 0666, []byte(content)); err != nil {
   535  		t.Errorf("Unexpected error writing file: %s", err)
   536  	}
   537  
   538  	f, err := fs.OpenFile("/readme.txt", os.O_RDWR|os.O_TRUNC, 0666)
   539  	if err != nil {
   540  		t.Errorf("Error opening file truncated: %s", err)
   541  	}
   542  	f.Close()
   543  
   544  	b, err := readFile(fs, "/readme.txt")
   545  	if err != nil {
   546  		t.Errorf("Error reading truncated file: %s", err)
   547  	}
   548  	if len(b) != 0 {
   549  		t.Errorf("File should be empty after truncation")
   550  	}
   551  	if fi, err := fs.Stat("/readme.txt"); err != nil {
   552  		t.Errorf("Error stat file: %s", err)
   553  	} else if fi.Size() != 0 {
   554  		t.Errorf("Filesize should be 0 after truncation")
   555  	}
   556  }
   557  
   558  func TestStat(t *testing.T) {
   559  	fs := Create()
   560  	f, err := fs.OpenFile("/readme.txt", os.O_CREATE|os.O_RDWR, 0666)
   561  	if err != nil {
   562  		t.Fatalf("Could not open file: %s", err)
   563  	}
   564  
   565  	// Write first dots
   566  	if n, err := f.Write([]byte(dots)); err != nil {
   567  		t.Fatalf("Unexpected error: %s", err)
   568  	} else if n != len(dots) {
   569  		t.Fatalf("Invalid write count: %d", n)
   570  	}
   571  	f.Close()
   572  
   573  	if err := fs.Mkdir("/tmp", 0777); err != nil {
   574  		t.Fatalf("Mkdir error: %s", err)
   575  	}
   576  
   577  	fi, err := fs.Stat(f.Name())
   578  	if err != nil {
   579  		t.Errorf("Stat error: %s", err)
   580  	}
   581  
   582  	// Fileinfo name is base name
   583  	if name := fi.Name(); name != "readme.txt" {
   584  		t.Errorf("Invalid fileinfo name: %s", name)
   585  	}
   586  
   587  	// File name is abs name
   588  	if name := f.Name(); name != "/readme.txt" {
   589  		t.Errorf("Invalid file name: %s", name)
   590  	}
   591  
   592  	if s := fi.Size(); s != int64(len(dots)) {
   593  		t.Errorf("Invalid size: %d", s)
   594  	}
   595  	if fi.IsDir() {
   596  		t.Errorf("Invalid IsDir")
   597  	}
   598  	if m := fi.Mode(); m != 0666 {
   599  		t.Errorf("Invalid mode: %d", m)
   600  	}
   601  }
   602  
   603  func writeFile(fs vfs.Filesystem, name string, flags int, mode os.FileMode, b []byte) (int, error) {
   604  	f, err := fs.OpenFile(name, flags, mode)
   605  	if err != nil {
   606  		return 0, err
   607  	}
   608  	return f.Write(b)
   609  }
   610  
   611  func readFile(fs vfs.Filesystem, name string) ([]byte, error) {
   612  	f, err := fs.OpenFile(name, os.O_RDONLY, 0)
   613  	if err != nil {
   614  		return nil, err
   615  	}
   616  	return io.ReadAll(f)
   617  }
   618  
   619  func TestRename(t *testing.T) {
   620  	const content = "read me"
   621  	fs := Create()
   622  	if _, err := writeFile(fs, "/readme.txt", os.O_CREATE|os.O_RDWR, 0666, []byte(content)); err != nil {
   623  		t.Errorf("Unexpected error writing file: %s", err)
   624  	}
   625  
   626  	if err := fs.Rename("/readme.txt", "/README.txt"); err != nil {
   627  		t.Errorf("Unexpected error renaming file: %s", err)
   628  	}
   629  
   630  	if _, err := fs.Stat("/readme.txt"); err == nil {
   631  		t.Errorf("Old file still exists")
   632  	}
   633  
   634  	if _, err := fs.Stat("/README.txt"); err != nil {
   635  		t.Errorf("Error stat newfile: %s", err)
   636  	}
   637  	if b, err := readFile(fs, "/README.txt"); err != nil {
   638  		t.Errorf("Error reading file: %s", err)
   639  	} else if s := string(b); s != content {
   640  		t.Errorf("Invalid content: %s", s)
   641  	}
   642  
   643  	// Rename unknown file
   644  	if err := fs.Rename("/nonexisting.txt", "/goodtarget.txt"); err == nil {
   645  		t.Errorf("Expected error renaming file")
   646  	}
   647  
   648  	// Rename unknown file in nonexisting directory
   649  	if err := fs.Rename("/nonexisting/nonexisting.txt", "/goodtarget.txt"); err == nil {
   650  		t.Errorf("Expected error renaming file")
   651  	}
   652  
   653  	// Rename existing file to nonexisting directory
   654  	if err := fs.Rename("/README.txt", "/nonexisting/nonexisting.txt"); err == nil {
   655  		t.Errorf("Expected error renaming file")
   656  	}
   657  
   658  	if err := fs.Mkdir("/newdirectory", 0777); err != nil {
   659  		t.Errorf("Error creating directory: %s", err)
   660  	}
   661  
   662  	if err := fs.Rename("/README.txt", "/newdirectory/README.txt"); err != nil {
   663  		t.Errorf("Error renaming file: %s", err)
   664  	}
   665  
   666  	// Create the same file again at root
   667  	if _, err := writeFile(fs, "/README.txt", os.O_CREATE|os.O_RDWR, 0666, []byte(content)); err != nil {
   668  		t.Errorf("Unexpected error writing file: %s", err)
   669  	}
   670  
   671  	// Overwrite existing file
   672  	if err := fs.Rename("/newdirectory/README.txt", "/README.txt"); err == nil {
   673  		t.Errorf("Expected error renaming file")
   674  	}
   675  }
   676  
   677  func TestModTime(t *testing.T) {
   678  	fs := Create()
   679  
   680  	tBeforeWrite := time.Now()
   681  	writeFile(fs, "/readme.txt", os.O_CREATE|os.O_RDWR, 0666, []byte{0, 0, 0})
   682  	fi, _ := fs.Stat("/readme.txt")
   683  	mtimeAfterWrite := fi.ModTime()
   684  
   685  	if !mtimeAfterWrite.After(tBeforeWrite) {
   686  		t.Error("Open should modify mtime")
   687  	}
   688  
   689  	f, err := fs.OpenFile("/readme.txt", os.O_RDONLY, 0666)
   690  	if err != nil {
   691  		t.Fatalf("Could not open file: %s", err)
   692  	}
   693  	f.Close()
   694  	tAfterRead := fi.ModTime()
   695  
   696  	if tAfterRead != mtimeAfterWrite {
   697  		t.Error("Open with O_RDONLY should not modify mtime")
   698  	}
   699  }