blob: 92977ac0c5807293a2177be5d0a5ceac187a68cb [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
Kent Hagerman2a07b862020-06-19 15:23:07 -040063 devicePorts map[uint32]*voltha.Port
Kent Hagerman2b216042020-04-03 18:28:56 -040064 done chan int
khenaidoo6e55d9e2019-12-12 18:26:26 -050065}
66
Rohan Agrawal31f21802020-06-12 05:38:46 +000067func newDATest(ctx context.Context) *DATest {
khenaidoo6e55d9e2019-12-12 18:26:26 -050068 test := &DATest{}
69 // Start the embedded etcd server
70 var err error
Rohan Agrawal31f21802020-06-12 05:38:46 +000071 test.etcdServer, test.kvClientPort, err = tst.StartEmbeddedEtcdServer(ctx, "voltha.rwcore.da.test", "voltha.rwcore.da.etcd", "error")
khenaidoo6e55d9e2019-12-12 18:26:26 -050072 if err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +000073 logger.Fatal(ctx, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -050074 }
75 // Create the kafka client
Matteo Scandolod525ae32020-04-02 17:27:29 -070076 test.kClient = mock_kafka.NewKafkaClient()
khenaidoo6e55d9e2019-12-12 18:26:26 -050077 test.oltAdapterName = "olt_adapter_mock"
78 test.onuAdapterName = "onu_adapter_mock"
79 test.coreInstanceID = "rw-da-test"
80 test.defaultTimeout = 5 * time.Second
81 test.maxTimeout = 20 * time.Second
82 test.done = make(chan int)
83 parentID := com.GetRandomString(10)
84 test.device = &voltha.Device{
85 Type: "onu_adapter_mock",
86 ParentId: parentID,
87 ParentPortNo: 1,
88 VendorId: "onu_adapter_mock",
89 Adapter: "onu_adapter_mock",
90 Vlan: 100,
91 Address: nil,
92 ProxyAddress: &voltha.Device_ProxyAddress{
93 DeviceId: parentID,
94 DeviceType: "olt_adapter_mock",
95 ChannelId: 100,
96 ChannelGroupId: 0,
97 ChannelTermination: "",
98 OnuId: 2,
99 },
100 AdminState: voltha.AdminState_PREPROVISIONED,
101 OperStatus: voltha.OperStatus_UNKNOWN,
102 Reason: "All good",
103 ConnectStatus: voltha.ConnectStatus_UNKNOWN,
104 Custom: nil,
Kent Hagerman2a07b862020-06-19 15:23:07 -0400105 }
106 test.devicePorts = map[uint32]*voltha.Port{
107 1: {PortNo: 1, Label: "pon-1", Type: voltha.Port_PON_ONU, AdminState: voltha.AdminState_ENABLED,
108 OperStatus: voltha.OperStatus_ACTIVE, Peers: []*voltha.Port_PeerPort{{DeviceId: parentID, PortNo: 1}}},
109 100: {PortNo: 100, Label: "uni-100", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
110 OperStatus: voltha.OperStatus_ACTIVE},
khenaidoo6e55d9e2019-12-12 18:26:26 -0500111 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500112 return test
113}
114
Rohan Agrawal31f21802020-06-12 05:38:46 +0000115func (dat *DATest) startCore(ctx context.Context) {
khenaidoo6e55d9e2019-12-12 18:26:26 -0500116 cfg := config.NewRWCoreFlags()
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700117 cfg.CoreTopic = "rw_core"
khenaidoo442e7c72020-03-10 16:13:48 -0400118 cfg.DefaultRequestTimeout = dat.defaultTimeout
Neha Sharmad1387da2020-05-07 20:07:28 +0000119 cfg.KVStoreAddress = "127.0.0.1" + ":" + strconv.Itoa(dat.kvClientPort)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500120 grpcPort, err := freeport.GetFreePort()
121 if err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000122 logger.Fatal(ctx, "Cannot get a freeport for grpc")
khenaidoo6e55d9e2019-12-12 18:26:26 -0500123 }
Neha Sharmad1387da2020-05-07 20:07:28 +0000124 cfg.GrpcAddress = "127.0.0.1" + ":" + strconv.Itoa(grpcPort)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000125 client := tst.SetupKVClient(ctx, cfg, dat.coreInstanceID)
Kent Hagerman2b216042020-04-03 18:28:56 -0400126 backend := &db.Backend{
127 Client: client,
128 StoreType: cfg.KVStoreType,
Neha Sharmad1387da2020-05-07 20:07:28 +0000129 Address: cfg.KVStoreAddress,
Kent Hagerman2b216042020-04-03 18:28:56 -0400130 Timeout: cfg.KVStoreTimeout,
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700131 LivenessChannelInterval: cfg.LiveProbeInterval / 2}
Kent Hagerman2b216042020-04-03 18:28:56 -0400132 dat.kmp = kafka.NewInterContainerProxy(
Neha Sharmad1387da2020-05-07 20:07:28 +0000133 kafka.InterContainerAddress(cfg.KafkaAdapterAddress),
Kent Hagerman2b216042020-04-03 18:28:56 -0400134 kafka.MsgClient(dat.kClient),
David Bainbridge9ae13132020-06-22 17:28:01 -0700135 kafka.DefaultTopic(&kafka.Topic{Name: cfg.CoreTopic}))
Kent Hagerman2b216042020-04-03 18:28:56 -0400136
137 endpointMgr := kafka.NewEndpointManager(backend)
Kent Hagermanf5a67352020-04-30 15:15:26 -0400138 proxy := model.NewDBPath(backend)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000139 dat.adapterMgr = adapter.NewAdapterManager(ctx, proxy, dat.coreInstanceID, dat.kClient)
Kent Hagerman2b216042020-04-03 18:28:56 -0400140
serkant.uluderya8ff291d2020-05-20 00:58:00 -0700141 dat.deviceMgr, dat.logicalDeviceMgr = NewManagers(proxy, dat.adapterMgr, dat.kmp, endpointMgr, cfg.CoreTopic, dat.coreInstanceID, cfg.DefaultCoreTimeout)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700142 dat.adapterMgr.Start(context.Background())
Rohan Agrawal31f21802020-06-12 05:38:46 +0000143 if err = dat.kmp.Start(ctx); err != nil {
144 logger.Fatal(ctx, "Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530145 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700146
Rohan Agrawal31f21802020-06-12 05:38:46 +0000147 if err := dat.kmp.SubscribeWithDefaultRequestHandler(ctx, kafka.Topic{Name: cfg.CoreTopic}, kafka.OffsetNewest); err != nil {
148 logger.Fatalf(ctx, "Cannot add default request handler: %s", err)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700149 }
150
khenaidoo6e55d9e2019-12-12 18:26:26 -0500151}
152
Rohan Agrawal31f21802020-06-12 05:38:46 +0000153func (dat *DATest) stopAll(ctx context.Context) {
khenaidoo6e55d9e2019-12-12 18:26:26 -0500154 if dat.kClient != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000155 dat.kClient.Stop(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500156 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400157 if dat.kmp != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000158 dat.kmp.Stop(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500159 }
160 if dat.etcdServer != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000161 tst.StopEmbeddedEtcdServer(ctx, dat.etcdServer)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500162 }
163}
164
Kent Hagerman2b216042020-04-03 18:28:56 -0400165func (dat *DATest) createDeviceAgent(t *testing.T) *Agent {
166 deviceMgr := dat.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500167 clonedDevice := proto.Clone(dat.device).(*voltha.Device)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700168 deviceAgent := newAgent(deviceMgr.adapterProxy, clonedDevice, deviceMgr, deviceMgr.dbPath, deviceMgr.dProxy, deviceMgr.defaultTimeout)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500169 d, err := deviceAgent.start(context.TODO(), clonedDevice)
170 assert.Nil(t, err)
171 assert.NotNil(t, d)
Kent Hagerman2a07b862020-06-19 15:23:07 -0400172 for _, port := range dat.devicePorts {
173 err := deviceAgent.addPort(context.TODO(), port)
174 assert.Nil(t, err)
175 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500176 deviceMgr.addDeviceAgentToMap(deviceAgent)
177 return deviceAgent
178}
179
Kent Hagerman2b216042020-04-03 18:28:56 -0400180func (dat *DATest) updateDeviceConcurrently(t *testing.T, da *Agent, globalWG *sync.WaitGroup) {
khenaidoo442e7c72020-03-10 16:13:48 -0400181 originalDevice, err := da.getDevice(context.Background())
Kent Hagerman2a07b862020-06-19 15:23:07 -0400182 originalDevicePorts := da.listDevicePorts()
khenaidoo442e7c72020-03-10 16:13:48 -0400183 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500184 assert.NotNil(t, originalDevice)
185 var localWG sync.WaitGroup
186
187 // Update device routine
188 var (
189 root = false
190 vendor = "onu_adapter_mock"
191 model = "go-mock"
192 serialNumber = com.GetRandomSerialNumber()
193 macAddress = strings.ToUpper(com.GetRandomMacAddress())
194 vlan = rand.Uint32()
195 reason = "testing concurrent device update"
196 portToAdd = &voltha.Port{PortNo: 101, Label: "uni-101", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
197 OperStatus: voltha.OperStatus_ACTIVE}
198 )
199 localWG.Add(1)
200 go func() {
201 deviceToUpdate := proto.Clone(originalDevice).(*voltha.Device)
202 deviceToUpdate.Root = root
203 deviceToUpdate.Vendor = vendor
204 deviceToUpdate.Model = model
205 deviceToUpdate.SerialNumber = serialNumber
206 deviceToUpdate.MacAddress = macAddress
207 deviceToUpdate.Vlan = vlan
208 deviceToUpdate.Reason = reason
npujar467fe752020-01-16 20:17:45 +0530209 err := da.updateDeviceUsingAdapterData(context.Background(), deviceToUpdate)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500210 assert.Nil(t, err)
211 localWG.Done()
212 }()
213
214 // Update the device status routine
215 localWG.Add(1)
216 go func() {
npujar467fe752020-01-16 20:17:45 +0530217 err := da.updateDeviceStatus(context.Background(), voltha.OperStatus_ACTIVE, voltha.ConnectStatus_REACHABLE)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500218 assert.Nil(t, err)
219 localWG.Done()
220 }()
221
222 // Add a port routine
223 localWG.Add(1)
224 go func() {
npujar467fe752020-01-16 20:17:45 +0530225 err := da.addPort(context.Background(), portToAdd)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500226 assert.Nil(t, err)
227 localWG.Done()
228 }()
229
230 // wait for go routines to be done
231 localWG.Wait()
232
233 expectedChange := proto.Clone(originalDevice).(*voltha.Device)
234 expectedChange.OperStatus = voltha.OperStatus_ACTIVE
235 expectedChange.ConnectStatus = voltha.ConnectStatus_REACHABLE
khenaidoo6e55d9e2019-12-12 18:26:26 -0500236 expectedChange.Root = root
237 expectedChange.Vendor = vendor
238 expectedChange.Model = model
239 expectedChange.SerialNumber = serialNumber
240 expectedChange.MacAddress = macAddress
241 expectedChange.Vlan = vlan
242 expectedChange.Reason = reason
243
khenaidoo442e7c72020-03-10 16:13:48 -0400244 updatedDevice, _ := da.getDevice(context.Background())
Kent Hagerman2a07b862020-06-19 15:23:07 -0400245 updatedDevicePorts := da.listDevicePorts()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500246 assert.NotNil(t, updatedDevice)
247 assert.True(t, proto.Equal(expectedChange, updatedDevice))
Kent Hagerman2a07b862020-06-19 15:23:07 -0400248 assert.Equal(t, len(originalDevicePorts)+1, len(updatedDevicePorts))
249 assert.True(t, proto.Equal(updatedDevicePorts[portToAdd.PortNo], portToAdd))
khenaidoo6e55d9e2019-12-12 18:26:26 -0500250
251 globalWG.Done()
252}
253
254func TestConcurrentDevices(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000255 ctx := context.Background()
khenaidoo442e7c72020-03-10 16:13:48 -0400256 for i := 0; i < 2; i++ {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000257 da := newDATest(ctx)
khenaidoo442e7c72020-03-10 16:13:48 -0400258 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000259 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700260 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
khenaidoo442e7c72020-03-10 16:13:48 -0400261 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000262 da.startCore(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500263
khenaidoo442e7c72020-03-10 16:13:48 -0400264 var wg sync.WaitGroup
265 numConCurrentDeviceAgents := 20
266 for i := 0; i < numConCurrentDeviceAgents; i++ {
267 wg.Add(1)
268 a := da.createDeviceAgent(t)
269 go da.updateDeviceConcurrently(t, a, &wg)
270 }
271
272 wg.Wait()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500273 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500274}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700275func TestFlowUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000276 ctx := context.Background()
277 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700278 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000279 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700280
281 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
282 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000283 da.startCore(ctx)
284 da.oltAdapter, da.onuAdapter = tst.CreateAndregisterAdapters(ctx, t, da.kClient, da.coreInstanceID, da.oltAdapterName, da.onuAdapterName, da.adapterMgr)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700285
286 a := da.createDeviceAgent(t)
287 cloned := a.getDeviceWithoutLock()
Rohan Agrawal31f21802020-06-12 05:38:46 +0000288 err := a.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700289 assert.Nil(t, err)
290 da.testFlowAddDeletes(t, a)
291}
292
293func TestGroupUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000294 ctx := context.Background()
295 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700296 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000297 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700298
299 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000300 da.startCore(ctx)
301 da.oltAdapter, da.onuAdapter = tst.CreateAndregisterAdapters(ctx, t, da.kClient, da.coreInstanceID, da.oltAdapterName, da.onuAdapterName, da.adapterMgr)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700302 a := da.createDeviceAgent(t)
303 cloned := a.getDeviceWithoutLock()
Rohan Agrawal31f21802020-06-12 05:38:46 +0000304 err := a.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700305 assert.Nil(t, err)
306 da.testGroupAddDeletes(t, a)
307}
khenaidoob2121e52019-12-16 17:17:22 -0500308
309func isFlowSliceEqual(a, b []*ofp.OfpFlowStats) bool {
310 if len(a) != len(b) {
311 return false
312 }
313 sort.Slice(a, func(i, j int) bool {
314 return a[i].Id < a[j].Id
315 })
316 sort.Slice(b, func(i, j int) bool {
317 return b[i].Id < b[j].Id
318 })
319 for idx := range a {
320 if !proto.Equal(a[idx], b[idx]) {
321 return false
322 }
323 }
324 return true
325}
326
327func isGroupSliceEqual(a, b []*ofp.OfpGroupEntry) bool {
328 if len(a) != len(b) {
329 return false
330 }
331 sort.Slice(a, func(i, j int) bool {
332 return a[i].Desc.GroupId < a[j].Desc.GroupId
333 })
334 sort.Slice(b, func(i, j int) bool {
335 return b[i].Desc.GroupId < b[j].Desc.GroupId
336 })
337 for idx := range a {
338 if !proto.Equal(a[idx], b[idx]) {
339 return false
340 }
341 }
342 return true
343}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700344func changeToFlowList(flowList map[uint64]*ofp.OfpFlowStats) []*ofp.OfpFlowStats {
345 flows := make([]*ofp.OfpFlowStats, 0)
346 for _, flow := range flowList {
347 flows = append(flows, flow)
348 }
349 return flows
khenaidoob2121e52019-12-16 17:17:22 -0500350}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700351func changeToGroupList(groupList map[uint32]*ofp.OfpGroupEntry) []*ofp.OfpGroupEntry {
352 groups := make([]*ofp.OfpGroupEntry, 0)
353 for _, group := range groupList {
354 groups = append(groups, group)
355 }
356 return groups
357}
358func (dat *DATest) testFlowAddDeletes(t *testing.T, da *Agent) {
359 //Add new Flows on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500360 newFlows := []*ofp.OfpFlowStats{
361 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
362 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
363 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
364 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700365 err := da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
366 assert.Nil(t, err)
367 daFlows := changeToFlowList(da.listDeviceFlows())
368 assert.True(t, isFlowSliceEqual(newFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500369
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700370 //Add new Flows on existing ones
371 newFlows = []*ofp.OfpFlowStats{
372 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500373 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
374 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700375
376 expectedFlows := []*ofp.OfpFlowStats{
377 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
378 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
379 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
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: 1270000, PacketCount: 0},
382 }
383
384 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
385 assert.Nil(t, err)
386 daFlows = changeToFlowList(da.listDeviceFlows())
387 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
388
389 //Add existing Flows again with a new flow
390 newFlows = []*ofp.OfpFlowStats{
391 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
392 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
393 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
394 }
395
396 expectedFlows = []*ofp.OfpFlowStats{
397 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
398 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
399 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
400 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
401 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
402 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
403 }
404
405 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
406 assert.Nil(t, err)
407 daFlows = changeToFlowList(da.listDeviceFlows())
408 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
409
410 //Add already existing flows again
411 newFlows = []*ofp.OfpFlowStats{
412 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
413 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
414 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
415 }
416
417 expectedFlows = []*ofp.OfpFlowStats{
418 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
419 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
420 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
421 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
422 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
423 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
424 }
425
426 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
427 assert.Nil(t, err)
428 daFlows = changeToFlowList(da.listDeviceFlows())
429 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
430
431 //Delete flows
432 flowsToDelete := []*ofp.OfpFlowStats{
433 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
434 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
435 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
436 }
437
438 expectedFlows = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500439 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
440 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
441 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
442 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700443
444 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
445 assert.Nil(t, err)
446 daFlows = changeToFlowList(da.listDeviceFlows())
447 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
448 //Delete flows with an unexisting one
449 flowsToDelete = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500450 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700451 {Id: 129, TableId: 1290, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1290000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500452 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700453
454 expectedFlows = []*ofp.OfpFlowStats{
455 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500456 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500457 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700458
459 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
460 assert.Nil(t, err)
461 daFlows = changeToFlowList(da.listDeviceFlows())
462 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500463}
464
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700465func (dat *DATest) testGroupAddDeletes(t *testing.T, da *Agent) {
466 //Add new Groups on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500467 newGroups := []*ofp.OfpGroupEntry{
468 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
469 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
470 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700471 err := da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
472 assert.Nil(t, err)
473 daGroups := changeToGroupList(da.listDeviceGroups())
474 assert.True(t, isGroupSliceEqual(newGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500475
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700476 //Add new Groups on existing ones
477 newGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500478 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
479 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
480 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700481 expectedGroups := []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500482 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
483 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
484 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
485 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
486 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700487 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
488 assert.Nil(t, err)
489 daGroups = changeToGroupList(da.listDeviceGroups())
490 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500491
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700492 //Add new Groups on existing ones
493 newGroups = []*ofp.OfpGroupEntry{
494 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
495 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
496 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500497 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700498 expectedGroups = []*ofp.OfpGroupEntry{
499 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500500 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
501 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700502 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
503 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500504 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700505 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
506 assert.Nil(t, err)
507 daGroups = changeToGroupList(da.listDeviceGroups())
508 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
509
510 //Modify Group
511 updtGroups := []*ofp.OfpGroupEntry{
512 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
513 }
514 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500515 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500516 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700517 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
518 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
519 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500520 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700521 err = da.updateFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, updtGroups, &voltha.FlowMetadata{})
522 assert.Nil(t, err)
523 daGroups = changeToGroupList(da.listDeviceGroups())
524 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
525
526 //Delete Group
527 delGroups := []*ofp.OfpGroupEntry{
528 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
529 }
530 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500531 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700532 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
533 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
534 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
535 }
536 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
537 assert.Nil(t, err)
538 daGroups = changeToGroupList(da.listDeviceGroups())
539 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
540
541 //Delete Group
542 delGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500543 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
544 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700545 expectedGroups = []*ofp.OfpGroupEntry{
546 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
547 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
548 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
549 }
550 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
551 assert.Nil(t, err)
552 daGroups = changeToGroupList(da.listDeviceGroups())
553 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500554}