edeaa3403dedcf15a8560f0c258078526e3a0720
[govpp.git] / core / trace_test.go
1 package core_test
2
3 import (
4         "git.fd.io/govpp.git/api"
5         interfaces "git.fd.io/govpp.git/binapi/interface"
6         "git.fd.io/govpp.git/binapi/ip"
7         "git.fd.io/govpp.git/binapi/l2"
8         memclnt "git.fd.io/govpp.git/binapi/memclnt"
9         "git.fd.io/govpp.git/binapi/memif"
10         "git.fd.io/govpp.git/core"
11         . "github.com/onsi/gomega"
12         "strings"
13         "testing"
14 )
15
16 func TestTraceEnabled(t *testing.T) {
17         ctx := setupTest(t, false)
18         defer ctx.teardownTest()
19
20         Expect(ctx.conn.Trace()).ToNot(BeNil())
21         ctx.conn.Trace().Enable(true)
22
23         request := []api.Message{
24                 &interfaces.CreateLoopback{},
25                 &memif.MemifCreate{},
26                 &l2.BridgeDomainAddDel{},
27                 &ip.IPTableAddDel{},
28         }
29         reply := []api.Message{
30                 &interfaces.CreateLoopbackReply{},
31                 &memif.MemifCreateReply{},
32                 &l2.BridgeDomainAddDelReply{},
33                 &ip.IPTableAddDelReply{},
34         }
35
36         for i := 0; i < len(request); i++ {
37                 ctx.mockVpp.MockReply(reply[i])
38                 err := ctx.ch.SendRequest(request[i]).ReceiveReply(reply[i])
39                 Expect(err).To(BeNil())
40         }
41
42         traced := ctx.conn.Trace().GetRecords()
43         Expect(traced).ToNot(BeNil())
44         Expect(traced).To(HaveLen(8))
45         for i, entry := range traced {
46                 Expect(entry.Timestamp).ToNot(BeNil())
47                 Expect(entry.Message.GetMessageName()).ToNot(Equal(""))
48                 if strings.HasSuffix(entry.Message.GetMessageName(), "_reply") ||
49                         strings.HasSuffix(entry.Message.GetMessageName(), "_details") {
50                         Expect(entry.IsReceived).To(BeTrue())
51                 } else {
52                         Expect(entry.IsReceived).To(BeFalse())
53                 }
54                 if i%2 == 0 {
55                         Expect(request[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
56                 } else {
57                         Expect(reply[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
58                 }
59         }
60 }
61
62 func TestMultiRequestTraceEnabled(t *testing.T) {
63         ctx := setupTest(t, false)
64         defer ctx.teardownTest()
65
66         ctx.conn.Trace().Enable(true)
67
68         request := []api.Message{
69                 &interfaces.SwInterfaceDump{},
70         }
71         reply := []api.Message{
72                 &interfaces.SwInterfaceDetails{
73                         SwIfIndex: 1,
74                 },
75                 &interfaces.SwInterfaceDetails{
76                         SwIfIndex: 2,
77                 },
78                 &interfaces.SwInterfaceDetails{
79                         SwIfIndex: 3,
80                 },
81                 &memclnt.ControlPingReply{},
82         }
83
84         ctx.mockVpp.MockReply(reply...)
85         multiCtx := ctx.ch.SendMultiRequest(request[0])
86
87         i := 0
88         for {
89                 last, err := multiCtx.ReceiveReply(reply[i])
90                 Expect(err).ToNot(HaveOccurred())
91                 if last {
92                         break
93                 }
94                 i++
95         }
96
97         traced := ctx.conn.Trace().GetRecords()
98         Expect(traced).ToNot(BeNil())
99         Expect(traced).To(HaveLen(6))
100         for i, entry := range traced {
101                 Expect(entry.Timestamp).ToNot(BeNil())
102                 Expect(entry.Message.GetMessageName()).ToNot(Equal(""))
103                 if strings.HasSuffix(entry.Message.GetMessageName(), "_reply") ||
104                         strings.HasSuffix(entry.Message.GetMessageName(), "_details") {
105                         Expect(entry.IsReceived).To(BeTrue())
106                 } else {
107                         Expect(entry.IsReceived).To(BeFalse())
108                 }
109                 if i == 0 {
110                         Expect(request[0].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
111                 } else if i == len(traced)-1 {
112                         msg := memclnt.ControlPing{}
113                         Expect(msg.GetMessageName()).To(Equal(entry.Message.GetMessageName()))
114                 } else {
115                         Expect(reply[i-1].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
116                 }
117         }
118 }
119
120 func TestTraceDisabled(t *testing.T) {
121         ctx := setupTest(t, false)
122         defer ctx.teardownTest()
123
124         ctx.conn.Trace().Enable(false)
125
126         request := []api.Message{
127                 &interfaces.CreateLoopback{},
128                 &memif.MemifCreate{},
129                 &l2.BridgeDomainAddDel{},
130                 &ip.IPTableAddDel{},
131         }
132         reply := []api.Message{
133                 &interfaces.CreateLoopbackReply{},
134                 &memif.MemifCreateReply{},
135                 &l2.BridgeDomainAddDelReply{},
136                 &ip.IPTableAddDelReply{},
137         }
138
139         for i := 0; i < len(request); i++ {
140                 ctx.mockVpp.MockReply(reply[i])
141                 err := ctx.ch.SendRequest(request[i]).ReceiveReply(reply[i])
142                 Expect(err).To(BeNil())
143         }
144
145         traced := ctx.conn.Trace().GetRecords()
146         Expect(traced).To(BeNil())
147 }
148
149 func TestTracePerChannel(t *testing.T) {
150         ctx := setupTest(t, false)
151         defer ctx.teardownTest()
152
153         ctx.conn.Trace().Enable(true)
154
155         ch1 := ctx.ch
156         ch2, err := ctx.conn.NewAPIChannel()
157         Expect(err).ToNot(HaveOccurred())
158
159         requestCh1 := []api.Message{
160                 &interfaces.CreateLoopback{},
161                 &memif.MemifCreate{},
162                 &l2.BridgeDomainAddDel{},
163         }
164         replyCh1 := []api.Message{
165                 &interfaces.CreateLoopbackReply{},
166                 &memif.MemifCreateReply{},
167                 &l2.BridgeDomainAddDelReply{},
168         }
169         requestCh2 := []api.Message{
170                 &ip.IPTableAddDel{},
171         }
172         replyCh2 := []api.Message{
173                 &ip.IPTableAddDelReply{},
174         }
175
176         for i := 0; i < len(requestCh1); i++ {
177                 ctx.mockVpp.MockReply(replyCh1[i])
178                 err := ch1.SendRequest(requestCh1[i]).ReceiveReply(replyCh1[i])
179                 Expect(err).To(BeNil())
180         }
181         for i := 0; i < len(requestCh2); i++ {
182                 ctx.mockVpp.MockReply(replyCh2[i])
183                 err := ch2.SendRequest(requestCh2[i]).ReceiveReply(replyCh2[i])
184                 Expect(err).To(BeNil())
185         }
186
187         trace := ctx.conn.Trace().GetRecords()
188         Expect(trace).ToNot(BeNil())
189         Expect(trace).To(HaveLen(8))
190
191         // per channel
192         channel1, ok := ch1.(*core.Channel)
193         Expect(ok).To(BeTrue())
194         channel2, ok := ch2.(*core.Channel)
195         Expect(ok).To(BeTrue())
196
197         tracedCh1 := ctx.conn.Trace().GetRecordsForChannel(channel1.GetID())
198         Expect(tracedCh1).ToNot(BeNil())
199         Expect(tracedCh1).To(HaveLen(6))
200         for i, entry := range tracedCh1 {
201                 Expect(entry.Timestamp).ToNot(BeNil())
202                 Expect(entry.Message.GetMessageName()).ToNot(Equal(""))
203                 if strings.HasSuffix(entry.Message.GetMessageName(), "_reply") ||
204                         strings.HasSuffix(entry.Message.GetMessageName(), "_details") {
205                         Expect(entry.IsReceived).To(BeTrue())
206                 } else {
207                         Expect(entry.IsReceived).To(BeFalse())
208                 }
209                 if i%2 == 0 {
210                         Expect(requestCh1[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
211                 } else {
212                         Expect(replyCh1[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
213                 }
214         }
215
216         tracedCh2 := ctx.conn.Trace().GetRecordsForChannel(channel2.GetID())
217         Expect(tracedCh2).ToNot(BeNil())
218         Expect(tracedCh2).To(HaveLen(2))
219         for i, entry := range tracedCh2 {
220                 Expect(entry.Timestamp).ToNot(BeNil())
221                 Expect(entry.Message.GetMessageName()).ToNot(Equal(""))
222                 if strings.HasSuffix(entry.Message.GetMessageName(), "_reply") ||
223                         strings.HasSuffix(entry.Message.GetMessageName(), "_details") {
224                         Expect(entry.IsReceived).To(BeTrue())
225                 } else {
226                         Expect(entry.IsReceived).To(BeFalse())
227                 }
228                 if i%2 == 0 {
229                         Expect(requestCh2[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
230                 } else {
231                         Expect(replyCh2[i/2].GetMessageName()).To(Equal(entry.Message.GetMessageName()))
232                 }
233         }
234 }
235
236 func TestTraceClear(t *testing.T) {
237         ctx := setupTest(t, false)
238         defer ctx.teardownTest()
239
240         ctx.conn.Trace().Enable(true)
241
242         request := []api.Message{
243                 &interfaces.CreateLoopback{},
244                 &memif.MemifCreate{},
245         }
246         reply := []api.Message{
247                 &interfaces.CreateLoopbackReply{},
248                 &memif.MemifCreateReply{},
249         }
250
251         for i := 0; i < len(request); i++ {
252                 ctx.mockVpp.MockReply(reply[i])
253                 err := ctx.ch.SendRequest(request[i]).ReceiveReply(reply[i])
254                 Expect(err).To(BeNil())
255         }
256
257         traced := ctx.conn.Trace().GetRecords()
258         Expect(traced).ToNot(BeNil())
259         Expect(traced).To(HaveLen(4))
260
261         ctx.conn.Trace().Clear()
262         traced = ctx.conn.Trace().GetRecords()
263         Expect(traced).To(BeNil())
264         Expect(traced).To(BeEmpty())
265 }