2018-04-24 17:55:15 -07:00
|
|
|
package tests
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
2019-02-08 12:45:23 -08:00
|
|
|
"os"
|
2019-06-05 16:26:17 -07:00
|
|
|
"strings"
|
2019-02-08 13:45:41 -08:00
|
|
|
"testing"
|
2018-04-24 17:55:15 -07:00
|
|
|
"time"
|
|
|
|
|
2019-02-08 13:45:41 -08:00
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
2018-06-13 17:41:01 -07:00
|
|
|
tmclient "github.com/tendermint/tendermint/rpc/client"
|
2018-04-24 17:55:15 -07:00
|
|
|
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
|
|
|
rpcclient "github.com/tendermint/tendermint/rpc/lib/client"
|
2019-06-05 16:26:17 -07:00
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
2018-04-24 17:55:15 -07:00
|
|
|
)
|
|
|
|
|
2018-06-13 18:33:09 -07:00
|
|
|
// Wait for the next tendermint block from the Tendermint RPC
|
|
|
|
// on localhost
|
2018-06-13 17:41:01 -07:00
|
|
|
func WaitForNextHeightTM(port string) {
|
2018-06-25 14:53:48 -07:00
|
|
|
WaitForNextNBlocksTM(1, port)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for N tendermint blocks to pass using the Tendermint RPC
|
|
|
|
// on localhost
|
|
|
|
func WaitForNextNBlocksTM(n int64, port string) {
|
2018-07-02 21:33:53 -07:00
|
|
|
// get the latest block and wait for n more
|
2018-06-13 17:41:01 -07:00
|
|
|
url := fmt.Sprintf("http://localhost:%v", port)
|
2020-01-16 13:46:51 -08:00
|
|
|
cl, err := tmclient.NewHTTP(url, "/websocket")
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("failed to create Tendermint HTTP client: %s", err))
|
|
|
|
}
|
|
|
|
|
2018-07-02 21:33:53 -07:00
|
|
|
var height int64
|
2020-01-16 13:46:51 -08:00
|
|
|
|
|
|
|
resBlock, err := cl.Block(nil)
|
2018-07-02 21:33:53 -07:00
|
|
|
if err != nil || resBlock.Block == nil {
|
|
|
|
// wait for the first block to exist
|
|
|
|
WaitForHeightTM(1, port)
|
|
|
|
height = 1 + n
|
|
|
|
} else {
|
|
|
|
height = resBlock.Block.Height + n
|
2018-06-13 17:41:01 -07:00
|
|
|
}
|
2020-01-16 13:46:51 -08:00
|
|
|
|
2018-07-02 21:33:53 -07:00
|
|
|
waitForHeightTM(height, url)
|
2018-06-13 17:41:01 -07:00
|
|
|
}
|
|
|
|
|
2018-06-13 18:33:09 -07:00
|
|
|
// Wait for the given height from the Tendermint RPC
|
|
|
|
// on localhost
|
2018-06-13 17:41:01 -07:00
|
|
|
func WaitForHeightTM(height int64, port string) {
|
|
|
|
url := fmt.Sprintf("http://localhost:%v", port)
|
|
|
|
waitForHeightTM(height, url)
|
|
|
|
}
|
|
|
|
|
|
|
|
func waitForHeightTM(height int64, url string) {
|
2020-01-16 13:46:51 -08:00
|
|
|
cl, err := tmclient.NewHTTP(url, "/websocket")
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("failed to create Tendermint HTTP client: %s", err))
|
|
|
|
}
|
|
|
|
|
2018-04-24 17:55:15 -07:00
|
|
|
for {
|
2018-06-13 17:41:01 -07:00
|
|
|
// get url, try a few times
|
|
|
|
var resBlock *ctypes.ResultBlock
|
|
|
|
var err error
|
|
|
|
INNER:
|
|
|
|
for i := 0; i < 5; i++ {
|
|
|
|
resBlock, err = cl.Block(nil)
|
|
|
|
if err == nil {
|
|
|
|
break INNER
|
|
|
|
}
|
|
|
|
time.Sleep(time.Millisecond * 200)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-04-24 17:55:15 -07:00
|
|
|
|
2019-08-03 06:56:15 -07:00
|
|
|
if resBlock.Block != nil && resBlock.Block.Height >= height {
|
2018-06-13 17:41:01 -07:00
|
|
|
return
|
|
|
|
}
|
2019-08-03 06:56:15 -07:00
|
|
|
|
2018-06-13 17:41:01 -07:00
|
|
|
time.Sleep(time.Millisecond * 100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-13 18:33:09 -07:00
|
|
|
// Wait for height from the LCD API on localhost
|
2018-06-13 17:41:01 -07:00
|
|
|
func WaitForHeight(height int64, port string) {
|
|
|
|
url := fmt.Sprintf("http://localhost:%v/blocks/latest", port)
|
|
|
|
waitForHeight(height, url)
|
|
|
|
}
|
2018-05-31 18:46:25 -07:00
|
|
|
|
2018-06-19 15:29:54 -07:00
|
|
|
// Whether or not an HTTP status code was "successful"
|
|
|
|
func StatusOK(statusCode int) bool {
|
|
|
|
switch statusCode {
|
|
|
|
case http.StatusOK:
|
|
|
|
case http.StatusCreated:
|
|
|
|
case http.StatusNoContent:
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
2018-06-13 17:41:01 -07:00
|
|
|
func waitForHeight(height int64, url string) {
|
2018-06-30 16:32:52 -07:00
|
|
|
var res *http.Response
|
|
|
|
var err error
|
2019-08-03 06:56:15 -07:00
|
|
|
|
2018-06-13 17:41:01 -07:00
|
|
|
for {
|
2019-06-26 13:30:36 -07:00
|
|
|
// Since this is in a testing file we are accepting nolint to be passed
|
2019-10-14 08:43:19 -07:00
|
|
|
res, err = http.Get(url) // nolint:gosec
|
2018-04-24 17:55:15 -07:00
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
body, err := ioutil.ReadAll(res.Body)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2019-08-03 06:56:15 -07:00
|
|
|
|
|
|
|
if err = res.Body.Close(); err != nil {
|
2018-06-28 15:52:10 -07:00
|
|
|
panic(err)
|
|
|
|
}
|
2018-04-24 17:55:15 -07:00
|
|
|
|
2018-05-31 18:46:25 -07:00
|
|
|
var resultBlock ctypes.ResultBlock
|
2019-08-03 06:56:15 -07:00
|
|
|
if err = cdc.UnmarshalJSON(body, &resultBlock); err != nil {
|
2018-04-24 17:55:15 -07:00
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2019-08-03 06:56:15 -07:00
|
|
|
if resultBlock.Block != nil && resultBlock.Block.Height >= height {
|
2018-04-24 17:55:15 -07:00
|
|
|
return
|
|
|
|
}
|
2019-08-03 06:56:15 -07:00
|
|
|
|
2018-04-24 17:55:15 -07:00
|
|
|
time.Sleep(time.Millisecond * 100)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-02 21:33:53 -07:00
|
|
|
// wait for tendermint to start by querying the LCD
|
|
|
|
func WaitForLCDStart(port string) {
|
2018-06-30 16:32:52 -07:00
|
|
|
url := fmt.Sprintf("http://localhost:%v/blocks/latest", port)
|
2018-07-02 21:33:53 -07:00
|
|
|
WaitForStart(url)
|
|
|
|
}
|
|
|
|
|
|
|
|
// wait for tendermint to start by querying tendermint
|
|
|
|
func WaitForTMStart(port string) {
|
|
|
|
url := fmt.Sprintf("http://localhost:%v/block", port)
|
|
|
|
WaitForStart(url)
|
|
|
|
}
|
|
|
|
|
|
|
|
// WaitForStart waits for the node to start by pinging the url
|
2018-12-04 01:57:44 -08:00
|
|
|
// every 100ms for 10s until it returns 200. If it takes longer than 5s,
|
2018-07-02 21:33:53 -07:00
|
|
|
// it panics.
|
|
|
|
func WaitForStart(url string) {
|
|
|
|
var err error
|
2018-04-24 17:55:15 -07:00
|
|
|
|
2018-06-30 16:32:52 -07:00
|
|
|
// ping the status endpoint a few times a second
|
|
|
|
// for a few seconds until we get a good response.
|
|
|
|
// otherwise something probably went wrong
|
2018-12-04 01:57:44 -08:00
|
|
|
for i := 0; i < 100; i++ {
|
2018-06-30 16:32:52 -07:00
|
|
|
time.Sleep(time.Millisecond * 100)
|
2018-05-31 18:46:25 -07:00
|
|
|
|
|
|
|
var res *http.Response
|
2019-10-14 08:43:19 -07:00
|
|
|
res, err = http.Get(url) // nolint:gosec
|
2018-06-30 16:32:52 -07:00
|
|
|
if err != nil || res == nil {
|
2018-05-31 18:46:25 -07:00
|
|
|
continue
|
2018-04-24 17:55:15 -07:00
|
|
|
}
|
2018-07-02 21:33:53 -07:00
|
|
|
// body, _ := ioutil.ReadAll(res.Body)
|
|
|
|
// fmt.Println("BODY", string(body))
|
2018-06-30 16:32:52 -07:00
|
|
|
err = res.Body.Close()
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
2018-04-24 17:55:15 -07:00
|
|
|
|
2018-06-30 16:32:52 -07:00
|
|
|
if res.StatusCode == http.StatusOK {
|
|
|
|
// good!
|
2018-04-24 17:55:15 -07:00
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2018-06-30 16:32:52 -07:00
|
|
|
// still haven't started up?! panic!
|
|
|
|
panic(err)
|
2018-04-24 17:55:15 -07:00
|
|
|
}
|
|
|
|
|
2018-05-31 18:46:25 -07:00
|
|
|
// TODO: these functions just print to Stdout.
|
|
|
|
// consider using the logger.
|
|
|
|
|
2018-04-24 17:55:15 -07:00
|
|
|
// Wait for the RPC server to respond to /status
|
|
|
|
func WaitForRPC(laddr string) {
|
|
|
|
fmt.Println("LADDR", laddr)
|
2020-01-16 13:46:51 -08:00
|
|
|
client, err := rpcclient.NewJSONRPCClient(laddr)
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("failed to create Tendermint RPC client: %s", err))
|
|
|
|
}
|
|
|
|
|
2018-04-24 17:55:15 -07:00
|
|
|
ctypes.RegisterAmino(client.Codec())
|
|
|
|
result := new(ctypes.ResultStatus)
|
|
|
|
for {
|
|
|
|
_, err := client.Call("status", map[string]interface{}{}, result)
|
|
|
|
if err == nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
fmt.Printf("Waiting for RPC server to start on %s:%v\n", laddr, err)
|
|
|
|
time.Sleep(time.Millisecond)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-08-31 08:20:06 -07:00
|
|
|
// ExtractPortFromAddress extract port from listenAddress
|
|
|
|
// The listenAddress must be some strings like tcp://0.0.0.0:12345
|
|
|
|
func ExtractPortFromAddress(listenAddress string) string {
|
|
|
|
stringList := strings.Split(listenAddress, ":")
|
|
|
|
length := len(stringList)
|
|
|
|
if length != 3 {
|
|
|
|
panic(fmt.Errorf("expected listen address: tcp://0.0.0.0:12345, got %s", listenAddress))
|
|
|
|
}
|
|
|
|
return stringList[2]
|
|
|
|
}
|
|
|
|
|
2019-02-08 13:45:41 -08:00
|
|
|
// NewTestCaseDir creates a new temporary directory for a test case.
|
|
|
|
// Returns the directory path and a cleanup function.
|
|
|
|
// nolint: errcheck
|
|
|
|
func NewTestCaseDir(t *testing.T) (string, func()) {
|
|
|
|
dir, err := ioutil.TempDir("", t.Name()+"_")
|
|
|
|
require.NoError(t, err)
|
|
|
|
return dir, func() { os.RemoveAll(dir) }
|
|
|
|
}
|
|
|
|
|
2019-06-05 16:26:17 -07:00
|
|
|
var cdc = codec.New()
|
2018-04-24 17:55:15 -07:00
|
|
|
|
|
|
|
func init() {
|
|
|
|
ctypes.RegisterAmino(cdc)
|
|
|
|
}
|
2019-06-26 13:30:36 -07:00
|
|
|
|
|
|
|
//DONTCOVER
|