gitlab.com/SkynetLabs/skyd@v1.6.9/skymodules/renter/workermaintenance_test.go (about) 1 package renter 2 3 import ( 4 "context" 5 "fmt" 6 "math" 7 "testing" 8 "time" 9 10 "github.com/opentracing/opentracing-go" 11 "gitlab.com/SkynetLabs/skyd/build" 12 "gitlab.com/SkynetLabs/skyd/siatest/dependencies" 13 "gitlab.com/SkynetLabs/skyd/skymodules" 14 "go.sia.tech/siad/crypto" 15 "go.sia.tech/siad/modules" 16 "go.sia.tech/siad/types" 17 ) 18 19 // TestWorkerMaintenanceCoolDown verifies the functionality of the worker's 20 // cooldown of the RHP3 related subsystems. 21 func TestWorkerMaintenanceCoolDown(t *testing.T) { 22 if testing.Short() { 23 t.SkipNow() 24 } 25 t.Parallel() 26 27 wt, err := newWorkerTesterCustomDependency(t.Name(), &dependencies.DependencyDisableCriticalOnMaxBalance{}, modules.ProdDependencies) 28 if err != nil { 29 t.Fatal(err) 30 } 31 defer func() { 32 err := wt.Close() 33 if err != nil { 34 t.Fatal(err) 35 } 36 }() 37 w := wt.worker 38 39 // verify the worker is not on an maintenance cooldown 40 if w.managedOnMaintenanceCooldown() { 41 t.Fatal("Unexpected maintenance cooldown") 42 } 43 44 // set a negative balance, tricking the worker into thinking it has to 45 // refill 46 w.staticAccount.mu.Lock() 47 w.staticAccount.negativeBalance = w.staticAccount.balance 48 w.staticAccount.mu.Unlock() 49 50 // manually trigger a refill 51 w.managedRefillAccount() 52 53 // verify the worker has been put on maintenance cooldown 54 if !w.managedOnMaintenanceCooldown() { 55 t.Fatal("Expected maintenance cooldown") 56 } 57 58 // the workerloop should have synced the account balance 59 if err := build.Retry(200, 100*time.Millisecond, func() error { 60 w.staticAccount.mu.Lock() 61 defer w.staticAccount.mu.Unlock() 62 if !w.staticAccount.negativeBalance.IsZero() { 63 return fmt.Errorf("worker account balance not reset: %v", w.staticAccount.negativeBalance) 64 } 65 return nil 66 }); err != nil { 67 t.Fatal(err) 68 } 69 70 // create a ctx with test span 71 ctx := opentracing.ContextWithSpan(context.Background(), testSpan()) 72 73 // run a couple of has sector jobs to spend money 74 rc := make(chan *jobHasSectorResponse) 75 jhs := w.newJobHasSector(ctx, rc, skymodules.RenterDefaultNumPieces, crypto.Hash{}) 76 for i := 0; i < 100; i++ { 77 if !w.staticJobHasSectorQueue.callAdd(jhs) { 78 t.Fatal("could not add job to queue") 79 } 80 } 81 82 // manually trigger a refill 83 w.managedRefillAccount() 84 85 // verify the account is not on cooldown 86 if w.managedOnMaintenanceCooldown() { 87 t.Fatal("Worker's RHP3 subsystems should not be on cooldown") 88 } 89 } 90 91 // TestWorkerMaintenanceRefillLowContractFunds verifies that a contract with 92 // less remaining funds than the EA balance target can still be used to refill 93 // an EA. 94 func TestWorkerMaintenanceRefillLowContractFunds(t *testing.T) { 95 if testing.Short() { 96 t.SkipNow() 97 } 98 t.Parallel() 99 100 deps := &dependencies.DependencyDisableWorker{} 101 wt, err := newWorkerTesterCustomDependency(t.Name(), deps, modules.ProdDependencies) 102 if err != nil { 103 t.Fatal(err) 104 } 105 defer func() { 106 err := wt.Close() 107 if err != nil { 108 t.Fatal(err) 109 } 110 }() 111 112 // allow for a large balance on the host. 113 is := wt.host.InternalSettings() 114 is.MaxEphemeralAccountBalance = types.SiacoinPrecision.Mul64(math.MaxUint64) 115 err = wt.host.SetInternalSettings(is) 116 if err != nil { 117 t.Fatal(err) 118 } 119 120 w := wt.worker 121 r := w.staticRenter 122 123 // fetch a pricetable. 124 w.staticUpdatePriceTable() 125 126 // balance should be 0 right now. 127 w.staticAccount.mu.Lock() 128 accountBalance := w.staticAccount.balance 129 w.staticAccount.mu.Unlock() 130 if !accountBalance.IsZero() { 131 t.Fatal("balance should be zero at beginning of test") 132 } 133 134 // check remaining balance on contract. 135 contract, ok := r.staticHostContractor.ContractByPublicKey(wt.staticHostPubKey) 136 if !ok { 137 t.Fatal("contract not found") 138 } 139 funds := contract.RenterFunds 140 141 // set the target to the balance. 142 r.staticAccountBalanceTarget = funds 143 144 // trigger a refill. 145 w.managedRefillAccount() 146 147 // check if the balance increased. 148 w.staticAccount.mu.Lock() 149 accountBalance = w.staticAccount.balance 150 w.staticAccount.mu.Unlock() 151 expectedBalance := funds.Sub(wt.staticPriceTable().staticPriceTable.FundAccountCost) 152 if !accountBalance.Equals(expectedBalance) { 153 t.Fatalf("expected balance %v but got %v", accountBalance, expectedBalance) 154 } 155 }