/
rtt_test.go
112 lines (95 loc) · 2.88 KB
/
rtt_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package mokumokuren_test
import (
"fmt"
"os"
"testing"
"time"
moku "github.com/britram/mokumokuren"
"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
)
type ExpectedRTTMetrics struct {
Handshake time.Duration
Minimum time.Duration
Mean time.Duration
Count uint
}
type ExpectedFlowRTTs map[moku.FlowKey]ExpectedRTTMetrics
var RTTEmitterLog *os.File
func init() {
if DumpExpectedFlows {
var err error
RTTEmitterLog, err = os.Create("testdata/rtt_test.log")
if err != nil {
panic(err)
}
}
}
func rttVerificationEmitter(t *testing.T, filename string, e ExpectedFlowRTTs) moku.FlowChainFn {
return func(fe *moku.FlowEntry) bool {
rttdata := fe.Data[moku.RTTDataIndex].(*moku.RTTData)
if DumpExpectedFlows {
fmt.Fprintf(RTTEmitterLog, "// in file %s\n", filename)
fmt.Fprintf(RTTEmitterLog, "{\"%s\",\"%s\",%d,%d,%d}: ExpectedRTTMetrics{%d,%d,%d,%d}\n",
fe.Key.Sip, fe.Key.Dip, fe.Key.Sp, fe.Key.Dp, fe.Key.P,
rttdata.HandshakeRTT, rttdata.MinimumRTT, rttdata.MeanRTT, rttdata.RTTSampleCount)
}
metrics, ok := e[fe.Key]
if ok {
if metrics.Handshake != rttdata.HandshakeRTT {
t.Logf("flow %s expected hsrtt %d got %d", fe.Key, metrics.Handshake, rttdata.HandshakeRTT)
t.Fail()
}
if metrics.Minimum != rttdata.MinimumRTT {
t.Logf("flow %s expected minrtt %d got %d", fe.Key, metrics.Minimum, rttdata.MinimumRTT)
t.Fail()
}
if metrics.Mean != rttdata.MeanRTT {
t.Logf("flow %s expected meanrtt %d got %d", fe.Key, metrics.Mean, rttdata.MeanRTT)
t.Fail()
}
if metrics.Count != rttdata.RTTSampleCount {
t.Logf("flow %s expected samplecount %d got %d", fe.Key, metrics.Count, rttdata.RTTSampleCount)
t.Fail()
}
}
return true
}
}
func TestRTTMeasurement(t *testing.T) {
moku.QUICPort = 4433
specs := []struct {
filename string
expectation ExpectedFlowRTTs
}{
{"testdata/magpie_v6.pcap",
ExpectedFlowRTTs{
{"2001:67c:370:128:10b8:6449:2dbf:4fc", "2a03:b0c0:3:d0::27a1:1", 61040, 443, 6}: ExpectedRTTMetrics{183653000, 188679000, 378764714, 7},
},
},
{"testdata/bunchaquic.pcap",
ExpectedFlowRTTs{
{"31.133.128.140", "35.156.158.137", 52550, 4433, 17}: ExpectedRTTMetrics{230483000, 0, 0, 0},
{"31.133.128.140", "139.162.123.134", 52551, 4433, 17}: ExpectedRTTMetrics{81776000, 0, 0, 0},
{"31.133.128.140", "133.242.206.244", 52552, 4433, 17}: ExpectedRTTMetrics{97955000, 0, 0, 0},
},
},
}
for _, spec := range specs {
handle, err := pcap.OpenOffline(spec.filename)
if err != nil {
t.Fatal(err.Error())
}
defer handle.Close()
ps := gopacket.NewPacketSource(handle, handle.LinkType())
ft := moku.NewFlowTable()
ft.CountPacketsAndOctets()
ft.TrackTCPClose()
ft.TrackRoundTripTime()
ft.AddEmitterFunction(rttVerificationEmitter(t, spec.filename, spec.expectation))
for p := range ps.Packets() {
ft.HandlePacket(p)
}
ft.Shutdown()
}
}