Skip to content

Commit

Permalink
rpctest - Fix wallet RPC port, and lots of docs and formatting. (#313)
Browse files Browse the repository at this point in the history
* Fix node RPC port incorrectly being used for wallet RPC port when harness instance IDs > 0.
Documentation fixes in rpcharness.go.
Include .vscode in .gitignore.

* Minor formatting of comments.
  • Loading branch information
chappjc authored and alexlyp committed Aug 9, 2016
1 parent 3b33911 commit 8d79e45
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 47 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -1,3 +1,4 @@
btcwallet
vendor
*~
.vscode
6 changes: 4 additions & 2 deletions rpctest/node.go
@@ -1,4 +1,5 @@
// Copyright (c) 2016 The btcsuite developers
// Copyright (c) 2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -42,11 +43,12 @@ type nodeConfig struct {
certificates []byte
}

// newConfig returns a newConfig with all default values.
// newConfig returns a nodeConfig with default values.
func newConfig(prefix, certFile, keyFile string, extra []string) (*nodeConfig, error) {
// TODO: use defaultP2pPort and defaultRPCPort instead of literals
a := &nodeConfig{
listen: "127.0.0.1:18555",
rpcListen: "127.0.0.1:18556",
rpcListen: "127.0.0.1:19556",
rpcUser: "user",
rpcPass: "pass",
extra: extra,
Expand Down
76 changes: 44 additions & 32 deletions rpctest/rpcharness.go
@@ -1,4 +1,4 @@
// Copyright (c) 2016 The decred developers
// Copyright (c) 2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -26,41 +26,44 @@ var (
// current number of active test nodes.
numTestInstances = 0

// defaultP2pPort is the initial p2p port which will be used by the
// first created rpc harnesses to listen on for incoming p2p connections.
// defaultP2pPort is the initial p2p port which will be used by the first
// created rpc harnesses to listen on for incoming p2p connections.
// Subsequent allocated ports for future rpc harness instances will be
// monotonically increasing odd numbers calculated as such:
// defaultP2pPort + (2 * harness.nodeNum).
defaultP2pPort = 18555

// defaultRPCPort is the initial rpc port which will be used by the first created
// rpc harnesses to listen on for incoming rpc connections. Subsequent
// allocated ports for future rpc harness instances will be monotonically
// increasing even numbers calculated as such:
// defaultP2pPort + (2 * harness.nodeNum).
// defaultRPCPort is the initial rpc port which will be used by the first
// created rpc harnesses to listen on for incoming rpc connections.
// Subsequent allocated ports for future rpc harness instances will be
// monotonically increasing even numbers calculated as such:
// defaultRPCPort + (2 * harness.nodeNum).
defaultRPCPort = 19556

// defaultWalletRPCPort is the initial RPC port similar to defaultRPCPort
// but used for the wallet RPC.
defaultWalletRPCPort = 19557

// testInstances is a private package-level slice used to keep track of
// allvactive test harnesses. This global can be used to perform various
// all active test harnesses. This global can be used to perform various
// "joins", shutdown several active harnesses after a test, etc.
testInstances map[string]*Harness

// Used to protest concurrent access to above declared variables.
// harnessStateMtx is used to protect concurrent access to the variables
// declared above.
harnessStateMtx sync.RWMutex
)

// Harness fully encapsulates an active dcrd process, along with an embdedded
// dcrwallet in order to provide a unified platform for creating rpc driven
// integration tests involving dcrd. The active dcrd node will typically be
// run in simnet mode in order to allow for easy generation of test blockchains.
// Additionally, a special method is provided which allows on to easily generate
// coinbase spends. The active dcrd process if fully managed by Harness, which
// handles the necessary initialization, and teardown of the process along with
// any temporary directories created as a result. Multiple Harness instances may
// be run concurrently, in order to allow for testing complex scenarios involving
// multuple nodes.
// Harness fully encapsulates an active dcrd process, along with an embedded
// dcrwallet to provide a unified platform for creating RPC-driven integration
// tests involving dcrd. The active dcrd node will typically be run in simnet
// mode to allow for easy generation of test blockchains. Additionally, a
// special method is provided which allows one to easily generate coinbase
// spends. The active dcrd process is fully managed by Harness, which handles
// the necessary initialization, and teardown of the process along with any
// temporary directories created as a result. Multiple Harness instances may be
// run concurrently, to allow for testing complex scenarios involving multuple
// nodes.
type Harness struct {
ActiveNet *chaincfg.Params

Expand All @@ -79,9 +82,10 @@ type Harness struct {
nodeNum int
}

// NewHarness creates and initializes new instance of the rpc test harness.
// NewHarness creates and initializes a new instance of the rpc test harness.
// Optionally, websocket handlers and a specified configuration may be passed.
// In the case that a nil config is passed, a default configuration will be used.
// In the case that a nil configuration is passed, a default configuration will
// be used.
//
// NOTE: This function is safe for concurrent access.
func NewHarness(activeNet *chaincfg.Params, handlers *rpc.NotificationHandlers,
Expand All @@ -90,6 +94,7 @@ func NewHarness(activeNet *chaincfg.Params, handlers *rpc.NotificationHandlers,
harnessStateMtx.Lock()
defer harnessStateMtx.Unlock()

// Create data folders for this Harness instance
harnessID := strconv.Itoa(int(numTestInstances))
testDataPath := "rpctest-" + harnessID

Expand All @@ -98,11 +103,13 @@ func NewHarness(activeNet *chaincfg.Params, handlers *rpc.NotificationHandlers,
return nil, err
}

// Subdirectory for daemon data
nodeTestData, err := ioutil.TempDir(testData, "node")
if err != nil {
return nil, err
}

// Subdirectory for wallet data
walletTestData, err := ioutil.TempDir(testData, "wallet")
if err != nil {
return nil, err
Expand All @@ -121,6 +128,7 @@ func NewHarness(activeNet *chaincfg.Params, handlers *rpc.NotificationHandlers,
// Generate p2p+rpc listening addresses.
p2p, rpcPort, walletRPC := generateListeningAddresses()

// Create new nodeConfig
config, err := newConfig(nodeTestData, certFile, keyFile, extraArgs)
if err != nil {
return nil, err
Expand All @@ -134,15 +142,17 @@ func NewHarness(activeNet *chaincfg.Params, handlers *rpc.NotificationHandlers,
return nil, err
}

// Create new walletTestConfig
walletConfig, err := newWalletConfig(walletTestData, certFile, certFileWallet, keyFileWallet, nil)
if err != nil {
return nil, err
}

// Generate p2p+rpc listening addresses.
// Set RPC connect (node) port
walletConfig.rpcConnect = rpcPort
// Set RPC listen port
walletConfig.rpcListen = walletRPC

// Create the testing wallet
walletTest, err := newWallet(walletConfig, walletTestData)
if err != nil {
return nil, err
Expand Down Expand Up @@ -217,7 +227,8 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error {
break
}
if miningAddr == nil {
return fmt.Errorf("RPC not up for mining addr %v %v", h.testNodeDir, h.testWalletDir)
return fmt.Errorf("RPC not up for mining addr %v %v", h.testNodeDir,
h.testWalletDir)
}

var extraArgs []string
Expand All @@ -229,7 +240,8 @@ func (h *Harness) SetUp(createTestChain bool, numMatureOutputs uint32) error {
return err
}

config, err := newConfig(h.node.config.prefix, h.node.config.certFile, h.node.config.keyFile, extraArgs)
config, err := newConfig(h.node.config.prefix, h.node.config.certFile,
h.node.config.keyFile, extraArgs)
if err != nil {
return err
}
Expand Down Expand Up @@ -295,7 +307,7 @@ out:
return nil
}

// TearDown stops the running rpc test instance. All created p.
// TearDown stops the running rpc test instance. All created p. (?)
// killed, and temporary directories removed.
func (h *Harness) TearDown() error {
if h.Node != nil {
Expand Down Expand Up @@ -359,10 +371,10 @@ func (h *Harness) RPCConfig() rpc.ConnConfig {
return h.node.config.rpcConnConfig()
}

// generateListeningAddresses returns two strings representing listening
// addresses designated for the current rpc test. If there haven't been any
// test instances created, the default ports are used. Otherwise, in order to
// support multiple test nodes running at once, the p2p and rpc port are
// generateListeningAddresses returns three strings representing listening
// addresses designated for the current rpc test. If there haven't been any test
// instances created, the default ports are used. Otherwise, in order to support
// multiple test nodes running at once, the p2p and both rpc ports are
// incremented after each initialization.
func generateListeningAddresses() (string, string, string) {
var p2p, rpc, walletRPC string
Expand All @@ -378,7 +390,7 @@ func generateListeningAddresses() (string, string, string) {
rpc = net.JoinHostPort(localhost,
strconv.Itoa(defaultRPCPort+(2*numTestInstances)))
walletRPC = net.JoinHostPort(localhost,
strconv.Itoa(defaultRPCPort+(2*numTestInstances)))
strconv.Itoa(defaultWalletRPCPort+(2*numTestInstances)))
}

return p2p, rpc, walletRPC
Expand Down
1 change: 1 addition & 0 deletions rpctest/rpcharness_test.go
Expand Up @@ -58,6 +58,7 @@ func TestRpcServer(t *testing.T) {
testCase(primaryHarness, t)
}
}

func testSendFrom(r *Harness, t *testing.T) {

accountName := "sendFromTest"
Expand Down
28 changes: 15 additions & 13 deletions rpctest/walletnode.go
@@ -1,4 +1,4 @@
// Copyright (c) 2016 The decred developers
// Copyright (c) 2016 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

Expand Down Expand Up @@ -42,6 +42,7 @@ type walletTestConfig struct {

// newConfig returns a newConfig with all default values.
func newWalletConfig(prefix, caFile, certFile, keyFile string, extra []string) (*walletTestConfig, error) {
// TODO: use defaultRPCPort and defaultWalletRPCPort instead of literals
a := &walletTestConfig{
rpcConnect: "127.0.0.1:19556",
rpcListen: "127.0.0.1:19557",
Expand Down Expand Up @@ -132,7 +133,8 @@ func (n *walletTestConfig) arguments() []string {
return args
}

// command returns the exec.Cmd which will be used to start the dcrwallet process.
// command returns the exec.Cmd which will be used to start the dcrwallet
// process.
func (n *walletTestConfig) command() *exec.Cmd {
return exec.Command(n.exe, n.arguments()...)
}
Expand Down Expand Up @@ -170,8 +172,8 @@ func (n *walletTestConfig) cleanup() error {
return err
}

// walletTest houses the neccessary state required to configure, launch, and manaage
// a dcrwallet process.
// walletTest houses the neccessary state required to configure, launch, and
// manaage a dcrwallet process.
type walletTest struct {
config *walletTestConfig

Expand All @@ -181,9 +183,9 @@ type walletTest struct {
dataDir string
}

// newNode creates a new walletTest 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 dcrwallet.
// newWallet creates a new walletTest 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 dcrwallet.
func newWallet(config *walletTestConfig, dataDir string) (*walletTest, error) {
return &walletTest{
config: config,
Expand All @@ -192,11 +194,11 @@ func newWallet(config *walletTestConfig, dataDir string) (*walletTest, error) {
}, nil
}

// Start creates a new dcrwallet process, and writes its pid in a file reserved for
// recording the pid of the launched process. This file can ue used to terminate
// the procress in case of a hang, or panic. In the case of a failing test case,
// or panic, it is important that the process be stopped via stop(), otherwise,
// it will persist unless explicitly killed.
// Start creates a new dcrwallet process, and writes its pid in a file reserved
// for recording the pid of the launched process. This file can ue used to
// terminate the process in case of a hang, or panic. In the case of a failing
// test case, or panic, it is important that the process be stopped via Stop(),
// otherwise, it will persist unless explicitly killed.
func (n *walletTest) Start() error {
if err := n.cmd.Start(); err != nil {
return err
Expand Down Expand Up @@ -248,7 +250,7 @@ func (n *walletTest) Cleanup() error {
return n.config.cleanup()
}

// shutdown terminates the running dcrwallet process, and cleans up all
// Shutdown terminates the running dcrwallet process, and cleans up all
// file/directories created by walletTest.
func (n *walletTest) Shutdown() error {
if err := n.Stop(); err != nil {
Expand Down

0 comments on commit 8d79e45

Please sign in to comment.