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