blob: b388d97c45121d9f2d7d8c36669f21c804fcb059 [file] [log] [blame]
Stephane Barbariedc5022d2018-11-19 15:21:44 -05001/*
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 model
17
18import (
19 "encoding/hex"
20 "github.com/google/uuid"
21 "github.com/opencord/voltha-go/common/log"
22 "github.com/opencord/voltha-go/protos/common"
23 "github.com/opencord/voltha-go/protos/openflow_13"
24 "github.com/opencord/voltha-go/protos/voltha"
25 "math/rand"
26 "reflect"
27 "strconv"
28 "sync"
29 "testing"
30)
31
32var (
33 ltDevProxy *Proxy
34 plt *proxyLoadTest
35 tlog log.Logger
36)
37
38type proxyLoadChanges struct {
39 ID string
40 Before interface{}
41 After interface{}
42}
43type proxyLoadTest struct {
44 sync.RWMutex
45 addedDevices [] string
46 updatedFirmwares []proxyLoadChanges
47 updatedFlows []proxyLoadChanges
48 preAddExecuted bool
49 postAddExecuted bool
50 preUpdateExecuted bool
51 postUpdateExecuted bool
52}
53
54func (plt *proxyLoadTest) SetPreAddExecuted(status bool) {
55 plt.Lock()
56 defer plt.Unlock()
57 plt.preAddExecuted = status
58}
59func (plt *proxyLoadTest) SetPostAddExecuted(status bool) {
60 plt.Lock()
61 defer plt.Unlock()
62 plt.postAddExecuted = status
63}
64func (plt *proxyLoadTest) SetPreUpdateExecuted(status bool) {
65 plt.Lock()
66 defer plt.Unlock()
67 plt.preUpdateExecuted = status
68}
69func (plt *proxyLoadTest) SetPostUpdateExecuted(status bool) {
70 plt.Lock()
71 defer plt.Unlock()
72 plt.postUpdateExecuted = status
73}
74func init() {
75 tlog, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
76 log.UpdateAllLoggers(log.Fields{"instanceId": "PROXY_LOAD_TEST"})
77 defer log.CleanUp()
78
79 ltDevProxy = modelTestConfig.Root.node.CreateProxy("/", false)
80 // Register ADD instructions callbacks
81 plt = &proxyLoadTest{}
82
83 ltDevProxy.RegisterCallback(PRE_ADD, commonCallbackFunc, "PRE_ADD", plt.SetPreAddExecuted)
84 ltDevProxy.RegisterCallback(POST_ADD, commonCallbackFunc, "POST_ADD", plt.SetPostAddExecuted)
85
86 //// Register UPDATE instructions callbacks
87 ltDevProxy.RegisterCallback(PRE_UPDATE, commonCallbackFunc, "PRE_UPDATE", plt.SetPreUpdateExecuted)
88 ltDevProxy.RegisterCallback(POST_UPDATE, commonCallbackFunc, "POST_UPDATE", plt.SetPostUpdateExecuted)
89
90}
91
92func Benchmark_ProxyLoad_AddDevice(b *testing.B) {
93 defer GetProfiling().Report()
94 b.RunParallel(func(pb *testing.PB) {
95 b.Log("Started adding devices")
96 for pb.Next() {
97 ltPorts := []*voltha.Port{
98 {
99 PortNo: 123,
100 Label: "lt-port-0",
101 Type: voltha.Port_PON_OLT,
102 AdminState: common.AdminState_ENABLED,
103 OperStatus: common.OperStatus_ACTIVE,
104 DeviceId: "lt-port-0-device-id",
105 Peers: []*voltha.Port_PeerPort{},
106 },
107 }
108
109 ltStats := &openflow_13.OfpFlowStats{
110 Id: 1000,
111 }
112 ltFlows := &openflow_13.Flows{
113 Items: []*openflow_13.OfpFlowStats{ltStats},
114 }
115 ltDevice := &voltha.Device{
116 Id: "",
117 Type: "simulated_olt",
118 Address: &voltha.Device_HostAndPort{HostAndPort: "1.2.3.4:5555"},
119 AdminState: voltha.AdminState_PREPROVISIONED,
120 Flows: ltFlows,
121 Ports: ltPorts,
122 }
123
124 ltDevIDBin, _ := uuid.New().MarshalBinary()
125 ltDevID := "0001" + hex.EncodeToString(ltDevIDBin)[:12]
126 ltDevice.Id = ltDevID
127
128 plt.SetPreAddExecuted(false)
129 plt.SetPostAddExecuted(false)
130
131 var added interface{}
132 // Add the device
133 if added = ltDevProxy.AddWithID("/devices", ltDevID, ltDevice, ""); added == nil {
134 tlog.Errorf("Failed to add device: %+v", ltDevice)
135 continue
136 } else {
137 tlog.Infof("Device was added 1: %+v", added)
138 }
139
140 plt.Lock()
141 plt.addedDevices = append(plt.addedDevices, added.(*voltha.Device).Id)
142 plt.Unlock()
143 }
144 })
145
146 tlog.Infof("Number of added devices : %d", len(plt.addedDevices))
147}
148
149func Benchmark_ProxyLoad_UpdateFirmware(b *testing.B) {
150 b.RunParallel(func(pb *testing.PB) {
151 for pb.Next() {
152 //for i:=0; i < b.N; i++ {
153
154 if len(plt.addedDevices) > 0 {
155 var target interface{}
156 randomID := plt.addedDevices[rand.Intn(len(plt.addedDevices))]
157 firmProxy := modelTestConfig.Root.node.CreateProxy("/", false)
158 if target = firmProxy.Get("/devices/"+randomID, 0, false,
159 ""); !reflect.ValueOf(target).IsValid() {
160 tlog.Errorf("Failed to find device: %s %+v", randomID, target)
161 continue
162 }
163
164 plt.SetPreUpdateExecuted(false)
165 plt.SetPostUpdateExecuted(false)
166 firmProxy.RegisterCallback(PRE_UPDATE, commonCallbackFunc, "PRE_UPDATE", plt.SetPreUpdateExecuted)
167 firmProxy.RegisterCallback(POST_UPDATE, commonCallbackFunc, "POST_UPDATE", plt.SetPostUpdateExecuted)
168
169 var fwVersion int
170
171 before := target.(*voltha.Device).FirmwareVersion
172 if target.(*voltha.Device).FirmwareVersion == "n/a" {
173 fwVersion = 0
174 } else {
175 fwVersion, _ = strconv.Atoi(target.(*voltha.Device).FirmwareVersion)
176 fwVersion++
177 }
178
179 target.(*voltha.Device).FirmwareVersion = strconv.Itoa(fwVersion)
180 after := target.(*voltha.Device).FirmwareVersion
181
182 var updated interface{}
183 if updated = firmProxy.Update("/devices/"+randomID, target.(*voltha.Device), false,
184 ""); updated == nil {
185 tlog.Errorf("Failed to update device: %+v", target)
186 continue
187 } else {
188 tlog.Infof("Device was updated : %+v", updated)
189
190 }
191
192 if d := firmProxy.Get("/devices/"+randomID, 0, false,
193 ""); !reflect.ValueOf(d).IsValid() {
194 tlog.Errorf("Failed to get device: %s", randomID)
195 continue
196 } else if d.(*voltha.Device).FirmwareVersion == after {
197 tlog.Infof("Imm Device was updated with new value: %s %+v", randomID, d)
198 } else if d.(*voltha.Device).FirmwareVersion == before {
199 tlog.Errorf("Imm Device kept old value: %s %+v %+v", randomID, d, target)
200 } else {
201 tlog.Errorf("Imm Device has unknown value: %s %+v %+v", randomID, d, target)
202 }
203
204 plt.Lock()
205 plt.updatedFirmwares = append(
206 plt.updatedFirmwares,
207 proxyLoadChanges{ID: randomID, Before: before, After: after},
208 )
209 plt.Unlock()
210 }
211 }
212 })
213}
214
215func traverseBranches(revision Revision, depth int) {
216 if revision == nil {
217 return
218 }
219 prefix := strconv.Itoa(depth) + " ~~~~ "
220 for i := 0; i < depth; i++ {
221 prefix += " "
222 }
223
224 tlog.Debugf("%sRevision: %s %+v", prefix, revision.GetHash(), revision.GetData())
225
226 //for brIdx, brRev := range revision.GetBranch().Revisions {
227 // tlog.Debugf("%sbranchIndex: %s", prefix, brIdx)
228 // traverseBranches(brRev, depth+1)
229 //}
230 for childrenI, children := range revision.GetChildren() {
231 tlog.Debugf("%schildrenIndex: %s, length: %d", prefix, childrenI, len(children))
232
233 for _, subrev := range children {
234 //subrev.GetBranch().Latest
235 traverseBranches(subrev, depth+1)
236 }
237 }
238
239}
240func Benchmark_ProxyLoad_UpdateFlows(b *testing.B) {
241 b.RunParallel(func(pb *testing.PB) {
242 for pb.Next() {
243 if len(plt.addedDevices) > 0 {
244 randomID := plt.addedDevices[rand.Intn(len(plt.addedDevices))]
245
246 flowsProxy := modelTestConfig.Root.node.CreateProxy("/devices/"+randomID+"/flows", false)
247 flows := flowsProxy.Get("/", 0, false, "")
248
249 before := flows.(*openflow_13.Flows).Items[0].TableId
250 flows.(*openflow_13.Flows).Items[0].TableId = uint32(rand.Intn(3000))
251 after := flows.(*openflow_13.Flows).Items[0].TableId
252
253 flowsProxy.RegisterCallback(
254 PRE_UPDATE,
255 commonCallback2,
256 )
257 flowsProxy.RegisterCallback(
258 POST_UPDATE,
259 commonCallback2,
260 )
261
262 var updated interface{}
263 if updated = flowsProxy.Update("/", flows.(*openflow_13.Flows), false, ""); updated == nil {
264 b.Errorf("Failed to update flows for device: %+v", flows)
265 } else {
266 tlog.Infof("Flows were updated : %+v", updated)
267 }
268 plt.Lock()
269 plt.updatedFlows = append(
270 plt.updatedFlows,
271 proxyLoadChanges{ID: randomID, Before: before, After: after},
272 )
273 plt.Unlock()
274 }
275 }
276 })
277}
278
279func Benchmark_ProxyLoad_GetDevices(b *testing.B) {
280 traverseBranches(ltDevProxy.Root.node.Branches[NONE].GetLatest(), 0)
281
282 for i := 0; i < len(plt.addedDevices); i++ {
283 devToGet := plt.addedDevices[i]
284 // Verify that the added device can now be retrieved
285 if d := ltDevProxy.Get("/devices/"+devToGet, 0, false,
286 ""); !reflect.ValueOf(d).IsValid() {
287 tlog.Errorf("Failed to get device: %s", devToGet)
288 continue
289 } else {
290 tlog.Infof("Got device: %s %+v", devToGet, d)
291 }
292 }
293}
294
295func Benchmark_ProxyLoad_GetUpdatedFirmware(b *testing.B) {
296 for i := 0; i < len(plt.updatedFirmwares); i++ {
297 devToGet := plt.updatedFirmwares[i].ID
298 // Verify that the updated device can be retrieved and that the updates were actually applied
299 if d := ltDevProxy.Get("/devices/"+devToGet, 0, false,
300 ""); !reflect.ValueOf(d).IsValid() {
301 tlog.Errorf("Failed to get device: %s", devToGet)
302 continue
303 } else if d.(*voltha.Device).FirmwareVersion == plt.updatedFirmwares[i].After.(string) {
304 tlog.Infof("Device was updated with new value: %s %+v", devToGet, d)
305 } else if d.(*voltha.Device).FirmwareVersion == plt.updatedFirmwares[i].Before.(string) {
306 tlog.Errorf("Device kept old value: %s %+v %+v", devToGet, d, plt.updatedFirmwares[i])
307 } else {
308 tlog.Errorf("Device has unknown value: %s %+v %+v", devToGet, d, plt.updatedFirmwares[i])
309 }
310 }
311}
312
313func Benchmark_ProxyLoad_GetUpdatedFlows(b *testing.B) {
314 var d interface{}
315 for i := 0; i < len(plt.updatedFlows); i++ {
316 devToGet := plt.updatedFlows[i].ID
317 // Verify that the updated device can be retrieved and that the updates were actually applied
318 flowsProxy := modelTestConfig.Root.node.CreateProxy("/devices/"+devToGet+"/flows", false)
319 if d = flowsProxy.Get("/", 0, false,
320 ""); !reflect.ValueOf(d).IsValid() {
321 tlog.Errorf("Failed to get device flows: %s", devToGet)
322 continue
323 } else if d.(*openflow_13.Flows).Items[0].TableId == plt.updatedFlows[i].After.(uint32) {
324 tlog.Infof("Device was updated with new flow value: %s %+v", devToGet, d)
325 } else if d.(*openflow_13.Flows).Items[0].TableId == plt.updatedFlows[i].Before.(uint32) {
326 tlog.Errorf("Device kept old flow value: %s %+v %+v", devToGet, d, plt.updatedFlows[i])
327 } else {
328 tlog.Errorf("Device has unknown flow value: %s %+v %+v", devToGet, d, plt.updatedFlows[i])
329 }
330 //if d = ltDevProxy.Get("/devices/"+devToGet, 0, false,
331 // ""); !reflect.ValueOf(d).IsValid() {
332 // tlog.Errorf("Failed to get device: %s", devToGet)
333 // continue
334 //} else if d.(*voltha.Device).Flows.Items[0].TableId == plt.updatedFlows[i].After.(uint32) {
335 // tlog.Infof("Device was updated with new flow value: %s %+v", devToGet, d)
336 //} else if d.(*voltha.Device).Flows.Items[0].TableId == plt.updatedFlows[i].Before.(uint32) {
337 // tlog.Errorf("Device kept old flow value: %s %+v %+v", devToGet, d, plt.updatedFlows[i])
338 //} else {
339 // tlog.Errorf("Device has unknown flow value: %s %+v %+v", devToGet, d, plt.updatedFlows[i])
340 //}
341 }
342}