github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/gossip/comm/comm_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 comm 18 19 import ( 20 "bytes" 21 "crypto/hmac" 22 "crypto/sha256" 23 "crypto/tls" 24 "fmt" 25 "math/rand" 26 "os" 27 "strings" 28 "sync" 29 "testing" 30 "time" 31 32 "github.com/hyperledger/fabric/bccsp/factory" 33 "github.com/hyperledger/fabric/core/config" 34 "github.com/hyperledger/fabric/gossip/api" 35 "github.com/hyperledger/fabric/gossip/common" 36 "github.com/hyperledger/fabric/gossip/identity" 37 "github.com/hyperledger/fabric/gossip/util" 38 proto "github.com/hyperledger/fabric/protos/gossip" 39 "github.com/spf13/viper" 40 "github.com/stretchr/testify/assert" 41 "golang.org/x/net/context" 42 "google.golang.org/grpc" 43 "google.golang.org/grpc/credentials" 44 ) 45 46 func init() { 47 util.SetupTestLogging() 48 rand.Seed(time.Now().UnixNano()) 49 factory.InitFactories(nil) 50 } 51 52 func acceptAll(msg interface{}) bool { 53 return true 54 } 55 56 var ( 57 naiveSec = &naiveSecProvider{} 58 hmacKey = []byte{0, 0, 0} 59 ) 60 61 type naiveSecProvider struct { 62 } 63 64 func (*naiveSecProvider) ValidateIdentity(peerIdentity api.PeerIdentityType) error { 65 return nil 66 } 67 68 // GetPKIidOfCert returns the PKI-ID of a peer's identity 69 func (*naiveSecProvider) GetPKIidOfCert(peerIdentity api.PeerIdentityType) common.PKIidType { 70 return common.PKIidType(peerIdentity) 71 } 72 73 // VerifyBlock returns nil if the block is properly signed, 74 // else returns error 75 func (*naiveSecProvider) VerifyBlock(chainID common.ChainID, signedBlock []byte) error { 76 return nil 77 } 78 79 // Sign signs msg with this peer's signing key and outputs 80 // the signature if no error occurred. 81 func (*naiveSecProvider) Sign(msg []byte) ([]byte, error) { 82 mac := hmac.New(sha256.New, hmacKey) 83 mac.Write(msg) 84 return mac.Sum(nil), nil 85 } 86 87 // Verify checks that signature is a valid signature of message under a peer's verification key. 88 // If the verification succeeded, Verify returns nil meaning no error occurred. 89 // If peerCert is nil, then the signature is verified against this peer's verification key. 90 func (*naiveSecProvider) Verify(peerIdentity api.PeerIdentityType, signature, message []byte) error { 91 mac := hmac.New(sha256.New, hmacKey) 92 mac.Write(message) 93 expected := mac.Sum(nil) 94 if !bytes.Equal(signature, expected) { 95 return fmt.Errorf("Wrong certificate:%v, %v", signature, message) 96 } 97 return nil 98 } 99 100 // VerifyByChannel verifies a peer's signature on a message in the context 101 // of a specific channel 102 func (*naiveSecProvider) VerifyByChannel(_ common.ChainID, _ api.PeerIdentityType, _, _ []byte) error { 103 return nil 104 } 105 106 func newCommInstance(port int, sec api.MessageCryptoService) (Comm, error) { 107 endpoint := fmt.Sprintf("localhost:%d", port) 108 inst, err := NewCommInstanceWithServer(port, identity.NewIdentityMapper(sec), []byte(endpoint)) 109 return inst, err 110 } 111 112 func handshaker(endpoint string, comm Comm, t *testing.T, sigMutator func([]byte) []byte, pkiIDmutator func([]byte) []byte, mutualTLS bool) <-chan proto.ReceivedMessage { 113 c := &commImpl{} 114 err := generateCertificates("key.pem", "cert.pem") 115 assert.NoError(t, err, "%v", err) 116 defer os.Remove("cert.pem") 117 defer os.Remove("key.pem") 118 cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") 119 assert.NoError(t, err, "%v", err) 120 tlsCfg := &tls.Config{ 121 InsecureSkipVerify: true, 122 } 123 124 if mutualTLS { 125 tlsCfg.Certificates = []tls.Certificate{cert} 126 } 127 128 ta := credentials.NewTLS(tlsCfg) 129 130 acceptChan := comm.Accept(acceptAll) 131 conn, err := grpc.Dial("localhost:9611", grpc.WithTransportCredentials(&authCreds{tlsCreds: ta}), grpc.WithBlock(), grpc.WithTimeout(time.Second)) 132 assert.NoError(t, err, "%v", err) 133 if err != nil { 134 return nil 135 } 136 cl := proto.NewGossipClient(conn) 137 stream, err := cl.GossipStream(context.Background()) 138 assert.NoError(t, err, "%v", err) 139 if err != nil { 140 return nil 141 } // cert.Certificate[0] 142 143 var clientCertHash []byte 144 if mutualTLS { 145 clientCertHash = certHashFromRawCert(tlsCfg.Certificates[0].Certificate[0]) 146 } 147 148 pkiID := common.PKIidType(endpoint) 149 if pkiIDmutator != nil { 150 pkiID = common.PKIidType(pkiIDmutator([]byte(endpoint))) 151 } 152 assert.NoError(t, err, "%v", err) 153 msg := c.createConnectionMsg(pkiID, clientCertHash, []byte(endpoint), func(msg []byte) ([]byte, error) { 154 if !mutualTLS { 155 return msg, nil 156 } 157 mac := hmac.New(sha256.New, hmacKey) 158 mac.Write(msg) 159 return mac.Sum(nil), nil 160 }) 161 162 if sigMutator != nil { 163 msg.Envelope.Signature = sigMutator(msg.Envelope.Signature) 164 } 165 166 stream.Send(msg.Envelope) 167 envelope, err := stream.Recv() 168 assert.NoError(t, err, "%v", err) 169 msg, err = envelope.ToGossipMessage() 170 assert.NoError(t, err, "%v", err) 171 if sigMutator == nil { 172 hash := extractCertificateHashFromContext(stream.Context()) 173 expectedMsg := c.createConnectionMsg(common.PKIidType("localhost:9611"), hash, []byte("localhost:9611"), func(msg []byte) ([]byte, error) { 174 mac := hmac.New(sha256.New, hmacKey) 175 mac.Write(msg) 176 return mac.Sum(nil), nil 177 }) 178 if mutualTLS { 179 assert.Equal(t, expectedMsg.Envelope.Signature, msg.Envelope.Signature) 180 } 181 182 } 183 assert.Equal(t, []byte("localhost:9611"), msg.GetConn().PkiId) 184 msg2Send := createGossipMsg() 185 nonce := uint64(rand.Int()) 186 msg2Send.Nonce = nonce 187 go stream.Send(msg2Send.Envelope) 188 return acceptChan 189 } 190 191 func TestViperConfig(t *testing.T) { 192 viper.SetConfigName("core") 193 viper.SetEnvPrefix("CORE") 194 config.AddDevConfigPath(nil) 195 viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) 196 viper.AutomaticEnv() 197 err := viper.ReadInConfig() 198 if err != nil { // Handle errors reading the config file 199 panic(fmt.Errorf("fatal error config file: %s", err)) 200 } 201 202 assert.Equal(t, time.Duration(2)*time.Second, util.GetDurationOrDefault("peer.gossip.connTimeout", 0)) 203 assert.Equal(t, time.Duration(300)*time.Millisecond, util.GetDurationOrDefault("peer.gossip.dialTimeout", 0)) 204 assert.Equal(t, 20, util.GetIntOrDefault("peer.gossip.recvBuffSize", 0)) 205 assert.Equal(t, 20, util.GetIntOrDefault("peer.gossip.sendBuffSize", 0)) 206 } 207 208 func TestHandshake(t *testing.T) { 209 t.Parallel() 210 comm, _ := newCommInstance(9611, naiveSec) 211 defer comm.Stop() 212 213 acceptChan := handshaker("localhost:9610", comm, t, nil, nil, true) 214 time.Sleep(2 * time.Second) 215 assert.Equal(t, 1, len(acceptChan)) 216 msg := <-acceptChan 217 expectedPKIID := common.PKIidType("localhost:9610") 218 assert.Equal(t, expectedPKIID, msg.GetConnectionInfo().ID) 219 assert.Equal(t, api.PeerIdentityType("localhost:9610"), msg.GetConnectionInfo().Identity) 220 assert.NotNil(t, msg.GetConnectionInfo().Auth) 221 assert.True(t, msg.GetConnectionInfo().IsAuthenticated()) 222 sig, _ := (&naiveSecProvider{}).Sign(msg.GetConnectionInfo().Auth.SignedData) 223 assert.Equal(t, sig, msg.GetConnectionInfo().Auth.Signature) 224 // negative path, nothing should be read from the channel because the signature is wrong 225 mutateSig := func(b []byte) []byte { 226 if b[0] == 0 { 227 b[0] = 1 228 } else { 229 b[0] = 0 230 } 231 return b 232 } 233 acceptChan = handshaker("localhost:9612", comm, t, mutateSig, nil, true) 234 time.Sleep(time.Second) 235 assert.Equal(t, 0, len(acceptChan)) 236 237 // negative path, nothing should be read from the channel because the PKIid doesn't match the identity 238 mutatePKIID := func(b []byte) []byte { 239 return []byte("localhost:9650") 240 } 241 acceptChan = handshaker("localhost:9613", comm, t, nil, mutatePKIID, true) 242 time.Sleep(time.Second) 243 assert.Equal(t, 0, len(acceptChan)) 244 245 // Now we test for a handshake without mutual TLS 246 // The first time should fail 247 acceptChan = handshaker("localhost:9614", comm, t, nil, nil, false) 248 select { 249 case <-acceptChan: 250 assert.Fail(t, "Should not have successfully authenticated to remote peer") 251 case <-time.After(time.Second): 252 } 253 254 // And the second time should succeed 255 comm.(*commImpl).skipHandshake = true 256 acceptChan = handshaker("localhost:9615", comm, t, nil, nil, false) 257 select { 258 case <-acceptChan: 259 case <-time.After(time.Second * 10): 260 assert.Fail(t, "skipHandshake flag should have authorized the authentication") 261 } 262 } 263 264 func TestBasic(t *testing.T) { 265 t.Parallel() 266 comm1, _ := newCommInstance(2000, naiveSec) 267 comm2, _ := newCommInstance(3000, naiveSec) 268 comm1.(*commImpl).SetDialOpts() 269 comm2.(*commImpl).SetDialOpts() 270 defer comm1.Stop() 271 defer comm2.Stop() 272 m1 := comm1.Accept(acceptAll) 273 m2 := comm2.Accept(acceptAll) 274 out := make(chan uint64, 2) 275 reader := func(ch <-chan proto.ReceivedMessage) { 276 m := <-ch 277 out <- m.GetGossipMessage().Nonce 278 } 279 go reader(m1) 280 go reader(m2) 281 comm1.Send(createGossipMsg(), remotePeer(3000)) 282 time.Sleep(time.Second) 283 comm2.Send(createGossipMsg(), remotePeer(2000)) 284 waitForMessages(t, out, 2, "Didn't receive 2 messages") 285 } 286 287 func TestProdConstructor(t *testing.T) { 288 t.Parallel() 289 keyFileName := fmt.Sprintf("key.%d.pem", util.RandomUInt64()) 290 certFileName := fmt.Sprintf("cert.%d.pem", util.RandomUInt64()) 291 292 generateCertificates(keyFileName, certFileName) 293 cert, _ := tls.LoadX509KeyPair(certFileName, keyFileName) 294 os.Remove(keyFileName) 295 os.Remove(certFileName) 296 srv, lsnr, dialOpts, certHash := createGRPCLayer(20000) 297 defer srv.Stop() 298 defer lsnr.Close() 299 comm1, _ := NewCommInstance(srv, &cert, identity.NewIdentityMapper(naiveSec), []byte("localhost:20000"), dialOpts) 300 comm1.(*commImpl).selfCertHash = certHash 301 go srv.Serve(lsnr) 302 303 generateCertificates(keyFileName, certFileName) 304 cert, _ = tls.LoadX509KeyPair(certFileName, keyFileName) 305 os.Remove(keyFileName) 306 os.Remove(certFileName) 307 srv, lsnr, dialOpts, certHash = createGRPCLayer(30000) 308 defer srv.Stop() 309 defer lsnr.Close() 310 comm2, _ := NewCommInstance(srv, &cert, identity.NewIdentityMapper(naiveSec), []byte("localhost:30000"), dialOpts) 311 comm2.(*commImpl).selfCertHash = certHash 312 go srv.Serve(lsnr) 313 defer comm1.Stop() 314 defer comm2.Stop() 315 m1 := comm1.Accept(acceptAll) 316 m2 := comm2.Accept(acceptAll) 317 out := make(chan uint64, 2) 318 reader := func(ch <-chan proto.ReceivedMessage) { 319 m := <-ch 320 out <- m.GetGossipMessage().Nonce 321 } 322 go reader(m1) 323 go reader(m2) 324 comm1.Send(createGossipMsg(), remotePeer(30000)) 325 time.Sleep(time.Second) 326 comm2.Send(createGossipMsg(), remotePeer(20000)) 327 waitForMessages(t, out, 2, "Didn't receive 2 messages") 328 } 329 330 func TestGetConnectionInfo(t *testing.T) { 331 t.Parallel() 332 comm1, _ := newCommInstance(6000, naiveSec) 333 comm2, _ := newCommInstance(7000, naiveSec) 334 defer comm1.Stop() 335 defer comm2.Stop() 336 m1 := comm1.Accept(acceptAll) 337 comm2.Send(createGossipMsg(), remotePeer(6000)) 338 select { 339 case <-time.After(time.Second * 10): 340 t.Fatal("Didn't receive a message in time") 341 case msg := <-m1: 342 assert.Equal(t, comm2.GetPKIid(), msg.GetConnectionInfo().ID) 343 assert.NotNil(t, msg.GetSourceEnvelope()) 344 } 345 } 346 347 func TestCloseConn(t *testing.T) { 348 t.Parallel() 349 comm1, _ := newCommInstance(1611, naiveSec) 350 defer comm1.Stop() 351 acceptChan := comm1.Accept(acceptAll) 352 353 err := generateCertificates("key.pem", "cert.pem") 354 assert.NoError(t, err, "%v", err) 355 defer os.Remove("cert.pem") 356 defer os.Remove("key.pem") 357 cert, err := tls.LoadX509KeyPair("cert.pem", "key.pem") 358 assert.NoError(t, err, "%v", err) 359 tlsCfg := &tls.Config{ 360 InsecureSkipVerify: true, 361 Certificates: []tls.Certificate{cert}, 362 } 363 ta := credentials.NewTLS(tlsCfg) 364 365 conn, err := grpc.Dial("localhost:1611", grpc.WithTransportCredentials(&authCreds{tlsCreds: ta}), grpc.WithBlock(), grpc.WithTimeout(time.Second)) 366 assert.NoError(t, err, "%v", err) 367 cl := proto.NewGossipClient(conn) 368 stream, err := cl.GossipStream(context.Background()) 369 assert.NoError(t, err, "%v", err) 370 c := &commImpl{} 371 hash := certHashFromRawCert(tlsCfg.Certificates[0].Certificate[0]) 372 connMsg := c.createConnectionMsg(common.PKIidType("pkiID"), hash, api.PeerIdentityType("pkiID"), func(msg []byte) ([]byte, error) { 373 mac := hmac.New(sha256.New, hmacKey) 374 mac.Write(msg) 375 return mac.Sum(nil), nil 376 }) 377 assert.NoError(t, stream.Send(connMsg.Envelope)) 378 stream.Send(createGossipMsg().Envelope) 379 select { 380 case <-acceptChan: 381 case <-time.After(time.Second): 382 assert.Fail(t, "Didn't receive a message within a timely period") 383 } 384 comm1.CloseConn(&RemotePeer{PKIID: common.PKIidType("pkiID")}) 385 time.Sleep(time.Second * 10) 386 gotErr := false 387 msg2Send := createGossipMsg() 388 msg2Send.GetDataMsg().Payload = &proto.Payload{ 389 Data: make([]byte, 1024*1024), 390 } 391 msg2Send.NoopSign() 392 for i := 0; i < defRecvBuffSize; i++ { 393 err := stream.Send(msg2Send.Envelope) 394 if err != nil { 395 gotErr = true 396 break 397 } 398 } 399 assert.True(t, gotErr, "Should have failed because connection is closed") 400 } 401 402 func TestParallelSend(t *testing.T) { 403 t.Parallel() 404 comm1, _ := newCommInstance(5411, naiveSec) 405 comm2, _ := newCommInstance(5412, naiveSec) 406 defer comm1.Stop() 407 defer comm2.Stop() 408 409 messages2Send := util.GetIntOrDefault("peer.gossip.recvBuffSize", defRecvBuffSize) 410 411 wg := sync.WaitGroup{} 412 go func() { 413 for i := 0; i < messages2Send; i++ { 414 wg.Add(1) 415 emptyMsg := createGossipMsg() 416 go func() { 417 defer wg.Done() 418 comm1.Send(emptyMsg, remotePeer(5412)) 419 }() 420 } 421 wg.Wait() 422 }() 423 424 c := 0 425 waiting := true 426 ticker := time.NewTicker(time.Duration(5) * time.Second) 427 ch := comm2.Accept(acceptAll) 428 for waiting { 429 select { 430 case <-ch: 431 c++ 432 if c == messages2Send { 433 waiting = false 434 } 435 case <-ticker.C: 436 waiting = false 437 } 438 } 439 assert.Equal(t, messages2Send, c) 440 } 441 442 func TestResponses(t *testing.T) { 443 t.Parallel() 444 comm1, _ := newCommInstance(8611, naiveSec) 445 comm2, _ := newCommInstance(8612, naiveSec) 446 447 defer comm1.Stop() 448 defer comm2.Stop() 449 450 msg := createGossipMsg() 451 go func() { 452 inChan := comm1.Accept(acceptAll) 453 for m := range inChan { 454 reply := createGossipMsg() 455 reply.Nonce = m.GetGossipMessage().Nonce + 1 456 m.Respond(reply.GossipMessage) 457 } 458 }() 459 expectedNOnce := uint64(msg.Nonce + 1) 460 responsesFromComm1 := comm2.Accept(acceptAll) 461 462 ticker := time.NewTicker(time.Duration(6000) * time.Millisecond) 463 comm2.Send(msg, remotePeer(8611)) 464 time.Sleep(time.Duration(100) * time.Millisecond) 465 466 select { 467 case <-ticker.C: 468 assert.Fail(t, "Haven't got response from comm1 within a timely manner") 469 break 470 case resp := <-responsesFromComm1: 471 ticker.Stop() 472 assert.Equal(t, expectedNOnce, resp.GetGossipMessage().Nonce) 473 break 474 } 475 } 476 477 func TestAccept(t *testing.T) { 478 t.Parallel() 479 comm1, _ := newCommInstance(7611, naiveSec) 480 comm2, _ := newCommInstance(7612, naiveSec) 481 482 evenNONCESelector := func(m interface{}) bool { 483 return m.(proto.ReceivedMessage).GetGossipMessage().Nonce%2 == 0 484 } 485 486 oddNONCESelector := func(m interface{}) bool { 487 return m.(proto.ReceivedMessage).GetGossipMessage().Nonce%2 != 0 488 } 489 490 evenNONCES := comm1.Accept(evenNONCESelector) 491 oddNONCES := comm1.Accept(oddNONCESelector) 492 493 var evenResults []uint64 494 var oddResults []uint64 495 496 out := make(chan uint64, util.GetIntOrDefault("peer.gossip.recvBuffSize", defRecvBuffSize)) 497 sem := make(chan struct{}, 0) 498 499 readIntoSlice := func(a *[]uint64, ch <-chan proto.ReceivedMessage) { 500 for m := range ch { 501 *a = append(*a, m.GetGossipMessage().Nonce) 502 out <- m.GetGossipMessage().Nonce 503 } 504 sem <- struct{}{} 505 } 506 507 go readIntoSlice(&evenResults, evenNONCES) 508 go readIntoSlice(&oddResults, oddNONCES) 509 510 for i := 0; i < util.GetIntOrDefault("peer.gossip.recvBuffSize", defRecvBuffSize); i++ { 511 comm2.Send(createGossipMsg(), remotePeer(7611)) 512 } 513 514 waitForMessages(t, out, util.GetIntOrDefault("peer.gossip.recvBuffSize", defRecvBuffSize), "Didn't receive all messages sent") 515 516 comm1.Stop() 517 comm2.Stop() 518 519 <-sem 520 <-sem 521 522 assert.NotEmpty(t, evenResults) 523 assert.NotEmpty(t, oddResults) 524 525 remainderPredicate := func(a []uint64, rem uint64) { 526 for _, n := range a { 527 assert.Equal(t, n%2, rem) 528 } 529 } 530 531 remainderPredicate(evenResults, 0) 532 remainderPredicate(oddResults, 1) 533 } 534 535 func TestReConnections(t *testing.T) { 536 t.Parallel() 537 comm1, _ := newCommInstance(3611, naiveSec) 538 comm2, _ := newCommInstance(3612, naiveSec) 539 540 reader := func(out chan uint64, in <-chan proto.ReceivedMessage) { 541 for { 542 msg := <-in 543 if msg == nil { 544 return 545 } 546 out <- msg.GetGossipMessage().Nonce 547 } 548 } 549 550 out1 := make(chan uint64, 10) 551 out2 := make(chan uint64, 10) 552 553 go reader(out1, comm1.Accept(acceptAll)) 554 go reader(out2, comm2.Accept(acceptAll)) 555 556 // comm1 connects to comm2 557 comm1.Send(createGossipMsg(), remotePeer(3612)) 558 waitForMessages(t, out2, 1, "Comm2 didn't receive a message from comm1 in a timely manner") 559 time.Sleep(time.Second) 560 // comm2 sends to comm1 561 comm2.Send(createGossipMsg(), remotePeer(3611)) 562 waitForMessages(t, out1, 1, "Comm1 didn't receive a message from comm2 in a timely manner") 563 564 comm1.Stop() 565 comm1, _ = newCommInstance(3611, naiveSec) 566 time.Sleep(time.Second) 567 out1 = make(chan uint64, 1) 568 go reader(out1, comm1.Accept(acceptAll)) 569 comm2.Send(createGossipMsg(), remotePeer(3611)) 570 waitForMessages(t, out1, 1, "Comm1 didn't receive a message from comm2 in a timely manner") 571 } 572 573 func TestProbe(t *testing.T) { 574 t.Parallel() 575 comm1, _ := newCommInstance(6611, naiveSec) 576 defer comm1.Stop() 577 comm2, _ := newCommInstance(6612, naiveSec) 578 time.Sleep(time.Duration(1) * time.Second) 579 assert.NoError(t, comm1.Probe(remotePeer(6612))) 580 _, err := comm1.Handshake(remotePeer(6612)) 581 assert.NoError(t, err) 582 assert.Error(t, comm1.Probe(remotePeer(9012))) 583 _, err = comm1.Handshake(remotePeer(9012)) 584 assert.Error(t, err) 585 comm2.Stop() 586 time.Sleep(time.Second) 587 assert.Error(t, comm1.Probe(remotePeer(6612))) 588 _, err = comm1.Handshake(remotePeer(6612)) 589 assert.Error(t, err) 590 comm2, _ = newCommInstance(6612, naiveSec) 591 defer comm2.Stop() 592 time.Sleep(time.Duration(1) * time.Second) 593 assert.NoError(t, comm2.Probe(remotePeer(6611))) 594 _, err = comm2.Handshake(remotePeer(6611)) 595 assert.NoError(t, err) 596 assert.NoError(t, comm1.Probe(remotePeer(6612))) 597 _, err = comm1.Handshake(remotePeer(6612)) 598 assert.NoError(t, err) 599 // Now try a deep probe with an expected PKI-ID that doesn't match 600 wrongRemotePeer := remotePeer(6612) 601 if wrongRemotePeer.PKIID[0] == 0 { 602 wrongRemotePeer.PKIID[0] = 1 603 } else { 604 wrongRemotePeer.PKIID[0] = 0 605 } 606 _, err = comm1.Handshake(wrongRemotePeer) 607 assert.Error(t, err) 608 // Try a deep probe with a nil PKI-ID 609 id, err := comm1.Handshake(&RemotePeer{Endpoint: "localhost:6612"}) 610 assert.NoError(t, err) 611 assert.Equal(t, api.PeerIdentityType("localhost:6612"), id) 612 } 613 614 func TestPresumedDead(t *testing.T) { 615 t.Parallel() 616 comm1, _ := newCommInstance(4611, naiveSec) 617 comm2, _ := newCommInstance(4612, naiveSec) 618 go comm1.Send(createGossipMsg(), remotePeer(4612)) 619 <-comm2.Accept(acceptAll) 620 comm2.Stop() 621 go func() { 622 for i := 0; i < 5; i++ { 623 comm1.Send(createGossipMsg(), remotePeer(4612)) 624 time.Sleep(time.Millisecond * 200) 625 } 626 }() 627 628 ticker := time.NewTicker(time.Second * time.Duration(3)) 629 select { 630 case <-ticker.C: 631 assert.Fail(t, "Didn't get a presumed dead message within a timely manner") 632 break 633 case <-comm1.PresumedDead(): 634 ticker.Stop() 635 break 636 } 637 } 638 639 func createGossipMsg() *proto.SignedGossipMessage { 640 return (&proto.GossipMessage{ 641 Tag: proto.GossipMessage_EMPTY, 642 Nonce: uint64(rand.Int()), 643 Content: &proto.GossipMessage_DataMsg{ 644 DataMsg: &proto.DataMessage{}, 645 }, 646 }).NoopSign() 647 } 648 649 func remotePeer(port int) *RemotePeer { 650 endpoint := fmt.Sprintf("localhost:%d", port) 651 return &RemotePeer{Endpoint: endpoint, PKIID: []byte(endpoint)} 652 } 653 654 func waitForMessages(t *testing.T, msgChan chan uint64, count int, errMsg string) { 655 c := 0 656 waiting := true 657 ticker := time.NewTicker(time.Duration(10) * time.Second) 658 for waiting { 659 select { 660 case <-msgChan: 661 c++ 662 if c == count { 663 waiting = false 664 } 665 case <-ticker.C: 666 waiting = false 667 } 668 } 669 assert.Equal(t, count, c, errMsg) 670 } 671 672 func TestMain(m *testing.M) { 673 SetDialTimeout(time.Duration(300) * time.Millisecond) 674 675 ret := m.Run() 676 os.Exit(ret) 677 }