Skip to content

Commit

Permalink
Move mocks from worker package into test/mocks package (#1666)
Browse files Browse the repository at this point in the history
This makes mocks usable for testing outside of the worker package which
is needed for moving the uploader out of the worker

It also moves bigger mocks to dedicated files
  • Loading branch information
ChrisSchinnerl authored Nov 13, 2024
1 parent 92ed015 commit e98388d
Show file tree
Hide file tree
Showing 11 changed files with 904 additions and 819 deletions.
45 changes: 45 additions & 0 deletions internal/test/mocks/contractlocker.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package mocks

import (
"context"
"sync"
"time"

"go.sia.tech/core/types"
)

type contractLockerMock struct {
mu sync.Mutex
locks map[types.FileContractID]*sync.Mutex
}

func newContractLockerMock() *contractLockerMock {
return &contractLockerMock{
locks: make(map[types.FileContractID]*sync.Mutex),
}
}

func (cs *contractLockerMock) AcquireContract(_ context.Context, fcid types.FileContractID, _ int, _ time.Duration) (uint64, error) {
cs.mu.Lock()
lock, exists := cs.locks[fcid]
if !exists {
cs.locks[fcid] = new(sync.Mutex)
lock = cs.locks[fcid]
}
cs.mu.Unlock()

lock.Lock()
return 0, nil
}

func (cs *contractLockerMock) ReleaseContract(_ context.Context, fcid types.FileContractID, _ uint64) error {
cs.mu.Lock()
defer cs.mu.Unlock()

cs.locks[fcid].Unlock()
return nil
}

func (*contractLockerMock) KeepaliveContract(context.Context, types.FileContractID, uint64, time.Duration) error {
return nil
}
153 changes: 153 additions & 0 deletions internal/test/mocks/contractstore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package mocks

import (
"context"
"errors"
"sync"

rhpv2 "go.sia.tech/core/rhp/v2"
"go.sia.tech/core/types"
"go.sia.tech/renterd/api"
)

type ContractStore struct {
mu sync.Mutex
contracts map[types.FileContractID]*Contract
hosts2fcid map[types.PublicKey]types.FileContractID
fcidCntr uint
}

func NewContractStore() *ContractStore {
return &ContractStore{
contracts: make(map[types.FileContractID]*Contract),
hosts2fcid: make(map[types.PublicKey]types.FileContractID),
}
}

func (cs *ContractStore) RenewedContract(ctx context.Context, fcid types.FileContractID) (api.ContractMetadata, error) {
return cs.Contract(ctx, fcid)
}

func (cs *ContractStore) Contract(_ context.Context, fcid types.FileContractID) (api.ContractMetadata, error) {
cs.mu.Lock()
defer cs.mu.Unlock()

contract, ok := cs.contracts[fcid]
if !ok {
return api.ContractMetadata{}, api.ErrContractNotFound
}
return contract.metadata, nil
}

func (*ContractStore) ContractSize(context.Context, types.FileContractID) (api.ContractSize, error) {
return api.ContractSize{}, nil
}

func (*ContractStore) ContractRoots(context.Context, types.FileContractID) ([]types.Hash256, error) {
return nil, nil
}

func (cs *ContractStore) Contracts(context.Context, api.ContractsOpts) (metadatas []api.ContractMetadata, _ error) {
cs.mu.Lock()
defer cs.mu.Unlock()
for _, c := range cs.contracts {
metadatas = append(metadatas, c.metadata)
}
return
}

func (cs *ContractStore) AddContract(hk types.PublicKey) *Contract {
cs.mu.Lock()
defer cs.mu.Unlock()

fcid := cs.newFileContractID()
cs.contracts[fcid] = NewContract(hk, fcid)
cs.hosts2fcid[hk] = fcid
return cs.contracts[fcid]
}

func (cs *ContractStore) DeleteContracdt(fcid types.FileContractID) {
cs.mu.Lock()
defer cs.mu.Unlock()
delete(cs.contracts, fcid)
}

func (cs *ContractStore) RenewContract(hk types.PublicKey) (*Contract, error) {
cs.mu.Lock()
defer cs.mu.Unlock()

curr, ok := cs.hosts2fcid[hk]
if !ok {
return nil, errors.New("host not found")
}
c := cs.contracts[curr]
if c == nil {
return nil, errors.New("host does not have a contract to renew")
}
delete(cs.contracts, curr)

renewal := NewContract(hk, cs.newFileContractID())
renewal.metadata.RenewedFrom = c.metadata.ID
renewal.metadata.WindowStart = c.metadata.WindowEnd
renewal.metadata.WindowEnd = renewal.metadata.WindowStart + (c.metadata.WindowEnd - c.metadata.WindowStart)
cs.contracts[renewal.metadata.ID] = renewal
cs.hosts2fcid[hk] = renewal.metadata.ID
return renewal, nil
}

func (cs *ContractStore) newFileContractID() types.FileContractID {
cs.fcidCntr++
return types.FileContractID{byte(cs.fcidCntr)}
}

type Contract struct {
rev types.FileContractRevision
metadata api.ContractMetadata

mu sync.Mutex
sectors map[types.Hash256]*[rhpv2.SectorSize]byte
}

func NewContract(hk types.PublicKey, fcid types.FileContractID) *Contract {
return &Contract{
metadata: api.ContractMetadata{
ID: fcid,
HostKey: hk,
WindowStart: 0,
WindowEnd: 10,
},
rev: types.FileContractRevision{ParentID: fcid},
sectors: make(map[types.Hash256]*[rhpv2.SectorSize]byte),
}
}

func (c *Contract) AddSector(root types.Hash256, sector *[rhpv2.SectorSize]byte) {
c.mu.Lock()
c.sectors[root] = sector
c.mu.Unlock()
}

func (c *Contract) ID() types.FileContractID {
c.mu.Lock()
defer c.mu.Unlock()
return c.metadata.ID
}

func (c *Contract) Metadata() api.ContractMetadata {
c.mu.Lock()
defer c.mu.Unlock()
return c.metadata
}

func (c *Contract) Revision() types.FileContractRevision {
c.mu.Lock()
defer c.mu.Unlock()
return c.rev
}

func (c *Contract) Sector(root types.Hash256) (sector *[rhpv2.SectorSize]byte, found bool) {
c.mu.Lock()
sector, found = c.sectors[root]
c.mu.Unlock()
return
}
52 changes: 52 additions & 0 deletions internal/test/mocks/hoststore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package mocks

import (
"context"
"sync"

"go.sia.tech/core/types"
"go.sia.tech/renterd/api"
)

type HostStore struct {
mu sync.Mutex
hosts map[types.PublicKey]*Host
hkCntr uint
}

func NewHostStore() *HostStore {
return &HostStore{hosts: make(map[types.PublicKey]*Host)}
}

func (hs *HostStore) Host(ctx context.Context, hostKey types.PublicKey) (api.Host, error) {
hs.mu.Lock()
defer hs.mu.Unlock()

h, ok := hs.hosts[hostKey]
if !ok {
return api.Host{}, api.ErrHostNotFound
}
return h.hi, nil
}

func (hs *HostStore) RecordHostScans(ctx context.Context, scans []api.HostScan) error {
return nil
}

func (hs *HostStore) RecordPriceTables(ctx context.Context, priceTableUpdate []api.HostPriceTableUpdate) error {
return nil
}

func (hs *HostStore) RecordContractSpending(ctx context.Context, records []api.ContractSpendingRecord) error {
return nil
}

func (hs *HostStore) AddHost() *Host {
hs.mu.Lock()
defer hs.mu.Unlock()

hs.hkCntr++
hk := types.PublicKey{byte(hs.hkCntr)}
hs.hosts[hk] = NewHost(hk)
return hs.hosts[hk]
}
Loading

0 comments on commit e98388d

Please sign in to comment.