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 }