From b5d1e5c94e06865a5ae47acbe4aa6ab45ab3b95a Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Tue, 11 Sep 2018 16:36:32 +0200 Subject: [PATCH 1/2] Integration tests are defined declaratively with single implementation --- bchain/coins/bch/bcashrpc_test.go | 141 ----- bchain/coins/blockchain.go | 44 +- bchain/coins/btc/bitcoinrpc_test.go | 142 ----- bchain/coins/dash/dashrpc_test.go | 129 ----- bchain/coins/dogecoin/dogecoinrpc_test.go | 70 --- bchain/coins/eth/ethrpc_test.go | 62 --- bchain/coins/litecoin/litecoinrpc_test.go | 72 --- bchain/coins/monacoin/monacoinrpc_test.go | 72 --- bchain/coins/namecoin/namecoinrpc_test.go | 86 ---- bchain/coins/vertcoin/vertcoinrpc_test.go | 84 --- bchain/coins/zec/zcashrpc_test.go | 130 ----- bchain/tests/rpc/config.json | 77 --- bchain/tests/rpc/data.go | 49 +- bchain/tests/rpc/rpc.go | 455 ---------------- bchain/tests/rpc/rpc_test.go | 484 ++++++++++++++++++ .../rpc/testdata/{Bcash.json => bcash.json} | 0 ...{Bcash_Testnet.json => bcash_testnet.json} | 0 .../testdata/{Bitcoin.json => bitcoin.json} | 0 ...coin_Testnet.json => bitcoin_testnet.json} | 0 .../rpc/testdata/{Dash.json => dash.json} | 0 .../{Dash_Testnet.json => dash_testnet.json} | 0 .../testdata/{Dogecoin.json => dogecoin.json} | 0 ...net.json => ethereum_testnet_ropsten.json} | 0 .../testdata/{Litecoin.json => litecoin.json} | 0 .../testdata/{Monacoin.json => monacoin.json} | 0 .../testdata/{Namecoin.json => namecoin.json} | 0 .../testdata/{Vertcoin.json => vertcoin.json} | 0 .../rpc/testdata/{Zcash.json => zcash.json} | 0 ...{Zcash_Testnet.json => zcash_testnet.json} | 0 build/docker/bin/Makefile | 15 +- build/templates/generate.go | 288 +---------- build/tools/templates.go | 288 +++++++++++ configs/coins/bcash.json | 4 + configs/coins/bcash_testnet.json | 4 + configs/coins/bitcoin.json | 4 + configs/coins/bitcoin_testnet.json | 4 + configs/coins/dash.json | 4 + configs/coins/dash_testnet.json | 4 + configs/coins/dogecoin.json | 3 + configs/coins/ethereum_testnet_ropsten.json | 3 + configs/coins/litecoin.json | 4 + configs/coins/monacoin.json | 4 + configs/coins/namecoin.json | 4 + configs/coins/vertcoin.json | 4 + configs/coins/zcash.json | 4 + configs/coins/zcash_testnet.json | 4 + 46 files changed, 876 insertions(+), 1866 deletions(-) delete mode 100644 bchain/coins/bch/bcashrpc_test.go delete mode 100644 bchain/coins/btc/bitcoinrpc_test.go delete mode 100644 bchain/coins/dash/dashrpc_test.go delete mode 100644 bchain/coins/dogecoin/dogecoinrpc_test.go delete mode 100644 bchain/coins/eth/ethrpc_test.go delete mode 100644 bchain/coins/litecoin/litecoinrpc_test.go delete mode 100644 bchain/coins/monacoin/monacoinrpc_test.go delete mode 100644 bchain/coins/namecoin/namecoinrpc_test.go delete mode 100644 bchain/coins/vertcoin/vertcoinrpc_test.go delete mode 100644 bchain/coins/zec/zcashrpc_test.go delete mode 100644 bchain/tests/rpc/config.json delete mode 100644 bchain/tests/rpc/rpc.go create mode 100644 bchain/tests/rpc/rpc_test.go rename bchain/tests/rpc/testdata/{Bcash.json => bcash.json} (100%) rename bchain/tests/rpc/testdata/{Bcash_Testnet.json => bcash_testnet.json} (100%) rename bchain/tests/rpc/testdata/{Bitcoin.json => bitcoin.json} (100%) rename bchain/tests/rpc/testdata/{Bitcoin_Testnet.json => bitcoin_testnet.json} (100%) rename bchain/tests/rpc/testdata/{Dash.json => dash.json} (100%) rename bchain/tests/rpc/testdata/{Dash_Testnet.json => dash_testnet.json} (100%) rename bchain/tests/rpc/testdata/{Dogecoin.json => dogecoin.json} (100%) rename bchain/tests/rpc/testdata/{Ethereum_Testnet.json => ethereum_testnet_ropsten.json} (100%) rename bchain/tests/rpc/testdata/{Litecoin.json => litecoin.json} (100%) rename bchain/tests/rpc/testdata/{Monacoin.json => monacoin.json} (100%) rename bchain/tests/rpc/testdata/{Namecoin.json => namecoin.json} (100%) rename bchain/tests/rpc/testdata/{Vertcoin.json => vertcoin.json} (100%) rename bchain/tests/rpc/testdata/{Zcash.json => zcash.json} (100%) rename bchain/tests/rpc/testdata/{Zcash_Testnet.json => zcash_testnet.json} (100%) create mode 100644 build/tools/templates.go diff --git a/bchain/coins/bch/bcashrpc_test.go b/bchain/coins/bch/bcashrpc_test.go deleted file mode 100644 index 7056125b..00000000 --- a/bchain/coins/bch/bcashrpc_test.go +++ /dev/null @@ -1,141 +0,0 @@ -// +build integration - -package bch - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(chain string) func(json.RawMessage) (bchain.BlockChain, error) { - return func(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewBCashRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*BCashRPC) - cli.Parser, err = NewBCashParser(GetChainParams(chain), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil - } -} - -var tests struct { - mainnet *rpc.Test - testnet *rpc.Test -} - -func TestMain(m *testing.M) { - flag.Parse() - - t, err := rpc.NewTest("Bcash", getRPCClient("main")) - if err != nil { - panic(err) - } - - tests.mainnet = t - - t, err = rpc.NewTest("Bcash Testnet", getRPCClient("test")) - if err != nil { - panic(err) - } - - tests.testnet = t - - os.Exit(m.Run()) -} - -func TestBCashRPC_GetBlockHash(t *testing.T) { - tests.mainnet.TestGetBlockHash(t) -} - -func TestBCashRPC_GetBlock(t *testing.T) { - tests.mainnet.TestGetBlock(t) -} - -func TestBCashRPC_GetTransaction(t *testing.T) { - tests.mainnet.TestGetTransaction(t) -} - -func TestBCashRPC_GetTransactionForMempool(t *testing.T) { - tests.mainnet.TestGetTransactionForMempool(t) -} - -func TestBCashRPC_MempoolSync(t *testing.T) { - tests.mainnet.TestMempoolSync(t) -} - -func TestBCashRPC_GetMempoolEntry(t *testing.T) { - tests.mainnet.TestGetMempoolEntry(t) -} - -func TestBCashRPC_EstimateSmartFee(t *testing.T) { - tests.mainnet.TestEstimateSmartFee(t) -} - -func TestBCashRPC_EstimateFee(t *testing.T) { - tests.mainnet.TestEstimateFee(t) -} - -func TestBCashRPC_GetBestBlockHash(t *testing.T) { - tests.mainnet.TestGetBestBlockHash(t) -} - -func TestBCashRPC_GetBestBlockHeight(t *testing.T) { - tests.mainnet.TestGetBestBlockHeight(t) -} - -func TestBCashRPC_GetBlockHeader(t *testing.T) { - tests.mainnet.TestGetBlockHeader(t) -} - -func TestBCashTestnetRPC_GetBlockHash(t *testing.T) { - tests.testnet.TestGetBlockHash(t) -} - -func TestBCashTestnetRPC_GetBlock(t *testing.T) { - tests.testnet.TestGetBlock(t) -} - -func TestBCashTestnetRPC_GetTransaction(t *testing.T) { - tests.testnet.TestGetTransaction(t) -} - -func TestBCashTestnetRPC_GetTransactionForMempool(t *testing.T) { - tests.testnet.TestGetTransactionForMempool(t) -} - -func TestBCashTestnetRPC_MempoolSync(t *testing.T) { - tests.testnet.TestMempoolSync(t) -} - -func TestBCashTestnetRPC_GetMempoolEntry(t *testing.T) { - tests.testnet.TestGetMempoolEntry(t) -} - -func TestBCashTestnetRPC_EstimateSmartFee(t *testing.T) { - tests.testnet.TestEstimateSmartFee(t) -} - -func TestBCashTestnetRPC_EstimateFee(t *testing.T) { - tests.testnet.TestEstimateFee(t) -} - -func TestBCashTestnetRPC_GetBestBlockHash(t *testing.T) { - tests.testnet.TestGetBestBlockHash(t) -} - -func TestBCashTestnetRPC_GetBestBlockHeight(t *testing.T) { - tests.testnet.TestGetBestBlockHeight(t) -} - -func TestBCashTestnetRPC_GetBlockHeader(t *testing.T) { - tests.testnet.TestGetBlockHeader(t) -} diff --git a/bchain/coins/blockchain.go b/bchain/coins/blockchain.go index b0be1d2b..3e3f6ae0 100644 --- a/bchain/coins/blockchain.go +++ b/bchain/coins/blockchain.go @@ -27,28 +27,28 @@ import ( type blockChainFactory func(config json.RawMessage, pushHandler func(bchain.NotificationType)) (bchain.BlockChain, error) -var blockChainFactories = make(map[string]blockChainFactory) +var BlockChainFactories = make(map[string]blockChainFactory) func init() { - blockChainFactories["Bitcoin"] = btc.NewBitcoinRPC - blockChainFactories["Testnet"] = btc.NewBitcoinRPC - blockChainFactories["Zcash"] = zec.NewZCashRPC - blockChainFactories["Zcash Testnet"] = zec.NewZCashRPC - blockChainFactories["Ethereum"] = eth.NewEthereumRPC - blockChainFactories["Ethereum Testnet Ropsten"] = eth.NewEthereumRPC - blockChainFactories["Bcash"] = bch.NewBCashRPC - blockChainFactories["Bcash Testnet"] = bch.NewBCashRPC - blockChainFactories["Bgold"] = btg.NewBGoldRPC - blockChainFactories["Dash"] = dash.NewDashRPC - blockChainFactories["Dash Testnet"] = dash.NewDashRPC - blockChainFactories["Litecoin"] = litecoin.NewLitecoinRPC - blockChainFactories["Litecoin Testnet"] = litecoin.NewLitecoinRPC - blockChainFactories["Dogecoin"] = dogecoin.NewDogecoinRPC - blockChainFactories["Vertcoin"] = vertcoin.NewVertcoinRPC - blockChainFactories["Vertcoin Testnet"] = vertcoin.NewVertcoinRPC - blockChainFactories["Namecoin"] = namecoin.NewNamecoinRPC - blockChainFactories["Monacoin"] = monacoin.NewMonacoinRPC - blockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC + BlockChainFactories["Bitcoin"] = btc.NewBitcoinRPC + BlockChainFactories["Testnet"] = btc.NewBitcoinRPC + BlockChainFactories["Zcash"] = zec.NewZCashRPC + BlockChainFactories["Zcash Testnet"] = zec.NewZCashRPC + BlockChainFactories["Ethereum"] = eth.NewEthereumRPC + BlockChainFactories["Ethereum Testnet Ropsten"] = eth.NewEthereumRPC + BlockChainFactories["Bcash"] = bch.NewBCashRPC + BlockChainFactories["Bcash Testnet"] = bch.NewBCashRPC + BlockChainFactories["Bgold"] = btg.NewBGoldRPC + BlockChainFactories["Dash"] = dash.NewDashRPC + BlockChainFactories["Dash Testnet"] = dash.NewDashRPC + BlockChainFactories["Litecoin"] = litecoin.NewLitecoinRPC + BlockChainFactories["Litecoin Testnet"] = litecoin.NewLitecoinRPC + BlockChainFactories["Dogecoin"] = dogecoin.NewDogecoinRPC + BlockChainFactories["Vertcoin"] = vertcoin.NewVertcoinRPC + BlockChainFactories["Vertcoin Testnet"] = vertcoin.NewVertcoinRPC + BlockChainFactories["Namecoin"] = namecoin.NewNamecoinRPC + BlockChainFactories["Monacoin"] = monacoin.NewMonacoinRPC + BlockChainFactories["Monacoin Testnet"] = monacoin.NewMonacoinRPC } // GetCoinNameFromConfig gets coin name and coin shortcut from config file @@ -79,9 +79,9 @@ func NewBlockChain(coin string, configfile string, pushHandler func(bchain.Notif if err != nil { return nil, errors.Annotatef(err, "Error parsing file %v", configfile) } - bcf, ok := blockChainFactories[coin] + bcf, ok := BlockChainFactories[coin] if !ok { - return nil, errors.New(fmt.Sprint("Unsupported coin '", coin, "'. Must be one of ", reflect.ValueOf(blockChainFactories).MapKeys())) + return nil, errors.New(fmt.Sprint("Unsupported coin '", coin, "'. Must be one of ", reflect.ValueOf(BlockChainFactories).MapKeys())) } bc, err := bcf(config, pushHandler) if err != nil { diff --git a/bchain/coins/btc/bitcoinrpc_test.go b/bchain/coins/btc/bitcoinrpc_test.go deleted file mode 100644 index 882a1bd7..00000000 --- a/bchain/coins/btc/bitcoinrpc_test.go +++ /dev/null @@ -1,142 +0,0 @@ -// +build integration - -package btc - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(chain string) func(json.RawMessage) (bchain.BlockChain, error) { - return func(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewBitcoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*BitcoinRPC) - cli.Parser = NewBitcoinParser(GetChainParams(chain), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil - } -} - -var tests struct { - mainnet *rpc.Test - testnet *rpc.Test -} - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Bitcoin", getRPCClient("main")) - if err != nil { - panic(err) - } - - tests.mainnet = t - - t, err = rpc.NewTest("Bitcoin Testnet", getRPCClient("test")) - if err != nil { - panic(err) - } - - tests.testnet = t - - os.Exit(m.Run()) -} - -func TestBitcoinRPC_GetBlockHash(t *testing.T) { - tests.mainnet.TestGetBlockHash(t) -} - -func TestBitcoinRPC_GetBlock(t *testing.T) { - tests.mainnet.TestGetBlock(t) -} - -func TestBitcoinRPC_GetTransaction(t *testing.T) { - tests.mainnet.TestGetTransaction(t) -} - -func TestBitcoinRPC_GetTransactionForMempool(t *testing.T) { - tests.mainnet.TestGetTransactionForMempool(t) -} - -// FIXME -func TestBitcoinRPC_MempoolSync(t *testing.T) { - t.Skip("skipping test, run too long") - // tests.mainnet.TestMempoolSync(t) -} - -func TestBitcoinRPC_GetMempoolEntry(t *testing.T) { - tests.mainnet.TestGetMempoolEntry(t) -} - -func TestBitcoinRPC_EstimateSmartFee(t *testing.T) { - tests.mainnet.TestEstimateSmartFee(t) -} - -func TestBitcoinRPC_EstimateFee(t *testing.T) { - tests.mainnet.TestEstimateFee(t) -} - -func TestBitcoinRPC_GetBestBlockHash(t *testing.T) { - tests.mainnet.TestGetBestBlockHash(t) -} - -func TestBitcoinRPC_GetBestBlockHeight(t *testing.T) { - tests.mainnet.TestGetBestBlockHeight(t) -} - -func TestBitcoinRPC_GetBlockHeader(t *testing.T) { - tests.mainnet.TestGetBlockHeader(t) -} - -func TestBitcoinTestnetRPC_GetBlockHash(t *testing.T) { - tests.testnet.TestGetBlockHash(t) -} - -func TestBitcoinTestnetRPC_GetBlock(t *testing.T) { - tests.testnet.TestGetBlock(t) -} - -func TestBitcoinTestnetRPC_GetTransaction(t *testing.T) { - tests.testnet.TestGetTransaction(t) -} - -func TestBitcoinTestnetRPC_GetTransactionForMempool(t *testing.T) { - tests.testnet.TestGetTransactionForMempool(t) -} - -func TestBitcoinTestnetRPC_MempoolSync(t *testing.T) { - tests.testnet.TestMempoolSync(t) -} - -func TestBitcoinTestnetRPC_GetMempoolEntry(t *testing.T) { - tests.testnet.TestGetMempoolEntry(t) -} - -func TestBitcoinTestnetRPC_EstimateSmartFee(t *testing.T) { - tests.testnet.TestEstimateSmartFee(t) -} - -func TestBitcoinTestnetRPC_EstimateFee(t *testing.T) { - tests.testnet.TestEstimateFee(t) -} - -func TestBitcoinTestnetRPC_GetBestBlockHash(t *testing.T) { - tests.testnet.TestGetBestBlockHash(t) -} - -func TestBitcoinTestnetRPC_GetBestBlockHeight(t *testing.T) { - tests.testnet.TestGetBestBlockHeight(t) -} - -func TestBitcoinTestnetRPC_GetBlockHeader(t *testing.T) { - tests.testnet.TestGetBlockHeader(t) -} diff --git a/bchain/coins/dash/dashrpc_test.go b/bchain/coins/dash/dashrpc_test.go deleted file mode 100644 index 98662672..00000000 --- a/bchain/coins/dash/dashrpc_test.go +++ /dev/null @@ -1,129 +0,0 @@ -// +build integration - -package dash - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(chain string) func(json.RawMessage) (bchain.BlockChain, error) { - return func(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewDashRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*DashRPC) - cli.Parser = NewDashParser(GetChainParams(chain), cli.ChainConfig) - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil - } -} - -var tests struct { - mainnet *rpc.Test - testnet *rpc.Test -} - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Dash", getRPCClient("main")) - if err != nil { - panic(err) - } - - tests.mainnet = t - - t, err = rpc.NewTest("Dash Testnet", getRPCClient("test")) - if err != nil { - panic(err) - } - - tests.testnet = t - - os.Exit(m.Run()) -} - -func TestDashRPC_GetBlockHash(t *testing.T) { - tests.mainnet.TestGetBlockHash(t) -} - -func TestDashRPC_GetBlock(t *testing.T) { - tests.mainnet.TestGetBlock(t) -} - -func TestDashRPC_GetTransaction(t *testing.T) { - tests.mainnet.TestGetTransaction(t) -} - -func TestDashRPC_GetTransactionForMempool(t *testing.T) { - tests.mainnet.TestGetTransactionForMempool(t) -} - -func TestDashRPC_MempoolSync(t *testing.T) { - tests.mainnet.TestMempoolSync(t) -} - -func TestDashRPC_EstimateSmartFee(t *testing.T) { - tests.mainnet.TestEstimateSmartFee(t) -} - -func TestDashRPC_EstimateFee(t *testing.T) { - tests.mainnet.TestEstimateFee(t) -} - -func TestDashRPC_GetBestBlockHash(t *testing.T) { - tests.mainnet.TestGetBestBlockHash(t) -} - -func TestDashRPC_GetBestBlockHeight(t *testing.T) { - tests.mainnet.TestGetBestBlockHeight(t) -} - -func TestDashRPC_GetBlockHeader(t *testing.T) { - tests.mainnet.TestGetBlockHeader(t) -} - -func TestDashTestnetRPC_GetBlockHash(t *testing.T) { - tests.testnet.TestGetBlockHash(t) -} - -func TestDashTestnetRPC_GetBlock(t *testing.T) { - tests.testnet.TestGetBlock(t) -} - -func TestDashTestnetRPC_GetTransaction(t *testing.T) { - tests.testnet.TestGetTransaction(t) -} - -func TestDashTestnetRPC_GetTransactionForMempool(t *testing.T) { - tests.testnet.TestGetTransactionForMempool(t) -} - -func TestDashTestnetRPC_MempoolSync(t *testing.T) { - tests.testnet.TestMempoolSync(t) -} - -func TestDashTestnetRPC_EstimateSmartFee(t *testing.T) { - tests.testnet.TestEstimateSmartFee(t) -} - -func TestDashTestnetRPC_EstimateFee(t *testing.T) { - tests.testnet.TestEstimateFee(t) -} - -func TestDashTestnetRPC_GetBestBlockHash(t *testing.T) { - tests.testnet.TestGetBestBlockHash(t) -} - -func TestDashTestnetRPC_GetBestBlockHeight(t *testing.T) { - tests.testnet.TestGetBestBlockHeight(t) -} - -func TestDashTestnetRPC_GetBlockHeader(t *testing.T) { - tests.testnet.TestGetBlockHeader(t) -} diff --git a/bchain/coins/dogecoin/dogecoinrpc_test.go b/bchain/coins/dogecoin/dogecoinrpc_test.go deleted file mode 100644 index b9d3bbc4..00000000 --- a/bchain/coins/dogecoin/dogecoinrpc_test.go +++ /dev/null @@ -1,70 +0,0 @@ -// +build integration - -package dogecoin - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewDogecoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*DogecoinRPC) - cli.Parser = NewDogecoinParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Dogecoin", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestDogecoinRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestDogecoinRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestDogecoinRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestDogecoinRPC_GetTransactionForMempool(t *testing.T) { - rpcTest.TestGetTransactionForMempool(t) -} - -func TestDogecoinRPC_MempoolSync(t *testing.T) { - rpcTest.TestMempoolSync(t) -} - -func TestDogecoinRPC_EstimateSmartFee(t *testing.T) { - t.Skip("skipping test, unreliable") - // rpcTest.TestEstimateSmartFee(t) -} - -func TestDogecoinRPC_EstimateFee(t *testing.T) { - t.Skip("skipping test, unreliable") - // rpcTest.TestEstimateFee(t) -} diff --git a/bchain/coins/eth/ethrpc_test.go b/bchain/coins/eth/ethrpc_test.go deleted file mode 100644 index fab3349f..00000000 --- a/bchain/coins/eth/ethrpc_test.go +++ /dev/null @@ -1,62 +0,0 @@ -// +build integration - -package eth - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewEthereumRPC(cfg, nil) - if err != nil { - return nil, err - } - return c, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Ethereum Testnet", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestEthRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestEthRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestEthRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestEthRPC_GetBestBlockHash(t *testing.T) { - rpcTest.TestGetBestBlockHash(t) -} - -func TestEthRPC_GetBestBlockHeight(t *testing.T) { - rpcTest.TestGetBestBlockHeight(t) -} - -func TestEthRPC_GetBlockHeader(t *testing.T) { - rpcTest.TestGetBlockHeader(t) -} - -func TestEthRPC_EstimateFee(t *testing.T) { - rpcTest.TestEstimateFee(t) -} diff --git a/bchain/coins/litecoin/litecoinrpc_test.go b/bchain/coins/litecoin/litecoinrpc_test.go deleted file mode 100644 index 33a67b91..00000000 --- a/bchain/coins/litecoin/litecoinrpc_test.go +++ /dev/null @@ -1,72 +0,0 @@ -// +build integration - -package litecoin - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewLitecoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*LitecoinRPC) - cli.Parser = NewLitecoinParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Litecoin", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestLitecoinRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestLitecoinRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestLitecoinRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestLitecoinRPC_GetTransactionForMempool(t *testing.T) { - rpcTest.TestGetTransactionForMempool(t) -} - -func TestLitecoinRPC_MempoolSync(t *testing.T) { - rpcTest.TestMempoolSync(t) -} - -func TestLitecoinRPC_GetMempoolEntry(t *testing.T) { - rpcTest.TestGetMempoolEntry(t) -} - -func TestLitecoinRPC_EstimateSmartFee(t *testing.T) { - rpcTest.TestEstimateSmartFee(t) -} - -func TestLitecoinRPC_EstimateFee(t *testing.T) { - rpcTest.TestEstimateFee(t) -} diff --git a/bchain/coins/monacoin/monacoinrpc_test.go b/bchain/coins/monacoin/monacoinrpc_test.go deleted file mode 100644 index 4a4a7f5c..00000000 --- a/bchain/coins/monacoin/monacoinrpc_test.go +++ /dev/null @@ -1,72 +0,0 @@ -// +build integration - -package monacoin - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewMonacoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*MonacoinRPC) - cli.Parser = NewMonacoinParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Monacoin", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestMonacoinRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestMonacoinRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestMonacoinRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestMonacoinRPC_GetTransactionForMempool(t *testing.T) { - rpcTest.TestGetTransactionForMempool(t) -} - -func TestMonacoinRPC_MempoolSync(t *testing.T) { - rpcTest.TestMempoolSync(t) -} - -func TestMonacoinRPC_GetMempoolEntry(t *testing.T) { - rpcTest.TestGetMempoolEntry(t) -} - -func TestMonacoinRPC_EstimateSmartFee(t *testing.T) { - rpcTest.TestEstimateSmartFee(t) -} - -func TestMonacoinRPC_EstimateFee(t *testing.T) { - rpcTest.TestEstimateFee(t) -} diff --git a/bchain/coins/namecoin/namecoinrpc_test.go b/bchain/coins/namecoin/namecoinrpc_test.go deleted file mode 100644 index d50ef581..00000000 --- a/bchain/coins/namecoin/namecoinrpc_test.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build integration - -package namecoin - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewNamecoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*NamecoinRPC) - cli.Parser = NewNamecoinParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Namecoin", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestNamecoinRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestNamecoinRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestNamecoinRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestNamecoinRPC_GetTransactionForMempool(t *testing.T) { - // extra opcodes (name_new, name_firstupdate, name_update) aren't supported, so some transactions - // in mempool can't be parsed correctly - t.Skipf("Skipped because of instability") -} - -func TestNamecoinRPC_MempoolSync(t *testing.T) { - rpcTest.TestMempoolSync(t) -} - -func TestNamecoinRPC_GetMempoolEntry(t *testing.T) { - rpcTest.TestGetMempoolEntry(t) -} - -func TestNamecoinRPC_EstimateSmartFee(t *testing.T) { - rpcTest.TestEstimateSmartFee(t) -} - -func TestNamecoinRPC_EstimateFee(t *testing.T) { - rpcTest.TestEstimateFee(t) -} - -func TestNamecoinRPC_GetBestBlockHash(t *testing.T) { - rpcTest.TestGetBestBlockHash(t) -} - -func TestNamecoinRPC_GetBestBlockHeight(t *testing.T) { - rpcTest.TestGetBestBlockHeight(t) -} - -func TestNamecoinRPC_GetBlockHeader(t *testing.T) { - rpcTest.TestGetBlockHeader(t) -} diff --git a/bchain/coins/vertcoin/vertcoinrpc_test.go b/bchain/coins/vertcoin/vertcoinrpc_test.go deleted file mode 100644 index aa4c615e..00000000 --- a/bchain/coins/vertcoin/vertcoinrpc_test.go +++ /dev/null @@ -1,84 +0,0 @@ -// +build integration - -package vertcoin - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewVertcoinRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*VertcoinRPC) - cli.Parser = NewVertcoinParser(GetChainParams("main"), cli.ChainConfig) - if err != nil { - return nil, err - } - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil -} - -var rpcTest *rpc.Test - -func TestMain(m *testing.M) { - flag.Parse() - t, err := rpc.NewTest("Vertcoin", getRPCClient) - if err != nil { - panic(err) - } - - rpcTest = t - - os.Exit(m.Run()) -} - -func TestVertcoinRPC_GetBlockHash(t *testing.T) { - rpcTest.TestGetBlockHash(t) -} - -func TestVertcoinRPC_GetBlock(t *testing.T) { - rpcTest.TestGetBlock(t) -} - -func TestVertcoinRPC_GetTransaction(t *testing.T) { - rpcTest.TestGetTransaction(t) -} - -func TestVertcoinRPC_GetTransactionForMempool(t *testing.T) { - rpcTest.TestGetTransactionForMempool(t) -} - -func TestVertcoinRPC_MempoolSync(t *testing.T) { - rpcTest.TestMempoolSync(t) -} - -func TestVertcoinRPC_GetMempoolEntry(t *testing.T) { - rpcTest.TestGetMempoolEntry(t) -} - -func TestVertcoinRPC_EstimateSmartFee(t *testing.T) { - rpcTest.TestEstimateSmartFee(t) -} - -func TestVertcoinRPC_EstimateFee(t *testing.T) { - rpcTest.TestEstimateFee(t) -} - -func TestVertcoinRPC_GetBestBlockHash(t *testing.T) { - rpcTest.TestGetBestBlockHash(t) -} - -func TestVertcoinRPC_GetBestBlockHeight(t *testing.T) { - rpcTest.TestGetBestBlockHeight(t) -} - -func TestVertcoinRPC_GetBlockHeader(t *testing.T) { - rpcTest.TestGetBlockHeader(t) -} diff --git a/bchain/coins/zec/zcashrpc_test.go b/bchain/coins/zec/zcashrpc_test.go deleted file mode 100644 index be6be633..00000000 --- a/bchain/coins/zec/zcashrpc_test.go +++ /dev/null @@ -1,130 +0,0 @@ -// +build integration - -package zec - -import ( - "blockbook/bchain" - "blockbook/bchain/tests/rpc" - "encoding/json" - "flag" - "os" - "testing" -) - -func getRPCClient(chain string) func(cfg json.RawMessage) (bchain.BlockChain, error) { - return func(cfg json.RawMessage) (bchain.BlockChain, error) { - c, err := NewZCashRPC(cfg, nil) - if err != nil { - return nil, err - } - cli := c.(*ZCashRPC) - cli.Parser = NewZCashParser(GetChainParams(chain), cli.ChainConfig) - cli.Mempool = bchain.NewUTXOMempool(cli, cli.ChainConfig.MempoolWorkers, cli.ChainConfig.MempoolSubWorkers) - return cli, nil - } -} - -var tests struct { - mainnet *rpc.Test - testnet *rpc.Test -} - -func TestMain(m *testing.M) { - flag.Parse() - - t, err := rpc.NewTest("Zcash", getRPCClient("main")) - if err != nil { - panic(err) - } - - tests.mainnet = t - - t, err = rpc.NewTest("Zcash Testnet", getRPCClient("test")) - if err != nil { - panic(err) - } - - tests.testnet = t - - os.Exit(m.Run()) -} - -func TestZCashRPC_GetBlockHash(t *testing.T) { - tests.mainnet.TestGetBlockHash(t) -} - -func TestZCashRPC_GetBlock(t *testing.T) { - tests.mainnet.TestGetBlock(t) -} - -func TestZCashRPC_GetTransaction(t *testing.T) { - tests.mainnet.TestGetTransaction(t) -} - -func TestZCashRPC_GetTransactionForMempool(t *testing.T) { - tests.mainnet.TestGetTransactionForMempool(t) -} - -func TestZCashRPC_MempoolSync(t *testing.T) { - tests.mainnet.TestMempoolSync(t) -} - -func TestZCashRPC_EstimateSmartFee(t *testing.T) { - tests.mainnet.TestEstimateSmartFee(t) -} - -func TestZCashRPC_EstimateFee(t *testing.T) { - tests.mainnet.TestEstimateFee(t) -} - -func TestZCashRPC_GetBestBlockHash(t *testing.T) { - tests.mainnet.TestGetBestBlockHash(t) -} - -func TestZCashRPC_GetBestBlockHeight(t *testing.T) { - tests.mainnet.TestGetBestBlockHeight(t) -} - -func TestZCashRPC_GetBlockHeader(t *testing.T) { - tests.mainnet.TestGetBlockHeader(t) -} - -func TestZCashTestnetRPC_GetBlockHash(t *testing.T) { - tests.testnet.TestGetBlockHash(t) -} - -func TestZCashTestnetRPC_GetBlock(t *testing.T) { - tests.testnet.TestGetBlock(t) -} - -func TestZCashTestnetRPC_GetTransaction(t *testing.T) { - tests.testnet.TestGetTransaction(t) -} - -func TestZCashTestnetRPC_GetTransactionForMempool(t *testing.T) { - tests.testnet.TestGetTransactionForMempool(t) -} - -func TestZCashTestnetRPC_MempoolSync(t *testing.T) { - tests.testnet.TestMempoolSync(t) -} - -func TestZCashTestnetRPC_EstimateSmartFee(t *testing.T) { - tests.testnet.TestEstimateSmartFee(t) -} - -func TestZCashTestnetRPC_EstimateFee(t *testing.T) { - tests.testnet.TestEstimateFee(t) -} - -func TestZCashTestnetRPC_GetBestBlockHash(t *testing.T) { - tests.mainnet.TestGetBestBlockHash(t) -} - -func TestZCashTestnetRPC_GetBestBlockHeight(t *testing.T) { - tests.mainnet.TestGetBestBlockHeight(t) -} - -func TestZCashTestnetRPC_GetBlockHeader(t *testing.T) { - tests.mainnet.TestGetBlockHeader(t) -} diff --git a/bchain/tests/rpc/config.json b/bchain/tests/rpc/config.json deleted file mode 100644 index 2e8be7a8..00000000 --- a/bchain/tests/rpc/config.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "Bitcoin": { - "url": "http://localhost:8030", - "user": "rpc", - "pass": "rpc" - }, - "Bcash": { - "url": "http://localhost:8031", - "user": "rpc", - "pass": "rpc" - }, - "Zcash": { - "url": "http://localhost:8032", - "user": "rpc", - "pass": "rpc" - }, - "Dash": { - "url": "http://localhost:8033", - "user": "rpc", - "pass": "rpc" - }, - "Litecoin": { - "url": "http://localhost:8034", - "user": "rpc", - "pass": "rpc" - }, - "Ethereum": { - "url": "ws://localhost:8036", - "user": null, - "pass": null - }, - "Dogecoin": { - "url": "http://localhost:8038", - "user": "rpc", - "pass": "rpcp" - }, - "Namecoin": { - "url": "http://localhost:8039", - "user": "rpc", - "pass": "rpc" - }, - "Vertcoin": { - "url": "http://localhost:8040", - "user": "rpc", - "pass": "rpc" - }, - "Monacoin": { - "url": "http://localhost:8041", - "user": "rpc", - "pass": "rpc" - }, - "Bitcoin Testnet": { - "url": "http://localhost:18030", - "user": "rpc", - "pass": "rpc" - }, - "Bcash Testnet": { - "url": "http://localhost:18031", - "user": "rpc", - "pass": "rpc" - }, - "Zcash Testnet": { - "url": "http://localhost:18032", - "user": "rpc", - "pass": "rpc" - }, - "Dash Testnet": { - "url": "http://localhost:18033", - "user": "rpc", - "pass": "rpc" - }, - "Ethereum Testnet": { - "url": "ws://localhost:18036", - "user": null, - "pass": null - } -} \ No newline at end of file diff --git a/bchain/tests/rpc/data.go b/bchain/tests/rpc/data.go index d855ed48..dbe8c1f8 100644 --- a/bchain/tests/rpc/data.go +++ b/bchain/tests/rpc/data.go @@ -4,12 +4,19 @@ import ( "blockbook/bchain" "encoding/json" "errors" - "fmt" "io/ioutil" "path/filepath" "strings" ) +type TestData struct { + BlockHeight uint32 `json:"blockHeight"` + BlockHash string `json:"blockHash"` + BlockTime int64 `json:"blockTime"` + BlockTxs []string `json:"blockTxs"` + TxDetails map[string]*bchain.Tx `json:"txDetails"` +} + func joinPathsWithCommonElement(p1, p2 string) (string, bool) { idx := strings.IndexRune(p2, filepath.Separator) if idx <= 0 { @@ -42,46 +49,6 @@ func readDataFile(dir, relDir, filename string) ([]byte, error) { return ioutil.ReadFile(path) } -var testConfigRegistry map[string]*TestConfig - -func LoadTestConfig(coin string) (*TestConfig, error) { - if testConfigRegistry == nil { - b, err := readDataFile(".", "bchain/tests/rpc", "config.json") - if err != nil { - return nil, err - } - var v map[string]*TestConfig - err = json.Unmarshal(b, &v) - if err != nil { - return nil, err - } - testConfigRegistry = v - } - c, found := testConfigRegistry[coin] - if !found { - return nil, errors.New("Test config not found") - } - return c, nil -} - -func LoadRPCConfig(coin string) (json.RawMessage, error) { - t := `{ - "coin_name": "%s", - "rpc_url": "%s", - "rpc_user": "%s", - "rpc_pass": "%s", - "rpc_timeout": 25, - "parse": true - }` - - c, err := LoadTestConfig(coin) - if err != nil { - return json.RawMessage{}, err - } - - return json.RawMessage(fmt.Sprintf(t, coin, c.URL, c.User, c.Pass)), nil -} - func LoadTestData(coin string, parser bchain.BlockChainParser) (*TestData, error) { b, err := readDataFile(".", "bchain/tests/rpc/testdata", coin+".json") if err != nil { diff --git a/bchain/tests/rpc/rpc.go b/bchain/tests/rpc/rpc.go deleted file mode 100644 index 675e6015..00000000 --- a/bchain/tests/rpc/rpc.go +++ /dev/null @@ -1,455 +0,0 @@ -package rpc - -import ( - "blockbook/bchain" - "encoding/json" - "math/rand" - "net" - "reflect" - "testing" - "time" - - "github.com/deckarep/golang-set" -) - -type TestConfig struct { - URL string `json:"url"` - User string `json:"user"` - Pass string `json:"pass"` -} - -type TestData struct { - BlockHeight uint32 `json:"blockHeight"` - BlockHash string `json:"blockHash"` - BlockTime int64 `json:"blockTime"` - BlockTxs []string `json:"blockTxs"` - TxDetails map[string]*bchain.Tx `json:"txDetails"` -} - -type Test struct { - Client bchain.BlockChain - TestData *TestData - connected bool -} - -type TestChainFactoryFunc func(json.RawMessage) (bchain.BlockChain, error) - -func NewTest(coin string, factory TestChainFactoryFunc) (*Test, error) { - var ( - connected = true - cli bchain.BlockChain - cfg json.RawMessage - td *TestData - err error - ) - - cfg, err = LoadRPCConfig(coin) - if err != nil { - return nil, err - } - - cli, err = factory(cfg) - if err != nil { - if isNetError(err) { - connected = false - } else { - return nil, err - } - } else { - td, err = LoadTestData(coin, cli.GetChainParser()) - if err != nil { - return nil, err - } - - if td.TxDetails != nil { - parser := cli.GetChainParser() - - for _, tx := range td.TxDetails { - err := setTxAddresses(parser, tx) - if err != nil { - return nil, err - } - } - } - - _, err = cli.GetBlockChainInfo() - if err != nil && isNetError(err) { - connected = false - } - } - - return &Test{Client: cli, TestData: td, connected: connected}, nil -} - -func isNetError(err error) bool { - if _, ok := err.(net.Error); ok { - return true - } - return false -} - -func setTxAddresses(parser bchain.BlockChainParser, tx *bchain.Tx) error { - // pack and unpack transaction in order to get addresses decoded - ugly but works - var tmp *bchain.Tx - b, err := parser.PackTx(tx, 0, 0) - if err == nil { - tmp, _, err = parser.UnpackTx(b) - if err == nil { - for i := 0; i < len(tx.Vout); i++ { - tx.Vout[i].ScriptPubKey.Addresses = tmp.Vout[i].ScriptPubKey.Addresses - } - } - } - return err -} - -func (rt *Test) skipUnconnected(t *testing.T) { - if !rt.connected { - t.Skip("Skipping test, not connected to backend service") - } -} - -func (rt *Test) TestGetBlockHash(t *testing.T) { - rt.skipUnconnected(t) - - hash, err := rt.Client.GetBlockHash(rt.TestData.BlockHeight) - if err != nil { - t.Error(err) - return - } - - if hash != rt.TestData.BlockHash { - t.Errorf("GetBlockHash() got %q, want %q", hash, rt.TestData.BlockHash) - } -} - -func (rt *Test) TestGetBlock(t *testing.T) { - rt.skipUnconnected(t) - - blk, err := rt.Client.GetBlock(rt.TestData.BlockHash, 0) - if err != nil { - t.Error(err) - return - } - - if len(blk.Txs) != len(rt.TestData.BlockTxs) { - t.Errorf("GetBlock() number of transactions: got %d, want %d", len(blk.Txs), len(rt.TestData.BlockTxs)) - } - - for ti, tx := range blk.Txs { - if tx.Txid != rt.TestData.BlockTxs[ti] { - t.Errorf("GetBlock() transaction %d: got %s, want %s", ti, tx.Txid, rt.TestData.BlockTxs[ti]) - } - } - -} - -func (rt *Test) TestGetTransaction(t *testing.T) { - rt.skipUnconnected(t) - - for txid, want := range rt.TestData.TxDetails { - got, err := rt.Client.GetTransaction(txid) - if err != nil { - t.Error(err) - return - } - // Confirmations is variable field, we just check if is set and reset it - if got.Confirmations <= 0 { - t.Errorf("GetTransaction() got struct with invalid Confirmations field") - continue - } - got.Confirmations = 0 - - if !reflect.DeepEqual(got, want) { - t.Errorf("GetTransaction() got %+v, want %+v", got, want) - } - } -} - -func (rt *Test) TestGetTransactionForMempool(t *testing.T) { - rt.skipUnconnected(t) - - for txid, want := range rt.TestData.TxDetails { - // reset fields that are not parsed by BlockChainParser - want.Confirmations, want.Blocktime, want.Time = 0, 0, 0 - - got, err := rt.Client.GetTransactionForMempool(txid) - if err != nil { - t.Fatal(err) - } - // transactions parsed from JSON may contain additional data - got.Confirmations, got.Blocktime, got.Time = 0, 0, 0 - if !reflect.DeepEqual(got, want) { - t.Errorf("GetTransactionForMempool() got %+v, want %+v", got, want) - } - } -} - -func (rt *Test) getMempool(t *testing.T) []string { - txs, err := rt.Client.GetMempool() - if err != nil { - t.Fatal(err) - } - if len(txs) == 0 { - t.Skip("Skipping test, mempool is empty") - } - - return txs -} - -func (rt *Test) getMempoolAddresses(t *testing.T, txs []string) map[string][]string { - txid2addrs := map[string][]string{} - for i := 0; i < len(txs); i++ { - tx, err := rt.Client.GetTransactionForMempool(txs[i]) - if err != nil { - t.Fatal(err) - } - addrs := []string{} - for _, vin := range tx.Vin { - for _, a := range vin.Addresses { - addrs = append(addrs, a) - } - } - for _, vout := range tx.Vout { - for _, a := range vout.ScriptPubKey.Addresses { - addrs = append(addrs, a) - } - } - if len(addrs) > 0 { - txid2addrs[tx.Txid] = addrs - } - } - return txid2addrs -} - -func (rt *Test) TestMempoolSync(t *testing.T) { - rt.skipUnconnected(t) - - for i := 0; i < 3; i++ { - txs := rt.getMempool(t) - - n, err := rt.Client.ResyncMempool(nil) - if err != nil { - t.Fatal(err) - } - if n == 0 { - // no transactions to test - continue - } - - txs = intersect(txs, rt.getMempool(t)) - if len(txs) == 0 { - // no transactions to test - continue - } - - txid2addrs := rt.getMempoolAddresses(t, txs) - if len(txid2addrs) == 0 { - t.Skip("Skipping test, no addresses in mempool") - } - - for txid, addrs := range txid2addrs { - for _, a := range addrs { - got, err := rt.Client.GetMempoolTransactions(a) - if err != nil { - t.Fatal(err) - } - if !containsString(got, txid) { - t.Errorf("ResyncMempool() - for address %s, transaction %s wasn't found in mempool", a, txid) - return - } - } - } - - // done - return - } - t.Skip("Skipping test, all attempts to sync mempool failed due to network state changes") -} - -func intersect(a, b []string) []string { - setA := mapset.NewSet() - for _, v := range a { - setA.Add(v) - } - setB := mapset.NewSet() - for _, v := range b { - setB.Add(v) - } - inter := setA.Intersect(setB) - res := make([]string, 0, inter.Cardinality()) - for v := range inter.Iter() { - res = append(res, v.(string)) - } - return res -} - -func containsString(slice []string, s string) bool { - for i := 0; i < len(slice); i++ { - if slice[i] == s { - return true - } - } - return false -} - -func (rt *Test) TestGetMempoolEntry(t *testing.T) { - rt.skipUnconnected(t) - - for i := 0; i < 3; i++ { - txs := rt.getMempool(t) - h, err := rt.Client.GetBestBlockHeight() - if err != nil { - t.Fatal(err) - } - - txid := txs[rand.Intn(len(txs))] - tx, err := rt.Client.GetTransactionForMempool(txid) - if err != nil { - t.Fatal(err) - } - if tx.Confirmations > 0 { - // tx confirmed - continue - } - - e, err := rt.Client.GetMempoolEntry(txid) - if err != nil { - if err, ok := err.(*bchain.RPCError); ok && err.Code == -5 { - // tx confirmed - continue - } - t.Fatal(err) - } - - if d := int(e.Height) - int(h); d < -1 || d > 1 { - t.Errorf("GetMempoolEntry() got height %d, want %d", e.Height, h) - } - if e.Size <= 0 { - t.Errorf("GetMempoolEntry() got zero or negative size %d", e.Size) - } - if e.FeeSat.Sign() != 1 { - t.Errorf("GetMempoolEntry() got zero or negative fee %v", e.FeeSat.String()) - } - - // done - return - } - t.Skip("Skipping test, all attempts to get mempool entry failed due to network state changes") -} - -func (rt *Test) TestEstimateSmartFee(t *testing.T) { - rt.skipUnconnected(t) - - for _, blocks := range []int{1, 2, 3, 5, 10} { - fee, err := rt.Client.EstimateSmartFee(blocks, true) - if err != nil { - t.Error(err) - } - if fee.Sign() == -1 { - sf := rt.Client.GetChainParser().AmountToDecimalString(&fee) - if sf != "-1" { - t.Errorf("EstimateSmartFee() returned unexpected fee rate: %v", sf) - } - } - } -} - -func (rt *Test) TestEstimateFee(t *testing.T) { - rt.skipUnconnected(t) - - for _, blocks := range []int{1, 2, 3, 5, 10} { - fee, err := rt.Client.EstimateFee(blocks) - if err != nil { - t.Error(err) - } - if fee.Sign() == -1 { - sf := rt.Client.GetChainParser().AmountToDecimalString(&fee) - if sf != "-1" { - t.Errorf("EstimateFee() returned unexpected fee rate: %v", sf) - } - } - } -} - -func (rt *Test) TestGetBestBlockHash(t *testing.T) { - rt.skipUnconnected(t) - - for i := 0; i < 3; i++ { - hash, err := rt.Client.GetBestBlockHash() - if err != nil { - t.Fatal(err) - } - - height, err := rt.Client.GetBestBlockHeight() - if err != nil { - t.Fatal(err) - } - hh, err := rt.Client.GetBlockHash(height) - if err != nil { - t.Fatal(err) - } - if hash != hh { - time.Sleep(time.Millisecond * 100) - continue - } - - // we expect no next block - _, err = rt.Client.GetBlock("", height+1) - if err != nil { - if err != bchain.ErrBlockNotFound { - t.Error(err) - } - return - } - } - t.Error("GetBestBlockHash() didn't get the best hash") -} - -func (rt *Test) TestGetBestBlockHeight(t *testing.T) { - rt.skipUnconnected(t) - - for i := 0; i < 3; i++ { - height, err := rt.Client.GetBestBlockHeight() - if err != nil { - t.Fatal(err) - } - - // we expect no next block - _, err = rt.Client.GetBlock("", height+1) - if err != nil { - if err != bchain.ErrBlockNotFound { - t.Error(err) - } - return - } - } - t.Error("GetBestBlockHeigh() didn't get the the best heigh") -} - -func (rt *Test) TestGetBlockHeader(t *testing.T) { - rt.skipUnconnected(t) - - want := &bchain.BlockHeader{ - Hash: rt.TestData.BlockHash, - Height: rt.TestData.BlockHeight, - Time: rt.TestData.BlockTime, - } - - got, err := rt.Client.GetBlockHeader(rt.TestData.BlockHash) - if err != nil { - t.Fatal(err) - } - - // Confirmations is variable field, we just check if is set and reset it - if got.Confirmations <= 0 { - t.Fatalf("GetBlockHeader() got struct with invalid Confirmations field") - } - got.Confirmations = 0 - - got.Prev, got.Next = "", "" - - if !reflect.DeepEqual(got, want) { - t.Errorf("GetBlockHeader() got=%+v, want=%+v", got, want) - } -} diff --git a/bchain/tests/rpc/rpc_test.go b/bchain/tests/rpc/rpc_test.go new file mode 100644 index 00000000..8c9f91b5 --- /dev/null +++ b/bchain/tests/rpc/rpc_test.go @@ -0,0 +1,484 @@ +// +build integration + +package rpc + +import ( + "blockbook/bchain" + "blockbook/bchain/coins" + "blockbook/build/tools" + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net" + "os" + "path/filepath" + "reflect" + "strings" + "testing" + "time" + + "github.com/deckarep/golang-set" +) + +var testMap = map[string]func(t *testing.T, th *TestHandler){ + "GetBlockHash": testGetBlockHash, + "GetBlock": testGetBlock, + "GetTransaction": testGetTransaction, + "GetTransactionForMempool": testGetTransactionForMempool, + "MempoolSync": testMempoolSync, + "EstimateSmartFee": testEstimateSmartFee, + "EstimateFee": testEstimateFee, + "GetBestBlockHash": testGetBestBlockHash, + "GetBestBlockHeight": testGetBestBlockHeight, + "GetBlockHeader": testGetBlockHeader, +} + +type TestHandler struct { + Client bchain.BlockChain + TestData *TestData + connected bool +} + +var notConnectedError = errors.New("Not connected to backend server") + +func TestRPCIntegration(t *testing.T) { + src := os.Getenv("BLOCKBOOK_SRC") + if src == "" { + t.Fatalf("Missing environment variable BLOCKBOOK_SRC") + } + + configsDir := filepath.Join(src, "configs") + templateDir := filepath.Join(src, "build/templates") + + noTests := 0 + skippedTests := make([]string, 0, 10) + + err := filepath.Walk(filepath.Join(configsDir, "coins"), func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() || info.Name()[0] == '.' { + return nil + } + + n := strings.TrimSuffix(info.Name(), ".json") + c, err := build.LoadConfig(configsDir, n) + if err != nil { + t.Errorf("%s: cannot load configuration: %s", n, err) + return nil + } + if len(c.IntegrationTests["rpc"]) == 0 { + return nil + } + + cfg, err := makeBlockChainConfig(c, templateDir) + if err != nil { + t.Errorf("%s: cannot make blockchain config: %s", n, err) + return nil + } + + t.Run(c.Coin.Alias, func(t *testing.T) { + noTests += 1 + err := runTests(t, c.Coin.Name, c.Coin.Alias, cfg, c.IntegrationTests["rpc"]) + if err != nil { + if err == notConnectedError { + skippedTests = append(skippedTests, c.Coin.Alias) + t.Skip(err) + } + t.Fatal(err) + } + }) + + return nil + }) + + if err != nil { + t.Fatal(err) + } + + if len(skippedTests) > 0 { + t.Errorf("Too many skipped tests: %q", skippedTests) + } +} + +func makeBlockChainConfig(c *build.Config, templateDir string) (json.RawMessage, error) { + outputDir, err := ioutil.TempDir("", "rpc_test") + if err != nil { + return nil, err + } + defer os.RemoveAll(outputDir) + + err = build.GeneratePackageDefinitions(c, templateDir, outputDir) + if err != nil { + return nil, err + } + + b, err := ioutil.ReadFile(filepath.Join(outputDir, "blockbook", "blockchaincfg.json")) + if err != nil { + return nil, err + } + + var v json.RawMessage + err = json.Unmarshal(b, &v) + if err != nil { + return nil, err + } + + return v, nil +} + +func runTests(t *testing.T, coinName, coinAlias string, cfg json.RawMessage, tests []string) error { + cli, err := initBlockChain(coinName, cfg) + if err != nil { + if err == notConnectedError { + return err + } + t.Fatal(err) + } + td, err := LoadTestData(coinAlias, cli.GetChainParser()) + if err != nil { + t.Fatalf("Test data loading failed: %s", err) + } + + if td.TxDetails != nil { + parser := cli.GetChainParser() + + for _, tx := range td.TxDetails { + err := setTxAddresses(parser, tx) + if err != nil { + t.Fatalf("Test data loading failed: %s", err) + } + } + } + + h := TestHandler{Client: cli, TestData: td} + + for _, test := range tests { + if f, found := testMap[test]; found { + t.Run(test, func(t *testing.T) { f(t, &h) }) + } else { + t.Errorf("%s: test not found", test) + continue + } + } + + return nil +} + +func initBlockChain(coinName string, cfg json.RawMessage) (bchain.BlockChain, error) { + factory, found := coins.BlockChainFactories[coinName] + if !found { + return nil, fmt.Errorf("Factory function not found") + } + + cli, err := factory(cfg, func(_ bchain.NotificationType) {}) + if err != nil { + if isNetError(err) { + return nil, notConnectedError + } + return nil, fmt.Errorf("Factory function failed: %s", err) + } + + err = cli.Initialize() + if err != nil { + if isNetError(err) { + return nil, notConnectedError + } + return nil, fmt.Errorf("BlockChain initialization failed: %s", err) + } + + return cli, nil +} + +func isNetError(err error) bool { + if _, ok := err.(net.Error); ok { + return true + } + return false +} + +func setTxAddresses(parser bchain.BlockChainParser, tx *bchain.Tx) error { + // pack and unpack transaction in order to get addresses decoded - ugly but works + var tmp *bchain.Tx + b, err := parser.PackTx(tx, 0, 0) + if err == nil { + tmp, _, err = parser.UnpackTx(b) + if err == nil { + for i := 0; i < len(tx.Vout); i++ { + tx.Vout[i].ScriptPubKey.Addresses = tmp.Vout[i].ScriptPubKey.Addresses + } + } + } + return err +} + +func testGetBlockHash(t *testing.T, h *TestHandler) { + hash, err := h.Client.GetBlockHash(h.TestData.BlockHeight) + if err != nil { + t.Error(err) + return + } + + if hash != h.TestData.BlockHash { + t.Errorf("GetBlockHash() got %q, want %q", hash, h.TestData.BlockHash) + } +} +func testGetBlock(t *testing.T, h *TestHandler) { + blk, err := h.Client.GetBlock(h.TestData.BlockHash, 0) + if err != nil { + t.Error(err) + return + } + + if len(blk.Txs) != len(h.TestData.BlockTxs) { + t.Errorf("GetBlock() number of transactions: got %d, want %d", len(blk.Txs), len(h.TestData.BlockTxs)) + } + + for ti, tx := range blk.Txs { + if tx.Txid != h.TestData.BlockTxs[ti] { + t.Errorf("GetBlock() transaction %d: got %s, want %s", ti, tx.Txid, h.TestData.BlockTxs[ti]) + } + } +} +func testGetTransaction(t *testing.T, h *TestHandler) { + for txid, want := range h.TestData.TxDetails { + got, err := h.Client.GetTransaction(txid) + if err != nil { + t.Error(err) + return + } + // Confirmations is variable field, we just check if is set and reset it + if got.Confirmations <= 0 { + t.Errorf("GetTransaction() got struct with invalid Confirmations field") + continue + } + got.Confirmations = 0 + + if !reflect.DeepEqual(got, want) { + t.Errorf("GetTransaction() got %+v, want %+v", got, want) + } + } +} +func testGetTransactionForMempool(t *testing.T, h *TestHandler) { + for txid, want := range h.TestData.TxDetails { + // reset fields that are not parsed by BlockChainParser + want.Confirmations, want.Blocktime, want.Time = 0, 0, 0 + + got, err := h.Client.GetTransactionForMempool(txid) + if err != nil { + t.Fatal(err) + } + // transactions parsed from JSON may contain additional data + got.Confirmations, got.Blocktime, got.Time = 0, 0, 0 + if !reflect.DeepEqual(got, want) { + t.Errorf("GetTransactionForMempool() got %+v, want %+v", got, want) + } + } +} +func testMempoolSync(t *testing.T, h *TestHandler) { + for i := 0; i < 3; i++ { + txs := getMempool(t, h) + + n, err := h.Client.ResyncMempool(nil) + if err != nil { + t.Fatal(err) + } + if n == 0 { + // no transactions to test + continue + } + + txs = intersect(txs, getMempool(t, h)) + if len(txs) == 0 { + // no transactions to test + continue + } + + txid2addrs := getMempoolAddresses(t, h, txs) + if len(txid2addrs) == 0 { + t.Skip("Skipping test, no addresses in mempool") + } + + for txid, addrs := range txid2addrs { + for _, a := range addrs { + got, err := h.Client.GetMempoolTransactions(a) + if err != nil { + t.Fatal(err) + } + if !containsString(got, txid) { + t.Errorf("ResyncMempool() - for address %s, transaction %s wasn't found in mempool", a, txid) + return + } + } + } + + // done + return + } + t.Skip("Skipping test, all attempts to sync mempool failed due to network state changes") +} +func testEstimateSmartFee(t *testing.T, h *TestHandler) { + for _, blocks := range []int{1, 2, 3, 5, 10} { + fee, err := h.Client.EstimateSmartFee(blocks, true) + if err != nil { + t.Error(err) + } + if fee.Sign() == -1 { + sf := h.Client.GetChainParser().AmountToDecimalString(&fee) + if sf != "-1" { + t.Errorf("EstimateSmartFee() returned unexpected fee rate: %v", sf) + } + } + } +} +func testEstimateFee(t *testing.T, h *TestHandler) { + for _, blocks := range []int{1, 2, 3, 5, 10} { + fee, err := h.Client.EstimateFee(blocks) + if err != nil { + t.Error(err) + } + if fee.Sign() == -1 { + sf := h.Client.GetChainParser().AmountToDecimalString(&fee) + if sf != "-1" { + t.Errorf("EstimateFee() returned unexpected fee rate: %v", sf) + } + } + } +} +func testGetBestBlockHash(t *testing.T, h *TestHandler) { + for i := 0; i < 3; i++ { + hash, err := h.Client.GetBestBlockHash() + if err != nil { + t.Fatal(err) + } + + height, err := h.Client.GetBestBlockHeight() + if err != nil { + t.Fatal(err) + } + hh, err := h.Client.GetBlockHash(height) + if err != nil { + t.Fatal(err) + } + if hash != hh { + time.Sleep(time.Millisecond * 100) + continue + } + + // we expect no next block + _, err = h.Client.GetBlock("", height+1) + if err != nil { + if err != bchain.ErrBlockNotFound { + t.Error(err) + } + return + } + } + t.Error("GetBestBlockHash() didn't get the best hash") +} +func testGetBestBlockHeight(t *testing.T, h *TestHandler) { + for i := 0; i < 3; i++ { + height, err := h.Client.GetBestBlockHeight() + if err != nil { + t.Fatal(err) + } + + // we expect no next block + _, err = h.Client.GetBlock("", height+1) + if err != nil { + if err != bchain.ErrBlockNotFound { + t.Error(err) + } + return + } + } + t.Error("GetBestBlockHeigh() didn't get the the best heigh") +} +func testGetBlockHeader(t *testing.T, h *TestHandler) { + want := &bchain.BlockHeader{ + Hash: h.TestData.BlockHash, + Height: h.TestData.BlockHeight, + Time: h.TestData.BlockTime, + } + + got, err := h.Client.GetBlockHeader(h.TestData.BlockHash) + if err != nil { + t.Fatal(err) + } + + // Confirmations is variable field, we just check if is set and reset it + if got.Confirmations <= 0 { + t.Fatalf("GetBlockHeader() got struct with invalid Confirmations field") + } + got.Confirmations = 0 + + got.Prev, got.Next = "", "" + + if !reflect.DeepEqual(got, want) { + t.Errorf("GetBlockHeader() got=%+v, want=%+v", got, want) + } +} + +func getMempool(t *testing.T, h *TestHandler) []string { + txs, err := h.Client.GetMempool() + if err != nil { + t.Fatal(err) + } + if len(txs) == 0 { + t.Skip("Skipping test, mempool is empty") + } + + return txs +} + +func getMempoolAddresses(t *testing.T, h *TestHandler, txs []string) map[string][]string { + txid2addrs := map[string][]string{} + for i := 0; i < len(txs); i++ { + tx, err := h.Client.GetTransactionForMempool(txs[i]) + if err != nil { + t.Fatal(err) + } + addrs := []string{} + for _, vin := range tx.Vin { + for _, a := range vin.Addresses { + addrs = append(addrs, a) + } + } + for _, vout := range tx.Vout { + for _, a := range vout.ScriptPubKey.Addresses { + addrs = append(addrs, a) + } + } + if len(addrs) > 0 { + txid2addrs[tx.Txid] = addrs + } + } + return txid2addrs +} + +func intersect(a, b []string) []string { + setA := mapset.NewSet() + for _, v := range a { + setA.Add(v) + } + setB := mapset.NewSet() + for _, v := range b { + setB.Add(v) + } + inter := setA.Intersect(setB) + res := make([]string, 0, inter.Cardinality()) + for v := range inter.Iter() { + res = append(res, v.(string)) + } + return res +} + +func containsString(slice []string, s string) bool { + for i := 0; i < len(slice); i++ { + if slice[i] == s { + return true + } + } + return false +} diff --git a/bchain/tests/rpc/testdata/Bcash.json b/bchain/tests/rpc/testdata/bcash.json similarity index 100% rename from bchain/tests/rpc/testdata/Bcash.json rename to bchain/tests/rpc/testdata/bcash.json diff --git a/bchain/tests/rpc/testdata/Bcash_Testnet.json b/bchain/tests/rpc/testdata/bcash_testnet.json similarity index 100% rename from bchain/tests/rpc/testdata/Bcash_Testnet.json rename to bchain/tests/rpc/testdata/bcash_testnet.json diff --git a/bchain/tests/rpc/testdata/Bitcoin.json b/bchain/tests/rpc/testdata/bitcoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Bitcoin.json rename to bchain/tests/rpc/testdata/bitcoin.json diff --git a/bchain/tests/rpc/testdata/Bitcoin_Testnet.json b/bchain/tests/rpc/testdata/bitcoin_testnet.json similarity index 100% rename from bchain/tests/rpc/testdata/Bitcoin_Testnet.json rename to bchain/tests/rpc/testdata/bitcoin_testnet.json diff --git a/bchain/tests/rpc/testdata/Dash.json b/bchain/tests/rpc/testdata/dash.json similarity index 100% rename from bchain/tests/rpc/testdata/Dash.json rename to bchain/tests/rpc/testdata/dash.json diff --git a/bchain/tests/rpc/testdata/Dash_Testnet.json b/bchain/tests/rpc/testdata/dash_testnet.json similarity index 100% rename from bchain/tests/rpc/testdata/Dash_Testnet.json rename to bchain/tests/rpc/testdata/dash_testnet.json diff --git a/bchain/tests/rpc/testdata/Dogecoin.json b/bchain/tests/rpc/testdata/dogecoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Dogecoin.json rename to bchain/tests/rpc/testdata/dogecoin.json diff --git a/bchain/tests/rpc/testdata/Ethereum_Testnet.json b/bchain/tests/rpc/testdata/ethereum_testnet_ropsten.json similarity index 100% rename from bchain/tests/rpc/testdata/Ethereum_Testnet.json rename to bchain/tests/rpc/testdata/ethereum_testnet_ropsten.json diff --git a/bchain/tests/rpc/testdata/Litecoin.json b/bchain/tests/rpc/testdata/litecoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Litecoin.json rename to bchain/tests/rpc/testdata/litecoin.json diff --git a/bchain/tests/rpc/testdata/Monacoin.json b/bchain/tests/rpc/testdata/monacoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Monacoin.json rename to bchain/tests/rpc/testdata/monacoin.json diff --git a/bchain/tests/rpc/testdata/Namecoin.json b/bchain/tests/rpc/testdata/namecoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Namecoin.json rename to bchain/tests/rpc/testdata/namecoin.json diff --git a/bchain/tests/rpc/testdata/Vertcoin.json b/bchain/tests/rpc/testdata/vertcoin.json similarity index 100% rename from bchain/tests/rpc/testdata/Vertcoin.json rename to bchain/tests/rpc/testdata/vertcoin.json diff --git a/bchain/tests/rpc/testdata/Zcash.json b/bchain/tests/rpc/testdata/zcash.json similarity index 100% rename from bchain/tests/rpc/testdata/Zcash.json rename to bchain/tests/rpc/testdata/zcash.json diff --git a/bchain/tests/rpc/testdata/Zcash_Testnet.json b/bchain/tests/rpc/testdata/zcash_testnet.json similarity index 100% rename from bchain/tests/rpc/testdata/Zcash_Testnet.json rename to bchain/tests/rpc/testdata/zcash_testnet.json diff --git a/build/docker/bin/Makefile b/build/docker/bin/Makefile index 2043a202..f972f896 100644 --- a/build/docker/bin/Makefile +++ b/build/docker/bin/Makefile @@ -4,17 +4,20 @@ VERSION ?= devel GITCOMMIT = $(shell cd /src && git describe --tags --always --dirty) BUILDTIME = $(shell date --iso-8601=seconds) LDFLAGS := -X blockbook/common.version=$(VERSION) -X blockbook/common.gitcommit=$(GITCOMMIT) -X blockbook/common.buildtime=$(BUILDTIME) +BLOCKBOOK_SRC := $(GOPATH)/src/blockbook ARGS ?= +export BLOCKBOOK_SRC + all: build tools build: prepare-sources - cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="-s -w $(LDFLAGS)" $(ARGS) + cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags="-s -w $(LDFLAGS)" $(ARGS) cp $(CURDIR)/blockbook /out/blockbook chown $(PACKAGER) /out/blockbook build-debug: prepare-sources - cd $(GOPATH)/src/blockbook && go build -o $(CURDIR)/blockbook -ldflags="$(LDFLAGS)" $(ARGS) + cd $(BLOCKBOOK_SRC) && go build -o $(CURDIR)/blockbook -ldflags="$(LDFLAGS)" $(ARGS) cp $(CURDIR)/blockbook /out/blockbook chown $(PACKAGER) /out/blockbook @@ -23,20 +26,20 @@ tools: chown $(PACKAGER) /out/{ldb,sst_dump} test: prepare-sources - cd $(GOPATH)/src/blockbook && go test -tags unittest `go list ./... | grep -v '^blockbook/contrib'` $(ARGS) + cd $(BLOCKBOOK_SRC) && go test -tags unittest `go list ./... | grep -v '^blockbook/contrib'` $(ARGS) test-all: prepare-sources - cd $(GOPATH)/src/blockbook && go test -tags 'unittest integration' `go list ./... | grep -v '^blockbook/contrib'` $(ARGS) + cd $(BLOCKBOOK_SRC) && go test -tags 'unittest integration' `go list ./... | grep -v '^blockbook/contrib'` $(ARGS) prepare-sources: @ [ -n "`ls /src 2> /dev/null`" ] || (echo "/src doesn't exist or is empty" 1>&2 && exit 1) - [ -d $(GOPATH)/src/blockbook ] || cp -r /src $(GOPATH)/src/blockbook + [ -d $(BLOCKBOOK_SRC) ] || cp -r /src $(BLOCKBOOK_SRC) $(MAKE) prepare-vendor prepare-vendor: @ if [ "$(UPDATE_VENDOR)" -eq 1 ]; then \ echo "Updating vendor"; \ - rm -rf $(GOPATH)/src/blockbook/vendor && cd $(GOPATH)/src/blockbook && dep ensure -vendor-only ; \ + rm -rf $(BLOCKBOOK_SRC)/vendor && cd $(BLOCKBOOK_SRC) && dep ensure -vendor-only ; \ else \ echo "Update of vendor not demanded, keeping version from src" ; \ fi diff --git a/build/templates/generate.go b/build/templates/generate.go index 20d2f893..6c44ee7b 100644 --- a/build/templates/generate.go +++ b/build/templates/generate.go @@ -1,126 +1,19 @@ package main import ( - "encoding/json" + "blockbook/build/tools" "fmt" - "io" "os" "path/filepath" "strings" - "text/template" - "time" ) const ( - configsDir = "configs" - inputDir = "build/templates" - outputDir = "build/pkg-defs" + configsDir = "configs" + templateDir = "build/templates" + outputDir = "build/pkg-defs" ) -type Config struct { - Meta struct { - BuildDatetime string // generated field - PackageMaintainer string `json:"package_maintainer"` - PackageMaintainerEmail string `json:"package_maintainer_email"` - } - Env struct { - Version string `json:"version"` - BackendInstallPath string `json:"backend_install_path"` - BackendDataPath string `json:"backend_data_path"` - BlockbookInstallPath string `json:"blockbook_install_path"` - BlockbookDataPath string `json:"blockbook_data_path"` - } `json:"env"` - Coin struct { - Name string `json:"name"` - Shortcut string `json:"shortcut"` - Label string `json:"label"` - Alias string `json:"alias"` - } `json:"coin"` - Ports struct { - BackendRPC int `json:"backend_rpc"` - BackendMessageQueue int `json:"backend_message_queue"` - BlockbookInternal int `json:"blockbook_internal"` - BlockbookPublic int `json:"blockbook_public"` - } `json:"ports"` - IPC struct { - RPCURLTemplate string `json:"rpc_url_template"` - RPCUser string `json:"rpc_user"` - RPCPass string `json:"rpc_pass"` - RPCTimeout int `json:"rpc_timeout"` - MessageQueueBindingTemplate string `json:"message_queue_binding_template"` - } `json:"ipc"` - Backend struct { - PackageName string `json:"package_name"` - PackageRevision string `json:"package_revision"` - SystemUser string `json:"system_user"` - Version string `json:"version"` - BinaryURL string `json:"binary_url"` - VerificationType string `json:"verification_type"` - VerificationSource string `json:"verification_source"` - ExtractCommand string `json:"extract_command"` - ExcludeFiles []string `json:"exclude_files"` - ExecCommandTemplate string `json:"exec_command_template"` - LogrotateFilesTemplate string `json:"logrotate_files_template"` - PostinstScriptTemplate string `json:"postinst_script_template"` - ServiceType string `json:"service_type"` - ServiceAdditionalParamsTemplate string `json:"service_additional_params_template"` - ProtectMemory bool `json:"protect_memory"` - Mainnet bool `json:"mainnet"` - ConfigFile string `json:"config_file"` - AdditionalParams interface{} `json:"additional_params"` - } `json:"backend"` - Blockbook struct { - PackageName string `json:"package_name"` - SystemUser string `json:"system_user"` - InternalBindingTemplate string `json:"internal_binding_template"` - PublicBindingTemplate string `json:"public_binding_template"` - ExplorerURL string `json:"explorer_url"` - AdditionalParams string `json:"additional_params"` - BlockChain struct { - Parse bool `json:"parse"` - Subversion string `json:"subversion"` - AddressFormat string `json:"address_format"` - MempoolWorkers int `json:"mempool_workers"` - MempoolSubWorkers int `json:"mempool_sub_workers"` - BlockAddressesToKeep int `json:"block_addresses_to_keep"` - AdditionalParams map[string]json.RawMessage `json:"additional_params"` - } `json:"block_chain"` - } `json:"blockbook"` -} - -func jsonToString(msg json.RawMessage) (string, error) { - d, err := msg.MarshalJSON() - if err != nil { - return "", err - } - return string(d), nil -} - -func (c *Config) ParseTemplate() *template.Template { - templates := map[string]string{ - "IPC.RPCURLTemplate": c.IPC.RPCURLTemplate, - "IPC.MessageQueueBindingTemplate": c.IPC.MessageQueueBindingTemplate, - "Backend.ExecCommandTemplate": c.Backend.ExecCommandTemplate, - "Backend.LogrotateFilesTemplate": c.Backend.LogrotateFilesTemplate, - "Backend.PostinstScriptTemplate": c.Backend.PostinstScriptTemplate, - "Backend.ServiceAdditionalParamsTemplate": c.Backend.ServiceAdditionalParamsTemplate, - "Blockbook.InternalBindingTemplate": c.Blockbook.InternalBindingTemplate, - "Blockbook.PublicBindingTemplate": c.Blockbook.PublicBindingTemplate, - } - - funcMap := template.FuncMap{ - "jsonToString": jsonToString, - } - - t := template.New("").Funcs(funcMap) - - for name, def := range templates { - t = template.Must(t.Parse(fmt.Sprintf(`{{define "%s"}}%s{{end}}`, name, def))) - } - - return t -} - func main() { if len(os.Args) < 2 { var coins []string @@ -136,171 +29,12 @@ func main() { } coin := os.Args[1] - config := loadConfig(coin) - generatePackageDefinitions(config) + config, err := build.LoadConfig(configsDir, coin) + if err == nil { + err = build.GeneratePackageDefinitions(config, templateDir, outputDir) + } + if err != nil { + panic(err) + } fmt.Printf("Package files for %v generated to %v\n", coin, outputDir) } - -func loadConfig(coin string) *Config { - config := new(Config) - - f, err := os.Open(filepath.Join(configsDir, "coins", coin+".json")) - if err != nil { - panic(err) - } - d := json.NewDecoder(f) - err = d.Decode(config) - if err != nil { - panic(err) - } - - f, err = os.Open(filepath.Join(configsDir, "environ.json")) - if err != nil { - panic(err) - } - d = json.NewDecoder(f) - err = d.Decode(&config.Env) - if err != nil { - panic(err) - } - - config.Meta.BuildDatetime = time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700") - - if !isEmpty(config, "backend") { - switch config.Backend.ServiceType { - case "forking": - case "simple": - default: - panic("Invalid service type: " + config.Backend.ServiceType) - } - - switch config.Backend.VerificationType { - case "": - case "gpg": - case "sha256": - case "gpg-sha256": - default: - panic("Invalid verification type: " + config.Backend.VerificationType) - } - } - - return config -} - -func isEmpty(config *Config, target string) bool { - switch target { - case "backend": - return config.Backend.PackageName == "" - case "blockbook": - return config.Blockbook.PackageName == "" - default: - panic("Invalid target name: " + target) - } -} - -func generatePackageDefinitions(config *Config) { - templ := config.ParseTemplate() - - makeOutputDir(outputDir) - - for _, subdir := range []string{"backend", "blockbook"} { - if isEmpty(config, subdir) { - continue - } - - root := filepath.Join(inputDir, subdir) - - err := os.Mkdir(filepath.Join(outputDir, subdir), 0755) - if err != nil { - panic(err) - } - - err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { - if err != nil { - return fmt.Errorf("%s: %s", path, err) - } - - if path == root { - return nil - } - if filepath.Base(path)[0] == '.' { - return nil - } - - subpath := path[len(root)-len(subdir):] - - if info.IsDir() { - err = os.Mkdir(filepath.Join(outputDir, subpath), info.Mode()) - if err != nil { - return fmt.Errorf("%s: %s", path, err) - } - return nil - } - - t := template.Must(templ.Clone()) - t = template.Must(t.ParseFiles(path)) - - err = writeTemplate(filepath.Join(outputDir, subpath), info, t, config) - if err != nil { - return fmt.Errorf("%s: %s", path, err) - } - - return nil - }) - if err != nil { - panic(err) - } - } - - if !isEmpty(config, "backend") { - writeBackendConfigFile(config) - } -} - -func makeOutputDir(path string) { - err := os.RemoveAll(path) - if err == nil { - err = os.Mkdir(path, 0755) - } - if err != nil { - panic(err) - } -} - -func writeTemplate(path string, info os.FileInfo, templ *template.Template, config *Config) error { - f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode()) - if err != nil { - return err - } - defer f.Close() - - err = templ.ExecuteTemplate(f, "main", config) - if err != nil { - return err - } - - return nil -} - -func writeBackendConfigFile(config *Config) { - out, err := os.OpenFile(filepath.Join(outputDir, "backend/backend.conf"), os.O_CREATE|os.O_WRONLY, 0644) - if err != nil { - panic(err) - } - defer out.Close() - - if config.Backend.ConfigFile == "" { - return - } else { - in, err := os.Open(filepath.Join(outputDir, "backend/config", config.Backend.ConfigFile)) - if err != nil { - panic(err) - } - defer in.Close() - - _, err = io.Copy(out, in) - if err != nil { - panic(err) - } - } -} diff --git a/build/tools/templates.go b/build/tools/templates.go new file mode 100644 index 00000000..c2e34157 --- /dev/null +++ b/build/tools/templates.go @@ -0,0 +1,288 @@ +package build + +import ( + "encoding/json" + "fmt" + "io" + "os" + "path/filepath" + "text/template" + "time" +) + +type Config struct { + Meta struct { + BuildDatetime string // generated field + PackageMaintainer string `json:"package_maintainer"` + PackageMaintainerEmail string `json:"package_maintainer_email"` + } + Env struct { + Version string `json:"version"` + BackendInstallPath string `json:"backend_install_path"` + BackendDataPath string `json:"backend_data_path"` + BlockbookInstallPath string `json:"blockbook_install_path"` + BlockbookDataPath string `json:"blockbook_data_path"` + } `json:"env"` + Coin struct { + Name string `json:"name"` + Shortcut string `json:"shortcut"` + Label string `json:"label"` + Alias string `json:"alias"` + } `json:"coin"` + Ports struct { + BackendRPC int `json:"backend_rpc"` + BackendMessageQueue int `json:"backend_message_queue"` + BlockbookInternal int `json:"blockbook_internal"` + BlockbookPublic int `json:"blockbook_public"` + } `json:"ports"` + IPC struct { + RPCURLTemplate string `json:"rpc_url_template"` + RPCUser string `json:"rpc_user"` + RPCPass string `json:"rpc_pass"` + RPCTimeout int `json:"rpc_timeout"` + MessageQueueBindingTemplate string `json:"message_queue_binding_template"` + } `json:"ipc"` + Backend struct { + PackageName string `json:"package_name"` + PackageRevision string `json:"package_revision"` + SystemUser string `json:"system_user"` + Version string `json:"version"` + BinaryURL string `json:"binary_url"` + VerificationType string `json:"verification_type"` + VerificationSource string `json:"verification_source"` + ExtractCommand string `json:"extract_command"` + ExcludeFiles []string `json:"exclude_files"` + ExecCommandTemplate string `json:"exec_command_template"` + LogrotateFilesTemplate string `json:"logrotate_files_template"` + PostinstScriptTemplate string `json:"postinst_script_template"` + ServiceType string `json:"service_type"` + ServiceAdditionalParamsTemplate string `json:"service_additional_params_template"` + ProtectMemory bool `json:"protect_memory"` + Mainnet bool `json:"mainnet"` + ConfigFile string `json:"config_file"` + AdditionalParams interface{} `json:"additional_params"` + } `json:"backend"` + Blockbook struct { + PackageName string `json:"package_name"` + SystemUser string `json:"system_user"` + InternalBindingTemplate string `json:"internal_binding_template"` + PublicBindingTemplate string `json:"public_binding_template"` + ExplorerURL string `json:"explorer_url"` + AdditionalParams string `json:"additional_params"` + BlockChain struct { + Parse bool `json:"parse"` + Subversion string `json:"subversion"` + AddressFormat string `json:"address_format"` + MempoolWorkers int `json:"mempool_workers"` + MempoolSubWorkers int `json:"mempool_sub_workers"` + BlockAddressesToKeep int `json:"block_addresses_to_keep"` + AdditionalParams map[string]json.RawMessage `json:"additional_params"` + } `json:"block_chain"` + } `json:"blockbook"` + IntegrationTests map[string][]string `json:"integration_tests"` +} + +func jsonToString(msg json.RawMessage) (string, error) { + d, err := msg.MarshalJSON() + if err != nil { + return "", err + } + return string(d), nil +} + +func (c *Config) ParseTemplate() *template.Template { + templates := map[string]string{ + "IPC.RPCURLTemplate": c.IPC.RPCURLTemplate, + "IPC.MessageQueueBindingTemplate": c.IPC.MessageQueueBindingTemplate, + "Backend.ExecCommandTemplate": c.Backend.ExecCommandTemplate, + "Backend.LogrotateFilesTemplate": c.Backend.LogrotateFilesTemplate, + "Backend.PostinstScriptTemplate": c.Backend.PostinstScriptTemplate, + "Backend.ServiceAdditionalParamsTemplate": c.Backend.ServiceAdditionalParamsTemplate, + "Blockbook.InternalBindingTemplate": c.Blockbook.InternalBindingTemplate, + "Blockbook.PublicBindingTemplate": c.Blockbook.PublicBindingTemplate, + } + + funcMap := template.FuncMap{ + "jsonToString": jsonToString, + } + + t := template.New("").Funcs(funcMap) + + for name, def := range templates { + t = template.Must(t.Parse(fmt.Sprintf(`{{define "%s"}}%s{{end}}`, name, def))) + } + + return t +} + +func LoadConfig(configsDir, coin string) (*Config, error) { + config := new(Config) + + f, err := os.Open(filepath.Join(configsDir, "coins", coin+".json")) + if err != nil { + return nil, err + } + d := json.NewDecoder(f) + err = d.Decode(config) + if err != nil { + return nil, err + } + + f, err = os.Open(filepath.Join(configsDir, "environ.json")) + if err != nil { + return nil, err + } + d = json.NewDecoder(f) + err = d.Decode(&config.Env) + if err != nil { + return nil, err + } + + config.Meta.BuildDatetime = time.Now().Format("Mon, 02 Jan 2006 15:04:05 -0700") + + if !isEmpty(config, "backend") { + switch config.Backend.ServiceType { + case "forking": + case "simple": + default: + return nil, fmt.Errorf("Invalid service type: %s", config.Backend.ServiceType) + } + + switch config.Backend.VerificationType { + case "": + case "gpg": + case "sha256": + case "gpg-sha256": + default: + return nil, fmt.Errorf("Invalid verification type: %s", config.Backend.VerificationType) + } + } + + return config, nil +} + +func isEmpty(config *Config, target string) bool { + switch target { + case "backend": + return config.Backend.PackageName == "" + case "blockbook": + return config.Blockbook.PackageName == "" + default: + panic("Invalid target name: " + target) + } +} + +func GeneratePackageDefinitions(config *Config, templateDir, outputDir string) error { + templ := config.ParseTemplate() + + err := makeOutputDir(outputDir) + if err != nil { + return err + } + + for _, subdir := range []string{"backend", "blockbook"} { + if isEmpty(config, subdir) { + continue + } + + root := filepath.Join(templateDir, subdir) + + err = os.Mkdir(filepath.Join(outputDir, subdir), 0755) + if err != nil { + return err + } + + err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error { + if err != nil { + return fmt.Errorf("%s: %s", path, err) + } + + if path == root { + return nil + } + if filepath.Base(path)[0] == '.' { + return nil + } + + subpath := path[len(root)-len(subdir):] + + if info.IsDir() { + err = os.Mkdir(filepath.Join(outputDir, subpath), info.Mode()) + if err != nil { + return fmt.Errorf("%s: %s", path, err) + } + return nil + } + + t := template.Must(templ.Clone()) + t = template.Must(t.ParseFiles(path)) + + err = writeTemplate(filepath.Join(outputDir, subpath), info, t, config) + if err != nil { + return fmt.Errorf("%s: %s", path, err) + } + + return nil + }) + if err != nil { + return err + } + } + + if !isEmpty(config, "backend") { + err = writeBackendConfigFile(config, outputDir) + if err != nil { + return err + } + } + + return nil +} + +func makeOutputDir(path string) error { + err := os.RemoveAll(path) + if err == nil { + err = os.Mkdir(path, 0755) + } + return err +} + +func writeTemplate(path string, info os.FileInfo, templ *template.Template, config *Config) error { + f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, info.Mode()) + if err != nil { + return err + } + defer f.Close() + + err = templ.ExecuteTemplate(f, "main", config) + if err != nil { + return err + } + + return nil +} + +func writeBackendConfigFile(config *Config, outputDir string) error { + out, err := os.OpenFile(filepath.Join(outputDir, "backend/backend.conf"), os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return err + } + defer out.Close() + + if config.Backend.ConfigFile == "" { + return nil + } else { + in, err := os.Open(filepath.Join(outputDir, "backend/config", config.Backend.ConfigFile)) + if err != nil { + return err + } + defer in.Close() + + _, err = io.Copy(out, in) + if err != nil { + return err + } + } + + return nil +} diff --git a/configs/coins/bcash.json b/configs/coins/bcash.json index 78c74336..69035ab0 100644 --- a/configs/coins/bcash.json +++ b/configs/coins/bcash.json @@ -59,5 +59,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/bcash_testnet.json b/configs/coins/bcash_testnet.json index af58f66a..33427f04 100644 --- a/configs/coins/bcash_testnet.json +++ b/configs/coins/bcash_testnet.json @@ -59,5 +59,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/bitcoin.json b/configs/coins/bitcoin.json index ec93e446..76ee0ead 100644 --- a/configs/coins/bitcoin.json +++ b/configs/coins/bitcoin.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/bitcoin_testnet.json b/configs/coins/bitcoin_testnet.json index 760163be..7d76c723 100644 --- a/configs/coins/bitcoin_testnet.json +++ b/configs/coins/bitcoin_testnet.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/dash.json b/configs/coins/dash.json index d2895671..9da990c2 100644 --- a/configs/coins/dash.json +++ b/configs/coins/dash.json @@ -61,5 +61,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/dash_testnet.json b/configs/coins/dash_testnet.json index 38407e37..da73d850 100644 --- a/configs/coins/dash_testnet.json +++ b/configs/coins/dash_testnet.json @@ -61,5 +61,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/dogecoin.json b/configs/coins/dogecoin.json index cb9b7a68..a04bda04 100644 --- a/configs/coins/dogecoin.json +++ b/configs/coins/dogecoin.json @@ -63,5 +63,8 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync"] } } diff --git a/configs/coins/ethereum_testnet_ropsten.json b/configs/coins/ethereum_testnet_ropsten.json index a236e16d..6d567f80 100644 --- a/configs/coins/ethereum_testnet_ropsten.json +++ b/configs/coins/ethereum_testnet_ropsten.json @@ -53,5 +53,8 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/litecoin.json b/configs/coins/litecoin.json index e4541bf9..8bd0e15e 100644 --- a/configs/coins/litecoin.json +++ b/configs/coins/litecoin.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee"] } } diff --git a/configs/coins/monacoin.json b/configs/coins/monacoin.json index 563b1db6..1a1040a7 100644 --- a/configs/coins/monacoin.json +++ b/configs/coins/monacoin.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "wakiyamap", "package_maintainer_email": "wakiyamap@gmail.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee"] } } diff --git a/configs/coins/namecoin.json b/configs/coins/namecoin.json index 754ee628..5514625d 100644 --- a/configs/coins/namecoin.json +++ b/configs/coins/namecoin.json @@ -67,5 +67,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/vertcoin.json b/configs/coins/vertcoin.json index d68a0a0f..5669577a 100644 --- a/configs/coins/vertcoin.json +++ b/configs/coins/vertcoin.json @@ -58,5 +58,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/zcash.json b/configs/coins/zcash.json index ab65b246..539029ac 100644 --- a/configs/coins/zcash.json +++ b/configs/coins/zcash.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } diff --git a/configs/coins/zcash_testnet.json b/configs/coins/zcash_testnet.json index c2793c96..c34270ea 100644 --- a/configs/coins/zcash_testnet.json +++ b/configs/coins/zcash_testnet.json @@ -60,5 +60,9 @@ "meta": { "package_maintainer": "Jakub Matys", "package_maintainer_email": "jakub.matys@satoshilabs.com" + }, + "integration_tests": { + "rpc": ["GetBlock", "GetBlockHash", "GetTransaction", "GetTransactionForMempool", "MempoolSync", "EstimateSmartFee", + "EstimateFee", "GetBestBlockHash", "GetBestBlockHeight", "GetBlockHeader"] } } From f6fffefec941951932f693b6adeae892b12d5739 Mon Sep 17 00:00:00 2001 From: Jakub Matys Date: Wed, 12 Sep 2018 10:29:16 +0200 Subject: [PATCH 2/2] Tests fixed --- bchain/tests/rpc/rpc_test.go | 14 +++++++++++--- configs/coins/bcash_testnet.json | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/bchain/tests/rpc/rpc_test.go b/bchain/tests/rpc/rpc_test.go index 8c9f91b5..b5658846 100644 --- a/bchain/tests/rpc/rpc_test.go +++ b/bchain/tests/rpc/rpc_test.go @@ -98,7 +98,7 @@ func TestRPCIntegration(t *testing.T) { } if len(skippedTests) > 0 { - t.Errorf("Too many skipped tests: %q", skippedTests) + t.Errorf("Too many skipped tests due to connection issues: %q", skippedTests) } } @@ -442,12 +442,16 @@ func getMempoolAddresses(t *testing.T, h *TestHandler, txs []string) map[string] addrs := []string{} for _, vin := range tx.Vin { for _, a := range vin.Addresses { - addrs = append(addrs, a) + if isSearchableAddr(a) { + addrs = append(addrs, a) + } } } for _, vout := range tx.Vout { for _, a := range vout.ScriptPubKey.Addresses { - addrs = append(addrs, a) + if isSearchableAddr(a) { + addrs = append(addrs, a) + } } } if len(addrs) > 0 { @@ -457,6 +461,10 @@ func getMempoolAddresses(t *testing.T, h *TestHandler, txs []string) map[string] return txid2addrs } +func isSearchableAddr(addr string) bool { + return len(addr) > 3 && addr[:3] != "OP_" +} + func intersect(a, b []string) []string { setA := mapset.NewSet() for _, v := range a { diff --git a/configs/coins/bcash_testnet.json b/configs/coins/bcash_testnet.json index 33427f04..462430ea 100644 --- a/configs/coins/bcash_testnet.json +++ b/configs/coins/bcash_testnet.json @@ -49,7 +49,7 @@ "block_chain": { "parse": true, "subversion": "/Bitcoin ABC:0.17.1/", - "address_format": "legacy", + "address_format": "cashaddr", "mempool_workers": 8, "mempool_sub_workers": 2, "block_addresses_to_keep": 300,