github.com/landontclipp/afero@v1.1.1/composite_test.go (about)

     1  package afero
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"testing"
     9  	"time"
    10  )
    11  
    12  var tempDirs []string
    13  
    14  func NewTempOsBaseFs(t *testing.T) Fs {
    15  	name, err := TempDir(NewOsFs(), "", "")
    16  	if err != nil {
    17  		t.Error("error creating tempDir", err)
    18  	}
    19  
    20  	tempDirs = append(tempDirs, name)
    21  
    22  	return NewBasePathFs(NewOsFs(), name)
    23  }
    24  
    25  func CleanupTempDirs(t *testing.T) {
    26  	osfs := NewOsFs()
    27  	type ev struct {
    28  		path string
    29  		e    error
    30  	}
    31  
    32  	errs := []ev{}
    33  
    34  	for _, x := range tempDirs {
    35  		err := osfs.RemoveAll(x)
    36  		if err != nil {
    37  			errs = append(errs, ev{path: x, e: err})
    38  		}
    39  	}
    40  
    41  	for _, e := range errs {
    42  		fmt.Println("error removing tempDir", e.path, e.e)
    43  	}
    44  
    45  	if len(errs) > 0 {
    46  		t.Error("error cleaning up tempDirs")
    47  	}
    48  	tempDirs = []string{}
    49  }
    50  
    51  func TestUnionCreateExisting(t *testing.T) {
    52  	base := &MemMapFs{}
    53  	roBase := &ReadOnlyFs{source: base}
    54  	ufs := NewCopyOnWriteFs(roBase, &MemMapFs{})
    55  
    56  	base.MkdirAll("/home/test", 0777)
    57  	fh, _ := base.Create("/home/test/file.txt")
    58  	fh.WriteString("This is a test")
    59  	fh.Close()
    60  
    61  	fh, err := ufs.OpenFile("/home/test/file.txt", os.O_RDWR, 0666)
    62  	if err != nil {
    63  		t.Errorf("Failed to open file r/w: %s", err)
    64  	}
    65  
    66  	_, err = fh.Write([]byte("####"))
    67  	if err != nil {
    68  		t.Errorf("Failed to write file: %s", err)
    69  	}
    70  	fh.Seek(0, 0)
    71  	data, err := ioutil.ReadAll(fh)
    72  	if err != nil {
    73  		t.Errorf("Failed to read file: %s", err)
    74  	}
    75  	if string(data) != "#### is a test" {
    76  		t.Errorf("Got wrong data")
    77  	}
    78  	fh.Close()
    79  
    80  	fh, _ = base.Open("/home/test/file.txt")
    81  	data, err = ioutil.ReadAll(fh)
    82  	if string(data) != "This is a test" {
    83  		t.Errorf("Got wrong data in base file")
    84  	}
    85  	fh.Close()
    86  
    87  	fh, err = ufs.Create("/home/test/file.txt")
    88  	switch err {
    89  	case nil:
    90  		if fi, _ := fh.Stat(); fi.Size() != 0 {
    91  			t.Errorf("Create did not truncate file")
    92  		}
    93  		fh.Close()
    94  	default:
    95  		t.Errorf("Create failed on existing file")
    96  	}
    97  
    98  }
    99  
   100  func TestUnionMergeReaddir(t *testing.T) {
   101  	base := &MemMapFs{}
   102  	roBase := &ReadOnlyFs{source: base}
   103  
   104  	ufs := &CopyOnWriteFs{base: roBase, layer: &MemMapFs{}}
   105  
   106  	base.MkdirAll("/home/test", 0777)
   107  	fh, _ := base.Create("/home/test/file.txt")
   108  	fh.WriteString("This is a test")
   109  	fh.Close()
   110  
   111  	fh, _ = ufs.Create("/home/test/file2.txt")
   112  	fh.WriteString("This is a test")
   113  	fh.Close()
   114  
   115  	fh, _ = ufs.Open("/home/test")
   116  	files, err := fh.Readdirnames(-1)
   117  	if err != nil {
   118  		t.Errorf("Readdirnames failed")
   119  	}
   120  	if len(files) != 2 {
   121  		t.Errorf("Got wrong number of files: %v", files)
   122  	}
   123  }
   124  
   125  func TestExistingDirectoryCollisionReaddir(t *testing.T) {
   126  	base := &MemMapFs{}
   127  	roBase := &ReadOnlyFs{source: base}
   128  	overlay := &MemMapFs{}
   129  
   130  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   131  
   132  	base.MkdirAll("/home/test", 0777)
   133  	fh, _ := base.Create("/home/test/file.txt")
   134  	fh.WriteString("This is a test")
   135  	fh.Close()
   136  
   137  	overlay.MkdirAll("home/test", 0777)
   138  	fh, _ = overlay.Create("/home/test/file2.txt")
   139  	fh.WriteString("This is a test")
   140  	fh.Close()
   141  
   142  	fh, _ = ufs.Create("/home/test/file3.txt")
   143  	fh.WriteString("This is a test")
   144  	fh.Close()
   145  
   146  	fh, _ = ufs.Open("/home/test")
   147  	files, err := fh.Readdirnames(-1)
   148  	if err != nil {
   149  		t.Errorf("Readdirnames failed")
   150  	}
   151  	if len(files) != 3 {
   152  		t.Errorf("Got wrong number of files in union: %v", files)
   153  	}
   154  
   155  	fh, _ = overlay.Open("/home/test")
   156  	files, err = fh.Readdirnames(-1)
   157  	if err != nil {
   158  		t.Errorf("Readdirnames failed")
   159  	}
   160  	if len(files) != 2 {
   161  		t.Errorf("Got wrong number of files in overlay: %v", files)
   162  	}
   163  }
   164  
   165  func TestNestedDirBaseReaddir(t *testing.T) {
   166  	base := &MemMapFs{}
   167  	roBase := &ReadOnlyFs{source: base}
   168  	overlay := &MemMapFs{}
   169  
   170  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   171  
   172  	base.MkdirAll("/home/test/foo/bar", 0777)
   173  	fh, _ := base.Create("/home/test/file.txt")
   174  	fh.WriteString("This is a test")
   175  	fh.Close()
   176  
   177  	fh, _ = base.Create("/home/test/foo/file2.txt")
   178  	fh.WriteString("This is a test")
   179  	fh.Close()
   180  	fh, _ = base.Create("/home/test/foo/bar/file3.txt")
   181  	fh.WriteString("This is a test")
   182  	fh.Close()
   183  
   184  	overlay.MkdirAll("/", 0777)
   185  
   186  	// Opening something only in the base
   187  	fh, _ = ufs.Open("/home/test/foo")
   188  	list, err := fh.Readdir(-1)
   189  	if err != nil {
   190  		t.Errorf("Readdir failed %s", err)
   191  	}
   192  	if len(list) != 2 {
   193  		for _, x := range list {
   194  			fmt.Println(x.Name())
   195  		}
   196  		t.Errorf("Got wrong number of files in union: %v", len(list))
   197  	}
   198  }
   199  
   200  func TestNestedDirOverlayReaddir(t *testing.T) {
   201  	base := &MemMapFs{}
   202  	roBase := &ReadOnlyFs{source: base}
   203  	overlay := &MemMapFs{}
   204  
   205  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   206  
   207  	base.MkdirAll("/", 0777)
   208  	overlay.MkdirAll("/home/test/foo/bar", 0777)
   209  	fh, _ := overlay.Create("/home/test/file.txt")
   210  	fh.WriteString("This is a test")
   211  	fh.Close()
   212  	fh, _ = overlay.Create("/home/test/foo/file2.txt")
   213  	fh.WriteString("This is a test")
   214  	fh.Close()
   215  	fh, _ = overlay.Create("/home/test/foo/bar/file3.txt")
   216  	fh.WriteString("This is a test")
   217  	fh.Close()
   218  
   219  	// Opening nested dir only in the overlay
   220  	fh, _ = ufs.Open("/home/test/foo")
   221  	list, err := fh.Readdir(-1)
   222  	if err != nil {
   223  		t.Errorf("Readdir failed %s", err)
   224  	}
   225  	if len(list) != 2 {
   226  		for _, x := range list {
   227  			fmt.Println(x.Name())
   228  		}
   229  		t.Errorf("Got wrong number of files in union: %v", len(list))
   230  	}
   231  }
   232  
   233  func TestNestedDirOverlayOsFsReaddir(t *testing.T) {
   234  	defer CleanupTempDirs(t)
   235  	base := NewTempOsBaseFs(t)
   236  	roBase := &ReadOnlyFs{source: base}
   237  	overlay := NewTempOsBaseFs(t)
   238  
   239  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   240  
   241  	base.MkdirAll("/", 0777)
   242  	overlay.MkdirAll("/home/test/foo/bar", 0777)
   243  	fh, _ := overlay.Create("/home/test/file.txt")
   244  	fh.WriteString("This is a test")
   245  	fh.Close()
   246  	fh, _ = overlay.Create("/home/test/foo/file2.txt")
   247  	fh.WriteString("This is a test")
   248  	fh.Close()
   249  	fh, _ = overlay.Create("/home/test/foo/bar/file3.txt")
   250  	fh.WriteString("This is a test")
   251  	fh.Close()
   252  
   253  	// Opening nested dir only in the overlay
   254  	fh, _ = ufs.Open("/home/test/foo")
   255  	list, err := fh.Readdir(-1)
   256  	fh.Close()
   257  	if err != nil {
   258  		t.Errorf("Readdir failed %s", err)
   259  	}
   260  	if len(list) != 2 {
   261  		for _, x := range list {
   262  			fmt.Println(x.Name())
   263  		}
   264  		t.Errorf("Got wrong number of files in union: %v", len(list))
   265  	}
   266  }
   267  
   268  func TestCopyOnWriteFsWithOsFs(t *testing.T) {
   269  	defer CleanupTempDirs(t)
   270  	base := NewTempOsBaseFs(t)
   271  	roBase := &ReadOnlyFs{source: base}
   272  	overlay := NewTempOsBaseFs(t)
   273  
   274  	ufs := &CopyOnWriteFs{base: roBase, layer: overlay}
   275  
   276  	base.MkdirAll("/home/test", 0777)
   277  	fh, _ := base.Create("/home/test/file.txt")
   278  	fh.WriteString("This is a test")
   279  	fh.Close()
   280  
   281  	overlay.MkdirAll("home/test", 0777)
   282  	fh, _ = overlay.Create("/home/test/file2.txt")
   283  	fh.WriteString("This is a test")
   284  	fh.Close()
   285  
   286  	fh, _ = ufs.Create("/home/test/file3.txt")
   287  	fh.WriteString("This is a test")
   288  	fh.Close()
   289  
   290  	fh, _ = ufs.Open("/home/test")
   291  	files, err := fh.Readdirnames(-1)
   292  	fh.Close()
   293  	if err != nil {
   294  		t.Errorf("Readdirnames failed")
   295  	}
   296  	if len(files) != 3 {
   297  		t.Errorf("Got wrong number of files in union: %v", files)
   298  	}
   299  
   300  	fh, _ = overlay.Open("/home/test")
   301  	files, err = fh.Readdirnames(-1)
   302  	fh.Close()
   303  	if err != nil {
   304  		t.Errorf("Readdirnames failed")
   305  	}
   306  	if len(files) != 2 {
   307  		t.Errorf("Got wrong number of files in overlay: %v", files)
   308  	}
   309  }
   310  
   311  func TestUnionCacheWrite(t *testing.T) {
   312  	base := &MemMapFs{}
   313  	layer := &MemMapFs{}
   314  
   315  	ufs := NewCacheOnReadFs(base, layer, 0)
   316  
   317  	base.Mkdir("/data", 0777)
   318  
   319  	fh, err := ufs.Create("/data/file.txt")
   320  	if err != nil {
   321  		t.Errorf("Failed to create file")
   322  	}
   323  	_, err = fh.Write([]byte("This is a test"))
   324  	if err != nil {
   325  		t.Errorf("Failed to write file")
   326  	}
   327  
   328  	fh.Seek(0, os.SEEK_SET)
   329  	buf := make([]byte, 4)
   330  	_, err = fh.Read(buf)
   331  	fh.Write([]byte(" IS A"))
   332  	fh.Close()
   333  
   334  	baseData, _ := ReadFile(base, "/data/file.txt")
   335  	layerData, _ := ReadFile(layer, "/data/file.txt")
   336  	if string(baseData) != string(layerData) {
   337  		t.Errorf("Different data: %s <=> %s", baseData, layerData)
   338  	}
   339  }
   340  
   341  func TestUnionCacheExpire(t *testing.T) {
   342  	base := &MemMapFs{}
   343  	layer := &MemMapFs{}
   344  	ufs := &CacheOnReadFs{base: base, layer: layer, cacheTime: 1 * time.Second}
   345  
   346  	base.Mkdir("/data", 0777)
   347  
   348  	fh, err := ufs.Create("/data/file.txt")
   349  	if err != nil {
   350  		t.Errorf("Failed to create file")
   351  	}
   352  	_, err = fh.Write([]byte("This is a test"))
   353  	if err != nil {
   354  		t.Errorf("Failed to write file")
   355  	}
   356  	fh.Close()
   357  
   358  	fh, _ = base.Create("/data/file.txt")
   359  	// sleep some time, so we really get a different time.Now() on write...
   360  	time.Sleep(2 * time.Second)
   361  	fh.WriteString("Another test")
   362  	fh.Close()
   363  
   364  	data, _ := ReadFile(ufs, "/data/file.txt")
   365  	if string(data) != "Another test" {
   366  		t.Errorf("cache time failed: <%s>", data)
   367  	}
   368  }
   369  
   370  func TestCacheOnReadFsNotInLayer(t *testing.T) {
   371  	base := NewMemMapFs()
   372  	layer := NewMemMapFs()
   373  	fs := NewCacheOnReadFs(base, layer, 0)
   374  
   375  	fh, err := base.Create("/file.txt")
   376  	if err != nil {
   377  		t.Fatal("unable to create file: ", err)
   378  	}
   379  
   380  	txt := []byte("This is a test")
   381  	fh.Write(txt)
   382  	fh.Close()
   383  
   384  	fh, err = fs.Open("/file.txt")
   385  	if err != nil {
   386  		t.Fatal("could not open file: ", err)
   387  	}
   388  
   389  	b, err := ReadAll(fh)
   390  	fh.Close()
   391  
   392  	if err != nil {
   393  		t.Fatal("could not read file: ", err)
   394  	} else if !bytes.Equal(txt, b) {
   395  		t.Fatalf("wanted file text %q, got %q", txt, b)
   396  	}
   397  
   398  	fh, err = layer.Open("/file.txt")
   399  	if err != nil {
   400  		t.Fatal("could not open file from layer: ", err)
   401  	}
   402  	fh.Close()
   403  }