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 }