btcd.go raw

   1  package rpctest
   2  
   3  import (
   4  	"fmt"
   5  	"go/build"
   6  	"os/exec"
   7  	"path/filepath"
   8  	"runtime"
   9  	"sync"
  10  	
  11  	"github.com/p9c/p9/pkg/util/gobin"
  12  )
  13  
  14  var (
  15  	// compileMtx guards access to the executable path so that the project is only compiled once.
  16  	compileMtx sync.Mutex
  17  	// executablePath is the path to the compiled executable. This is the empty string until pod is compiled. This
  18  	// should not be accessed directly; instead use the function podExecutablePath().
  19  	executablePath string
  20  )
  21  
  22  // podExecutablePath returns a path to the pod executable to be used by rpctests. To ensure the code tests against the
  23  // most up-to-date version of pod, this method compiles pod the first time it is called. After that, the generated
  24  // binary is used for subsequent test harnesses. The executable file is not cleaned up, but since it lives at a static
  25  // path in a temp directory, it is not a big deal.
  26  func podExecutablePath() (string, error) {
  27  	compileMtx.Lock()
  28  	defer compileMtx.Unlock()
  29  	// If pod has already been compiled, just use that.
  30  	if len(executablePath) != 0 {
  31  		return executablePath, nil
  32  	}
  33  	testDir, e := baseDir()
  34  	if e != nil {
  35  		return "", e
  36  	}
  37  	// Determine import path of this package. Not necessarily pod if this is a forked repo.
  38  	_, rpctestDir, _, ok := runtime.Caller(1)
  39  	if !ok {
  40  		return "", fmt.Errorf("cannot get path to pod source code")
  41  	}
  42  	podPkgPath := filepath.Join(rpctestDir, "..", "..", "..")
  43  	podPkg, e := build.ImportDir(podPkgPath, build.FindOnly)
  44  	if e != nil {
  45  		return "", fmt.Errorf("failed to podbuild pod: %v", e)
  46  	}
  47  	// Build pod and output an executable in a static temp path.
  48  	outputPath := filepath.Join(testDir, "pod")
  49  	if runtime.GOOS == "windows" {
  50  		outputPath += ".exe"
  51  	}
  52  	var gb string
  53  	if gb, e = gobin.Get(); E.Chk(e) {
  54  		return "", e
  55  	}
  56  	cmd := exec.Command(gb, "podbuild", "-o", outputPath, podPkg.ImportPath)
  57  	e = cmd.Run()
  58  	if e != nil {
  59  		return "", fmt.Errorf("failed to podbuild pod: %v", e)
  60  	}
  61  	// Save executable path so future calls do not recompile.
  62  	executablePath = outputPath
  63  	return executablePath, nil
  64  }
  65