Skip to content

Commit

Permalink
dcrdtest: Remove need for *testing.T
Browse files Browse the repository at this point in the history
This removes the need for passing a valid *testing.T object to the
harness initializing function New() by switching the logging statements
from using the test object to log it to using a standard slog logger.

The API is not yet changed to avoid having to perform a major version
bump in the package, but a deprecation note is added to the function's
documentation.

The purpose of this change is to allow this package to be more broadly
useful, not just in tests, but also in benchmarks and in generic code
not tied specifically to tests.
  • Loading branch information
matheusd authored and davecgh committed Oct 18, 2023
1 parent 824c67e commit 53bcbaa
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 147 deletions.
40 changes: 0 additions & 40 deletions dcrdtest/debug.go

This file was deleted.

17 changes: 17 additions & 0 deletions dcrdtest/log.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) 2023 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package dcrdtest

import "github.com/decred/slog"

// log is a logger that is initialized with no output filters. This
// means the package will not perform any logging by default until the caller
// requests it.
// The default amount of logging is none.
var log = slog.Disabled

// UseLogger uses a specified Logger to output package logging info.
func UseLogger(logger slog.Logger) {
log = logger
}
50 changes: 23 additions & 27 deletions dcrdtest/memwallet.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"encoding/binary"
"fmt"
"sync"
"testing"

"github.com/decred/dcrd/blockchain/standalone/v2"
"github.com/decred/dcrd/chaincfg/chainhash"
Expand Down Expand Up @@ -115,16 +114,14 @@ type memWallet struct {

net *chaincfg.Params

t *testing.T

rpc *rpcclient.Client

sync.RWMutex
}

// newMemWallet creates and returns a fully initialized instance of the
// memWallet given a particular blockchain's parameters.
func newMemWallet(t *testing.T, net *chaincfg.Params, harnessID uint32) (*memWallet, error) {
func newMemWallet(net *chaincfg.Params, harnessID uint32) (*memWallet, error) {
// The wallet's final HD seed is: hdSeed || harnessID. This method
// ensures that each harness instance uses a deterministic root seed
// based on its harness ID.
Expand Down Expand Up @@ -164,7 +161,6 @@ func newMemWallet(t *testing.T, net *chaincfg.Params, harnessID uint32) (*memWal
hdIndex: 1,
hdRoot: hdRoot,
addrs: addrs,
t: t,
utxos: make(map[wire.OutPoint]*utxo),
chainUpdateSignal: make(chan struct{}),
reorgJournal: make(map[int64]*undoEntry),
Expand Down Expand Up @@ -195,8 +191,8 @@ func (m *memWallet) SetRPCClient(rpcClient *rpcclient.Client) {
// connected to the main chain. Ingesting a block updates the wallet's internal
// utxo state based on the outputs created and destroyed within each block.
func (m *memWallet) IngestBlock(header []byte, filteredTxns [][]byte) {
tracef(m.t, "memwallet.IngestBlock")
defer tracef(m.t, "memwallet.IngestBlock exit")
log.Tracef("memwallet.IngestBlock")
defer log.Tracef("memwallet.IngestBlock exit")

var hdr wire.BlockHeader
if err := hdr.FromBytes(header); err != nil {
Expand Down Expand Up @@ -232,8 +228,8 @@ func (m *memWallet) IngestBlock(header []byte, filteredTxns [][]byte) {
//
// NOTE: This MUST be run as a goroutine.
func (m *memWallet) chainSyncer() {
tracef(m.t, "memwallet.chainSyncer")
defer tracef(m.t, "memwallet.chainSyncer exit")
log.Tracef("memwallet.chainSyncer")
defer log.Tracef("memwallet.chainSyncer exit")

var update *chainUpdate

Expand Down Expand Up @@ -273,8 +269,8 @@ func (m *memWallet) chainSyncer() {
// evalOutputs evaluates each of the passed outputs, creating a new matching
// utxo within the wallet if we're able to spend the output.
func (m *memWallet) evalOutputs(outputs []*wire.TxOut, txHash *chainhash.Hash, isCoinbase bool, undo *undoEntry) {
tracef(m.t, "memwallet.evalOutputs")
defer tracef(m.t, "memwallet.evalOutputs exit")
log.Tracef("memwallet.evalOutputs")
defer log.Tracef("memwallet.evalOutputs exit")

for i, output := range outputs {
pkScript := output.PkScript
Expand Down Expand Up @@ -310,8 +306,8 @@ func (m *memWallet) evalOutputs(outputs []*wire.TxOut, txHash *chainhash.Hash, i
// evalInputs scans all the passed inputs, destroying any utxos within the
// wallet which are spent by an input.
func (m *memWallet) evalInputs(inputs []*wire.TxIn, undo *undoEntry) {
tracef(m.t, "memwallet.evalInputs")
defer tracef(m.t, "memwallet.evalInputs exit")
log.Tracef("memwallet.evalInputs")
defer log.Tracef("memwallet.evalInputs exit")

for _, txIn := range inputs {
op := txIn.PreviousOutPoint
Expand All @@ -329,8 +325,8 @@ func (m *memWallet) evalInputs(inputs []*wire.TxIn, undo *undoEntry) {
// disconnected from the main chain. Unwinding a block undoes the effect that a
// particular block had on the wallet's internal utxo state.
func (m *memWallet) UnwindBlock(header []byte) {
tracef(m.t, "memwallet.UnwindBlock")
defer tracef(m.t, "memwallet.UnwindBlock exit")
log.Tracef("memwallet.UnwindBlock")
defer log.Tracef("memwallet.UnwindBlock exit")

var hdr wire.BlockHeader
if err := hdr.FromBytes(header); err != nil {
Expand Down Expand Up @@ -358,8 +354,8 @@ func (m *memWallet) UnwindBlock(header []byte) {
// loads the address into the RPC client's transaction filter to ensure any
// transactions that involve it are delivered via the notifications.
func (m *memWallet) newAddress(ctx context.Context) (stdaddr.Address, error) {
tracef(m.t, "memwallet.newAddress")
defer tracef(m.t, "memwallet.newAddress exit")
log.Tracef("memwallet.newAddress")
defer log.Tracef("memwallet.newAddress exit")

index := m.hdIndex

Expand Down Expand Up @@ -407,8 +403,8 @@ func (m *memWallet) NewAddress(ctx context.Context) (stdaddr.Address, error) {
//
// NOTE: The memWallet's mutex must be held when this function is called.
func (m *memWallet) fundTx(ctx context.Context, tx *wire.MsgTx, amt dcrutil.Amount, feeRate dcrutil.Amount) error {
tracef(m.t, "memwallet.fundTx")
defer tracef(m.t, "memwallet.fundTx exit")
log.Tracef("memwallet.fundTx")
defer log.Tracef("memwallet.fundTx exit")

const (
// spendSize is the largest number of bytes of a sigScript
Expand Down Expand Up @@ -474,8 +470,8 @@ func (m *memWallet) fundTx(ctx context.Context, tx *wire.MsgTx, amt dcrutil.Amou
// while observing the passed fee rate. The passed fee rate should be expressed
// in atoms-per-byte.
func (m *memWallet) SendOutputs(ctx context.Context, outputs []*wire.TxOut, feeRate dcrutil.Amount) (*chainhash.Hash, error) {
tracef(m.t, "memwallet.SendOutputs")
defer tracef(m.t, "memwallet.SendOutputs exit")
log.Tracef("memwallet.SendOutputs")
defer log.Tracef("memwallet.SendOutputs exit")

tx, err := m.CreateTransaction(ctx, outputs, feeRate)
if err != nil {
Expand All @@ -491,8 +487,8 @@ func (m *memWallet) SendOutputs(ctx context.Context, outputs []*wire.TxOut, feeR
//
// This function is safe for concurrent access.
func (m *memWallet) CreateTransaction(ctx context.Context, outputs []*wire.TxOut, feeRate dcrutil.Amount) (*wire.MsgTx, error) {
tracef(m.t, "memwallet.CreateTransaction")
defer tracef(m.t, "memwallet.CreateTransaction exit")
log.Tracef("memwallet.CreateTransaction")
defer log.Tracef("memwallet.CreateTransaction exit")

m.Lock()
defer m.Unlock()
Expand Down Expand Up @@ -557,8 +553,8 @@ func (m *memWallet) CreateTransaction(ctx context.Context, outputs []*wire.TxOut
//
// This function is safe for concurrent access.
func (m *memWallet) UnlockOutputs(inputs []*wire.TxIn) {
tracef(m.t, "memwallet.UnlockOutputs")
defer tracef(m.t, "memwallet.UnlockOutputs exit")
log.Tracef("memwallet.UnlockOutputs")
defer log.Tracef("memwallet.UnlockOutputs exit")

m.Lock()
defer m.Unlock()
Expand All @@ -577,8 +573,8 @@ func (m *memWallet) UnlockOutputs(inputs []*wire.TxIn) {
//
// This function is safe for concurrent access.
func (m *memWallet) ConfirmedBalance() dcrutil.Amount {
tracef(m.t, "memwallet.ConfirmedBalance")
defer tracef(m.t, "memwallet.ConfirmedBalance exit")
log.Tracef("memwallet.ConfirmedBalance")
defer log.Tracef("memwallet.ConfirmedBalance exit")

m.RLock()
defer m.RUnlock()
Expand Down
50 changes: 18 additions & 32 deletions dcrdtest/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"runtime"
"strconv"
"sync"
"testing"
"time"

"github.com/decred/dcrd/certgen"
Expand Down Expand Up @@ -187,35 +186,22 @@ type node struct {
rpcAddr string

dataDir string

t *testing.T
}

// logf is identical to n.t.Logf but it prepends the pid of this node.
func (n *node) logf(format string, args ...interface{}) {
pid := strconv.Itoa(n.pid) + " "
logf(n.t, pid+format, args...)
}

// tracef is identical to debug.go.tracef but it prepends the pid of this
// node.
func (n *node) tracef(format string, args ...interface{}) {
if !trace {
return
}
pid := strconv.Itoa(n.pid) + " "
tracef(n.t, pid+format, args...)
log.Debugf(pid+format, args...)
}

// newNode creates a new node instance according to the passed config. dataDir
// will be used to hold a file recording the pid of the launched process, and
// as the base for the log and data directories for dcrd.
func newNode(t *testing.T, config *nodeConfig, dataDir string) (*node, error) {
func newNode(config *nodeConfig, dataDir string) (*node, error) {
return &node{
config: config,
dataDir: dataDir,
cmd: config.command(),
t: t,
}, nil
}

Expand Down Expand Up @@ -243,7 +229,7 @@ func (n *node) start(ctx context.Context) error {
for {
line, err := r.ReadBytes('\n')
if errors.Is(err, io.EOF) {
n.tracef("stderr: EOF")
log.Tracef("stderr: EOF")
return
}
n.logf("stderr: %s", line)
Expand All @@ -263,10 +249,10 @@ func (n *node) start(ctx context.Context) error {
for {
line, err := r.ReadBytes('\n')
if errors.Is(err, io.EOF) {
n.tracef("stdout: EOF")
log.Tracef("stdout: EOF")
return
}
n.tracef("stdout: %s", line)
log.Tracef("stdout: %s", line)
}
}()

Expand Down Expand Up @@ -337,8 +323,8 @@ func (n *node) start(ctx context.Context) error {
// properly. On windows, interrupt is not supported, so a kill signal is used
// instead
func (n *node) stop() error {
n.tracef("stop %p %p", n.cmd, n.cmd.Process)
defer n.tracef("stop done")
log.Tracef("stop %p %p", n.cmd, n.cmd.Process)
defer log.Tracef("stop done")

if n.cmd == nil || n.cmd.Process == nil {
// return if not properly initialized
Expand All @@ -353,27 +339,27 @@ func (n *node) stop() error {

// Make a harder attempt at shutdown, by sending an interrupt
// signal.
n.tracef("stop send kill")
log.Tracef("stop send kill")
var err error
if runtime.GOOS == "windows" {
err = n.cmd.Process.Signal(os.Kill)
} else {
err = n.cmd.Process.Signal(os.Interrupt)
}
if err != nil {
n.t.Logf("stop Signal error: %v", err)
log.Debugf("stop Signal error: %v", err)
}
}

// Wait for pipes.
n.tracef("stop wg")
log.Tracef("stop wg")
n.wg.Wait()

// Wait for command to exit.
n.tracef("stop cmd.Wait")
log.Tracef("stop cmd.Wait")
err = n.cmd.Wait()
if err != nil {
n.t.Logf("stop cmd.Wait error: %v", err)
log.Debugf("stop cmd.Wait error: %v", err)
}

// Close the IPC pipes.
Expand All @@ -387,12 +373,12 @@ func (n *node) stop() error {
// created process will be deleted, as well as any directories created by the
// process.
func (n *node) cleanup() error {
n.tracef("cleanup")
defer n.tracef("cleanup done")
log.Tracef("cleanup")
defer log.Tracef("cleanup done")

if n.pidFile != "" {
if err := os.Remove(n.pidFile); err != nil {
n.t.Logf("unable to remove file %s: %v", n.pidFile,
log.Debugf("unable to remove file %s: %v", n.pidFile,
err)
return err
}
Expand All @@ -404,11 +390,11 @@ func (n *node) cleanup() error {
// shutdown terminates the running dcrd process, and cleans up all
// file/directories created by node.
func (n *node) shutdown() error {
n.tracef("shutdown")
defer n.tracef("shutdown done")
log.Tracef("shutdown")
defer log.Tracef("shutdown done")

if err := n.stop(); err != nil {
n.t.Logf("shutdown stop error: %v", err)
log.Debugf("shutdown stop error: %v", err)
return err
}
return n.cleanup()
Expand Down
Loading

0 comments on commit 53bcbaa

Please sign in to comment.