blob: 5af75ecedb7826ed53c13bcac64c21043a17582d [file] [log] [blame]
khenaidoo6e55d9e2019-12-12 18:26:26 -05001/*
Kent Hagerman45a13e42020-04-13 12:23:50 -04002 * Copyright 2019-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.
khenaidoo6e55d9e2019-12-12 18:26:26 -050015 */
Kent Hagerman45a13e42020-04-13 12:23:50 -040016
Kent Hagerman2b216042020-04-03 18:28:56 -040017package device
khenaidoo6e55d9e2019-12-12 18:26:26 -050018
19import (
20 "context"
Mahir Gunyel03de0d32020-06-03 01:36:59 -070021 "math/rand"
22 "sort"
Neha Sharmad1387da2020-05-07 20:07:28 +000023 "strconv"
Mahir Gunyel03de0d32020-06-03 01:36:59 -070024 "strings"
25 "sync"
26 "testing"
27 "time"
28
khenaidoo6e55d9e2019-12-12 18:26:26 -050029 "github.com/gogo/protobuf/proto"
Kent Hagerman2b216042020-04-03 18:28:56 -040030 "github.com/opencord/voltha-go/db/model"
khenaidoo6e55d9e2019-12-12 18:26:26 -050031 "github.com/opencord/voltha-go/rw_core/config"
Kent Hagerman2b216042020-04-03 18:28:56 -040032 "github.com/opencord/voltha-go/rw_core/core/adapter"
Mahir Gunyel03de0d32020-06-03 01:36:59 -070033 cm "github.com/opencord/voltha-go/rw_core/mocks"
34 tst "github.com/opencord/voltha-go/rw_core/test"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080035 com "github.com/opencord/voltha-lib-go/v3/pkg/adapters/common"
Kent Hagerman2b216042020-04-03 18:28:56 -040036 "github.com/opencord/voltha-lib-go/v3/pkg/db"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080037 "github.com/opencord/voltha-lib-go/v3/pkg/kafka"
Scott Baker504b4802020-04-17 10:12:20 -070038 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Matteo Scandolod525ae32020-04-02 17:27:29 -070039 mock_etcd "github.com/opencord/voltha-lib-go/v3/pkg/mocks/etcd"
40 mock_kafka "github.com/opencord/voltha-lib-go/v3/pkg/mocks/kafka"
serkant.uluderya2ae470f2020-01-21 11:13:09 -080041 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
42 "github.com/opencord/voltha-protos/v3/go/voltha"
khenaidoo6e55d9e2019-12-12 18:26:26 -050043 "github.com/phayes/freeport"
44 "github.com/stretchr/testify/assert"
khenaidoo6e55d9e2019-12-12 18:26:26 -050045)
46
47type DATest struct {
Kent Hagerman2b216042020-04-03 18:28:56 -040048 etcdServer *mock_etcd.EtcdServer
49 deviceMgr *Manager
50 logicalDeviceMgr *LogicalManager
Mahir Gunyel03de0d32020-06-03 01:36:59 -070051 adapterMgr *adapter.Manager
Kent Hagerman2b216042020-04-03 18:28:56 -040052 kmp kafka.InterContainerProxy
53 kClient kafka.Client
54 kvClientPort int
Mahir Gunyel03de0d32020-06-03 01:36:59 -070055 oltAdapter *cm.OLTAdapter
56 onuAdapter *cm.ONUAdapter
Kent Hagerman2b216042020-04-03 18:28:56 -040057 oltAdapterName string
58 onuAdapterName string
59 coreInstanceID string
60 defaultTimeout time.Duration
61 maxTimeout time.Duration
62 device *voltha.Device
63 done chan int
khenaidoo6e55d9e2019-12-12 18:26:26 -050064}
65
66func newDATest() *DATest {
67 test := &DATest{}
68 // Start the embedded etcd server
69 var err error
Mahir Gunyel03de0d32020-06-03 01:36:59 -070070 test.etcdServer, test.kvClientPort, err = tst.StartEmbeddedEtcdServer("voltha.rwcore.da.test", "voltha.rwcore.da.etcd", "error")
khenaidoo6e55d9e2019-12-12 18:26:26 -050071 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +000072 logger.Fatal(err)
khenaidoo6e55d9e2019-12-12 18:26:26 -050073 }
74 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -070075 test.kClient = mock_kafka.NewKafkaClient()
khenaidoo6e55d9e2019-12-12 18:26:26 -050076 test.oltAdapterName = "olt_adapter_mock"
77 test.onuAdapterName = "onu_adapter_mock"
78 test.coreInstanceID = "rw-da-test"
79 test.defaultTimeout = 5 * time.Second
80 test.maxTimeout = 20 * time.Second
81 test.done = make(chan int)
82 parentID := com.GetRandomString(10)
83 test.device = &voltha.Device{
84 Type: "onu_adapter_mock",
85 ParentId: parentID,
86 ParentPortNo: 1,
87 VendorId: "onu_adapter_mock",
88 Adapter: "onu_adapter_mock",
89 Vlan: 100,
90 Address: nil,
91 ProxyAddress: &voltha.Device_ProxyAddress{
92 DeviceId: parentID,
93 DeviceType: "olt_adapter_mock",
94 ChannelId: 100,
95 ChannelGroupId: 0,
96 ChannelTermination: "",
97 OnuId: 2,
98 },
99 AdminState: voltha.AdminState_PREPROVISIONED,
100 OperStatus: voltha.OperStatus_UNKNOWN,
101 Reason: "All good",
102 ConnectStatus: voltha.ConnectStatus_UNKNOWN,
103 Custom: nil,
104 Ports: []*voltha.Port{
105 {PortNo: 1, Label: "pon-1", Type: voltha.Port_PON_ONU, AdminState: voltha.AdminState_ENABLED,
106 OperStatus: voltha.OperStatus_ACTIVE, Peers: []*voltha.Port_PeerPort{{DeviceId: parentID, PortNo: 1}}},
107 {PortNo: 100, Label: "uni-100", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
108 OperStatus: voltha.OperStatus_ACTIVE},
109 },
110 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500111 return test
112}
113
David Bainbridge9ae13132020-06-22 17:28:01 -0700114func (dat *DATest) startCore() {
khenaidoo6e55d9e2019-12-12 18:26:26 -0500115 cfg := config.NewRWCoreFlags()
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700116 cfg.CoreTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -0400117 cfg.DefaultRequestTimeout = dat.defaultTimeout
Neha Sharmad1387da2020-05-07 20:07:28 +0000118 cfg.KVStoreAddress = "127.0.0.1" + ":" + strconv.Itoa(dat.kvClientPort)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500119 grpcPort, err := freeport.GetFreePort()
120 if err != nil {
Girish Kumarf56a4682020-03-20 20:07:46 +0000121 logger.Fatal("Cannot get a freeport for grpc")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500122 }
Neha Sharmad1387da2020-05-07 20:07:28 +0000123 cfg.GrpcAddress = "127.0.0.1" + ":" + strconv.Itoa(grpcPort)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700124 client := tst.SetupKVClient(cfg, dat.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400125 backend := &db.Backend{
126 Client: client,
127 StoreType: cfg.KVStoreType,
Neha Sharmad1387da2020-05-07 20:07:28 +0000128 Address: cfg.KVStoreAddress,
Kent Hagerman2b216042020-04-03 18:28:56 -0400129 Timeout: cfg.KVStoreTimeout,
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700130 LivenessChannelInterval: cfg.LiveProbeInterval / 2}
Kent Hagerman2b216042020-04-03 18:28:56 -0400131 dat.kmp = kafka.NewInterContainerProxy(
Neha Sharmad1387da2020-05-07 20:07:28 +0000132 kafka.InterContainerAddress(cfg.KafkaAdapterAddress),
Kent Hagerman2b216042020-04-03 18:28:56 -0400133 kafka.MsgClient(dat.kClient),
David Bainbridge9ae13132020-06-22 17:28:01 -0700134 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}))
Kent Hagerman2b216042020-04-03 18:28:56 -0400135
136 endpointMgr := kafka.NewEndpointManager(backend)
Kent Hagermanf5a67352020-04-30 15:15:26 -0400137 proxy := model.NewDBPath(backend)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700138 dat.adapterMgr = adapter.NewAdapterManager(proxy, dat.coreInstanceID, dat.kClient)
Kent Hagerman2b216042020-04-03 18:28:56 -0400139
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700140 dat.deviceMgr, dat.logicalDeviceMgr = NewManagers(proxy, dat.adapterMgr, dat.kmp, endpointMgr, cfg.CoreTopic, dat.coreInstanceID, cfg.DefaultCoreTimeout)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700141 dat.adapterMgr.Start(context.Background())
Kent Hagerman2b216042020-04-03 18:28:56 -0400142 if err = dat.kmp.Start(); err != nil {
143 logger.Fatal("Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530144 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700145
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700146 if err := dat.kmp.SubscribeWithDefaultRequestHandler(kafka.Topic{Name: cfg.CoreTopic}, kafka.OffsetNewest); err != nil {
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700147 logger.Fatalf("Cannot add default request handler: %s", err)
148 }
149
khenaidoo6e55d9e2019-12-12 18:26:26 -0500150}
151
152func (dat *DATest) stopAll() {
153 if dat.kClient != nil {
154 dat.kClient.Stop()
155 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400156 if dat.kmp != nil {
157 dat.kmp.Stop()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500158 }
159 if dat.etcdServer != nil {
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700160 tst.StopEmbeddedEtcdServer(dat.etcdServer)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500161 }
162}
163
Kent Hagerman2b216042020-04-03 18:28:56 -0400164func (dat *DATest) createDeviceAgent(t *testing.T) *Agent {
165 deviceMgr := dat.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500166 clonedDevice := proto.Clone(dat.device).(*voltha.Device)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700167 deviceAgent := newAgent(deviceMgr.adapterProxy, clonedDevice, deviceMgr, deviceMgr.dbPath, deviceMgr.dProxy, deviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500168 d, err := deviceAgent.start(context.TODO(), clonedDevice)
169 assert.Nil(t, err)
170 assert.NotNil(t, d)
171 deviceMgr.addDeviceAgentToMap(deviceAgent)
172 return deviceAgent
173}
174
Kent Hagerman2b216042020-04-03 18:28:56 -0400175func (dat *DATest) updateDeviceConcurrently(t *testing.T, da *Agent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400176 originalDevice, err := da.getDevice(context.Background())
177 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500178 assert.NotNil(t, originalDevice)
179 var localWG sync.WaitGroup
180
181 // Update device routine
182 var (
183 root = false
184 vendor = "onu_adapter_mock"
185 model = "go-mock"
186 serialNumber = com.GetRandomSerialNumber()
187 macAddress = strings.ToUpper(com.GetRandomMacAddress())
188 vlan = rand.Uint32()
189 reason = "testing concurrent device update"
190 portToAdd = &voltha.Port{PortNo: 101, Label: "uni-101", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
191 OperStatus: voltha.OperStatus_ACTIVE}
192 )
193 localWG.Add(1)
194 go func() {
195 deviceToUpdate := proto.Clone(originalDevice).(*voltha.Device)
196 deviceToUpdate.Root = root
197 deviceToUpdate.Vendor = vendor
198 deviceToUpdate.Model = model
199 deviceToUpdate.SerialNumber = serialNumber
200 deviceToUpdate.MacAddress = macAddress
201 deviceToUpdate.Vlan = vlan
202 deviceToUpdate.Reason = reason
npujar467fe752020-01-16 20:17:45 +0530203 err := da.updateDeviceUsingAdapterData(context.Background(), deviceToUpdate)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500204 assert.Nil(t, err)
205 localWG.Done()
206 }()
207
208 // Update the device status routine
209 localWG.Add(1)
210 go func() {
npujar467fe752020-01-16 20:17:45 +0530211 err := da.updateDeviceStatus(context.Background(), voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500212 assert.Nil(t, err)
213 localWG.Done()
214 }()
215
216 // Add a port routine
217 localWG.Add(1)
218 go func() {
npujar467fe752020-01-16 20:17:45 +0530219 err := da.addPort(context.Background(), portToAdd)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500220 assert.Nil(t, err)
221 localWG.Done()
222 }()
223
224 // wait for go routines to be done
225 localWG.Wait()
226
227 expectedChange := proto.Clone(originalDevice).(*voltha.Device)
228 expectedChange.OperStatus = voltha.OperStatus_ACTIVE
229 expectedChange.ConnectStatus = voltha.ConnectStatus_REACHABLE
230 expectedChange.Ports = append(expectedChange.Ports, portToAdd)
231 expectedChange.Root = root
232 expectedChange.Vendor = vendor
233 expectedChange.Model = model
234 expectedChange.SerialNumber = serialNumber
235 expectedChange.MacAddress = macAddress
236 expectedChange.Vlan = vlan
237 expectedChange.Reason = reason
238
khenaidoo442e7c72020-03-10 16:13:48 -0400239 updatedDevice, _ := da.getDevice(context.Background())
khenaidoo6e55d9e2019-12-12 18:26:26 -0500240 assert.NotNil(t, updatedDevice)
241 assert.True(t, proto.Equal(expectedChange, updatedDevice))
242
243 globalWG.Done()
244}
245
246func TestConcurrentDevices(t *testing.T) {
khenaidoo442e7c72020-03-10 16:13:48 -0400247 for i := 0; i < 2; i++ {
248 da := newDATest()
249 assert.NotNil(t, da)
250 defer da.stopAll()
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700251 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
khenaidoo442e7c72020-03-10 16:13:48 -0400252 // Start the Core
David Bainbridge9ae13132020-06-22 17:28:01 -0700253 da.startCore()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500254
khenaidoo442e7c72020-03-10 16:13:48 -0400255 var wg sync.WaitGroup
256 numConCurrentDeviceAgents := 20
257 for i := 0; i < numConCurrentDeviceAgents; i++ {
258 wg.Add(1)
259 a := da.createDeviceAgent(t)
260 go da.updateDeviceConcurrently(t, a, &wg)
261 }
262
263 wg.Wait()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500264 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500265}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700266func TestFlowUpdates(t *testing.T) {
267 da := newDATest()
268 assert.NotNil(t, da)
269 defer da.stopAll()
270
271 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
272 // Start the Core
David Bainbridge9ae13132020-06-22 17:28:01 -0700273 da.startCore()
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700274 da.oltAdapter, da.onuAdapter = tst.CreateAndregisterAdapters(t, da.kClient, da.coreInstanceID, da.oltAdapterName, da.onuAdapterName, da.adapterMgr)
275
276 a := da.createDeviceAgent(t)
277 cloned := a.getDeviceWithoutLock()
278 err := a.updateDeviceStateInStoreWithoutLock(context.Background(), cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
279 assert.Nil(t, err)
280 da.testFlowAddDeletes(t, a)
281}
282
283func TestGroupUpdates(t *testing.T) {
284 da := newDATest()
285 assert.NotNil(t, da)
286 defer da.stopAll()
287
288 // Start the Core
David Bainbridge9ae13132020-06-22 17:28:01 -0700289 da.startCore()
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700290 da.oltAdapter, da.onuAdapter = tst.CreateAndregisterAdapters(t, da.kClient, da.coreInstanceID, da.oltAdapterName, da.onuAdapterName, da.adapterMgr)
291 a := da.createDeviceAgent(t)
292 cloned := a.getDeviceWithoutLock()
293 err := a.updateDeviceStateInStoreWithoutLock(context.Background(), cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
294 assert.Nil(t, err)
295 da.testGroupAddDeletes(t, a)
296}
khenaidoob2121e52019-12-16 17:17:22 -0500297
298func isFlowSliceEqual(a, b []*ofp.OfpFlowStats) bool {
299 if len(a) != len(b) {
300 return false
301 }
302 sort.Slice(a, func(i, j int) bool {
303 return a[i].Id < a[j].Id
304 })
305 sort.Slice(b, func(i, j int) bool {
306 return b[i].Id < b[j].Id
307 })
308 for idx := range a {
309 if !proto.Equal(a[idx], b[idx]) {
310 return false
311 }
312 }
313 return true
314}
315
316func isGroupSliceEqual(a, b []*ofp.OfpGroupEntry) bool {
317 if len(a) != len(b) {
318 return false
319 }
320 sort.Slice(a, func(i, j int) bool {
321 return a[i].Desc.GroupId < a[j].Desc.GroupId
322 })
323 sort.Slice(b, func(i, j int) bool {
324 return b[i].Desc.GroupId < b[j].Desc.GroupId
325 })
326 for idx := range a {
327 if !proto.Equal(a[idx], b[idx]) {
328 return false
329 }
330 }
331 return true
332}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700333func changeToFlowList(flowList map[uint64]*ofp.OfpFlowStats) []*ofp.OfpFlowStats {
334 flows := make([]*ofp.OfpFlowStats, 0)
335 for _, flow := range flowList {
336 flows = append(flows, flow)
337 }
338 return flows
khenaidoob2121e52019-12-16 17:17:22 -0500339}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700340func changeToGroupList(groupList map[uint32]*ofp.OfpGroupEntry) []*ofp.OfpGroupEntry {
341 groups := make([]*ofp.OfpGroupEntry, 0)
342 for _, group := range groupList {
343 groups = append(groups, group)
344 }
345 return groups
346}
347func (dat *DATest) testFlowAddDeletes(t *testing.T, da *Agent) {
348 //Add new Flows on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500349 newFlows := []*ofp.OfpFlowStats{
350 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
351 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
352 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
353 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700354 err := da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
355 assert.Nil(t, err)
356 daFlows := changeToFlowList(da.listDeviceFlows())
357 assert.True(t, isFlowSliceEqual(newFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500358
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700359 //Add new Flows on existing ones
360 newFlows = []*ofp.OfpFlowStats{
361 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500362 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
363 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700364
365 expectedFlows := []*ofp.OfpFlowStats{
366 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
367 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
368 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
369 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
370 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
371 }
372
373 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
374 assert.Nil(t, err)
375 daFlows = changeToFlowList(da.listDeviceFlows())
376 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
377
378 //Add existing Flows again with a new flow
379 newFlows = []*ofp.OfpFlowStats{
380 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
381 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
382 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
383 }
384
385 expectedFlows = []*ofp.OfpFlowStats{
386 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
387 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
388 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
389 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
390 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
391 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
392 }
393
394 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
395 assert.Nil(t, err)
396 daFlows = changeToFlowList(da.listDeviceFlows())
397 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
398
399 //Add already existing flows again
400 newFlows = []*ofp.OfpFlowStats{
401 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
402 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
403 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
404 }
405
406 expectedFlows = []*ofp.OfpFlowStats{
407 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
408 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
409 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
410 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
411 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
412 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
413 }
414
415 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
416 assert.Nil(t, err)
417 daFlows = changeToFlowList(da.listDeviceFlows())
418 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
419
420 //Delete flows
421 flowsToDelete := []*ofp.OfpFlowStats{
422 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
423 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
424 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
425 }
426
427 expectedFlows = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500428 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
429 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
430 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
431 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700432
433 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
434 assert.Nil(t, err)
435 daFlows = changeToFlowList(da.listDeviceFlows())
436 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
437 //Delete flows with an unexisting one
438 flowsToDelete = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500439 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700440 {Id: 129, TableId: 1290, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1290000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500441 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700442
443 expectedFlows = []*ofp.OfpFlowStats{
444 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500445 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500446 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700447
448 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
449 assert.Nil(t, err)
450 daFlows = changeToFlowList(da.listDeviceFlows())
451 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500452}
453
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700454func (dat *DATest) testGroupAddDeletes(t *testing.T, da *Agent) {
455 //Add new Groups on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500456 newGroups := []*ofp.OfpGroupEntry{
457 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
458 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
459 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700460 err := da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
461 assert.Nil(t, err)
462 daGroups := changeToGroupList(da.listDeviceGroups())
463 assert.True(t, isGroupSliceEqual(newGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500464
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700465 //Add new Groups on existing ones
466 newGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500467 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
468 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
469 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700470 expectedGroups := []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500471 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
472 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
473 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
474 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
475 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700476 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
477 assert.Nil(t, err)
478 daGroups = changeToGroupList(da.listDeviceGroups())
479 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500480
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700481 //Add new Groups on existing ones
482 newGroups = []*ofp.OfpGroupEntry{
483 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
484 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
485 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500486 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700487 expectedGroups = []*ofp.OfpGroupEntry{
488 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500489 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
490 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700491 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
492 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500493 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700494 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
495 assert.Nil(t, err)
496 daGroups = changeToGroupList(da.listDeviceGroups())
497 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
498
499 //Modify Group
500 updtGroups := []*ofp.OfpGroupEntry{
501 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
502 }
503 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500504 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500505 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700506 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
507 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
508 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500509 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700510 err = da.updateFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, updtGroups, &voltha.FlowMetadata{})
511 assert.Nil(t, err)
512 daGroups = changeToGroupList(da.listDeviceGroups())
513 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
514
515 //Delete Group
516 delGroups := []*ofp.OfpGroupEntry{
517 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
518 }
519 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500520 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700521 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
522 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
523 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
524 }
525 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
526 assert.Nil(t, err)
527 daGroups = changeToGroupList(da.listDeviceGroups())
528 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
529
530 //Delete Group
531 delGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500532 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
533 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700534 expectedGroups = []*ofp.OfpGroupEntry{
535 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
536 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
537 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
538 }
539 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
540 assert.Nil(t, err)
541 daGroups = changeToGroupList(da.listDeviceGroups())
542 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500543}