github.com/nebulouslabs/sia@v1.3.7/modules/renter/hostdb/scan_test.go (about) 1 package hostdb 2 3 import ( 4 "errors" 5 "testing" 6 "time" 7 8 "github.com/NebulousLabs/Sia/modules" 9 "github.com/NebulousLabs/Sia/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 }