2018-06-06 02:38:16 +00:00
|
|
|
package p2p
|
|
|
|
|
2018-07-17 18:39:04 +00:00
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io/ioutil"
|
|
|
|
"reflect"
|
2018-07-25 16:11:15 +00:00
|
|
|
"sync"
|
2018-07-17 18:39:04 +00:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/ethereum/go-ethereum/event"
|
|
|
|
"github.com/golang/protobuf/proto"
|
2018-07-24 15:21:58 +00:00
|
|
|
"github.com/prysmaticlabs/prysm/shared"
|
2018-07-17 18:39:04 +00:00
|
|
|
|
|
|
|
floodsub "github.com/libp2p/go-floodsub"
|
|
|
|
swarmt "github.com/libp2p/go-libp2p-swarm/testing"
|
|
|
|
bhost "github.com/libp2p/go-libp2p/p2p/host/basic"
|
2018-07-31 18:54:45 +00:00
|
|
|
shardpb "github.com/prysmaticlabs/prysm/proto/sharding/p2p/v1"
|
2018-07-21 17:51:18 +00:00
|
|
|
"github.com/sirupsen/logrus"
|
2018-07-17 18:39:04 +00:00
|
|
|
)
|
2018-06-06 02:38:16 +00:00
|
|
|
|
2018-06-13 12:44:33 +00:00
|
|
|
// Ensure that server implements service.
|
2018-07-24 15:21:58 +00:00
|
|
|
var _ = shared.Service(&Server{})
|
2018-07-17 18:39:04 +00:00
|
|
|
|
|
|
|
func init() {
|
2018-07-21 17:51:18 +00:00
|
|
|
logrus.SetLevel(logrus.DebugLevel)
|
|
|
|
logrus.SetOutput(ioutil.Discard)
|
2018-07-17 18:39:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestBroadcast(t *testing.T) {
|
|
|
|
s, err := NewServer()
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Could not start a new server: %v", err)
|
|
|
|
}
|
|
|
|
|
2018-07-31 18:54:45 +00:00
|
|
|
msg := &shardpb.CollationBodyRequest{}
|
2018-07-17 18:39:04 +00:00
|
|
|
s.Broadcast(msg)
|
|
|
|
|
|
|
|
// TODO: test that topic was published
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSubscribeToTopic(t *testing.T) {
|
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
h := bhost.New(swarmt.GenSwarm(t, ctx))
|
|
|
|
|
|
|
|
gsub, err := floodsub.NewFloodSub(ctx, h)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Failed to create floodsub: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s := Server{
|
|
|
|
ctx: ctx,
|
|
|
|
gsub: gsub,
|
|
|
|
host: h,
|
|
|
|
feeds: make(map[reflect.Type]*event.Feed),
|
2018-07-25 16:11:15 +00:00
|
|
|
mutex: &sync.Mutex{},
|
2018-07-17 18:39:04 +00:00
|
|
|
}
|
|
|
|
|
2018-07-31 18:54:45 +00:00
|
|
|
feed := s.Feed(shardpb.CollationBodyRequest{})
|
2018-07-17 18:39:04 +00:00
|
|
|
ch := make(chan Message)
|
|
|
|
sub := feed.Subscribe(ch)
|
|
|
|
defer sub.Unsubscribe()
|
|
|
|
|
2018-07-29 01:18:56 +00:00
|
|
|
testSubscribe(ctx, t, s, gsub, ch)
|
2018-07-26 14:16:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestSubscribe(t *testing.T) {
|
|
|
|
ctx, cancel := context.WithTimeout(context.TODO(), 1*time.Second)
|
|
|
|
defer cancel()
|
|
|
|
h := bhost.New(swarmt.GenSwarm(t, ctx))
|
|
|
|
|
|
|
|
gsub, err := floodsub.NewFloodSub(ctx, h)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Failed to create floodsub: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
s := Server{
|
|
|
|
ctx: ctx,
|
|
|
|
gsub: gsub,
|
|
|
|
host: h,
|
|
|
|
feeds: make(map[reflect.Type]*event.Feed),
|
|
|
|
mutex: &sync.Mutex{},
|
|
|
|
}
|
|
|
|
|
|
|
|
ch := make(chan Message)
|
2018-07-31 18:54:45 +00:00
|
|
|
sub := s.Subscribe(shardpb.CollationBodyRequest{}, ch)
|
2018-07-26 14:16:31 +00:00
|
|
|
defer sub.Unsubscribe()
|
|
|
|
|
2018-07-29 01:18:56 +00:00
|
|
|
testSubscribe(ctx, t, s, gsub, ch)
|
2018-07-26 14:16:31 +00:00
|
|
|
}
|
|
|
|
|
2018-07-29 01:18:56 +00:00
|
|
|
func testSubscribe(ctx context.Context, t *testing.T, s Server, gsub *floodsub.PubSub, ch chan Message) {
|
2018-07-31 18:54:45 +00:00
|
|
|
topic := shardpb.Topic_COLLATION_BODY_REQUEST
|
2018-07-17 18:39:04 +00:00
|
|
|
msgType := topicTypeMapping[topic]
|
|
|
|
go s.subscribeToTopic(topic, msgType)
|
|
|
|
|
|
|
|
// Short delay to let goroutine add subscription.
|
|
|
|
time.Sleep(time.Millisecond * 10)
|
|
|
|
|
|
|
|
// The topic should be subscribed with gsub.
|
|
|
|
topics := gsub.GetTopics()
|
|
|
|
if len(topics) < 1 || topics[0] != topic.String() {
|
|
|
|
t.Errorf("Unexpected subscribed topics: %v. Wanted %s", topics, topic)
|
|
|
|
}
|
|
|
|
|
2018-07-31 18:54:45 +00:00
|
|
|
pbMsg := &shardpb.CollationBodyRequest{ShardId: 5}
|
2018-07-17 18:39:04 +00:00
|
|
|
|
|
|
|
done := make(chan bool)
|
|
|
|
go func() {
|
|
|
|
// The message should be received from the feed.
|
|
|
|
msg := <-ch
|
|
|
|
if !proto.Equal(msg.Data.(proto.Message), pbMsg) {
|
|
|
|
t.Errorf("Unexpected msg: %+v. Wanted %+v.", msg.Data, pbMsg)
|
|
|
|
}
|
|
|
|
|
|
|
|
done <- true
|
|
|
|
}()
|
|
|
|
|
|
|
|
b, err := proto.Marshal(pbMsg)
|
|
|
|
if err != nil {
|
2018-07-28 19:53:02 +00:00
|
|
|
t.Errorf("Failed to marshal service %v", err)
|
2018-07-17 18:39:04 +00:00
|
|
|
}
|
|
|
|
if err = gsub.Publish(topic.String(), b); err != nil {
|
|
|
|
t.Errorf("Failed to publish message: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Wait for our message assertion to complete.
|
|
|
|
select {
|
|
|
|
case <-done:
|
|
|
|
case <-ctx.Done():
|
|
|
|
t.Error("Context timed out before a message was received!")
|
|
|
|
}
|
|
|
|
}
|