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

     1  package hostdb
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  	"time"
     7  
     8  	"gitlab.com/SiaPrime/SiaPrime/modules"
     9  	"gitlab.com/SiaPrime/SiaPrime/types"
    10  )
    11  
    12  // TestUpdateEntry checks that the various components of updateEntry are
    13  // working correctly.
    14  func TestUpdateEntry(t *testing.T) {
    15  	if testing.Short() {
    16  		t.SkipNow()
    17  	}
    18  	hdbt, err := newHDBTesterDeps(t.Name(), &disableScanLoopDeps{})
    19  	if err != nil {
    20  		t.Fatal(err)
    21  	}
    22  
    23  	// Test 1: try calling updateEntry with a blank host. Result should be a
    24  	// host with len 2 scan history.
    25  	someErr := errors.New("testing err")
    26  	entry1 := modules.HostDBEntry{
    27  		PublicKey: types.SiaPublicKey{
    28  			Key: []byte{1},
    29  		},
    30  	}
    31  	entry2 := modules.HostDBEntry{
    32  		PublicKey: types.SiaPublicKey{
    33  			Key: []byte{2},
    34  		},
    35  	}
    36  
    37  	// Try inserting the first entry. Result in the host tree should be a host
    38  	// with a scan history length of two.
    39  	hdbt.hdb.updateEntry(entry1, nil)
    40  	updatedEntry, exists := hdbt.hdb.hostTree.Select(entry1.PublicKey)
    41  	if !exists {
    42  		t.Fatal("Entry did not get inserted into the host tree")
    43  	}
    44  	if len(updatedEntry.ScanHistory) != 2 {
    45  		t.Fatal("new entry was not given two scanning history entries")
    46  	}
    47  	if !updatedEntry.ScanHistory[0].Timestamp.Before(updatedEntry.ScanHistory[1].Timestamp) {
    48  		t.Error("new entry was not provided with a sorted scanning history")
    49  	}
    50  	if !updatedEntry.ScanHistory[0].Success || !updatedEntry.ScanHistory[1].Success {
    51  		t.Error("new entry was not given success values despite a successful scan")
    52  	}
    53  
    54  	// Try inserting the second entry, but with an error. Results should largely
    55  	// be the same.
    56  	hdbt.hdb.updateEntry(entry2, someErr)
    57  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry2.PublicKey)
    58  	if !exists {
    59  		t.Fatal("Entry did not get inserted into the host tree")
    60  	}
    61  	if len(updatedEntry.ScanHistory) != 2 {
    62  		t.Fatal("new entry was not given two scanning history entries")
    63  	}
    64  	if !updatedEntry.ScanHistory[0].Timestamp.Before(updatedEntry.ScanHistory[1].Timestamp) {
    65  		t.Error("new entry was not provided with a sorted scanning history")
    66  	}
    67  	if updatedEntry.ScanHistory[0].Success || updatedEntry.ScanHistory[1].Success {
    68  		t.Error("new entry was not given success values despite a successful scan")
    69  	}
    70  
    71  	// Insert the first entry twice more, with no error. There should be 4
    72  	// entries, and the timestamps should be strictly increasing.
    73  	hdbt.hdb.updateEntry(entry1, nil)
    74  	hdbt.hdb.updateEntry(entry1, nil)
    75  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
    76  	if !exists {
    77  		t.Fatal("Entry did not get inserted into the host tree")
    78  	}
    79  	if len(updatedEntry.ScanHistory) != 4 {
    80  		t.Fatal("new entry was not given two scanning history entries")
    81  	}
    82  	if !updatedEntry.ScanHistory[1].Timestamp.Before(updatedEntry.ScanHistory[2].Timestamp) {
    83  		t.Error("new entry was not provided with a sorted scanning history")
    84  	}
    85  	if !updatedEntry.ScanHistory[2].Timestamp.Before(updatedEntry.ScanHistory[3].Timestamp) {
    86  		t.Error("new entry was not provided with a sorted scanning history")
    87  	}
    88  	if !updatedEntry.ScanHistory[2].Success || !updatedEntry.ScanHistory[3].Success {
    89  		t.Error("new entries did not get added with successful timestamps")
    90  	}
    91  
    92  	// Add a non-successful scan and verify that it is registered properly.
    93  	hdbt.hdb.updateEntry(entry1, someErr)
    94  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
    95  	if !exists {
    96  		t.Fatal("Entry did not get inserted into the host tree")
    97  	}
    98  	if len(updatedEntry.ScanHistory) != 5 {
    99  		t.Fatal("new entry was not given two scanning history entries")
   100  	}
   101  	if !updatedEntry.ScanHistory[3].Success || updatedEntry.ScanHistory[4].Success {
   102  		t.Error("new entries did not get added with successful timestamps")
   103  	}
   104  
   105  	// Prefix an invalid entry to have a scan from more than maxHostDowntime
   106  	// days ago. At less than minScans total, the host should not be deleted
   107  	// upon update.
   108  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry2.PublicKey)
   109  	if !exists {
   110  		t.Fatal("Entry did not get inserted into the host tree")
   111  	}
   112  	updatedEntry.ScanHistory = append([]modules.HostDBScan{{}}, updatedEntry.ScanHistory...)
   113  	err = hdbt.hdb.hostTree.Modify(updatedEntry)
   114  	if err != nil {
   115  		t.Fatal(err)
   116  	}
   117  	// Entry should still exist.
   118  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry2.PublicKey)
   119  	if !exists {
   120  		t.Fatal("Entry did not get inserted into the host tree")
   121  	}
   122  	// Add enough entries to get to minScans total length. When that length is
   123  	// reached, the entry should be deleted.
   124  	for i := len(updatedEntry.ScanHistory); i < minScans; i++ {
   125  		hdbt.hdb.updateEntry(entry2, someErr)
   126  	}
   127  	// The entry should no longer exist in the hostdb, wiped for being offline.
   128  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry2.PublicKey)
   129  	if exists {
   130  		t.Fatal("entry should have been purged for being offline for too long")
   131  	}
   132  
   133  	// Trigger compression on entry1 by adding a past scan and then adding
   134  	// unsuccessful scans until compression happens.
   135  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
   136  	if !exists {
   137  		t.Fatal("Entry did not get inserted into the host tree")
   138  	}
   139  	updatedEntry.ScanHistory = append([]modules.HostDBScan{{Timestamp: time.Now().Add(maxHostDowntime * -1).Add(time.Hour * -1)}}, updatedEntry.ScanHistory...)
   140  	err = hdbt.hdb.hostTree.Modify(updatedEntry)
   141  	if err != nil {
   142  		t.Fatal(err)
   143  	}
   144  	for i := len(updatedEntry.ScanHistory); i <= minScans; i++ {
   145  		hdbt.hdb.updateEntry(entry1, someErr)
   146  	}
   147  	// The result should be compression, and not the entry getting deleted.
   148  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
   149  	if !exists {
   150  		t.Fatal("entry should not have been purged for being offline for too long")
   151  	}
   152  	if len(updatedEntry.ScanHistory) != minScans {
   153  		t.Error("expecting a different number of scans", len(updatedEntry.ScanHistory))
   154  	}
   155  	if updatedEntry.HistoricDowntime == 0 {
   156  		t.Error("host reporting historic downtime?")
   157  	}
   158  	if updatedEntry.HistoricUptime != 0 {
   159  		t.Error("host not reporting historic uptime?")
   160  	}
   161  
   162  	// Repeat triggering compression, but with uptime this time.
   163  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
   164  	if !exists {
   165  		t.Fatal("Entry did not get inserted into the host tree")
   166  	}
   167  	updatedEntry.ScanHistory = append([]modules.HostDBScan{{Success: true, Timestamp: time.Now().Add(time.Hour * 24 * 11 * -1)}}, updatedEntry.ScanHistory...)
   168  	err = hdbt.hdb.hostTree.Modify(updatedEntry)
   169  	if err != nil {
   170  		t.Fatal(err)
   171  	}
   172  	hdbt.hdb.updateEntry(entry1, someErr)
   173  	// The result should be compression, and not the entry getting deleted.
   174  	updatedEntry, exists = hdbt.hdb.hostTree.Select(entry1.PublicKey)
   175  	if !exists {
   176  		t.Fatal("entry should not have been purged for being offline for too long")
   177  	}
   178  	if len(updatedEntry.ScanHistory) != minScans+1 {
   179  		t.Error("expecting a different number of scans")
   180  	}
   181  	if updatedEntry.HistoricUptime == 0 {
   182  		t.Error("host not reporting historic uptime?")
   183  	}
   184  }
   185  
   186  // TestFeeChangeSignificant is a unit test for the feeChangeSignificant
   187  // function.
   188  func TestFeeChangeSignificant(t *testing.T) {
   189  	// If the difference is exactly txnFeesUpdateRatio it is significant.
   190  	n1 := uint64(100)
   191  	n2 := uint64(100 * (1 + txnFeesUpdateRatio))
   192  	s := feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   193  	if !s {
   194  		t.Fatalf("should be significant but wasn't")
   195  	}
   196  	n1 = uint64(100)
   197  	n2 = uint64(100 * (1 - txnFeesUpdateRatio))
   198  	s = feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   199  	if !s {
   200  		t.Fatalf("should be significant but wasn't")
   201  	}
   202  	// If the difference is bigger than txnFeesUpdateRatio it is significant.
   203  	n1 = uint64(100)
   204  	n2 = uint64(100*(1+txnFeesUpdateRatio) + 1)
   205  	s = feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   206  	if !s {
   207  		t.Fatalf("should be significant but wasn't")
   208  	}
   209  	n1 = uint64(100)
   210  	n2 = uint64(100*(1-txnFeesUpdateRatio) - 1)
   211  	s = feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   212  	if !s {
   213  		t.Fatalf("should be significant but wasn't")
   214  	}
   215  	// If the difference is a bit less then it shouldn't be significant.
   216  	n1 = uint64(100)
   217  	n2 = uint64(100*(1+txnFeesUpdateRatio) - 1)
   218  	s = feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   219  	if s {
   220  		t.Fatalf("shouldn't be significant but was")
   221  	}
   222  	n1 = uint64(100)
   223  	n2 = uint64(100*(1-txnFeesUpdateRatio) + 1)
   224  	s = feeChangeSignificant(types.NewCurrency64(n1), types.NewCurrency64(n2))
   225  	if s {
   226  		t.Fatalf("shouldn't be significant but was")
   227  	}
   228  }