Add integration test

* Update Travis to run integration tests
This commit is contained in:
Matt Krump 2017-10-24 09:24:07 -05:00 committed by Eric Meyer
parent 51ab23dd3a
commit 571bc7f63a
12 changed files with 105 additions and 10 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
.idea .idea
test_data_dir/

View File

@ -0,0 +1 @@
1234

View File

@ -1,3 +1,5 @@
language: go language: go
go: go:
- 1.9 - 1.9
script:
- go test -v ./core/...

View File

@ -10,4 +10,15 @@ By default, `go get` does not work for private GitHub repos. This will fix that.
## Running the Tests ## Running the Tests
`go test ./...` ### Integration Test
In order to run the integration tests, you will need to run them against a real blockchain. Here are steps to create a local, private blockchain.
1. Run `./scripts/setup` to create a private blockchain with a new account.
* This will result in a warning.
2. Run `./scripts/start_private_blockchain` as a separate process.
3. `go test ./...`
### Unit Tests
`go test ./core`

View File

@ -46,8 +46,8 @@ var _ = Describe("The fake blockchain", func() {
blockchain.AddBlock(core.Block{Number: big.NewInt(123)}) blockchain.AddBlock(core.Block{Number: big.NewInt(123)})
Expect(blockchainObserver.LastAddedBlock.Number).ShouldNot(BeNil()) Expect(blockchainObserver.LastAddedBlock().Number).ShouldNot(BeNil())
Expect(blockchainObserver.LastAddedBlock.Number).Should(Equal(big.NewInt(123))) Expect(blockchainObserver.LastAddedBlock().Number).Should(Equal(big.NewInt(123)))
}) })
}) })

View File

@ -2,6 +2,7 @@ package core
import ( import (
"fmt" "fmt"
"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/ethclient"
"golang.org/x/net/context" "golang.org/x/net/context"
@ -9,8 +10,9 @@ import (
) )
type GethBlockchain struct { type GethBlockchain struct {
client *ethclient.Client client *ethclient.Client
observers []BlockchainObserver observers []BlockchainObserver
subscription ethereum.Subscription
} }
func NewGethBlockchain(ipcPath string) *GethBlockchain { func NewGethBlockchain(ipcPath string) *GethBlockchain {
@ -21,12 +23,14 @@ func NewGethBlockchain(ipcPath string) *GethBlockchain {
blockchain.client = client blockchain.client = client
return &blockchain return &blockchain
} }
func (blockchain GethBlockchain) notifyObservers(getBlock *types.Block) { func (blockchain GethBlockchain) notifyObservers(getBlock *types.Block) {
block := convertBlock(getBlock) block := convertBlock(getBlock)
for _, observer := range blockchain.observers { for _, observer := range blockchain.observers {
observer.NotifyBlockAdded(block) observer.NotifyBlockAdded(block)
} }
} }
func convertBlock(gethBlock *types.Block) Block { func convertBlock(gethBlock *types.Block) Block {
return Block{ return Block{
Number: gethBlock.Number(), Number: gethBlock.Number(),
@ -42,7 +46,8 @@ func (blockchain *GethBlockchain) RegisterObserver(observer BlockchainObserver)
func (blockchain *GethBlockchain) SubscribeToEvents() { func (blockchain *GethBlockchain) SubscribeToEvents() {
headers := make(chan *types.Header, 10) headers := make(chan *types.Header, 10)
myContext := context.Background() myContext := context.Background()
blockchain.client.SubscribeNewHead(myContext, headers) sub, _ := blockchain.client.SubscribeNewHead(myContext, headers)
blockchain.subscription = sub
for header := range headers { for header := range headers {
gethBlock, _ := blockchain.client.BlockByNumber(myContext, header.Number) gethBlock, _ := blockchain.client.BlockByNumber(myContext, header.Number)
blockchain.notifyObservers(gethBlock) blockchain.notifyObservers(gethBlock)

View File

@ -18,5 +18,4 @@ func (blockchain *Blockchain) AddBlock(block core.Block) {
} }
} }
func (_ *Blockchain) SubscribeToEvents() { func (_ *Blockchain) SubscribeToEvents() {}
}

View File

@ -6,7 +6,7 @@ import (
type BlockchainObserver struct { type BlockchainObserver struct {
wasToldBlockAdded bool wasToldBlockAdded bool
LastAddedBlock core.Block blocks []core.Block
} }
func (blockchainObserver *BlockchainObserver) WasToldBlockAdded() bool { func (blockchainObserver *BlockchainObserver) WasToldBlockAdded() bool {
@ -14,6 +14,10 @@ func (blockchainObserver *BlockchainObserver) WasToldBlockAdded() bool {
} }
func (blockchainObserver *BlockchainObserver) NotifyBlockAdded(block core.Block) { func (blockchainObserver *BlockchainObserver) NotifyBlockAdded(block core.Block) {
blockchainObserver.LastAddedBlock = block blockchainObserver.blocks = append(blockchainObserver.blocks, block)
blockchainObserver.wasToldBlockAdded = true blockchainObserver.wasToldBlockAdded = true
} }
func (observer *BlockchainObserver) LastAddedBlock() core.Block {
return observer.blocks[len(observer.blocks)-1]
}

View File

@ -0,0 +1,51 @@
package integration_test
import (
"fmt"
"github.com/8thlight/vulcanizedb/core"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"math/big"
"path"
"path/filepath"
"runtime"
)
var (
_, filename, _, _ = runtime.Caller(0)
basepath = filepath.Dir(filename)
)
func RunTimePath() string {
return path.Join(path.Dir(filename), "../")
}
type ObserverWithChannel struct {
blocks chan core.Block
}
func (observer *ObserverWithChannel) NotifyBlockAdded(block core.Block) {
fmt.Println("Block: ", block.Number)
observer.blocks <- block
}
var _ = Describe("Reading from the Geth blockchain", func() {
It("reads two blocks with incrementing numbers", func(done Done) {
addedBlock := make(chan core.Block, 10)
observer := &ObserverWithChannel{addedBlock}
var blockchain core.Blockchain = core.NewGethBlockchain(RunTimePath() + "/test_data_dir/geth.ipc")
blockchain.RegisterObserver(observer)
go blockchain.SubscribeToEvents()
firstBlock := <-addedBlock
Expect(firstBlock).ShouldNot(BeNil())
secondBlock := <-addedBlock
Expect(firstBlock.Number.Add(firstBlock.Number, big.NewInt(1))).Should(Equal(secondBlock.Number))
close(done)
}, 30)
})

View File

@ -0,0 +1,13 @@
package integration_test
import (
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"testing"
)
func TestIntegrationTest(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "IntegrationTest Suite")
}

6
scripts/setup Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
echo "Deleting test blockchain"
rm -rf test_data_dir
echo "Creating test blockchain with a new account"
mkdir test_data_dir
geth --datadir test_data_dir --password .private_blockchain_password account new

View File

@ -0,0 +1,2 @@
#!/bin/bash
geth --datadir test_data_dir --dev --nodiscover --mine --minerthreads 1 --maxpeers 0 --verbosity 3 --unlock 0 --password .private_blockchain_password --rpc