github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/events/events_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 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 events
    18  
    19  import (
    20  	"fmt"
    21  	"net"
    22  	"os"
    23  	"sync"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/golang/protobuf/ptypes/timestamp"
    28  	"github.com/hyperledger/fabric/events/consumer"
    29  	"github.com/hyperledger/fabric/events/producer"
    30  	"github.com/hyperledger/fabric/protos/common"
    31  	ehpb "github.com/hyperledger/fabric/protos/peer"
    32  	"github.com/hyperledger/fabric/protos/utils"
    33  	"github.com/spf13/viper"
    34  	"google.golang.org/grpc"
    35  	"google.golang.org/grpc/credentials"
    36  	"google.golang.org/grpc/grpclog"
    37  )
    38  
    39  type Adapter struct {
    40  	sync.RWMutex
    41  	notfy chan struct{}
    42  	count int
    43  }
    44  
    45  var peerAddress string
    46  var adapter *Adapter
    47  var obcEHClient *consumer.EventsClient
    48  
    49  func (a *Adapter) GetInterestedEvents() ([]*ehpb.Interest, error) {
    50  	return []*ehpb.Interest{
    51  		&ehpb.Interest{EventType: ehpb.EventType_BLOCK},
    52  		&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event1"}}},
    53  		&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event2"}}},
    54  	}, nil
    55  	//return []*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_BLOCK}}, nil
    56  }
    57  
    58  func (a *Adapter) updateCountNotify() {
    59  	a.Lock()
    60  	a.count--
    61  	if a.count <= 0 {
    62  		a.notfy <- struct{}{}
    63  	}
    64  	a.Unlock()
    65  }
    66  
    67  func (a *Adapter) Recv(msg *ehpb.Event) (bool, error) {
    68  	switch x := msg.Event.(type) {
    69  	case *ehpb.Event_Block, *ehpb.Event_ChaincodeEvent, *ehpb.Event_Register, *ehpb.Event_Unregister:
    70  		a.updateCountNotify()
    71  	case nil:
    72  		// The field is not set.
    73  		return false, fmt.Errorf("event not set")
    74  	default:
    75  		return false, fmt.Errorf("unexpected type %T", x)
    76  	}
    77  	return true, nil
    78  }
    79  
    80  func (a *Adapter) Disconnected(err error) {
    81  	if err != nil {
    82  		fmt.Printf("Error: %s\n", err)
    83  	}
    84  }
    85  
    86  func createTestBlock(t *testing.T) *common.Block {
    87  	chdr := &common.ChannelHeader{
    88  		Type:    int32(common.HeaderType_ENDORSER_TRANSACTION),
    89  		Version: 1,
    90  		Timestamp: &timestamp.Timestamp{
    91  			Seconds: time.Now().Unix(),
    92  			Nanos:   0,
    93  		},
    94  		ChannelId: "test"}
    95  	hdr := &common.Header{ChannelHeader: utils.MarshalOrPanic(chdr)}
    96  	payload := &common.Payload{Header: hdr}
    97  	cea := &ehpb.ChaincodeEndorsedAction{}
    98  	ccaPayload := &ehpb.ChaincodeActionPayload{Action: cea}
    99  	env := &common.Envelope{}
   100  	taa := &ehpb.TransactionAction{}
   101  	taas := make([]*ehpb.TransactionAction, 1)
   102  	taas[0] = taa
   103  	tx := &ehpb.Transaction{Actions: taas}
   104  
   105  	events := &ehpb.ChaincodeEvent{
   106  		ChaincodeId: "ccid",
   107  		EventName:   "EventName",
   108  		Payload:     []byte("EventPayload"),
   109  		TxId:        "TxID"}
   110  
   111  	pHashBytes := []byte("proposal_hash")
   112  	pResponse := &ehpb.Response{Status: 200}
   113  	results := []byte("results")
   114  	eventBytes, err := utils.GetBytesChaincodeEvent(events)
   115  	if err != nil {
   116  		t.Fatalf("Failure while marshalling the ProposalResponsePayload")
   117  	}
   118  	ccaPayload.Action.ProposalResponsePayload, err = utils.GetBytesProposalResponsePayload(pHashBytes, pResponse, results, eventBytes)
   119  	if err != nil {
   120  		t.Fatalf("Failure while marshalling the ProposalResponsePayload")
   121  	}
   122  	tx.Actions[0].Payload, err = utils.GetBytesChaincodeActionPayload(ccaPayload)
   123  	if err != nil {
   124  		t.Fatalf("Error marshalling tx action payload for block event: %s", err)
   125  	}
   126  	payload.Data, err = utils.GetBytesTransaction(tx)
   127  	if err != nil {
   128  		t.Fatalf("Failure while marshalling payload for block event: %s", err)
   129  	}
   130  	env.Payload, err = utils.GetBytesPayload(payload)
   131  	if err != nil {
   132  		t.Fatalf("Failure while marshalling tx envelope for block event: %s", err)
   133  	}
   134  	ebytes, err := utils.GetBytesEnvelope(env)
   135  	if err != nil {
   136  		t.Fatalf("Failure while marshalling transaction %s", err)
   137  	}
   138  
   139  	block := common.NewBlock(1, []byte{})
   140  	block.Data.Data = append(block.Data.Data, ebytes)
   141  	block.Header.DataHash = block.Data.Hash()
   142  	return block
   143  }
   144  
   145  func createTestChaincodeEvent(tid string, typ string) *ehpb.Event {
   146  	emsg := producer.CreateChaincodeEvent(&ehpb.ChaincodeEvent{ChaincodeId: tid, EventName: typ})
   147  	return emsg
   148  }
   149  
   150  func closeListenerAndSleep(l net.Listener) {
   151  	l.Close()
   152  	time.Sleep(2 * time.Second)
   153  }
   154  
   155  // Test the invocation of a transaction.
   156  func TestReceiveMessage(t *testing.T) {
   157  	var err error
   158  
   159  	adapter.count = 1
   160  	//emsg := createTestBlock()
   161  	emsg := createTestChaincodeEvent("0xffffffff", "event1")
   162  	if err = producer.Send(emsg); err != nil {
   163  		t.Fail()
   164  		t.Logf("Error sending message %s", err)
   165  	}
   166  
   167  	select {
   168  	case <-adapter.notfy:
   169  	case <-time.After(2 * time.Second):
   170  		t.Fail()
   171  		t.Logf("timed out on messge")
   172  	}
   173  }
   174  func TestReceiveAnyMessage(t *testing.T) {
   175  	var err error
   176  
   177  	adapter.count = 1
   178  	block := createTestBlock(t)
   179  	if err = producer.SendProducerBlockEvent(block); err != nil {
   180  		t.Fail()
   181  		t.Logf("Error sending message %s", err)
   182  	}
   183  
   184  	emsg := createTestChaincodeEvent("0xffffffff", "event2")
   185  	if err = producer.Send(emsg); err != nil {
   186  		t.Fail()
   187  		t.Logf("Error sending message %s", err)
   188  	}
   189  
   190  	//receive 2 messages - a block and a chaincode event
   191  	for i := 0; i < 2; i++ {
   192  		select {
   193  		case <-adapter.notfy:
   194  		case <-time.After(5 * time.Second):
   195  			t.Fail()
   196  			t.Logf("timed out on messge")
   197  		}
   198  	}
   199  }
   200  func TestReceiveCCWildcard(t *testing.T) {
   201  	var err error
   202  
   203  	adapter.count = 1
   204  	obcEHClient.RegisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: ""}}}})
   205  
   206  	select {
   207  	case <-adapter.notfy:
   208  	case <-time.After(2 * time.Second):
   209  		t.Fail()
   210  		t.Logf("timed out on messge")
   211  	}
   212  
   213  	adapter.count = 1
   214  	emsg := createTestChaincodeEvent("0xffffffff", "wildcardevent")
   215  	if err = producer.Send(emsg); err != nil {
   216  		t.Fail()
   217  		t.Logf("Error sending message %s", err)
   218  	}
   219  
   220  	select {
   221  	case <-adapter.notfy:
   222  	case <-time.After(2 * time.Second):
   223  		t.Fail()
   224  		t.Logf("timed out on messge")
   225  	}
   226  	adapter.count = 1
   227  	obcEHClient.UnregisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: ""}}}})
   228  
   229  	select {
   230  	case <-adapter.notfy:
   231  	case <-time.After(2 * time.Second):
   232  		t.Fail()
   233  		t.Logf("timed out on messge")
   234  	}
   235  }
   236  
   237  func TestFailReceive(t *testing.T) {
   238  	var err error
   239  
   240  	adapter.count = 1
   241  	emsg := createTestChaincodeEvent("badcc", "event1")
   242  	if err = producer.Send(emsg); err != nil {
   243  		t.Fail()
   244  		t.Logf("Error sending message %s", err)
   245  	}
   246  
   247  	select {
   248  	case <-adapter.notfy:
   249  		t.Fail()
   250  		t.Logf("should NOT have received event1")
   251  	case <-time.After(2 * time.Second):
   252  	}
   253  }
   254  
   255  func TestUnregister(t *testing.T) {
   256  	var err error
   257  	obcEHClient.RegisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event10"}}}})
   258  
   259  	adapter.count = 1
   260  	select {
   261  	case <-adapter.notfy:
   262  	case <-time.After(2 * time.Second):
   263  		t.Fail()
   264  		t.Logf("timed out on messge")
   265  	}
   266  
   267  	emsg := createTestChaincodeEvent("0xffffffff", "event10")
   268  	if err = producer.Send(emsg); err != nil {
   269  		t.Fail()
   270  		t.Logf("Error sending message %s", err)
   271  	}
   272  
   273  	adapter.count = 1
   274  	select {
   275  	case <-adapter.notfy:
   276  	case <-time.After(2 * time.Second):
   277  		t.Fail()
   278  		t.Logf("timed out on messge")
   279  	}
   280  	obcEHClient.UnregisterAsync([]*ehpb.Interest{&ehpb.Interest{EventType: ehpb.EventType_CHAINCODE, RegInfo: &ehpb.Interest_ChaincodeRegInfo{ChaincodeRegInfo: &ehpb.ChaincodeReg{ChaincodeId: "0xffffffff", EventName: "event10"}}}})
   281  	adapter.count = 1
   282  	select {
   283  	case <-adapter.notfy:
   284  	case <-time.After(2 * time.Second):
   285  		t.Fail()
   286  		t.Logf("should have received unreg")
   287  	}
   288  
   289  	adapter.count = 1
   290  	emsg = createTestChaincodeEvent("0xffffffff", "event10")
   291  	if err = producer.Send(emsg); err != nil {
   292  		t.Fail()
   293  		t.Logf("Error sending message %s", err)
   294  	}
   295  
   296  	select {
   297  	case <-adapter.notfy:
   298  		t.Fail()
   299  		t.Logf("should NOT have received event1")
   300  	case <-time.After(5 * time.Second):
   301  	}
   302  
   303  }
   304  
   305  func BenchmarkMessages(b *testing.B) {
   306  	numMessages := 10000
   307  
   308  	adapter.count = numMessages
   309  
   310  	var err error
   311  	//b.ResetTimer()
   312  
   313  	for i := 0; i < numMessages; i++ {
   314  		go func() {
   315  			//emsg := createTestBlock()
   316  			emsg := createTestChaincodeEvent("0xffffffff", "event1")
   317  			if err = producer.Send(emsg); err != nil {
   318  				b.Fail()
   319  				b.Logf("Error sending message %s", err)
   320  			}
   321  		}()
   322  	}
   323  
   324  	select {
   325  	case <-adapter.notfy:
   326  	case <-time.After(5 * time.Second):
   327  		b.Fail()
   328  		b.Logf("timed out on messge")
   329  	}
   330  }
   331  
   332  func TestMain(m *testing.M) {
   333  	SetupTestConfig()
   334  	var opts []grpc.ServerOption
   335  	if viper.GetBool("peer.tls.enabled") {
   336  		creds, err := credentials.NewServerTLSFromFile(viper.GetString("peer.tls.cert.file"), viper.GetString("peer.tls.key.file"))
   337  		if err != nil {
   338  			grpclog.Fatalf("Failed to generate credentials %v", err)
   339  		}
   340  		opts = []grpc.ServerOption{grpc.Creds(creds)}
   341  	}
   342  	grpcServer := grpc.NewServer(opts...)
   343  
   344  	//use a different address than what we usually use for "peer"
   345  	//we override the peerAddress set in chaincode_support.go
   346  	peerAddress = "0.0.0.0:60303"
   347  
   348  	lis, err := net.Listen("tcp", peerAddress)
   349  	if err != nil {
   350  		fmt.Printf("Error starting events listener %s....not doing tests", err)
   351  		return
   352  	}
   353  
   354  	// Register EventHub server
   355  	// use a buffer of 100 and blocking timeout
   356  	ehServer := producer.NewEventsServer(100, 0)
   357  	ehpb.RegisterEventsServer(grpcServer, ehServer)
   358  
   359  	fmt.Printf("Starting events server\n")
   360  	go grpcServer.Serve(lis)
   361  
   362  	var regTimeout = 5 * time.Second
   363  	done := make(chan struct{})
   364  	adapter = &Adapter{notfy: done}
   365  	obcEHClient, _ = consumer.NewEventsClient(peerAddress, regTimeout, adapter)
   366  	if err = obcEHClient.Start(); err != nil {
   367  		fmt.Printf("could not start chat %s\n", err)
   368  		obcEHClient.Stop()
   369  		return
   370  	}
   371  
   372  	time.Sleep(2 * time.Second)
   373  
   374  	os.Exit(m.Run())
   375  }