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  }