github.com/opencord/voltha-go@v2.2.0+incompatible/db/model/proxy_load_test.go (about) 1 /* 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 */ 16 package model 17 18 import ( 19 "context" 20 "encoding/hex" 21 "github.com/google/uuid" 22 "github.com/opencord/voltha-go/common/log" 23 "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 33 var ( 34 BenchmarkProxy_Root *root 35 BenchmarkProxy_DeviceProxy *Proxy 36 BenchmarkProxy_PLT *proxyLoadTest 37 BenchmarkProxy_Logger log.Logger 38 ) 39 40 type proxyLoadChanges struct { 41 ID string 42 Before interface{} 43 After interface{} 44 } 45 type 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 62 func (plt *proxyLoadTest) SetPreAddExecuted(status bool) { 63 plt.mutex.Lock() 64 defer plt.mutex.Unlock() 65 plt.preAddExecuted = status 66 } 67 func (plt *proxyLoadTest) SetPostAddExecuted(status bool) { 68 plt.mutex.Lock() 69 defer plt.mutex.Unlock() 70 plt.postAddExecuted = status 71 } 72 func (plt *proxyLoadTest) SetPreUpdateExecuted(status bool) { 73 plt.mutex.Lock() 74 defer plt.mutex.Unlock() 75 plt.preUpdateExecuted = status 76 } 77 func (plt *proxyLoadTest) SetPostUpdateExecuted(status bool) { 78 plt.mutex.Lock() 79 defer plt.mutex.Unlock() 80 plt.postUpdateExecuted = status 81 } 82 83 func 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-go/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 112 func 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 169 func 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 236 func 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 } 261 func 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 300 func 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 316 func 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 }