blob: ece626f780d3d6699c3aab6580328fb37ebd74f0 [file] [log] [blame]
khenaidoo89b0e942018-10-21 21:11:33 -04001/*
2 * Copyright 2018-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package graph
17
18import (
19 "errors"
20 "fmt"
William Kurkiandaa6bb22019-03-07 12:26:28 -050021 "github.com/opencord/voltha-protos/go/openflow_13"
22 "github.com/opencord/voltha-protos/go/voltha"
khenaidoo89b0e942018-10-21 21:11:33 -040023 "github.com/stretchr/testify/assert"
khenaidoof934a1e2019-05-01 21:44:09 -040024 "strconv"
25 "strings"
khenaidoo910204f2019-04-08 17:56:40 -040026 "sync"
khenaidoo89b0e942018-10-21 21:11:33 -040027 "testing"
28 "time"
29)
30
khenaidoof934a1e2019-05-01 21:44:09 -040031var (
32 ld voltha.LogicalDevice
33 olt voltha.Device
34 onus map[int][]voltha.Device
35 logicalDeviceId string
36 oltDeviceId string
37 numCalled int
38 lock sync.RWMutex
khenaidoo89b0e942018-10-21 21:11:33 -040039)
40
41func init() {
khenaidoo910204f2019-04-08 17:56:40 -040042 logicalDeviceId = "ld"
43 oltDeviceId = "olt"
44 lock = sync.RWMutex{}
khenaidoof934a1e2019-05-01 21:44:09 -040045}
khenaidoo89b0e942018-10-21 21:11:33 -040046
khenaidoof934a1e2019-05-01 21:44:09 -040047func setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu int) {
48 // Create the OLT and add the NNI ports
khenaidoo89b0e942018-10-21 21:11:33 -040049 olt = voltha.Device{Id: oltDeviceId, ParentId: logicalDeviceId}
khenaidoo89b0e942018-10-21 21:11:33 -040050 olt.Ports = make([]*voltha.Port, 0)
khenaidoof934a1e2019-05-01 21:44:09 -040051 for nniPort := 1; nniPort < numNNIPort+1; nniPort++ {
52 p := voltha.Port{PortNo: uint32(nniPort), DeviceId: oltDeviceId, Type: voltha.Port_ETHERNET_NNI}
53 olt.Ports = append(olt.Ports, &p)
54 }
khenaidoo89b0e942018-10-21 21:11:33 -040055
khenaidoof934a1e2019-05-01 21:44:09 -040056 // Create the ONUs and associate them with the OLT
57 onus = make(map[int][]voltha.Device)
58 for pPortNo := numNNIPort + 1; pPortNo < numPonPortOnOlt+numNNIPort+1; pPortNo++ {
59 onusOnPon := make([]voltha.Device, 0)
60 var onu voltha.Device
61 oltPeerPort := uint32(pPortNo)
62 oltPonPort := voltha.Port{PortNo: uint32(pPortNo), DeviceId: oltDeviceId, Type: voltha.Port_PON_OLT}
63 oltPonPort.Peers = make([]*voltha.Port_PeerPort, 0)
64 for i := 0; i < numOnuPerOltPonPort; i++ {
65 id := fmt.Sprintf("%d-onu-%d", pPortNo, i)
66 onu = voltha.Device{Id: id, ParentId: oltDeviceId, ParentPortNo: uint32(pPortNo)}
67 ponPort := voltha.Port{PortNo: 1, DeviceId: onu.Id, Type: voltha.Port_PON_ONU}
68 ponPort.Peers = make([]*voltha.Port_PeerPort, 0)
69 peerPort := voltha.Port_PeerPort{DeviceId: oltDeviceId, PortNo: oltPeerPort}
70 ponPort.Peers = append(ponPort.Peers, &peerPort)
71 onu.Ports = make([]*voltha.Port, 0)
72 onu.Ports = append(onu.Ports, &ponPort)
73 for j := 2; j < numUniPerOnu+2; j++ {
74 uniPort := voltha.Port{PortNo: uint32(j), DeviceId: onu.Id, Type: voltha.Port_ETHERNET_UNI}
75 onu.Ports = append(onu.Ports, &uniPort)
76 }
77 onusOnPon = append(onusOnPon, onu)
78 oltPeerPort := voltha.Port_PeerPort{DeviceId: onu.Id, PortNo: 1}
79 oltPonPort.Peers = append(oltPonPort.Peers, &oltPeerPort)
80 }
81 onus[pPortNo] = onusOnPon
82 olt.Ports = append(olt.Ports, &oltPonPort)
83 }
84
85 // Create the logical device
khenaidoo89b0e942018-10-21 21:11:33 -040086 ld = voltha.LogicalDevice{Id: logicalDeviceId}
87 ld.Ports = make([]*voltha.LogicalPort, 0)
88 ofpPortNo := 1
khenaidoof934a1e2019-05-01 21:44:09 -040089 var id string
90 //Add olt NNI ports
khenaidoo89b0e942018-10-21 21:11:33 -040091 for i, port := range olt.Ports {
92 if port.Type == voltha.Port_ETHERNET_NNI {
93 id = fmt.Sprintf("nni-%d", i)
94 lp := voltha.LogicalPort{Id: id, DeviceId: olt.Id, DevicePortNo: port.PortNo, OfpPort: &openflow_13.OfpPort{PortNo: uint32(ofpPortNo)}, RootPort: true}
95 ld.Ports = append(ld.Ports, &lp)
96 ofpPortNo = ofpPortNo + 1
97 }
98 }
khenaidoof934a1e2019-05-01 21:44:09 -040099 //Add onu UNI ports
100 for _, onusOnPort := range onus {
101 for _, onu := range onusOnPort {
102 for j, port := range onu.Ports {
103 if port.Type == voltha.Port_ETHERNET_UNI {
104 id = fmt.Sprintf("%s:uni-%d", onu.Id, j)
105 lp := voltha.LogicalPort{Id: id, DeviceId: onu.Id, DevicePortNo: port.PortNo, OfpPort: &openflow_13.OfpPort{PortNo: uint32(ofpPortNo)}, RootPort: false}
106 ld.Ports = append(ld.Ports, &lp)
107 ofpPortNo = ofpPortNo + 1
108 }
khenaidoo89b0e942018-10-21 21:11:33 -0400109 }
110 }
111 }
112}
113
114func GetDeviceHelper(id string) (*voltha.Device, error) {
khenaidoo910204f2019-04-08 17:56:40 -0400115 lock.Lock()
116 numCalled += 1
117 lock.Unlock()
khenaidoo89b0e942018-10-21 21:11:33 -0400118 if id == "olt" {
119 return &olt, nil
120 }
khenaidoof934a1e2019-05-01 21:44:09 -0400121 // Extract the olt pon port from the id ("<ponport>-onu-<onu number>")
122 res := strings.Split(id, "-")
123 if len(res) == 3 {
124 if ponPort, err := strconv.Atoi(res[0]); err == nil {
125 for _, onu := range onus[ponPort] {
126 if onu.Id == id {
127 return &onu, nil
128 }
129 }
130
khenaidoo89b0e942018-10-21 21:11:33 -0400131 }
132 }
133 return nil, errors.New("Not-found")
134}
135
khenaidoo910204f2019-04-08 17:56:40 -0400136func TestGetRoutesOneShot(t *testing.T) {
khenaidoof934a1e2019-05-01 21:44:09 -0400137 numNNIPort := 1
138 numPonPortOnOlt := 1
139 numOnuPerOltPonPort := 64
140 numUniPerOnu := 1
khenaidoo89b0e942018-10-21 21:11:33 -0400141
khenaidoof934a1e2019-05-01 21:44:09 -0400142 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
khenaidoo89b0e942018-10-21 21:11:33 -0400143 getDevice := GetDeviceHelper
144
khenaidoof934a1e2019-05-01 21:44:09 -0400145 fmt.Println(fmt.Sprintf("Test: Computing all routes. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
khenaidoo89b0e942018-10-21 21:11:33 -0400146 // Create a device graph and computes Routes
147 start := time.Now()
khenaidoo910204f2019-04-08 17:56:40 -0400148 dg := NewDeviceGraph(logicalDeviceId, getDevice)
khenaidoo89b0e942018-10-21 21:11:33 -0400149 dg.ComputeRoutes(ld.Ports)
khenaidoo89b0e942018-10-21 21:11:33 -0400150 assert.NotNil(t, dg.GGraph)
khenaidoof934a1e2019-05-01 21:44:09 -0400151 fmt.Println(fmt.Sprintf("Total Time:%dms Total Routes:%d", time.Since(start)/time.Millisecond, len(dg.Routes)))
152 assert.EqualValues(t, (2 * numNNIPort * numPonPortOnOlt * numOnuPerOltPonPort * numUniPerOnu), len(dg.Routes))
khenaidoo910204f2019-04-08 17:56:40 -0400153}
khenaidoo89b0e942018-10-21 21:11:33 -0400154
khenaidoof934a1e2019-05-01 21:44:09 -0400155func TestGetRoutesPerPort(t *testing.T) {
156 numNNIPort := 1
157 numPonPortOnOlt := 1
158 numOnuPerOltPonPort := 64
159 numUniPerOnu := 1
khenaidoo910204f2019-04-08 17:56:40 -0400160
khenaidoof934a1e2019-05-01 21:44:09 -0400161 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
khenaidoo910204f2019-04-08 17:56:40 -0400162 getDevice := GetDeviceHelper
163
khenaidoof934a1e2019-05-01 21:44:09 -0400164 fmt.Println(fmt.Sprintf("Test: Compute routes per port. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
165
khenaidoo910204f2019-04-08 17:56:40 -0400166 // Create a device graph and computes Routes
167 start := time.Now()
khenaidoof934a1e2019-05-01 21:44:09 -0400168 var pt time.Time
khenaidoo910204f2019-04-08 17:56:40 -0400169 dg := NewDeviceGraph(logicalDeviceId, getDevice)
khenaidoof934a1e2019-05-01 21:44:09 -0400170 for k, lp := range ld.Ports {
171 if k == len(ld.Ports)-1 {
172 pt = time.Now()
173 }
khenaidoo910204f2019-04-08 17:56:40 -0400174 dg.AddPort(lp)
175 }
khenaidoo910204f2019-04-08 17:56:40 -0400176 assert.NotNil(t, dg.GGraph)
khenaidoof934a1e2019-05-01 21:44:09 -0400177 fmt.Println(fmt.Sprintf("Total Time:%dms. Total Routes:%d. LastPort_Time:%dms", time.Since(start)/time.Millisecond, len(dg.Routes), time.Since(pt)/time.Millisecond))
178 assert.EqualValues(t, (2 * numNNIPort * numPonPortOnOlt * numOnuPerOltPonPort * numUniPerOnu), len(dg.Routes))
179}
180
181func TestGetRoutesPerPortMultipleUNIs(t *testing.T) {
182 numNNIPort := 1
183 numPonPortOnOlt := 1
184 numOnuPerOltPonPort := 64
185 numUniPerOnu := 5
186
187 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
188 getDevice := GetDeviceHelper
189
190 fmt.Println(fmt.Sprintf("Test: Compute routes per port - multiple UNIs. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
191
192 // Create a device graph and computes Routes
193 start := time.Now()
194 var pt time.Time
195 dg := NewDeviceGraph(logicalDeviceId, getDevice)
196 for k, lp := range ld.Ports {
197 if k == len(ld.Ports)-1 {
198 pt = time.Now()
199 }
200 dg.AddPort(lp)
201 }
202 assert.NotNil(t, dg.GGraph)
203 fmt.Println(fmt.Sprintf("Total Time:%dms. Total Routes:%d. LastPort_Time:%dms", time.Since(start)/time.Millisecond, len(dg.Routes), time.Since(pt)/time.Millisecond))
204 assert.EqualValues(t, (2 * numNNIPort * numPonPortOnOlt * numOnuPerOltPonPort * numUniPerOnu), len(dg.Routes))
205}
206
207func TestGetRoutesPerPortNoUNI(t *testing.T) {
208 numNNIPort := 1
209 numPonPortOnOlt := 1
210 numOnuPerOltPonPort := 1
211 numUniPerOnu := 0
212
213 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
214 getDevice := GetDeviceHelper
215 assert.EqualValues(t, 1, len(ld.Ports))
216
217 fmt.Println(fmt.Sprintf("Test: Compute routes per port - no UNI. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
218
219 // Create a device graph and computes Routes
220 start := time.Now()
221 var pt time.Time
222 dg := NewDeviceGraph(logicalDeviceId, getDevice)
223 for k, lp := range ld.Ports {
224 if k == len(ld.Ports)-1 {
225 pt = time.Now()
226 }
227 dg.AddPort(lp)
228 }
229 assert.NotNil(t, dg.GGraph)
230 fmt.Println(fmt.Sprintf("Total Time:%dms. Total Routes:%d. LastPort_Time:%dms", time.Since(start)/time.Millisecond, len(dg.Routes), time.Since(pt)/time.Millisecond))
231 assert.EqualValues(t, 0, len(dg.Routes))
232}
233
234func TestGetRoutesPerPortNoONU(t *testing.T) {
235 numNNIPort := 1
236 numPonPortOnOlt := 1
237 numOnuPerOltPonPort := 0
238 numUniPerOnu := 0
239
240 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
241 getDevice := GetDeviceHelper
242 assert.EqualValues(t, 1, len(ld.Ports))
243
244 fmt.Println(fmt.Sprintf("Test: Compute routes per port - no ONU. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
245
246 // Create a device graph and computes Routes
247 start := time.Now()
248 var pt time.Time
249 dg := NewDeviceGraph(logicalDeviceId, getDevice)
250 for k, lp := range ld.Ports {
251 if k == len(ld.Ports)-1 {
252 pt = time.Now()
253 }
254 dg.AddPort(lp)
255 }
256 assert.NotNil(t, dg.GGraph)
257 fmt.Println(fmt.Sprintf("Total Time:%dms. Total Routes:%d. LastPort_Time:%dms", time.Since(start)/time.Millisecond, len(dg.Routes), time.Since(pt)/time.Millisecond))
258 assert.EqualValues(t, 0, len(dg.Routes))
259}
260
261func TestGetRoutesPerPortNoNNI(t *testing.T) {
262 numNNIPort := 0
263 numPonPortOnOlt := 1
264 numOnuPerOltPonPort := 1
265 numUniPerOnu := 1
266
267 setupDevices(numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu)
268 getDevice := GetDeviceHelper
269 assert.EqualValues(t, 1, len(ld.Ports))
270
271 fmt.Println(fmt.Sprintf("Test: Compute routes per port - no NNI. LogicalPorts:%d, NNI:%d, Pon/OLT:%d, ONU/Pon:%d, Uni/Onu:%d", len(ld.Ports), numNNIPort, numPonPortOnOlt, numOnuPerOltPonPort, numUniPerOnu))
272
273 // Create a device graph and computes Routes
274 start := time.Now()
275 var pt time.Time
276 dg := NewDeviceGraph(logicalDeviceId, getDevice)
277 for k, lp := range ld.Ports {
278 if k == len(ld.Ports)-1 {
279 pt = time.Now()
280 }
281 dg.AddPort(lp)
282 }
283 assert.NotNil(t, dg.GGraph)
284 fmt.Println(fmt.Sprintf("Total Time:%dms. Total Routes:%d. LastPort_Time:%dms", time.Since(start)/time.Millisecond, len(dg.Routes), time.Since(pt)/time.Millisecond))
285 assert.EqualValues(t, 0, len(dg.Routes))
khenaidoo89b0e942018-10-21 21:11:33 -0400286}