github.com/maynardminer/ethereumprogpow@v1.8.23/swarm/fuse/swarmfs_test.go (about)

     1  // Copyright 2018 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  	"flag"
    24  	"fmt"
    25  	"io"
    26  	"io/ioutil"
    27  	"math/rand"
    28  	"os"
    29  	"path/filepath"
    30  	"testing"
    31  
    32  	"github.com/ethereumprogpow/ethereumprogpow/log"
    33  	"github.com/ethereumprogpow/ethereumprogpow/swarm/api"
    34  	"github.com/ethereumprogpow/ethereumprogpow/swarm/storage"
    35  	"github.com/ethereumprogpow/ethereumprogpow/swarm/testutil"
    36  	colorable "github.com/mattn/go-colorable"
    37  )
    38  
    39  var (
    40  	loglevel    = flag.Int("loglevel", 4, "verbosity of logs")
    41  	rawlog      = flag.Bool("rawlog", false, "turn off terminal formatting in logs")
    42  	longrunning = flag.Bool("longrunning", false, "do run long-running tests")
    43  )
    44  
    45  func init() {
    46  	flag.Parse()
    47  	log.PrintOrigins(true)
    48  	log.Root().SetHandler(log.LvlFilterHandler(log.Lvl(*loglevel), log.StreamHandler(colorable.NewColorableStderr(), log.TerminalFormat(!*rawlog))))
    49  }
    50  
    51  type fileInfo struct {
    52  	perm     uint64
    53  	uid      int
    54  	gid      int
    55  	contents []byte
    56  }
    57  
    58  //create files from the map of name and content provided and upload them to swarm via api
    59  func createTestFilesAndUploadToSwarm(t *testing.T, api *api.API, files map[string]fileInfo, uploadDir string, toEncrypt bool) string {
    60  
    61  	//iterate the map
    62  	for fname, finfo := range files {
    63  		actualPath := filepath.Join(uploadDir, fname)
    64  		filePath := filepath.Dir(actualPath)
    65  
    66  		//create directory
    67  		err := os.MkdirAll(filePath, 0777)
    68  		if err != nil {
    69  			t.Fatalf("Error creating directory '%v' : %v", filePath, err)
    70  		}
    71  
    72  		//create file
    73  		fd, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(finfo.perm))
    74  		if err1 != nil {
    75  			t.Fatalf("Error creating file %v: %v", actualPath, err1)
    76  		}
    77  
    78  		//write content to file
    79  		_, err = fd.Write(finfo.contents)
    80  		if err != nil {
    81  			t.Fatalf("Error writing to file '%v' : %v", filePath, err)
    82  		}
    83  		/*
    84  				Note @holisticode: It's not clear why the Chown command was added to the test suite.
    85  				Some files are initialized with different permissions in the individual test,
    86  				resulting in errors on Chown which were not checked.
    87  			  After adding the checks tests would fail.
    88  
    89  				What's then the reason to have this check in the first place?
    90  				Disabling for now
    91  
    92  			  err = fd.Chown(finfo.uid, finfo.gid)
    93  			  if err != nil {
    94  			    t.Fatalf("Error chown file '%v' : %v", filePath, err)
    95  				}
    96  		*/
    97  		err = fd.Chmod(os.FileMode(finfo.perm))
    98  		if err != nil {
    99  			t.Fatalf("Error chmod file '%v' : %v", filePath, err)
   100  		}
   101  		err = fd.Sync()
   102  		if err != nil {
   103  			t.Fatalf("Error sync file '%v' : %v", filePath, err)
   104  		}
   105  		err = fd.Close()
   106  		if err != nil {
   107  			t.Fatalf("Error closing file '%v' : %v", filePath, err)
   108  		}
   109  	}
   110  
   111  	//upload directory to swarm and return hash
   112  	bzzhash, err := Upload(uploadDir, "", api, toEncrypt)
   113  	if err != nil {
   114  		t.Fatalf("Error uploading directory %v: %vm encryption: %v", uploadDir, err, toEncrypt)
   115  	}
   116  
   117  	return bzzhash
   118  }
   119  
   120  //mount a swarm hash as a directory on files system via FUSE
   121  func mountDir(t *testing.T, api *api.API, files map[string]fileInfo, bzzHash string, mountDir string) *SwarmFS {
   122  	swarmfs := NewSwarmFS(api)
   123  	_, err := swarmfs.Mount(bzzHash, mountDir)
   124  	if isFUSEUnsupportedError(err) {
   125  		t.Skip("FUSE not supported:", err)
   126  	} else if err != nil {
   127  		t.Fatalf("Error mounting hash %v: %v", bzzHash, err)
   128  	}
   129  
   130  	//check directory is mounted
   131  	found := false
   132  	mi := swarmfs.Listmounts()
   133  	for _, minfo := range mi {
   134  		minfo.lock.RLock()
   135  		if minfo.MountPoint == mountDir {
   136  			if minfo.StartManifest != bzzHash ||
   137  				minfo.LatestManifest != bzzHash ||
   138  				minfo.fuseConnection == nil {
   139  				minfo.lock.RUnlock()
   140  				t.Fatalf("Error mounting: exp(%s): act(%s)", bzzHash, minfo.StartManifest)
   141  			}
   142  			found = true
   143  		}
   144  		minfo.lock.RUnlock()
   145  	}
   146  
   147  	// Test listMounts
   148  	if !found {
   149  		t.Fatalf("Error getting mounts information for %v: %v", mountDir, err)
   150  	}
   151  
   152  	// Check if file and their attributes are as expected
   153  	compareGeneratedFileWithFileInMount(t, files, mountDir)
   154  
   155  	return swarmfs
   156  }
   157  
   158  // Check if file and their attributes are as expected
   159  func compareGeneratedFileWithFileInMount(t *testing.T, files map[string]fileInfo, mountDir string) {
   160  	err := filepath.Walk(mountDir, func(path string, f os.FileInfo, err error) error {
   161  		if f.IsDir() {
   162  			return nil
   163  		}
   164  		fname := path[len(mountDir)+1:]
   165  		if _, ok := files[fname]; !ok {
   166  			t.Fatalf(" file %v present in mount dir and is not expected", fname)
   167  		}
   168  		return nil
   169  	})
   170  	if err != nil {
   171  		t.Fatalf("Error walking dir %v", mountDir)
   172  	}
   173  
   174  	for fname, finfo := range files {
   175  		destinationFile := filepath.Join(mountDir, fname)
   176  
   177  		dfinfo, err := os.Stat(destinationFile)
   178  		if err != nil {
   179  			t.Fatalf("Destination file %v missing in mount: %v", fname, err)
   180  		}
   181  
   182  		if int64(len(finfo.contents)) != dfinfo.Size() {
   183  			t.Fatalf("file %v Size mismatch  source (%v) vs destination(%v)", fname, int64(len(finfo.contents)), dfinfo.Size())
   184  		}
   185  
   186  		if dfinfo.Mode().Perm().String() != "-rwx------" {
   187  			t.Fatalf("file %v Permission mismatch source (-rwx------) vs destination(%v)", fname, dfinfo.Mode().Perm())
   188  		}
   189  
   190  		fileContents, err := ioutil.ReadFile(filepath.Join(mountDir, fname))
   191  		if err != nil {
   192  			t.Fatalf("Could not readfile %v : %v", fname, err)
   193  		}
   194  		if !bytes.Equal(fileContents, finfo.contents) {
   195  			t.Fatalf("File %v contents mismatch: %v , %v", fname, fileContents, finfo.contents)
   196  		}
   197  		// TODO: check uid and gid
   198  	}
   199  }
   200  
   201  //check mounted file with provided content
   202  func checkFile(t *testing.T, testMountDir, fname string, contents []byte) {
   203  	destinationFile := filepath.Join(testMountDir, fname)
   204  	dfinfo, err1 := os.Stat(destinationFile)
   205  	if err1 != nil {
   206  		t.Fatalf("Could not stat file %v", destinationFile)
   207  	}
   208  	if dfinfo.Size() != int64(len(contents)) {
   209  		t.Fatalf("Mismatch in size  actual(%v) vs expected(%v)", dfinfo.Size(), int64(len(contents)))
   210  	}
   211  
   212  	fd, err2 := os.OpenFile(destinationFile, os.O_RDONLY, os.FileMode(0665))
   213  	if err2 != nil {
   214  		t.Fatalf("Could not open file %v", destinationFile)
   215  	}
   216  	newcontent := make([]byte, len(contents))
   217  	_, err := fd.Read(newcontent)
   218  	if err != nil {
   219  		t.Fatalf("Could not read from file %v", err)
   220  	}
   221  	err = fd.Close()
   222  	if err != nil {
   223  		t.Fatalf("Could not close file %v", err)
   224  	}
   225  
   226  	if !bytes.Equal(contents, newcontent) {
   227  		t.Fatalf("File content mismatch expected (%v): received (%v) ", contents, newcontent)
   228  	}
   229  }
   230  
   231  func isDirEmpty(name string) bool {
   232  	f, err := os.Open(name)
   233  	if err != nil {
   234  		return false
   235  	}
   236  	defer f.Close()
   237  
   238  	_, err = f.Readdirnames(1)
   239  
   240  	return err == io.EOF
   241  }
   242  
   243  type testAPI struct {
   244  	api *api.API
   245  }
   246  
   247  type testData struct {
   248  	testDir       string
   249  	testUploadDir string
   250  	testMountDir  string
   251  	bzzHash       string
   252  	files         map[string]fileInfo
   253  	toEncrypt     bool
   254  	swarmfs       *SwarmFS
   255  }
   256  
   257  //create the root dir of a test
   258  func (ta *testAPI) initSubtest(name string) (*testData, error) {
   259  	var err error
   260  	d := &testData{}
   261  	d.testDir, err = ioutil.TempDir(os.TempDir(), name)
   262  	if err != nil {
   263  		return nil, fmt.Errorf("Couldn't create test dir: %v", err)
   264  	}
   265  	return d, nil
   266  }
   267  
   268  //upload data and mount directory
   269  func (ta *testAPI) uploadAndMount(dat *testData, t *testing.T) (*testData, error) {
   270  	//create upload dir
   271  	err := os.MkdirAll(dat.testUploadDir, 0777)
   272  	if err != nil {
   273  		return nil, fmt.Errorf("Couldn't create upload dir: %v", err)
   274  	}
   275  	//create mount dir
   276  	err = os.MkdirAll(dat.testMountDir, 0777)
   277  	if err != nil {
   278  		return nil, fmt.Errorf("Couldn't create mount dir: %v", err)
   279  	}
   280  	//upload the file
   281  	dat.bzzHash = createTestFilesAndUploadToSwarm(t, ta.api, dat.files, dat.testUploadDir, dat.toEncrypt)
   282  	log.Debug("Created test files and uploaded to Swarm")
   283  	//mount the directory
   284  	dat.swarmfs = mountDir(t, ta.api, dat.files, dat.bzzHash, dat.testMountDir)
   285  	log.Debug("Mounted swarm fs")
   286  	return dat, nil
   287  }
   288  
   289  //add a directory to the test directory tree
   290  func addDir(root string, name string) (string, error) {
   291  	d := filepath.Join(root, name)
   292  	err := os.MkdirAll(d, 0777)
   293  	if err != nil {
   294  		return "", fmt.Errorf("Couldn't create dir inside test dir: %v", err)
   295  	}
   296  	return d, nil
   297  }
   298  
   299  func (ta *testAPI) mountListAndUnmountEncrypted(t *testing.T) {
   300  	log.Debug("Starting mountListAndUnmountEncrypted test")
   301  	ta.mountListAndUnmount(t, true)
   302  	log.Debug("Test mountListAndUnmountEncrypted terminated")
   303  }
   304  
   305  func (ta *testAPI) mountListAndUnmountNonEncrypted(t *testing.T) {
   306  	log.Debug("Starting mountListAndUnmountNonEncrypted test")
   307  	ta.mountListAndUnmount(t, false)
   308  	log.Debug("Test mountListAndUnmountNonEncrypted terminated")
   309  }
   310  
   311  //mount a directory unmount and check the directory is empty afterwards
   312  func (ta *testAPI) mountListAndUnmount(t *testing.T, toEncrypt bool) {
   313  	dat, err := ta.initSubtest("mountListAndUnmount")
   314  	if err != nil {
   315  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   316  	}
   317  	defer os.RemoveAll(dat.testDir)
   318  
   319  	dat.toEncrypt = toEncrypt
   320  	dat.testUploadDir = filepath.Join(dat.testDir, "testUploadDir")
   321  	dat.testMountDir = filepath.Join(dat.testDir, "testMountDir")
   322  	dat.files = make(map[string]fileInfo)
   323  
   324  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   325  	dat.files["2.txt"] = fileInfo{0711, 333, 444, testutil.RandomBytes(2, 10)}
   326  	dat.files["3.txt"] = fileInfo{0622, 333, 444, testutil.RandomBytes(3, 100)}
   327  	dat.files["4.txt"] = fileInfo{0533, 333, 444, testutil.RandomBytes(4, 1024)}
   328  	dat.files["5.txt"] = fileInfo{0544, 333, 444, testutil.RandomBytes(5, 10)}
   329  	dat.files["6.txt"] = fileInfo{0555, 333, 444, testutil.RandomBytes(6, 10)}
   330  	dat.files["7.txt"] = fileInfo{0666, 333, 444, testutil.RandomBytes(7, 10)}
   331  	dat.files["8.txt"] = fileInfo{0777, 333, 333, testutil.RandomBytes(8, 10)}
   332  	dat.files["11.txt"] = fileInfo{0777, 333, 444, testutil.RandomBytes(9, 10)}
   333  	dat.files["111.txt"] = fileInfo{0777, 333, 444, testutil.RandomBytes(10, 10)}
   334  	dat.files["two/2.txt"] = fileInfo{0777, 333, 444, testutil.RandomBytes(11, 10)}
   335  	dat.files["two/2/2.txt"] = fileInfo{0777, 333, 444, testutil.RandomBytes(12, 10)}
   336  	dat.files["two/2./2.txt"] = fileInfo{0777, 444, 444, testutil.RandomBytes(13, 10)}
   337  	dat.files["twice/2.txt"] = fileInfo{0777, 444, 333, testutil.RandomBytes(14, 200)}
   338  	dat.files["one/two/three/four/five/six/seven/eight/nine/10.txt"] = fileInfo{0777, 333, 444, testutil.RandomBytes(15, 10240)}
   339  	dat.files["one/two/three/four/five/six/six"] = fileInfo{0777, 333, 444, testutil.RandomBytes(16, 10)}
   340  
   341  	dat, err = ta.uploadAndMount(dat, t)
   342  	if err != nil {
   343  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   344  	}
   345  	defer dat.swarmfs.Stop()
   346  	// Check unmount
   347  	_, err = dat.swarmfs.Unmount(dat.testMountDir)
   348  	if err != nil {
   349  		t.Fatalf("could not unmount  %v", dat.bzzHash)
   350  	}
   351  	log.Debug("Unmount successful")
   352  	if !isDirEmpty(dat.testMountDir) {
   353  		t.Fatalf("unmount didnt work for %v", dat.testMountDir)
   354  	}
   355  	log.Debug("subtest terminated")
   356  }
   357  
   358  func (ta *testAPI) maxMountsEncrypted(t *testing.T) {
   359  	log.Debug("Starting maxMountsEncrypted test")
   360  	ta.runMaxMounts(t, true)
   361  	log.Debug("Test maxMountsEncrypted terminated")
   362  }
   363  
   364  func (ta *testAPI) maxMountsNonEncrypted(t *testing.T) {
   365  	log.Debug("Starting maxMountsNonEncrypted test")
   366  	ta.runMaxMounts(t, false)
   367  	log.Debug("Test maxMountsNonEncrypted terminated")
   368  }
   369  
   370  //mount several different directories until the maximum has been reached
   371  func (ta *testAPI) runMaxMounts(t *testing.T, toEncrypt bool) {
   372  	dat, err := ta.initSubtest("runMaxMounts")
   373  	if err != nil {
   374  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   375  	}
   376  	defer os.RemoveAll(dat.testDir)
   377  
   378  	dat.toEncrypt = toEncrypt
   379  	dat.testUploadDir = filepath.Join(dat.testDir, "max-upload1")
   380  	dat.testMountDir = filepath.Join(dat.testDir, "max-mount1")
   381  	dat.files = make(map[string]fileInfo)
   382  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   383  
   384  	dat, err = ta.uploadAndMount(dat, t)
   385  	if err != nil {
   386  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   387  	}
   388  	defer dat.swarmfs.Stop()
   389  
   390  	dat.testUploadDir = filepath.Join(dat.testDir, "max-upload2")
   391  	dat.testMountDir = filepath.Join(dat.testDir, "max-mount2")
   392  	dat.files["2.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   393  
   394  	dat, err = ta.uploadAndMount(dat, t)
   395  	if err != nil {
   396  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   397  	}
   398  
   399  	dat.testUploadDir = filepath.Join(dat.testDir, "max-upload3")
   400  	dat.testMountDir = filepath.Join(dat.testDir, "max-mount3")
   401  	dat.files["3.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   402  
   403  	dat, err = ta.uploadAndMount(dat, t)
   404  	if err != nil {
   405  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   406  	}
   407  
   408  	dat.testUploadDir = filepath.Join(dat.testDir, "max-upload4")
   409  	dat.testMountDir = filepath.Join(dat.testDir, "max-mount4")
   410  	dat.files["4.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   411  
   412  	dat, err = ta.uploadAndMount(dat, t)
   413  	if err != nil {
   414  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   415  	}
   416  
   417  	dat.testUploadDir = filepath.Join(dat.testDir, "max-upload5")
   418  	dat.testMountDir = filepath.Join(dat.testDir, "max-mount5")
   419  	dat.files["5.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   420  
   421  	dat, err = ta.uploadAndMount(dat, t)
   422  	if err != nil {
   423  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   424  	}
   425  
   426  	//now try an additional mount, should fail due to max mounts reached
   427  	testUploadDir6 := filepath.Join(dat.testDir, "max-upload6")
   428  	err = os.MkdirAll(testUploadDir6, 0777)
   429  	if err != nil {
   430  		t.Fatalf("Couldn't create upload dir 6: %v", err)
   431  	}
   432  	dat.files["6.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   433  	testMountDir6 := filepath.Join(dat.testDir, "max-mount6")
   434  	err = os.MkdirAll(testMountDir6, 0777)
   435  	if err != nil {
   436  		t.Fatalf("Couldn't create mount dir 5: %v", err)
   437  	}
   438  	bzzHash6 := createTestFilesAndUploadToSwarm(t, ta.api, dat.files, testUploadDir6, toEncrypt)
   439  	log.Debug("Created test files and uploaded to swarm with uploadDir6")
   440  	_, err = dat.swarmfs.Mount(bzzHash6, testMountDir6)
   441  	if err == nil {
   442  		t.Fatalf("Expected this mount to fail due to exceeding max number of allowed mounts, but succeeded. %v", bzzHash6)
   443  	}
   444  	log.Debug("Maximum mount reached, additional mount failed. Correct.")
   445  }
   446  
   447  func (ta *testAPI) remountEncrypted(t *testing.T) {
   448  	log.Debug("Starting remountEncrypted test")
   449  	ta.remount(t, true)
   450  	log.Debug("Test remountEncrypted terminated")
   451  }
   452  func (ta *testAPI) remountNonEncrypted(t *testing.T) {
   453  	log.Debug("Starting remountNonEncrypted test")
   454  	ta.remount(t, false)
   455  	log.Debug("Test remountNonEncrypted terminated")
   456  }
   457  
   458  //test remounting same hash second time and different hash in already mounted point
   459  func (ta *testAPI) remount(t *testing.T, toEncrypt bool) {
   460  	dat, err := ta.initSubtest("remount")
   461  	if err != nil {
   462  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   463  	}
   464  	defer os.RemoveAll(dat.testDir)
   465  
   466  	dat.toEncrypt = toEncrypt
   467  	dat.testUploadDir = filepath.Join(dat.testDir, "remount-upload1")
   468  	dat.testMountDir = filepath.Join(dat.testDir, "remount-mount1")
   469  	dat.files = make(map[string]fileInfo)
   470  
   471  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   472  
   473  	dat, err = ta.uploadAndMount(dat, t)
   474  	if err != nil {
   475  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   476  	}
   477  	defer dat.swarmfs.Stop()
   478  
   479  	// try mounting the same hash second time
   480  	testMountDir2, err2 := addDir(dat.testDir, "remount-mount2")
   481  	if err2 != nil {
   482  		t.Fatalf("Error creating second mount dir: %v", err2)
   483  	}
   484  	_, err2 = dat.swarmfs.Mount(dat.bzzHash, testMountDir2)
   485  	if err2 != nil {
   486  		t.Fatalf("Error mounting hash second time on different dir  %v", dat.bzzHash)
   487  	}
   488  
   489  	// mount a different hash in already mounted point
   490  	dat.files["2.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   491  	testUploadDir2, err3 := addDir(dat.testDir, "remount-upload2")
   492  	if err3 != nil {
   493  		t.Fatalf("Error creating second upload dir: %v", err3)
   494  	}
   495  	bzzHash2 := createTestFilesAndUploadToSwarm(t, ta.api, dat.files, testUploadDir2, toEncrypt)
   496  	_, err = swarmfs.Mount(bzzHash2, dat.testMountDir)
   497  	if err == nil {
   498  		t.Fatalf("Error mounting hash  %v", bzzHash2)
   499  	}
   500  	log.Debug("Mount on existing mount point failed. Correct.")
   501  
   502  	// mount nonexistent hash
   503  	failDir, err3 := addDir(dat.testDir, "remount-fail")
   504  	if err3 != nil {
   505  		t.Fatalf("Error creating remount dir: %v", bzzHash2)
   506  	}
   507  	failHash := "0xfea11223344"
   508  	_, err = swarmfs.Mount(failHash, failDir)
   509  	if err == nil {
   510  		t.Fatalf("Expected this mount to fail due to non existing hash. But succeeded %v", failHash)
   511  	}
   512  	log.Debug("Nonexistent hash hasn't been mounted. Correct.")
   513  }
   514  
   515  func (ta *testAPI) unmountEncrypted(t *testing.T) {
   516  	log.Debug("Starting unmountEncrypted test")
   517  	ta.unmount(t, true)
   518  	log.Debug("Test unmountEncrypted terminated")
   519  }
   520  
   521  func (ta *testAPI) unmountNonEncrypted(t *testing.T) {
   522  	log.Debug("Starting unmountNonEncrypted test")
   523  	ta.unmount(t, false)
   524  	log.Debug("Test unmountNonEncrypted terminated")
   525  }
   526  
   527  //mount then unmount and check that it has been unmounted
   528  func (ta *testAPI) unmount(t *testing.T, toEncrypt bool) {
   529  	dat, err := ta.initSubtest("unmount")
   530  	if err != nil {
   531  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   532  	}
   533  	defer os.RemoveAll(dat.testDir)
   534  
   535  	dat.toEncrypt = toEncrypt
   536  	dat.testUploadDir = filepath.Join(dat.testDir, "ex-upload1")
   537  	dat.testMountDir = filepath.Join(dat.testDir, "ex-mount1")
   538  	dat.files = make(map[string]fileInfo)
   539  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   540  
   541  	dat, err = ta.uploadAndMount(dat, t)
   542  	if err != nil {
   543  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   544  	}
   545  	defer dat.swarmfs.Stop()
   546  
   547  	_, err = dat.swarmfs.Unmount(dat.testMountDir)
   548  	if err != nil {
   549  		t.Fatalf("could not unmount  %v", dat.bzzHash)
   550  	}
   551  	log.Debug("Unmounted Dir")
   552  
   553  	mi := swarmfs.Listmounts()
   554  	log.Debug("Going to list mounts")
   555  	for _, minfo := range mi {
   556  		log.Debug("Mount point in list: ", "point", minfo.MountPoint)
   557  		if minfo.MountPoint == dat.testMountDir {
   558  			t.Fatalf("mount state not cleaned up in unmount case %v", dat.testMountDir)
   559  		}
   560  	}
   561  	log.Debug("subtest terminated")
   562  }
   563  
   564  func (ta *testAPI) unmountWhenResourceBusyEncrypted(t *testing.T) {
   565  	log.Debug("Starting unmountWhenResourceBusyEncrypted test")
   566  	ta.unmountWhenResourceBusy(t, true)
   567  	log.Debug("Test unmountWhenResourceBusyEncrypted terminated")
   568  }
   569  func (ta *testAPI) unmountWhenResourceBusyNonEncrypted(t *testing.T) {
   570  	log.Debug("Starting unmountWhenResourceBusyNonEncrypted test")
   571  	ta.unmountWhenResourceBusy(t, false)
   572  	log.Debug("Test unmountWhenResourceBusyNonEncrypted terminated")
   573  }
   574  
   575  //unmount while a resource is busy; should fail
   576  func (ta *testAPI) unmountWhenResourceBusy(t *testing.T, toEncrypt bool) {
   577  	dat, err := ta.initSubtest("unmountWhenResourceBusy")
   578  	if err != nil {
   579  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   580  	}
   581  	defer os.RemoveAll(dat.testDir)
   582  
   583  	dat.toEncrypt = toEncrypt
   584  	dat.testUploadDir = filepath.Join(dat.testDir, "ex-upload1")
   585  	dat.testMountDir = filepath.Join(dat.testDir, "ex-mount1")
   586  	dat.files = make(map[string]fileInfo)
   587  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   588  
   589  	dat, err = ta.uploadAndMount(dat, t)
   590  	if err != nil {
   591  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   592  	}
   593  	defer dat.swarmfs.Stop()
   594  
   595  	//create a file in the mounted directory, then try to unmount - should fail
   596  	actualPath := filepath.Join(dat.testMountDir, "2.txt")
   597  	//d, err := os.OpenFile(actualPath, os.O_RDWR, os.FileMode(0700))
   598  	d, err := os.Create(actualPath)
   599  	if err != nil {
   600  		t.Fatalf("Couldn't create new file: %v", err)
   601  	}
   602  	//we need to manually close the file before mount for this test
   603  	//but let's defer too in case of errors
   604  	defer d.Close()
   605  	_, err = d.Write(testutil.RandomBytes(1, 10))
   606  	if err != nil {
   607  		t.Fatalf("Couldn't write to file: %v", err)
   608  	}
   609  	log.Debug("Bytes written")
   610  
   611  	_, err = dat.swarmfs.Unmount(dat.testMountDir)
   612  	if err == nil {
   613  		t.Fatalf("Expected mount to fail due to resource busy, but it succeeded...")
   614  	}
   615  	//free resources
   616  	err = d.Close()
   617  	if err != nil {
   618  		t.Fatalf("Couldn't close file!  %v", dat.bzzHash)
   619  	}
   620  	log.Debug("File closed")
   621  
   622  	//now unmount after explicitly closed file
   623  	_, err = dat.swarmfs.Unmount(dat.testMountDir)
   624  	if err != nil {
   625  		t.Fatalf("Expected mount to succeed after freeing resource, but it failed: %v", err)
   626  	}
   627  	//check if the dir is still mounted
   628  	mi := dat.swarmfs.Listmounts()
   629  	log.Debug("Going to list mounts")
   630  	for _, minfo := range mi {
   631  		log.Debug("Mount point in list: ", "point", minfo.MountPoint)
   632  		if minfo.MountPoint == dat.testMountDir {
   633  			t.Fatalf("mount state not cleaned up in unmount case %v", dat.testMountDir)
   634  		}
   635  	}
   636  	log.Debug("subtest terminated")
   637  }
   638  
   639  func (ta *testAPI) seekInMultiChunkFileEncrypted(t *testing.T) {
   640  	log.Debug("Starting seekInMultiChunkFileEncrypted test")
   641  	ta.seekInMultiChunkFile(t, true)
   642  	log.Debug("Test seekInMultiChunkFileEncrypted terminated")
   643  }
   644  
   645  func (ta *testAPI) seekInMultiChunkFileNonEncrypted(t *testing.T) {
   646  	log.Debug("Starting seekInMultiChunkFileNonEncrypted test")
   647  	ta.seekInMultiChunkFile(t, false)
   648  	log.Debug("Test seekInMultiChunkFileNonEncrypted terminated")
   649  }
   650  
   651  //open a file in a mounted dir and go to a certain position
   652  func (ta *testAPI) seekInMultiChunkFile(t *testing.T, toEncrypt bool) {
   653  	dat, err := ta.initSubtest("seekInMultiChunkFile")
   654  	if err != nil {
   655  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   656  	}
   657  	defer os.RemoveAll(dat.testDir)
   658  
   659  	dat.toEncrypt = toEncrypt
   660  	dat.testUploadDir = filepath.Join(dat.testDir, "seek-upload1")
   661  	dat.testMountDir = filepath.Join(dat.testDir, "seek-mount")
   662  	dat.files = make(map[string]fileInfo)
   663  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10240)}
   664  
   665  	dat, err = ta.uploadAndMount(dat, t)
   666  	if err != nil {
   667  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   668  	}
   669  	defer dat.swarmfs.Stop()
   670  
   671  	// Open the file in the mounted dir and seek the second chunk
   672  	actualPath := filepath.Join(dat.testMountDir, "1.txt")
   673  	d, err := os.OpenFile(actualPath, os.O_RDONLY, os.FileMode(0700))
   674  	if err != nil {
   675  		t.Fatalf("Couldn't open file: %v", err)
   676  	}
   677  	log.Debug("Opened file")
   678  	defer func() {
   679  		err := d.Close()
   680  		if err != nil {
   681  			t.Fatalf("Error closing file! %v", err)
   682  		}
   683  	}()
   684  
   685  	_, err = d.Seek(5000, 0)
   686  	if err != nil {
   687  		t.Fatalf("Error seeking in file: %v", err)
   688  	}
   689  
   690  	contents := make([]byte, 1024)
   691  	_, err = d.Read(contents)
   692  	if err != nil {
   693  		t.Fatalf("Error reading file: %v", err)
   694  	}
   695  	log.Debug("Read contents")
   696  	finfo := dat.files["1.txt"]
   697  
   698  	if !bytes.Equal(finfo.contents[:6024][5000:], contents) {
   699  		t.Fatalf("File seek contents mismatch")
   700  	}
   701  	log.Debug("subtest terminated")
   702  }
   703  
   704  func (ta *testAPI) createNewFileEncrypted(t *testing.T) {
   705  	log.Debug("Starting createNewFileEncrypted test")
   706  	ta.createNewFile(t, true)
   707  	log.Debug("Test createNewFileEncrypted terminated")
   708  }
   709  
   710  func (ta *testAPI) createNewFileNonEncrypted(t *testing.T) {
   711  	log.Debug("Starting createNewFileNonEncrypted test")
   712  	ta.createNewFile(t, false)
   713  	log.Debug("Test createNewFileNonEncrypted terminated")
   714  }
   715  
   716  //create a new file in a mounted swarm directory,
   717  //unmount the fuse dir and then remount to see if new file is still there
   718  func (ta *testAPI) createNewFile(t *testing.T, toEncrypt bool) {
   719  	dat, err := ta.initSubtest("createNewFile")
   720  	if err != nil {
   721  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   722  	}
   723  	defer os.RemoveAll(dat.testDir)
   724  
   725  	dat.toEncrypt = toEncrypt
   726  	dat.testUploadDir = filepath.Join(dat.testDir, "create-upload1")
   727  	dat.testMountDir = filepath.Join(dat.testDir, "create-mount")
   728  	dat.files = make(map[string]fileInfo)
   729  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   730  	dat.files["five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
   731  	dat.files["six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
   732  
   733  	dat, err = ta.uploadAndMount(dat, t)
   734  	if err != nil {
   735  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   736  	}
   737  	defer dat.swarmfs.Stop()
   738  
   739  	// Create a new file in the root dir and check
   740  	actualPath := filepath.Join(dat.testMountDir, "2.txt")
   741  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   742  	if err1 != nil {
   743  		t.Fatalf("Could not open file %s : %v", actualPath, err1)
   744  	}
   745  	defer d.Close()
   746  	log.Debug("Opened file")
   747  	contents := testutil.RandomBytes(1, 11)
   748  	log.Debug("content read")
   749  	_, err = d.Write(contents)
   750  	if err != nil {
   751  		t.Fatalf("Couldn't write contents: %v", err)
   752  	}
   753  	log.Debug("content written")
   754  	err = d.Close()
   755  	if err != nil {
   756  		t.Fatalf("Couldn't close file: %v", err)
   757  	}
   758  	log.Debug("file closed")
   759  
   760  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
   761  	if err2 != nil {
   762  		t.Fatalf("Could not unmount %v", err2)
   763  	}
   764  	log.Debug("Directory unmounted")
   765  
   766  	testMountDir2, err3 := addDir(dat.testDir, "create-mount2")
   767  	if err3 != nil {
   768  		t.Fatalf("Error creating mount dir2: %v", err3)
   769  	}
   770  	// mount again and see if things are okay
   771  	dat.files["2.txt"] = fileInfo{0700, 333, 444, contents}
   772  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2)
   773  	log.Debug("Directory mounted again")
   774  
   775  	checkFile(t, testMountDir2, "2.txt", contents)
   776  	_, err2 = dat.swarmfs.Unmount(testMountDir2)
   777  	if err2 != nil {
   778  		t.Fatalf("Could not unmount %v", err2)
   779  	}
   780  	log.Debug("subtest terminated")
   781  }
   782  
   783  func (ta *testAPI) createNewFileInsideDirectoryEncrypted(t *testing.T) {
   784  	log.Debug("Starting createNewFileInsideDirectoryEncrypted test")
   785  	ta.createNewFileInsideDirectory(t, true)
   786  	log.Debug("Test createNewFileInsideDirectoryEncrypted terminated")
   787  }
   788  
   789  func (ta *testAPI) createNewFileInsideDirectoryNonEncrypted(t *testing.T) {
   790  	log.Debug("Starting createNewFileInsideDirectoryNonEncrypted test")
   791  	ta.createNewFileInsideDirectory(t, false)
   792  	log.Debug("Test createNewFileInsideDirectoryNonEncrypted terminated")
   793  }
   794  
   795  //create a new file inside a directory inside the mount
   796  func (ta *testAPI) createNewFileInsideDirectory(t *testing.T, toEncrypt bool) {
   797  	dat, err := ta.initSubtest("createNewFileInsideDirectory")
   798  	if err != nil {
   799  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   800  	}
   801  	defer os.RemoveAll(dat.testDir)
   802  
   803  	dat.toEncrypt = toEncrypt
   804  	dat.testUploadDir = filepath.Join(dat.testDir, "createinsidedir-upload")
   805  	dat.testMountDir = filepath.Join(dat.testDir, "createinsidedir-mount")
   806  	dat.files = make(map[string]fileInfo)
   807  	dat.files["one/1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   808  
   809  	dat, err = ta.uploadAndMount(dat, t)
   810  	if err != nil {
   811  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   812  	}
   813  	defer dat.swarmfs.Stop()
   814  
   815  	// Create a new file inside a existing dir and check
   816  	dirToCreate := filepath.Join(dat.testMountDir, "one")
   817  	actualPath := filepath.Join(dirToCreate, "2.txt")
   818  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   819  	if err1 != nil {
   820  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   821  	}
   822  	defer d.Close()
   823  	log.Debug("File opened")
   824  	contents := testutil.RandomBytes(1, 11)
   825  	log.Debug("Content read")
   826  	_, err = d.Write(contents)
   827  	if err != nil {
   828  		t.Fatalf("Error writing random bytes into file %v", err)
   829  	}
   830  	log.Debug("Content written")
   831  	err = d.Close()
   832  	if err != nil {
   833  		t.Fatalf("Error closing file %v", err)
   834  	}
   835  	log.Debug("File closed")
   836  
   837  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
   838  	if err2 != nil {
   839  		t.Fatalf("Could not unmount %v", err2)
   840  	}
   841  	log.Debug("Directory unmounted")
   842  
   843  	testMountDir2, err3 := addDir(dat.testDir, "createinsidedir-mount2")
   844  	if err3 != nil {
   845  		t.Fatalf("Error creating mount dir2: %v", err3)
   846  	}
   847  	// mount again and see if things are okay
   848  	dat.files["one/2.txt"] = fileInfo{0700, 333, 444, contents}
   849  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2)
   850  	log.Debug("Directory mounted again")
   851  
   852  	checkFile(t, testMountDir2, "one/2.txt", contents)
   853  	_, err = dat.swarmfs.Unmount(testMountDir2)
   854  	if err != nil {
   855  		t.Fatalf("could not unmount  %v", dat.bzzHash)
   856  	}
   857  	log.Debug("subtest terminated")
   858  }
   859  
   860  func (ta *testAPI) createNewFileInsideNewDirectoryEncrypted(t *testing.T) {
   861  	log.Debug("Starting createNewFileInsideNewDirectoryEncrypted test")
   862  	ta.createNewFileInsideNewDirectory(t, true)
   863  	log.Debug("Test createNewFileInsideNewDirectoryEncrypted terminated")
   864  }
   865  
   866  func (ta *testAPI) createNewFileInsideNewDirectoryNonEncrypted(t *testing.T) {
   867  	log.Debug("Starting createNewFileInsideNewDirectoryNonEncrypted test")
   868  	ta.createNewFileInsideNewDirectory(t, false)
   869  	log.Debug("Test createNewFileInsideNewDirectoryNonEncrypted terminated")
   870  }
   871  
   872  //create a new directory in mount and a new file
   873  func (ta *testAPI) createNewFileInsideNewDirectory(t *testing.T, toEncrypt bool) {
   874  	dat, err := ta.initSubtest("createNewFileInsideNewDirectory")
   875  	if err != nil {
   876  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   877  	}
   878  	defer os.RemoveAll(dat.testDir)
   879  
   880  	dat.toEncrypt = toEncrypt
   881  	dat.testUploadDir = filepath.Join(dat.testDir, "createinsidenewdir-upload")
   882  	dat.testMountDir = filepath.Join(dat.testDir, "createinsidenewdir-mount")
   883  	dat.files = make(map[string]fileInfo)
   884  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   885  
   886  	dat, err = ta.uploadAndMount(dat, t)
   887  	if err != nil {
   888  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   889  	}
   890  	defer dat.swarmfs.Stop()
   891  
   892  	// Create a new file inside a existing dir and check
   893  	dirToCreate, err2 := addDir(dat.testMountDir, "one")
   894  	if err2 != nil {
   895  		t.Fatalf("Error creating mount dir2: %v", err2)
   896  	}
   897  	actualPath := filepath.Join(dirToCreate, "2.txt")
   898  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
   899  	if err1 != nil {
   900  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
   901  	}
   902  	defer d.Close()
   903  	log.Debug("File opened")
   904  	contents := testutil.RandomBytes(1, 11)
   905  	log.Debug("content read")
   906  	_, err = d.Write(contents)
   907  	if err != nil {
   908  		t.Fatalf("Error writing to file: %v", err)
   909  	}
   910  	log.Debug("content written")
   911  	err = d.Close()
   912  	if err != nil {
   913  		t.Fatalf("Error closing file: %v", err)
   914  	}
   915  	log.Debug("File closed")
   916  
   917  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
   918  	if err2 != nil {
   919  		t.Fatalf("Could not unmount %v", err2)
   920  	}
   921  	log.Debug("Directory unmounted")
   922  
   923  	// mount again and see if things are okay
   924  	dat.files["one/2.txt"] = fileInfo{0700, 333, 444, contents}
   925  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir)
   926  	log.Debug("Directory mounted again")
   927  
   928  	checkFile(t, dat.testMountDir, "one/2.txt", contents)
   929  	_, err2 = dat.swarmfs.Unmount(dat.testMountDir)
   930  	if err2 != nil {
   931  		t.Fatalf("Could not unmount %v", err2)
   932  	}
   933  	log.Debug("subtest terminated")
   934  }
   935  
   936  func (ta *testAPI) removeExistingFileEncrypted(t *testing.T) {
   937  	log.Debug("Starting removeExistingFileEncrypted test")
   938  	ta.removeExistingFile(t, true)
   939  	log.Debug("Test removeExistingFileEncrypted terminated")
   940  }
   941  
   942  func (ta *testAPI) removeExistingFileNonEncrypted(t *testing.T) {
   943  	log.Debug("Starting removeExistingFileNonEncrypted test")
   944  	ta.removeExistingFile(t, false)
   945  	log.Debug("Test removeExistingFileNonEncrypted terminated")
   946  }
   947  
   948  //remove existing file in mount
   949  func (ta *testAPI) removeExistingFile(t *testing.T, toEncrypt bool) {
   950  	dat, err := ta.initSubtest("removeExistingFile")
   951  	if err != nil {
   952  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
   953  	}
   954  	defer os.RemoveAll(dat.testDir)
   955  
   956  	dat.toEncrypt = toEncrypt
   957  	dat.testUploadDir = filepath.Join(dat.testDir, "remove-upload")
   958  	dat.testMountDir = filepath.Join(dat.testDir, "remove-mount")
   959  	dat.files = make(map[string]fileInfo)
   960  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
   961  	dat.files["five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
   962  	dat.files["six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
   963  
   964  	dat, err = ta.uploadAndMount(dat, t)
   965  	if err != nil {
   966  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
   967  	}
   968  	defer dat.swarmfs.Stop()
   969  
   970  	// Remove a file in the root dir and check
   971  	actualPath := filepath.Join(dat.testMountDir, "five.txt")
   972  	err = os.Remove(actualPath)
   973  	if err != nil {
   974  		t.Fatalf("Error removing file! %v", err)
   975  	}
   976  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
   977  	if err2 != nil {
   978  		t.Fatalf("Could not unmount %v", err2)
   979  	}
   980  	log.Debug("Directory unmounted")
   981  
   982  	// mount again and see if things are okay
   983  	delete(dat.files, "five.txt")
   984  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir)
   985  	_, err = os.Stat(actualPath)
   986  	if err == nil {
   987  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
   988  	}
   989  	_, err2 = dat.swarmfs.Unmount(dat.testMountDir)
   990  	if err2 != nil {
   991  		t.Fatalf("Could not unmount %v", err2)
   992  	}
   993  	log.Debug("subtest terminated")
   994  }
   995  
   996  func (ta *testAPI) removeExistingFileInsideDirEncrypted(t *testing.T) {
   997  	log.Debug("Starting removeExistingFileInsideDirEncrypted test")
   998  	ta.removeExistingFileInsideDir(t, true)
   999  	log.Debug("Test removeExistingFileInsideDirEncrypted terminated")
  1000  }
  1001  
  1002  func (ta *testAPI) removeExistingFileInsideDirNonEncrypted(t *testing.T) {
  1003  	log.Debug("Starting removeExistingFileInsideDirNonEncrypted test")
  1004  	ta.removeExistingFileInsideDir(t, false)
  1005  	log.Debug("Test removeExistingFileInsideDirNonEncrypted terminated")
  1006  }
  1007  
  1008  //remove a file inside a directory inside a mount
  1009  func (ta *testAPI) removeExistingFileInsideDir(t *testing.T, toEncrypt bool) {
  1010  	dat, err := ta.initSubtest("removeExistingFileInsideDir")
  1011  	if err != nil {
  1012  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1013  	}
  1014  	defer os.RemoveAll(dat.testDir)
  1015  
  1016  	dat.toEncrypt = toEncrypt
  1017  	dat.testUploadDir = filepath.Join(dat.testDir, "remove-upload")
  1018  	dat.testMountDir = filepath.Join(dat.testDir, "remove-mount")
  1019  	dat.files = make(map[string]fileInfo)
  1020  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1021  	dat.files["one/five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1022  	dat.files["one/six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1023  
  1024  	dat, err = ta.uploadAndMount(dat, t)
  1025  	if err != nil {
  1026  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1027  	}
  1028  	defer dat.swarmfs.Stop()
  1029  
  1030  	// Remove a file in the root dir and check
  1031  	actualPath := filepath.Join(dat.testMountDir, "one")
  1032  	actualPath = filepath.Join(actualPath, "five.txt")
  1033  	err = os.Remove(actualPath)
  1034  	if err != nil {
  1035  		t.Fatalf("Error removing file! %v", err)
  1036  	}
  1037  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
  1038  	if err2 != nil {
  1039  		t.Fatalf("Could not unmount %v", err2)
  1040  	}
  1041  	log.Debug("Directory unmounted")
  1042  
  1043  	// mount again and see if things are okay
  1044  	delete(dat.files, "one/five.txt")
  1045  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, dat.testMountDir)
  1046  	_, err = os.Stat(actualPath)
  1047  	if err == nil {
  1048  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1049  	}
  1050  
  1051  	okPath := filepath.Join(dat.testMountDir, "one")
  1052  	okPath = filepath.Join(okPath, "six.txt")
  1053  	_, err = os.Stat(okPath)
  1054  	if err != nil {
  1055  		t.Fatal("Expected file to be present in re-mount after removal, but it is not there")
  1056  	}
  1057  	_, err2 = dat.swarmfs.Unmount(dat.testMountDir)
  1058  	if err2 != nil {
  1059  		t.Fatalf("Could not unmount %v", err2)
  1060  	}
  1061  	log.Debug("subtest terminated")
  1062  }
  1063  
  1064  func (ta *testAPI) removeNewlyAddedFileEncrypted(t *testing.T) {
  1065  	log.Debug("Starting removeNewlyAddedFileEncrypted test")
  1066  	ta.removeNewlyAddedFile(t, true)
  1067  	log.Debug("Test removeNewlyAddedFileEncrypted terminated")
  1068  }
  1069  
  1070  func (ta *testAPI) removeNewlyAddedFileNonEncrypted(t *testing.T) {
  1071  	log.Debug("Starting removeNewlyAddedFileNonEncrypted test")
  1072  	ta.removeNewlyAddedFile(t, false)
  1073  	log.Debug("Test removeNewlyAddedFileNonEncrypted terminated")
  1074  }
  1075  
  1076  //add a file in mount and then remove it; on remount file should not be there
  1077  func (ta *testAPI) removeNewlyAddedFile(t *testing.T, toEncrypt bool) {
  1078  	dat, err := ta.initSubtest("removeNewlyAddedFile")
  1079  	if err != nil {
  1080  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1081  	}
  1082  	defer os.RemoveAll(dat.testDir)
  1083  
  1084  	dat.toEncrypt = toEncrypt
  1085  	dat.testUploadDir = filepath.Join(dat.testDir, "removenew-upload")
  1086  	dat.testMountDir = filepath.Join(dat.testDir, "removenew-mount")
  1087  	dat.files = make(map[string]fileInfo)
  1088  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1089  	dat.files["five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1090  	dat.files["six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1091  
  1092  	dat, err = ta.uploadAndMount(dat, t)
  1093  	if err != nil {
  1094  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1095  	}
  1096  	defer dat.swarmfs.Stop()
  1097  
  1098  	// Add a a new file and remove it
  1099  	dirToCreate := filepath.Join(dat.testMountDir, "one")
  1100  	err = os.MkdirAll(dirToCreate, os.FileMode(0665))
  1101  	if err != nil {
  1102  		t.Fatalf("Error creating dir in mounted dir: %v", err)
  1103  	}
  1104  	actualPath := filepath.Join(dirToCreate, "2.txt")
  1105  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
  1106  	if err1 != nil {
  1107  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
  1108  	}
  1109  	defer d.Close()
  1110  	log.Debug("file opened")
  1111  	contents := testutil.RandomBytes(1, 11)
  1112  	log.Debug("content read")
  1113  	_, err = d.Write(contents)
  1114  	if err != nil {
  1115  		t.Fatalf("Error writing random bytes to file: %v", err)
  1116  	}
  1117  	log.Debug("content written")
  1118  	err = d.Close()
  1119  	if err != nil {
  1120  		t.Fatalf("Error closing file: %v", err)
  1121  	}
  1122  	log.Debug("file closed")
  1123  
  1124  	checkFile(t, dat.testMountDir, "one/2.txt", contents)
  1125  	log.Debug("file checked")
  1126  
  1127  	err = os.Remove(actualPath)
  1128  	if err != nil {
  1129  		t.Fatalf("Error removing file: %v", err)
  1130  	}
  1131  	log.Debug("file removed")
  1132  
  1133  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
  1134  	if err2 != nil {
  1135  		t.Fatalf("Could not unmount %v", err2)
  1136  	}
  1137  	log.Debug("Directory unmounted")
  1138  
  1139  	testMountDir2, err3 := addDir(dat.testDir, "removenew-mount2")
  1140  	if err3 != nil {
  1141  		t.Fatalf("Error creating mount dir2: %v", err3)
  1142  	}
  1143  	// mount again and see if things are okay
  1144  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2)
  1145  	log.Debug("Directory mounted again")
  1146  
  1147  	if dat.bzzHash != mi.LatestManifest {
  1148  		t.Fatalf("same contents different hash orig(%v): new(%v)", dat.bzzHash, mi.LatestManifest)
  1149  	}
  1150  	_, err2 = dat.swarmfs.Unmount(testMountDir2)
  1151  	if err2 != nil {
  1152  		t.Fatalf("Could not unmount %v", err2)
  1153  	}
  1154  	log.Debug("subtest terminated")
  1155  }
  1156  
  1157  func (ta *testAPI) addNewFileAndModifyContentsEncrypted(t *testing.T) {
  1158  	log.Debug("Starting addNewFileAndModifyContentsEncrypted test")
  1159  	ta.addNewFileAndModifyContents(t, true)
  1160  	log.Debug("Test addNewFileAndModifyContentsEncrypted terminated")
  1161  }
  1162  
  1163  func (ta *testAPI) addNewFileAndModifyContentsNonEncrypted(t *testing.T) {
  1164  	log.Debug("Starting addNewFileAndModifyContentsNonEncrypted test")
  1165  	ta.addNewFileAndModifyContents(t, false)
  1166  	log.Debug("Test addNewFileAndModifyContentsNonEncrypted terminated")
  1167  }
  1168  
  1169  //add a new file and modify content; remount and check the modified file is intact
  1170  func (ta *testAPI) addNewFileAndModifyContents(t *testing.T, toEncrypt bool) {
  1171  	dat, err := ta.initSubtest("addNewFileAndModifyContents")
  1172  	if err != nil {
  1173  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1174  	}
  1175  	defer os.RemoveAll(dat.testDir)
  1176  
  1177  	dat.toEncrypt = toEncrypt
  1178  	dat.testUploadDir = filepath.Join(dat.testDir, "modifyfile-upload")
  1179  	dat.testMountDir = filepath.Join(dat.testDir, "modifyfile-mount")
  1180  	dat.files = make(map[string]fileInfo)
  1181  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1182  	dat.files["five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1183  	dat.files["six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1184  
  1185  	dat, err = ta.uploadAndMount(dat, t)
  1186  	if err != nil {
  1187  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1188  	}
  1189  	defer dat.swarmfs.Stop()
  1190  
  1191  	// Create a new file in the root dir
  1192  	actualPath := filepath.Join(dat.testMountDir, "2.txt")
  1193  	d, err1 := os.OpenFile(actualPath, os.O_RDWR|os.O_CREATE, os.FileMode(0665))
  1194  	if err1 != nil {
  1195  		t.Fatalf("Could not create file %s : %v", actualPath, err1)
  1196  	}
  1197  	defer d.Close()
  1198  	//write some random data into the file
  1199  	log.Debug("file opened")
  1200  	line1 := []byte("Line 1")
  1201  	_, err = rand.Read(line1)
  1202  	if err != nil {
  1203  		t.Fatalf("Error writing random bytes to byte array: %v", err)
  1204  	}
  1205  	log.Debug("line read")
  1206  	_, err = d.Write(line1)
  1207  	if err != nil {
  1208  		t.Fatalf("Error writing random bytes to file: %v", err)
  1209  	}
  1210  	log.Debug("line written")
  1211  	err = d.Close()
  1212  	if err != nil {
  1213  		t.Fatalf("Error closing file: %v", err)
  1214  	}
  1215  	log.Debug("file closed")
  1216  
  1217  	//unmount the hash on the mounted dir
  1218  	mi1, err2 := dat.swarmfs.Unmount(dat.testMountDir)
  1219  	if err2 != nil {
  1220  		t.Fatalf("Could not unmount %v", err2)
  1221  	}
  1222  	log.Debug("Directory unmounted")
  1223  
  1224  	//mount on a different dir to see if modified file is correct
  1225  	testMountDir2, err3 := addDir(dat.testDir, "modifyfile-mount2")
  1226  	if err3 != nil {
  1227  		t.Fatalf("Error creating mount dir2: %v", err3)
  1228  	}
  1229  	dat.files["2.txt"] = fileInfo{0700, 333, 444, line1}
  1230  	_ = mountDir(t, ta.api, dat.files, mi1.LatestManifest, testMountDir2)
  1231  	log.Debug("Directory mounted again")
  1232  
  1233  	checkFile(t, testMountDir2, "2.txt", line1)
  1234  	log.Debug("file checked")
  1235  
  1236  	//unmount second dir
  1237  	mi2, err4 := dat.swarmfs.Unmount(testMountDir2)
  1238  	if err4 != nil {
  1239  		t.Fatalf("Could not unmount %v", err4)
  1240  	}
  1241  	log.Debug("Directory unmounted again")
  1242  
  1243  	//mount again on original dir and modify the file
  1244  	//let's clean up the mounted dir first: remove...
  1245  	err = os.RemoveAll(dat.testMountDir)
  1246  	if err != nil {
  1247  		t.Fatalf("Error cleaning up mount dir: %v", err)
  1248  	}
  1249  	//...and re-create
  1250  	err = os.MkdirAll(dat.testMountDir, 0777)
  1251  	if err != nil {
  1252  		t.Fatalf("Error re-creating mount dir: %v", err)
  1253  	}
  1254  	//now remount
  1255  	_ = mountDir(t, ta.api, dat.files, mi2.LatestManifest, dat.testMountDir)
  1256  	log.Debug("Directory mounted yet again")
  1257  
  1258  	//open the file....
  1259  	fd, err5 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665))
  1260  	if err5 != nil {
  1261  		t.Fatalf("Could not create file %s : %v", actualPath, err5)
  1262  	}
  1263  	defer fd.Close()
  1264  	log.Debug("file opened")
  1265  	//...and modify something
  1266  	line2 := []byte("Line 2")
  1267  	_, err = rand.Read(line2)
  1268  	if err != nil {
  1269  		t.Fatalf("Error modifying random bytes to byte array: %v", err)
  1270  	}
  1271  	log.Debug("line read")
  1272  	_, err = fd.Seek(int64(len(line1)), 0)
  1273  	if err != nil {
  1274  		t.Fatalf("Error seeking position for modification: %v", err)
  1275  	}
  1276  	_, err = fd.Write(line2)
  1277  	if err != nil {
  1278  		t.Fatalf("Error modifying file: %v", err)
  1279  	}
  1280  	log.Debug("line written")
  1281  	err = fd.Close()
  1282  	if err != nil {
  1283  		t.Fatalf("Error closing modified file; %v", err)
  1284  	}
  1285  	log.Debug("file closed")
  1286  
  1287  	//unmount the modified directory
  1288  	mi3, err6 := dat.swarmfs.Unmount(dat.testMountDir)
  1289  	if err6 != nil {
  1290  		t.Fatalf("Could not unmount %v", err6)
  1291  	}
  1292  	log.Debug("Directory unmounted yet again")
  1293  
  1294  	//now remount on a different dir and check that the modified file is ok
  1295  	testMountDir4, err7 := addDir(dat.testDir, "modifyfile-mount4")
  1296  	if err7 != nil {
  1297  		t.Fatalf("Could not unmount %v", err7)
  1298  	}
  1299  	b := [][]byte{line1, line2}
  1300  	line1and2 := bytes.Join(b, []byte(""))
  1301  	dat.files["2.txt"] = fileInfo{0700, 333, 444, line1and2}
  1302  	_ = mountDir(t, ta.api, dat.files, mi3.LatestManifest, testMountDir4)
  1303  	log.Debug("Directory mounted final time")
  1304  
  1305  	checkFile(t, testMountDir4, "2.txt", line1and2)
  1306  	_, err = dat.swarmfs.Unmount(testMountDir4)
  1307  	if err != nil {
  1308  		t.Fatalf("Could not unmount %v", err)
  1309  	}
  1310  	log.Debug("subtest terminated")
  1311  }
  1312  
  1313  func (ta *testAPI) removeEmptyDirEncrypted(t *testing.T) {
  1314  	log.Debug("Starting removeEmptyDirEncrypted test")
  1315  	ta.removeEmptyDir(t, true)
  1316  	log.Debug("Test removeEmptyDirEncrypted terminated")
  1317  }
  1318  
  1319  func (ta *testAPI) removeEmptyDirNonEncrypted(t *testing.T) {
  1320  	log.Debug("Starting removeEmptyDirNonEncrypted test")
  1321  	ta.removeEmptyDir(t, false)
  1322  	log.Debug("Test removeEmptyDirNonEncrypted terminated")
  1323  }
  1324  
  1325  //remove an empty dir inside mount
  1326  func (ta *testAPI) removeEmptyDir(t *testing.T, toEncrypt bool) {
  1327  	dat, err := ta.initSubtest("removeEmptyDir")
  1328  	if err != nil {
  1329  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1330  	}
  1331  	defer os.RemoveAll(dat.testDir)
  1332  
  1333  	dat.toEncrypt = toEncrypt
  1334  	dat.testUploadDir = filepath.Join(dat.testDir, "rmdir-upload")
  1335  	dat.testMountDir = filepath.Join(dat.testDir, "rmdir-mount")
  1336  	dat.files = make(map[string]fileInfo)
  1337  	dat.files["1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1338  	dat.files["five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1339  	dat.files["six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1340  
  1341  	dat, err = ta.uploadAndMount(dat, t)
  1342  	if err != nil {
  1343  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1344  	}
  1345  	defer dat.swarmfs.Stop()
  1346  
  1347  	_, err2 := addDir(dat.testMountDir, "newdir")
  1348  	if err2 != nil {
  1349  		t.Fatalf("Could not unmount %v", err2)
  1350  	}
  1351  	mi, err := dat.swarmfs.Unmount(dat.testMountDir)
  1352  	if err != nil {
  1353  		t.Fatalf("Could not unmount %v", err)
  1354  	}
  1355  	log.Debug("Directory unmounted")
  1356  	//by just adding an empty dir, the hash doesn't change; test this
  1357  	if dat.bzzHash != mi.LatestManifest {
  1358  		t.Fatalf("same contents different hash orig(%v): new(%v)", dat.bzzHash, mi.LatestManifest)
  1359  	}
  1360  	log.Debug("subtest terminated")
  1361  }
  1362  
  1363  func (ta *testAPI) removeDirWhichHasFilesEncrypted(t *testing.T) {
  1364  	log.Debug("Starting removeDirWhichHasFilesEncrypted test")
  1365  	ta.removeDirWhichHasFiles(t, true)
  1366  	log.Debug("Test removeDirWhichHasFilesEncrypted terminated")
  1367  }
  1368  func (ta *testAPI) removeDirWhichHasFilesNonEncrypted(t *testing.T) {
  1369  	log.Debug("Starting removeDirWhichHasFilesNonEncrypted test")
  1370  	ta.removeDirWhichHasFiles(t, false)
  1371  	log.Debug("Test removeDirWhichHasFilesNonEncrypted terminated")
  1372  }
  1373  
  1374  //remove a directory with a file; check on remount file isn't there
  1375  func (ta *testAPI) removeDirWhichHasFiles(t *testing.T, toEncrypt bool) {
  1376  	dat, err := ta.initSubtest("removeDirWhichHasFiles")
  1377  	if err != nil {
  1378  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1379  	}
  1380  	defer os.RemoveAll(dat.testDir)
  1381  
  1382  	dat.toEncrypt = toEncrypt
  1383  	dat.testUploadDir = filepath.Join(dat.testDir, "rmdir-upload")
  1384  	dat.testMountDir = filepath.Join(dat.testDir, "rmdir-mount")
  1385  	dat.files = make(map[string]fileInfo)
  1386  	dat.files["one/1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1387  	dat.files["two/five.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1388  	dat.files["two/six.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1389  
  1390  	dat, err = ta.uploadAndMount(dat, t)
  1391  	if err != nil {
  1392  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1393  	}
  1394  	defer dat.swarmfs.Stop()
  1395  
  1396  	//delete a directory inside the mounted dir with all its files
  1397  	dirPath := filepath.Join(dat.testMountDir, "two")
  1398  	err = os.RemoveAll(dirPath)
  1399  	if err != nil {
  1400  		t.Fatalf("Error removing directory in mounted dir: %v", err)
  1401  	}
  1402  
  1403  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
  1404  	if err2 != nil {
  1405  		t.Fatalf("Could not unmount %v ", err2)
  1406  	}
  1407  	log.Debug("Directory unmounted")
  1408  
  1409  	//we deleted files in the OS, so let's delete them also in the files map
  1410  	delete(dat.files, "two/five.txt")
  1411  	delete(dat.files, "two/six.txt")
  1412  
  1413  	// mount again and see if deleted files have been deleted indeed
  1414  	testMountDir2, err3 := addDir(dat.testDir, "remount-mount2")
  1415  	if err3 != nil {
  1416  		t.Fatalf("Could not unmount %v", err3)
  1417  	}
  1418  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2)
  1419  	log.Debug("Directory mounted")
  1420  	actualPath := filepath.Join(dirPath, "five.txt")
  1421  	_, err = os.Stat(actualPath)
  1422  	if err == nil {
  1423  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1424  	}
  1425  	_, err = os.Stat(dirPath)
  1426  	if err == nil {
  1427  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1428  	}
  1429  	_, err = dat.swarmfs.Unmount(testMountDir2)
  1430  	if err != nil {
  1431  		t.Fatalf("Could not unmount %v", err)
  1432  	}
  1433  	log.Debug("subtest terminated")
  1434  }
  1435  
  1436  func (ta *testAPI) removeDirWhichHasSubDirsEncrypted(t *testing.T) {
  1437  	log.Debug("Starting removeDirWhichHasSubDirsEncrypted test")
  1438  	ta.removeDirWhichHasSubDirs(t, true)
  1439  	log.Debug("Test removeDirWhichHasSubDirsEncrypted terminated")
  1440  }
  1441  
  1442  func (ta *testAPI) removeDirWhichHasSubDirsNonEncrypted(t *testing.T) {
  1443  	log.Debug("Starting removeDirWhichHasSubDirsNonEncrypted test")
  1444  	ta.removeDirWhichHasSubDirs(t, false)
  1445  	log.Debug("Test removeDirWhichHasSubDirsNonEncrypted terminated")
  1446  }
  1447  
  1448  //remove a directory with subdirectories inside mount; on remount check they are not there
  1449  func (ta *testAPI) removeDirWhichHasSubDirs(t *testing.T, toEncrypt bool) {
  1450  	dat, err := ta.initSubtest("removeDirWhichHasSubDirs")
  1451  	if err != nil {
  1452  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1453  	}
  1454  	defer os.RemoveAll(dat.testDir)
  1455  
  1456  	dat.toEncrypt = toEncrypt
  1457  	dat.testUploadDir = filepath.Join(dat.testDir, "rmsubdir-upload")
  1458  	dat.testMountDir = filepath.Join(dat.testDir, "rmsubdir-mount")
  1459  	dat.files = make(map[string]fileInfo)
  1460  	dat.files["one/1.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(1, 10)}
  1461  	dat.files["two/three/2.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(2, 10)}
  1462  	dat.files["two/three/3.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(3, 10)}
  1463  	dat.files["two/four/5.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(4, 10)}
  1464  	dat.files["two/four/6.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(5, 10)}
  1465  	dat.files["two/four/six/7.txt"] = fileInfo{0700, 333, 444, testutil.RandomBytes(6, 10)}
  1466  
  1467  	dat, err = ta.uploadAndMount(dat, t)
  1468  	if err != nil {
  1469  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1470  	}
  1471  	defer dat.swarmfs.Stop()
  1472  
  1473  	dirPath := filepath.Join(dat.testMountDir, "two")
  1474  	err = os.RemoveAll(dirPath)
  1475  	if err != nil {
  1476  		t.Fatalf("Error removing directory in mounted dir: %v", err)
  1477  	}
  1478  
  1479  	//delete a directory inside the mounted dir with all its files
  1480  	mi, err2 := dat.swarmfs.Unmount(dat.testMountDir)
  1481  	if err2 != nil {
  1482  		t.Fatalf("Could not unmount %v ", err2)
  1483  	}
  1484  	log.Debug("Directory unmounted")
  1485  
  1486  	//we deleted files in the OS, so let's delete them also in the files map
  1487  	delete(dat.files, "two/three/2.txt")
  1488  	delete(dat.files, "two/three/3.txt")
  1489  	delete(dat.files, "two/four/5.txt")
  1490  	delete(dat.files, "two/four/6.txt")
  1491  	delete(dat.files, "two/four/six/7.txt")
  1492  
  1493  	// mount again and see if things are okay
  1494  	testMountDir2, err3 := addDir(dat.testDir, "remount-mount2")
  1495  	if err3 != nil {
  1496  		t.Fatalf("Could not unmount %v", err3)
  1497  	}
  1498  	_ = mountDir(t, ta.api, dat.files, mi.LatestManifest, testMountDir2)
  1499  	log.Debug("Directory mounted again")
  1500  	actualPath := filepath.Join(dirPath, "three")
  1501  	actualPath = filepath.Join(actualPath, "2.txt")
  1502  	_, err = os.Stat(actualPath)
  1503  	if err == nil {
  1504  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1505  	}
  1506  	actualPath = filepath.Join(dirPath, "four")
  1507  	_, err = os.Stat(actualPath)
  1508  	if err == nil {
  1509  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1510  	}
  1511  	_, err = os.Stat(dirPath)
  1512  	if err == nil {
  1513  		t.Fatal("Expected file to not be present in re-mount after removal, but it is there")
  1514  	}
  1515  	_, err = dat.swarmfs.Unmount(testMountDir2)
  1516  	if err != nil {
  1517  		t.Fatalf("Could not unmount %v", err)
  1518  	}
  1519  	log.Debug("subtest terminated")
  1520  }
  1521  
  1522  func (ta *testAPI) appendFileContentsToEndEncrypted(t *testing.T) {
  1523  	log.Debug("Starting appendFileContentsToEndEncrypted test")
  1524  	ta.appendFileContentsToEnd(t, true)
  1525  	log.Debug("Test appendFileContentsToEndEncrypted terminated")
  1526  }
  1527  
  1528  func (ta *testAPI) appendFileContentsToEndNonEncrypted(t *testing.T) {
  1529  	log.Debug("Starting appendFileContentsToEndNonEncrypted test")
  1530  	ta.appendFileContentsToEnd(t, false)
  1531  	log.Debug("Test appendFileContentsToEndNonEncrypted terminated")
  1532  }
  1533  
  1534  //append contents to the end of a file; remount and check it's intact
  1535  func (ta *testAPI) appendFileContentsToEnd(t *testing.T, toEncrypt bool) {
  1536  	dat, err := ta.initSubtest("appendFileContentsToEnd")
  1537  	if err != nil {
  1538  		t.Fatalf("Couldn't initialize subtest dirs: %v", err)
  1539  	}
  1540  	defer os.RemoveAll(dat.testDir)
  1541  
  1542  	dat.toEncrypt = toEncrypt
  1543  	dat.testUploadDir = filepath.Join(dat.testDir, "appendlargefile-upload")
  1544  	dat.testMountDir = filepath.Join(dat.testDir, "appendlargefile-mount")
  1545  	dat.files = make(map[string]fileInfo)
  1546  
  1547  	line1 := testutil.RandomBytes(1, 10)
  1548  
  1549  	dat.files["1.txt"] = fileInfo{0700, 333, 444, line1}
  1550  
  1551  	dat, err = ta.uploadAndMount(dat, t)
  1552  	if err != nil {
  1553  		t.Fatalf("Error during upload of files to swarm / mount of swarm dir: %v", err)
  1554  	}
  1555  	defer dat.swarmfs.Stop()
  1556  
  1557  	actualPath := filepath.Join(dat.testMountDir, "1.txt")
  1558  	fd, err4 := os.OpenFile(actualPath, os.O_RDWR|os.O_APPEND, os.FileMode(0665))
  1559  	if err4 != nil {
  1560  		t.Fatalf("Could not create file %s : %v", actualPath, err4)
  1561  	}
  1562  	defer fd.Close()
  1563  	log.Debug("file opened")
  1564  	line2 := testutil.RandomBytes(1, 5)
  1565  	log.Debug("line read")
  1566  	_, err = fd.Seek(int64(len(line1)), 0)
  1567  	if err != nil {
  1568  		t.Fatalf("Error searching for position to append: %v", err)
  1569  	}
  1570  	_, err = fd.Write(line2)
  1571  	if err != nil {
  1572  		t.Fatalf("Error appending: %v", err)
  1573  	}
  1574  	log.Debug("line written")
  1575  	err = fd.Close()
  1576  	if err != nil {
  1577  		t.Fatalf("Error closing file: %v", err)
  1578  	}
  1579  	log.Debug("file closed")
  1580  
  1581  	mi1, err5 := dat.swarmfs.Unmount(dat.testMountDir)
  1582  	if err5 != nil {
  1583  		t.Fatalf("Could not unmount %v ", err5)
  1584  	}
  1585  	log.Debug("Directory unmounted")
  1586  
  1587  	// mount again and see if appended file is correct
  1588  	b := [][]byte{line1, line2}
  1589  	line1and2 := bytes.Join(b, []byte(""))
  1590  	dat.files["1.txt"] = fileInfo{0700, 333, 444, line1and2}
  1591  	testMountDir2, err6 := addDir(dat.testDir, "remount-mount2")
  1592  	if err6 != nil {
  1593  		t.Fatalf("Could not unmount %v", err6)
  1594  	}
  1595  	_ = mountDir(t, ta.api, dat.files, mi1.LatestManifest, testMountDir2)
  1596  	log.Debug("Directory mounted")
  1597  
  1598  	checkFile(t, testMountDir2, "1.txt", line1and2)
  1599  
  1600  	_, err = dat.swarmfs.Unmount(testMountDir2)
  1601  	if err != nil {
  1602  		t.Fatalf("Could not unmount %v", err)
  1603  	}
  1604  	log.Debug("subtest terminated")
  1605  }
  1606  
  1607  //run all the tests
  1608  func TestFUSE(t *testing.T) {
  1609  	t.Skip("disable fuse tests until they are stable")
  1610  	//create a data directory for swarm
  1611  	datadir, err := ioutil.TempDir("", "fuse")
  1612  	if err != nil {
  1613  		t.Fatalf("unable to create temp dir: %v", err)
  1614  	}
  1615  	defer os.RemoveAll(datadir)
  1616  
  1617  	fileStore, err := storage.NewLocalFileStore(datadir, make([]byte, 32))
  1618  	if err != nil {
  1619  		t.Fatal(err)
  1620  	}
  1621  	ta := &testAPI{api: api.NewAPI(fileStore, nil, nil, nil)}
  1622  
  1623  	//run a short suite of tests
  1624  	//approx time: 28s
  1625  	t.Run("mountListAndUnmountEncrypted", ta.mountListAndUnmountEncrypted)
  1626  	t.Run("remountEncrypted", ta.remountEncrypted)
  1627  	t.Run("unmountWhenResourceBusyNonEncrypted", ta.unmountWhenResourceBusyNonEncrypted)
  1628  	t.Run("removeExistingFileEncrypted", ta.removeExistingFileEncrypted)
  1629  	t.Run("addNewFileAndModifyContentsNonEncrypted", ta.addNewFileAndModifyContentsNonEncrypted)
  1630  	t.Run("removeDirWhichHasFilesNonEncrypted", ta.removeDirWhichHasFilesNonEncrypted)
  1631  	t.Run("appendFileContentsToEndEncrypted", ta.appendFileContentsToEndEncrypted)
  1632  
  1633  	//provide longrunning flag to execute all tests
  1634  	//approx time with longrunning: 140s
  1635  	if *longrunning {
  1636  		t.Run("mountListAndUnmountNonEncrypted", ta.mountListAndUnmountNonEncrypted)
  1637  		t.Run("maxMountsEncrypted", ta.maxMountsEncrypted)
  1638  		t.Run("maxMountsNonEncrypted", ta.maxMountsNonEncrypted)
  1639  		t.Run("remountNonEncrypted", ta.remountNonEncrypted)
  1640  		t.Run("unmountEncrypted", ta.unmountEncrypted)
  1641  		t.Run("unmountNonEncrypted", ta.unmountNonEncrypted)
  1642  		t.Run("unmountWhenResourceBusyEncrypted", ta.unmountWhenResourceBusyEncrypted)
  1643  		t.Run("unmountWhenResourceBusyNonEncrypted", ta.unmountWhenResourceBusyNonEncrypted)
  1644  		t.Run("seekInMultiChunkFileEncrypted", ta.seekInMultiChunkFileEncrypted)
  1645  		t.Run("seekInMultiChunkFileNonEncrypted", ta.seekInMultiChunkFileNonEncrypted)
  1646  		t.Run("createNewFileEncrypted", ta.createNewFileEncrypted)
  1647  		t.Run("createNewFileNonEncrypted", ta.createNewFileNonEncrypted)
  1648  		t.Run("createNewFileInsideDirectoryEncrypted", ta.createNewFileInsideDirectoryEncrypted)
  1649  		t.Run("createNewFileInsideDirectoryNonEncrypted", ta.createNewFileInsideDirectoryNonEncrypted)
  1650  		t.Run("createNewFileInsideNewDirectoryEncrypted", ta.createNewFileInsideNewDirectoryEncrypted)
  1651  		t.Run("createNewFileInsideNewDirectoryNonEncrypted", ta.createNewFileInsideNewDirectoryNonEncrypted)
  1652  		t.Run("removeExistingFileNonEncrypted", ta.removeExistingFileNonEncrypted)
  1653  		t.Run("removeExistingFileInsideDirEncrypted", ta.removeExistingFileInsideDirEncrypted)
  1654  		t.Run("removeExistingFileInsideDirNonEncrypted", ta.removeExistingFileInsideDirNonEncrypted)
  1655  		t.Run("removeNewlyAddedFileEncrypted", ta.removeNewlyAddedFileEncrypted)
  1656  		t.Run("removeNewlyAddedFileNonEncrypted", ta.removeNewlyAddedFileNonEncrypted)
  1657  		t.Run("addNewFileAndModifyContentsEncrypted", ta.addNewFileAndModifyContentsEncrypted)
  1658  		t.Run("removeEmptyDirEncrypted", ta.removeEmptyDirEncrypted)
  1659  		t.Run("removeEmptyDirNonEncrypted", ta.removeEmptyDirNonEncrypted)
  1660  		t.Run("removeDirWhichHasFilesEncrypted", ta.removeDirWhichHasFilesEncrypted)
  1661  		t.Run("removeDirWhichHasSubDirsEncrypted", ta.removeDirWhichHasSubDirsEncrypted)
  1662  		t.Run("removeDirWhichHasSubDirsNonEncrypted", ta.removeDirWhichHasSubDirsNonEncrypted)
  1663  		t.Run("appendFileContentsToEndNonEncrypted", ta.appendFileContentsToEndNonEncrypted)
  1664  	}
  1665  }
  1666  
  1667  func Upload(uploadDir, index string, a *api.API, toEncrypt bool) (hash string, err error) {
  1668  	fs := api.NewFileSystem(a)
  1669  	hash, err = fs.Upload(uploadDir, index, toEncrypt)
  1670  	return hash, err
  1671  }