gitlab.com/SiaPrime/SiaPrime@v1.4.1/modules/host/contractmanager/persist_test.go (about) 1 package contractmanager 2 3 import ( 4 "bytes" 5 "os" 6 "path/filepath" 7 "sync" 8 "testing" 9 "time" 10 11 "gitlab.com/SiaPrime/SiaPrime/crypto" 12 "gitlab.com/SiaPrime/SiaPrime/modules" 13 ) 14 15 // dependencyNoRecheck prevents the recheck loop from running in the contract 16 // manager. 17 type dependencyNoRecheck struct { 18 modules.ProductionDependencies 19 } 20 21 // disrupt prevents the recheck loop from running in the contract manager. 22 func (*dependencyNoRecheck) Disrupt(s string) bool { 23 if s == "noRecheck" { 24 return true 25 } 26 return false 27 } 28 29 // TestLoadMissingStorageFolder checks that loading a storage folder which is 30 // missing doesn't result in a complete loss of the storage folder on subsequent 31 // startups. 32 func TestLoadMissingStorageFolder(t *testing.T) { 33 if testing.Short() { 34 t.SkipNow() 35 } 36 t.Parallel() 37 cmt, err := newContractManagerTester(t.Name()) 38 if err != nil { 39 t.Fatal(err) 40 } 41 defer cmt.panicClose() 42 43 // Add a storage folder to the contract manager tester. 44 storageFolderDir := filepath.Join(cmt.persistDir, "storageFolderOne") 45 // Create the storage folder dir. 46 err = os.MkdirAll(storageFolderDir, 0700) 47 if err != nil { 48 t.Fatal(err) 49 } 50 err = cmt.cm.AddStorageFolder(storageFolderDir, modules.SectorSize*storageFolderGranularity*2) 51 if err != nil { 52 t.Fatal(err) 53 } 54 55 // Check that the storage folder has been added. 56 sfs := cmt.cm.StorageFolders() 57 if len(sfs) != 1 { 58 t.Fatal("There should be one storage folder reported") 59 } 60 // Check that the storage folder has the right path and size. 61 if sfs[0].Path != storageFolderDir { 62 t.Error("storage folder reported with wrong path") 63 } 64 if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 { 65 t.Error("storage folder reported with wrong sector size") 66 } 67 68 // Add a sector to the storage folder. 69 root, data := randSector() 70 err = cmt.cm.AddSector(root, data) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 // Check that the sector was successfully added. 76 sfs = cmt.cm.StorageFolders() 77 if len(sfs) != 1 { 78 t.Fatal("There should be one storage folder in the contract manager", len(sfs)) 79 } 80 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize { 81 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 82 } 83 sfOneIndex := sfs[0].Index 84 85 // Try reloading the contract manager after the storage folder has been 86 // moved somewhere else. 87 err = cmt.cm.Close() 88 if err != nil { 89 t.Fatal(err) 90 } 91 // Move the storage folder directory to a new location - hiding it from the 92 // contract manager. 93 err = os.Rename(storageFolderDir, storageFolderDir+"-moved") 94 if err != nil { 95 t.Fatal(err) 96 } 97 // Re-open the contract manager. 98 d := new(dependencyNoRecheck) 99 cmt.cm, err = newContractManager(d, filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 100 if err != nil { 101 t.Fatal(err) 102 } 103 // The contract manager should still be reporting the storage folder, but 104 // with errors reported. 105 sfs = cmt.cm.StorageFolders() 106 if len(sfs) != 1 { 107 t.Fatal("wrong number of storage folders being reported") 108 } 109 if sfs[0].FailedReads < 100000000 { 110 t.Error("Not enough failures reported for absent storage folder") 111 } 112 if sfs[0].FailedWrites < 100000000 { 113 t.Error("Not enough failures reported for absent storage folder") 114 } 115 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize { 116 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 117 } 118 119 // Reload the contract manager and make sure the storage folder is still 120 // there. 121 err = cmt.cm.Close() 122 if err != nil { 123 t.Fatal(err) 124 } 125 // Re-open the contract manager. 126 cmt.cm, err = newContractManager(d, filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 127 if err != nil { 128 t.Fatal(err) 129 } 130 // The contract manager should still be reporting the storage folder with 131 // errors. 132 sfs = cmt.cm.StorageFolders() 133 if len(sfs) != 1 { 134 t.Fatal("wrong number of storage folders being reported") 135 } 136 if sfs[0].FailedReads < 100000000 { 137 t.Error("Not enough failures reported for absent storage folder") 138 } 139 if sfs[0].FailedWrites < 100000000 { 140 t.Error("Not enough failures reported for absent storage folder") 141 } 142 143 // Try reading the sector from the missing storage folder. 144 _, err = cmt.cm.ReadSector(root) 145 if err == nil { 146 t.Fatal("Expecting error when reading missing sector.") 147 } 148 149 // Try adding a sector to the contract manager - no folder can receive it. 150 rootF, dataF := randSector() 151 err = cmt.cm.AddSector(rootF, dataF) 152 if err == nil { 153 t.Error("should not be able to add sector") 154 } 155 156 // Check that you can add folders, add sectors while the contract manager 157 // correctly works around the missing storage folder. 158 storageFolderTwo := filepath.Join(cmt.persistDir, "storageFolderTwo") 159 err = os.MkdirAll(storageFolderTwo, 0700) 160 if err != nil { 161 t.Fatal(err) 162 } 163 err = cmt.cm.AddStorageFolder(storageFolderTwo, modules.SectorSize*storageFolderGranularity*2) 164 if err != nil { 165 t.Fatal(err) 166 } 167 // Add a sector to the storage folder. 168 root2, data2 := randSector() 169 err = cmt.cm.AddSector(root2, data2) 170 if err != nil { 171 t.Fatal(err) 172 } 173 // Check that the sector was successfully added. 174 sfs = cmt.cm.StorageFolders() 175 if len(sfs) != 2 { 176 t.Fatal("There should be one storage folder in the contract manager", len(sfs)) 177 } 178 for i := range sfs { 179 if sfs[i].Capacity != sfs[i].CapacityRemaining+modules.SectorSize { 180 t.Error("One sector's worth of capacity should be consumed:", sfs[i].Capacity, sfs[i].CapacityRemaining, sfs[i].Path) 181 } 182 } 183 var sfTwoIndex uint16 184 if sfs[0].Index == sfOneIndex { 185 sfTwoIndex = sfs[1].Index 186 } else { 187 sfTwoIndex = sfs[0].Index 188 } 189 190 // Add two more sectors. 191 root3, data3 := randSector() 192 err = cmt.cm.AddSector(root3, data3) 193 if err != nil { 194 t.Fatal(err) 195 } 196 root4, data4 := randSector() 197 err = cmt.cm.AddSector(root4, data4) 198 if err != nil { 199 t.Fatal(err) 200 } 201 // Check that the sector was successfully added. 202 sfs = cmt.cm.StorageFolders() 203 if len(sfs) != 2 { 204 t.Fatal("There should be one storage folder in the contract manager", len(sfs)) 205 } 206 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize*3 && sfs[1].Capacity != sfs[1].CapacityRemaining+modules.SectorSize*3 { 207 t.Error("One sector's worth of capacity should be consumed") 208 } 209 210 // Try to shrink the missing storage folder. 211 err = cmt.cm.ResizeStorageFolder(sfOneIndex, modules.SectorSize*storageFolderGranularity, false) 212 if err == nil { 213 t.Fatal("should not be able to resize a missing storage folder") 214 } 215 err = cmt.cm.ResizeStorageFolder(sfOneIndex, modules.SectorSize*storageFolderGranularity, true) 216 if err == nil { 217 t.Fatal("should not be able to resize a missing storage folder") 218 } 219 220 // Check that the storage folder is still the original size. 221 sfs = cmt.cm.StorageFolders() 222 if len(sfs) != 2 { 223 t.Fatal("wrong storage folder count") 224 } 225 if sfs[0].Index == sfOneIndex && sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 { 226 t.Error("Storage folder has wrong size after failing to resize") 227 } 228 if sfs[1].Index == sfOneIndex && sfs[1].Capacity != modules.SectorSize*storageFolderGranularity*2 { 229 t.Error("Storage folder has wrong size after failing to resize") 230 } 231 232 // Try to grow the missing storage folder. 233 err = cmt.cm.ResizeStorageFolder(sfOneIndex, modules.SectorSize*storageFolderGranularity*4, false) 234 if err == nil { 235 t.Fatal("should not be able to resize a missing storage folder") 236 } 237 err = cmt.cm.ResizeStorageFolder(sfOneIndex, modules.SectorSize*storageFolderGranularity*4, true) 238 if err == nil { 239 t.Fatal("should not be able to resize a missing storage folder") 240 } 241 242 // Check that the storage folder is still the original size. 243 sfs = cmt.cm.StorageFolders() 244 if len(sfs) != 2 { 245 t.Fatal("wrong storage folder count") 246 } 247 if sfs[0].Index == sfOneIndex && sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 { 248 t.Error("Storage folder has wrong size after failing to resize") 249 } 250 if sfs[1].Index == sfOneIndex && sfs[1].Capacity != modules.SectorSize*storageFolderGranularity*2 { 251 t.Error("Storage folder has wrong size after failing to resize") 252 } 253 254 // Check that you can delete sectors and have the contract manager work 255 // correctly around the missing storage folder. 256 err = cmt.cm.DeleteSector(root2) 257 if err != nil { 258 t.Fatal(err) 259 } 260 err = cmt.cm.DeleteSector(root3) 261 if err != nil { 262 t.Fatal(err) 263 } 264 err = cmt.cm.DeleteSector(root4) 265 if err != nil { 266 t.Fatal(err) 267 } 268 // Check that the sectors are no longer reported. 269 sfs = cmt.cm.StorageFolders() 270 if len(sfs) != 2 { 271 t.Fatal("There should be one storage folder in the contract manager", len(sfs)) 272 } 273 if sfs[0].Capacity != sfs[0].CapacityRemaining && sfs[1].Capacity != sfs[1].CapacityRemaining { 274 t.Error("Deleted sector does not seem to have been deleted correctly.") 275 } 276 // Try reading the deleted sector. 277 _, err = cmt.cm.ReadSector(root2) 278 if err == nil { 279 t.Fatal("should get an error when reading a deleted sector") 280 } 281 282 // Check that it's okay to shrink a storage folder while missing a storage 283 // folder. 284 // 285 // Start by resizing the second storage folder so it can hold a lot of 286 // sectors. 287 err = cmt.cm.ResizeStorageFolder(sfTwoIndex, modules.SectorSize*storageFolderGranularity*4, false) 288 if err != nil { 289 t.Fatal(err) 290 } 291 // Add enough sectors to the storage folder that doing a shrink operation 292 // causes sectors to be moved around. 293 num := int(storageFolderGranularity*3 + 2) 294 roots := make([]crypto.Hash, num) 295 datas := make([][]byte, num) 296 var wg sync.WaitGroup // Add in parallel to get massive performance boost. 297 for i := 0; i < num; i++ { 298 wg.Add(1) 299 go func(i int) { 300 defer wg.Done() 301 rootI, dataI := randSector() 302 roots[i] = rootI 303 datas[i] = dataI 304 err := cmt.cm.AddSector(rootI, dataI) 305 if err != nil { 306 t.Fatal(err) 307 } 308 }(i) 309 } 310 wg.Wait() 311 // Make a new storage folder so the sectors have somewhere to go. 312 storageFolderThree := filepath.Join(cmt.persistDir, "storageFolderThree") 313 err = os.MkdirAll(storageFolderThree, 0700) 314 if err != nil { 315 t.Fatal(err) 316 } 317 err = cmt.cm.AddStorageFolder(storageFolderThree, modules.SectorSize*storageFolderGranularity) 318 if err != nil { 319 t.Fatal(err) 320 } 321 // Shrink the second storage folder such that some of the sectors are forced 322 // to move. 323 err = cmt.cm.ResizeStorageFolder(sfTwoIndex, modules.SectorSize*storageFolderGranularity*3, false) 324 if err != nil { 325 t.Fatal(err) 326 } 327 // Check that all of the sectors are still recoverable. 328 for i := range roots { 329 data, err := cmt.cm.ReadSector(roots[i]) 330 if err != nil { 331 t.Fatal(err) 332 } 333 if !bytes.Equal(data, datas[i]) { 334 t.Error("read sector does not have the same data that was inserted") 335 } 336 } 337 338 // Shrink the second storage folder again, such that there is not enough 339 // room in the available storage folders to accept the data. 340 err = cmt.cm.ResizeStorageFolder(sfTwoIndex, modules.SectorSize*storageFolderGranularity*2, false) 341 if err == nil { 342 t.Fatal("expected an error") 343 } 344 // Check that all of the sectors are still recoverable. 345 for i := range roots { 346 data, err := cmt.cm.ReadSector(roots[i]) 347 if err != nil { 348 t.Fatal(err) 349 } 350 if !bytes.Equal(data, datas[i]) { 351 t.Error("read sector does not have the same data that was inserted") 352 } 353 } 354 355 // Shrink the second storage folder again, such that there is not enough 356 // room in the available storage folders to accept the data. 357 err = cmt.cm.ResizeStorageFolder(sfTwoIndex, modules.SectorSize*storageFolderGranularity, true) 358 if err != nil { 359 t.Fatal(err) 360 } 361 // There is now data loss. 362 363 // Try deleting the second storage folder, which again will cause data loss. 364 err = cmt.cm.RemoveStorageFolder(sfTwoIndex, false) 365 if err == nil { 366 t.Fatal("should have gotten an error when trying to remove the storage folder.") 367 } 368 err = cmt.cm.RemoveStorageFolder(sfTwoIndex, true) 369 if err != nil { 370 t.Fatal(err) 371 } 372 373 // Try to recover the missing storage folder by closing and moving the 374 // storage folder to the right place. 375 err = cmt.cm.Close() 376 if err != nil { 377 t.Fatal(err) 378 } 379 err = os.Rename(storageFolderDir+"-moved", storageFolderDir) 380 if err != nil { 381 t.Fatal(err) 382 } 383 // Re-open the contract manager. 384 cmt.cm, err = newContractManager(d, filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 385 if err != nil { 386 t.Fatal(err) 387 } 388 // The contract manager should still be reporting the storage folder, but 389 // with errors reported. 390 sfs = cmt.cm.StorageFolders() 391 if len(sfs) != 2 { 392 t.Fatal("wrong number of storage folders being reported") 393 } 394 var sfOne modules.StorageFolderMetadata 395 for _, sf := range sfs { 396 if sf.Index == sfOneIndex { 397 sfOne = sf 398 } 399 } 400 if sfOne.FailedReads > 0 { 401 t.Error("folder should be visible again") 402 } 403 if sfOne.FailedWrites > 0 { 404 t.Error("folder should be visible again") 405 } 406 if sfOne.Capacity != sfOne.CapacityRemaining+modules.SectorSize { 407 cmt.cm.wal.mu.Lock() 408 t.Log("Usage len:", len(cmt.cm.storageFolders[sfOne.Index].usage)) 409 t.Log("Reported Sectors:", cmt.cm.storageFolders[sfOne.Index].sectors) 410 t.Log("Avail:", len(cmt.cm.storageFolders[sfOne.Index].availableSectors)) 411 cmt.cm.wal.mu.Unlock() 412 t.Error("One sector's worth of capacity should be consumed:", sfOne.Capacity, sfOne.CapacityRemaining) 413 } 414 415 // See if the sector is still available. 416 recoveredData, err := cmt.cm.ReadSector(root) 417 if err != nil { 418 t.Fatal(err) 419 } 420 if !bytes.Equal(recoveredData, data) { 421 t.Error("recovered data is not equal to original data") 422 } 423 424 // Redo the storage folder move, so we can test deleting a missing storage 425 // folder. 426 err = cmt.cm.Close() 427 if err != nil { 428 t.Fatal(err) 429 } 430 // Move the storage folder directory to a new location - hiding it from the 431 // contract manager. 432 err = os.Rename(storageFolderDir, storageFolderDir+"-moved") 433 if err != nil { 434 t.Fatal(err) 435 } 436 // Re-open the contract manager. 437 cmt.cm, err = newContractManager(d, filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 438 if err != nil { 439 t.Fatal(err) 440 } 441 442 // Try removing the storage folder without the --force option. It should 443 // fail. 444 err = cmt.cm.RemoveStorageFolder(sfOneIndex, false) 445 if err == nil { 446 t.Fatal("should have gotten an error") 447 } 448 sfs = cmt.cm.StorageFolders() 449 if len(sfs) != 2 { 450 t.Error("there should be two storage folders after a removal failed.") 451 } 452 err = cmt.cm.RemoveStorageFolder(sfOneIndex, true) 453 if err != nil { 454 t.Fatal(err) 455 } 456 sfs = cmt.cm.StorageFolders() 457 if len(sfs) != 1 { 458 t.Error("there should be only one storage folder remaining") 459 } 460 461 // Close and re-open the contract maanger, storage folder should still be 462 // missing. 463 err = cmt.cm.Close() 464 if err != nil { 465 t.Fatal(err) 466 } 467 // Re-open the contract manager. 468 cmt.cm, err = newContractManager(d, filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 469 if err != nil { 470 t.Fatal(err) 471 } 472 sfs = cmt.cm.StorageFolders() 473 if len(sfs) != 1 { 474 t.Error("there should be only one storage folder remaining") 475 } 476 } 477 478 // TestFolderRechecker verifies that the folder rechecker is able to discover 479 // when a storage folder has become available again. 480 func TestFolderRechecker(t *testing.T) { 481 if testing.Short() { 482 t.SkipNow() 483 } 484 t.Parallel() 485 cmt, err := newContractManagerTester(t.Name()) 486 if err != nil { 487 t.Fatal(err) 488 } 489 defer cmt.panicClose() 490 491 // Add a storage folder to the contract manager tester. 492 storageFolderDir := filepath.Join(cmt.persistDir, "storageFolderOne") 493 // Create the storage folder dir. 494 err = os.MkdirAll(storageFolderDir, 0700) 495 if err != nil { 496 t.Fatal(err) 497 } 498 err = cmt.cm.AddStorageFolder(storageFolderDir, modules.SectorSize*storageFolderGranularity*2) 499 if err != nil { 500 t.Fatal(err) 501 } 502 503 // Check that the storage folder has been added. 504 sfs := cmt.cm.StorageFolders() 505 if len(sfs) != 1 { 506 t.Fatal("There should be one storage folder reported") 507 } 508 // Check that the storage folder has the right path and size. 509 if sfs[0].Path != storageFolderDir { 510 t.Error("storage folder reported with wrong path") 511 } 512 if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*2 { 513 t.Error("storage folder reported with wrong sector size") 514 } 515 516 // Add a sector to the storage folder. 517 root, data := randSector() 518 err = cmt.cm.AddSector(root, data) 519 if err != nil { 520 t.Fatal(err) 521 } 522 523 // Check that the sector was successfully added. 524 sfs = cmt.cm.StorageFolders() 525 if len(sfs) != 1 { 526 t.Fatal("There should be one storage folder in the contract manager", len(sfs)) 527 } 528 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize { 529 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 530 } 531 532 // Try reloading the contract manager after the storage folder has been 533 // moved somewhere else. 534 err = cmt.cm.Close() 535 if err != nil { 536 t.Fatal(err) 537 } 538 // Move the storage folder directory to a new location - hiding it from the 539 // contract manager. 540 err = os.Rename(storageFolderDir, storageFolderDir+"-moved") 541 if err != nil { 542 t.Fatal(err) 543 } 544 // Re-open the contract manager. 545 cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 546 if err != nil { 547 t.Fatal(err) 548 } 549 // The contract manager should still be reporting the storage folder, but 550 // with errors reported. 551 sfs = cmt.cm.StorageFolders() 552 if len(sfs) != 1 { 553 t.Fatal("wrong number of storage folders being reported") 554 } 555 if sfs[0].FailedReads < 100000000 { 556 t.Error("Not enough failures reported for absent storage folder") 557 } 558 if sfs[0].FailedWrites < 100000000 { 559 t.Error("Not enough failures reported for absent storage folder") 560 } 561 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize { 562 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 563 } 564 565 // Move the storage folder back to where the contract manager can see it. 566 err = os.Rename(storageFolderDir+"-moved", storageFolderDir) 567 if err != nil { 568 t.Fatal(err) 569 } 570 571 // Sleep until the rechecker can find the storage folder. 572 time.Sleep(maxFolderRecheckInterval) 573 574 // Check that the storage folder has been found by the rechecker. 575 sfs = cmt.cm.StorageFolders() 576 if len(sfs) != 1 { 577 t.Fatal("wrong number of storage folders being reported") 578 } 579 if sfs[0].FailedReads != 0 { 580 t.Error("Not enough failures reported for absent storage folder") 581 } 582 if sfs[0].FailedWrites != 0 { 583 t.Error("Not enough failures reported for absent storage folder") 584 } 585 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize { 586 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 587 } 588 589 // Check that the sector is once again available. 590 recoveredData, err := cmt.cm.ReadSector(root) 591 if err != nil { 592 t.Fatal(err) 593 } 594 if !bytes.Equal(recoveredData, data) { 595 t.Error("recovered data does not equal original data") 596 } 597 598 // Try adding a sector to the contract manager - no folder can receive it. 599 root2, data2 := randSector() 600 err = cmt.cm.AddSector(root2, data2) 601 if err != nil { 602 t.Error("should not be able to add sector") 603 } 604 recoveredData, err = cmt.cm.ReadSector(root2) 605 if err != nil { 606 t.Fatal(err) 607 } 608 if !bytes.Equal(recoveredData, data2) { 609 t.Error("recovered data does not equal original data") 610 } 611 612 // Grow the storage folder. 613 err = cmt.cm.ResizeStorageFolder(sfs[0].Index, modules.SectorSize*storageFolderGranularity*4, false) 614 if err != nil { 615 t.Fatal(err) 616 } 617 sfs = cmt.cm.StorageFolders() 618 if len(sfs) != 1 { 619 t.Fatal("wrong number of storage folders being reported") 620 } 621 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize*2 { 622 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 623 } 624 if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*4 { 625 t.Error("the storage folder growth does not seem to have worked") 626 } 627 628 // Restart the client. Sector should still be readable, storage folder 629 // should still be grown. 630 err = cmt.cm.Close() 631 if err != nil { 632 t.Fatal(err) 633 } 634 cmt.cm, err = New(filepath.Join(cmt.persistDir, modules.ContractManagerDir)) 635 if err != nil { 636 t.Fatal(err) 637 } 638 // Check that the sector is once again available. 639 recoveredData, err = cmt.cm.ReadSector(root) 640 if err != nil { 641 t.Fatal(err) 642 } 643 if !bytes.Equal(recoveredData, data) { 644 t.Error("recovered data does not equal original data") 645 } 646 sfs = cmt.cm.StorageFolders() 647 if len(sfs) != 1 { 648 t.Fatal("wrong number of storage folders being reported") 649 } 650 if sfs[0].Capacity != sfs[0].CapacityRemaining+modules.SectorSize*2 { 651 t.Error("One sector's worth of capacity should be consumed:", sfs[0].Capacity, sfs[0].CapacityRemaining) 652 } 653 if sfs[0].Capacity != modules.SectorSize*storageFolderGranularity*4 { 654 t.Error("the storage folder growth does not seem to have worked") 655 } 656 }