-
Notifications
You must be signed in to change notification settings - Fork 8
/
convert_test.go
160 lines (144 loc) · 4.57 KB
/
convert_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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
package tools_test
import (
"encoding/binary"
"encoding/json"
"errors"
"io"
"log"
"syscall"
"testing"
"time"
"github.com/go-test/deep"
"github.com/m-lab/tcp-info/inetdiag"
tcpinfo "github.com/m-lab/tcp-info/nl-proto"
"github.com/m-lab/tcp-info/nl-proto/tools"
"github.com/m-lab/tcp-info/zstd"
)
func init() {
// Always prepend the filename and line number.
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
// NextMsg reads the next NetlinkMessage from a source readers.
func nextMsg(rdr io.Reader) (*syscall.NetlinkMessage, error) {
var header syscall.NlMsghdr
err := binary.Read(rdr, binary.LittleEndian, &header)
if err != nil {
return nil, err
}
data := make([]byte, header.Len-uint32(binary.Size(header)))
err = binary.Read(rdr, binary.LittleEndian, data)
if err != nil {
return nil, err
}
return &syscall.NetlinkMessage{Header: header, Data: data}, nil
}
// Package error messages
var (
ErrInetDiagParseFailed = errors.New("Error parsing inetdiag message")
ErrLocal = errors.New("Connection is loopback")
ErrUnknownMessageType = errors.New("Unknown netlink message type")
)
func convertToProto(msg *syscall.NetlinkMessage, t *testing.T) *tcpinfo.TCPDiagnosticsProto {
parsedMsg, err := inetdiag.Parse(msg, true)
if err != nil {
t.Fatal(err)
}
return tools.CreateProto(time.Now(), msg.Header, parsedMsg.InetDiagMsg, parsedMsg.Attributes[:])
}
func TestReader(t *testing.T) {
// Cache info new 140 err 0 same 277 local 789 diff 3 total 1209
// 1209 sockets 143 remotes 403 per iteration
source := "testdata/testdata.zst"
log.Println("Reading messages from", source)
rdr := zstd.NewReader(source)
parsed := 0
src4 := 0
dst4 := 0
for {
msg, err := nextMsg(rdr)
if err != nil {
if err == io.EOF {
break
}
t.Fatal(err)
}
p := convertToProto(msg, t)
if p.InetDiagMsg == nil {
t.Fatal("InetDiagMsg missing")
}
if p.CongestionAlgorithm != "cubic" {
t.Error(p.CongestionAlgorithm, []byte(p.CongestionAlgorithm))
}
if p.MemInfo == nil {
t.Error("MemInfo missing")
}
if p.TcpInfo == nil {
t.Fatal("TcpInfo missing")
}
if p.TcpInfo.State != p.InetDiagMsg.State {
t.Fatal("State mismatch")
}
if len(p.InetDiagMsg.SockId.Source.Ip) == 4 {
src4++
}
if len(p.InetDiagMsg.SockId.Destination.Ip) == 4 {
dst4++
}
parsed++
}
if src4 == 0 {
t.Error("There should be some ipv4 sources")
}
if dst4 == 0 {
t.Error("There should be some ipv4 destinations")
}
// TODO - do some test on the proto }
if parsed != 420 { // 140 new, 277 same, and 3 diff
t.Error(parsed)
}
}
func TestCompare(t *testing.T) {
var json1 = `{"Header":{"Len":356,"Type":20,"Flags":2,"Seq":1,"Pid":148940},"Data":"CgEAAOpWE6cmIAAAEAMEFbM+nWqBv4ehJgf4sEANDAoAAAAAAAAAgQAAAAAdWwAAAAAAAAAAAAAAAAAAAAAAAAAAAAC13zIBBQAIAAAAAAAFAAUAIAAAAAUABgAgAAAAFAABAAAAAAAAAAAAAAAAAAAAAAAoAAcAAAAAAICiBQAAAAAAALQAAAAAAAAAAAAAAAAAAAAAAAAAAAAArAACAAEAAAAAB3gBQIoDAECcAABEBQAAuAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUCEAAAAAAAAgIQAAQCEAANwFAACsywIAJW8AAIRKAAD///9/CgAAAJQFAAADAAAALMkAAIBwAAAAAAAALnUOAAAAAAD///////////ayBAAAAAAASfQPAAAAAADMEQAANRMAAAAAAABiNQAAxAsAAGMIAABX5AUAAAAAAAoABABjdWJpYwAAAA=="}`
nm := syscall.NetlinkMessage{}
err := json.Unmarshal([]byte(json1), &nm)
if err != nil {
log.Fatal(err)
}
mp1, err := inetdiag.Parse(&nm, true)
if err != nil {
log.Fatal(err)
}
// Another independent copy.
nm2 := syscall.NetlinkMessage{}
err = json.Unmarshal([]byte(json1), &nm2)
if err != nil {
log.Fatal(err)
}
mp2, err := inetdiag.Parse(&nm2, true)
if err != nil {
log.Fatal(err)
}
// INET_DIAG_INFO Last... fields should be ignored
for i := int(tools.LastDataSentOffset); i < int(tools.PmtuOffset); i++ {
mp2.Attributes[inetdiag.INET_DIAG_INFO].Value[i] += 1
}
diff := tools.Compare(mp1, mp2)
if diff != tools.NoMajorChange {
t.Error("Last field changes should not be detected:", deep.Equal(mp1.Attributes[inetdiag.INET_DIAG_INFO],
mp2.Attributes[inetdiag.INET_DIAG_INFO]))
}
// Early parts of INET_DIAG_INFO Should be ignored
mp2.Attributes[inetdiag.INET_DIAG_INFO].Value[10] = 7
diff = tools.Compare(mp1, mp2)
if diff != tools.StateOrCounterChange {
t.Error("Early field change not detected:", deep.Equal(mp1.Attributes[inetdiag.INET_DIAG_INFO],
mp2.Attributes[inetdiag.INET_DIAG_INFO]))
}
// packet, segment, and byte counts should NOT be ignored
mp2.Attributes[inetdiag.INET_DIAG_INFO].Value[tools.PmtuOffset] = 123
diff = tools.Compare(mp1, mp2)
if diff != tools.PacketCountChange {
t.Error("Late field change not detected:", deep.Equal(mp1.Attributes[inetdiag.INET_DIAG_INFO],
mp2.Attributes[inetdiag.INET_DIAG_INFO]))
}
}