neo-go/pkg/core/blockchain_test.go
Vsevolod Brekelov 100fee164b unitTest: reworked RPC unit test
earlier we had an issue with failing test in #353 and other one #305.
Reworked these test to have in-memory database. This led to multiple
changes: made some functions like Hash and Persist public(otherwise
it's not possible to control state of the blockchain); removed
unit_tests storage package which was used mainly for leveldb in unit
tests.
I see these tests not really good since they look like e2e tests and
as for me should be run in separate step against dockerized env or
in case we want to check rpc handler we might want to rework it in order
to have interface for proper unit tests.
As for me this patchset at least makes as safe with not removing totally
previous tests and at the same time CircleCI will be happy now.
2019-09-18 18:21:16 +03:00

180 lines
4.1 KiB
Go

package core
import (
"context"
"testing"
"github.com/CityOfZion/neo-go/config"
"github.com/CityOfZion/neo-go/pkg/core/storage"
"github.com/CityOfZion/neo-go/pkg/io"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestAddHeaders(t *testing.T) {
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
h1 := newBlock(1).Header()
h2 := newBlock(2).Header()
h3 := newBlock(3).Header()
if err := bc.AddHeaders(h1, h2, h3); err != nil {
t.Fatal(err)
}
assert.Equal(t, 0, bc.blockCache.Len())
assert.Equal(t, h3.Index, bc.HeaderHeight())
assert.Equal(t, uint32(0), bc.BlockHeight())
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
// Add them again, they should not be added.
if err := bc.AddHeaders(h3, h2, h1); err != nil {
t.Fatal(err)
}
assert.Equal(t, h3.Index, bc.HeaderHeight())
assert.Equal(t, uint32(0), bc.BlockHeight())
assert.Equal(t, h3.Hash(), bc.CurrentHeaderHash())
}
func TestAddBlock(t *testing.T) {
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
blocks := []*Block{
newBlock(1),
newBlock(2),
newBlock(3),
}
for i := 0; i < len(blocks); i++ {
if err := bc.AddBlock(blocks[i]); err != nil {
t.Fatal(err)
}
}
lastBlock := blocks[len(blocks)-1]
assert.Equal(t, 3, bc.blockCache.Len())
assert.Equal(t, lastBlock.Index, bc.HeaderHeight())
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
t.Log(bc.blockCache)
if err := bc.Persist(context.Background()); err != nil {
t.Fatal(err)
}
for _, block := range blocks {
key := storage.AppendPrefix(storage.DataBlock, block.Hash().BytesReverse())
if _, err := bc.Get(key); err != nil {
t.Fatalf("block %s not persisted", block.Hash())
}
}
assert.Equal(t, lastBlock.Index, bc.BlockHeight())
assert.Equal(t, lastBlock.Hash(), bc.CurrentHeaderHash())
assert.Equal(t, 0, bc.blockCache.Len())
}
func TestGetHeader(t *testing.T) {
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
block := newBlock(1)
err := bc.AddBlock(block)
assert.Nil(t, err)
hash := block.Hash()
header, err := bc.GetHeader(hash)
require.NoError(t, err)
assert.Equal(t, block.Header(), header)
block = newBlock(2)
_, err = bc.GetHeader(block.Hash())
assert.Error(t, err)
}
func TestGetBlock(t *testing.T) {
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
blocks := makeBlocks(100)
for i := 0; i < len(blocks); i++ {
if err := bc.AddBlock(blocks[i]); err != nil {
t.Fatal(err)
}
}
for i := 0; i < len(blocks); i++ {
block, err := bc.GetBlock(blocks[i].Hash())
if err != nil {
t.Fatal(err)
}
assert.Equal(t, blocks[i].Index, block.Index)
assert.Equal(t, blocks[i].Hash(), block.Hash())
}
}
func TestHasBlock(t *testing.T) {
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
blocks := makeBlocks(50)
for i := 0; i < len(blocks); i++ {
if err := bc.AddBlock(blocks[i]); err != nil {
t.Fatal(err)
}
}
assert.Nil(t, bc.Persist(context.Background()))
for i := 0; i < len(blocks); i++ {
assert.True(t, bc.HasBlock(blocks[i].Hash()))
}
newBlock := newBlock(51)
assert.False(t, bc.HasBlock(newBlock.Hash()))
}
func TestGetTransaction(t *testing.T) {
block := getDecodedBlock(t, 2)
bc := newTestChain(t)
defer func() {
require.NoError(t, bc.Close())
}()
assert.Nil(t, bc.AddBlock(block))
assert.Nil(t, bc.persistBlock(block))
tx, height, err := bc.GetTransaction(block.Transactions[0].Hash())
if err != nil {
t.Fatal(err)
}
assert.Equal(t, block.Index, height)
assert.Equal(t, block.Transactions[0], tx)
assert.Equal(t, 10, io.GetVarSize(tx))
assert.Equal(t, 1, io.GetVarSize(tx.Attributes))
assert.Equal(t, 1, io.GetVarSize(tx.Inputs))
assert.Equal(t, 1, io.GetVarSize(tx.Outputs))
assert.Equal(t, 1, io.GetVarSize(tx.Scripts))
}
func newTestChain(t *testing.T) *Blockchain {
cfg, err := config.Load("../../config", config.ModeUnitTestNet)
if err != nil {
t.Fatal(err)
}
chain, err := NewBlockchain(storage.NewMemoryStore(), cfg.ProtocolConfiguration)
if err != nil {
t.Fatal(err)
}
go chain.Run(context.Background())
return chain
}