diff --git a/goclean.sh b/goclean.sh index 1c77bceb0..8a4e8379a 100755 --- a/goclean.sh +++ b/goclean.sh @@ -12,7 +12,7 @@ set -ex test -z "$(go fmt $(glide novendor) | tee /dev/stderr)" test -z "$(for package in $(glide novendor); do golint $package; done | grep -v 'ALL_CAPS\|OP_\|NewFieldVal' | tee /dev/stderr)" test -z "$(go vet $(glide novendor) 2>&1 | tee /dev/stderr)" -env GORACE="halt_on_error=1" go test -p 1 -v -race $(glide novendor) +env GORACE="halt_on_error=1" go test -v -race $(glide novendor) # Run test coverage on each subdirectories and merge the coverage profile. diff --git a/rpctest/rpc_harness.go b/rpctest/rpc_harness.go index 0c5270fae..24fcd6313 100644 --- a/rpctest/rpc_harness.go +++ b/rpctest/rpc_harness.go @@ -22,23 +22,29 @@ import ( "github.com/btcsuite/btcutil" ) +const ( + // These constants define the minimum and maximum p2p and rpc port + // numbers used by a test harness. The min port is inclusive while the + // max port is exclusive. + minPeerPort = 10000 + maxPeerPort = 35000 + minRPCPort = maxPeerPort + maxRPCPort = 60000 +) + 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. 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 = 18556 + // processID is the process ID of the current running process. It is + // used to calculate ports based upon it when launching an rpc + // harnesses. The intent is to allow multiple process to run in + // parallel without port collisions. + // + // It should be noted however that there is still some small probability + // that there will be port collisions either due to other processes + // running or simply due to the stars aligning on the process IDs. + processID = os.Getppid() // testInstances is a private package-level slice used to keep track of // all active test harnesses. This global can be used to perform @@ -392,18 +398,15 @@ func (h *Harness) GenerateAndSubmitBlock(txns []*btcutil.Tx, blockVersion int32, // support multiple test nodes running at once, the p2p and rpc port are // incremented after each initialization. func generateListeningAddresses() (string, string) { - var p2p, rpc string localhost := "127.0.0.1" - if numTestInstances == 0 { - p2p = net.JoinHostPort(localhost, strconv.Itoa(defaultP2pPort)) - rpc = net.JoinHostPort(localhost, strconv.Itoa(defaultRPCPort)) - } else { - p2p = net.JoinHostPort(localhost, - strconv.Itoa(defaultP2pPort+(2*numTestInstances))) - rpc = net.JoinHostPort(localhost, - strconv.Itoa(defaultRPCPort+(2*numTestInstances))) + portString := func(minPort, maxPort int) string { + port := minPort + numTestInstances + ((20 * processID) % + (maxPort - minPort)) + return strconv.Itoa(port) } + p2p := net.JoinHostPort(localhost, portString(minPeerPort, maxPeerPort)) + rpc := net.JoinHostPort(localhost, portString(minRPCPort, maxRPCPort)) return p2p, rpc } diff --git a/rpctest/rpc_harness_test.go b/rpctest/rpc_harness_test.go index 042744a17..9cefaaa43 100644 --- a/rpctest/rpc_harness_test.go +++ b/rpctest/rpc_harness_test.go @@ -5,9 +5,7 @@ package rpctest import ( "fmt" - "net" "os" - "strconv" "testing" "time" @@ -82,14 +80,12 @@ func testSendOutputs(r *Harness, t *testing.T) { } func assertConnectedTo(t *testing.T, nodeA *Harness, nodeB *Harness) { - nodePort := defaultP2pPort + (2 * nodeB.nodeNum) - nodeAddr := net.JoinHostPort("127.0.0.1", strconv.Itoa(nodePort)) - nodeAPeers, err := nodeA.Node.GetPeerInfo() if err != nil { t.Fatalf("unable to get nodeA's peer info") } + nodeAddr := nodeB.node.config.listen addrFound := false for _, peerInfo := range nodeAPeers { if peerInfo.Addr == nodeAddr { diff --git a/rpctest/utils.go b/rpctest/utils.go index f33090884..b10f462f3 100644 --- a/rpctest/utils.go +++ b/rpctest/utils.go @@ -5,9 +5,7 @@ package rpctest import ( - "net" "reflect" - "strconv" "time" "github.com/btcsuite/btcd/chaincfg/chainhash" @@ -110,18 +108,13 @@ retry: // therefore in the case of disconnects, "from" will attempt to reestablish a // connection to the "to" harness. func ConnectNode(from *Harness, to *Harness) error { - // Calculate the target p2p addr+port for the node to be connected to. - // p2p ports uses within the package are always even, so we multiply - // the node number by two before offsetting from the defaultP2pPort. - targetPort := defaultP2pPort + (2 * to.nodeNum) - targetAddr := net.JoinHostPort("127.0.0.1", strconv.Itoa(targetPort)) - peerInfo, err := from.Node.GetPeerInfo() if err != nil { return err } numPeers := len(peerInfo) + targetAddr := to.node.config.listen if err := from.Node.AddNode(targetAddr, btcrpcclient.ANAdd); err != nil { return err }