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