github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/gossip/election/adapter_test.go (about)

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