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

     1  package contractor
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"gitlab.com/NebulousLabs/fastrand"
    10  	"gitlab.com/SiaPrime/SiaPrime/build"
    11  	"gitlab.com/SiaPrime/SiaPrime/modules"
    12  	"gitlab.com/SiaPrime/SiaPrime/modules/renter/proto"
    13  	"gitlab.com/SiaPrime/SiaPrime/types"
    14  )
    15  
    16  // memPersist implements the persister interface in-memory.
    17  type memPersist contractorPersist
    18  
    19  func (m *memPersist) save(data contractorPersist) error { *m = memPersist(data); return nil }
    20  func (m memPersist) load(data *contractorPersist) error { *data = contractorPersist(m); return nil }
    21  
    22  // TestSaveLoad tests that the contractor can save and load itself.
    23  func TestSaveLoad(t *testing.T) {
    24  	// create contractor with mocked persist dependency
    25  	c := &Contractor{
    26  		persist: new(memPersist),
    27  	}
    28  
    29  	c.oldContracts = map[types.FileContractID]modules.RenterContract{
    30  		{0}: {ID: types.FileContractID{0}, HostPublicKey: types.SiaPublicKey{Key: []byte("foo")}},
    31  		{1}: {ID: types.FileContractID{1}, HostPublicKey: types.SiaPublicKey{Key: []byte("bar")}},
    32  		{2}: {ID: types.FileContractID{2}, HostPublicKey: types.SiaPublicKey{Key: []byte("baz")}},
    33  	}
    34  
    35  	c.renewedFrom = map[types.FileContractID]types.FileContractID{
    36  		{1}: {2},
    37  	}
    38  	c.renewedTo = map[types.FileContractID]types.FileContractID{
    39  		{1}: {2},
    40  	}
    41  
    42  	// save, clear, and reload
    43  	err := c.save()
    44  	if err != nil {
    45  		t.Fatal(err)
    46  	}
    47  	c.hdb = stubHostDB{}
    48  	c.oldContracts = make(map[types.FileContractID]modules.RenterContract)
    49  	c.renewedFrom = make(map[types.FileContractID]types.FileContractID)
    50  	c.renewedTo = make(map[types.FileContractID]types.FileContractID)
    51  	err = c.load()
    52  	if err != nil {
    53  		t.Fatal(err)
    54  	}
    55  	// Check that all fields were restored
    56  	_, ok0 := c.oldContracts[types.FileContractID{0}]
    57  	_, ok1 := c.oldContracts[types.FileContractID{1}]
    58  	_, ok2 := c.oldContracts[types.FileContractID{2}]
    59  	if !ok0 || !ok1 || !ok2 {
    60  		t.Fatal("oldContracts were not restored properly:", c.oldContracts)
    61  	}
    62  	id := types.FileContractID{2}
    63  	if c.renewedFrom[types.FileContractID{1}] != id {
    64  		t.Fatal("renewedFrom not restored properly:", c.renewedFrom)
    65  	}
    66  	if c.renewedTo[types.FileContractID{1}] != id {
    67  		t.Fatal("renewedTo not restored properly:", c.renewedTo)
    68  	}
    69  	// use stdPersist instead of mock
    70  	c.persist = NewPersist(build.TempDir("contractor", t.Name()))
    71  	os.MkdirAll(build.TempDir("contractor", t.Name()), 0700)
    72  
    73  	// COMPATv136 save the allowance but make sure that the newly added fields
    74  	// are 0. After loading them from disk they should be set to the default
    75  	// values.
    76  	c.allowance = modules.DefaultAllowance
    77  	c.allowance.ExpectedStorage = 0
    78  	c.allowance.ExpectedUpload = 0
    79  	c.allowance.ExpectedDownload = 0
    80  	c.allowance.ExpectedRedundancy = 0
    81  
    82  	// save, clear, and reload
    83  	err = c.save()
    84  	if err != nil {
    85  		t.Fatal(err)
    86  	}
    87  	c.oldContracts = make(map[types.FileContractID]modules.RenterContract)
    88  	c.renewedFrom = make(map[types.FileContractID]types.FileContractID)
    89  	c.renewedTo = make(map[types.FileContractID]types.FileContractID)
    90  	err = c.load()
    91  	if err != nil {
    92  		t.Fatal(err)
    93  	}
    94  	// check that all fields were restored
    95  	_, ok0 = c.oldContracts[types.FileContractID{0}]
    96  	_, ok1 = c.oldContracts[types.FileContractID{1}]
    97  	_, ok2 = c.oldContracts[types.FileContractID{2}]
    98  	if !ok0 || !ok1 || !ok2 {
    99  		t.Fatal("oldContracts were not restored properly:", c.oldContracts)
   100  	}
   101  	if c.renewedFrom[types.FileContractID{1}] != id {
   102  		t.Fatal("renewedFrom not restored properly:", c.renewedFrom)
   103  	}
   104  	if c.renewedTo[types.FileContractID{1}] != id {
   105  		t.Fatal("renewedTo not restored properly:", c.renewedTo)
   106  	}
   107  	if c.allowance.ExpectedStorage != modules.DefaultAllowance.ExpectedStorage {
   108  		t.Errorf("ExpectedStorage was %v but should be %v",
   109  			c.allowance.ExpectedStorage, modules.DefaultAllowance.ExpectedStorage)
   110  	}
   111  	if c.allowance.ExpectedUpload != modules.DefaultAllowance.ExpectedUpload {
   112  		t.Errorf("ExpectedUpload was %v but should be %v",
   113  			c.allowance.ExpectedUpload, modules.DefaultAllowance.ExpectedUpload)
   114  	}
   115  	if c.allowance.ExpectedDownload != modules.DefaultAllowance.ExpectedDownload {
   116  		t.Errorf("ExpectedDownload was %v but should be %v",
   117  			c.allowance.ExpectedDownload, modules.DefaultAllowance.ExpectedDownload)
   118  	}
   119  	if c.allowance.ExpectedRedundancy != modules.DefaultAllowance.ExpectedRedundancy {
   120  		t.Errorf("ExpectedRedundancy was %v but should be %v",
   121  			c.allowance.ExpectedRedundancy, modules.DefaultAllowance.ExpectedRedundancy)
   122  	}
   123  
   124  	// Change the expected* fields of the allowance again, save, clear and reload.
   125  	c.allowance.ExpectedStorage = uint64(fastrand.Intn(100))
   126  	c.allowance.ExpectedUpload = uint64(fastrand.Intn(100))
   127  	c.allowance.ExpectedDownload = uint64(fastrand.Intn(100))
   128  	c.allowance.ExpectedRedundancy = float64(fastrand.Intn(100))
   129  	a := c.allowance
   130  	// Save
   131  	err = c.save()
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	// Clear allowance.
   136  	c.allowance = modules.Allowance{}
   137  	// Load
   138  	err = c.load()
   139  	if err != nil {
   140  		t.Fatal(err)
   141  	}
   142  	// Check if fields were restored.
   143  	if c.allowance.ExpectedStorage != a.ExpectedStorage {
   144  		t.Errorf("ExpectedStorage was %v but should be %v",
   145  			c.allowance.ExpectedStorage, a.ExpectedStorage)
   146  	}
   147  	if c.allowance.ExpectedUpload != a.ExpectedUpload {
   148  		t.Errorf("ExpectedUpload was %v but should be %v",
   149  			c.allowance.ExpectedUpload, a.ExpectedUpload)
   150  	}
   151  	if c.allowance.ExpectedDownload != a.ExpectedDownload {
   152  		t.Errorf("ExpectedDownload was %v but should be %v",
   153  			c.allowance.ExpectedDownload, a.ExpectedDownload)
   154  	}
   155  	if c.allowance.ExpectedRedundancy != a.ExpectedRedundancy {
   156  		t.Errorf("ExpectedRedundancy was %v but should be %v",
   157  			c.allowance.ExpectedRedundancy, a.ExpectedRedundancy)
   158  	}
   159  }
   160  
   161  // TestConvertPersist tests that contracts previously stored in the
   162  // .journal format can be converted to the .contract format.
   163  func TestConvertPersist(t *testing.T) {
   164  	dir := build.TempDir(filepath.Join("contractor", t.Name()))
   165  	os.MkdirAll(dir, 0700)
   166  	// copy the test data into the temp folder
   167  	testdata, err := ioutil.ReadFile(filepath.Join("testdata", "TestConvertPersist.journal"))
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  	err = ioutil.WriteFile(filepath.Join(dir, "contractor.journal"), testdata, 0600)
   172  	if err != nil {
   173  		t.Fatal(err)
   174  	}
   175  
   176  	// convert the journal
   177  	err = convertPersist(dir)
   178  	if err != nil {
   179  		t.Fatal(err)
   180  	}
   181  
   182  	// load the persist
   183  	var p contractorPersist
   184  	err = NewPersist(dir).load(&p)
   185  	if err != nil {
   186  		t.Fatal(err)
   187  	}
   188  	if !p.Allowance.Funds.Equals64(10) || p.Allowance.Hosts != 7 || p.Allowance.Period != 3 || p.Allowance.RenewWindow != 20 {
   189  		t.Fatal("recovered allowance was wrong:", p.Allowance)
   190  	}
   191  
   192  	// load the contracts
   193  	cs, err := proto.NewContractSet(filepath.Join(dir, "contracts"), modules.ProdDependencies)
   194  	if err != nil {
   195  		t.Fatal(err)
   196  	}
   197  	if cs.Len() != 1 {
   198  		t.Fatal("expected 1 contract, got", cs.Len())
   199  	}
   200  	m := cs.ViewAll()[0]
   201  	if m.ID.String() != "792b5eec683819d78416a9e80cba454ebcb5a52eeac4f17b443d177bd425fc5c" {
   202  		t.Fatal("recovered contract has wrong ID", m.ID)
   203  	}
   204  }