github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/libs/cosmos-sdk/tests/util.go (about) 1 package tests 2 3 import ( 4 "fmt" 5 "io/ioutil" 6 "net/http" 7 "os" 8 "strings" 9 "testing" 10 "time" 11 12 rpchttp "github.com/fibonacci-chain/fbc/libs/tendermint/rpc/client/http" 13 ctypes "github.com/fibonacci-chain/fbc/libs/tendermint/rpc/core/types" 14 tmjsonrpc "github.com/fibonacci-chain/fbc/libs/tendermint/rpc/jsonrpc/client" 15 "github.com/stretchr/testify/require" 16 17 "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/codec" 18 ) 19 20 // Wait for the next tendermint block from the Tendermint RPC 21 // on localhost 22 func WaitForNextHeightTM(port string) { 23 WaitForNextNBlocksTM(1, port) 24 } 25 26 // Wait for N tendermint blocks to pass using the Tendermint RPC 27 // on localhost 28 func WaitForNextNBlocksTM(n int64, port string) { 29 // get the latest block and wait for n more 30 url := fmt.Sprintf("http://localhost:%v", port) 31 cl, err := rpchttp.New(url, "/websocket") 32 if err != nil { 33 panic(fmt.Sprintf("failed to create Tendermint HTTP client: %s", err)) 34 } 35 36 var height int64 37 38 resBlock, err := cl.Block(nil) 39 if err != nil || resBlock.Block == nil { 40 // wait for the first block to exist 41 WaitForHeightTM(1, port) 42 height = 1 + n 43 } else { 44 height = resBlock.Block.Height + n 45 } 46 47 waitForHeightTM(height, url) 48 } 49 50 // Wait for the given height from the Tendermint RPC 51 // on localhost 52 func WaitForHeightTM(height int64, port string) { 53 url := fmt.Sprintf("http://localhost:%v", port) 54 waitForHeightTM(height, url) 55 } 56 57 func waitForHeightTM(height int64, url string) { 58 cl, err := rpchttp.New(url, "/websocket") 59 if err != nil { 60 panic(fmt.Sprintf("failed to create Tendermint HTTP client: %s", err)) 61 } 62 63 for { 64 // get url, try a few times 65 var resBlock *ctypes.ResultBlock 66 var err error 67 INNER: 68 for i := 0; i < 5; i++ { 69 resBlock, err = cl.Block(nil) 70 if err == nil { 71 break INNER 72 } 73 time.Sleep(time.Millisecond * 200) 74 } 75 if err != nil { 76 panic(err) 77 } 78 79 if resBlock.Block != nil && resBlock.Block.Height >= height { 80 return 81 } 82 83 time.Sleep(time.Millisecond * 100) 84 } 85 } 86 87 // Wait for height from the LCD API on localhost 88 func WaitForHeight(height int64, port string) { 89 url := fmt.Sprintf("http://localhost:%v/blocks/latest", port) 90 waitForHeight(height, url) 91 } 92 93 // Whether or not an HTTP status code was "successful" 94 func StatusOK(statusCode int) bool { 95 switch statusCode { 96 case http.StatusOK: 97 case http.StatusCreated: 98 case http.StatusNoContent: 99 return true 100 } 101 return false 102 } 103 104 func waitForHeight(height int64, url string) { 105 var res *http.Response 106 var err error 107 108 for { 109 // Since this is in a testing file we are accepting nolint to be passed 110 res, err = http.Get(url) // nolint:gosec 111 if err != nil { 112 panic(err) 113 } 114 115 body, err := ioutil.ReadAll(res.Body) 116 if err != nil { 117 panic(err) 118 } 119 120 if err = res.Body.Close(); err != nil { 121 panic(err) 122 } 123 124 var resultBlock ctypes.ResultBlock 125 if err = cdc.UnmarshalJSON(body, &resultBlock); err != nil { 126 panic(err) 127 } 128 129 if resultBlock.Block != nil && resultBlock.Block.Height >= height { 130 return 131 } 132 133 time.Sleep(time.Millisecond * 100) 134 } 135 } 136 137 // wait for tendermint to start by querying the LCD 138 func WaitForLCDStart(port string) { 139 url := fmt.Sprintf("http://localhost:%v/blocks/latest", port) 140 WaitForStart(url) 141 } 142 143 // wait for tendermint to start by querying tendermint 144 func WaitForTMStart(port string) { 145 url := fmt.Sprintf("http://localhost:%v/block", port) 146 WaitForStart(url) 147 } 148 149 // WaitForStart waits for the node to start by pinging the url 150 // every 100ms for 10s until it returns 200. If it takes longer than 5s, 151 // it panics. 152 func WaitForStart(url string) { 153 var err error 154 155 // ping the status endpoint a few times a second 156 // for a few seconds until we get a good response. 157 // otherwise something probably went wrong 158 for i := 0; i < 100; i++ { 159 time.Sleep(time.Millisecond * 100) 160 161 var res *http.Response 162 res, err = http.Get(url) // nolint:gosec 163 if err != nil || res == nil { 164 continue 165 } 166 // body, _ := ioutil.ReadAll(res.Body) 167 // fmt.Println("BODY", string(body)) 168 err = res.Body.Close() 169 if err != nil { 170 panic(err) 171 } 172 173 if res.StatusCode == http.StatusOK { 174 // good! 175 return 176 } 177 } 178 // still haven't started up?! panic! 179 panic(err) 180 } 181 182 // Wait for the RPC server to respond to /status 183 func WaitForRPC(laddr string) { 184 fmt.Println("LADDR", laddr) 185 client, err := tmjsonrpc.New(laddr) 186 if err != nil { 187 panic(fmt.Sprintf("failed to create Tendermint RPC client: %s", err)) 188 } 189 190 ctypes.RegisterAmino(client.Codec()) 191 result := new(ctypes.ResultStatus) 192 for { 193 _, err := client.Call("status", map[string]interface{}{}, result) 194 if err == nil { 195 return 196 } 197 fmt.Printf("Waiting for RPC server to start on %s:%v\n", laddr, err) 198 time.Sleep(time.Millisecond) 199 } 200 } 201 202 // ExtractPortFromAddress extract port from listenAddress 203 // The listenAddress must be some strings like tcp://0.0.0.0:12345 204 func ExtractPortFromAddress(listenAddress string) string { 205 stringList := strings.Split(listenAddress, ":") 206 length := len(stringList) 207 if length != 3 { 208 panic(fmt.Errorf("expected listen address: tcp://0.0.0.0:12345, got %s", listenAddress)) 209 } 210 return stringList[2] 211 } 212 213 // NewTestCaseDir creates a new temporary directory for a test case. 214 // Returns the directory path and a cleanup function. 215 // nolint: errcheck 216 func NewTestCaseDir(t *testing.T) (string, func()) { 217 dir, err := ioutil.TempDir("", t.Name()+"_") 218 require.NoError(t, err) 219 return dir, func() { os.RemoveAll(dir) } 220 } 221 222 var cdc = codec.New() 223 224 func init() { 225 ctypes.RegisterAmino(cdc) 226 } 227 228 //DONTCOVER