github.com/ethersphere/bee/v2@v2.2.0/pkg/p2p/streamtest/streamtest_test.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package streamtest_test 6 7 import ( 8 "bufio" 9 "context" 10 "errors" 11 "fmt" 12 "io" 13 "strings" 14 "testing" 15 "time" 16 17 "github.com/ethersphere/bee/v2/pkg/p2p" 18 "github.com/ethersphere/bee/v2/pkg/p2p/streamtest" 19 "github.com/ethersphere/bee/v2/pkg/swarm" 20 ma "github.com/multiformats/go-multiaddr" 21 ) 22 23 func TestRecorder(t *testing.T) { 24 t.Parallel() 25 26 var answers = map[string]string{ 27 "What is your name?": "Sir Lancelot of Camelot", 28 "What is your quest?": "To seek the Holy Grail.", 29 "What is your favorite color?": "Blue.", 30 "What is the air-speed velocity of an unladen swallow?": "What do you mean? An African or European swallow?", 31 } 32 33 recorder := streamtest.New( 34 streamtest.WithProtocols( 35 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 36 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 37 for { 38 q, err := rw.ReadString('\n') 39 if err != nil { 40 if errors.Is(err, io.EOF) { 41 break 42 } 43 return fmt.Errorf("read: %w", err) 44 } 45 q = strings.TrimRight(q, "\n") 46 if _, err = rw.WriteString(answers[q] + "\n"); err != nil { 47 return fmt.Errorf("write: %w", err) 48 } 49 if err := rw.Flush(); err != nil { 50 return fmt.Errorf("flush: %w", err) 51 } 52 } 53 return nil 54 }), 55 ), 56 ) 57 58 ask := func(ctx context.Context, s p2p.Streamer, address swarm.Address, questions ...string) (answers []string, err error) { 59 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 60 if err != nil { 61 return nil, fmt.Errorf("new stream: %w", err) 62 } 63 defer stream.Close() 64 65 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 66 67 for _, q := range questions { 68 if _, err := rw.WriteString(q + "\n"); err != nil { 69 return nil, fmt.Errorf("write: %w", err) 70 } 71 if err := rw.Flush(); err != nil { 72 return nil, fmt.Errorf("flush: %w", err) 73 } 74 75 a, err := rw.ReadString('\n') 76 if err != nil { 77 return nil, fmt.Errorf("read: %w", err) 78 } 79 a = strings.TrimRight(a, "\n") 80 answers = append(answers, a) 81 } 82 return answers, nil 83 } 84 85 questions := []string{"What is your name?", "What is your quest?", "What is your favorite color?"} 86 87 aa, err := ask(context.Background(), recorder, swarm.ZeroAddress, questions...) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 for i, q := range questions { 93 if aa[i] != answers[q] { 94 t.Errorf("got answer %q for question %q, want %q", aa[i], q, answers[q]) 95 } 96 } 97 98 _, err = recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, "invalid stream name") 99 if !errors.Is(err, streamtest.ErrRecordsNotFound) { 100 t.Errorf("got error %v, want %v", err, streamtest.ErrRecordsNotFound) 101 } 102 103 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 testRecords(t, records, [][2]string{ 109 { 110 "What is your name?\nWhat is your quest?\nWhat is your favorite color?\n", 111 "Sir Lancelot of Camelot\nTo seek the Holy Grail.\nBlue.\n", 112 }, 113 }, nil) 114 } 115 116 func TestRecorder_errStreamNotSupported(t *testing.T) { 117 t.Parallel() 118 119 r := streamtest.New() 120 121 _, err := r.NewStream(context.Background(), swarm.ZeroAddress, nil, "testing", "messages", "1.0.1") 122 if !errors.Is(err, streamtest.ErrStreamNotSupported) { 123 t.Fatalf("got error %v, want %v", err, streamtest.ErrStreamNotSupported) 124 } 125 } 126 127 func TestRecorder_fullcloseWithRemoteClose(t *testing.T) { 128 t.Parallel() 129 130 recorder := streamtest.New( 131 streamtest.WithProtocols( 132 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 133 defer stream.Close() 134 _, err := bufio.NewReader(stream).ReadString('\n') 135 return err 136 }), 137 ), 138 ) 139 140 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 141 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 142 if err != nil { 143 return fmt.Errorf("new stream: %w", err) 144 } 145 146 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 147 if _, err := rw.WriteString("message\n"); err != nil { 148 return fmt.Errorf("write: %w", err) 149 } 150 if err := rw.Flush(); err != nil { 151 return fmt.Errorf("flush: %w", err) 152 } 153 154 return stream.FullClose() 155 } 156 157 err := request(context.Background(), recorder, swarm.ZeroAddress) 158 if err != nil { 159 t.Fatal(err) 160 } 161 162 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 163 if err != nil { 164 t.Fatal(err) 165 } 166 167 testRecords(t, records, [][2]string{ 168 { 169 "message\n", 170 }, 171 }, nil) 172 } 173 174 func TestRecorder_fullcloseWithoutRemoteClose(t *testing.T) { 175 t.Parallel() 176 177 recorder := streamtest.New( 178 streamtest.WithProtocols( 179 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 180 // don't close the stream here 181 // just try to read the message that it terminated with 182 // a new line character 183 _, err := bufio.NewReader(stream).ReadString('\n') 184 return err 185 }), 186 ), 187 ) 188 189 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 190 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 191 if err != nil { 192 return fmt.Errorf("new stream: %w", err) 193 } 194 195 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 196 if _, err := rw.WriteString("message\n"); err != nil { 197 return fmt.Errorf("write: %w", err) 198 } 199 if err := rw.Flush(); err != nil { 200 return fmt.Errorf("flush: %w", err) 201 } 202 203 return stream.FullClose() 204 } 205 206 err := request(context.Background(), recorder, swarm.ZeroAddress) 207 if err != nil { 208 t.Fatal(err) 209 } 210 211 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 212 if err != nil { 213 t.Fatal(err) 214 } 215 216 testRecords(t, records, [][2]string{ 217 { 218 "message\n", 219 }, 220 }, nil) 221 } 222 223 func TestRecorder_multipleParallelFullCloseAndClose(t *testing.T) { 224 t.Parallel() 225 226 recorder := streamtest.New( 227 streamtest.WithProtocols( 228 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 229 if _, err := bufio.NewReader(stream).ReadString('\n'); err != nil { 230 return err 231 } 232 233 return stream.FullClose() 234 }), 235 ), 236 ) 237 238 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 239 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 240 if err != nil { 241 return fmt.Errorf("new stream: %w", err) 242 } 243 244 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 245 if _, err := rw.WriteString("message\n"); err != nil { 246 return fmt.Errorf("write: %w", err) 247 } 248 if err := rw.Flush(); err != nil { 249 return fmt.Errorf("flush: %w", err) 250 } 251 252 return stream.FullClose() 253 } 254 255 err := request(context.Background(), recorder, swarm.ZeroAddress) 256 if err != nil { 257 t.Fatal(err) 258 } 259 260 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 261 if err != nil { 262 t.Fatal(err) 263 } 264 265 testRecords(t, records, [][2]string{ 266 { 267 "message\n", 268 }, 269 }, nil) 270 } 271 272 func TestRecorder_closeAfterPartialWrite(t *testing.T) { 273 t.Parallel() 274 275 recorder := streamtest.New( 276 streamtest.WithProtocols( 277 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 278 // just try to read the message that it terminated with 279 // a new line character 280 _, err := bufio.NewReader(stream).ReadString('\n') 281 return err 282 }), 283 ), 284 ) 285 286 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 287 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 288 if err != nil { 289 return fmt.Errorf("new stream: %w", err) 290 } 291 defer stream.Close() 292 293 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 294 295 // write a message, but do not write a new line character for handler to 296 // know that it is complete 297 if _, err := rw.WriteString("unterminated message"); err != nil { 298 return fmt.Errorf("write: %w", err) 299 } 300 if err := rw.Flush(); err != nil { 301 return fmt.Errorf("flush: %w", err) 302 } 303 304 // deliberately close the stream before the new line character is 305 // written to the stream 306 if err := stream.Close(); err != nil { 307 return err 308 } 309 310 // stream should be closed and write should return err 311 if _, err := rw.WriteString("expect err message"); err != nil { 312 return fmt.Errorf("write: %w", err) 313 } 314 315 if err := rw.Flush(); err == nil { 316 return fmt.Errorf("expected err") 317 } 318 319 return nil 320 } 321 322 err := request(context.Background(), recorder, swarm.ZeroAddress) 323 if err != nil { 324 t.Fatal(err) 325 } 326 327 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 328 if err != nil { 329 t.Fatal(err) 330 } 331 332 testRecords(t, records, [][2]string{ 333 { 334 "unterminated message", 335 "", 336 }, 337 }, nil) 338 } 339 340 func TestRecorder_resetAfterPartialWrite(t *testing.T) { 341 t.Parallel() 342 343 recorder := streamtest.New( 344 streamtest.WithProtocols( 345 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 346 // just try to read the message that it terminated with 347 // a new line character 348 _, err := bufio.NewReader(stream).ReadString('\n') 349 return err 350 }), 351 ), 352 ) 353 354 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 355 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 356 if err != nil { 357 return fmt.Errorf("new stream: %w", err) 358 } 359 defer stream.Close() 360 361 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 362 363 // write a message, but do not write a new line character for handler to 364 // know that it is complete 365 if _, err := rw.WriteString("unterminated message"); err != nil { 366 return fmt.Errorf("write: %w", err) 367 } 368 if err := rw.Flush(); err != nil { 369 return fmt.Errorf("flush: %w", err) 370 } 371 372 // deliberately reset the stream before the new line character is 373 // written to the stream 374 if err := stream.Reset(); err != nil { 375 return err 376 } 377 378 // stream should be closed and read should return streamtest.ErrStreamClosed 379 if _, err := rw.ReadString('\n'); !errors.Is(err, streamtest.ErrStreamClosed) { 380 return fmt.Errorf("got error %w, want %w", err, streamtest.ErrStreamClosed) 381 } 382 383 return nil 384 } 385 386 err := request(context.Background(), recorder, swarm.ZeroAddress) 387 if err != nil { 388 t.Fatal(err) 389 } 390 391 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 392 if err != nil { 393 t.Fatal(err) 394 } 395 396 testRecords(t, records, [][2]string{ 397 { 398 "unterminated message", 399 "", 400 }, 401 }, nil) 402 } 403 404 func TestRecorder_withMiddlewares(t *testing.T) { 405 t.Parallel() 406 407 recorder := streamtest.New( 408 streamtest.WithProtocols( 409 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 410 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 411 412 if _, err := rw.ReadString('\n'); err != nil { 413 return err 414 } 415 416 if _, err := rw.WriteString("handler, "); err != nil { 417 return err 418 } 419 if err := rw.Flush(); err != nil { 420 return err 421 } 422 423 return nil 424 }), 425 ), 426 streamtest.WithMiddlewares( 427 func(h p2p.HandlerFunc) p2p.HandlerFunc { 428 return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error { 429 if err := h(ctx, peer, stream); err != nil { 430 return err 431 } 432 // close stream after all previous middlewares wrote to it 433 // so that the receiving peer can get all the post messages 434 return stream.Close() 435 } 436 }, 437 func(h p2p.HandlerFunc) p2p.HandlerFunc { 438 return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error { 439 if _, err := stream.Write([]byte("pre 1, ")); err != nil { 440 return err 441 } 442 if err := h(ctx, peer, stream); err != nil { 443 return err 444 } 445 if _, err := stream.Write([]byte("post 1, ")); err != nil { 446 return err 447 } 448 return nil 449 } 450 }, 451 func(h p2p.HandlerFunc) p2p.HandlerFunc { 452 return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error { 453 if _, err := stream.Write([]byte("pre 2, ")); err != nil { 454 return err 455 } 456 if err := h(ctx, peer, stream); err != nil { 457 return err 458 } 459 if _, err := stream.Write([]byte("post 2, ")); err != nil { 460 return err 461 } 462 return nil 463 } 464 }, 465 ), 466 streamtest.WithMiddlewares( 467 func(h p2p.HandlerFunc) p2p.HandlerFunc { 468 return func(ctx context.Context, peer p2p.Peer, stream p2p.Stream) error { 469 if _, err := stream.Write([]byte("pre 3, ")); err != nil { 470 return err 471 } 472 if err := h(ctx, peer, stream); err != nil { 473 return err 474 } 475 if _, err := stream.Write([]byte("post 3, ")); err != nil { 476 return err 477 } 478 return nil 479 } 480 }, 481 ), 482 ) 483 484 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) error { 485 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 486 if err != nil { 487 return fmt.Errorf("new stream: %w", err) 488 } 489 defer stream.Close() 490 491 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 492 493 if _, err := rw.WriteString("test\n"); err != nil { 494 return err 495 } 496 if err := rw.Flush(); err != nil { 497 return err 498 } 499 _, err = io.ReadAll(rw) 500 return err 501 } 502 503 err := request(context.Background(), recorder, swarm.ZeroAddress) 504 if err != nil { 505 t.Fatal(err) 506 } 507 508 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 509 if err != nil { 510 t.Fatal(err) 511 } 512 513 testRecords(t, records, [][2]string{ 514 { 515 "test\n", 516 "pre 1, pre 2, pre 3, handler, post 3, post 2, post 1, ", 517 }, 518 }, nil) 519 } 520 521 func TestRecorder_recordErr(t *testing.T) { 522 t.Parallel() 523 524 testErr := errors.New("test error") 525 526 recorder := streamtest.New( 527 streamtest.WithProtocols( 528 newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 529 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 530 defer stream.Close() 531 532 if _, err := rw.ReadString('\n'); err != nil { 533 return err 534 } 535 536 if _, err := rw.WriteString("resp\n"); err != nil { 537 return err 538 } 539 if err := rw.Flush(); err != nil { 540 return err 541 } 542 543 return testErr 544 }), 545 ), 546 ) 547 548 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) (err error) { 549 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 550 if err != nil { 551 return fmt.Errorf("new stream: %w", err) 552 } 553 defer stream.Close() 554 555 if _, err = stream.Write([]byte("req\n")); err != nil { 556 return err 557 } 558 559 _, err = io.ReadAll(stream) 560 return err 561 } 562 563 err := request(context.Background(), recorder, swarm.ZeroAddress) 564 if err != nil { 565 t.Fatal(err) 566 } 567 568 records, err := recorder.Records(swarm.ZeroAddress, testProtocolName, testProtocolVersion, testStreamName) 569 if err != nil { 570 t.Fatal(err) 571 } 572 573 testRecords(t, records, [][2]string{ 574 { 575 "req\n", 576 "resp\n", 577 }, 578 }, testErr) 579 } 580 581 func TestRecorder_withPeerProtocols(t *testing.T) { 582 t.Parallel() 583 584 peer1 := swarm.MustParseHexAddress("1000000000000000000000000000000000000000000000000000000000000000") 585 peer2 := swarm.MustParseHexAddress("2000000000000000000000000000000000000000000000000000000000000000") 586 recorder := streamtest.New( 587 streamtest.WithPeerProtocols(map[string]p2p.ProtocolSpec{ 588 peer1.String(): newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 589 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 590 591 if _, err := rw.ReadString('\n'); err != nil { 592 return err 593 } 594 if _, err := rw.WriteString("handler 1\n"); err != nil { 595 return err 596 } 597 if err := rw.Flush(); err != nil { 598 return err 599 } 600 601 return nil 602 }), 603 peer2.String(): newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 604 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 605 606 if _, err := rw.ReadString('\n'); err != nil { 607 return err 608 } 609 if _, err := rw.WriteString("handler 2\n"); err != nil { 610 return err 611 } 612 if err := rw.Flush(); err != nil { 613 return err 614 } 615 616 return nil 617 }), 618 }), 619 ) 620 621 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) error { 622 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 623 if err != nil { 624 return fmt.Errorf("new stream: %w", err) 625 } 626 defer stream.Close() 627 628 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 629 630 if _, err := rw.WriteString("req\n"); err != nil { 631 return err 632 } 633 if err := rw.Flush(); err != nil { 634 return err 635 } 636 _, err = rw.ReadString('\n') 637 return err 638 } 639 640 err := request(context.Background(), recorder, peer1) 641 if err != nil { 642 t.Fatal(err) 643 } 644 645 records, err := recorder.Records(peer1, testProtocolName, testProtocolVersion, testStreamName) 646 if err != nil { 647 t.Fatal(err) 648 } 649 650 testRecords(t, records, [][2]string{ 651 { 652 "req\n", 653 "handler 1\n", 654 }, 655 }, nil) 656 657 err = request(context.Background(), recorder, peer2) 658 if err != nil { 659 t.Fatal(err) 660 } 661 662 records, err = recorder.Records(peer2, testProtocolName, testProtocolVersion, testStreamName) 663 if err != nil { 664 t.Fatal(err) 665 } 666 667 testRecords(t, records, [][2]string{ 668 { 669 "req\n", 670 "handler 2\n", 671 }, 672 }, nil) 673 } 674 675 func TestRecorder_withStreamError(t *testing.T) { 676 t.Parallel() 677 678 peer1 := swarm.MustParseHexAddress("1000000000000000000000000000000000000000000000000000000000000000") 679 peer2 := swarm.MustParseHexAddress("2000000000000000000000000000000000000000000000000000000000000000") 680 testErr := errors.New("dummy stream error") 681 recorder := streamtest.New( 682 streamtest.WithPeerProtocols(map[string]p2p.ProtocolSpec{ 683 peer1.String(): newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 684 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 685 686 if _, err := rw.ReadString('\n'); err != nil { 687 return err 688 } 689 if _, err := rw.WriteString("handler 1\n"); err != nil { 690 return err 691 } 692 if err := rw.Flush(); err != nil { 693 return err 694 } 695 696 return nil 697 }), 698 peer2.String(): newTestProtocol(func(_ context.Context, peer p2p.Peer, stream p2p.Stream) error { 699 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 700 701 if _, err := rw.ReadString('\n'); err != nil { 702 return err 703 } 704 if _, err := rw.WriteString("handler 2\n"); err != nil { 705 return err 706 } 707 if err := rw.Flush(); err != nil { 708 return err 709 } 710 711 return nil 712 }), 713 }), 714 streamtest.WithStreamError(func(addr swarm.Address, _, _, _ string) error { 715 if addr.String() == peer1.String() { 716 return testErr 717 } 718 return nil 719 }), 720 ) 721 722 request := func(ctx context.Context, s p2p.Streamer, address swarm.Address) error { 723 stream, err := s.NewStream(ctx, address, nil, testProtocolName, testProtocolVersion, testStreamName) 724 if err != nil { 725 return fmt.Errorf("new stream: %w", err) 726 } 727 defer stream.Close() 728 729 rw := bufio.NewReadWriter(bufio.NewReader(stream), bufio.NewWriter(stream)) 730 731 if _, err := rw.WriteString("req\n"); err != nil { 732 return err 733 } 734 if err := rw.Flush(); err != nil { 735 return err 736 } 737 _, err = rw.ReadString('\n') 738 return err 739 } 740 741 err := request(context.Background(), recorder, peer1) 742 if err == nil { 743 t.Fatal("expected error on NewStream for peer") 744 } 745 746 err = request(context.Background(), recorder, peer2) 747 if err != nil { 748 t.Fatal(err) 749 } 750 751 records, err := recorder.Records(peer2, testProtocolName, testProtocolVersion, testStreamName) 752 if err != nil { 753 t.Fatal(err) 754 } 755 756 testRecords(t, records, [][2]string{ 757 { 758 "req\n", 759 "handler 2\n", 760 }, 761 }, nil) 762 } 763 764 func TestRecorder_ping(t *testing.T) { 765 t.Parallel() 766 767 testAddr, _ := ma.NewMultiaddr("/ip4/0.0.0.0/tcp/0") 768 769 rec := streamtest.New() 770 771 _, err := rec.Ping(context.Background(), testAddr) 772 if err != nil { 773 t.Fatalf("unable to ping err: %s", err.Error()) 774 } 775 776 rec2 := streamtest.New( 777 streamtest.WithPingErr(func(_ ma.Multiaddr) (rtt time.Duration, err error) { 778 return rtt, errors.New("fail") 779 }), 780 ) 781 782 _, err = rec2.Ping(context.Background(), testAddr) 783 if err == nil { 784 t.Fatal("expected ping err") 785 } 786 } 787 788 const ( 789 testProtocolName = "testing" 790 testProtocolVersion = "1.0.1" 791 testStreamName = "messages" 792 ) 793 794 func newTestProtocol(h p2p.HandlerFunc) p2p.ProtocolSpec { 795 return p2p.ProtocolSpec{ 796 Name: testProtocolName, 797 Version: testProtocolVersion, 798 StreamSpecs: []p2p.StreamSpec{ 799 { 800 Name: testStreamName, 801 Handler: h, 802 }, 803 }, 804 } 805 } 806 807 func testRecords(t *testing.T, records []*streamtest.Record, want [][2]string, wantErr error) { 808 t.Helper() 809 810 lr := len(records) 811 lw := len(want) 812 if lr != lw { 813 t.Fatalf("got %v records, want %v", lr, lw) 814 } 815 816 for i := 0; i < lr; i++ { 817 record := records[i] 818 819 if err := record.Err(); !errors.Is(err, wantErr) { 820 t.Fatalf("got error from record %v, want %v", err, wantErr) 821 } 822 823 w := want[i] 824 825 gotIn := string(record.In()) 826 if gotIn != w[0] { 827 t.Errorf("got stream in %q, want %q", gotIn, w[0]) 828 } 829 830 gotOut := string(record.Out()) 831 if gotOut != w[1] { 832 t.Errorf("got stream out %q, want %q", gotOut, w[1]) 833 } 834 } 835 }