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