github.com/cilium/cilium@v1.16.2/pkg/fqdn/name_manager_bench_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package fqdn
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"net"
    10  	"net/netip"
    11  	"strconv"
    12  	"testing"
    13  
    14  	"github.com/cilium/cilium/pkg/defaults"
    15  	"github.com/cilium/cilium/pkg/fqdn/dns"
    16  	"github.com/cilium/cilium/pkg/fqdn/re"
    17  	"github.com/cilium/cilium/pkg/policy/api"
    18  	testipcache "github.com/cilium/cilium/pkg/testutils/ipcache"
    19  	"github.com/cilium/cilium/pkg/time"
    20  )
    21  
    22  // BenchmarkUpdateGenerateDNS tests updating a large number of selectors.
    23  //
    24  // Run it like
    25  // go test -benchmem -run=^$ -bench ^BenchmarkUpdateGeneratedDNS$ github.com/cilium/cilium/pkg/fqdn -benchtime=4x -count=10
    26  func BenchmarkUpdateGenerateDNS(b *testing.B) {
    27  
    28  	// For every i in range 1 .. K, create selectors
    29  	// - "$K.example.com"
    30  	// - "*.$K.example.com"
    31  	// as well as *.example.com.
    32  	//
    33  	// Then, update the generated DNS N * K times, setting i to N % K, and updating
    34  	// - $i.example.com
    35  	// - foo.$i.example.com
    36  	// with a random new IP
    37  
    38  	numSelectors := 1000
    39  
    40  	re.InitRegexCompileLRU(defaults.FQDNRegexCompileLRUSize)
    41  
    42  	nameManager := NewNameManager(Config{
    43  		MinTTL:  1,
    44  		Cache:   NewDNSCache(0),
    45  		IPCache: testipcache.NewMockIPCache(),
    46  	})
    47  
    48  	for i := 0; i < numSelectors; i++ {
    49  		nameManager.RegisterFQDNSelector(api.FQDNSelector{
    50  			MatchName: fmt.Sprintf("%d.example.com", i),
    51  		})
    52  		nameManager.RegisterFQDNSelector(api.FQDNSelector{
    53  			MatchPattern: fmt.Sprintf("*.%d.example.com", i),
    54  		})
    55  	}
    56  	nameManager.RegisterFQDNSelector(api.FQDNSelector{
    57  		MatchPattern: "*.example.com",
    58  	})
    59  
    60  	t := time.Now() // doesn't matter, just need a stable base
    61  	ip := netip.MustParseAddr("10.0.0.0")
    62  
    63  	b.ResetTimer() // Don't benchmark adding selectors, just evaluating them
    64  	for i := 0; i < b.N*numSelectors; i++ {
    65  		t = t.Add(1 * time.Second)
    66  		ip = ip.Next()
    67  
    68  		k := i % numSelectors
    69  		nameManager.UpdateGenerateDNS(context.Background(), t, map[string]*DNSIPRecords{
    70  			dns.FQDN(fmt.Sprintf("%d.example.com", k)): {
    71  				TTL: 60,
    72  				IPs: []net.IP{ip.AsSlice()},
    73  			}})
    74  
    75  		nameManager.UpdateGenerateDNS(context.Background(), t, map[string]*DNSIPRecords{
    76  			dns.FQDN(fmt.Sprintf("example.%d.example.com", k)): {
    77  				TTL: 60,
    78  				IPs: []net.IP{ip.AsSlice()},
    79  			}})
    80  	}
    81  }
    82  
    83  // BenchmarkFqdnCache tests how slow a full dump of DNSHistory from a number of
    84  // endpoints is. Each endpoints has 1000 DNS lookups, each with 10 IPs. The
    85  // dump iterates over all endpoints, lookups, and IPs.
    86  func BenchmarkFqdnCache(b *testing.B) {
    87  	const endpoints = 8
    88  
    89  	caches := make([]*DNSCache, 0, endpoints)
    90  	for i := 0; i < b.N; i++ {
    91  		lookupTime := time.Now()
    92  		dnsHistory := NewDNSCache(0)
    93  
    94  		for i := 0; i < 1000; i++ {
    95  			dnsHistory.Update(lookupTime, fmt.Sprintf("domain-%d.com.", i), makeIPs(10), 1000)
    96  		}
    97  
    98  		caches = append(caches, dnsHistory)
    99  	}
   100  
   101  	nameManager := NewNameManager(Config{
   102  		MinTTL:  1,
   103  		Cache:   NewDNSCache(0),
   104  		IPCache: testipcache.NewMockIPCache(),
   105  		GetEndpointsDNSInfo: func(endpointID string) []EndpointDNSInfo {
   106  			out := make([]EndpointDNSInfo, 0, len(caches))
   107  			for i, c := range caches {
   108  				out = append(out, EndpointDNSInfo{
   109  					ID:         strconv.Itoa(i),
   110  					ID64:       int64(i),
   111  					DNSHistory: c,
   112  					DNSZombies: NewDNSZombieMappings(1000, 1000),
   113  				})
   114  			}
   115  			return out
   116  		},
   117  	})
   118  	prefixMatcher := func(_ netip.Addr) bool { return true }
   119  	nameMatcher := func(_ string) bool { return true }
   120  
   121  	b.ResetTimer()
   122  	for i := 0; i < b.N; i++ {
   123  		nameManager.GetDNSHistoryModel("", prefixMatcher, nameMatcher, "")
   124  	}
   125  }