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 }