blob: b01859ebe6adac86484361284f1157fac07187be [file] [log] [blame]
Matteo Scandolo813402b2019-10-23 19:24:52 -07001/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package devices
18
19import (
Matteo Scandolo813402b2019-10-23 19:24:52 -070020 "github.com/google/gopacket/layers"
21 "github.com/looplab/fsm"
Matteo Scandolo3de9de02019-11-14 13:40:03 -080022 "github.com/opencord/voltha-protos/v2/go/openolt"
Matteo Scandolo813402b2019-10-23 19:24:52 -070023 "gotest.tools/assert"
Matteo Scandolo5ff80082019-12-20 13:20:57 -080024 "sync"
Matteo Scandolo813402b2019-10-23 19:24:52 -070025 "testing"
Matteo Scandolo5ff80082019-12-20 13:20:57 -080026 "time"
Matteo Scandolo813402b2019-10-23 19:24:52 -070027)
28
Matteo Scandolo813402b2019-10-23 19:24:52 -070029func Test_Onu_SendEapolFlow(t *testing.T) {
Matteo Scandoloc1147092019-10-29 09:38:33 -070030 onu := createMockOnu(1, 1, 900, 900, false, false)
Matteo Scandolo813402b2019-10-23 19:24:52 -070031
32 client := &mockClient{
33 FlowAddSpy: FlowAddSpy{
34 Calls: make(map[int]*openolt.Flow),
35 },
36 fail: false,
37 }
38
39 onu.sendEapolFlow(client)
40 assert.Equal(t, client.FlowAddSpy.CallCount, 1)
41
42 assert.Equal(t, client.FlowAddSpy.Calls[1].AccessIntfId, int32(onu.PonPortID))
43 assert.Equal(t, client.FlowAddSpy.Calls[1].OnuId, int32(onu.ID))
44 assert.Equal(t, client.FlowAddSpy.Calls[1].UniId, int32(0))
45 assert.Equal(t, client.FlowAddSpy.Calls[1].FlowId, onu.ID)
46 assert.Equal(t, client.FlowAddSpy.Calls[1].FlowType, "downstream")
47 assert.Equal(t, client.FlowAddSpy.Calls[1].PortNo, onu.ID)
48}
49
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -070050// checks that the FlowId is added to the list
51func Test_HandleFlowAddFlowId(t *testing.T) {
52 onu := createMockOnu(1, 1, 900, 900, true, false)
53
54 flow := openolt.Flow{
55 FlowId: 64,
56 Classifier: &openolt.Classifier{},
57 }
58 msg := OnuFlowUpdateMessage{
59 OnuID: onu.ID,
60 PonPortID: onu.PonPortID,
61 Flow: &flow,
62 }
63 onu.handleFlowAdd(msg)
64 assert.Equal(t, len(onu.FlowIds), 1)
65 assert.Equal(t, onu.FlowIds[0], uint32(64))
66}
67
Matteo Scandolo813402b2019-10-23 19:24:52 -070068// validates that when an ONU receives an EAPOL flow for UNI 0
Matteo Scandolo5ff80082019-12-20 13:20:57 -080069// and the GemPort has already been configured
Matteo Scandolo813402b2019-10-23 19:24:52 -070070// it transition to auth_started state
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -070071func Test_HandleFlowAddEapolWithGem(t *testing.T) {
Matteo Scandolo813402b2019-10-23 19:24:52 -070072
Matteo Scandoloc1147092019-10-29 09:38:33 -070073 onu := createMockOnu(1, 1, 900, 900, true, false)
Matteo Scandolo813402b2019-10-23 19:24:52 -070074
75 onu.InternalState = fsm.NewFSM(
Matteo Scandolo5ff80082019-12-20 13:20:57 -080076 "enabled",
Matteo Scandolo813402b2019-10-23 19:24:52 -070077 fsm.Events{
Matteo Scandolo5ff80082019-12-20 13:20:57 -080078 {Name: "start_auth", Src: []string{"enabled"}, Dst: "auth_started"},
Matteo Scandolo813402b2019-10-23 19:24:52 -070079 },
80 fsm.Callbacks{},
81 )
82
83 flow := openolt.Flow{
84 AccessIntfId: int32(onu.PonPortID),
85 OnuId: int32(onu.ID),
86 UniId: int32(0),
87 FlowId: uint32(onu.ID),
88 FlowType: "downstream",
89 AllocId: int32(0),
90 NetworkIntfId: int32(0),
91 Classifier: &openolt.Classifier{
92 EthType: uint32(layers.EthernetTypeEAPOL),
93 OVid: 4091,
94 },
95 Action: &openolt.Action{},
96 Priority: int32(100),
97 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
98 }
99
100 msg := OnuFlowUpdateMessage{
101 PonPortID: 1,
102 OnuID: 1,
103 Flow: &flow,
104 }
105
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700106 onu.handleFlowAdd(msg)
Matteo Scandolo813402b2019-10-23 19:24:52 -0700107 assert.Equal(t, onu.InternalState.Current(), "auth_started")
108}
109
110// validates that when an ONU receives an EAPOL flow for UNI that is not 0
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800111// no action is taken (this is independent of GemPort status
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700112func Test_HandleFlowAddEapolWrongUNI(t *testing.T) {
Matteo Scandolo813402b2019-10-23 19:24:52 -0700113
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800114 onu := createMockOnu(1, 1, 900, 900, true, false)
Matteo Scandolo813402b2019-10-23 19:24:52 -0700115
116 onu.InternalState = fsm.NewFSM(
117 "enabled",
118 fsm.Events{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800119 {Name: "start_auth", Src: []string{"enabled"}, Dst: "auth_started"},
Matteo Scandolo813402b2019-10-23 19:24:52 -0700120 },
121 fsm.Callbacks{},
122 )
123
124 flow := openolt.Flow{
125 AccessIntfId: int32(onu.PonPortID),
126 OnuId: int32(onu.ID),
127 UniId: int32(1),
128 FlowId: uint32(onu.ID),
129 FlowType: "downstream",
130 AllocId: int32(0),
131 NetworkIntfId: int32(0),
132 Classifier: &openolt.Classifier{
133 EthType: uint32(layers.EthernetTypeEAPOL),
134 OVid: 4091,
135 },
136 Action: &openolt.Action{},
137 Priority: int32(100),
138 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
139 }
140
141 msg := OnuFlowUpdateMessage{
142 PonPortID: 1,
143 OnuID: 1,
144 Flow: &flow,
145 }
146
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700147 onu.handleFlowAdd(msg)
Matteo Scandolo813402b2019-10-23 19:24:52 -0700148 assert.Equal(t, onu.InternalState.Current(), "enabled")
149}
150
Matteo Scandoloc1147092019-10-29 09:38:33 -0700151// validates that when an ONU receives an EAPOL flow for UNI 0
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800152// and the GemPort has not yet been configured
153// it transition to auth_started state
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700154func Test_HandleFlowAddEapolWithoutGem(t *testing.T) {
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800155
156 onu := createMockOnu(1, 1, 900, 900, true, false)
157 onu.GemPortAdded = false
Matteo Scandoloc1147092019-10-29 09:38:33 -0700158
159 onu.InternalState = fsm.NewFSM(
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800160 "enabled",
Matteo Scandoloc1147092019-10-29 09:38:33 -0700161 fsm.Events{
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800162 {Name: "start_auth", Src: []string{"enabled"}, Dst: "auth_started"},
Matteo Scandoloc1147092019-10-29 09:38:33 -0700163 },
164 fsm.Callbacks{},
165 )
166
167 flow := openolt.Flow{
168 AccessIntfId: int32(onu.PonPortID),
169 OnuId: int32(onu.ID),
170 UniId: int32(0),
171 FlowId: uint32(onu.ID),
172 FlowType: "downstream",
173 AllocId: int32(0),
174 NetworkIntfId: int32(0),
175 Classifier: &openolt.Classifier{
176 EthType: uint32(layers.EthernetTypeEAPOL),
177 OVid: 4091,
178 },
179 Action: &openolt.Action{},
180 Priority: int32(100),
181 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
182 }
183
184 msg := OnuFlowUpdateMessage{
185 PonPortID: 1,
186 OnuID: 1,
187 Flow: &flow,
188 }
189
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700190 onu.handleFlowAdd(msg)
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800191
192 wg := sync.WaitGroup{}
193 wg.Add(1)
194 go func(wg *sync.WaitGroup) {
195 defer wg.Done()
196 time.Sleep(100 * time.Millisecond)
197
198 // emulate the addition of a GemPort
199 for _, ch := range onu.GemPortChannels {
200 ch <- true
201 }
202
203 time.Sleep(100 * time.Millisecond)
204 assert.Equal(t, onu.InternalState.Current(), "auth_started")
205 }(&wg)
206 wg.Wait()
207
Matteo Scandoloc1147092019-10-29 09:38:33 -0700208}
209
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800210// validates that when an ONU receives an EAPOL flow for UNI 0
211// but the noAuth bit is set no action is taken
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700212func Test_HandleFlowAddEapolNoAuth(t *testing.T) {
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800213 onu := createMockOnu(1, 1, 900, 900, false, false)
214
215 onu.InternalState = fsm.NewFSM(
216 "enabled",
217 fsm.Events{
218 {Name: "start_auth", Src: []string{"enabled"}, Dst: "auth_started"},
219 },
220 fsm.Callbacks{},
221 )
222
223 flow := openolt.Flow{
224 AccessIntfId: int32(onu.PonPortID),
225 OnuId: int32(onu.ID),
226 UniId: int32(0),
227 FlowId: uint32(onu.ID),
228 FlowType: "downstream",
229 AllocId: int32(0),
230 NetworkIntfId: int32(0),
231 Classifier: &openolt.Classifier{
232 EthType: uint32(layers.EthernetTypeEAPOL),
233 OVid: 4091,
234 },
235 Action: &openolt.Action{},
236 Priority: int32(100),
237 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
238 }
239
240 msg := OnuFlowUpdateMessage{
241 PonPortID: 1,
242 OnuID: 1,
243 Flow: &flow,
244 }
245
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700246 onu.handleFlowAdd(msg)
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800247 assert.Equal(t, onu.InternalState.Current(), "enabled")
248}
249
250// validates that when an ONU receives a DHCP flow for UNI 0 and pbit 0
251// and the GemPort has already been configured
252// it transition to dhcp_started state
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700253func Test_HandleFlowAddDhcp(t *testing.T) {
Matteo Scandoloc1147092019-10-29 09:38:33 -0700254 onu := createMockOnu(1, 1, 900, 900, false, true)
255
256 onu.InternalState = fsm.NewFSM(
257 "eap_response_success_received",
258 fsm.Events{
259 {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
260 },
261 fsm.Callbacks{},
262 )
263
264 flow := openolt.Flow{
265 AccessIntfId: int32(onu.PonPortID),
266 OnuId: int32(onu.ID),
267 UniId: int32(0),
268 FlowId: uint32(onu.ID),
269 FlowType: "downstream",
270 AllocId: int32(0),
271 NetworkIntfId: int32(0),
272 Classifier: &openolt.Classifier{
273 EthType: uint32(layers.EthernetTypeIPv4),
274 SrcPort: uint32(68),
275 DstPort: uint32(67),
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800276 OPbits: 0,
Matteo Scandoloc1147092019-10-29 09:38:33 -0700277 },
278 Action: &openolt.Action{},
279 Priority: int32(100),
280 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
281 }
282
283 msg := OnuFlowUpdateMessage{
284 PonPortID: 1,
285 OnuID: 1,
286 Flow: &flow,
287 }
288
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700289 onu.handleFlowAdd(msg)
Matteo Scandoloc1147092019-10-29 09:38:33 -0700290 assert.Equal(t, onu.InternalState.Current(), "dhcp_started")
291 assert.Equal(t, onu.DhcpFlowReceived, true)
292}
293
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800294// validates that when an ONU receives a DHCP flow for UNI 0 and pbit 255
295// and the GemPort has already been configured
296// it transition to dhcp_started state
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700297func Test_HandleFlowAddDhcpPBit255(t *testing.T) {
Matteo Scandolod74abba2020-04-16 16:36:44 -0700298 onu := createMockOnu(1, 1, 900, 900, false, true)
299
300 onu.InternalState = fsm.NewFSM(
301 "eap_response_success_received",
302 fsm.Events{
303 {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
304 },
305 fsm.Callbacks{},
306 )
307
308 flow := openolt.Flow{
309 AccessIntfId: int32(onu.PonPortID),
310 OnuId: int32(onu.ID),
311 UniId: int32(0),
312 FlowId: uint32(onu.ID),
313 FlowType: "downstream",
314 AllocId: int32(0),
315 NetworkIntfId: int32(0),
316 Classifier: &openolt.Classifier{
317 EthType: uint32(layers.EthernetTypeIPv4),
318 SrcPort: uint32(68),
319 DstPort: uint32(67),
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800320 OPbits: 255,
Matteo Scandolod74abba2020-04-16 16:36:44 -0700321 },
322 Action: &openolt.Action{},
323 Priority: int32(100),
324 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
325 }
326
327 msg := OnuFlowUpdateMessage{
328 PonPortID: 1,
329 OnuID: 1,
330 Flow: &flow,
331 }
332
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700333 onu.handleFlowAdd(msg)
Matteo Scandolod74abba2020-04-16 16:36:44 -0700334 assert.Equal(t, onu.InternalState.Current(), "dhcp_started")
335 assert.Equal(t, onu.DhcpFlowReceived, true)
336}
337
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800338// validates that when an ONU receives a DHCP flow for UNI 0 and pbit not 0 or 255
339// and the GemPort has already been configured
340// it ignores the message
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700341func Test_HandleFlowAddDhcpIgnoreByPbit(t *testing.T) {
Matteo Scandolod74abba2020-04-16 16:36:44 -0700342 onu := createMockOnu(1, 1, 900, 900, false, true)
343
344 onu.InternalState = fsm.NewFSM(
345 "eap_response_success_received",
346 fsm.Events{
347 {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
348 },
349 fsm.Callbacks{},
350 )
351
352 flow := openolt.Flow{
353 AccessIntfId: int32(onu.PonPortID),
354 OnuId: int32(onu.ID),
355 UniId: int32(0),
356 FlowId: uint32(onu.ID),
357 FlowType: "downstream",
358 AllocId: int32(0),
359 NetworkIntfId: int32(0),
360 Classifier: &openolt.Classifier{
361 EthType: uint32(layers.EthernetTypeIPv4),
362 SrcPort: uint32(68),
363 DstPort: uint32(67),
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800364 OPbits: 1,
Matteo Scandolod74abba2020-04-16 16:36:44 -0700365 },
366 Action: &openolt.Action{},
367 Priority: int32(100),
368 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
369 }
370
371 msg := OnuFlowUpdateMessage{
372 PonPortID: 1,
373 OnuID: 1,
374 Flow: &flow,
375 }
376
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700377 onu.handleFlowAdd(msg)
Matteo Scandolod74abba2020-04-16 16:36:44 -0700378 assert.Equal(t, onu.InternalState.Current(), "eap_response_success_received")
379 assert.Equal(t, onu.DhcpFlowReceived, false)
380}
381
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800382// validates that when an ONU receives a DHCP flow for UNI 0
383// but the noDchp bit is set no action is taken
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700384func Test_HandleFlowAddDhcpNoDhcp(t *testing.T) {
Matteo Scandoloc1147092019-10-29 09:38:33 -0700385 onu := createMockOnu(1, 1, 900, 900, false, false)
386
387 onu.InternalState = fsm.NewFSM(
388 "eap_response_success_received",
389 fsm.Events{
390 {Name: "start_dhcp", Src: []string{"eap_response_success_received"}, Dst: "dhcp_started"},
391 },
392 fsm.Callbacks{},
393 )
394
395 flow := openolt.Flow{
396 AccessIntfId: int32(onu.PonPortID),
397 OnuId: int32(onu.ID),
398 UniId: int32(0),
399 FlowId: uint32(onu.ID),
400 FlowType: "downstream",
401 AllocId: int32(0),
402 NetworkIntfId: int32(0),
403 Classifier: &openolt.Classifier{
404 EthType: uint32(layers.EthernetTypeIPv4),
405 SrcPort: uint32(68),
406 DstPort: uint32(67),
407 },
408 Action: &openolt.Action{},
409 Priority: int32(100),
410 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
411 }
412
413 msg := OnuFlowUpdateMessage{
414 PonPortID: 1,
415 OnuID: 1,
416 Flow: &flow,
417 }
418
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700419 onu.handleFlowAdd(msg)
Matteo Scandoloc1147092019-10-29 09:38:33 -0700420 assert.Equal(t, onu.InternalState.Current(), "eap_response_success_received")
Matteo Scandolod74abba2020-04-16 16:36:44 -0700421 assert.Equal(t, onu.DhcpFlowReceived, false)
Matteo Scandoloc1147092019-10-29 09:38:33 -0700422}
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800423
424// validates that when an ONU receives a DHCP flow for UNI 0 and pbit not 0 or 255
425// and the GemPort has not already been configured
426// it transition to dhcp_started state
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700427func Test_HandleFlowAddDhcpWithoutGem(t *testing.T) {
428 // NOTE that this feature is required as there is no guarantee that the gemport is the same
429 // one we received with the EAPOL flow
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800430 onu := createMockOnu(1, 1, 900, 900, false, true)
431
432 onu.GemPortAdded = false
433
434 onu.InternalState = fsm.NewFSM(
435 "enabled",
436 fsm.Events{
437 {Name: "start_dhcp", Src: []string{"enabled"}, Dst: "dhcp_started"},
438 },
439 fsm.Callbacks{},
440 )
441
442 flow := openolt.Flow{
443 AccessIntfId: int32(onu.PonPortID),
444 OnuId: int32(onu.ID),
445 UniId: int32(0),
446 FlowId: uint32(onu.ID),
447 FlowType: "downstream",
448 AllocId: int32(0),
449 NetworkIntfId: int32(0),
450 Classifier: &openolt.Classifier{
451 EthType: uint32(layers.EthernetTypeIPv4),
452 SrcPort: uint32(68),
453 DstPort: uint32(67),
454 OPbits: 0,
455 },
456 Action: &openolt.Action{},
457 Priority: int32(100),
458 PortNo: uint32(onu.ID), // NOTE we are using this to map an incoming packetIndication to an ONU
459 }
460
461 msg := OnuFlowUpdateMessage{
462 PonPortID: 1,
463 OnuID: 1,
464 Flow: &flow,
465 }
466
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700467 onu.handleFlowAdd(msg)
Matteo Scandolo5ff80082019-12-20 13:20:57 -0800468
469 wg := sync.WaitGroup{}
470 wg.Add(1)
471 go func(wg *sync.WaitGroup) {
472 defer wg.Done()
473 time.Sleep(100 * time.Millisecond)
474
475 // emulate the addition of a GemPort
476 for _, ch := range onu.GemPortChannels {
477 ch <- true
478 }
479
480 time.Sleep(100 * time.Millisecond)
481 assert.Equal(t, onu.InternalState.Current(), "dhcp_started")
482 assert.Equal(t, onu.DhcpFlowReceived, true)
483 }(&wg)
484 wg.Wait()
485}
Matteo Scandoloeb6b5af2020-06-24 16:23:58 -0700486
487// checks that we only remove the correct flow
488func Test_HandleFlowRemoveFlowId(t *testing.T) {
489 onu := createMockOnu(1, 1, 900, 900, true, false)
490
491 onu.FlowIds = []uint32{1, 2, 34, 64, 92}
492
493 flow := openolt.Flow{
494 FlowId: 64,
495 Classifier: &openolt.Classifier{},
496 }
497 msg := OnuFlowUpdateMessage{
498 OnuID: onu.ID,
499 PonPortID: onu.PonPortID,
500 Flow: &flow,
501 }
502 onu.handleFlowRemove(msg)
503 assert.Equal(t, len(onu.FlowIds), 4)
504 assert.Equal(t, onu.FlowIds[0], uint32(1))
505 assert.Equal(t, onu.FlowIds[1], uint32(2))
506 assert.Equal(t, onu.FlowIds[2], uint32(34))
507 assert.Equal(t, onu.FlowIds[3], uint32(92))
508}
509
510// checks that when the last flow is removed we reset the stored flags in the ONU
511func Test_HandleFlowRemoveFlowId_LastFlow(t *testing.T) {
512 onu := createMockOnu(1, 1, 900, 900, true, false)
513 onu.GemPortAdded = true
514 onu.DhcpFlowReceived = true
515 onu.EapolFlowReceived = true
516
517 onu.FlowIds = []uint32{64}
518
519 flow := openolt.Flow{
520 FlowId: 64,
521 Classifier: &openolt.Classifier{},
522 }
523 msg := OnuFlowUpdateMessage{
524 OnuID: onu.ID,
525 PonPortID: onu.PonPortID,
526 Flow: &flow,
527 }
528 onu.handleFlowRemove(msg)
529 assert.Equal(t, len(onu.FlowIds), 0)
530 assert.Equal(t, onu.GemPortAdded, false)
531 assert.Equal(t, onu.DhcpFlowReceived, false)
532 assert.Equal(t, onu.EapolFlowReceived, false)
533}