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