prysm-pulse/beacon-chain/simulator/service_test.go

143 lines
3.2 KiB
Go

package simulator
import (
"context"
"io/ioutil"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/golang/protobuf/proto"
"github.com/prysmaticlabs/prysm/beacon-chain/db"
"github.com/prysmaticlabs/prysm/beacon-chain/internal"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/event"
"github.com/prysmaticlabs/prysm/shared/p2p"
"github.com/prysmaticlabs/prysm/shared/testutil"
"github.com/sirupsen/logrus"
logTest "github.com/sirupsen/logrus/hooks/test"
)
func init() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(ioutil.Discard)
}
type mockP2P struct {
broadcastHash []byte
}
func (mp *mockP2P) Subscribe(msg proto.Message, channel chan p2p.Message) event.Subscription {
return new(event.Feed).Subscribe(channel)
}
func (mp *mockP2P) Broadcast(msg proto.Message) {
mp.broadcastHash = msg.(*pb.BeaconBlockHashAnnounce).GetHash()
}
func (mp *mockP2P) Send(msg proto.Message, peer p2p.Peer) {}
type mockPOWChainService struct{}
func (mpow *mockPOWChainService) LatestBlockHash() common.Hash {
return common.BytesToHash([]byte{})
}
func setupSimulator(t *testing.T, beaconDB *db.BeaconDB) (*Simulator, *mockP2P) {
ctx := context.Background()
p2pService := &mockP2P{}
err := beaconDB.InitializeState(nil)
if err != nil {
t.Fatalf("Failed to initialize state: %v", err)
}
cfg := &Config{
BlockRequestBuf: 0,
P2P: p2pService,
Web3Service: &mockPOWChainService{},
BeaconDB: beaconDB,
EnablePOWChain: true,
}
return NewSimulator(ctx, cfg), p2pService
}
func TestLifecycle(t *testing.T) {
hook := logTest.NewGlobal()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
sim, _ := setupSimulator(t, db)
sim.Start()
testutil.AssertLogsContain(t, hook, "Starting service")
sim.Stop()
testutil.AssertLogsContain(t, hook, "Stopping service")
// The context should have been canceled.
if sim.ctx.Err() == nil {
t.Error("context was not canceled")
}
}
func TestBroadcastBlockHash(t *testing.T) {
hook := logTest.NewGlobal()
db := internal.SetupDB(t)
defer internal.TeardownDB(t, db)
sim, p2pService := setupSimulator(t, db)
slotChan := make(chan uint64)
requestChan := make(chan p2p.Message)
exitRoutine := make(chan bool)
go func() {
sim.run(slotChan, requestChan)
<-exitRoutine
}()
// trigger a new block
slotChan <- 1
// test an invalid block request
requestChan <- p2p.Message{
Data: &pb.BeaconBlockRequest{
Hash: make([]byte, 32),
},
}
// test a valid block request
blockHash := p2pService.broadcastHash
requestChan <- p2p.Message{
Data: &pb.BeaconBlockRequest{
Hash: blockHash,
},
}
// trigger another block
slotChan <- 2
testutil.AssertLogsContain(t, hook, "Broadcast block hash")
testutil.AssertLogsContain(t, hook, "Requested block not found")
testutil.AssertLogsContain(t, hook, "Responding to full block request")
// reset logs
hook.Reset()
// ensure that another request for the same block can't be made
requestChan <- p2p.Message{
Data: &pb.BeaconBlockRequest{
Hash: blockHash,
},
}
sim.cancel()
exitRoutine <- true
testutil.AssertLogsContain(t, hook, "Requested block not found")
testutil.AssertLogsDoNotContain(t, hook, "Responding to full block request")
hook.Reset()
}