github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/events/producer/producer_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 producer
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"math/rand"
    24  	"net"
    25  	"os"
    26  	"sync"
    27  	"testing"
    28  	"time"
    29  
    30  	"golang.org/x/net/context"
    31  
    32  	"google.golang.org/grpc"
    33  	"google.golang.org/grpc/credentials"
    34  	"google.golang.org/grpc/grpclog"
    35  	"google.golang.org/grpc/metadata"
    36  
    37  	"github.com/hyperledger/fabric/common/ledger/testutil"
    38  	mmsp "github.com/hyperledger/fabric/common/mocks/msp"
    39  	"github.com/hyperledger/fabric/common/util"
    40  	"github.com/hyperledger/fabric/core/config"
    41  	coreutil "github.com/hyperledger/fabric/core/testutil"
    42  	"github.com/hyperledger/fabric/events/consumer"
    43  	"github.com/hyperledger/fabric/msp"
    44  	"github.com/hyperledger/fabric/msp/mgmt"
    45  	"github.com/hyperledger/fabric/msp/mgmt/testtools"
    46  	"github.com/hyperledger/fabric/protos/peer"
    47  	ehpb "github.com/hyperledger/fabric/protos/peer"
    48  	"github.com/hyperledger/fabric/protos/utils"
    49  	"github.com/spf13/viper"
    50  	"github.com/stretchr/testify/assert"
    51  )
    52  
    53  type Adapter struct {
    54  	sync.RWMutex
    55  	notfy chan struct{}
    56  	count int
    57  }
    58  
    59  var adapter *Adapter
    60  var obcEHClient *consumer.EventsClient
    61  var ehServer *EventsServer
    62  
    63  func (a *Adapter) GetInterestedEvents() ([]*ehpb.Interest, error) {
    64  	return []*ehpb.Interest{
    65  		&ehpb.Interest{EventType: ehpb.EventType_BLOCK},
    66  		&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event1"}}},
    67  		&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event2"}}},
    68  		&ehpb.Interest{EventType: ehpb.EventType_REGISTER, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event3"}}},
    69  		&ehpb.Interest{EventType: ehpb.EventType_REJECTION, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event4"}}},
    70  	}, nil
    71  }
    72  
    73  func (a *Adapter) updateCountNotify() {
    74  	a.Lock()
    75  	a.count--
    76  	if a.count <= 0 {
    77  		a.notfy <- struct{}{}
    78  	}
    79  	a.Unlock()
    80  }
    81  
    82  func (a *Adapter) Recv(msg *ehpb.Event) (bool, error) {
    83  	switch x := msg.Event.(type) {
    84  	case *ehpb.Event_Block, *ehpb.Event_ChaincodeEvent, *ehpb.Event_Register, *ehpb.Event_Unregister:
    85  		a.updateCountNotify()
    86  	case nil:
    87  		// The field is not set.
    88  		return false, fmt.Errorf("event not set")
    89  	default:
    90  		return false, fmt.Errorf("unexpected type %T", x)
    91  	}
    92  	return true, nil
    93  }
    94  
    95  func (a *Adapter) Disconnected(err error) {
    96  	if err != nil {
    97  		fmt.Printf("Error: %s\n", err)
    98  	}
    99  }
   100  
   101  func createEvent() (*peer.Event, error) {
   102  	events := make([]*peer.Interest, 2)
   103  	events[0] = &peer.Interest{
   104  		EventType: peer.EventType_BLOCK,
   105  	}
   106  	events[1] = &peer.Interest{
   107  		EventType: peer.EventType_BLOCK,
   108  		ChainID:   util.GetTestChainID(),
   109  	}
   110  
   111  	evt := &peer.Event{
   112  		Event: &peer.Event_Register{
   113  			Register: &peer.Register{
   114  				Events: events,
   115  			},
   116  		},
   117  		Creator: signerSerialized,
   118  	}
   119  
   120  	return evt, nil
   121  }
   122  
   123  var r *rand.Rand
   124  
   125  func corrupt(bytes []byte) {
   126  	if r == nil {
   127  		r = rand.New(rand.NewSource(time.Now().Unix()))
   128  	}
   129  
   130  	bytes[r.Int31n(int32(len(bytes)))]--
   131  }
   132  
   133  func TestSignedEvent(t *testing.T) {
   134  	// get a test event
   135  	evt, err := createEvent()
   136  	if err != nil {
   137  		t.Fatalf("createEvent failed, err %s", err)
   138  		return
   139  	}
   140  
   141  	// sign it
   142  	sEvt, err := utils.GetSignedEvent(evt, signer)
   143  	if err != nil {
   144  		t.Fatalf("GetSignedEvent failed, err %s", err)
   145  		return
   146  	}
   147  
   148  	// validate it. Expected to succeed
   149  	_, err = validateEventMessage(sEvt)
   150  	if err != nil {
   151  		t.Fatalf("validateEventMessage failed, err %s", err)
   152  		return
   153  	}
   154  
   155  	// mess with the signature
   156  	corrupt(sEvt.Signature)
   157  
   158  	// validate it, it should fail
   159  	_, err = validateEventMessage(sEvt)
   160  	if err == nil {
   161  		t.Fatalf("validateEventMessage should have failed")
   162  		return
   163  	}
   164  
   165  	// get a bad signing identity
   166  	badSigner, err := mmsp.NewNoopMsp().GetDefaultSigningIdentity()
   167  	if err != nil {
   168  		t.Fatal("couldn't get noop signer")
   169  		return
   170  	}
   171  
   172  	// sign it again with the bad signer
   173  	sEvt, err = utils.GetSignedEvent(evt, badSigner)
   174  	if err != nil {
   175  		t.Fatalf("GetSignedEvent failed, err %s", err)
   176  		return
   177  	}
   178  
   179  	// validate it, it should fail
   180  	_, err = validateEventMessage(sEvt)
   181  	if err == nil {
   182  		t.Fatalf("validateEventMessage should have failed")
   183  		return
   184  	}
   185  }
   186  
   187  func createTestChaincodeEvent(tid string, typ string) *ehpb.Event {
   188  	emsg := CreateChaincodeEvent(&ehpb.ChaincodeEvent{ChaincodeId: tid, EventName: typ})
   189  	return emsg
   190  }
   191  
   192  // Test the invocation of a transaction.
   193  func TestReceiveMessage(t *testing.T) {
   194  	var err error
   195  
   196  	adapter.count = 1
   197  	emsg := createTestChaincodeEvent("0xffffffff", "event1")
   198  	if err = Send(emsg); err != nil {
   199  		t.Fail()
   200  		t.Logf("Error sending message %s", err)
   201  	}
   202  
   203  	select {
   204  	case <-adapter.notfy:
   205  	case <-time.After(5 * time.Second):
   206  		t.Fail()
   207  		t.Logf("timed out on message")
   208  	}
   209  }
   210  
   211  func TestReceiveAnyMessage(t *testing.T) {
   212  	var err error
   213  
   214  	adapter.count = 1
   215  	block := testutil.ConstructTestBlock(t, 1, 10, 100)
   216  	if err = SendProducerBlockEvent(block); err != nil {
   217  		t.Fail()
   218  		t.Logf("Error sending message %s", err)
   219  	}
   220  
   221  	emsg := createTestChaincodeEvent("0xffffffff", "event2")
   222  	if err = Send(emsg); err != nil {
   223  		t.Fail()
   224  		t.Logf("Error sending message %s", err)
   225  	}
   226  
   227  	//receive 2 messages - a block and a chaincode event
   228  	for i := 0; i < 2; i++ {
   229  		select {
   230  		case <-adapter.notfy:
   231  		case <-time.After(5 * time.Second):
   232  			t.Fail()
   233  			t.Logf("timed out on message")
   234  		}
   235  	}
   236  }
   237  
   238  func TestReceiveCCWildcard(t *testing.T) {
   239  	var err error
   240  
   241  	adapter.count = 1
   242  	obcEHClient.RegisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: ""}}}})
   243  
   244  	select {
   245  	case <-adapter.notfy:
   246  	case <-time.After(2 * time.Second):
   247  		t.Fail()
   248  		t.Logf("timed out on message")
   249  	}
   250  
   251  	adapter.count = 1
   252  	emsg := createTestChaincodeEvent("0xffffffff", "wildcardevent")
   253  	if err = Send(emsg); err != nil {
   254  		t.Fail()
   255  		t.Logf("Error sending message %s", err)
   256  	}
   257  
   258  	select {
   259  	case <-adapter.notfy:
   260  	case <-time.After(2 * time.Second):
   261  		t.Fail()
   262  		t.Logf("timed out on message")
   263  	}
   264  	adapter.count = 1
   265  	obcEHClient.UnregisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: ""}}}})
   266  
   267  	select {
   268  	case <-adapter.notfy:
   269  	case <-time.After(2 * time.Second):
   270  		t.Fail()
   271  		t.Logf("timed out on message")
   272  	}
   273  }
   274  
   275  func TestFailReceive(t *testing.T) {
   276  	var err error
   277  
   278  	adapter.count = 1
   279  	emsg := createTestChaincodeEvent("badcc", "event1")
   280  	if err = Send(emsg); err != nil {
   281  		t.Fail()
   282  		t.Logf("Error sending message %s", err)
   283  	}
   284  
   285  	select {
   286  	case <-adapter.notfy:
   287  		t.Fail()
   288  		t.Logf("should NOT have received event1")
   289  	case <-time.After(2 * time.Second):
   290  	}
   291  }
   292  
   293  func TestUnregister(t *testing.T) {
   294  	var err error
   295  	obcEHClient.RegisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event10"}}}})
   296  
   297  	adapter.count = 1
   298  	select {
   299  	case <-adapter.notfy:
   300  	case <-time.After(2 * time.Second):
   301  		t.Fail()
   302  		t.Logf("timed out on message")
   303  	}
   304  
   305  	emsg := createTestChaincodeEvent("0xffffffff", "event10")
   306  	if err = Send(emsg); err != nil {
   307  		t.Fail()
   308  		t.Logf("Error sending message %s", err)
   309  	}
   310  
   311  	adapter.count = 1
   312  	select {
   313  	case <-adapter.notfy:
   314  	case <-time.After(2 * time.Second):
   315  		t.Fail()
   316  		t.Logf("timed out on message")
   317  	}
   318  	obcEHClient.UnregisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event10"}}}})
   319  	adapter.count = 1
   320  	select {
   321  	case <-adapter.notfy:
   322  	case <-time.After(2 * time.Second):
   323  		t.Fail()
   324  		t.Logf("should have received unreg")
   325  	}
   326  
   327  	adapter.count = 1
   328  	emsg = createTestChaincodeEvent("0xffffffff", "event10")
   329  	if err = Send(emsg); err != nil {
   330  		t.Fail()
   331  		t.Logf("Error sending message %s", err)
   332  	}
   333  
   334  	select {
   335  	case <-adapter.notfy:
   336  		t.Fail()
   337  		t.Logf("should NOT have received event1")
   338  	case <-time.After(5 * time.Second):
   339  	}
   340  
   341  }
   342  
   343  func TestNewEventsServer(t *testing.T) {
   344  	doubleCreation := func() {
   345  		NewEventsServer(
   346  			uint(viper.GetInt("peer.events.buffersize")),
   347  			viper.GetDuration("peer.events.timeout"))
   348  	}
   349  	assert.Panics(t, doubleCreation)
   350  
   351  	assert.NotNil(t, ehServer, "nil EventServer found")
   352  }
   353  
   354  type mockstream struct {
   355  	c chan *streamEvent
   356  }
   357  
   358  type streamEvent struct {
   359  	event *peer.SignedEvent
   360  	err   error
   361  }
   362  
   363  func (*mockstream) Send(*peer.Event) error {
   364  	return nil
   365  }
   366  
   367  func (s *mockstream) Recv() (*peer.SignedEvent, error) {
   368  	se := <-s.c
   369  	if se.err == nil {
   370  		return se.event, nil
   371  	}
   372  	return nil, se.err
   373  }
   374  
   375  func (*mockstream) SetHeader(metadata.MD) error {
   376  	panic("not implemented")
   377  }
   378  
   379  func (*mockstream) SendHeader(metadata.MD) error {
   380  	panic("not implemented")
   381  }
   382  
   383  func (*mockstream) SetTrailer(metadata.MD) {
   384  	panic("not implemented")
   385  }
   386  
   387  func (*mockstream) Context() context.Context {
   388  	panic("not implemented")
   389  }
   390  
   391  func (*mockstream) SendMsg(m interface{}) error {
   392  	panic("not implemented")
   393  }
   394  
   395  func (*mockstream) RecvMsg(m interface{}) error {
   396  	panic("not implemented")
   397  }
   398  
   399  func TestChat(t *testing.T) {
   400  	recvChan := make(chan *streamEvent)
   401  	stream := &mockstream{c: recvChan}
   402  	go ehServer.Chat(stream)
   403  	e, err := createEvent()
   404  	sEvt, err := utils.GetSignedEvent(e, signer)
   405  	assert.NoError(t, err)
   406  	recvChan <- &streamEvent{event: sEvt}
   407  	recvChan <- &streamEvent{event: &peer.SignedEvent{}}
   408  	go ehServer.Chat(stream)
   409  	recvChan <- &streamEvent{err: io.EOF}
   410  	go ehServer.Chat(stream)
   411  	recvChan <- &streamEvent{err: errors.New("err")}
   412  	time.Sleep(time.Second)
   413  }
   414  
   415  var signer msp.SigningIdentity
   416  var signerSerialized []byte
   417  
   418  func TestMain(m *testing.M) {
   419  	// setup crypto algorithms
   420  	// setup the MSP manager so that we can sign/verify
   421  	err := msptesttools.LoadMSPSetupForTesting()
   422  	if err != nil {
   423  		fmt.Printf("Could not initialize msp, err %s", err)
   424  		os.Exit(-1)
   425  		return
   426  	}
   427  
   428  	signer, err = mgmt.GetLocalMSP().GetDefaultSigningIdentity()
   429  	if err != nil {
   430  		fmt.Println("Could not get signer")
   431  		os.Exit(-1)
   432  		return
   433  	}
   434  
   435  	signerSerialized, err = signer.Serialize()
   436  	if err != nil {
   437  		fmt.Println("Could not serialize identity")
   438  		os.Exit(-1)
   439  		return
   440  	}
   441  	coreutil.SetupTestConfig()
   442  	var opts []grpc.ServerOption
   443  	if viper.GetBool("peer.tls.enabled") {
   444  		creds, err := credentials.NewServerTLSFromFile(config.GetPath("peer.tls.cert.file"), config.GetPath("peer.tls.key.file"))
   445  		if err != nil {
   446  			grpclog.Fatalf("Failed to generate credentials %v", err)
   447  		}
   448  		opts = []grpc.ServerOption{grpc.Creds(creds)}
   449  	}
   450  	grpcServer := grpc.NewServer(opts...)
   451  
   452  	//use a different address than what we usually use for "peer"
   453  	//we override the peerAddress set in chaincode_support.go
   454  	peerAddress = "0.0.0.0:60303"
   455  
   456  	lis, err := net.Listen("tcp", peerAddress)
   457  	if err != nil {
   458  		fmt.Printf("Error starting events listener %s....not doing tests", err)
   459  		return
   460  	}
   461  
   462  	// Register EventHub server
   463  	// use a buffer of 100 and blocking timeout
   464  	viper.Set("peer.events.buffersize", 100)
   465  	viper.Set("peer.events.timeout", 0)
   466  
   467  	ehServer = NewEventsServer(
   468  		uint(viper.GetInt("peer.events.buffersize")),
   469  		viper.GetDuration("peer.events.timeout"))
   470  	ehpb.RegisterEventsServer(grpcServer, ehServer)
   471  
   472  	go grpcServer.Serve(lis)
   473  
   474  	var regTimeout = 5 * time.Second
   475  	done := make(chan struct{})
   476  	adapter = &Adapter{notfy: done}
   477  	obcEHClient, _ = consumer.NewEventsClient(peerAddress, regTimeout, adapter)
   478  	if err = obcEHClient.Start(); err != nil {
   479  		fmt.Printf("could not start chat %s\n", err)
   480  		obcEHClient.Stop()
   481  		return
   482  	}
   483  
   484  	time.Sleep(2 * time.Second)
   485  	os.Exit(m.Run())
   486  }