github.com/defanghe/fabric@v2.1.1+incompatible/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  	proto "github.com/hyperledger/fabric-protos-go/gossip"
    18  	"github.com/hyperledger/fabric/common/metrics/disabled"
    19  	"github.com/hyperledger/fabric/gossip/common"
    20  	"github.com/hyperledger/fabric/gossip/discovery"
    21  	"github.com/hyperledger/fabric/gossip/metrics"
    22  	"github.com/hyperledger/fabric/gossip/metrics/mocks"
    23  	"github.com/hyperledger/fabric/gossip/protoext"
    24  	"github.com/hyperledger/fabric/gossip/util"
    25  	"github.com/stretchr/testify/assert"
    26  )
    27  
    28  func init() {
    29  	util.SetupTestLogging()
    30  }
    31  
    32  func TestNewAdapter(t *testing.T) {
    33  	selfNetworkMember := &discovery.NetworkMember{
    34  		Endpoint: "p0",
    35  		Metadata: []byte{},
    36  		PKIid:    []byte{byte(0)},
    37  	}
    38  	mockGossip := newGossip("peer0", selfNetworkMember, nil)
    39  
    40  	peersCluster := newClusterOfPeers("0")
    41  	peersCluster.addPeer("peer0", mockGossip)
    42  
    43  	NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"),
    44  		metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics)
    45  }
    46  
    47  func TestAdapterImpl_CreateMessage(t *testing.T) {
    48  	selfNetworkMember := &discovery.NetworkMember{
    49  		Endpoint: "p0",
    50  		Metadata: []byte{},
    51  		PKIid:    []byte{byte(0)},
    52  	}
    53  	mockGossip := newGossip("peer0", selfNetworkMember, nil)
    54  
    55  	adapter := NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"),
    56  		metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics)
    57  	msg := adapter.CreateMessage(true)
    58  
    59  	if !protoext.IsLeadershipMsg(msg.(*msgImpl).msg) {
    60  		t.Error("Newly created message should be LeadershipMsg")
    61  	}
    62  
    63  	if !msg.IsDeclaration() {
    64  		t.Error("Newly created msg should be Declaration msg")
    65  	}
    66  
    67  	msg = adapter.CreateMessage(false)
    68  
    69  	if !protoext.IsLeadershipMsg(msg.(*msgImpl).msg) {
    70  		t.Error("Newly created message should be LeadershipMsg")
    71  	}
    72  
    73  	if !msg.IsProposal() || msg.IsDeclaration() {
    74  		t.Error("Newly created msg should be Proposal msg")
    75  	}
    76  }
    77  
    78  func TestAdapterImpl_Peers(t *testing.T) {
    79  	peersOrgA := map[string]struct{}{
    80  		"Peer0": {},
    81  		"Peer1": {},
    82  		"Peer2": {},
    83  		"Peer3": {},
    84  		"Peer4": {},
    85  		"Peer5": {},
    86  	}
    87  	peersOrgB := map[string]struct{}{
    88  		"Peer6": {},
    89  		"Peer7": {},
    90  		"Peer8": {},
    91  	}
    92  
    93  	pki2org := make(map[string]string)
    94  	for id := range peersOrgA {
    95  		pki2org[id] = "A"
    96  	}
    97  	for id := range peersOrgB {
    98  		pki2org[id] = "B"
    99  	}
   100  
   101  	_, adapters := createCluster(pki2org, 0, 1, 2, 3, 4, 5, 6, 7, 8)
   102  
   103  	for id, adapter := range adapters {
   104  		var myPeersOrg map[string]struct{}
   105  		if pki2org[id] == "A" {
   106  			myPeersOrg = peersOrgA
   107  		} else {
   108  			myPeersOrg = peersOrgB
   109  		}
   110  		peers := adapter.Peers()
   111  		if len(peers) != len(myPeersOrg) {
   112  			t.Errorf("Should return %d peers, not %d", len(myPeersOrg), len(peers))
   113  		}
   114  
   115  		for _, peer := range peers {
   116  			if _, exist := myPeersOrg[peer.(*peerImpl).member.Endpoint]; !exist {
   117  				t.Errorf("Peer %s PKID not found", peer.(*peerImpl).member.Endpoint)
   118  			}
   119  		}
   120  	}
   121  
   122  }
   123  
   124  func TestAdapterImpl_Stop(t *testing.T) {
   125  	_, adapters := createCluster(nil, 0, 1, 2, 3, 4, 5)
   126  
   127  	for _, adapter := range adapters {
   128  		adapter.Accept()
   129  	}
   130  
   131  	for _, adapter := range adapters {
   132  		adapter.Stop()
   133  	}
   134  }
   135  
   136  func TestAdapterImpl_Gossip(t *testing.T) {
   137  	_, adapters := createCluster(nil, 0, 1, 2)
   138  
   139  	channels := make(map[string]<-chan Msg)
   140  
   141  	for peerID, adapter := range adapters {
   142  		channels[peerID] = adapter.Accept()
   143  	}
   144  
   145  	sender := adapters[fmt.Sprintf("Peer%d", 0)]
   146  
   147  	sender.Gossip(sender.CreateMessage(true))
   148  
   149  	totalMsg := 0
   150  
   151  	timer := time.After(time.Duration(1) * time.Second)
   152  
   153  	for {
   154  		select {
   155  		case <-timer:
   156  			if totalMsg != 2 {
   157  				t.Error("Not all messages accepted")
   158  				t.FailNow()
   159  			} else {
   160  				return
   161  			}
   162  		case msg := <-channels[fmt.Sprintf("Peer%d", 1)]:
   163  			if !msg.IsDeclaration() {
   164  				t.Error("Msg should be declaration")
   165  			} else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) {
   166  				t.Error("Msg Sender is wrong")
   167  			} else {
   168  				totalMsg++
   169  			}
   170  		case msg := <-channels[fmt.Sprintf("Peer%d", 2)]:
   171  			if !msg.IsDeclaration() {
   172  				t.Error("Msg should be declaration")
   173  			} else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) {
   174  				t.Error("Msg Sender is wrong")
   175  			} else {
   176  				totalMsg++
   177  			}
   178  		}
   179  
   180  	}
   181  
   182  }
   183  
   184  type mockAcceptor struct {
   185  	ch       chan *proto.GossipMessage
   186  	acceptor common.MessageAcceptor
   187  }
   188  
   189  type peerMockGossip struct {
   190  	cluster      *clusterOfPeers
   191  	member       *discovery.NetworkMember
   192  	acceptors    []*mockAcceptor
   193  	acceptorLock *sync.RWMutex
   194  	clusterLock  *sync.RWMutex
   195  	id           string
   196  	pki2org      map[string]string
   197  }
   198  
   199  func (g *peerMockGossip) PeersOfChannel(channel common.ChannelID) []discovery.NetworkMember {
   200  	g.clusterLock.RLock()
   201  	if g.cluster == nil {
   202  		g.clusterLock.RUnlock()
   203  		return []discovery.NetworkMember{*g.member}
   204  	}
   205  	peerLock := g.cluster.peersLock
   206  	g.clusterLock.RUnlock()
   207  
   208  	peerLock.RLock()
   209  	res := make([]discovery.NetworkMember, 0)
   210  	g.clusterLock.RLock()
   211  	for _, val := range g.cluster.peersGossip {
   212  		res = append(res, *val.member)
   213  	}
   214  	g.clusterLock.RUnlock()
   215  	peerLock.RUnlock()
   216  	return res
   217  }
   218  
   219  func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan protoext.ReceivedMessage) {
   220  	ch := make(chan *proto.GossipMessage, 100)
   221  	g.acceptorLock.Lock()
   222  	g.acceptors = append(g.acceptors, &mockAcceptor{
   223  		ch:       ch,
   224  		acceptor: acceptor,
   225  	})
   226  	g.acceptorLock.Unlock()
   227  	return ch, nil
   228  }
   229  
   230  func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) {
   231  	g.clusterLock.RLock()
   232  	if g.cluster == nil {
   233  		g.clusterLock.RUnlock()
   234  		return
   235  	}
   236  	peersLock := g.cluster.peersLock
   237  	g.clusterLock.RUnlock()
   238  
   239  	peersLock.RLock()
   240  	g.clusterLock.RLock()
   241  	for _, val := range g.cluster.peersGossip {
   242  		if strings.Compare(val.id, g.id) != 0 {
   243  			val.putToAcceptors(msg)
   244  		}
   245  	}
   246  	g.clusterLock.RUnlock()
   247  	peersLock.RUnlock()
   248  
   249  }
   250  
   251  func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) {
   252  	g.acceptorLock.RLock()
   253  	for _, acceptor := range g.acceptors {
   254  		if acceptor.acceptor(msg) {
   255  			if len(acceptor.ch) < 10 {
   256  				acceptor.ch <- msg
   257  			}
   258  		}
   259  	}
   260  	g.acceptorLock.RUnlock()
   261  
   262  }
   263  
   264  func (g *peerMockGossip) IsInMyOrg(member discovery.NetworkMember) bool {
   265  	var myOrg, memberOrg string
   266  	var exists bool
   267  	if myOrg, exists = g.pki2org[g.id]; !exists {
   268  		return false
   269  	}
   270  	if memberOrg, exists = g.pki2org[member.Endpoint]; !exists {
   271  		return false
   272  	}
   273  	return myOrg == memberOrg
   274  }
   275  
   276  func newGossip(peerID string, member *discovery.NetworkMember, pki2org map[string]string) *peerMockGossip {
   277  	return &peerMockGossip{
   278  		id:           peerID,
   279  		member:       member,
   280  		acceptorLock: &sync.RWMutex{},
   281  		clusterLock:  &sync.RWMutex{},
   282  		acceptors:    make([]*mockAcceptor, 0),
   283  		pki2org:      pki2org,
   284  	}
   285  }
   286  
   287  type clusterOfPeers struct {
   288  	peersGossip map[string]*peerMockGossip
   289  	peersLock   *sync.RWMutex
   290  	id          string
   291  }
   292  
   293  func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) {
   294  	cop.peersLock.Lock()
   295  	cop.peersGossip[peerID] = gossip
   296  	gossip.clusterLock.Lock()
   297  	gossip.cluster = cop
   298  	gossip.clusterLock.Unlock()
   299  	cop.peersLock.Unlock()
   300  
   301  }
   302  
   303  func newClusterOfPeers(id string) *clusterOfPeers {
   304  	return &clusterOfPeers{
   305  		id:          id,
   306  		peersGossip: make(map[string]*peerMockGossip),
   307  		peersLock:   &sync.RWMutex{},
   308  	}
   309  
   310  }
   311  
   312  func createCluster(pki2org map[string]string, peers ...int) (*clusterOfPeers, map[string]*adapterImpl) {
   313  	adapters := make(map[string]*adapterImpl)
   314  	cluster := newClusterOfPeers("0")
   315  	for _, peer := range peers {
   316  		peerEndpoint := fmt.Sprintf("Peer%d", peer)
   317  		peerPKID := []byte{byte(peer)}
   318  		peerMember := &discovery.NetworkMember{
   319  			Metadata: []byte{},
   320  			Endpoint: peerEndpoint,
   321  			PKIid:    peerPKID,
   322  		}
   323  
   324  		mockGossip := newGossip(peerEndpoint, peerMember, pki2org)
   325  		adapter := NewAdapter(mockGossip, peerMember.PKIid, []byte("channel0"),
   326  			metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics)
   327  		adapters[peerEndpoint] = adapter.(*adapterImpl)
   328  		cluster.addPeer(peerEndpoint, mockGossip)
   329  	}
   330  
   331  	return cluster, adapters
   332  }
   333  
   334  func TestReportMetrics(t *testing.T) {
   335  
   336  	testMetricProvider := mocks.TestUtilConstructMetricProvider()
   337  	electionMetrics := metrics.NewGossipMetrics(testMetricProvider.FakeProvider).ElectionMetrics
   338  
   339  	mockGossip := newGossip("", &discovery.NetworkMember{}, nil)
   340  	adapter := NewAdapter(mockGossip, nil, []byte("channel0"), electionMetrics)
   341  
   342  	adapter.ReportMetrics(true)
   343  
   344  	assert.Equal(t,
   345  		[]string{"channel", "channel0"},
   346  		testMetricProvider.FakeDeclarationGauge.WithArgsForCall(0),
   347  	)
   348  	assert.EqualValues(t,
   349  		1,
   350  		testMetricProvider.FakeDeclarationGauge.SetArgsForCall(0),
   351  	)
   352  
   353  	adapter.ReportMetrics(false)
   354  
   355  	assert.Equal(t,
   356  		[]string{"channel", "channel0"},
   357  		testMetricProvider.FakeDeclarationGauge.WithArgsForCall(1),
   358  	)
   359  	assert.EqualValues(t,
   360  		0,
   361  		testMetricProvider.FakeDeclarationGauge.SetArgsForCall(1),
   362  	)
   363  
   364  }