1// Copyright 2017 Istio Authors 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 15package perftests 16 17import ( 18 "testing" 19 20 "istio.io/istio/mixer/pkg/perf" 21 spyadapter "istio.io/istio/mixer/test/spyAdapter" 22) 23 24// Tests single check call into Mixer that dispatches instances to multiple noop inproc adapters. 25func Benchmark_Check_1Client_1Call(b *testing.B) { 26 settings, spyAdapter := settingsWithAdapterAndTmpls() 27 settings.RunMode = perf.InProcess 28 29 setup := perf.Setup{ 30 Config: perf.Config{ 31 Global: mixerGlobalCfg, 32 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 33 }, 34 35 Loads: []perf.Load{{ 36 Multiplier: 1, 37 Requests: []perf.Request{ 38 perf.BuildBasicCheck(baseAttr, nil), 39 }, 40 }}, 41 } 42 43 perf.Run(b, &setup, settings) 44 validateCheckBehavior(spyAdapter, b) 45} 46 47// Tests 5 synchronous identical check call into Mixer that dispatches instances to multiple noop inproc adapters. 48func Benchmark_Check_1Client_5SameCalls(b *testing.B) { 49 settings, spyAdapter := settingsWithAdapterAndTmpls() 50 settings.RunMode = perf.InProcess 51 52 setup := perf.Setup{ 53 Config: perf.Config{ 54 Global: mixerGlobalCfg, 55 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 56 }, 57 58 Loads: []perf.Load{{ 59 Multiplier: 5, 60 Requests: []perf.Request{ 61 perf.BuildBasicCheck(baseAttr, nil), 62 }, 63 }}, 64 } 65 66 perf.Run(b, &setup, settings) 67 validateCheckBehavior(spyAdapter, b) 68} 69 70// Tests 5 synchronous different check call into Mixer that dispatches instances to multiple noop inproc adapters. 71func Benchmark_Check_1Client_5DifferentCalls(b *testing.B) { 72 settings, spyAdapter := settingsWithAdapterAndTmpls() 73 settings.RunMode = perf.InProcess 74 75 setup := perf.Setup{ 76 Config: perf.Config{ 77 Global: mixerGlobalCfg, 78 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 79 }, 80 81 Loads: []perf.Load{ 82 { 83 Multiplier: 1, 84 Requests: []perf.Request{ 85 perf.BuildBasicCheck(attr1, nil), 86 perf.BuildBasicCheck(attr2, nil), 87 perf.BuildBasicCheck(attr3, nil), 88 perf.BuildBasicCheck(attr4, nil), 89 perf.BuildBasicCheck(attr5, nil), 90 }, 91 }, 92 }, 93 } 94 95 perf.Run(b, &setup, settings) 96 validateCheckBehavior(spyAdapter, b) 97} 98 99// Tests 4 async client, each sending 5 identical check call into Mixer that dispatches instances to 100// multiple noop inproc adapters. 101func Benchmark_Check_4Clients_5SameCallsEach(b *testing.B) { 102 settings, spyAdapter := settingsWithAdapterAndTmpls() 103 settings.RunMode = perf.InProcess 104 setup := perf.Setup{ 105 Config: perf.Config{ 106 Global: mixerGlobalCfg, 107 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 108 }, 109 110 Loads: []perf.Load{ 111 { 112 Multiplier: 5, 113 Requests: []perf.Request{ 114 perf.BuildBasicCheck(baseAttr, nil), 115 }, 116 }, 117 { 118 Multiplier: 5, 119 Requests: []perf.Request{ 120 perf.BuildBasicCheck(baseAttr, nil), 121 }, 122 }, 123 { 124 Multiplier: 5, 125 Requests: []perf.Request{ 126 perf.BuildBasicCheck(baseAttr, nil), 127 }, 128 }, 129 { 130 Multiplier: 5, 131 Requests: []perf.Request{ 132 perf.BuildBasicCheck(baseAttr, nil), 133 }, 134 }, 135 }, 136 } 137 138 perf.Run(b, &setup, settings) 139 validateCheckBehavior(spyAdapter, b) 140} 141 142// Tests 4 async client, each sending 5 different check call into Mixer that dispatches instances to 143// multiple noop inproc adapters. 144func Benchmark_Check_4Clients_5DifferentCallsEach(b *testing.B) { 145 settings, spyAdapter := settingsWithAdapterAndTmpls() 146 settings.RunMode = perf.InProcess 147 setup := perf.Setup{ 148 Config: perf.Config{ 149 Global: mixerGlobalCfg, 150 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 151 }, 152 153 Loads: []perf.Load{ 154 { 155 Multiplier: 1, 156 Requests: []perf.Request{ 157 perf.BuildBasicCheck(attr1, nil), 158 perf.BuildBasicCheck(attr2, nil), 159 perf.BuildBasicCheck(attr3, nil), 160 perf.BuildBasicCheck(attr4, nil), 161 perf.BuildBasicCheck(attr5, nil), 162 }, 163 }, 164 { 165 Multiplier: 1, 166 Requests: []perf.Request{ 167 perf.BuildBasicCheck(attr1, nil), 168 perf.BuildBasicCheck(attr2, nil), 169 perf.BuildBasicCheck(attr3, nil), 170 perf.BuildBasicCheck(attr4, nil), 171 perf.BuildBasicCheck(attr5, nil), 172 }, 173 }, 174 { 175 Multiplier: 1, 176 Requests: []perf.Request{ 177 perf.BuildBasicCheck(attr1, nil), 178 perf.BuildBasicCheck(attr2, nil), 179 perf.BuildBasicCheck(attr3, nil), 180 perf.BuildBasicCheck(attr4, nil), 181 perf.BuildBasicCheck(attr5, nil), 182 }, 183 }, 184 { 185 Multiplier: 1, 186 Requests: []perf.Request{ 187 perf.BuildBasicCheck(attr1, nil), 188 perf.BuildBasicCheck(attr2, nil), 189 perf.BuildBasicCheck(attr3, nil), 190 perf.BuildBasicCheck(attr4, nil), 191 perf.BuildBasicCheck(attr5, nil), 192 }, 193 }, 194 }, 195 } 196 197 perf.Run(b, &setup, settings) 198 validateCheckBehavior(spyAdapter, b) 199} 200 201// Tests 4 async client, each sending 5 identical check call into Mixer that dispatches instances to 202// multiple noop inproc adapters. The APA in this case is a slow by 1ms. 203func Benchmark_Check_4Clients_5SameCallsEach_1MilliSecSlowApa(b *testing.B) { 204 settings, spyAdapter := settingsWith1milliSecApaAdapterAndTmpls() 205 settings.RunMode = perf.InProcess 206 setup := perf.Setup{ 207 Config: perf.Config{ 208 Global: mixerGlobalCfg, 209 Service: checkInstToSpyAdapter + attrGenToSpyAdapter, 210 }, 211 212 Loads: []perf.Load{ 213 { 214 Multiplier: 5, 215 Requests: []perf.Request{ 216 perf.BuildBasicCheck(baseAttr, nil), 217 }, 218 }, 219 { 220 Multiplier: 5, 221 Requests: []perf.Request{ 222 perf.BuildBasicCheck(baseAttr, nil), 223 }, 224 }, 225 { 226 Multiplier: 5, 227 Requests: []perf.Request{ 228 perf.BuildBasicCheck(baseAttr, nil), 229 }, 230 }, 231 { 232 Multiplier: 5, 233 Requests: []perf.Request{ 234 perf.BuildBasicCheck(baseAttr, nil), 235 }, 236 }, 237 }, 238 } 239 240 perf.Run(b, &setup, settings) 241 validateCheckBehavior(spyAdapter, b) 242} 243 244func validateCheckBehavior(spyAdapter *spyadapter.Adapter, b *testing.B) { 245 // validate all went as expected. 246 // 247 // based on the config, there must be, for each Check call from client, 248 // * single attribute generation call 249 // * single list check call 250 foundAttrGenCall := false 251 foundCheckCall := false 252 for _, cc := range spyAdapter.HandlerData.CapturedCalls { 253 if cc.Name == "HandleSampleApaAttributes" && len(cc.Instances) == 1 { 254 foundAttrGenCall = true 255 } 256 if cc.Name == "HandleSampleCheck" && len(cc.Instances) == 1 { 257 foundCheckCall = true 258 } 259 } 260 261 if !foundAttrGenCall || !foundCheckCall { 262 b.Errorf("got spy adapter calls %v; want calls with HandleSampleApaAttributes:1 & HandleSampleCheck:1", 263 spyAdapter.HandlerData.CapturedCalls) 264 } 265} 266 267const ( 268 // contains 1 rules that pass 1 instance to a check adapter 269 checkInstToSpyAdapter = ` 270apiVersion: "config.istio.io/v1alpha2" 271kind: spyadapter 272metadata: 273 name: spyadapterHandler 274 namespace: istio-system 275spec: 276 277--- 278apiVersion: "config.istio.io/v1alpha2" 279kind: samplecheck 280metadata: 281 name: samplecheckInst 282 namespace: istio-system 283spec: 284 stringPrimitive: source.labels["version"] | "unknown" 285--- 286apiVersion: "config.istio.io/v1alpha2" 287kind: rule 288metadata: 289 name: listEntryRule 290 namespace: istio-system 291spec: 292 match: context.protocol == "http" 293 actions: 294 - handler: spyadapterHandler.spyadapter 295 instances: 296 - samplecheckInst.samplecheck 297--- 298` 299) 300