github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/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  	"fmt"
    21  	"strings"
    22  	"sync"
    23  	"testing"
    24  	"time"
    25  
    26  	"github.com/hyperledger/fabric/gossip/api"
    27  	"github.com/hyperledger/fabric/gossip/common"
    28  	"github.com/hyperledger/fabric/gossip/discovery"
    29  	proto "github.com/hyperledger/fabric/protos/gossip"
    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)
    39  
    40  	peersCluster := newClusterOfPeers("0")
    41  	peersCluster.addPeer("peer0", mockGossip)
    42  
    43  	NewAdapter(mockGossip, selfNetworkMember, []byte("channel0"))
    44  }
    45  
    46  func TestAdapterImpl_CreateMessage(t *testing.T) {
    47  	selfNetworkMember := &discovery.NetworkMember{
    48  		Endpoint: "p0",
    49  		Metadata: []byte{},
    50  		PKIid:    []byte{byte(0)},
    51  	}
    52  	mockGossip := newGossip("peer0", selfNetworkMember)
    53  
    54  	adapter := NewAdapter(mockGossip, selfNetworkMember, []byte("channel0"))
    55  	msg := adapter.CreateMessage(true)
    56  
    57  	if !msg.(*msgImpl).msg.IsLeadershipMsg() {
    58  		t.Error("Newly created message should be LeadershipMsg")
    59  	}
    60  
    61  	if !msg.IsDeclaration() {
    62  		t.Error("Newly created msg should be Declaration msg")
    63  	}
    64  
    65  	msg = adapter.CreateMessage(false)
    66  
    67  	if !msg.(*msgImpl).msg.IsLeadershipMsg() {
    68  		t.Error("Newly created message should be LeadershipMsg")
    69  	}
    70  
    71  	if !msg.IsProposal() || msg.IsDeclaration() {
    72  		t.Error("Newly created msg should be Proposal msg")
    73  	}
    74  }
    75  
    76  func TestAdapterImpl_Peers(t *testing.T) {
    77  	_, adapters := createCluster(0, 1, 2, 3, 4, 5)
    78  
    79  	peersPKIDs := make(map[string]string)
    80  	peersPKIDs[string([]byte{0})] = string([]byte{0})
    81  	peersPKIDs[string([]byte{1})] = string([]byte{1})
    82  	peersPKIDs[string([]byte{2})] = string([]byte{2})
    83  	peersPKIDs[string([]byte{3})] = string([]byte{2})
    84  	peersPKIDs[string([]byte{4})] = string([]byte{4})
    85  	peersPKIDs[string([]byte{5})] = string([]byte{5})
    86  
    87  	for _, adapter := range adapters {
    88  		peers := adapter.Peers()
    89  		if len(peers) != 6 {
    90  			t.Errorf("Should return 6 peers, not %d", len(peers))
    91  		}
    92  
    93  		for _, peer := range peers {
    94  			if _, exist := peersPKIDs[peer.ID()]; !exist {
    95  				t.Errorf("Peer %s PKID not found", peer.(*peerImpl).member.Endpoint)
    96  			}
    97  		}
    98  	}
    99  
   100  }
   101  
   102  func TestAdapterImpl_Stop(t *testing.T) {
   103  	_, adapters := createCluster(0, 1, 2, 3, 4, 5)
   104  	var ch []<-chan Msg
   105  
   106  	for _, adapter := range adapters {
   107  		ch = append(ch, adapter.Accept())
   108  	}
   109  
   110  	for _, adapter := range adapters {
   111  		adapter.Stop()
   112  	}
   113  }
   114  
   115  func TestAdapterImpl_Gossip(t *testing.T) {
   116  	_, adapters := createCluster(0, 1, 2)
   117  
   118  	channels := make(map[string]<-chan Msg)
   119  
   120  	for peerID, adapter := range adapters {
   121  		channels[peerID] = adapter.Accept()
   122  	}
   123  
   124  	sender := adapters[fmt.Sprintf("Peer%d", 0)]
   125  
   126  	sender.Gossip(sender.CreateMessage(true))
   127  
   128  	totalMsg := 0
   129  
   130  	timer := time.After(time.Duration(1) * time.Second)
   131  
   132  	for {
   133  		select {
   134  		case <-timer:
   135  			if totalMsg != 2 {
   136  				t.Error("Not all messages accepted")
   137  				t.FailNow()
   138  			} else {
   139  				return
   140  			}
   141  		case msg := <-channels[fmt.Sprintf("Peer%d", 1)]:
   142  			if !msg.IsDeclaration() {
   143  				t.Error("Msg should be declaration")
   144  			} else if strings.Compare(msg.SenderID(), string(sender.self.PKIid)) != 0 {
   145  				t.Error("Msg Sender is wrong")
   146  			} else {
   147  				totalMsg++
   148  			}
   149  		case msg := <-channels[fmt.Sprintf("Peer%d", 2)]:
   150  			if !msg.IsDeclaration() {
   151  				t.Error("Msg should be declaration")
   152  			} else if strings.Compare(msg.SenderID(), string(sender.self.PKIid)) != 0 {
   153  				t.Error("Msg Sender is wrong")
   154  			} else {
   155  				totalMsg++
   156  			}
   157  		}
   158  
   159  	}
   160  
   161  }
   162  
   163  type mockMsgCrypto struct {
   164  }
   165  
   166  // Sign signs a message, returns a signed message on success
   167  // or an error on failure
   168  func (is *mockMsgCrypto) Sign(msg []byte) ([]byte, error) {
   169  	return msg, nil
   170  }
   171  
   172  // Verify verifies a signed message
   173  func (is *mockMsgCrypto) Verify(vkID, signature, message []byte) error {
   174  	return nil
   175  }
   176  
   177  // Get returns the identity of a given pkiID, or error if such an identity
   178  // isn't found
   179  func (is *mockMsgCrypto) Get(pkiID common.PKIidType) (api.PeerIdentityType, error) {
   180  	return nil, nil
   181  }
   182  
   183  type mockAcceptor struct {
   184  	ch       chan *proto.GossipMessage
   185  	acceptor common.MessageAcceptor
   186  }
   187  
   188  type peerMockGossip struct {
   189  	cluster      *clusterOfPeers
   190  	member       *discovery.NetworkMember
   191  	acceptors    []*mockAcceptor
   192  	acceptorLock *sync.RWMutex
   193  	clusterLock  *sync.RWMutex
   194  	id           string
   195  }
   196  
   197  func (g *peerMockGossip) Peers() []discovery.NetworkMember {
   198  
   199  	g.clusterLock.RLock()
   200  	if g.cluster == nil {
   201  		return []discovery.NetworkMember{*g.member}
   202  	}
   203  	peerLock := g.cluster.peersLock
   204  	g.clusterLock.RUnlock()
   205  
   206  	peerLock.RLock()
   207  	res := make([]discovery.NetworkMember, 0)
   208  	g.clusterLock.RLock()
   209  	for _, val := range g.cluster.peersGossip {
   210  		res = append(res, *val.member)
   211  
   212  	}
   213  	g.clusterLock.RUnlock()
   214  	peerLock.RUnlock()
   215  	return res
   216  }
   217  
   218  func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage) {
   219  	ch := make(chan *proto.GossipMessage, 100)
   220  	g.acceptorLock.Lock()
   221  	g.acceptors = append(g.acceptors, &mockAcceptor{
   222  		ch:       ch,
   223  		acceptor: acceptor,
   224  	})
   225  	g.acceptorLock.Unlock()
   226  	return ch, nil
   227  }
   228  
   229  func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) {
   230  	g.clusterLock.RLock()
   231  	if g.cluster == nil {
   232  		return
   233  	}
   234  	peersLock := g.cluster.peersLock
   235  	g.clusterLock.RUnlock()
   236  
   237  	peersLock.RLock()
   238  	g.clusterLock.RLock()
   239  	for _, val := range g.cluster.peersGossip {
   240  		if strings.Compare(val.id, g.id) != 0 {
   241  			val.putToAcceptors(msg)
   242  		}
   243  	}
   244  	g.clusterLock.RUnlock()
   245  	peersLock.RUnlock()
   246  
   247  }
   248  
   249  func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) {
   250  	g.acceptorLock.RLock()
   251  	for _, acceptor := range g.acceptors {
   252  		if acceptor.acceptor(msg) {
   253  			if len(acceptor.ch) < 10 {
   254  				acceptor.ch <- msg
   255  			}
   256  		}
   257  	}
   258  	g.acceptorLock.RUnlock()
   259  
   260  }
   261  
   262  func newGossip(peerID string, member *discovery.NetworkMember) *peerMockGossip {
   263  	return &peerMockGossip{
   264  		id:           peerID,
   265  		member:       member,
   266  		acceptorLock: &sync.RWMutex{},
   267  		clusterLock:  &sync.RWMutex{},
   268  		acceptors:    make([]*mockAcceptor, 0),
   269  	}
   270  }
   271  
   272  type clusterOfPeers struct {
   273  	peersGossip map[string]*peerMockGossip
   274  	peersLock   *sync.RWMutex
   275  	id          string
   276  }
   277  
   278  func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) {
   279  	cop.peersLock.Lock()
   280  	cop.peersGossip[peerID] = gossip
   281  	gossip.clusterLock.Lock()
   282  	gossip.cluster = cop
   283  	gossip.clusterLock.Unlock()
   284  	cop.peersLock.Unlock()
   285  
   286  }
   287  
   288  func newClusterOfPeers(id string) *clusterOfPeers {
   289  	return &clusterOfPeers{
   290  		id:          id,
   291  		peersGossip: make(map[string]*peerMockGossip),
   292  		peersLock:   &sync.RWMutex{},
   293  	}
   294  
   295  }
   296  
   297  func createCluster(peers ...int) (*clusterOfPeers, map[string]*adapterImpl) {
   298  	adapters := make(map[string]*adapterImpl)
   299  	cluster := newClusterOfPeers("0")
   300  	for _, peer := range peers {
   301  		peerEndpoint := fmt.Sprintf("Peer%d", peer)
   302  		peerPKID := []byte{byte(peer)}
   303  		peerMember := &discovery.NetworkMember{
   304  			Metadata: []byte{},
   305  			Endpoint: peerEndpoint,
   306  			PKIid:    peerPKID,
   307  		}
   308  
   309  		mockGossip := newGossip(peerEndpoint, peerMember)
   310  		adapter := NewAdapter(mockGossip, peerMember, []byte("channel0"))
   311  		adapters[peerEndpoint] = adapter.(*adapterImpl)
   312  		cluster.addPeer(peerEndpoint, mockGossip)
   313  	}
   314  
   315  	return cluster, adapters
   316  }