From c85221440798c83e1bcc902e2d6207c949eed014 Mon Sep 17 00:00:00 2001 From: Martin Boehm Date: Fri, 19 Oct 2018 12:27:54 +0200 Subject: [PATCH] Complete explorer/api unit tests --- db/rocksdb.go | 8 +- server/public_test.go | 220 +++++++++++++++++++++++++++++----- tests/dbtestdata/fakechain.go | 10 +- 3 files changed, 197 insertions(+), 41 deletions(-) diff --git a/db/rocksdb.go b/db/rocksdb.go index e1dc2238..300f9c63 100644 --- a/db/rocksdb.go +++ b/db/rocksdb.go @@ -927,7 +927,7 @@ func (d *RocksDB) packBlockInfo(block *BlockInfo) ([]byte, error) { func (d *RocksDB) unpackBlockInfo(buf []byte) (*BlockInfo, error) { pl := d.chainParser.PackedTxidLen() - // minimum length is PackedTxidLen+4 bytes time + 1 byte txs + 1 byte size + // minimum length is PackedTxidLen + 4 bytes time + 1 byte txs + 1 byte size if len(buf) < pl+4+2 { return nil, nil } @@ -986,12 +986,8 @@ func (d *RocksDB) GetBlockInfo(height uint32) (*BlockInfo, error) { return nil, err } defer val.Free() - if val.Size() == 0 { - // block not found - return nil, nil - } bi, err := d.unpackBlockInfo(val.Data()) - if err != nil { + if err != nil || bi == nil { return nil, err } bi.Height = height diff --git a/server/public_test.go b/server/public_test.go index 5a6c8c4b..eae1d2ff 100644 --- a/server/public_test.go +++ b/server/public_test.go @@ -39,7 +39,7 @@ func setupRocksDB(t *testing.T, parser bchain.BlockChainParser) (*db.RocksDB, *c if err != nil { t.Fatal(err) } - is, err := d.LoadInternalState("btc-testnet") + is, err := d.LoadInternalState("fakecoin") if err != nil { t.Fatal(err) } @@ -60,11 +60,11 @@ func setupPublicHTTPServer(t *testing.T) (*PublicServer, string) { &btc.Configuration{BlockAddressesToKeep: 1}) d, is, path := setupRocksDB(t, parser) - is.Coin = "Testnet" - is.CoinLabel = "Bitcoin Testnet" - is.CoinShortcut = "TEST" + is.Coin = "Fakecoin" + is.CoinLabel = "Fake Coin" + is.CoinShortcut = "FAKE" - metrics, err := common.GetMetrics("Testnet") + metrics, err := common.GetMetrics("Fakecoin") if err != nil { glog.Fatal("metrics: ", err) } @@ -103,14 +103,7 @@ func newGetRequest(url string, body io.Reader) *http.Request { return r } -func Test_PublicServer_UTXO(t *testing.T) { - s, dbpath := setupPublicHTTPServer(t) - defer closeAndDestroyPublicServer(t, s, dbpath) - s.ConnectFullPublicInterface() - // take the handler of the public server and pass it to the test server - ts := httptest.NewServer(s.https.Handler) - defer ts.Close() - +func httpTests(t *testing.T, ts *httptest.Server) { tests := []struct { name string r *http.Request @@ -124,12 +117,12 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Transaction

`, `fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db`, - `td class="data">0 TEST`, + `td class="data">0 FAKE`, `mzVznVsCHkVHX9UN8WPFASWUUHtxnNn4Jj`, - `13.60030331 TEST`, + `13.60030331 FAKE`, `No Inputs (Newly Generated Coins)`, ``, }, @@ -140,16 +133,16 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Address`, - `0 TEST`, + `0 FAKE`, `mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz`, - `0.00012345 TEST`, + `0.00012345 FAKE`, `7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25`, - `3172.83951061 TEST `, + `3172.83951061 FAKE `, `mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, `td>mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, - `9172.83951061 TEST ×`, + `9172.83951061 FAKE ×`, `00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840`, ``, }, @@ -160,10 +153,22 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Transaction

`, `3d90d15ed026dc45e19ffb52875ed18fa9e8012ad123d7f7212176e2b0ebdb71`, - `0.00000062 TEST`, + `0.00000062 FAKE`, + ``, + }, + }, + { + name: "explorerSpendingTx - not found", + r: newGetRequest(ts.URL+"/spending/123be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25/0", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Error

`, + `

Transaction not found

`, ``, }, }, @@ -173,7 +178,7 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Blocks`, `225494`, `00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6`, @@ -190,12 +195,12 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Block 225494

`, `00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6`, `4`, // number of transactions `mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, - `9172.83951061 TEST`, + `9172.83951061 FAKE`, `fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db`, ``, }, @@ -206,15 +211,160 @@ func Test_PublicServer_UTXO(t *testing.T) { status: http.StatusOK, contentType: "text/html; charset=utf-8", body: []string{ - `Bitcoin Testnet Explorer`, + `Fake Coin Explorer`, `

Application status

`, `

Synchronization with backend is disabled, the state of index is not up to date.

`, `225494`, - `/Satoshi:0.16.3/`, + `/Fakecoin:0.0.1/`, ``, }, }, - // explorerSearch + { + name: "explorerSearch block height", + r: newGetRequest(ts.URL+"/search?q=225494", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Block 225494

`, + `00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6`, + `4`, // number of transactions + `mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, + `9172.83951061 FAKE`, + `fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db`, + ``, + }, + }, + { + name: "explorerSearch block hash", + r: newGetRequest(ts.URL+"/search?q=00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Block 225494

`, + `00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6`, + `4`, // number of transactions + `mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, + `9172.83951061 FAKE`, + `fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db`, + ``, + }, + }, + { + name: "explorerSearch tx", + r: newGetRequest(ts.URL+"/search?q=fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Transaction

`, + `fdd824a780cbb718eeb766eb05d83fdefc793a27082cd5e67f856d69798cf7db`, + `td class="data">0 FAKE`, + `mzVznVsCHkVHX9UN8WPFASWUUHtxnNn4Jj`, + `13.60030331 FAKE`, + `No Inputs (Newly Generated Coins)`, + ``, + }, + }, + { + name: "explorerSearch address", + r: newGetRequest(ts.URL+"/search?q=mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Address`, + `0 FAKE`, + `mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz`, + `0.00012345 FAKE`, + `7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25`, + `3172.83951061 FAKE `, + `mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, + `td>mtR97eM2HPWVM6c8FGLGcukgaHHQv7THoL`, + `9172.83951061 FAKE ×`, + `00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840`, + ``, + }, + }, + { + name: "explorerSearch not found", + r: newGetRequest(ts.URL+"/search?q=1234", nil), + status: http.StatusOK, + contentType: "text/html; charset=utf-8", + body: []string{ + `Fake Coin Explorer`, + `

Error

`, + `

No matching records found for '1234'

`, + ``, + }, + }, + { + name: "apiIndex", + r: newGetRequest(ts.URL+"/api", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"blockbook":{"coin":"Fakecoin"`, + `"bestHeight":225494`, + `"backend":{"chain":"fakecoin","blocks":2,"headers":2,"bestblockhash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6"`, + `"version":"001001","subversion":"/Fakecoin:0.0.1/"`, + }, + }, + { + name: "apiBlockIndex", + r: newGetRequest(ts.URL+"/api/block-index/", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"blockHash":"00000000eb0443fd7dc4a1ed5c686a8e995057805f9a161d9a5a77a95e72b7b6"}`, + }, + }, + { + name: "apiTx", + r: newGetRequest(ts.URL+"/api/tx/05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"txid":"05e2e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07","vin":[{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vout":2,"n":0,"scriptSig":{"hex":""},"addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"],"value":"0.00009876"}],"vout":[{"value":"0.00009","n":0,"scriptPubKey":{"hex":"a914e921fc4912a315078f370d959f2c4f7b6d2a683c87","addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"]}}],"blockheight":0,"confirmations":0,"time":22549400002,"blocktime":22549400002,"valueOut":"0.00009","valueIn":"0.00009876","fees":"0.00000876","hex":""}`, + }, + }, + { + name: "apiTx - not found", + r: newGetRequest(ts.URL+"/api/tx/1232e48aeabdd9b75def7b48d756ba304713c2aba7b522bf9dbc893fc4231b07", nil), + status: http.StatusInternalServerError, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"error":"Tx not found, Not found"}`, + }, + }, + { + name: "apiTxSpecific", + r: newGetRequest(ts.URL+"/api/tx-specific/00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"hex":"","txid":"00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840","version":0,"locktime":0,"vin":null,"vout":[{"ValueSat":100000000,"value":0,"n":0,"scriptPubKey":{"hex":"76a914010d39800f86122416e28f485029acf77507169288ac","addresses":null}},{"ValueSat":12345,"value":0,"n":1,"scriptPubKey":{"hex":"76a9148bdf0aa3c567aa5975c2e61321b8bebbe7293df688ac","addresses":null}}],"time":22549300000,"blocktime":22549300000}`, + }, + }, + { + name: "apiAddress", + r: newGetRequest(ts.URL+"/api/address/mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"page":1,"totalPages":1,"itemsOnPage":1000,"addrStr":"mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw","balance":"0","totalReceived":"12345.67890123","totalSent":"12345.67890123","unconfirmedBalance":"0","unconfirmedTxApperances":0,"txApperances":2,"transactions":["7c3be24063f268aaa1ed81b64776798f56088757641a34fb156c4f51ed2e9d25","effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75"]}`, + }, + }, + { + name: "apiBlock", + r: newGetRequest(ts.URL+"/api/block/225493", nil), + status: http.StatusOK, + contentType: "application/json; charset=utf-8", + body: []string{ + `{"page":1,"totalPages":1,"itemsOnPage":1000,"hash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","previousblockhash":"","nextblockhash":"","height":225493,"confirmations":0,"size":1234567,"time":1534858021,"version":0,"merkleroot":"","nonce":0,"bits":"","difficulty":0,"TxCount":2,"txs":[{"txid":"00b2c06055e5e90e9c82bd4181fde310104391a7fa4f289b1704e5d90caa3840","vin":[],"vout":[{"value":"1","n":0,"scriptPubKey":{"hex":"","addresses":["mfcWp7DB6NuaZsExybTTXpVgWz559Np4Ti"]}},{"value":"0.00012345","n":1,"scriptPubKey":{"hex":"","addresses":["mtGXQvBowMkBpnhLckhxhbwYK44Gs9eEtz"]}}],"blockhash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockheight":225493,"confirmations":2,"time":1534858021,"blocktime":1534858021,"valueOut":"1.00012345","valueIn":"0","fees":"0","hex":""},{"txid":"effd9ef509383d536b1c8af5bf434c8efbf521a4f2befd4022bbd68694b4ac75","vin":[],"vout":[{"value":"12345.67890123","n":0,"scriptPubKey":{"hex":"","addresses":["mv9uLThosiEnGRbVPS7Vhyw6VssbVRsiAw"]}},{"value":"0.00000001","n":1,"scriptPubKey":{"hex":"","addresses":["2Mz1CYoppGGsLNUGF2YDhTif6J661JitALS"]}},{"value":"0.00009876","n":2,"scriptPubKey":{"hex":"","addresses":["2NEVv9LJmAnY99W1pFoc5UJjVdypBqdnvu1"]}}],"blockhash":"0000000076fbbed90fd75b0e18856aa35baa984e9c9d444cf746ad85e94e2997","blockheight":225493,"confirmations":2,"time":1534858021,"blocktime":1534858021,"valueOut":"12345.679","valueIn":"0","fees":"0","hex":""}]}`, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -242,5 +392,15 @@ func Test_PublicServer_UTXO(t *testing.T) { } }) } - +} + +func Test_PublicServer_UTXO(t *testing.T) { + s, dbpath := setupPublicHTTPServer(t) + defer closeAndDestroyPublicServer(t, s, dbpath) + s.ConnectFullPublicInterface() + // take the handler of the public server and pass it to the test server + ts := httptest.NewServer(s.https.Handler) + defer ts.Close() + + httpTests(t, ts) } diff --git a/tests/dbtestdata/fakechain.go b/tests/dbtestdata/fakechain.go index a155da27..0495ac37 100644 --- a/tests/dbtestdata/fakechain.go +++ b/tests/dbtestdata/fakechain.go @@ -29,15 +29,15 @@ func (c *fakeBlockChain) IsTestnet() bool { } func (c *fakeBlockChain) GetNetworkName() string { - return "test" + return "fakecoin" } func (c *fakeBlockChain) GetCoinName() string { - return "Testnet" + return "Fakecoin" } func (c *fakeBlockChain) GetSubversion() string { - return "/Satoshi:0.16.3/" + return "/Fakecoin:0.0.1/" } func (c *fakeBlockChain) GetChainInfo() (v *bchain.ChainInfo, err error) { @@ -46,7 +46,7 @@ func (c *fakeBlockChain) GetChainInfo() (v *bchain.ChainInfo, err error) { Blocks: 2, Headers: 2, Bestblockhash: GetTestUTXOBlock2(c.parser).BlockHeader.Hash, - Version: "160300", + Version: "001001", Subversion: c.GetSubversion(), }, nil } @@ -138,7 +138,7 @@ func (c *fakeBlockChain) GetTransaction(txid string) (v *bchain.Tx, err error) { if v != nil { return v, nil } - return nil, errors.New("Not implemented") + return nil, errors.New("Not found") } func (c *fakeBlockChain) GetTransactionSpecific(txid string) (v json.RawMessage, err error) {