Skip to content

Commit

Permalink
rpctest: Compile current version of btcd and run that.
Browse files Browse the repository at this point in the history
Previously, rpctest would start a btcd node using the btcd executable
in the environment PATH. This caused difficult-to-find issues where
the code would be tested against an older version of btcd, or another
fork entirely. Now it compiles btcd the first time it is needed and
uses that fresh version when launching nodes.
  • Loading branch information
Jim Posen committed Oct 20, 2017
1 parent fb43a17 commit 11d7cae
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 6 deletions.
73 changes: 73 additions & 0 deletions integration/rpctest/btcd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2017 The btcsuite developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package rpctest

import (
"fmt"
"go/build"
"os/exec"
"path/filepath"
"runtime"
"sync"
)

var (
// compileMtx guards access to the executable path so that the project is
// only compiled once.
compileMtx sync.Mutex

// executablePath is the path to the compiled executable. This is the empty
// string until btcd is compiled. This should not be accessed directly;
// instead use the function btcdExecutablePath().
executablePath string
)

// btcdExecutablePath returns a path to the btcd executable to be used by
// rpctests. To ensure the code tests against the most up-to-date version of
// btcd, this method compiles btcd the first time it is called. After that, the
// generated binary is used for subsequent test harnesses. The executable file
// is not cleaned up, but since it lives at a static path in a temp directory,
// it is not a big deal.
func btcdExecutablePath() (string, error) {
compileMtx.Lock()
defer compileMtx.Unlock()

// If btcd has already been compiled, just use that.
if len(executablePath) != 0 {
return executablePath, nil
}

testDir, err := baseDir()
if err != nil {
return "", err
}

// Determine import path of this package. Not necessarily btcsuite/btcd if
// this is a forked repo.
_, rpctestDir, _, ok := runtime.Caller(1)
if !ok {
return "", fmt.Errorf("Cannot get path to btcd source code")
}
btcdPkgPath := filepath.Join(rpctestDir, "..", "..", "..")
btcdPkg, err := build.ImportDir(btcdPkgPath, build.FindOnly)
if err != nil {
return "", fmt.Errorf("Failed to build btcd: %v", err)
}

// Build btcd and output an executable in a static temp path.
outputPath := filepath.Join(testDir, "btcd")
if runtime.GOOS == "windows" {
outputPath += ".exe"
}
cmd := exec.Command("go", "build", "-o", outputPath, btcdPkg.ImportPath)
err = cmd.Run()
if err != nil {
return "", fmt.Errorf("Failed to build btcd: %v", err)
}

// Save executable path so future calls do not recompile.
executablePath = outputPath
return executablePath, nil
}
14 changes: 9 additions & 5 deletions integration/rpctest/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,22 @@ type nodeConfig struct {

// newConfig returns a newConfig with all default values.
func newConfig(prefix, certFile, keyFile string, extra []string) (*nodeConfig, error) {
btcdPath, err := btcdExecutablePath()
if err != nil {
return nil, err
}

a := &nodeConfig{
listen: "127.0.0.1:18555",
rpcListen: "127.0.0.1:18556",
rpcUser: "user",
rpcPass: "pass",
extra: extra,
prefix: prefix,

exe: "btcd",
endpoint: "ws",
certFile: certFile,
keyFile: keyFile,
exe: btcdPath,
endpoint: "ws",
certFile: certFile,
keyFile: keyFile,
}
if err := a.setDefaults(); err != nil {
return nil, err
Expand Down
14 changes: 13 additions & 1 deletion integration/rpctest/rpc_harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,13 @@ func New(activeNet *chaincfg.Params, handlers *rpcclient.NotificationHandlers,
"of the supported chain networks")
}

testDir, err := baseDir()
if err != nil {
return nil, err
}

harnessID := strconv.Itoa(numTestInstances)
nodeTestData, err := ioutil.TempDir("", "rpctest-"+harnessID)
nodeTestData, err := ioutil.TempDir(testDir, "harness-"+harnessID)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -453,3 +458,10 @@ func generateListeningAddresses() (string, string) {
rpc := net.JoinHostPort(localhost, portString(minRPCPort, maxRPCPort))
return p2p, rpc
}

// baseDir is the directory path of the temp directory for all rpctest files.
func baseDir() (string, error) {
dirPath := filepath.Join(os.TempDir(), "btcd", "rpctest")
err := os.MkdirAll(dirPath, 0755)
return dirPath, err
}

0 comments on commit 11d7cae

Please sign in to comment.