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 }