blob: e9bd663d2d8ab17c19e3f010a5bc2063fa2b9084 [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
Rohan Agrawal31f21802020-06-12 05:38:46 +000066func newDATest(ctx context.Context) *DATest {
khenaidoo6e55d9e2019-12-12 18:26:26 -050067 test := &DATest{}
68 // Start the embedded etcd server
69 var err error
Rohan Agrawal31f21802020-06-12 05:38:46 +000070 test.etcdServer, test.kvClientPort, err = tst.StartEmbeddedEtcdServer(ctx, "voltha.rwcore.da.test", "voltha.rwcore.da.etcd", "error")
khenaidoo6e55d9e2019-12-12 18:26:26 -050071 if err != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +000072 logger.Fatal(ctx, 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
Rohan Agrawal31f21802020-06-12 05:38:46 +0000114func (dat *DATest) startCore(ctx context.Context) {
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 {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000121 logger.Fatal(ctx, "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)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000124 client := tst.SetupKVClient(ctx, 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)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000138 dat.adapterMgr = adapter.NewAdapterManager(ctx, 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())
Rohan Agrawal31f21802020-06-12 05:38:46 +0000142 if err = dat.kmp.Start(ctx); err != nil {
143 logger.Fatal(ctx, "Cannot start InterContainerProxy")
Thomas Lee Se5a44012019-11-07 20:32:24 +0530144 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700145
Rohan Agrawal31f21802020-06-12 05:38:46 +0000146 if err := dat.kmp.SubscribeWithDefaultRequestHandler(ctx, kafka.Topic{Name: cfg.CoreTopic}, kafka.OffsetNewest); err != nil {
147 logger.Fatalf(ctx, "Cannot add default request handler: %s", err)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700148 }
149
khenaidoo6e55d9e2019-12-12 18:26:26 -0500150}
151
Rohan Agrawal31f21802020-06-12 05:38:46 +0000152func (dat *DATest) stopAll(ctx context.Context) {
khenaidoo6e55d9e2019-12-12 18:26:26 -0500153 if dat.kClient != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000154 dat.kClient.Stop(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500155 }
Kent Hagerman2b216042020-04-03 18:28:56 -0400156 if dat.kmp != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000157 dat.kmp.Stop(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500158 }
159 if dat.etcdServer != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000160 tst.StopEmbeddedEtcdServer(ctx, 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) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000247 ctx := context.Background()
khenaidoo442e7c72020-03-10 16:13:48 -0400248 for i := 0; i < 2; i++ {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000249 da := newDATest(ctx)
khenaidoo442e7c72020-03-10 16:13:48 -0400250 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000251 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700252 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
khenaidoo442e7c72020-03-10 16:13:48 -0400253 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000254 da.startCore(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500255
khenaidoo442e7c72020-03-10 16:13:48 -0400256 var wg sync.WaitGroup
257 numConCurrentDeviceAgents := 20
258 for i := 0; i < numConCurrentDeviceAgents; i++ {
259 wg.Add(1)
260 a := da.createDeviceAgent(t)
261 go da.updateDeviceConcurrently(t, a, &wg)
262 }
263
264 wg.Wait()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500265 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500266}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700267func TestFlowUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000268 ctx := context.Background()
269 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700270 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000271 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700272
273 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
274 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000275 da.startCore(ctx)
276 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 -0700277
278 a := da.createDeviceAgent(t)
279 cloned := a.getDeviceWithoutLock()
Rohan Agrawal31f21802020-06-12 05:38:46 +0000280 err := a.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700281 assert.Nil(t, err)
282 da.testFlowAddDeletes(t, a)
283}
284
285func TestGroupUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000286 ctx := context.Background()
287 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700288 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000289 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700290
291 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000292 da.startCore(ctx)
293 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 -0700294 a := da.createDeviceAgent(t)
295 cloned := a.getDeviceWithoutLock()
Rohan Agrawal31f21802020-06-12 05:38:46 +0000296 err := a.updateDeviceStateInStoreWithoutLock(ctx, cloned, voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700297 assert.Nil(t, err)
298 da.testGroupAddDeletes(t, a)
299}
khenaidoob2121e52019-12-16 17:17:22 -0500300
301func isFlowSliceEqual(a, b []*ofp.OfpFlowStats) bool {
302 if len(a) != len(b) {
303 return false
304 }
305 sort.Slice(a, func(i, j int) bool {
306 return a[i].Id < a[j].Id
307 })
308 sort.Slice(b, func(i, j int) bool {
309 return b[i].Id < b[j].Id
310 })
311 for idx := range a {
312 if !proto.Equal(a[idx], b[idx]) {
313 return false
314 }
315 }
316 return true
317}
318
319func isGroupSliceEqual(a, b []*ofp.OfpGroupEntry) bool {
320 if len(a) != len(b) {
321 return false
322 }
323 sort.Slice(a, func(i, j int) bool {
324 return a[i].Desc.GroupId < a[j].Desc.GroupId
325 })
326 sort.Slice(b, func(i, j int) bool {
327 return b[i].Desc.GroupId < b[j].Desc.GroupId
328 })
329 for idx := range a {
330 if !proto.Equal(a[idx], b[idx]) {
331 return false
332 }
333 }
334 return true
335}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700336func changeToFlowList(flowList map[uint64]*ofp.OfpFlowStats) []*ofp.OfpFlowStats {
337 flows := make([]*ofp.OfpFlowStats, 0)
338 for _, flow := range flowList {
339 flows = append(flows, flow)
340 }
341 return flows
khenaidoob2121e52019-12-16 17:17:22 -0500342}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700343func changeToGroupList(groupList map[uint32]*ofp.OfpGroupEntry) []*ofp.OfpGroupEntry {
344 groups := make([]*ofp.OfpGroupEntry, 0)
345 for _, group := range groupList {
346 groups = append(groups, group)
347 }
348 return groups
349}
350func (dat *DATest) testFlowAddDeletes(t *testing.T, da *Agent) {
351 //Add new Flows on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500352 newFlows := []*ofp.OfpFlowStats{
353 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
354 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
355 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
356 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700357 err := da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
358 assert.Nil(t, err)
359 daFlows := changeToFlowList(da.listDeviceFlows())
360 assert.True(t, isFlowSliceEqual(newFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500361
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700362 //Add new Flows on existing ones
363 newFlows = []*ofp.OfpFlowStats{
364 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500365 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
366 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700367
368 expectedFlows := []*ofp.OfpFlowStats{
369 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
370 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
371 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
372 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
373 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
374 }
375
376 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
377 assert.Nil(t, err)
378 daFlows = changeToFlowList(da.listDeviceFlows())
379 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
380
381 //Add existing Flows again with a new flow
382 newFlows = []*ofp.OfpFlowStats{
383 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
384 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
385 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
386 }
387
388 expectedFlows = []*ofp.OfpFlowStats{
389 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
390 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
391 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
392 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
393 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
394 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
395 }
396
397 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
398 assert.Nil(t, err)
399 daFlows = changeToFlowList(da.listDeviceFlows())
400 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
401
402 //Add already existing flows again
403 newFlows = []*ofp.OfpFlowStats{
404 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
405 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
406 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
407 }
408
409 expectedFlows = []*ofp.OfpFlowStats{
410 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
411 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
412 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
413 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
414 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
415 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
416 }
417
418 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
419 assert.Nil(t, err)
420 daFlows = changeToFlowList(da.listDeviceFlows())
421 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
422
423 //Delete flows
424 flowsToDelete := []*ofp.OfpFlowStats{
425 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
426 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
427 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
428 }
429
430 expectedFlows = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500431 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
432 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
433 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
434 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700435
436 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
437 assert.Nil(t, err)
438 daFlows = changeToFlowList(da.listDeviceFlows())
439 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
440 //Delete flows with an unexisting one
441 flowsToDelete = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500442 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700443 {Id: 129, TableId: 1290, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1290000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500444 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700445
446 expectedFlows = []*ofp.OfpFlowStats{
447 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500448 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500449 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700450
451 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &voltha.FlowMetadata{})
452 assert.Nil(t, err)
453 daFlows = changeToFlowList(da.listDeviceFlows())
454 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500455}
456
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700457func (dat *DATest) testGroupAddDeletes(t *testing.T, da *Agent) {
458 //Add new Groups on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500459 newGroups := []*ofp.OfpGroupEntry{
460 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
461 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
462 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700463 err := da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
464 assert.Nil(t, err)
465 daGroups := changeToGroupList(da.listDeviceGroups())
466 assert.True(t, isGroupSliceEqual(newGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500467
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700468 //Add new Groups on existing ones
469 newGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500470 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
471 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
472 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700473 expectedGroups := []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500474 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
475 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
476 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
477 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
478 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700479 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
480 assert.Nil(t, err)
481 daGroups = changeToGroupList(da.listDeviceGroups())
482 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500483
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700484 //Add new Groups on existing ones
485 newGroups = []*ofp.OfpGroupEntry{
486 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
487 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
488 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500489 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700490 expectedGroups = []*ofp.OfpGroupEntry{
491 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500492 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
493 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700494 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
495 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500496 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700497 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &voltha.FlowMetadata{})
498 assert.Nil(t, err)
499 daGroups = changeToGroupList(da.listDeviceGroups())
500 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
501
502 //Modify Group
503 updtGroups := []*ofp.OfpGroupEntry{
504 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
505 }
506 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500507 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500508 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700509 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
510 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
511 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500512 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700513 err = da.updateFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, updtGroups, &voltha.FlowMetadata{})
514 assert.Nil(t, err)
515 daGroups = changeToGroupList(da.listDeviceGroups())
516 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
517
518 //Delete Group
519 delGroups := []*ofp.OfpGroupEntry{
520 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
521 }
522 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500523 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700524 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
525 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
526 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
527 }
528 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
529 assert.Nil(t, err)
530 daGroups = changeToGroupList(da.listDeviceGroups())
531 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
532
533 //Delete Group
534 delGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500535 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
536 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700537 expectedGroups = []*ofp.OfpGroupEntry{
538 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
539 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
540 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
541 }
542 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &voltha.FlowMetadata{})
543 assert.Nil(t, err)
544 daGroups = changeToGroupList(da.listDeviceGroups())
545 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500546}