go.ligato.io/vpp-agent/v3@v3.5.0/examples/kvscheduler/mock_plugins/scenario/perf.go (about) 1 // Copyright (c) 2019 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package scenario 16 17 import ( 18 "context" 19 "fmt" 20 "log" 21 "net" 22 "strconv" 23 "time" 24 25 "encoding/binary" 26 27 "go.ligato.io/vpp-agent/v3/client" 28 29 interfaces "go.ligato.io/vpp-agent/v3/examples/kvscheduler/mock_plugins/ifplugin/model" 30 l2 "go.ligato.io/vpp-agent/v3/examples/kvscheduler/mock_plugins/l2plugin/model" 31 "go.ligato.io/vpp-agent/v3/plugins/kvscheduler" 32 ) 33 34 const iterations = 1000 35 const groupSize = 100 36 37 func profile(c client.ConfigClient, runTxn func(iter int, withOrch bool), description ...string) { 38 var ( 39 total time.Duration 40 group time.Duration 41 ) 42 43 for _, withOrch := range []bool{false, true} { 44 emptyResync(c) 45 total = 0 46 47 // describe perf test 48 withOrchStr := "With" 49 if !withOrch { 50 withOrchStr += "out" 51 } 52 msg := []string{fmt.Sprintf("%dx Change config (%s Orchestrator)", iterations, withOrchStr)} 53 msg = append(msg, description...) 54 printMessage(msg...) 55 56 for i := 0; i < iterations; i++ { 57 t := time.Now() 58 runTxn(i, withOrch) 59 elapsed := time.Since(t) 60 total += elapsed 61 group += elapsed 62 63 if (i+1)%groupSize == 0 { 64 fmt.Printf(DebugMsgColor, fmt.Sprintf("Txns %d-%d: %v", 65 i-groupSize+1, i, group)) 66 group = 0 67 } 68 } 69 fmt.Printf(DebugMsgColor, fmt.Sprintf("=> Total elapsed time: %v", total)) 70 } 71 } 72 73 func emptyResync(c client.ConfigClient) { 74 printMessage("Empty Resync") 75 err := c.ResyncConfig() 76 if err != nil { 77 log.Fatalln(err) 78 } 79 } 80 81 func PerfTest() { 82 c := client.LocalClient 83 listKnownModels(c) 84 85 // perf test #1 86 addTap := func(iter int, withOrch bool) { 87 tap := &interfaces.Interface{ 88 Name: "tap-" + strconv.Itoa(iter), 89 Type: interfaces.Interface_TAP, 90 Enabled: true, 91 } 92 if withOrch { 93 req := c.ChangeRequest() 94 req.Update(tap) 95 if err := req.Send(context.Background()); err != nil { 96 log.Fatalln(err) 97 } 98 } else { 99 txn := kvscheduler.DefaultPlugin.StartNBTransaction() 100 txn.SetValue(interfaces.InterfaceKey(tap.GetName()), tap) 101 _, err := txn.Commit(context.Background()) 102 if err != nil { 103 log.Fatalln(err) 104 } 105 } 106 } 107 profile(c, addTap, 108 " - add new TAP interface") 109 110 // perf test #3 111 var bdIfaces []string 112 addTapWithFIB := func(iter int, withOrch bool) { 113 tap := &interfaces.Interface{ 114 Name: "tap-" + strconv.Itoa(iter), 115 Type: interfaces.Interface_TAP, 116 Enabled: true, 117 } 118 119 // bd 120 if iter == 0 { 121 bdIfaces = []string{} 122 } 123 bdIfaces = append(bdIfaces, tap.GetName()) 124 bd := &l2.BridgeDomain{ 125 Name: "bd1", 126 Interfaces: make([]*l2.BridgeDomain_Interface, 0, len(bdIfaces)), 127 } 128 for _, iface := range bdIfaces { 129 bd.Interfaces = append(bd.Interfaces, &l2.BridgeDomain_Interface{ 130 Name: iface, 131 }) 132 } 133 134 // fib 135 var hwAddr [6]byte 136 binary.BigEndian.PutUint32(hwAddr[2:], uint32(iter)) 137 fib := &l2.FIBEntry{ 138 PhysAddress: net.HardwareAddr(hwAddr[:]).String(), 139 BridgeDomain: bd.GetName(), 140 Action: l2.FIBEntry_FORWARD, 141 OutgoingInterface: tap.GetName(), 142 } 143 144 if withOrch { 145 req := c.ChangeRequest() 146 req.Update(tap, bd, fib) 147 if err := req.Send(context.Background()); err != nil { 148 log.Fatalln(err) 149 } 150 } else { 151 txn := kvscheduler.DefaultPlugin.StartNBTransaction() 152 txn.SetValue(interfaces.InterfaceKey(tap.GetName()), tap) 153 txn.SetValue(l2.BridgeDomainKey(bd.GetName()), bd) 154 txn.SetValue(l2.FIBKey(fib.BridgeDomain, fib.PhysAddress), fib) 155 _, err := txn.Commit(context.Background()) 156 if err != nil { 157 log.Fatalln(err) 158 } 159 } 160 } 161 profile(c, addTapWithFIB, 162 " - add new TAP interface", 163 " - insert the new TAP interface into the bridge domain", 164 " - add FIB routing traffic for a certain MAC via the new interface", 165 ) 166 }