blob: 5cc1f2617c6677cbcae9dc33198cc1445de7f289 [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
khenaidood948f772021-08-11 17:49:24 -040029 ver "github.com/opencord/voltha-lib-go/v7/pkg/version"
khenaidoo9beaaf12021-10-19 17:32:01 -040030 ca "github.com/opencord/voltha-protos/v5/go/core_adapter"
khenaidood948f772021-08-11 17:49:24 -040031
khenaidoo6e55d9e2019-12-12 18:26:26 -050032 "github.com/gogo/protobuf/proto"
Kent Hagerman2b216042020-04-03 18:28:56 -040033 "github.com/opencord/voltha-go/db/model"
khenaidoo6e55d9e2019-12-12 18:26:26 -050034 "github.com/opencord/voltha-go/rw_core/config"
Kent Hagerman2b216042020-04-03 18:28:56 -040035 "github.com/opencord/voltha-go/rw_core/core/adapter"
Mahir Gunyel03de0d32020-06-03 01:36:59 -070036 tst "github.com/opencord/voltha-go/rw_core/test"
khenaidood948f772021-08-11 17:49:24 -040037 com "github.com/opencord/voltha-lib-go/v7/pkg/adapters/common"
38 "github.com/opencord/voltha-lib-go/v7/pkg/db"
39 "github.com/opencord/voltha-lib-go/v7/pkg/events"
40 "github.com/opencord/voltha-lib-go/v7/pkg/kafka"
41 "github.com/opencord/voltha-lib-go/v7/pkg/log"
42 mock_etcd "github.com/opencord/voltha-lib-go/v7/pkg/mocks/etcd"
43 mock_kafka "github.com/opencord/voltha-lib-go/v7/pkg/mocks/kafka"
44 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
45 "github.com/opencord/voltha-protos/v5/go/voltha"
khenaidoo6e55d9e2019-12-12 18:26:26 -050046 "github.com/phayes/freeport"
47 "github.com/stretchr/testify/assert"
khenaidoo6e55d9e2019-12-12 18:26:26 -050048)
49
50type DATest struct {
Kent Hagerman2b216042020-04-03 18:28:56 -040051 etcdServer *mock_etcd.EtcdServer
52 deviceMgr *Manager
53 logicalDeviceMgr *LogicalManager
Mahir Gunyel03de0d32020-06-03 01:36:59 -070054 adapterMgr *adapter.Manager
Kent Hagerman2b216042020-04-03 18:28:56 -040055 kClient kafka.Client
Himani Chawlab4c25912020-11-12 17:16:38 +053056 kEventClient kafka.Client
Kent Hagerman2b216042020-04-03 18:28:56 -040057 kvClientPort int
58 oltAdapterName string
59 onuAdapterName string
60 coreInstanceID string
khenaidood948f772021-08-11 17:49:24 -040061 internalTimeout time.Duration
Kent Hagerman2b216042020-04-03 18:28:56 -040062 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()
Himani Chawlab4c25912020-11-12 17:16:38 +053077 test.kEventClient = mock_kafka.NewKafkaClient()
khenaidood948f772021-08-11 17:49:24 -040078 test.oltAdapterName = "olt-mock-adapter"
79 test.onuAdapterName = "onu-mock-adapter"
khenaidoo6e55d9e2019-12-12 18:26:26 -050080 test.coreInstanceID = "rw-da-test"
khenaidood948f772021-08-11 17:49:24 -040081 test.internalTimeout = 5 * time.Second
khenaidoo6e55d9e2019-12-12 18:26:26 -050082 test.done = make(chan int)
83 parentID := com.GetRandomString(10)
84 test.device = &voltha.Device{
khenaidood948f772021-08-11 17:49:24 -040085 Type: "onu-mock-device-type",
khenaidoo6e55d9e2019-12-12 18:26:26 -050086 ParentId: parentID,
87 ParentPortNo: 1,
khenaidood948f772021-08-11 17:49:24 -040088 VendorId: "onu-mock-vendor",
khenaidoo6e55d9e2019-12-12 18:26:26 -050089 Vlan: 100,
90 Address: nil,
91 ProxyAddress: &voltha.Device_ProxyAddress{
92 DeviceId: parentID,
khenaidood948f772021-08-11 17:49:24 -040093 DeviceType: "olt-mock-device-type",
khenaidoo6e55d9e2019-12-12 18:26:26 -050094 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,
Kent Hagerman2a07b862020-06-19 15:23:07 -0400104 }
105 test.devicePorts = map[uint32]*voltha.Port{
106 1: {PortNo: 1, Label: "pon-1", Type: voltha.Port_PON_ONU, AdminState: voltha.AdminState_ENABLED,
107 OperStatus: voltha.OperStatus_ACTIVE, Peers: []*voltha.Port_PeerPort{{DeviceId: parentID, PortNo: 1}}},
108 100: {PortNo: 100, Label: "uni-100", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
109 OperStatus: voltha.OperStatus_ACTIVE},
khenaidoo6e55d9e2019-12-12 18:26:26 -0500110 }
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) {
David K. Bainbridge6080c172021-07-24 00:22:28 +0000115 cfg := &config.RWCoreFlags{}
116 cfg.ParseCommandArguments([]string{})
Himani Chawlab4c25912020-11-12 17:16:38 +0530117 cfg.EventTopic = "voltha.events"
khenaidood948f772021-08-11 17:49:24 -0400118 cfg.InternalTimeout = dat.internalTimeout
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 }
khenaidood948f772021-08-11 17:49:24 -0400124 cfg.GrpcNBIAddress = "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
Kent Hagermanf5a67352020-04-30 15:15:26 -0400133 proxy := model.NewDBPath(backend)
khenaidood948f772021-08-11 17:49:24 -0400134 dat.adapterMgr = adapter.NewAdapterManager(proxy, dat.coreInstanceID, backend, 5)
Himani Chawlab4c25912020-11-12 17:16:38 +0530135 eventProxy := events.NewEventProxy(events.MsgClient(dat.kEventClient), events.MsgTopic(kafka.Topic{Name: cfg.EventTopic}))
khenaidood948f772021-08-11 17:49:24 -0400136 dat.deviceMgr, dat.logicalDeviceMgr = NewManagers(proxy, dat.adapterMgr, cfg, dat.coreInstanceID, eventProxy)
137 dat.adapterMgr.Start(context.Background(), "agent-test")
138 dat.registerAdapters(context.Background())
139 log.SetAllLogLevel(log.FatalLevel)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500140}
141
Rohan Agrawal31f21802020-06-12 05:38:46 +0000142func (dat *DATest) stopAll(ctx context.Context) {
khenaidoo6e55d9e2019-12-12 18:26:26 -0500143 if dat.kClient != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000144 dat.kClient.Stop(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500145 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500146 if dat.etcdServer != nil {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000147 tst.StopEmbeddedEtcdServer(ctx, dat.etcdServer)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500148 }
Himani Chawlab4c25912020-11-12 17:16:38 +0530149 if dat.kEventClient != nil {
150 dat.kEventClient.Stop(ctx)
151 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500152}
153
Kent Hagerman2b216042020-04-03 18:28:56 -0400154func (dat *DATest) createDeviceAgent(t *testing.T) *Agent {
155 deviceMgr := dat.deviceMgr
khenaidoo6e55d9e2019-12-12 18:26:26 -0500156 clonedDevice := proto.Clone(dat.device).(*voltha.Device)
Himani Chawla4b4bd252021-11-08 15:59:40 +0530157 deviceAgent := newAgent(clonedDevice, deviceMgr, deviceMgr.dbPath, deviceMgr.dProxy, deviceMgr.internalTimeout, deviceMgr.rpcTimeout, deviceMgr.flowTimeout)
khenaidoo7585a962021-06-10 16:15:38 -0400158 d, err := deviceAgent.start(context.TODO(), false, clonedDevice)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500159 assert.Nil(t, err)
160 assert.NotNil(t, d)
Kent Hagerman2a07b862020-06-19 15:23:07 -0400161 for _, port := range dat.devicePorts {
162 err := deviceAgent.addPort(context.TODO(), port)
163 assert.Nil(t, err)
164 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500165 deviceMgr.addDeviceAgentToMap(deviceAgent)
166 return deviceAgent
167}
168
Kent Hagerman2b216042020-04-03 18:28:56 -0400169func (dat *DATest) updateDeviceConcurrently(t *testing.T, da *Agent, globalWG *sync.WaitGroup) {
Kent Hagermancba2f302020-07-28 13:37:36 -0400170 originalDevice, err := da.getDeviceReadOnly(context.Background())
Kent Hagerman2a07b862020-06-19 15:23:07 -0400171 originalDevicePorts := da.listDevicePorts()
khenaidoo442e7c72020-03-10 16:13:48 -0400172 assert.Nil(t, err)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500173 assert.NotNil(t, originalDevice)
174 var localWG sync.WaitGroup
175
176 // Update device routine
177 var (
178 root = false
179 vendor = "onu_adapter_mock"
180 model = "go-mock"
181 serialNumber = com.GetRandomSerialNumber()
182 macAddress = strings.ToUpper(com.GetRandomMacAddress())
183 vlan = rand.Uint32()
184 reason = "testing concurrent device update"
185 portToAdd = &voltha.Port{PortNo: 101, Label: "uni-101", Type: voltha.Port_ETHERNET_UNI, AdminState: voltha.AdminState_ENABLED,
186 OperStatus: voltha.OperStatus_ACTIVE}
187 )
188 localWG.Add(1)
189 go func() {
190 deviceToUpdate := proto.Clone(originalDevice).(*voltha.Device)
191 deviceToUpdate.Root = root
192 deviceToUpdate.Vendor = vendor
193 deviceToUpdate.Model = model
194 deviceToUpdate.SerialNumber = serialNumber
195 deviceToUpdate.MacAddress = macAddress
196 deviceToUpdate.Vlan = vlan
197 deviceToUpdate.Reason = reason
khenaidood948f772021-08-11 17:49:24 -0400198 deviceToUpdate.OperStatus = voltha.OperStatus_ACTIVE
199 deviceToUpdate.ConnectStatus = voltha.ConnectStatus_REACHABLE
npujar467fe752020-01-16 20:17:45 +0530200 err := da.updateDeviceUsingAdapterData(context.Background(), deviceToUpdate)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500201 assert.Nil(t, err)
202 localWG.Done()
203 }()
204
khenaidoo6e55d9e2019-12-12 18:26:26 -0500205 // Add a port routine
206 localWG.Add(1)
207 go func() {
npujar467fe752020-01-16 20:17:45 +0530208 err := da.addPort(context.Background(), portToAdd)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500209 assert.Nil(t, err)
210 localWG.Done()
211 }()
212
213 // wait for go routines to be done
214 localWG.Wait()
215
216 expectedChange := proto.Clone(originalDevice).(*voltha.Device)
217 expectedChange.OperStatus = voltha.OperStatus_ACTIVE
218 expectedChange.ConnectStatus = voltha.ConnectStatus_REACHABLE
khenaidoo6e55d9e2019-12-12 18:26:26 -0500219 expectedChange.Root = root
220 expectedChange.Vendor = vendor
221 expectedChange.Model = model
222 expectedChange.SerialNumber = serialNumber
223 expectedChange.MacAddress = macAddress
224 expectedChange.Vlan = vlan
225 expectedChange.Reason = reason
226
Kent Hagermancba2f302020-07-28 13:37:36 -0400227 updatedDevice, _ := da.getDeviceReadOnly(context.Background())
Kent Hagerman2a07b862020-06-19 15:23:07 -0400228 updatedDevicePorts := da.listDevicePorts()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500229 assert.NotNil(t, updatedDevice)
230 assert.True(t, proto.Equal(expectedChange, updatedDevice))
Kent Hagerman2a07b862020-06-19 15:23:07 -0400231 assert.Equal(t, len(originalDevicePorts)+1, len(updatedDevicePorts))
232 assert.True(t, proto.Equal(updatedDevicePorts[portToAdd.PortNo], portToAdd))
khenaidoo6e55d9e2019-12-12 18:26:26 -0500233
234 globalWG.Done()
235}
236
237func TestConcurrentDevices(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000238 ctx := context.Background()
khenaidoo442e7c72020-03-10 16:13:48 -0400239 for i := 0; i < 2; i++ {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000240 da := newDATest(ctx)
khenaidoo442e7c72020-03-10 16:13:48 -0400241 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000242 defer da.stopAll(ctx)
khenaidood948f772021-08-11 17:49:24 -0400243
khenaidoo442e7c72020-03-10 16:13:48 -0400244 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000245 da.startCore(ctx)
khenaidoo6e55d9e2019-12-12 18:26:26 -0500246
khenaidoo442e7c72020-03-10 16:13:48 -0400247 var wg sync.WaitGroup
248 numConCurrentDeviceAgents := 20
249 for i := 0; i < numConCurrentDeviceAgents; i++ {
250 wg.Add(1)
251 a := da.createDeviceAgent(t)
252 go da.updateDeviceConcurrently(t, a, &wg)
253 }
khenaidoo442e7c72020-03-10 16:13:48 -0400254 wg.Wait()
khenaidoo6e55d9e2019-12-12 18:26:26 -0500255 }
khenaidoo6e55d9e2019-12-12 18:26:26 -0500256}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700257func TestFlowUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000258 ctx := context.Background()
259 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700260 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000261 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700262
263 log.SetPackageLogLevel("github.com/opencord/voltha-go/rw_core/core", log.DebugLevel)
264 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000265 da.startCore(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700266 a := da.createDeviceAgent(t)
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400267 err1 := a.requestQueue.WaitForGreenLight(ctx)
268 assert.Nil(t, err1)
269 cloned := a.cloneDeviceWithoutLock()
270 cloned.AdminState, cloned.ConnectStatus, cloned.OperStatus = voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE
271 err2 := a.updateDeviceAndReleaseLock(ctx, cloned)
272 assert.Nil(t, err2)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700273 da.testFlowAddDeletes(t, a)
274}
275
276func TestGroupUpdates(t *testing.T) {
Rohan Agrawal31f21802020-06-12 05:38:46 +0000277 ctx := context.Background()
278 da := newDATest(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700279 assert.NotNil(t, da)
Rohan Agrawal31f21802020-06-12 05:38:46 +0000280 defer da.stopAll(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700281
282 // Start the Core
Rohan Agrawal31f21802020-06-12 05:38:46 +0000283 da.startCore(ctx)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700284 a := da.createDeviceAgent(t)
Kent Hagermanf6db9f12020-07-22 17:16:19 -0400285 err1 := a.requestQueue.WaitForGreenLight(ctx)
286 assert.Nil(t, err1)
287 cloned := a.cloneDeviceWithoutLock()
288 cloned.AdminState, cloned.ConnectStatus, cloned.OperStatus = voltha.AdminState_ENABLED, voltha.ConnectStatus_REACHABLE, voltha.OperStatus_ACTIVE
289 err2 := a.updateDeviceAndReleaseLock(ctx, cloned)
290 assert.Nil(t, err2)
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700291 da.testGroupAddDeletes(t, a)
292}
khenaidoob2121e52019-12-16 17:17:22 -0500293
294func isFlowSliceEqual(a, b []*ofp.OfpFlowStats) bool {
295 if len(a) != len(b) {
296 return false
297 }
298 sort.Slice(a, func(i, j int) bool {
299 return a[i].Id < a[j].Id
300 })
301 sort.Slice(b, func(i, j int) bool {
302 return b[i].Id < b[j].Id
303 })
304 for idx := range a {
305 if !proto.Equal(a[idx], b[idx]) {
306 return false
307 }
308 }
309 return true
310}
311
312func isGroupSliceEqual(a, b []*ofp.OfpGroupEntry) bool {
313 if len(a) != len(b) {
314 return false
315 }
316 sort.Slice(a, func(i, j int) bool {
317 return a[i].Desc.GroupId < a[j].Desc.GroupId
318 })
319 sort.Slice(b, func(i, j int) bool {
320 return b[i].Desc.GroupId < b[j].Desc.GroupId
321 })
322 for idx := range a {
323 if !proto.Equal(a[idx], b[idx]) {
324 return false
325 }
326 }
327 return true
328}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700329func changeToFlowList(flowList map[uint64]*ofp.OfpFlowStats) []*ofp.OfpFlowStats {
330 flows := make([]*ofp.OfpFlowStats, 0)
331 for _, flow := range flowList {
332 flows = append(flows, flow)
333 }
334 return flows
khenaidoob2121e52019-12-16 17:17:22 -0500335}
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700336func changeToGroupList(groupList map[uint32]*ofp.OfpGroupEntry) []*ofp.OfpGroupEntry {
337 groups := make([]*ofp.OfpGroupEntry, 0)
338 for _, group := range groupList {
339 groups = append(groups, group)
340 }
341 return groups
342}
343func (dat *DATest) testFlowAddDeletes(t *testing.T, da *Agent) {
344 //Add new Flows on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500345 newFlows := []*ofp.OfpFlowStats{
346 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
347 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
348 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
349 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400350 err := da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400351 // Expect specific error as adapter communication, for unit tests, are not set
352 assert.NotNil(t, err)
353 assert.True(t, strings.Contains(err.Error(), "flow-failure-device-"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700354 daFlows := changeToFlowList(da.listDeviceFlows())
355 assert.True(t, isFlowSliceEqual(newFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500356
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700357 //Add new Flows on existing ones
358 newFlows = []*ofp.OfpFlowStats{
359 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500360 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
361 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700362
363 expectedFlows := []*ofp.OfpFlowStats{
364 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
365 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
366 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
367 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
368 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270000, PacketCount: 0},
369 }
370
khenaidoo9beaaf12021-10-19 17:32:01 -0400371 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400372 assert.NotNil(t, err)
373 assert.True(t, strings.Contains(err.Error(), "flow-failure-device-"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700374 daFlows = changeToFlowList(da.listDeviceFlows())
375 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
376
377 //Add existing Flows again with a new flow
378 newFlows = []*ofp.OfpFlowStats{
379 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
380 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
381 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
382 }
383
384 expectedFlows = []*ofp.OfpFlowStats{
385 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
386 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
387 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
388 {Id: 126, TableId: 1260, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1260000, PacketCount: 0},
389 {Id: 127, TableId: 1270, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1270001, PacketCount: 0},
390 {Id: 128, TableId: 1280, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1280000, PacketCount: 0},
391 }
392
khenaidoo9beaaf12021-10-19 17:32:01 -0400393 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400394 assert.NotNil(t, err)
395 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700396 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
khenaidoo9beaaf12021-10-19 17:32:01 -0400415 err = da.addFlowsAndGroups(context.Background(), newFlows, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700416 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
khenaidoo9beaaf12021-10-19 17:32:01 -0400433 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400434 assert.NotNil(t, err)
435 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700436 daFlows = changeToFlowList(da.listDeviceFlows())
437 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
438 //Delete flows with an unexisting one
439 flowsToDelete = []*ofp.OfpFlowStats{
khenaidoob2121e52019-12-16 17:17:22 -0500440 {Id: 125, TableId: 1250, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1250000, PacketCount: 0},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700441 {Id: 129, TableId: 1290, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1290000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500442 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700443
444 expectedFlows = []*ofp.OfpFlowStats{
445 {Id: 123, TableId: 1230, Priority: 100, IdleTimeout: 0, Flags: 0, Cookie: 1230000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500446 {Id: 124, TableId: 1240, Priority: 1000, IdleTimeout: 0, Flags: 0, Cookie: 1240000, PacketCount: 0},
khenaidoob2121e52019-12-16 17:17:22 -0500447 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700448
khenaidoo9beaaf12021-10-19 17:32:01 -0400449 err = da.deleteFlowsAndGroups(context.Background(), flowsToDelete, []*ofp.OfpGroupEntry{}, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400450 assert.NotNil(t, err)
451 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700452 daFlows = changeToFlowList(da.listDeviceFlows())
453 assert.True(t, isFlowSliceEqual(expectedFlows, daFlows))
khenaidoob2121e52019-12-16 17:17:22 -0500454}
455
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700456func (dat *DATest) testGroupAddDeletes(t *testing.T, da *Agent) {
457 //Add new Groups on empty list
khenaidoob2121e52019-12-16 17:17:22 -0500458 newGroups := []*ofp.OfpGroupEntry{
459 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
460 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
461 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400462 err := da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400463 assert.NotNil(t, err)
464 assert.True(t, strings.Contains(err.Error(), "flow-failure-device-"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700465 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 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400479 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400480 assert.NotNil(t, err)
481 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700482 daGroups = changeToGroupList(da.listDeviceGroups())
483 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500484
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700485 //Add new Groups on existing ones
486 newGroups = []*ofp.OfpGroupEntry{
487 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
488 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
489 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500490 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700491 expectedGroups = []*ofp.OfpGroupEntry{
492 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500493 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
494 {Desc: &ofp.OfpGroupDesc{Type: 3, GroupId: 30, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700495 {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 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400498 err = da.addFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, newGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400499 assert.NotNil(t, err)
500 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700501 daGroups = changeToGroupList(da.listDeviceGroups())
502 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
503
504 //Modify Group
505 updtGroups := []*ofp.OfpGroupEntry{
506 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
507 }
508 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500509 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500510 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700511 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
512 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
513 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
khenaidoob2121e52019-12-16 17:17:22 -0500514 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400515 err = da.updateFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, updtGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400516 assert.NotNil(t, err)
517 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700518 daGroups = changeToGroupList(da.listDeviceGroups())
519 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
520
521 //Delete Group
522 delGroups := []*ofp.OfpGroupEntry{
523 {Desc: &ofp.OfpGroupDesc{Type: 33, GroupId: 30, Buckets: nil}},
524 }
525 expectedGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500526 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700527 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
528 {Desc: &ofp.OfpGroupDesc{Type: 44, GroupId: 40, Buckets: nil}},
529 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
530 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400531 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400532 assert.NotNil(t, err)
533 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700534 daGroups = changeToGroupList(da.listDeviceGroups())
535 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
536
537 //Delete Group
538 delGroups = []*ofp.OfpGroupEntry{
khenaidoob2121e52019-12-16 17:17:22 -0500539 {Desc: &ofp.OfpGroupDesc{Type: 4, GroupId: 40, Buckets: nil}},
540 }
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700541 expectedGroups = []*ofp.OfpGroupEntry{
542 {Desc: &ofp.OfpGroupDesc{Type: 1, GroupId: 10, Buckets: nil}},
543 {Desc: &ofp.OfpGroupDesc{Type: 2, GroupId: 20, Buckets: nil}},
544 {Desc: &ofp.OfpGroupDesc{Type: 5, GroupId: 50, Buckets: nil}},
545 }
khenaidoo9beaaf12021-10-19 17:32:01 -0400546 err = da.deleteFlowsAndGroups(context.Background(), []*ofp.OfpFlowStats{}, delGroups, &ofp.FlowMetadata{})
khenaidood948f772021-08-11 17:49:24 -0400547 assert.NotNil(t, err)
548 assert.True(t, strings.Contains(err.Error(), "Aborted"))
Mahir Gunyel03de0d32020-06-03 01:36:59 -0700549 daGroups = changeToGroupList(da.listDeviceGroups())
550 assert.True(t, isGroupSliceEqual(expectedGroups, daGroups))
khenaidoob2121e52019-12-16 17:17:22 -0500551}
khenaidood948f772021-08-11 17:49:24 -0400552
553// registerAdapters registers the ONU and OLT adapters
554func (dat *DATest) registerAdapters(ctx context.Context) {
555 oltAdapter := &voltha.Adapter{
556 Id: "olt-mock-adapter-1",
557 Vendor: "olt-mock-vendor",
558 Version: ver.VersionInfo.Version,
559 Type: "olt-mock-adapter-type",
560 CurrentReplica: 1,
561 TotalReplicas: 1,
562 Endpoint: "mock-olt-endpoint",
563 }
564 types := []*voltha.DeviceType{{Id: "olt-mock-device-type", AdapterType: "olt-mock-adapter-type", AcceptsAddRemoveFlowUpdates: true}}
565 deviceTypes := &voltha.DeviceTypes{Items: types}
khenaidoo9beaaf12021-10-19 17:32:01 -0400566 _, err := dat.adapterMgr.RegisterAdapter(ctx, &ca.AdapterRegistration{
khenaidood948f772021-08-11 17:49:24 -0400567 Adapter: oltAdapter,
568 DTypes: deviceTypes,
569 })
570 if err != nil {
571 logger.Fatalw(ctx, "olt registration failed", log.Fields{"error": err})
572 }
573
574 onuAdapter := &voltha.Adapter{
575 Id: "onu-mock-adapter-1",
576 Vendor: "onu-mock-vendor",
577 Version: ver.VersionInfo.Version,
578 Type: "onu-mock-adapter-type",
579 CurrentReplica: 1,
580 TotalReplicas: 1,
581 Endpoint: "mock-onu-endpoint",
582 }
583 types = []*voltha.DeviceType{{Id: "onu-mock-device-type", AdapterType: "onu-mock-adapter-type", AcceptsAddRemoveFlowUpdates: true}}
584 deviceTypes = &voltha.DeviceTypes{Items: types}
khenaidoo9beaaf12021-10-19 17:32:01 -0400585 _, err = dat.adapterMgr.RegisterAdapter(ctx, &ca.AdapterRegistration{
khenaidood948f772021-08-11 17:49:24 -0400586 Adapter: onuAdapter,
587 DTypes: deviceTypes,
588 })
589 if err != nil {
590 logger.Fatalw(ctx, "onu registration failed", log.Fields{"error": err})
591 }
592}