1package dgram
2
3import (
4 "errors"
5 "testing"
6 "time"
7)
8
9func TestBytePacerUsesBurstThenFakeClockRate(t *testing.T) {
10 const mtu = 1200
11 clk := newManualClock(time.Date(2030, 1, 2, 3, 4, 5, 0, time.UTC))
12 c := newCongestionController(mtu)
13 p := bytePacer{clk: clk}
14 done := make(chan struct{})
15 limits := func() (int, int) { return c.bytesPerSecond(), c.burstBytes() }
16
17 for range dataBurstPackets {
18 if err := p.wait(done, mtu, limits); err != nil {
19 t.Fatal(err)
20 }
21 }
22 wait := make(chan error, 1)
23 go func() { wait <- p.wait(done, mtu, limits) }()
24 awaitSignal(t, clk.timerCreated, "byte pacer timer")
25 clk.advance(24 * time.Millisecond)
26 select {
27 case err := <-wait:
28 t.Fatalf("third MTU released early: %v", err)
29 default:
30 }
31 clk.advance(time.Millisecond)
32 if err := awaitResult(t, wait, "third paced MTU"); err != nil {
33 t.Fatal(err)
34 }
35
36 c.onLoss()
37 next := make(chan error, 1)
38 go func() { next <- p.wait(done, mtu, limits) }()
39 awaitSignal(t, clk.timerCreated, "reduced-cwnd byte pacer timer")
40 clk.advance(49 * time.Millisecond)
41 select {
42 case err := <-next:
43 t.Fatalf("reduced cwnd did not lengthen wait: %v", err)
44 default:
45 }
46 clk.advance(time.Millisecond)
47 if err := awaitResult(t, next, "reduced-cwnd paced MTU"); err != nil {
48 t.Fatal(err)
49 }
50}
51
52func TestBytePacerMaximumRateRefillsAfterMultiSecondFakeClockJump(t *testing.T) {
53 clk := newManualClock(time.Date(2030, 1, 2, 3, 4, 5, 0, time.UTC))
54 p := bytePacer{clk: clk}
55 done := make(chan struct{})
56 burst := int(^uint(0) >> 1)
57 limits := func() (int, int) { return burst, burst }
58
59 if err := p.wait(done, burst, limits); err != nil {
60 t.Fatal(err)
61 }
62 clk.advance(3 * time.Second)
63 if err := p.wait(done, burst, limits); err != nil {
64 t.Fatal(err)
65 }
66
67 wait := make(chan error, 1)
68 go func() { wait <- p.wait(done, burst, limits) }()
69 awaitSignal(t, clk.timerCreated, "maximum-rate byte pacer timer")
70 clk.advance(time.Second - time.Nanosecond)
71 select {
72 case err := <-wait:
73 t.Fatalf("maximum-rate burst released early: %v", err)
74 default:
75 }
76 clk.advance(time.Nanosecond)
77 if err := awaitResult(t, wait, "maximum-rate burst"); err != nil {
78 t.Fatal(err)
79 }
80}
81
82func TestBytePacerCancellation(t *testing.T) {
83 const mtu = 1200
84 clk := newManualClock(time.Date(2030, 1, 2, 3, 4, 5, 0, time.UTC))
85 p := bytePacer{clk: clk}
86 done := make(chan struct{})
87 limits := func() (int, int) { return mtu, mtu }
88 if err := p.wait(done, mtu, limits); err != nil {
89 t.Fatal(err)
90 }
91 wait := make(chan error, 1)
92 go func() { wait <- p.wait(done, mtu, limits) }()
93 awaitSignal(t, clk.timerCreated, "cancelled byte pacer timer")
94 close(done)
95 if err := awaitResult(t, wait, "byte pacer cancellation"); !errors.Is(err, errPacerClosed) {
96 t.Fatalf("cancellation error=%v, want %v", err, errPacerClosed)
97 }
98}