gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/renter/persist_test.go (about)

     1  package renter
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"os"
     7  	"path/filepath"
     8  	"testing"
     9  
    10  	"gitlab.com/NebulousLabs/fastrand"
    11  	"gitlab.com/SiaPrime/SiaPrime/crypto"
    12  	"gitlab.com/SiaPrime/SiaPrime/modules"
    13  	"gitlab.com/SiaPrime/SiaPrime/modules/renter/siafile"
    14  )
    15  
    16  // testingFileParams generates the ErasureCoder and a random name for a testing
    17  // file
    18  func testingFileParams() (modules.SiaPath, modules.ErasureCoder) {
    19  	nData := fastrand.Intn(10)
    20  	nParity := fastrand.Intn(10)
    21  	rsc, _ := siafile.NewRSCode(nData+1, nParity+1)
    22  	return modules.RandomSiaPath(), rsc
    23  }
    24  
    25  // equalFiles is a helper function that compares two files for equality.
    26  func equalFiles(f1, f2 *siafile.SiaFile) error {
    27  	if f1 == nil || f2 == nil {
    28  		return fmt.Errorf("one or both files are nil")
    29  	}
    30  	if f1.UID() != f2.UID() {
    31  		return fmt.Errorf("uids do not match: %v %v", f1.UID(), f2.UID())
    32  	}
    33  	if f1.Size() != f2.Size() {
    34  		return fmt.Errorf("sizes do not match: %v %v", f1.Size(), f2.Size())
    35  	}
    36  	mk1 := f1.MasterKey()
    37  	mk2 := f2.MasterKey()
    38  	if !bytes.Equal(mk1.Key(), mk2.Key()) {
    39  		return fmt.Errorf("keys do not match: %v %v", mk1.Key(), mk2.Key())
    40  	}
    41  	if f1.PieceSize() != f2.PieceSize() {
    42  		return fmt.Errorf("pieceSizes do not match: %v %v", f1.PieceSize(), f2.PieceSize())
    43  	}
    44  	return nil
    45  }
    46  
    47  // TestRenterSaveLoad probes the save and load methods of the renter type.
    48  func TestRenterSaveLoad(t *testing.T) {
    49  	if testing.Short() {
    50  		t.SkipNow()
    51  	}
    52  	rt, err := newRenterTester(t.Name())
    53  	if err != nil {
    54  		t.Fatal(err)
    55  	}
    56  	defer rt.Close()
    57  
    58  	// Check that the default values got set correctly.
    59  	settings := rt.renter.Settings()
    60  	if settings.MaxDownloadSpeed != DefaultMaxDownloadSpeed {
    61  		t.Error("default max download speed not set at init")
    62  	}
    63  	if settings.MaxUploadSpeed != DefaultMaxUploadSpeed {
    64  		t.Error("default max upload speed not set at init")
    65  	}
    66  
    67  	// Update the settings of the renter to have a new stream cache size and
    68  	// download speed.
    69  	newDownSpeed := int64(300e3)
    70  	newUpSpeed := int64(500e3)
    71  	settings.MaxDownloadSpeed = newDownSpeed
    72  	settings.MaxUploadSpeed = newUpSpeed
    73  	rt.renter.SetSettings(settings)
    74  
    75  	// Add a file to the renter
    76  	entry, err := rt.renter.newRenterTestFile()
    77  	if err != nil {
    78  		t.Fatal(err)
    79  	}
    80  	siapath := rt.renter.staticFileSet.SiaPath(entry)
    81  	err = entry.Close()
    82  	if err != nil {
    83  		t.Fatal(err)
    84  	}
    85  
    86  	// Check that SiaFileSet knows of the SiaFile
    87  	entry, err = rt.renter.staticFileSet.Open(siapath)
    88  	if err != nil {
    89  		t.Fatal("SiaFile not found in the renter's staticFileSet after creation")
    90  	}
    91  	err = entry.Close()
    92  	if err != nil {
    93  		t.Fatal(err)
    94  	}
    95  
    96  	err = rt.renter.saveSync() // save metadata
    97  	if err != nil {
    98  		t.Fatal(err)
    99  	}
   100  	err = rt.renter.Close()
   101  	if err != nil {
   102  		t.Fatal(err)
   103  	}
   104  
   105  	// load should now load the files into memory.
   106  	rt.renter, err = New(rt.gateway, rt.cs, rt.wallet, rt.tpool, filepath.Join(rt.dir, modules.RenterDir))
   107  	if err != nil {
   108  		t.Fatal(err)
   109  	}
   110  
   111  	newSettings := rt.renter.Settings()
   112  	if newSettings.MaxDownloadSpeed != newDownSpeed {
   113  		t.Error("download settings not being persisted correctly")
   114  	}
   115  	if newSettings.MaxUploadSpeed != newUpSpeed {
   116  		t.Error("upload settings not being persisted correctly")
   117  	}
   118  
   119  	// Check that SiaFileSet loaded the renter's file
   120  	_, err = rt.renter.staticFileSet.Open(siapath)
   121  	if err != nil {
   122  		t.Fatal("SiaFile not found in the renter's staticFileSet after load")
   123  	}
   124  }
   125  
   126  // TestRenterPaths checks that the renter properly handles nicknames
   127  // containing the path separator ("/").
   128  func TestRenterPaths(t *testing.T) {
   129  	if testing.Short() {
   130  		t.SkipNow()
   131  	}
   132  	rt, err := newRenterTester(t.Name())
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  	defer rt.Close()
   137  
   138  	// Create and save some files.
   139  	// The result of saving these files should be a directory containing:
   140  	//   foo.sia
   141  	//   foo/bar.sia
   142  	//   foo/bar/baz.sia
   143  
   144  	siaPath1, err := modules.NewSiaPath("foo")
   145  	if err != nil {
   146  		t.Fatal(err)
   147  	}
   148  	siaPath2, err := modules.NewSiaPath("foo/bar")
   149  	if err != nil {
   150  		t.Fatal(err)
   151  	}
   152  	siaPath3, err := modules.NewSiaPath("foo/bar/baz")
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	wal := rt.renter.wal
   158  	rc, err := siafile.NewRSSubCode(1, 1, crypto.SegmentSize)
   159  	if err != nil {
   160  		t.Fatal(err)
   161  	}
   162  	sk := crypto.GenerateSiaKey(crypto.TypeThreefish)
   163  	fileSize := uint64(modules.SectorSize)
   164  	fileMode := os.FileMode(0600)
   165  	f1, err := siafile.New(siaPath1.SiaFileSysPath(rt.renter.staticFilesDir), "", wal, rc, sk, fileSize, fileMode, nil, true)
   166  	if err != nil {
   167  		t.Fatal(err)
   168  	}
   169  	f2, err := siafile.New(siaPath2.SiaFileSysPath(rt.renter.staticFilesDir), "", wal, rc, sk, fileSize, fileMode, nil, true)
   170  	if err != nil {
   171  		t.Fatal(err)
   172  	}
   173  	f3, err := siafile.New(siaPath3.SiaFileSysPath(rt.renter.staticFilesDir), "", wal, rc, sk, fileSize, fileMode, nil, true)
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  
   178  	// Restart the renter to re-do the init cycle.
   179  	err = rt.renter.Close()
   180  	if err != nil {
   181  		t.Fatal(err)
   182  	}
   183  	rt.renter, err = New(rt.gateway, rt.cs, rt.wallet, rt.tpool, filepath.Join(rt.dir, modules.RenterDir))
   184  	if err != nil {
   185  		t.Fatal(err)
   186  	}
   187  
   188  	// Check that the files were loaded properly.
   189  	entry1, err := rt.renter.staticFileSet.Open(siaPath1)
   190  	if err != nil {
   191  		t.Fatal("File not found in renter", err)
   192  	}
   193  	if err := equalFiles(f1, entry1.SiaFile); err != nil {
   194  		t.Fatal(err)
   195  	}
   196  	entry2, err := rt.renter.staticFileSet.Open(siaPath2)
   197  	if err != nil {
   198  		t.Fatal("File not found in renter", err)
   199  	}
   200  	if err := equalFiles(f2, entry2.SiaFile); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	entry3, err := rt.renter.staticFileSet.Open(siaPath3)
   204  	if err != nil {
   205  		t.Fatal("File not found in renter", err)
   206  	}
   207  	if err := equalFiles(f3, entry3.SiaFile); err != nil {
   208  		t.Fatal(err)
   209  	}
   210  
   211  	// To confirm that the file structure was preserved, we walk the renter
   212  	// folder and emit the name of each .sia file encountered (filepath.Walk
   213  	// is deterministic; it orders the files lexically).
   214  	var walkStr string
   215  	filepath.Walk(rt.renter.staticFilesDir, func(path string, _ os.FileInfo, _ error) error {
   216  		// capture only .sia files
   217  		if filepath.Ext(path) != ".sia" {
   218  			return nil
   219  		}
   220  		rel, _ := filepath.Rel(rt.renter.staticFilesDir, path) // strip testdir prefix
   221  		walkStr += rel
   222  		return nil
   223  	})
   224  	// walk will descend into foo/bar/, reading baz, bar, and finally foo
   225  	sfs := rt.renter.staticFileSet
   226  	expWalkStr := (sfs.SiaPath(entry3).String() + ".sia") + (sfs.SiaPath(entry2).String() + ".sia") + (sfs.SiaPath(entry1).String() + ".sia")
   227  	if filepath.ToSlash(walkStr) != expWalkStr {
   228  		t.Fatalf("Bad walk string: expected %v, got %v", expWalkStr, walkStr)
   229  	}
   230  }
   231  
   232  // TestSiafileCompatibility tests that the renter is able to load v0.4.8 .sia files.
   233  func TestSiafileCompatibility(t *testing.T) {
   234  	if testing.Short() {
   235  		t.SkipNow()
   236  	}
   237  	rt, err := newRenterTester(t.Name())
   238  	if err != nil {
   239  		t.Fatal(err)
   240  	}
   241  	defer rt.Close()
   242  
   243  	// Load the compatibility file into the renter.
   244  	path := filepath.Join("..", "..", "compatibility", "siafile_v0.4.8.sia")
   245  	f, err := os.Open(path)
   246  	if err != nil {
   247  		t.Fatal(err)
   248  	}
   249  	var oc []modules.RenterContract
   250  	names, err := rt.renter.compatV137loadSiaFilesFromReader(f, make(map[string]v137TrackedFile), oc)
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  	if len(names) != 1 || names[0] != "testfile-183" {
   255  		t.Fatal("nickname not loaded properly:", names)
   256  	}
   257  	// Make sure that we can open the file afterwards.
   258  	siaPath, err := modules.NewSiaPath(names[0])
   259  	if err != nil {
   260  		t.Fatal(err)
   261  	}
   262  	_, err = rt.renter.staticFileSet.Open(siaPath)
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  }