istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/config/analysis/analyzers/analyzers_bench_test.go (about) 1 /* 2 Copyright Istio Authors 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 17 package analyzers 18 19 import ( 20 "fmt" 21 "testing" 22 23 "istio.io/istio/pilot/pkg/config/memory" 24 "istio.io/istio/pilot/pkg/model" 25 "istio.io/istio/pkg/cluster" 26 "istio.io/istio/pkg/config" 27 "istio.io/istio/pkg/config/analysis/local" 28 "istio.io/istio/pkg/config/resource" 29 "istio.io/istio/pkg/config/schema/collections" 30 resource2 "istio.io/istio/pkg/config/schema/resource" 31 "istio.io/istio/pkg/log" 32 ) 33 34 // This is a very basic benchmark on unit test data, so it doesn't tell us anything about how an analyzer performs at scale 35 func BenchmarkAnalyzers(b *testing.B) { 36 for _, tc := range testGrid { 37 tc := tc // Capture range variable so subtests work correctly 38 b.Run(tc.name+"-bench", func(b *testing.B) { 39 sa, err := setupAnalyzerForCase(tc, nil) 40 if err != nil { 41 b.Fatalf("Error setting up analysis for benchmark on testcase %s: %v", tc.name, err) 42 } 43 44 b.ResetTimer() 45 46 // Run the analysis 47 _, err = runAnalyzer(sa) 48 if err != nil { 49 b.Fatalf("Error running analysis for benchmark on testcase %s: %v", tc.name, err) 50 } 51 }) 52 } 53 } 54 55 func BenchmarkAnalyzersArtificialBlankData100(b *testing.B) { 56 benchmarkAnalyzersArtificialBlankData(100, b) 57 } 58 59 func BenchmarkAnalyzersArtificialBlankData200(b *testing.B) { 60 benchmarkAnalyzersArtificialBlankData(200, b) 61 } 62 63 func BenchmarkAnalyzersArtificialBlankData400(b *testing.B) { 64 benchmarkAnalyzersArtificialBlankData(400, b) 65 } 66 67 func BenchmarkAnalyzersArtificialBlankData800(b *testing.B) { 68 benchmarkAnalyzersArtificialBlankData(800, b) 69 } 70 71 // Benchmark analyzers against an artificial set of blank data. 72 // This does not cover all scaling factors, and it's not representative of a realistic snapshot, but it does cover some things. 73 func benchmarkAnalyzersArtificialBlankData(count int, b *testing.B) { 74 // Suppress log noise from validation warnings 75 validationScope := log.Scopes()["validation"] 76 oldLevel := validationScope.GetOutputLevel() 77 validationScope.SetOutputLevel(log.ErrorLevel) 78 defer validationScope.SetOutputLevel(oldLevel) 79 80 // Generate blank test data 81 store := memory.MakeSkipValidation(collections.All) 82 collections.All.ForEach(func(s resource2.Schema) bool { 83 for i := 0; i < count; i++ { 84 name := resource.NewFullName("default", resource.LocalName(fmt.Sprintf("%s-%d", s.Kind(), i))) 85 _, _ = store.Create(config.Config{ 86 Meta: config.Meta{ 87 GroupVersionKind: s.GroupVersionKind(), 88 Name: name.Name.String(), 89 Namespace: name.Namespace.String(), 90 }, 91 Spec: s.MustNewInstance(), 92 }) 93 } 94 95 return false 96 }) 97 stores := map[cluster.ID]model.ConfigStore{ 98 "fake": store, 99 } 100 ctx := local.NewContext(stores, make(chan struct{}), func(name config.GroupVersionKind) {}) 101 102 b.ResetTimer() 103 for _, a := range All() { 104 b.Run(a.Metadata().Name+"-bench", func(b *testing.B) { 105 a.Analyze(ctx) 106 }) 107 } 108 }