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: ×tamp.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 }