github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/gossip/election/adapter_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package election
     8  
     9  import (
    10  	"bytes"
    11  	"fmt"
    12  	"strings"
    13  	"sync"
    14  	"testing"
    15  	"time"
    16  
    17  	"github.com/hyperledger/fabric/gossip/common"
    18  	"github.com/hyperledger/fabric/gossip/discovery"
    19  	"github.com/hyperledger/fabric/gossip/util"
    20  	proto "github.com/hyperledger/fabric/protos/gossip"
    21  )
    22  
    23  func init() {
    24  	util.SetupTestLogging()
    25  }
    26  
    27  func TestNewAdapter(t *testing.T) {
    28  	selfNetworkMember := &discovery.NetworkMember{
    29  		Endpoint: "p0",
    30  		Metadata: []byte{},
    31  		PKIid:    []byte{byte(0)},
    32  	}
    33  	mockGossip := newGossip("peer0", selfNetworkMember)
    34  
    35  	peersCluster := newClusterOfPeers("0")
    36  	peersCluster.addPeer("peer0", mockGossip)
    37  
    38  	NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"))
    39  }
    40  
    41  func TestAdapterImpl_CreateMessage(t *testing.T) {
    42  	selfNetworkMember := &discovery.NetworkMember{
    43  		Endpoint: "p0",
    44  		Metadata: []byte{},
    45  		PKIid:    []byte{byte(0)},
    46  	}
    47  	mockGossip := newGossip("peer0", selfNetworkMember)
    48  
    49  	adapter := NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"))
    50  	msg := adapter.CreateMessage(true)
    51  
    52  	if !msg.(*msgImpl).msg.IsLeadershipMsg() {
    53  		t.Error("Newly created message should be LeadershipMsg")
    54  	}
    55  
    56  	if !msg.IsDeclaration() {
    57  		t.Error("Newly created msg should be Declaration msg")
    58  	}
    59  
    60  	msg = adapter.CreateMessage(false)
    61  
    62  	if !msg.(*msgImpl).msg.IsLeadershipMsg() {
    63  		t.Error("Newly created message should be LeadershipMsg")
    64  	}
    65  
    66  	if !msg.IsProposal() || msg.IsDeclaration() {
    67  		t.Error("Newly created msg should be Proposal msg")
    68  	}
    69  }
    70  
    71  func TestAdapterImpl_Peers(t *testing.T) {
    72  	_, adapters := createCluster(0, 1, 2, 3, 4, 5)
    73  
    74  	peersPKIDs := make(map[string]string)
    75  	peersPKIDs[string([]byte{0})] = string([]byte{0})
    76  	peersPKIDs[string([]byte{1})] = string([]byte{1})
    77  	peersPKIDs[string([]byte{2})] = string([]byte{2})
    78  	peersPKIDs[string([]byte{3})] = string([]byte{2})
    79  	peersPKIDs[string([]byte{4})] = string([]byte{4})
    80  	peersPKIDs[string([]byte{5})] = string([]byte{5})
    81  
    82  	for _, adapter := range adapters {
    83  		peers := adapter.Peers()
    84  		if len(peers) != 6 {
    85  			t.Errorf("Should return 6 peers, not %d", len(peers))
    86  		}
    87  
    88  		for _, peer := range peers {
    89  			if _, exist := peersPKIDs[string(peer.ID())]; !exist {
    90  				t.Errorf("Peer %s PKID not found", peer.(*peerImpl).member.Endpoint)
    91  			}
    92  		}
    93  	}
    94  
    95  }
    96  
    97  func TestAdapterImpl_Stop(t *testing.T) {
    98  	_, adapters := createCluster(0, 1, 2, 3, 4, 5)
    99  
   100  	for _, adapter := range adapters {
   101  		adapter.Accept()
   102  	}
   103  
   104  	for _, adapter := range adapters {
   105  		adapter.Stop()
   106  	}
   107  }
   108  
   109  func TestAdapterImpl_Gossip(t *testing.T) {
   110  	_, adapters := createCluster(0, 1, 2)
   111  
   112  	channels := make(map[string]<-chan Msg)
   113  
   114  	for peerID, adapter := range adapters {
   115  		channels[peerID] = adapter.Accept()
   116  	}
   117  
   118  	sender := adapters[fmt.Sprintf("Peer%d", 0)]
   119  
   120  	sender.Gossip(sender.CreateMessage(true))
   121  
   122  	totalMsg := 0
   123  
   124  	timer := time.After(time.Duration(1) * time.Second)
   125  
   126  	for {
   127  		select {
   128  		case <-timer:
   129  			if totalMsg != 2 {
   130  				t.Error("Not all messages accepted")
   131  				t.FailNow()
   132  			} else {
   133  				return
   134  			}
   135  		case msg := <-channels[fmt.Sprintf("Peer%d", 1)]:
   136  			if !msg.IsDeclaration() {
   137  				t.Error("Msg should be declaration")
   138  			} else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) {
   139  				t.Error("Msg Sender is wrong")
   140  			} else {
   141  				totalMsg++
   142  			}
   143  		case msg := <-channels[fmt.Sprintf("Peer%d", 2)]:
   144  			if !msg.IsDeclaration() {
   145  				t.Error("Msg should be declaration")
   146  			} else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) {
   147  				t.Error("Msg Sender is wrong")
   148  			} else {
   149  				totalMsg++
   150  			}
   151  		}
   152  
   153  	}
   154  
   155  }
   156  
   157  type mockAcceptor struct {
   158  	ch       chan *proto.GossipMessage
   159  	acceptor common.MessageAcceptor
   160  }
   161  
   162  type peerMockGossip struct {
   163  	cluster      *clusterOfPeers
   164  	member       *discovery.NetworkMember
   165  	acceptors    []*mockAcceptor
   166  	acceptorLock *sync.RWMutex
   167  	clusterLock  *sync.RWMutex
   168  	id           string
   169  }
   170  
   171  func (g *peerMockGossip) Peers() []discovery.NetworkMember {
   172  
   173  	g.clusterLock.RLock()
   174  	if g.cluster == nil {
   175  		return []discovery.NetworkMember{*g.member}
   176  	}
   177  	peerLock := g.cluster.peersLock
   178  	g.clusterLock.RUnlock()
   179  
   180  	peerLock.RLock()
   181  	res := make([]discovery.NetworkMember, 0)
   182  	g.clusterLock.RLock()
   183  	for _, val := range g.cluster.peersGossip {
   184  		res = append(res, *val.member)
   185  
   186  	}
   187  	g.clusterLock.RUnlock()
   188  	peerLock.RUnlock()
   189  	return res
   190  }
   191  
   192  func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage) {
   193  	ch := make(chan *proto.GossipMessage, 100)
   194  	g.acceptorLock.Lock()
   195  	g.acceptors = append(g.acceptors, &mockAcceptor{
   196  		ch:       ch,
   197  		acceptor: acceptor,
   198  	})
   199  	g.acceptorLock.Unlock()
   200  	return ch, nil
   201  }
   202  
   203  func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) {
   204  	g.clusterLock.RLock()
   205  	if g.cluster == nil {
   206  		return
   207  	}
   208  	peersLock := g.cluster.peersLock
   209  	g.clusterLock.RUnlock()
   210  
   211  	peersLock.RLock()
   212  	g.clusterLock.RLock()
   213  	for _, val := range g.cluster.peersGossip {
   214  		if strings.Compare(val.id, g.id) != 0 {
   215  			val.putToAcceptors(msg)
   216  		}
   217  	}
   218  	g.clusterLock.RUnlock()
   219  	peersLock.RUnlock()
   220  
   221  }
   222  
   223  func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) {
   224  	g.acceptorLock.RLock()
   225  	for _, acceptor := range g.acceptors {
   226  		if acceptor.acceptor(msg) {
   227  			if len(acceptor.ch) < 10 {
   228  				acceptor.ch <- msg
   229  			}
   230  		}
   231  	}
   232  	g.acceptorLock.RUnlock()
   233  
   234  }
   235  
   236  func newGossip(peerID string, member *discovery.NetworkMember) *peerMockGossip {
   237  	return &peerMockGossip{
   238  		id:           peerID,
   239  		member:       member,
   240  		acceptorLock: &sync.RWMutex{},
   241  		clusterLock:  &sync.RWMutex{},
   242  		acceptors:    make([]*mockAcceptor, 0),
   243  	}
   244  }
   245  
   246  type clusterOfPeers struct {
   247  	peersGossip map[string]*peerMockGossip
   248  	peersLock   *sync.RWMutex
   249  	id          string
   250  }
   251  
   252  func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) {
   253  	cop.peersLock.Lock()
   254  	cop.peersGossip[peerID] = gossip
   255  	gossip.clusterLock.Lock()
   256  	gossip.cluster = cop
   257  	gossip.clusterLock.Unlock()
   258  	cop.peersLock.Unlock()
   259  
   260  }
   261  
   262  func newClusterOfPeers(id string) *clusterOfPeers {
   263  	return &clusterOfPeers{
   264  		id:          id,
   265  		peersGossip: make(map[string]*peerMockGossip),
   266  		peersLock:   &sync.RWMutex{},
   267  	}
   268  
   269  }
   270  
   271  func createCluster(peers ...int) (*clusterOfPeers, map[string]*adapterImpl) {
   272  	adapters := make(map[string]*adapterImpl)
   273  	cluster := newClusterOfPeers("0")
   274  	for _, peer := range peers {
   275  		peerEndpoint := fmt.Sprintf("Peer%d", peer)
   276  		peerPKID := []byte{byte(peer)}
   277  		peerMember := &discovery.NetworkMember{
   278  			Metadata: []byte{},
   279  			Endpoint: peerEndpoint,
   280  			PKIid:    peerPKID,
   281  		}
   282  
   283  		mockGossip := newGossip(peerEndpoint, peerMember)
   284  		adapter := NewAdapter(mockGossip, peerMember.PKIid, []byte("channel0"))
   285  		adapters[peerEndpoint] = adapter.(*adapterImpl)
   286  		cluster.addPeer(peerEndpoint, mockGossip)
   287  	}
   288  
   289  	return cluster, adapters
   290  }