github.com/elfadel/cilium@v1.6.12/pkg/fqdn/dnspoller_test.go (about) 1 // Copyright 2018 Authors of Cilium 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 15 // +build !privileged_tests 16 17 package fqdn 18 19 import ( 20 "context" 21 "net" 22 "sync" 23 24 "github.com/cilium/cilium/pkg/policy/api" 25 "github.com/miekg/dns" 26 27 . "gopkg.in/check.v1" 28 ) 29 30 var ( 31 ciliumIOSel = api.FQDNSelector{ 32 MatchName: "cilium.io", 33 } 34 35 githubSel = api.FQDNSelector{ 36 MatchName: "github.com", 37 } 38 39 ciliumIOSelMatchPattern = api.FQDNSelector{ 40 MatchPattern: "*cilium.io.", 41 } 42 ) 43 44 func (ds *FQDNTestSuite) TestNameManagerSelectorHandling(c *C) { 45 var testCases = []struct { 46 desc string 47 selectorsToAdd api.FQDNSelectorSlice 48 selectorsToDelete api.FQDNSelectorSlice 49 lookupIterationsAfterAdd int // # of times to call LookupUpdateDNS after add but before delete 50 lookupIterationsAfterDelete int // # of times to call LookupUpdateDNS after delete 51 checkFunc func(lookups map[string]int, nameManager *NameManager) 52 }{ 53 { 54 desc: "Lookup a name when added in a rule", 55 lookupIterationsAfterAdd: 1, 56 lookupIterationsAfterDelete: 0, 57 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 58 c.Assert(len(lookups), Equals, 1, Commentf("More than one DNS name was looked up for a rule with 1 DNS name")) 59 for _, name := range []string{dns.Fqdn("cilium.io")} { 60 c.Assert(lookups[name], Not(Equals), 0, Commentf("No lookups for DNS name %s in rule", name)) 61 c.Assert(lookups[name], Equals, 1, Commentf("More than one DNS lookup was triggered for the same DNS name %s", name)) 62 } 63 }, 64 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel}, 65 selectorsToDelete: nil, 66 }, 67 { 68 desc: "Lookup each name once when 2 are added in a rule", 69 lookupIterationsAfterAdd: 1, 70 lookupIterationsAfterDelete: 0, 71 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 72 c.Assert(len(lookups), Equals, 2, Commentf("More than two DNS names was looked up for a rule with 2 DNS name")) 73 for _, name := range []string{dns.Fqdn("cilium.io"), dns.Fqdn("github.com")} { 74 c.Assert(lookups[name], Not(Equals), 0, Commentf("No lookups for DNS name %s in rule", name)) 75 c.Assert(lookups[name], Equals, 1, Commentf("More than one DNS lookup was triggered for the same DNS name %s", name)) 76 } 77 }, 78 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel, githubSel}, 79 selectorsToDelete: nil, 80 }, 81 { 82 desc: "Lookup name once when two rules refer to it", 83 lookupIterationsAfterAdd: 1, 84 lookupIterationsAfterDelete: 0, 85 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 86 c.Assert(len(lookups), Equals, 1, Commentf("More than one DNS name was looked up for a rule with 1 DNS name")) 87 for _, name := range []string{dns.Fqdn("cilium.io")} { 88 c.Assert(lookups[name], Not(Equals), 0, Commentf("No lookups for DNS name %s in rule", name)) 89 c.Assert(lookups[name], Equals, 1, Commentf("More than one DNS lookup was triggered for the same DNS name %s", name)) 90 } 91 }, 92 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel, ciliumIOSel}, 93 selectorsToDelete: nil, 94 }, 95 { 96 desc: "No lookups after removing all rules", 97 lookupIterationsAfterAdd: 0, 98 lookupIterationsAfterDelete: 1, 99 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 100 c.Assert(len(lookups), Equals, 0, Commentf("DNS lookups occurred after removing all rules")) 101 }, 102 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel}, 103 selectorsToDelete: api.FQDNSelectorSlice{ciliumIOSel}, 104 }, 105 { 106 desc: "One lookup for a name after removing one of two referring FQDNSelectors", 107 lookupIterationsAfterAdd: 0, 108 lookupIterationsAfterDelete: 1, 109 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 110 c.Assert(len(nameManager.GetDNSNames()), Equals, 0, Commentf("No more DNS names should be present since tracking of FQDNSelectors is done via set (adding two of the same selector is equivalent to adding one)")) 111 c.Assert(len(lookups), Equals, 0, Commentf("Incorrect number of lookups for single name with a single FQDNSelector")) 112 }, 113 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel, ciliumIOSel}, 114 selectorsToDelete: api.FQDNSelectorSlice{ciliumIOSel}, 115 }, 116 { 117 desc: "One lookup for a name after removing an unrelated rule", 118 lookupIterationsAfterAdd: 0, 119 lookupIterationsAfterDelete: 1, 120 checkFunc: func(lookups map[string]int, nameManager *NameManager) { 121 c.Assert(len(nameManager.GetDNSNames()), Equals, 1, Commentf("Incorrect number of DNS targets for single name with a single referring rule")) 122 c.Assert(len(lookups), Equals, 1, Commentf("Incorrect number of lookups for single name with a single referring rule")) 123 for _, name := range []string{dns.Fqdn("cilium.io")} { 124 c.Assert(lookups[name], Not(Equals), 0, Commentf("No lookups for DNS name %s in rule", name)) 125 c.Assert(lookups[name], Equals, 1, Commentf("More than one DNS lookup was triggered for the same DNS name %s", name)) 126 } 127 }, 128 selectorsToAdd: api.FQDNSelectorSlice{ciliumIOSel, githubSel}, 129 selectorsToDelete: api.FQDNSelectorSlice{githubSel}, 130 }, 131 } 132 133 for _, testCase := range testCases { 134 c.Logf("Testcase: %s", testCase.desc) 135 var ( 136 lookups = make(map[string]int) 137 138 cfg = Config{ 139 MinTTL: 1, 140 Cache: NewDNSCache(0), 141 142 LookupDNSNames: func(dnsNames []string) (DNSIPs map[string]*DNSIPRecords, errorDNSNames map[string]error) { 143 return lookupDNSNames(ipLookups, lookups, dnsNames), nil 144 }, 145 146 UpdateSelectors: func(context.Context, map[api.FQDNSelector][]net.IP, []api.FQDNSelector) (*sync.WaitGroup, error) { 147 return &sync.WaitGroup{}, nil 148 }, 149 } 150 151 nameManager = NewNameManager(cfg) 152 poller = NewDNSPoller(cfg, nameManager) 153 ) 154 155 nameManager.Lock() 156 for _, fqdnSel := range testCase.selectorsToAdd { 157 nameManager.RegisterForIdentityUpdatesLocked(fqdnSel) 158 } 159 nameManager.Unlock() 160 for i := testCase.lookupIterationsAfterAdd; i > 0; i-- { 161 err := poller.LookupUpdateDNS(context.Background()) 162 c.Assert(err, IsNil, Commentf("Error running DNS lookups")) 163 } 164 165 // delete rules listed in the test case (note: we don't delete any unless 166 // they are listed) 167 nameManager.Lock() 168 for _, fqdnSel := range testCase.selectorsToDelete { 169 nameManager.UnregisterForIdentityUpdatesLocked(fqdnSel) 170 } 171 nameManager.Unlock() 172 for i := testCase.lookupIterationsAfterDelete; i > 0; i-- { 173 err := poller.LookupUpdateDNS(context.Background()) 174 c.Assert(err, IsNil, Commentf("Error running DNS lookups")) 175 } 176 177 // call the testcase checkFunc, it will assert everything relevant to the test 178 testCase.checkFunc(lookups, nameManager) 179 } 180 }