github.com/braveheart12/just@v0.8.7/functest/utils_test.go (about)

     1  // +build functest
     2  
     3  /*
     4   *    Copyright 2019 Insolar Technologies
     5   *
     6   *    Licensed under the Apache License, Version 2.0 (the "License");
     7   *    you may not use this file except in compliance with the License.
     8   *    You may obtain a copy of the License at
     9   *
    10   *        http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   *    Unless required by applicable law or agreed to in writing, software
    13   *    distributed under the License is distributed on an "AS IS" BASIS,
    14   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   *    See the License for the specific language governing permissions and
    16   *    limitations under the License.
    17   */
    18  
    19  package functest
    20  
    21  import (
    22  	"bytes"
    23  	"context"
    24  	"encoding/json"
    25  	"fmt"
    26  	"io/ioutil"
    27  	"net"
    28  	"net/http"
    29  	"strings"
    30  	"testing"
    31  	"time"
    32  
    33  	"github.com/pkg/errors"
    34  
    35  	"github.com/insolar/insolar/api/requester"
    36  	"github.com/insolar/insolar/platformpolicy"
    37  	"github.com/stretchr/testify/require"
    38  )
    39  
    40  const sendRetryCount = 5
    41  
    42  type postParams map[string]interface{}
    43  
    44  type RPCResponseInterface interface {
    45  	getRPCVersion() string
    46  	getError() map[string]interface{}
    47  }
    48  
    49  type RPCResponse struct {
    50  	RPCVersion string                 `json:"jsonrpc"`
    51  	Error      map[string]interface{} `json:"error"`
    52  }
    53  
    54  func (r *RPCResponse) getRPCVersion() string {
    55  	return r.RPCVersion
    56  }
    57  
    58  func (r *RPCResponse) getError() map[string]interface{} {
    59  	return r.Error
    60  }
    61  
    62  type getSeedResponse struct {
    63  	RPCResponse
    64  	Result struct {
    65  		Seed    string `json:"Seed"`
    66  		TraceID string `json:"TraceID"`
    67  	} `json:"result"`
    68  }
    69  
    70  type bootstrapNode struct {
    71  	PublicKey string `json:"public_key"`
    72  }
    73  
    74  type infoResponse struct {
    75  	RootDomain string `json:"RootDomain"`
    76  	RootMember string `json:"RootMember"`
    77  	NodeDomain string `json:"NodeDomain"`
    78  	TraceID    string `json:"TraceID"`
    79  }
    80  
    81  type rpcInfoResponse struct {
    82  	RPCResponse
    83  	Result infoResponse `json:"result"`
    84  }
    85  
    86  type statusResponse struct {
    87  	NetworkState    string `json:"NetworkState"`
    88  	WorkingListSize int    `json:"WorkingListSize"`
    89  }
    90  
    91  type rpcStatusResponse struct {
    92  	RPCResponse
    93  	Result statusResponse `json:"result"`
    94  }
    95  
    96  func createMember(t *testing.T, name string) *user {
    97  	member, err := newUserWithKeys()
    98  	require.NoError(t, err)
    99  	result, err := signedRequest(&root, "CreateMember", name, member.pubKey)
   100  	require.NoError(t, err)
   101  	ref, ok := result.(string)
   102  	require.True(t, ok)
   103  	member.ref = ref
   104  	return member
   105  }
   106  
   107  func getBalanceNoErr(t *testing.T, caller *user, reference string) int {
   108  	balance, err := getBalance(caller, reference)
   109  	require.NoError(t, err)
   110  	return balance
   111  }
   112  
   113  func getBalance(caller *user, reference string) (int, error) {
   114  	res, err := signedRequest(caller, "GetBalance", reference)
   115  	if err != nil {
   116  		return 0, err
   117  	}
   118  	amount, ok := res.(float64)
   119  	if !ok {
   120  		return 0, errors.New("result is not int")
   121  	}
   122  	return int(amount), nil
   123  }
   124  
   125  func getRPSResponseBody(t *testing.T, postParams map[string]interface{}) []byte {
   126  	jsonValue, _ := json.Marshal(postParams)
   127  	postResp, err := http.Post(TestRPCUrl, "application/json", bytes.NewBuffer(jsonValue))
   128  	require.NoError(t, err)
   129  	require.Equal(t, http.StatusOK, postResp.StatusCode)
   130  	body, err := ioutil.ReadAll(postResp.Body)
   131  	require.NoError(t, err)
   132  	return body
   133  }
   134  
   135  func getSeed(t *testing.T) string {
   136  	body := getRPSResponseBody(t, postParams{
   137  		"jsonrpc": "2.0",
   138  		"method":  "seed.Get",
   139  		"id":      "",
   140  	})
   141  	getSeedResponse := &getSeedResponse{}
   142  	unmarshalRPCResponse(t, body, getSeedResponse)
   143  	require.NotNil(t, getSeedResponse.Result)
   144  	return getSeedResponse.Result.Seed
   145  }
   146  
   147  func getInfo(t *testing.T) infoResponse {
   148  	body := getRPSResponseBody(t, postParams{
   149  		"jsonrpc": "2.0",
   150  		"method":  "info.Get",
   151  		"id":      "",
   152  	})
   153  	rpcInfoResponse := &rpcInfoResponse{}
   154  	unmarshalRPCResponse(t, body, rpcInfoResponse)
   155  	require.NotNil(t, rpcInfoResponse.Result)
   156  	return rpcInfoResponse.Result
   157  }
   158  
   159  func getStatus(t *testing.T) statusResponse {
   160  	body := getRPSResponseBody(t, postParams{
   161  		"jsonrpc": "2.0",
   162  		"method":  "status.Get",
   163  		"id":      "",
   164  	})
   165  	rpcStatusResponse := &rpcStatusResponse{}
   166  	unmarshalRPCResponse(t, body, rpcStatusResponse)
   167  	require.NotNil(t, rpcStatusResponse.Result)
   168  	return rpcStatusResponse.Result
   169  }
   170  
   171  func unmarshalRPCResponse(t *testing.T, body []byte, response RPCResponseInterface) {
   172  	err := json.Unmarshal(body, &response)
   173  	require.NoError(t, err)
   174  	require.Equal(t, "2.0", response.getRPCVersion())
   175  	require.Nil(t, response.getError())
   176  }
   177  
   178  func unmarshalCallResponse(t *testing.T, body []byte, response *response) {
   179  	err := json.Unmarshal(body, &response)
   180  	require.NoError(t, err)
   181  }
   182  
   183  type response struct {
   184  	Result interface{}
   185  	Error  string
   186  }
   187  
   188  func signedRequest(user *user, method string, params ...interface{}) (interface{}, error) {
   189  	ctx := context.TODO()
   190  	rootCfg, err := requester.CreateUserConfig(user.ref, user.privKey)
   191  	if err != nil {
   192  		return nil, err
   193  	}
   194  	var resp response
   195  	for i := 0; i < sendRetryCount; i++ {
   196  		res, err := requester.Send(ctx, TestAPIURL, rootCfg, &requester.RequestConfigJSON{
   197  			Method: method,
   198  			Params: params,
   199  		})
   200  
   201  		if netErr, ok := errors.Cause(err).(net.Error); ok && netErr.Timeout() {
   202  			fmt.Println("Timeout, retry")
   203  			fmt.Printf("Method: %s\n", method)
   204  			time.Sleep(time.Second)
   205  			continue
   206  		} else if err != nil {
   207  			return nil, err
   208  		}
   209  
   210  		resp = response{}
   211  		err = json.Unmarshal(res, &resp)
   212  		if err != nil {
   213  			return nil, err
   214  		}
   215  
   216  		if resp.Error == "" {
   217  			return resp.Result, nil
   218  		}
   219  		if strings.Contains(resp.Error, "Incorrect message pulse") {
   220  			fmt.Printf("Incorrect message pulse, retry (error - %s)\n", resp.Error)
   221  			fmt.Printf("Method: %s\n", method)
   222  			time.Sleep(time.Second)
   223  			continue
   224  		}
   225  
   226  		if strings.Contains(resp.Error, "Messagebus timeout exceeded") {
   227  			fmt.Println("Messagebus timeout exceeded, retry")
   228  			fmt.Printf("Method: %s\n", method)
   229  			time.Sleep(time.Second)
   230  			continue
   231  		}
   232  
   233  		break
   234  	}
   235  	return resp.Result, errors.New(resp.Error)
   236  }
   237  
   238  func newUserWithKeys() (*user, error) {
   239  	ks := platformpolicy.NewKeyProcessor()
   240  
   241  	privateKey, err := ks.GeneratePrivateKey()
   242  	if err != nil {
   243  		return nil, err
   244  	}
   245  
   246  	privKeyStr, err := ks.ExportPrivateKeyPEM(privateKey)
   247  	if err != nil {
   248  		return nil, err
   249  	}
   250  	publicKey := ks.ExtractPublicKey(privateKey)
   251  	pubKeyStr, err := ks.ExportPublicKeyPEM(publicKey)
   252  	if err != nil {
   253  		return nil, err
   254  	}
   255  	return &user{
   256  		privKey: string(privKeyStr),
   257  		pubKey:  string(pubKeyStr),
   258  	}, nil
   259  }