udp_control_test.go 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package bwtest
  2. import (
  3. "context"
  4. "testing"
  5. "time"
  6. )
  7. func TestUDPPacerUsesDeliveryFeedback(t *testing.T) {
  8. p := newUDPPacer(0)
  9. initial := p.rate
  10. now := p.started.Add(2 * time.Second)
  11. p.observe(10000, now)
  12. if p.rate >= initial {
  13. t.Fatal("automatic rate did not fall after severe loss")
  14. }
  15. lower := p.rate
  16. p.observe(10000+lower/8, now.Add(time.Second))
  17. if p.rate <= lower {
  18. t.Fatal("automatic rate did not grow after successful delivery")
  19. }
  20. fixed := newUDPPacer(1234567)
  21. fixed.observe(0, fixed.started.Add(2*time.Second))
  22. if fixed.rate != 1234567 {
  23. t.Fatal("receiver feedback changed explicit rate limit")
  24. }
  25. }
  26. func TestUDPPacerCancellation(t *testing.T) {
  27. p := newUDPPacer(1)
  28. ctx, cancel := context.WithTimeout(context.Background(), 30*time.Millisecond)
  29. defer cancel()
  30. if p.wait(ctx, 1472) {
  31. t.Fatal("rate limiter ignored cancellation")
  32. }
  33. }
  34. func TestUDPTrackerStreamsReorderingDuplicates(t *testing.T) {
  35. var tracker udpTracker
  36. for _, v := range []struct {
  37. stream uint8
  38. seq uint64
  39. lost int64
  40. }{{0, 1, 0}, {1, 1, 0}, {0, 3, 1}, {1, 2, 1}, {0, 2, 0}, {0, 4, 0}} {
  41. ok, lost := tracker.accept(v.stream, v.seq)
  42. if !ok || lost != v.lost {
  43. t.Fatalf("stream %d seq %d: accepted=%v lost=%d want=%d", v.stream, v.seq, ok, lost, v.lost)
  44. }
  45. }
  46. if ok, lost := tracker.accept(0, 3); ok || lost != 0 {
  47. t.Fatal("duplicate counted as data or loss")
  48. }
  49. }
  50. func TestBandwidthUDPDirectionsAndAutomaticPacing(t *testing.T) {
  51. s := testServer(t)
  52. for _, direction := range []string{"rx", "both", "tx"} {
  53. t.Run(direction, func(t *testing.T) {
  54. c := NewClient()
  55. t.Cleanup(c.Stop)
  56. if err := c.Run(context.Background(), SessionRequest{Target: "127.0.0.1", Port: s.config.Port, Protocol: "udp", Direction: direction, Streams: 4, PacketSize: 1472, Duration: 2}); err != nil {
  57. t.Fatal(err)
  58. }
  59. deadline := time.Now().Add(5 * time.Second)
  60. for c.GetStatus().Running && time.Now().Before(deadline) {
  61. time.Sleep(10 * time.Millisecond)
  62. }
  63. st := c.GetStatus()
  64. if st.Running || st.Error != "" || st.Summary == nil {
  65. t.Fatalf("UDP test failed: %+v", st)
  66. }
  67. if direction != "rx" && st.Summary.TotalTxBytes < 100000 {
  68. t.Fatalf("no confirmed TX: %+v", st.Summary)
  69. }
  70. if direction != "tx" && st.Summary.TotalRxBytes < 100000 {
  71. t.Fatalf("no reverse UDP: %+v", st.Summary)
  72. }
  73. if st.Summary.AvgLossPct != 0 {
  74. t.Fatalf("streams or reordered packets falsely counted as loss: %+v", st.Summary)
  75. }
  76. if st.Summary.AvgTxMbps > 20 || st.Summary.AvgRxMbps > 20 {
  77. t.Fatal("automatic UDP started with an unbounded flood")
  78. }
  79. if direction == "tx" && st.Summary.TotalRxBytes != 0 {
  80. t.Fatal("TX delivery reports mislabeled as downloaded data")
  81. }
  82. })
  83. }
  84. }