From 2f746639cd707600f2c34d5e7745fa388a505344 Mon Sep 17 00:00:00 2001 From: Matthew Sevey Date: Fri, 13 Jul 2018 15:10:13 -0400 Subject: [PATCH] Debug siatest --- modules/renter/contractor/contractor.go | 6 +- modules/renter/contractor/contracts.go | 5 + node/api/client/renter.go | 6 +- node/api/renter.go | 6 +- node/api/routes.go | 2 +- siatest/renter/renter_test.go | 141 ++++++++++++++++-------- 6 files changed, 107 insertions(+), 59 deletions(-) diff --git a/modules/renter/contractor/contractor.go b/modules/renter/contractor/contractor.go index 4be06c69c4..7d79b92dcd 100644 --- a/modules/renter/contractor/contractor.go +++ b/modules/renter/contractor/contractor.go @@ -155,11 +155,11 @@ func (c *Contractor) ContractByPublicKey(pk types.SiaPublicKey) (modules.RenterC // CancelContract cancels the Contractor's contract by marking it !GoodForRenew // and !GoodForUpload func (c *Contractor) CancelContract(id types.FileContractID) error { - u := modules.ContractUtility{ + return c.managedUpdateContractUtility(id, modules.ContractUtility{ GoodForRenew: false, GoodForUpload: false, - } - return c.managedUpdateContractUtility(id, u) + Locked: true, + }) } // Contracts returns the contracts formed by the contractor in the current diff --git a/modules/renter/contractor/contracts.go b/modules/renter/contractor/contracts.go index 2a2685f1b5..db82982182 100644 --- a/modules/renter/contractor/contracts.go +++ b/modules/renter/contractor/contracts.go @@ -96,6 +96,11 @@ func (c *Contractor) managedMarkContractsUtility() error { // Update utility fields for each contract. for _, contract := range c.staticContracts.ViewAll() { utility := func() (u modules.ContractUtility) { + // Record current utility of the contract + u.GoodForRenew = contract.Utility.GoodForRenew + u.GoodForUpload = contract.Utility.GoodForUpload + u.Locked = contract.Utility.Locked + // Start the contract in good standing if the utility wasn't // locked. if !u.Locked { diff --git a/node/api/client/renter.go b/node/api/client/renter.go index 50eb37e4ca..80d8ab9c87 100644 --- a/node/api/client/renter.go +++ b/node/api/client/renter.go @@ -12,12 +12,12 @@ import ( "github.com/NebulousLabs/Sia/types" ) -// RenterCancelContractPost uses the /renter/cancel/contract endpoint to cancel +// RenterContractCancelPost uses the /renter/contract/cancel endpoint to cancel // a contract -func (c *Client) RenterCancelContractPost(id types.FileContractID) error { +func (c *Client) RenterContractCancelPost(id types.FileContractID) error { values := url.Values{} values.Set("id", id.String()) - err := c.post("/renter/cancel/contract", values.Encode(), nil) + err := c.post("/renter/contract/cancel", values.Encode(), nil) return err } diff --git a/node/api/renter.go b/node/api/renter.go index a13aa337b9..ac0ebf2c2a 100644 --- a/node/api/renter.go +++ b/node/api/renter.go @@ -275,10 +275,10 @@ func (api *API) renterHandlerPOST(w http.ResponseWriter, req *http.Request, _ ht WriteSuccess(w) } -// renterContractClearHandler handles the API call to cancel a specific Renter contract. -func (api *API) renterContractClearHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { +// renterContractCancelHandler handles the API call to cancel a specific Renter contract. +func (api *API) renterContractCancelHandler(w http.ResponseWriter, req *http.Request, _ httprouter.Params) { var fcid types.FileContractID - if err := fcid.LoadString(req.FormValue("ID")); err != nil { + if err := fcid.LoadString(req.FormValue("id")); err != nil { return } err := api.renter.CancelContract(fcid) diff --git a/node/api/routes.go b/node/api/routes.go index ad0a30f87e..8419a3e78d 100644 --- a/node/api/routes.go +++ b/node/api/routes.go @@ -69,7 +69,7 @@ func (api *API) buildHTTPRoutes(requiredUserAgent string, requiredPassword strin if api.renter != nil { router.GET("/renter", api.renterHandlerGET) router.POST("/renter", RequirePassword(api.renterHandlerPOST, requiredPassword)) - router.GET("/renter/contract/cancel", api.renterContractClearHandler) + router.POST("/renter/contract/cancel", RequirePassword(api.renterContractCancelHandler, requiredPassword)) router.GET("/renter/contracts", api.renterContractsHandler) router.GET("/renter/downloads", api.renterDownloadsHandler) router.POST("/renter/downloads/clear", RequirePassword(api.renterClearDownloadsHandler, requiredPassword)) diff --git a/siatest/renter/renter_test.go b/siatest/renter/renter_test.go index 2afd9fd327..b8c022ff33 100644 --- a/siatest/renter/renter_test.go +++ b/siatest/renter/renter_test.go @@ -57,7 +57,6 @@ func TestRenter(t *testing.T) { name string test func(*testing.T, *siatest.TestGroup) }{ - {"TestCancelContract", testCancelContract}, {"TestClearDownloadHistory", testClearDownloadHistory}, {"TestDownloadAfterRenew", testDownloadAfterRenew}, {"TestDownloadMultipleLargeSectors", testDownloadMultipleLargeSectors}, @@ -75,54 +74,6 @@ func TestRenter(t *testing.T) { } } -// testCancelContract tests the RenterCancelContract Endpoint -func testCancelContract(t *testing.T, tg *siatest.TestGroup) { - // Grab the first of the group's renters - r := tg.Renters()[0] - - // Grab contracts - rc, err := r.RenterContractsGet() - if err != nil { - t.Fatal(err) - } - - // Grab contract to cancel - contract := rc.ActiveContracts[0] - - // Cancel Contract - if err := r.RenterCancelContractPost(contract.ID); err != nil { - t.Fatal(err) - } - - // Mine block to trigger threadedContractMaintenance - m := tg.Miners()[0] - if err := m.MineBlock(); err != nil { - t.Fatal(err) - } - tg.Sync() - - // Check that Contract is now in inactive contracts and no longer in Active contracts - rc, err = r.RenterInactiveContractsGet() - if err != nil { - t.Fatal(err) - } - for _, c := range rc.ActiveContracts { - if c.ID == contract.ID { - t.Fatal("Contract not cancelled, contract found in Active Contracts") - } - } - i := 1 - for _, c := range rc.InactiveContracts { - if c.ID == contract.ID { - break - } - if i == len(rc.InactiveContracts) { - t.Fatal("Contract not found in Inactive Contracts") - } - i++ - } -} - // testClearDownloadHistory makes sure that the download history is // properly cleared when called through the API func testClearDownloadHistory(t *testing.T, tg *siatest.TestGroup) { @@ -1263,6 +1214,98 @@ func TestRenterCancelAllowance(t *testing.T) { } } +// TestRenterCancelContract tests the RenterCancelContract Endpoint +func TestRenterCancelContract(t *testing.T) { + if testing.Short() { + t.SkipNow() + } + t.Parallel() + + // Create a group for testing. + groupParams := siatest.GroupParams{ + Hosts: 2, + Renters: 1, + Miners: 1, + } + tg, err := siatest.NewGroupFromTemplate(groupParams) + if err != nil { + t.Fatal("Failed to create group: ", err) + } + defer func() { + if err := tg.Close(); err != nil { + t.Fatal(err) + } + }() + + // Grab the first of the group's renters + r := tg.Renters()[0] + + // Grab contracts + rc, err := r.RenterContractsGet() + if err != nil { + t.Fatal(err) + } + + // Grab contract to cancel + contract := rc.ActiveContracts[0] + + // Cancel Contract + if err := r.RenterContractCancelPost(contract.ID); err != nil { + t.Fatal(err) + } + + // Add a new host so new contract can be formed + hostDir, err := siatest.TestDir(filepath.Join(t.Name(), "host")) + if err != nil { + t.Fatal(err) + } + hostParams := node.Host(hostDir) + _, err = tg.AddNodes(hostParams) + if err != nil { + t.Fatal(err) + } + + // Mine block to trigger threadedContractMaintenance + m := tg.Miners()[0] + if err := m.MineBlock(); err != nil { + t.Fatal(err) + } + if err := tg.Sync(); err != nil { + t.Fatal(err) + } + + err = build.Retry(200, 100*time.Millisecond, func() error { + // Check that Contract is now in inactive contracts and no longer in Active contracts + rc, err = r.RenterInactiveContractsGet() + if err != nil { + t.Fatal(err) + } + // Confirm Renter has the expected number of contracts, meaning canceled contract should have been replaced. + if len(rc.ActiveContracts) != len(tg.Hosts())-1 { + return fmt.Errorf("Canceled contract was not replaced, only %v active contracts, expected %v", len(rc.ActiveContracts), len(tg.Hosts())) + } + for _, c := range rc.ActiveContracts { + if c.ID == contract.ID { + return errors.New("Contract not cancelled, contract found in Active Contracts") + } + } + i := 1 + for _, c := range rc.InactiveContracts { + if c.ID == contract.ID { + break + } + if i == len(rc.InactiveContracts) { + return errors.New("Contract not found in Inactive Contracts") + } + i++ + } + return nil + }) + if err != nil { + t.Fatal(err) + } +} + // TestRenterContractEndHeight makes sure that the endheight of renewed // contracts is set properly func TestRenterContractEndHeight(t *testing.T) {