github.com/27149chen/afero@v1.6.2/composite_test.go (about)

     1  package afero
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  var tempDirs []string
    14  
    15  func NewTempOsBaseFs(t *testing.T) Fs {
    16  	name, err := TempDir(NewOsFs(), "", "")
    17  	if err != nil {
    18  		t.Error("error creating tempDir", err)
    19  	}
    20  
    21  	tempDirs = append(tempDirs, name)
    22  
    23  	return NewBasePathFs(NewOsFs(), name)
    24  }
    25  
    26  func CleanupTempDirs(t *testing.T) {
    27  	osfs := NewOsFs()
    28  	type ev struct {
    29  		path string
    30  		e    error
    31  	}
    32  
    33  	errs := []ev{}
    34  
    35  	for _, x := range tempDirs {
    36  		err := osfs.RemoveAll(x)
    37  		if err != nil {
    38  			errs = append(errs, ev{path: x, e: err})
    39  		}
    40  	}
    41  
    42  	for _, e := range errs {
    43  		fmt.Println("error removing tempDir", e.path, e.e)
    44  	}
    45  
    46  	if len(errs) > 0 {
    47  		t.Error("error cleaning up tempDirs")
    48  	}
    49  	tempDirs = []string{}
    50  }
    51  
    52  func TestUnionCreateExisting(t *testing.T) {
    53  	base := &MemMapFs{}
    54  	roBase := &ReadOnlyFs{source: base}
    55  	ufs := NewCopyOnWriteFs(roBase, &MemMapFs{})
    56  
    57  	base.MkdirAll("/home/test", 0777)
    58  	fh, _ := base.Create("/home/test/file.txt")
    59  	fh.WriteString("This is a test")
    60  	fh.Close()
    61  
    62  	fh, err := ufs.OpenFile("/home/test/file.txt", os.O_RDWR, 0666)
    63  	if err != nil {
    64  		t.Errorf("Failed to open file r/w: %s", err)
    65  	}
    66  
    67  	_, err = fh.Write([]byte("####"))
    68  	if err != nil {
    69  		t.Errorf("Failed to write file: %s", err)
    70  	}
    71  	fh.Seek(0, 0)
    72  	data, err := ioutil.ReadAll(fh)
    73  	if err != nil {
    74  		t.Errorf("Failed to read file: %s", err)
    75  	}
    76  	if string(data) != "#### is a test" {
    77  		t.Errorf("Got wrong data")
    78  	}
    79  	fh.Close()
    80  
    81  	fh, _ = base.Open("/home/test/file.txt")
    82  	data, err = ioutil.ReadAll(fh)
    83  	if string(data) != "This is a test" {
    84  		t.Errorf("Got wrong data in base file")
    85  	}
    86  	fh.Close()
    87  
    88  	fh, err = ufs.Create("/home/test/file.txt")
    89  	switch err {
    90  	case nil:
    91  		if fi, _ := fh.Stat(); fi.Size() != 0 {
    92  			t.Errorf("Create did not truncate file")
    93  		}
    94  		fh.Close()
    95  	default:
    96  		t.Errorf("Create failed on existing file")
    97  	}
    98  
    99  }
   100  
   101  func TestUnionMergeReaddir(t *testing.T) {
   102  	base := &MemMapFs{}
   103  	roBase := &ReadOnlyFs{source: base}
   104  
   105  	ufs := &CopyOnWriteFs{base: roBase, layer: &MemMapFs{}}
   106  
   107  	base.MkdirAll("/home/test", 0777)
   108  	fh, _ := base.Create("/home/test/file.txt")
   109  	fh.WriteString("This is a test")
   110  	fh.Close()
   111  
   112  	fh, _ = ufs.Create("/home/test/file2.txt")
   113  	fh.WriteString("This is a test")
   114  	fh.Close()
   115  
   116  	fh, _ = ufs.Open("/home/test")
   117  	files, err := fh.Readdirnames(-1)
   118  	if err != nil {
   119  		t.Errorf("Readdirnames failed")
   120  	}
   121  	if len(files) != 2 {
   122  		t.Errorf("Got wrong number of files: %v", files)
   123  	}
   124  }
   125  
   126  func TestExistingDirectoryCollisionReaddir(t *testing.T) {
   127  	base := &MemMapFs{}
   128  	roBase := &ReadOnlyFs{source: base}
   129  	overlay := &MemMapFs{}
   130  
   131  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   132  
   133  	base.MkdirAll("/home/test", 0777)
   134  	fh, _ := base.Create("/home/test/file.txt")
   135  	fh.WriteString("This is a test")
   136  	fh.Close()
   137  
   138  	overlay.MkdirAll("home/test", 0777)
   139  	fh, _ = overlay.Create("/home/test/file2.txt")
   140  	fh.WriteString("This is a test")
   141  	fh.Close()
   142  
   143  	fh, _ = ufs.Create("/home/test/file3.txt")
   144  	fh.WriteString("This is a test")
   145  	fh.Close()
   146  
   147  	fh, _ = ufs.Open("/home/test")
   148  	files, err := fh.Readdirnames(-1)
   149  	if err != nil {
   150  		t.Errorf("Readdirnames failed")
   151  	}
   152  	if len(files) != 3 {
   153  		t.Errorf("Got wrong number of files in union: %v", files)
   154  	}
   155  
   156  	fh, _ = overlay.Open("/home/test")
   157  	files, err = fh.Readdirnames(-1)
   158  	if err != nil {
   159  		t.Errorf("Readdirnames failed")
   160  	}
   161  	if len(files) != 2 {
   162  		t.Errorf("Got wrong number of files in overlay: %v", files)
   163  	}
   164  }
   165  
   166  func TestNestedDirBaseReaddir(t *testing.T) {
   167  	base := &MemMapFs{}
   168  	roBase := &ReadOnlyFs{source: base}
   169  	overlay := &MemMapFs{}
   170  
   171  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   172  
   173  	base.MkdirAll("/home/test/foo/bar", 0777)
   174  	fh, _ := base.Create("/home/test/file.txt")
   175  	fh.WriteString("This is a test")
   176  	fh.Close()
   177  
   178  	fh, _ = base.Create("/home/test/foo/file2.txt")
   179  	fh.WriteString("This is a test")
   180  	fh.Close()
   181  	fh, _ = base.Create("/home/test/foo/bar/file3.txt")
   182  	fh.WriteString("This is a test")
   183  	fh.Close()
   184  
   185  	overlay.MkdirAll("/", 0777)
   186  
   187  	// Opening something only in the base
   188  	fh, _ = ufs.Open("/home/test/foo")
   189  	list, err := fh.Readdir(-1)
   190  	if err != nil {
   191  		t.Errorf("Readdir failed %s", err)
   192  	}
   193  	if len(list) != 2 {
   194  		for _, x := range list {
   195  			fmt.Println(x.Name())
   196  		}
   197  		t.Errorf("Got wrong number of files in union: %v", len(list))
   198  	}
   199  }
   200  
   201  func TestNestedDirOverlayReaddir(t *testing.T) {
   202  	base := &MemMapFs{}
   203  	roBase := &ReadOnlyFs{source: base}
   204  	overlay := &MemMapFs{}
   205  
   206  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   207  
   208  	base.MkdirAll("/", 0777)
   209  	overlay.MkdirAll("/home/test/foo/bar", 0777)
   210  	fh, _ := overlay.Create("/home/test/file.txt")
   211  	fh.WriteString("This is a test")
   212  	fh.Close()
   213  	fh, _ = overlay.Create("/home/test/foo/file2.txt")
   214  	fh.WriteString("This is a test")
   215  	fh.Close()
   216  	fh, _ = overlay.Create("/home/test/foo/bar/file3.txt")
   217  	fh.WriteString("This is a test")
   218  	fh.Close()
   219  
   220  	// Opening nested dir only in the overlay
   221  	fh, _ = ufs.Open("/home/test/foo")
   222  	list, err := fh.Readdir(-1)
   223  	if err != nil {
   224  		t.Errorf("Readdir failed %s", err)
   225  	}
   226  	if len(list) != 2 {
   227  		for _, x := range list {
   228  			fmt.Println(x.Name())
   229  		}
   230  		t.Errorf("Got wrong number of files in union: %v", len(list))
   231  	}
   232  }
   233  
   234  func TestNestedDirOverlayOsFsReaddir(t *testing.T) {
   235  	defer CleanupTempDirs(t)
   236  	base := NewTempOsBaseFs(t)
   237  	roBase := &ReadOnlyFs{source: base}
   238  	overlay := NewTempOsBaseFs(t)
   239  
   240  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   241  
   242  	base.MkdirAll("/", 0777)
   243  	overlay.MkdirAll("/home/test/foo/bar", 0777)
   244  	fh, _ := overlay.Create("/home/test/file.txt")
   245  	fh.WriteString("This is a test")
   246  	fh.Close()
   247  	fh, _ = overlay.Create("/home/test/foo/file2.txt")
   248  	fh.WriteString("This is a test")
   249  	fh.Close()
   250  	fh, _ = overlay.Create("/home/test/foo/bar/file3.txt")
   251  	fh.WriteString("This is a test")
   252  	fh.Close()
   253  
   254  	// Opening nested dir only in the overlay
   255  	fh, _ = ufs.Open("/home/test/foo")
   256  	list, err := fh.Readdir(-1)
   257  	fh.Close()
   258  	if err != nil {
   259  		t.Errorf("Readdir failed %s", err)
   260  	}
   261  	if len(list) != 2 {
   262  		for _, x := range list {
   263  			fmt.Println(x.Name())
   264  		}
   265  		t.Errorf("Got wrong number of files in union: %v", len(list))
   266  	}
   267  }
   268  
   269  func TestCopyOnWriteFsWithOsFs(t *testing.T) {
   270  	defer CleanupTempDirs(t)
   271  	base := NewTempOsBaseFs(t)
   272  	roBase := &ReadOnlyFs{source: base}
   273  	overlay := NewTempOsBaseFs(t)
   274  
   275  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   276  
   277  	base.MkdirAll("/home/test", 0777)
   278  	fh, _ := base.Create("/home/test/file.txt")
   279  	fh.WriteString("This is a test")
   280  	fh.Close()
   281  
   282  	overlay.MkdirAll("home/test", 0777)
   283  	fh, _ = overlay.Create("/home/test/file2.txt")
   284  	fh.WriteString("This is a test")
   285  	fh.Close()
   286  
   287  	fh, _ = ufs.Create("/home/test/file3.txt")
   288  	fh.WriteString("This is a test")
   289  	fh.Close()
   290  
   291  	fh, _ = ufs.Open("/home/test")
   292  	files, err := fh.Readdirnames(-1)
   293  	fh.Close()
   294  	if err != nil {
   295  		t.Errorf("Readdirnames failed")
   296  	}
   297  	if len(files) != 3 {
   298  		t.Errorf("Got wrong number of files in union: %v", files)
   299  	}
   300  
   301  	fh, _ = overlay.Open("/home/test")
   302  	files, err = fh.Readdirnames(-1)
   303  	fh.Close()
   304  	if err != nil {
   305  		t.Errorf("Readdirnames failed")
   306  	}
   307  	if len(files) != 2 {
   308  		t.Errorf("Got wrong number of files in overlay: %v", files)
   309  	}
   310  }
   311  
   312  func TestUnionCacheWrite(t *testing.T) {
   313  	base := &MemMapFs{}
   314  	layer := &MemMapFs{}
   315  
   316  	ufs := NewCacheOnReadFs(base, layer, 0)
   317  
   318  	base.Mkdir("/data", 0777)
   319  
   320  	fh, err := ufs.Create("/data/file.txt")
   321  	if err != nil {
   322  		t.Errorf("Failed to create file")
   323  	}
   324  	_, err = fh.Write([]byte("This is a test"))
   325  	if err != nil {
   326  		t.Errorf("Failed to write file")
   327  	}
   328  
   329  	fh.Seek(0, os.SEEK_SET)
   330  	buf := make([]byte, 4)
   331  	_, err = fh.Read(buf)
   332  	fh.Write([]byte(" IS A"))
   333  	fh.Close()
   334  
   335  	baseData, _ := ReadFile(base, "/data/file.txt")
   336  	layerData, _ := ReadFile(layer, "/data/file.txt")
   337  	if string(baseData) != string(layerData) {
   338  		t.Errorf("Different data: %s <=> %s", baseData, layerData)
   339  	}
   340  }
   341  
   342  func TestUnionCacheExpire(t *testing.T) {
   343  	base := &MemMapFs{}
   344  	layer := &MemMapFs{}
   345  	ufs := &CacheOnReadFs{base: base, layer: layer, cacheTime: 1 * time.Second}
   346  
   347  	base.Mkdir("/data", 0777)
   348  
   349  	fh, err := ufs.Create("/data/file.txt")
   350  	if err != nil {
   351  		t.Errorf("Failed to create file")
   352  	}
   353  	_, err = fh.Write([]byte("This is a test"))
   354  	if err != nil {
   355  		t.Errorf("Failed to write file")
   356  	}
   357  	fh.Close()
   358  
   359  	fh, _ = base.Create("/data/file.txt")
   360  	// sleep some time, so we really get a different time.Now() on write...
   361  	time.Sleep(2 * time.Second)
   362  	fh.WriteString("Another test")
   363  	fh.Close()
   364  
   365  	data, _ := ReadFile(ufs, "/data/file.txt")
   366  	if string(data) != "Another test" {
   367  		t.Errorf("cache time failed: <%s>", data)
   368  	}
   369  }
   370  
   371  func TestCacheOnReadFsNotInLayer(t *testing.T) {
   372  	base := NewMemMapFs()
   373  	layer := NewMemMapFs()
   374  	fs := NewCacheOnReadFs(base, layer, 0)
   375  
   376  	fh, err := base.Create("/file.txt")
   377  	if err != nil {
   378  		t.Fatal("unable to create file: ", err)
   379  	}
   380  
   381  	txt := []byte("This is a test")
   382  	fh.Write(txt)
   383  	fh.Close()
   384  
   385  	fh, err = fs.Open("/file.txt")
   386  	if err != nil {
   387  		t.Fatal("could not open file: ", err)
   388  	}
   389  
   390  	b, err := ReadAll(fh)
   391  	fh.Close()
   392  
   393  	if err != nil {
   394  		t.Fatal("could not read file: ", err)
   395  	} else if !bytes.Equal(txt, b) {
   396  		t.Fatalf("wanted file text %q, got %q", txt, b)
   397  	}
   398  
   399  	fh, err = layer.Open("/file.txt")
   400  	if err != nil {
   401  		t.Fatal("could not open file from layer: ", err)
   402  	}
   403  	fh.Close()
   404  }
   405  
   406  // #194
   407  func TestUnionFileReaddirEmpty(t *testing.T) {
   408  	osFs := NewOsFs()
   409  
   410  	base := NewMemMapFs()
   411  	overlay := NewMemMapFs()
   412  	ufs := &CopyOnWriteFs{base: base, layer: overlay}
   413  	mem := NewMemMapFs()
   414  
   415  	// The OS file will return io.EOF on end of directory.
   416  	for _, fs := range []Fs{osFs, ufs, mem} {
   417  		baseDir, err := TempDir(fs, "", "empty-dir")
   418  		if err != nil {
   419  			t.Fatal(err)
   420  		}
   421  
   422  		f, err := fs.Open(baseDir)
   423  		if err != nil {
   424  			t.Fatal(err)
   425  		}
   426  
   427  		names, err := f.Readdirnames(1)
   428  		if err != io.EOF {
   429  			t.Fatal(err)
   430  		}
   431  
   432  		if len(names) != 0 {
   433  			t.Fatal("should be empty")
   434  		}
   435  
   436  		f.Close()
   437  
   438  		fs.RemoveAll(baseDir)
   439  	}
   440  }
   441  
   442  // #197
   443  func TestUnionFileReaddirDuplicateEmpty(t *testing.T) {
   444  	base := NewMemMapFs()
   445  	dir, err := TempDir(base, "", "empty-dir")
   446  	if err != nil {
   447  		t.Fatal(err)
   448  	}
   449  
   450  	// Overlay shares same empty directory as base
   451  	overlay := NewMemMapFs()
   452  	err = overlay.Mkdir(dir, 0700)
   453  	if err != nil {
   454  		t.Fatal(err)
   455  	}
   456  
   457  	ufs := &CopyOnWriteFs{base: base, layer: overlay}
   458  
   459  	f, err := ufs.Open(dir)
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  	defer f.Close()
   464  
   465  	names, err := f.Readdirnames(0)
   466  
   467  	if err == io.EOF {
   468  		t.Errorf("unexpected io.EOF error")
   469  	}
   470  
   471  	if len(names) != 0 {
   472  		t.Fatal("should be empty")
   473  	}
   474  }
   475  
   476  func TestUnionFileReaddirAskForTooMany(t *testing.T) {
   477  	base := &MemMapFs{}
   478  	overlay := &MemMapFs{}
   479  
   480  	const testFiles = 5
   481  	for i := 0; i < testFiles; i++ {
   482  		WriteFile(base, fmt.Sprintf("file%d.txt", i), []byte("afero"), 0777)
   483  	}
   484  
   485  	ufs := &CopyOnWriteFs{base: base, layer: overlay}
   486  
   487  	f, err := ufs.Open("")
   488  	if err != nil {
   489  		t.Fatal(err)
   490  	}
   491  
   492  	defer f.Close()
   493  
   494  	// Read part of all files
   495  	wantNames := 3
   496  	names, err := f.Readdirnames(wantNames)
   497  	if err != nil {
   498  		t.Fatal(err)
   499  	}
   500  	if len(names) != wantNames {
   501  		t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
   502  	}
   503  
   504  	// Try to read more files than remaining
   505  	wantNames = testFiles - len(names)
   506  	names, err = f.Readdirnames(wantNames + 1)
   507  	if err != nil {
   508  		t.Fatal(err)
   509  	}
   510  	if len(names) != wantNames {
   511  		t.Fatalf("got %d names %v, want %d", len(names), names, wantNames)
   512  	}
   513  
   514  	// End of directory
   515  	_, err = f.Readdirnames(3)
   516  	if err != io.EOF {
   517  		t.Fatal(err)
   518  	}
   519  }