github.com/halybang/go-ethereum@v1.0.5-0.20180325041310-3b262bc1367c/swarm/fuse/swarmfs_test.go (about)

     1  // Copyright 2017 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  // +build linux darwin freebsd
    18  
    19  package fuse
    20  
    21  import (
    22  	"bytes"
    23  	"crypto/rand"
    24  	"io"
    25  	"io/ioutil"
    26  	"os"
    27  	"path/filepath"
    28  	"testing"
    29  
    30  	"github.com/wanchain/go-wanchain/swarm/api"
    31  	"github.com/wanchain/go-wanchain/swarm/storage"
    32  )
    33  
    34  type fileInfo struct {
    35  	perm     uint64
    36  	uid      int
    37  	gid      int
    38  	contents []byte
    39  }
    40  
    41  func createTestFilesAndUploadToSwarm(t *testing.T, api *api.Api, files map[string]fileInfo, uploadDir string) string {
    42  	os.RemoveAll(uploadDir)
    43  
    44  	for fname, finfo := range files {
    45  		actualPath := filepath.Join(uploadDir, fname)
    46  		filePath := filepath.Dir(actualPath)
    47  
    48  		err := os.MkdirAll(filePath, 0777)
    49  		if err != nil {
    50  			t.Fatalf("Error creating directory '%v' : %v", filePath, err)
    51  		}
    52  
    53  		fd, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(finfo.perm))
    54  		if err1 != nil {
    55  			t.Fatalf("Error creating file %v: %v", actualPath, err1)
    56  		}
    57  
    58  		fd.Write(finfo.contents)
    59  		fd.Chown(finfo.uid, finfo.gid)
    60  		fd.Chmod(os.FileMode(finfo.perm))
    61  		fd.Sync()
    62  		fd.Close()
    63  	}
    64  
    65  	bzzhash, err := api.Upload(uploadDir, "")
    66  	if err != nil {
    67  		t.Fatalf("Error uploading directory %v: %v", uploadDir, err)
    68  	}
    69  
    70  	return bzzhash
    71  }
    72  
    73  func mountDir(t *testing.T, api *api.Api, files map[string]fileInfo, bzzHash string, mountDir string) *SwarmFS {
    74  	os.RemoveAll(mountDir)
    75  	os.MkdirAll(mountDir, 0777)
    76  	swarmfs := NewSwarmFS(api)
    77  	_, err := swarmfs.Mount(bzzHash, mountDir)
    78  	if isFUSEUnsupportedError(err) {
    79  		t.Skip("FUSE not supported:", err)
    80  	} else if err != nil {
    81  		t.Fatalf("Error mounting hash %v: %v", bzzHash, err)
    82  	}
    83  
    84  	found := false
    85  	mi := swarmfs.Listmounts()
    86  	for _, minfo := range mi {
    87  		if minfo.MountPoint == mountDir {
    88  			if minfo.StartManifest != bzzHash ||
    89  				minfo.LatestManifest != bzzHash ||
    90  				minfo.fuseConnection == nil {
    91  				t.Fatalf("Error mounting: exp(%s): act(%s)", bzzHash, minfo.StartManifest)
    92  			}
    93  			found = true
    94  		}
    95  	}
    96  
    97  	// Test listMounts
    98  	if found == false {
    99  		t.Fatalf("Error getting mounts information for %v: %v", mountDir, err)
   100  	}
   101  
   102  	// Check if file and their attributes are as expected
   103  	compareGeneratedFileWithFileInMount(t, files, mountDir)
   104  
   105  	return swarmfs
   106  }
   107  
   108  func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo, mountDir string) {
   109  	err := filepath.Walk(mountDir, func(path string, f os.FileInfo, err error) error {
   110  		if f.IsDir() {
   111  			return nil
   112  		}
   113  		fname := path[len(mountDir)+1:]
   114  		if _, ok := files[fname]; !ok {
   115  			t.Fatalf(" file %v present in mount dir and is not expected", fname)
   116  		}
   117  		return nil
   118  	})
   119  	if err != nil {
   120  		t.Fatalf("Error walking dir %v", mountDir)
   121  	}
   122  
   123  	for fname, finfo := range files {
   124  		destinationFile := filepath.Join(mountDir, fname)
   125  
   126  		dfinfo, err := os.Stat(destinationFile)
   127  		if err != nil {
   128  			t.Fatalf("Destination file %v missing in mount: %v", fname, err)
   129  		}
   130  
   131  		if int64(len(finfo.contents)) != dfinfo.Size() {
   132  			t.Fatalf("file %v Size mismatch  source (%v) vs destination(%v)", fname, int64(len(finfo.contents)), dfinfo.Size())
   133  		}
   134  
   135  		if dfinfo.Mode().Perm().String() != "-rwx------" {
   136  			t.Fatalf("file %v Permission mismatch source (-rwx------) vs destination(%v)", fname, dfinfo.Mode().Perm())
   137  		}
   138  
   139  		fileContents, err := ioutil.ReadFile(filepath.Join(mountDir, fname))
   140  		if err != nil {
   141  			t.Fatalf("Could not readfile %v : %v", fname, err)
   142  		}
   143  		if !bytes.Equal(fileContents, finfo.contents) {
   144  			t.Fatalf("File %v contents mismatch: %v , %v", fname, fileContents, finfo.contents)
   145  
   146  		}
   147  		// TODO: check uid and gid
   148  	}
   149  }
   150  
   151  func checkFile(t *testing.T, testMountDir, fname string, contents []byte) {
   152  	destinationFile := filepath.Join(testMountDir, fname)
   153  	dfinfo, err1 := os.Stat(destinationFile)
   154  	if err1 != nil {
   155  		t.Fatalf("Could not stat file %v", destinationFile)
   156  	}
   157  	if dfinfo.Size() != int64(len(contents)) {
   158  		t.Fatalf("Mismatch in size  actual(%v) vs expected(%v)", dfinfo.Size(), int64(len(contents)))
   159  	}
   160  
   161  	fd, err2 := os.OpenFile(destinationFile, os.O_RDONLY, os.FileMode(0665))
   162  	if err2 != nil {
   163  		t.Fatalf("Could not open file %v", destinationFile)
   164  	}
   165  	newcontent := make([]byte, len(contents))
   166  	fd.Read(newcontent)
   167  	fd.Close()
   168  
   169  	if !bytes.Equal(contents, newcontent) {
   170  		t.Fatalf("File content mismatch expected (%v): received (%v) ", contents, newcontent)
   171  	}
   172  }
   173  
   174  func getRandomBtes(size int) []byte {
   175  	contents := make([]byte, size)
   176  	rand.Read(contents)
   177  	return contents
   178  }
   179  
   180  func isDirEmpty(name string) bool {
   181  	f, err := os.Open(name)
   182  	if err != nil {
   183  		return false
   184  	}
   185  	defer f.Close()
   186  
   187  	_, err = f.Readdirnames(1)
   188  	if err == io.EOF {
   189  		return true
   190  	}
   191  	return false
   192  }
   193  
   194  type testAPI struct {
   195  	api *api.Api
   196  }
   197  
   198  func (ta *testAPI) mountListAndUnmount(t *testing.T) {
   199  	files := make(map[string]fileInfo)
   200  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "fuse-source")
   201  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "fuse-dest")
   202  
   203  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   204  	files["2.txt"] = fileInfo{0711, 333, 444, getRandomBtes(10)}
   205  	files["3.txt"] = fileInfo{0622, 333, 444, getRandomBtes(100)}
   206  	files["4.txt"] = fileInfo{0533, 333, 444, getRandomBtes(1024)}
   207  	files["5.txt"] = fileInfo{0544, 333, 444, getRandomBtes(10)}
   208  	files["6.txt"] = fileInfo{0555, 333, 444, getRandomBtes(10)}
   209  	files["7.txt"] = fileInfo{0666, 333, 444, getRandomBtes(10)}
   210  	files["8.txt"] = fileInfo{0777, 333, 333, getRandomBtes(10)}
   211  	files["11.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)}
   212  	files["111.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)}
   213  	files["two/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)}
   214  	files["two/2/2.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10)}
   215  	files["two/2./2.txt"] = fileInfo{0777, 444, 444, getRandomBtes(10)}
   216  	files["twice/2.txt"] = fileInfo{0777, 444, 333, getRandomBtes(200)}
   217  	files["one/two/three/four/five/six/seven/eight/nine/10.txt"] = fileInfo{0777, 333, 444, getRandomBtes(10240)}
   218  	files["one/two/three/four/five/six/six"] = fileInfo{0777, 333, 444, getRandomBtes(10)}
   219  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   220  
   221  	swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir)
   222  	defer swarmfs.Stop()
   223  
   224  	// Check unmount
   225  	_, err := swarmfs.Unmount(testMountDir)
   226  	if err != nil {
   227  		t.Fatalf("could not unmount  %v", bzzHash)
   228  	}
   229  	if !isDirEmpty(testMountDir) {
   230  		t.Fatalf("unmount didnt work for %v", testMountDir)
   231  	}
   232  
   233  }
   234  
   235  func (ta *testAPI) maxMounts(t *testing.T) {
   236  	files := make(map[string]fileInfo)
   237  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   238  	uploadDir1, _ := ioutil.TempDir(os.TempDir(), "max-upload1")
   239  	bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1)
   240  	mount1, _ := ioutil.TempDir(os.TempDir(), "max-mount1")
   241  	swarmfs1 := mountDir(t, ta.api, files, bzzHash1, mount1)
   242  	defer swarmfs1.Stop()
   243  
   244  	files["2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   245  	uploadDir2, _ := ioutil.TempDir(os.TempDir(), "max-upload2")
   246  	bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2)
   247  	mount2, _ := ioutil.TempDir(os.TempDir(), "max-mount2")
   248  	swarmfs2 := mountDir(t, ta.api, files, bzzHash2, mount2)
   249  	defer swarmfs2.Stop()
   250  
   251  	files["3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   252  	uploadDir3, _ := ioutil.TempDir(os.TempDir(), "max-upload3")
   253  	bzzHash3 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir3)
   254  	mount3, _ := ioutil.TempDir(os.TempDir(), "max-mount3")
   255  	swarmfs3 := mountDir(t, ta.api, files, bzzHash3, mount3)
   256  	defer swarmfs3.Stop()
   257  
   258  	files["4.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   259  	uploadDir4, _ := ioutil.TempDir(os.TempDir(), "max-upload4")
   260  	bzzHash4 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir4)
   261  	mount4, _ := ioutil.TempDir(os.TempDir(), "max-mount4")
   262  	swarmfs4 := mountDir(t, ta.api, files, bzzHash4, mount4)
   263  	defer swarmfs4.Stop()
   264  
   265  	files["5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   266  	uploadDir5, _ := ioutil.TempDir(os.TempDir(), "max-upload5")
   267  	bzzHash5 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir5)
   268  	mount5, _ := ioutil.TempDir(os.TempDir(), "max-mount5")
   269  	swarmfs5 := mountDir(t, ta.api, files, bzzHash5, mount5)
   270  	defer swarmfs5.Stop()
   271  
   272  	files["6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   273  	uploadDir6, _ := ioutil.TempDir(os.TempDir(), "max-upload6")
   274  	bzzHash6 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir6)
   275  	mount6, _ := ioutil.TempDir(os.TempDir(), "max-mount6")
   276  
   277  	os.RemoveAll(mount6)
   278  	os.MkdirAll(mount6, 0777)
   279  	_, err := swarmfs.Mount(bzzHash6, mount6)
   280  	if err == nil {
   281  		t.Fatalf("Error: Going beyond max mounts  %v", bzzHash6)
   282  	}
   283  
   284  }
   285  
   286  func (ta *testAPI) remount(t *testing.T) {
   287  	files := make(map[string]fileInfo)
   288  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   289  	uploadDir1, _ := ioutil.TempDir(os.TempDir(), "re-upload1")
   290  	bzzHash1 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir1)
   291  	testMountDir1, _ := ioutil.TempDir(os.TempDir(), "re-mount1")
   292  	swarmfs := mountDir(t, ta.api, files, bzzHash1, testMountDir1)
   293  	defer swarmfs.Stop()
   294  
   295  	uploadDir2, _ := ioutil.TempDir(os.TempDir(), "re-upload2")
   296  	bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir2)
   297  	testMountDir2, _ := ioutil.TempDir(os.TempDir(), "re-mount2")
   298  
   299  	// try mounting the same hash second time
   300  	os.RemoveAll(testMountDir2)
   301  	os.MkdirAll(testMountDir2, 0777)
   302  	_, err := swarmfs.Mount(bzzHash1, testMountDir2)
   303  	if err != nil {
   304  		t.Fatalf("Error mounting hash  %v", bzzHash1)
   305  	}
   306  
   307  	// mount a different hash in already mounted point
   308  	_, err = swarmfs.Mount(bzzHash2, testMountDir1)
   309  	if err == nil {
   310  		t.Fatalf("Error mounting hash  %v", bzzHash2)
   311  	}
   312  
   313  	// mount nonexistent hash
   314  	_, err = swarmfs.Mount("0xfea11223344", testMountDir1)
   315  	if err == nil {
   316  		t.Fatalf("Error mounting hash  %v", bzzHash2)
   317  	}
   318  }
   319  
   320  func (ta *testAPI) unmount(t *testing.T) {
   321  	files := make(map[string]fileInfo)
   322  	uploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload")
   323  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount")
   324  
   325  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   326  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, uploadDir)
   327  
   328  	swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir)
   329  	defer swarmfs.Stop()
   330  
   331  	swarmfs.Unmount(testMountDir)
   332  
   333  	mi := swarmfs.Listmounts()
   334  	for _, minfo := range mi {
   335  		if minfo.MountPoint == testMountDir {
   336  			t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir)
   337  		}
   338  	}
   339  }
   340  
   341  func (ta *testAPI) unmountWhenResourceBusy(t *testing.T) {
   342  	files := make(map[string]fileInfo)
   343  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "ex-upload")
   344  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "ex-mount")
   345  
   346  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   347  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   348  
   349  	swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir)
   350  	defer swarmfs.Stop()
   351  
   352  	actualPath := filepath.Join(testMountDir, "2.txt")
   353  	d, err := os.OpenFile(actualPath, os.O_RDWR, os.FileMode(0700))
   354  	d.Write(getRandomBtes(10))
   355  
   356  	_, err = swarmfs.Unmount(testMountDir)
   357  	if err != nil {
   358  		t.Fatalf("could not unmount  %v", bzzHash)
   359  	}
   360  	d.Close()
   361  
   362  	mi := swarmfs.Listmounts()
   363  	for _, minfo := range mi {
   364  		if minfo.MountPoint == testMountDir {
   365  			t.Fatalf("mount state not cleaned up in unmount case %v", testMountDir)
   366  		}
   367  	}
   368  }
   369  
   370  func (ta *testAPI) seekInMultiChunkFile(t *testing.T) {
   371  	files := make(map[string]fileInfo)
   372  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "seek-upload")
   373  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "seek-mount")
   374  
   375  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10240)}
   376  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   377  
   378  	swarmfs := mountDir(t, ta.api, files, bzzHash, testMountDir)
   379  	defer swarmfs.Stop()
   380  
   381  	// Create a new file seek the second chunk
   382  	actualPath := filepath.Join(testMountDir, "1.txt")
   383  	d, _ := os.OpenFile(actualPath, os.O_RDONLY, os.FileMode(0700))
   384  
   385  	d.Seek(5000, 0)
   386  
   387  	contents := make([]byte, 1024)
   388  	d.Read(contents)
   389  	finfo := files["1.txt"]
   390  
   391  	if bytes.Compare(finfo.contents[:6024][5000:], contents) != 0 {
   392  		t.Fatalf("File seek contents mismatch")
   393  	}
   394  	d.Close()
   395  }
   396  
   397  func (ta *testAPI) createNewFile(t *testing.T) {
   398  	files := make(map[string]fileInfo)
   399  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "create-upload")
   400  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "create-mount")
   401  
   402  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   403  	files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   404  	files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   405  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   406  
   407  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   408  	defer swarmfs1.Stop()
   409  
   410  	// Create a new file in the root dir and check
   411  	actualPath := filepath.Join(testMountDir, "2.txt")
   412  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   413  	if err1 != nil {
   414  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   415  	}
   416  	contents := make([]byte, 11)
   417  	rand.Read(contents)
   418  	d.Write(contents)
   419  	d.Close()
   420  
   421  	mi, err2 := swarmfs1.Unmount(testMountDir)
   422  	if err2 != nil {
   423  		t.Fatalf("Could not unmount %v", err2)
   424  	}
   425  
   426  	// mount again and see if things are okay
   427  	files["2.txt"] = fileInfo{0700, 333, 444, contents}
   428  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   429  	defer swarmfs2.Stop()
   430  
   431  	checkFile(t, testMountDir, "2.txt", contents)
   432  }
   433  
   434  func (ta *testAPI) createNewFileInsideDirectory(t *testing.T) {
   435  	files := make(map[string]fileInfo)
   436  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-upload")
   437  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidedir-mount")
   438  
   439  	files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   440  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   441  
   442  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   443  	defer swarmfs1.Stop()
   444  
   445  	// Create a new file inside a existing dir and check
   446  	dirToCreate := filepath.Join(testMountDir, "one")
   447  	actualPath := filepath.Join(dirToCreate, "2.txt")
   448  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   449  	if err1 != nil {
   450  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   451  	}
   452  	contents := make([]byte, 11)
   453  	rand.Read(contents)
   454  	d.Write(contents)
   455  	d.Close()
   456  
   457  	mi, err2 := swarmfs1.Unmount(testMountDir)
   458  	if err2 != nil {
   459  		t.Fatalf("Could not unmount %v", err2)
   460  	}
   461  
   462  	// mount again and see if things are okay
   463  	files["one/2.txt"] = fileInfo{0700, 333, 444, contents}
   464  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   465  	defer swarmfs2.Stop()
   466  
   467  	checkFile(t, testMountDir, "one/2.txt", contents)
   468  }
   469  
   470  func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T) {
   471  	files := make(map[string]fileInfo)
   472  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-upload")
   473  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "createinsidenewdir-mount")
   474  
   475  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   476  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   477  
   478  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   479  	defer swarmfs1.Stop()
   480  
   481  	// Create a new file inside a existing dir and check
   482  	dirToCreate := filepath.Join(testMountDir, "one")
   483  	os.MkdirAll(dirToCreate, 0777)
   484  	actualPath := filepath.Join(dirToCreate, "2.txt")
   485  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   486  	if err1 != nil {
   487  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   488  	}
   489  	contents := make([]byte, 11)
   490  	rand.Read(contents)
   491  	d.Write(contents)
   492  	d.Close()
   493  
   494  	mi, err2 := swarmfs1.Unmount(testMountDir)
   495  	if err2 != nil {
   496  		t.Fatalf("Could not unmount %v", err2)
   497  	}
   498  
   499  	// mount again and see if things are okay
   500  	files["one/2.txt"] = fileInfo{0700, 333, 444, contents}
   501  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   502  	defer swarmfs2.Stop()
   503  
   504  	checkFile(t, testMountDir, "one/2.txt", contents)
   505  }
   506  
   507  func (ta *testAPI) removeExistingFile(t *testing.T) {
   508  	files := make(map[string]fileInfo)
   509  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload")
   510  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount")
   511  
   512  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   513  	files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   514  	files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   515  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   516  
   517  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   518  	defer swarmfs1.Stop()
   519  
   520  	// Remove a file in the root dir and check
   521  	actualPath := filepath.Join(testMountDir, "five.txt")
   522  	os.Remove(actualPath)
   523  
   524  	mi, err2 := swarmfs1.Unmount(testMountDir)
   525  	if err2 != nil {
   526  		t.Fatalf("Could not unmount %v", err2)
   527  	}
   528  
   529  	// mount again and see if things are okay
   530  	delete(files, "five.txt")
   531  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   532  	defer swarmfs2.Stop()
   533  }
   534  
   535  func (ta *testAPI) removeExistingFileInsideDir(t *testing.T) {
   536  	files := make(map[string]fileInfo)
   537  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "remove-upload")
   538  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "remove-mount")
   539  
   540  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   541  	files["one/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   542  	files["one/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   543  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   544  
   545  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   546  	defer swarmfs1.Stop()
   547  
   548  	// Remove a file in the root dir and check
   549  	actualPath := filepath.Join(testMountDir, "one/five.txt")
   550  	os.Remove(actualPath)
   551  
   552  	mi, err2 := swarmfs1.Unmount(testMountDir)
   553  	if err2 != nil {
   554  		t.Fatalf("Could not unmount %v", err2)
   555  	}
   556  
   557  	// mount again and see if things are okay
   558  	delete(files, "one/five.txt")
   559  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   560  	defer swarmfs2.Stop()
   561  }
   562  
   563  func (ta *testAPI) removeNewlyAddedFile(t *testing.T) {
   564  
   565  	files := make(map[string]fileInfo)
   566  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "removenew-upload")
   567  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "removenew-mount")
   568  
   569  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   570  	files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   571  	files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   572  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   573  
   574  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   575  	defer swarmfs1.Stop()
   576  
   577  	// Adda a new file and remove it
   578  	dirToCreate := filepath.Join(testMountDir, "one")
   579  	os.MkdirAll(dirToCreate, os.FileMode(0665))
   580  	actualPath := filepath.Join(dirToCreate, "2.txt")
   581  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   582  	if err1 != nil {
   583  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   584  	}
   585  	contents := make([]byte, 11)
   586  	rand.Read(contents)
   587  	d.Write(contents)
   588  	d.Close()
   589  
   590  	checkFile(t, testMountDir, "one/2.txt", contents)
   591  
   592  	os.Remove(actualPath)
   593  
   594  	mi, err2 := swarmfs1.Unmount(testMountDir)
   595  	if err2 != nil {
   596  		t.Fatalf("Could not unmount %v", err2)
   597  	}
   598  
   599  	// mount again and see if things are okay
   600  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   601  	defer swarmfs2.Stop()
   602  
   603  	if bzzHash != mi.LatestManifest {
   604  		t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest)
   605  	}
   606  }
   607  
   608  func (ta *testAPI) addNewFileAndModifyContents(t *testing.T) {
   609  	files := make(map[string]fileInfo)
   610  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-upload")
   611  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "modifyfile-mount")
   612  
   613  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   614  	files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   615  	files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   616  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   617  
   618  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   619  	defer swarmfs1.Stop()
   620  
   621  	// Create a new file in the root dir and check
   622  	actualPath := filepath.Join(testMountDir, "2.txt")
   623  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   624  	if err1 != nil {
   625  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   626  	}
   627  	line1 := []byte("Line 1")
   628  	rand.Read(line1)
   629  	d.Write(line1)
   630  	d.Close()
   631  
   632  	mi1, err2 := swarmfs1.Unmount(testMountDir)
   633  	if err2 != nil {
   634  		t.Fatalf("Could not unmount %v", err2)
   635  	}
   636  
   637  	// mount again and see if things are okay
   638  	files["2.txt"] = fileInfo{0700, 333, 444, line1}
   639  	swarmfs2 := mountDir(t, ta.api, files, mi1.LatestManifest, testMountDir)
   640  	defer swarmfs2.Stop()
   641  
   642  	checkFile(t, testMountDir, "2.txt", line1)
   643  
   644  	mi2, err3 := swarmfs2.Unmount(testMountDir)
   645  	if err3 != nil {
   646  		t.Fatalf("Could not unmount %v", err3)
   647  	}
   648  
   649  	// mount again and modify
   650  	swarmfs3 := mountDir(t, ta.api, files, mi2.LatestManifest, testMountDir)
   651  	defer swarmfs3.Stop()
   652  
   653  	fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665))
   654  	if err4 != nil {
   655  		t.Fatalf("Could not create file %s : %v", actualPath, err4)
   656  	}
   657  	line2 := []byte("Line 2")
   658  	rand.Read(line2)
   659  	fd.Seek(int64(len(line1)), 0)
   660  	fd.Write(line2)
   661  	fd.Close()
   662  
   663  	mi3, err5 := swarmfs3.Unmount(testMountDir)
   664  	if err5 != nil {
   665  		t.Fatalf("Could not unmount %v", err5)
   666  	}
   667  
   668  	// mount again and see if things are okay
   669  	b := [][]byte{line1, line2}
   670  	line1and2 := bytes.Join(b, []byte(""))
   671  	files["2.txt"] = fileInfo{0700, 333, 444, line1and2}
   672  	swarmfs4 := mountDir(t, ta.api, files, mi3.LatestManifest, testMountDir)
   673  	defer swarmfs4.Stop()
   674  
   675  	checkFile(t, testMountDir, "2.txt", line1and2)
   676  }
   677  
   678  func (ta *testAPI) removeEmptyDir(t *testing.T) {
   679  	files := make(map[string]fileInfo)
   680  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload")
   681  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount")
   682  
   683  	files["1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   684  	files["five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   685  	files["six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   686  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   687  
   688  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   689  	defer swarmfs1.Stop()
   690  
   691  	os.MkdirAll(filepath.Join(testMountDir, "newdir"), 0777)
   692  
   693  	mi, err3 := swarmfs1.Unmount(testMountDir)
   694  	if err3 != nil {
   695  		t.Fatalf("Could not unmount %v", err3)
   696  	}
   697  	if bzzHash != mi.LatestManifest {
   698  		t.Fatalf("same contents different hash orig(%v): new(%v)", bzzHash, mi.LatestManifest)
   699  	}
   700  }
   701  
   702  func (ta *testAPI) removeDirWhichHasFiles(t *testing.T) {
   703  	files := make(map[string]fileInfo)
   704  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-upload")
   705  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmdir-mount")
   706  
   707  	files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   708  	files["two/five.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   709  	files["two/six.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   710  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   711  
   712  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   713  	defer swarmfs1.Stop()
   714  
   715  	dirPath := filepath.Join(testMountDir, "two")
   716  	os.RemoveAll(dirPath)
   717  
   718  	mi, err2 := swarmfs1.Unmount(testMountDir)
   719  	if err2 != nil {
   720  		t.Fatalf("Could not unmount %v ", err2)
   721  	}
   722  
   723  	// mount again and see if things are okay
   724  	delete(files, "two/five.txt")
   725  	delete(files, "two/six.txt")
   726  
   727  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   728  	defer swarmfs2.Stop()
   729  }
   730  
   731  func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T) {
   732  	files := make(map[string]fileInfo)
   733  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-upload")
   734  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "rmsubdir-mount")
   735  
   736  	files["one/1.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   737  	files["two/three/2.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   738  	files["two/three/3.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   739  	files["two/four/5.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   740  	files["two/four/6.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   741  	files["two/four/six/7.txt"] = fileInfo{0700, 333, 444, getRandomBtes(10)}
   742  
   743  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   744  
   745  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   746  	defer swarmfs1.Stop()
   747  
   748  	dirPath := filepath.Join(testMountDir, "two")
   749  	os.RemoveAll(dirPath)
   750  
   751  	mi, err2 := swarmfs1.Unmount(testMountDir)
   752  	if err2 != nil {
   753  		t.Fatalf("Could not unmount %v ", err2)
   754  	}
   755  
   756  	// mount again and see if things are okay
   757  	delete(files, "two/three/2.txt")
   758  	delete(files, "two/three/3.txt")
   759  	delete(files, "two/four/5.txt")
   760  	delete(files, "two/four/6.txt")
   761  	delete(files, "two/four/six/7.txt")
   762  
   763  	swarmfs2 := mountDir(t, ta.api, files, mi.LatestManifest, testMountDir)
   764  	defer swarmfs2.Stop()
   765  }
   766  
   767  func (ta *testAPI) appendFileContentsToEnd(t *testing.T) {
   768  	files := make(map[string]fileInfo)
   769  	testUploadDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-upload")
   770  	testMountDir, _ := ioutil.TempDir(os.TempDir(), "appendlargefile-mount")
   771  
   772  	line1 := make([]byte, 10)
   773  	rand.Read(line1)
   774  	files["1.txt"] = fileInfo{0700, 333, 444, line1}
   775  	bzzHash := createTestFilesAndUploadToSwarm(t, ta.api, files, testUploadDir)
   776  
   777  	swarmfs1 := mountDir(t, ta.api, files, bzzHash, testMountDir)
   778  	defer swarmfs1.Stop()
   779  
   780  	actualPath := filepath.Join(testMountDir, "1.txt")
   781  	fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665))
   782  	if err4 != nil {
   783  		t.Fatalf("Could not create file %s : %v", actualPath, err4)
   784  	}
   785  	line2 := make([]byte, 5)
   786  	rand.Read(line2)
   787  	fd.Seek(int64(len(line1)), 0)
   788  	fd.Write(line2)
   789  	fd.Close()
   790  
   791  	mi1, err5 := swarmfs1.Unmount(testMountDir)
   792  	if err5 != nil {
   793  		t.Fatalf("Could not unmount %v ", err5)
   794  	}
   795  
   796  	// mount again and see if things are okay
   797  	b := [][]byte{line1, line2}
   798  	line1and2 := bytes.Join(b, []byte(""))
   799  	files["1.txt"] = fileInfo{0700, 333, 444, line1and2}
   800  	swarmfs2 := mountDir(t, ta.api, files, mi1.LatestManifest, testMountDir)
   801  	defer swarmfs2.Stop()
   802  
   803  	checkFile(t, testMountDir, "1.txt", line1and2)
   804  }
   805  
   806  func TestFUSE(t *testing.T) {
   807  	datadir, err := ioutil.TempDir("", "fuse")
   808  	if err != nil {
   809  		t.Fatalf("unable to create temp dir: %v", err)
   810  	}
   811  	os.RemoveAll(datadir)
   812  
   813  	dpa, err := storage.NewLocalDPA(datadir)
   814  	if err != nil {
   815  		t.Fatal(err)
   816  	}
   817  	//ta := &testAPI{api: api.NewApi(dpa, nil)}
   818  	dpa.Start()
   819  	defer dpa.Stop()
   820  
   821  	//t.Run("mountListAndUmount", ta.mountListAndUnmount)
   822  	//t.Run("maxMounts", ta.maxMounts)
   823  	//t.Run("remount", ta.remount)
   824  	//t.Run("unmount", ta.unmount)
   825  	//t.Run("unmountWhenResourceBusy", ta.unmountWhenResourceBusy)
   826  	//t.Run("seekInMultiChunkFile", ta.seekInMultiChunkFile)
   827  	//t.Run("createNewFile", ta.createNewFile)
   828  	//t.Run("createNewFileInsideDirectory", ta.createNewFileInsideDirectory)
   829  	//t.Run("createNewFileInsideNewDirectory", ta.createNewFileInsideNewDirectory)
   830  	//t.Run("removeExistingFile", ta.removeExistingFile)
   831  	//t.Run("removeExistingFileInsideDir", ta.removeExistingFileInsideDir)
   832  	//t.Run("removeNewlyAddedFile", ta.removeNewlyAddedFile)
   833  	//t.Run("addNewFileAndModifyContents", ta.addNewFileAndModifyContents)
   834  	//t.Run("removeEmptyDir", ta.removeEmptyDir)
   835  	//t.Run("removeDirWhichHasFiles", ta.removeDirWhichHasFiles)
   836  	//t.Run("removeDirWhichHasSubDirs", ta.removeDirWhichHasSubDirs)
   837  	//t.Run("appendFileContentsToEnd", ta.appendFileContentsToEnd)
   838  }