using actual running servers + http calls to test REST

This commit is contained in:
Fabian 2018-03-12 13:49:29 +01:00 committed by Ethan Buchman
parent 8858371c43
commit b3532e2d2b
2 changed files with 92 additions and 171 deletions

View File

@ -4,8 +4,8 @@ import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"os"
"regexp"
"testing"
@ -15,8 +15,7 @@ import (
"github.com/cosmos/cosmos-sdk/baseapp"
"github.com/cosmos/cosmos-sdk/client"
keys "github.com/cosmos/cosmos-sdk/client/keys"
"github.com/cosmos/cosmos-sdk/examples/basecoin/app"
"github.com/cosmos/cosmos-sdk/server"
"github.com/cosmos/cosmos-sdk/tests"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -29,22 +28,20 @@ import (
)
func TestKeys(t *testing.T) {
_, db, err := initKeybase(t)
require.Nil(t, err, "Couldn't init Keybase")
cdc := app.MakeCodec()
r := initRouter(cdc)
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
// empty keys
res := request(t, r, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
body := res.Body.String()
res, body := request(t, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
assert.Equal(t, body, "[]", "Expected an empty array")
// get seed
res = request(t, r, "GET", "/keys/seed", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
seed := res.Body.String()
res, body = request(t, "GET", "/keys/seed", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
seed := body
reg, err := regexp.Compile(`([a-z]+ ){12}`)
require.Nil(t, err)
match := reg.MatchString(seed)
@ -52,20 +49,20 @@ func TestKeys(t *testing.T) {
// add key
var jsonStr = []byte(`{"name":"test_fail", "password":"1234567890"}`)
res = request(t, r, "POST", "/keys", jsonStr)
res, body = request(t, "POST", "/keys", jsonStr)
assert.Equal(t, http.StatusBadRequest, res.Code, "Account creation should require a seed")
assert.Equal(t, http.StatusBadRequest, res.StatusCode, "Account creation should require a seed")
jsonStr = []byte(fmt.Sprintf(`{"name":"test", "password":"1234567890", "seed": "%s"}`, seed))
res = request(t, r, "POST", "/keys", jsonStr)
res, body = request(t, "POST", "/keys", jsonStr)
assert.Equal(t, http.StatusOK, res.Code, res.Body.String())
addr := res.Body.String()
assert.Equal(t, http.StatusOK, res.StatusCode, body)
addr := body
assert.Len(t, addr, 40, "Returned address has wrong format", addr)
// existing keys
res = request(t, r, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "GET", "/keys", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m [1]keys.KeyOutput
decoder := json.NewDecoder(res.Body)
err = decoder.Decode(&m)
@ -75,8 +72,8 @@ func TestKeys(t *testing.T) {
assert.Equal(t, m[0].Address, addr, "Did not serve keys Address correctly")
// select key
res = request(t, r, "GET", "/keys/test", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "GET", "/keys/test", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m2 keys.KeyOutput
decoder = json.NewDecoder(res.Body)
err = decoder.Decode(&m2)
@ -86,52 +83,46 @@ func TestKeys(t *testing.T) {
// update key
jsonStr = []byte(`{"old_password":"1234567890", "new_password":"12345678901"}`)
res = request(t, r, "PUT", "/keys/test", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "PUT", "/keys/test", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// here it should say unauthorized as we changed the password before
res = request(t, r, "PUT", "/keys/test", jsonStr)
require.Equal(t, http.StatusUnauthorized, res.Code, res.Body.String())
res, body = request(t, "PUT", "/keys/test", jsonStr)
require.Equal(t, http.StatusUnauthorized, res.StatusCode, body)
// delete key
jsonStr = []byte(`{"password":"12345678901"}`)
res = request(t, r, "DELETE", "/keys/test", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "DELETE", "/keys/test", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
db.Close()
}
func TestVersion(t *testing.T) {
prepareClient(t)
cdc := app.MakeCodec()
r := initRouter(cdc)
// node info
res := request(t, r, "GET", "/version", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
reg, err := regexp.Compile(`\d+\.\d+\.\d+(-dev)?`)
require.Nil(t, err)
match := reg.MatchString(res.Body.String())
assert.True(t, match, res.Body.String())
}
func TestNodeStatus(t *testing.T) {
//ch := server.StartServer(t)
//defer close(ch)
//prepareClient(t)
//cdc := app.MakeCodec() // TODO refactor so that cdc is included from a common test init function
//r := initRouter(cdc)
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
// node info
res := request(t, r, "GET", "/node_info", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body := request(t, "GET", "/version", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
reg, err := regexp.Compile(`\d+\.\d+\.\d+(-dev)?`)
require.Nil(t, err)
match := reg.MatchString(body)
assert.True(t, match, body)
}
func TestNodeStatus(t *testing.T) {
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
// node info
res, body := request(t, "GET", "/node_info", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m p2p.NodeInfo
decoder := json.NewDecoder(res.Body)
@ -141,22 +132,20 @@ func TestNodeStatus(t *testing.T) {
assert.NotEqual(t, p2p.NodeInfo{}, m, "res: %v", res)
// syncing
res = request(t, r, "GET", "/syncing", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "GET", "/syncing", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
assert.Equal(t, "true", res.Body.String())
assert.Equal(t, "true", body)
}
func TestBlock(t *testing.T) {
_, _ = startServer(t)
// TODO need to kill server after
prepareClient(t)
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
cdc := app.MakeCodec()
r := initRouter(cdc)
// res := request(t, r, "GET", "/blocks/latest", nil)
// require.Equal(t, http.StatusOK, res.Code, res.Body.String())
// res, body := request(t, "GET", "/blocks/latest", nil)
// require.Equal(t, http.StatusOK, res.StatusCode, body)
// var m ctypes.ResultBlock
// decoder := json.NewDecoder(res.Body)
@ -167,8 +156,8 @@ func TestBlock(t *testing.T) {
// --
res := request(t, r, "GET", "/blocks/1", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body := request(t, "GET", "/blocks/1", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m ctypes.ResultBlock
decoder := json.NewDecoder(res.Body)
@ -179,19 +168,18 @@ func TestBlock(t *testing.T) {
// --
res = request(t, r, "GET", "/blocks/2", nil)
require.Equal(t, http.StatusNotFound, res.Code, res.Body.String())
res, body = request(t, "GET", "/blocks/2", nil)
require.Equal(t, http.StatusNotFound, res.StatusCode, body)
}
func TestValidators(t *testing.T) {
_, _ = startServer(t)
// TODO need to kill server after
prepareClient(t)
cdc := app.MakeCodec()
r := initRouter(cdc)
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
// res := request(t, r, "GET", "/validatorsets/latest", nil)
// require.Equal(t, http.StatusOK, res.Code, res.Body.String())
// res, body := request(t, "GET", "/validatorsets/latest", nil)
// require.Equal(t, http.StatusOK, res.StatusCode, body)
// var m ctypes.ResultValidators
// decoder := json.NewDecoder(res.Body)
@ -202,8 +190,8 @@ func TestValidators(t *testing.T) {
// --
res := request(t, r, "GET", "/validatorsets/1", nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body := request(t, "GET", "/validatorsets/1", nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
var m ctypes.ResultValidators
decoder := json.NewDecoder(res.Body)
@ -214,17 +202,15 @@ func TestValidators(t *testing.T) {
// --
res = request(t, r, "GET", "/validatorsets/2", nil)
require.Equal(t, http.StatusNotFound, res.Code)
res, body = request(t, "GET", "/validatorsets/2", nil)
require.Equal(t, http.StatusNotFound, res.StatusCode)
}
func TestCoinSend(t *testing.T) {
ch := server.StartServer(t)
defer close(ch)
prepareClient(t)
cdc := app.MakeCodec()
r := initRouter(cdc)
err := tests.InitServer()
require.Nil(t, err)
err := tests.StartServer()
require.Nil(t, err)
// TODO make that account has coins
kb := client.MockKeyBase()
@ -233,12 +219,12 @@ func TestCoinSend(t *testing.T) {
addr := string(info.Address())
// query empty
res := request(t, r, "GET", "/accounts/1234567890123456789012345678901234567890", nil)
require.Equal(t, http.StatusNoContent, res.Code, res.Body.String())
res, body := request(t, "GET", "/accounts/1234567890123456789012345678901234567890", nil)
require.Equal(t, http.StatusNoContent, res.StatusCode, body)
// query
res = request(t, r, "GET", "/accounts/"+addr, nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "GET", "/accounts/"+addr, nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
assert.Equal(t, `{
"coins": [
@ -247,12 +233,12 @@ func TestCoinSend(t *testing.T) {
"amount": 9007199254740992
}
]
}`, res.Body.String())
}`, body)
// create account to send in keybase
var jsonStr = []byte(fmt.Sprintf(`{"name":"test", "password":"1234567890", "seed": "%s"}`, seed))
res = request(t, r, "POST", "/keys", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "POST", "/keys", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// create receive address
receiveInfo, _, err := kb.Create("receive_address", "1234567890", cryptoKeys.CryptoAlgo("ed25519"))
@ -268,12 +254,12 @@ func TestCoinSend(t *testing.T) {
"amount": 1
}]
}`)
res = request(t, r, "POST", "/accounts/"+receiveAddr+"/send", jsonStr)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "POST", "/accounts/"+receiveAddr+"/send", jsonStr)
require.Equal(t, http.StatusOK, res.StatusCode, body)
// check if received
res = request(t, r, "GET", "/accounts/"+receiveAddr, nil)
require.Equal(t, http.StatusOK, res.Code, res.Body.String())
res, body = request(t, "GET", "/accounts/"+receiveAddr, nil)
require.Equal(t, http.StatusOK, res.StatusCode, body)
assert.Equal(t, `{
"coins": [
@ -282,7 +268,7 @@ func TestCoinSend(t *testing.T) {
"amount": 1
}
]
}`, res.Body.String())
}`, body)
}
//__________________________________________________________
@ -301,86 +287,21 @@ func prepareClient(t *testing.T) {
app.Commit()
}
// setupViper creates a homedir to run inside,
// and returns a cleanup function to defer
func setupViper() func() {
rootDir, err := ioutil.TempDir("", "mock-sdk-cmd")
if err != nil {
panic(err) // fuck it!
func request(t *testing.T, method string, path string, payload []byte) (*http.Response, string) {
var res *http.Response
var err error
if method == "GET" {
res, err = http.Get(path)
}
viper.Set("home", rootDir)
return func() {
os.RemoveAll(rootDir)
if method == "POST" {
res, err = http.Post(path, "application/json", bytes.NewBuffer(payload))
}
}
// from baseoind.main
func defaultOptions(addr string) func(args []string) (json.RawMessage, error) {
return func(args []string) (json.RawMessage, error) {
opts := fmt.Sprintf(`{
"accounts": [{
"address": "%s",
"coins": [
{
"denom": "mycoin",
"amount": 9007199254740992
}
]
}]
}`, addr)
return json.RawMessage(opts), nil
}
}
func startServer(t *testing.T) (types.Address, string) {
defer setupViper()()
// init server
addr, secret, err := server.GenerateCoinKey()
require.NoError(t, err)
initCmd := server.InitCmd(defaultOptions(addr.String()), log.NewNopLogger())
err = initCmd.RunE(nil, nil)
require.NoError(t, err)
// start server
viper.Set("with-tendermint", true)
startCmd := server.StartCmd(mock.NewApp, log.NewNopLogger())
timeout := time.Duration(3) * time.Second
err = runOrTimeout(startCmd, timeout)
output, err := ioutil.ReadAll(res.Body)
require.NoError(t, err)
return addr, secret
}
// copied from server/start_test.go
func runOrTimeout(cmd *cobra.Command, timeout time.Duration) error {
done := make(chan error)
go func(out chan<- error) {
// this should NOT exit
err := cmd.RunE(nil, nil)
if err != nil {
out <- err
}
out <- fmt.Errorf("start died for unknown reasons")
}(done)
timer := time.NewTimer(timeout)
select {
case err := <-done:
return err
case <-timer.C:
return nil
}
}
func request(t *testing.T, r http.Handler, method string, path string, payload []byte) *httptest.ResponseRecorder {
req, err := http.NewRequest(method, path, bytes.NewBuffer(payload))
require.Nil(t, err)
res := httptest.NewRecorder()
r.ServeHTTP(res, req)
return res
return res, string(output)
}
func initKeybase(t *testing.T) (cryptoKeys.Keybase, *dbm.GoLevelDB, error) {