status-go/geth/testing/testing.go

158 lines
4.2 KiB
Go

package testing
import (
"bytes"
"context"
"io"
"os"
"path/filepath"
"strconv"
"strings"
gethcommon "github.com/ethereum/go-ethereum/common"
"github.com/status-im/status-go/geth/common"
"github.com/status-im/status-go/geth/log"
"github.com/status-im/status-go/geth/params"
assertions "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
var (
// TestConfig defines the default config usable at package-level.
TestConfig *common.TestConfig
// RootDir is the main application directory
RootDir string
// TestDataDir is data directory used for tests
TestDataDir string
// TestNetworkNames network ID to name mapping
TestNetworkNames = map[int]string{
params.MainNetworkID: "Mainnet",
params.RopstenNetworkID: "Ropsten",
params.RinkebyNetworkID: "Rinkeby",
}
)
func init() {
pwd, err := os.Getwd()
if err != nil {
panic(err)
}
// setup root directory
RootDir = filepath.Dir(pwd)
if strings.HasSuffix(RootDir, "geth") || strings.HasSuffix(RootDir, "cmd") { // we need to hop one more level
RootDir = filepath.Join(RootDir, "..")
}
// setup auxiliary directories
TestDataDir = filepath.Join(RootDir, ".ethereumtest")
TestConfig, err = common.LoadTestConfig()
if err != nil {
panic(err)
}
log.SetLevel("ERROR")
}
// BaseTestSuite defines a base tests suit which others suites can embedded to
// access initialization methods useful for testing.
type BaseTestSuite struct {
suite.Suite
NodeManager common.NodeManager
}
// StartTestNode initiazes a NodeManager instances with configuration retrieved
// from the test config.
func (s *BaseTestSuite) StartTestNode(networkID int, upstream bool) {
require := s.Require()
require.NotNil(s.NodeManager)
nodeConfig, err := MakeTestNodeConfig(networkID)
require.NoError(err)
nodeConfig.UpstreamConfig.Enabled = upstream
require.Equal(nodeConfig.UpstreamConfig.Enabled, upstream)
keyStoreDir := filepath.Join(TestDataDir, TestNetworkNames[networkID], "keystore")
require.NoError(common.ImportTestAccount(keyStoreDir, "test-account1.pk"))
require.NoError(common.ImportTestAccount(keyStoreDir, "test-account2.pk"))
require.False(s.NodeManager.IsNodeRunning())
nodeStarted, err := s.NodeManager.StartNode(nodeConfig)
require.NoError(err)
require.NotNil(nodeStarted)
<-nodeStarted
require.True(s.NodeManager.IsNodeRunning())
}
// StopTestNode attempts to stop initialized NodeManager.
func (s *BaseTestSuite) StopTestNode() {
require := s.Require()
require.NotNil(s.NodeManager)
require.True(s.NodeManager.IsNodeRunning())
nodeStopped, err := s.NodeManager.StopNode()
require.NoError(err)
<-nodeStopped
require.False(s.NodeManager.IsNodeRunning())
}
// FirstBlockHash validates Attach operation for the NodeManager.
func FirstBlockHash(require *assertions.Assertions, nodeManager common.NodeManager, expectedHash string) {
require.NotNil(nodeManager)
var firstBlock struct {
Hash gethcommon.Hash `json:"hash"`
}
// obtain RPC client for running node
runningNode, err := nodeManager.Node()
require.NoError(err)
require.NotNil(runningNode)
rpcClient, err := runningNode.Attach()
require.NoError(err)
// get first block
err = rpcClient.CallContext(context.Background(), &firstBlock, "eth_getBlockByNumber", "0x0", true)
require.NoError(err)
require.Equal(expectedHash, firstBlock.Hash.Hex())
}
// MakeTestNodeConfig defines a function to return a giving params.NodeConfig
// where specific network addresses are assigned based on provieded network id.
func MakeTestNodeConfig(networkID int) (*params.NodeConfig, error) {
configJSON := `{
"NetworkId": ` + strconv.Itoa(networkID) + `,
"DataDir": "` + filepath.Join(TestDataDir, TestNetworkNames[networkID]) + `",
"HTTPPort": ` + strconv.Itoa(TestConfig.Node.HTTPPort) + `,
"WSPort": ` + strconv.Itoa(TestConfig.Node.WSPort) + `,
"LogEnabled": true,
"LogLevel": "ERROR"
}`
nodeConfig, err := params.LoadNodeConfig(configJSON)
if err != nil {
return nil, err
}
return nodeConfig, nil
}
// LoadFromFile is useful for loading test data, from testdata/filename into a variable
// nolint: errcheck
func LoadFromFile(filename string) string {
f, err := os.Open(filename)
if err != nil {
return ""
}
buf := bytes.NewBuffer(nil)
io.Copy(buf, f)
f.Close()
return string(buf.Bytes())
}