func (n *node) Cleanup() error {
	if n.pidFile != "" {
		if err := os.Remove(n.pidFile); err != nil {
			log.Printf("unable to remove file %s: %v", n.pidFile,
				err)
		}
	}
	return n.config.cleanup()
}
Cleanup cleanups process and args files. The file housing the pid of the
created process will be deleted, as well as any directories created by the
process.
package rpctest
import (
	"crypto/elliptic"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"os/exec"
	"runtime"
	"strings"
	"time"
	"github.com/HcashOrg/hcashd/wire"
	rpc "github.com/HcashOrg/hcashrpcclient"
	"github.com/HcashOrg/hcashutil"
)
type nodeConfig struct {
	rpcUser    string
	rpcPass    string
	listen     string
	rpcListen  string
	rpcConnect string
	profile    string
	debugLevel string
	extra      []string
	appDataDir string
	exe          string
	endpoint     string
	certFile     string
	keyFile      string
	certificates []byte
}
func newConfig(appDataDir, certFile, keyFile string, extra []string) (*nodeConfig, error) {
	a := &nodeConfig{
		listen:     "127.0.0.1:18555",
		rpcListen:  "127.0.0.1:19556",
		rpcUser:    "user",
		rpcPass:    "pass",
		extra:      extra,
		appDataDir: appDataDir,
		exe:      "hcashd",
		endpoint: "ws",
		certFile: certFile,
		keyFile:  keyFile,
	}
	if err := a.setDefaults(); err != nil {
		return nil, err
	}
	return a, nil
}
func (n *nodeConfig) setDefaults() error {
	cert, err := ioutil.ReadFile(n.certFile)
	if err != nil {
		return err
	}
	n.certificates = cert
	return nil
}
func (n *nodeConfig) arguments() []string {
	args := []string{}
	args = append(args, fmt.Sprintf("--%s", strings.ToLower(wire.SimNet.String())))
	if n.rpcUser != "" {
		args = append(args, fmt.Sprintf("--rpcuser=%s", n.rpcUser))
	}
	if n.rpcPass != "" {
		args = append(args, fmt.Sprintf("--rpcpass=%s", n.rpcPass))
	}
	if n.listen != "" {
		args = append(args, fmt.Sprintf("--listen=%s", n.listen))
	}
	if n.rpcListen != "" {
		args = append(args, fmt.Sprintf("--rpclisten=%s", n.rpcListen))
	}
	if n.rpcConnect != "" {
		args = append(args, fmt.Sprintf("--rpcconnect=%s", n.rpcConnect))
	}
	args = append(args, fmt.Sprintf("--rpccert=%s", n.certFile))
	args = append(args, fmt.Sprintf("--rpckey=%s", n.keyFile))
	args = append(args, fmt.Sprintf("--appdata=%s", n.appDataDir))
	if n.profile != "" {
		args = append(args, fmt.Sprintf("--profile=%s", n.profile))
	}
	if n.debugLevel != "" {
		args = append(args, fmt.Sprintf("--debuglevel=%s", n.debugLevel))
	}
	args = append(args, "--txindex")
	args = append(args, "--addrindex")
	args = append(args, n.extra...)
	return args
}
func (n *nodeConfig) command() *exec.Cmd {
	return exec.Command(n.exe, n.arguments()...)
}
func (n *nodeConfig) rpcConnConfig() rpc.ConnConfig {
	return rpc.ConnConfig{
		Host:                 n.rpcListen,
		Endpoint:             n.endpoint,
		User:                 n.rpcUser,
		Pass:                 n.rpcPass,
		Certificates:         n.certificates,
		DisableAutoReconnect: true,
	}
}
func (n *nodeConfig) String() string {
	return n.appDataDir
}
func (n *nodeConfig) cleanup() error {
	return os.RemoveAll(n.appDataDir)
}
type node struct {
	config *nodeConfig
	cmd     *exec.Cmd
	pidFile string
	dataDir string
}
func newNode(config *nodeConfig, dataDir string) (*node, error) {
	return &node{
		config:  config,
		dataDir: dataDir,
		cmd:     config.command(),
	}, nil
}
func (n *node) Start() error {
	if err := n.cmd.Start(); err != nil {
		return err
	}
	pid, err := os.Create(fmt.Sprintf("%s.pid", n.config))
	if err != nil {
		return err
	}
	n.pidFile = pid.Name()
	if _, err = fmt.Fprintf(pid, "%d\n", n.cmd.Process.Pid); err != nil {
		return err
	}
	if err := pid.Close(); err != nil {
		return err
	}
	return nil
}
func (n *node) FullCommand() string {
	args := strings.Join(n.cmd.Args, " ")
	return n.cmd.Path + args
}
func (n *node) CertFile() string {
	return n.config.certFile
}
func (n *node) Stop() error {
	if n.cmd == nil || n.cmd.Process == nil {
		return nil
	}
	defer n.cmd.Wait()
	if runtime.GOOS == "windows" {
		return n.cmd.Process.Signal(os.Kill)
	}
	return n.cmd.Process.Signal(os.Interrupt)
}