Implement test of logged socket.io communication - WIP
This commit is contained in:
parent
ecd475f728
commit
9b061850f2
@ -466,18 +466,18 @@ func unmarshalGetBlockHeader(params []byte) (height uint32, hash string, err err
|
|||||||
|
|
||||||
type resultGetBlockHeader struct {
|
type resultGetBlockHeader struct {
|
||||||
Result struct {
|
Result struct {
|
||||||
Hash string `json:"hash"`
|
Hash string `json:"hash"`
|
||||||
Version int `json:"version"`
|
Version int `json:"version"`
|
||||||
Confirmations int `json:"confirmations"`
|
Confirmations int `json:"confirmations"`
|
||||||
Height int `json:"height"`
|
Height int `json:"height"`
|
||||||
ChainWork string `json:"chainWork"`
|
ChainWork string `json:"chainWork"`
|
||||||
NextHash string `json:"nextHash"`
|
NextHash string `json:"nextHash"`
|
||||||
MerkleRoot string `json:"merkleRoot"`
|
MerkleRoot string `json:"merkleRoot"`
|
||||||
Time int `json:"time"`
|
Time int `json:"time"`
|
||||||
MedianTime int `json:"medianTime"`
|
MedianTime int `json:"medianTime"`
|
||||||
Nonce int `json:"nonce"`
|
Nonce int `json:"nonce"`
|
||||||
Bits string `json:"bits"`
|
Bits string `json:"bits"`
|
||||||
Difficulty int `json:"difficulty"`
|
Difficulty float64 `json:"difficulty"`
|
||||||
} `json:"result"`
|
} `json:"result"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,8 +18,8 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// verifier functionality
|
// verifier functionality
|
||||||
verifylog = flag.String("verifylog", "", "path to logfile containing socket.io requests/responses")
|
verifylog = flag.String("verifylog", "/Users/mxb2/Downloads/messageLogBtc.log", "path to logfile containing socket.io requests/responses")
|
||||||
wsurl = flag.String("wsurl", "", "URL of socket.io interface to verify")
|
wsurl = flag.String("wsurl", "wss://blockbook-dev:8336", "URL of socket.io interface to verify")
|
||||||
)
|
)
|
||||||
|
|
||||||
type verifyStats struct {
|
type verifyStats struct {
|
||||||
@ -50,23 +50,134 @@ func getStat(m string, stats map[string]*verifyStats) *verifyStats {
|
|||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyGetInfo(t *testing.T, id int, lrs *logRequestResponse, bbRequest map[string]json.RawMessage, bbResponseS string, stat *verifyStats) {
|
func unmarshalResponses(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, bbResponse interface{}, logResponse interface{}) error {
|
||||||
bbResponse := resultGetInfo{}
|
err := json.Unmarshal([]byte(bbResStr), bbResponse)
|
||||||
err := json.Unmarshal([]byte(bbResponseS), &bbResponse)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(id, ": error unmarshal BB request ", err)
|
t.Log(id, ": error unmarshal BB request ", err)
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
logResponse := resultGetInfo{}
|
err = json.Unmarshal([]byte(lrs.Response), logResponse)
|
||||||
err = json.Unmarshal([]byte(lrs.Response), &logResponse)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Log(id, ": error unmarshal log request ", err)
|
t.Log(id, ": error unmarshal log request ", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyGetAddressHistory(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, stat *verifyStats, ws *gosocketio.Client, bbRequest map[string]json.RawMessage) {
|
||||||
|
type reqParamsData struct {
|
||||||
|
Start int `json:"start"`
|
||||||
|
End int `json:"end"`
|
||||||
|
QueryMempoolOnly bool `json:"queryMempoolOnly"`
|
||||||
|
From int `json:"from"`
|
||||||
|
To int `json:"to"`
|
||||||
|
}
|
||||||
|
bbResponse := resultGetAddressHistory{}
|
||||||
|
logResponse := resultGetAddressHistory{}
|
||||||
|
if err := unmarshalResponses(t, id, lrs, bbResStr, &bbResponse, &logResponse); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// parse request
|
||||||
|
addr, rr, err := unmarshalGetAddressRequest(bbRequest["params"])
|
||||||
|
if err != nil {
|
||||||
|
t.Log(id, ": getAddressHistory error unmarshal BB request ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !rr.QueryMempoolOnly {
|
||||||
|
if (logResponse.Result.TotalCount != bbResponse.Result.TotalCount) ||
|
||||||
|
len(logResponse.Result.Items) != len(bbResponse.Result.Items) {
|
||||||
|
t.Log("getAddressHistory", id, "mismatch bb:", bbResponse.Result.TotalCount, len(bbResponse.Result.Items),
|
||||||
|
"log:", logResponse.Result.TotalCount, len(logResponse.Result.Items))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if logResponse.Result.TotalCount > 0 {
|
||||||
|
for i, logItem := range logResponse.Result.Items {
|
||||||
|
bbItem := bbResponse.Result.Items[i]
|
||||||
|
if logItem.Tx.Hash != bbItem.Tx.Hash || logItem.Tx.Hex != bbItem.Tx.Hex {
|
||||||
|
t.Log("getAddressHistory", id, "mismatch in tx", i, "bb:", bbItem.Tx.Hash,
|
||||||
|
"log:", logItem.Tx.Hash)
|
||||||
|
|
||||||
|
// if multiple addresses are specified, BlockBook returns transactions in different order
|
||||||
|
// which causes problems in paged responses
|
||||||
|
// we have to get all transactions from blockbook and check that they are in the logged response
|
||||||
|
rr.From = 0
|
||||||
|
rr.To = 100000000
|
||||||
|
rq := map[string]interface{}{
|
||||||
|
"method": "getAddressHistory",
|
||||||
|
"params": []interface{}{
|
||||||
|
addr,
|
||||||
|
rr,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
rrq, err := json.Marshal(rq)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(id, ", getAddressHistory: rq marshall error ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := ws.Ack("message", json.RawMessage(rrq), time.Second*30)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(id, ", getAddressHistory: ws.Ack error ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
bbFullResponse := resultGetAddressHistory{}
|
||||||
|
t.Log(id, ": bbResponse", bbResponse.Result.TotalCount, "bbFullResponse", bbFullResponse.Result.TotalCount)
|
||||||
|
t.Log(string(rrq))
|
||||||
|
err = json.Unmarshal([]byte(res), &bbFullResponse)
|
||||||
|
if err != nil {
|
||||||
|
t.Log(id, ": getAddressHistory error unmarshal BB response ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stat.SuccessCount++
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyGetInfo(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, stat *verifyStats) {
|
||||||
|
bbResponse := resultGetInfo{}
|
||||||
|
logResponse := resultGetInfo{}
|
||||||
|
if err := unmarshalResponses(t, id, lrs, bbResStr, &bbResponse, &logResponse); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if logResponse.Result.Blocks <= bbResponse.Result.Blocks &&
|
if logResponse.Result.Blocks <= bbResponse.Result.Blocks &&
|
||||||
logResponse.Result.Testnet == bbResponse.Result.Testnet &&
|
logResponse.Result.Testnet == bbResponse.Result.Testnet &&
|
||||||
logResponse.Result.Network == bbResponse.Result.Network {
|
logResponse.Result.Network == bbResponse.Result.Network {
|
||||||
stat.SuccessCount++
|
stat.SuccessCount++
|
||||||
|
} else {
|
||||||
|
t.Log("getInfo", id, "mismatch bb:", bbResponse.Result.Blocks, bbResponse.Result.Testnet, bbResponse.Result.Network,
|
||||||
|
"log:", logResponse.Result.Blocks, logResponse.Result.Testnet, logResponse.Result.Network)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyGetBlockHeader(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, stat *verifyStats) {
|
||||||
|
bbResponse := resultGetBlockHeader{}
|
||||||
|
logResponse := resultGetBlockHeader{}
|
||||||
|
if err := unmarshalResponses(t, id, lrs, bbResStr, &bbResponse, &logResponse); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if logResponse.Result.Hash == bbResponse.Result.Hash {
|
||||||
|
stat.SuccessCount++
|
||||||
|
} else {
|
||||||
|
t.Log("getBlockHeader", id, "mismatch bb:", bbResponse.Result.Hash,
|
||||||
|
"log:", logResponse.Result.Hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func verifyEstimateSmartFee(t *testing.T, id int, lrs *logRequestResponse, bbResStr string, stat *verifyStats) {
|
||||||
|
bbResponse := resultEstimateSmartFee{}
|
||||||
|
logResponse := resultEstimateSmartFee{}
|
||||||
|
if err := unmarshalResponses(t, id, lrs, bbResStr, &bbResponse, &logResponse); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// it is not possible to compare fee directly, it changes over time,
|
||||||
|
// verify that the BB fee is in a reasonable range
|
||||||
|
if bbResponse.Result > 0 && bbResponse.Result < 1e-3 {
|
||||||
|
stat.SuccessCount++
|
||||||
|
} else {
|
||||||
|
t.Log("estimateSmartFee", id, "mismatch bb:", bbResponse.Result,
|
||||||
|
"log:", logResponse.Result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,25 +202,27 @@ func verifyMessage(t *testing.T, ws *gosocketio.Client, id int, lrs *logRequestR
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
ts := time.Since(start).Nanoseconds()
|
ts := time.Since(start).Nanoseconds()
|
||||||
t.Log(id, ",", method, ": response ", res)
|
// t.Log(id, ",", method, ": response ", res)
|
||||||
stat := getStat(method, stats)
|
stat := getStat(method, stats)
|
||||||
stat.Count++
|
stat.Count++
|
||||||
stat.TotalLogNs += lrs.LogElapsedTime
|
stat.TotalLogNs += lrs.LogElapsedTime
|
||||||
stat.TotalBlockbookNs += ts
|
stat.TotalBlockbookNs += ts
|
||||||
switch method {
|
switch method {
|
||||||
case "getAddressTxids":
|
// case "getAddressTxids":
|
||||||
case "getAddressHistory":
|
case "getAddressHistory":
|
||||||
|
verifyGetAddressHistory(t, id, lrs, res, stat, ws, req)
|
||||||
case "getBlockHeader":
|
case "getBlockHeader":
|
||||||
|
verifyGetBlockHeader(t, id, lrs, res, stat)
|
||||||
case "getDetailedTransaction":
|
case "getDetailedTransaction":
|
||||||
case "getInfo":
|
case "getInfo":
|
||||||
verifyGetInfo(t, id, lrs, req, res, stat)
|
verifyGetInfo(t, id, lrs, res, stat)
|
||||||
case "estimateSmartFee":
|
case "estimateSmartFee":
|
||||||
case "estimateFee":
|
verifyEstimateSmartFee(t, id, lrs, res, stat)
|
||||||
case "sendTransaction":
|
// case "estimateFee":
|
||||||
case "getMempoolEntry":
|
// case "sendTransaction":
|
||||||
break
|
// case "getMempoolEntry":
|
||||||
default:
|
default:
|
||||||
t.Log(id, ",", method, ": unknown method", method)
|
t.Log(id, ",", method, ": unknown/unverified method", method)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,10 +290,13 @@ func Test_VerifyLog(t *testing.T) {
|
|||||||
}
|
}
|
||||||
failures := 0
|
failures := 0
|
||||||
sort.Strings(keys)
|
sort.Strings(keys)
|
||||||
|
t.Log("Processed", line, "lines")
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
s := stats[k]
|
s := stats[k]
|
||||||
failures += s.Count - s.SuccessCount
|
failures += s.Count - s.SuccessCount
|
||||||
t.Log("Method:", k, "\tCount:", s.Count, "\tSuccess:", s.SuccessCount, "\tTime log:", s.TotalLogNs, "\tTime BB:", s.TotalBlockbookNs)
|
t.Log("Method:", k, "\tCount:", s.Count, "\tSuccess:", s.SuccessCount,
|
||||||
|
"\tTime log:", s.TotalLogNs, "\tTime BB:", s.TotalBlockbookNs,
|
||||||
|
"\tTime BB/log", float64(s.TotalBlockbookNs)/float64(s.TotalLogNs))
|
||||||
}
|
}
|
||||||
if failures != 0 {
|
if failures != 0 {
|
||||||
t.Error("Number of failures:", failures)
|
t.Error("Number of failures:", failures)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user