"Fossies" - the Fresh Open Source Software Archive

Member "AdGuardHome-0.104.3/internal/dnsfilter/dnsfilter_test.go" (19 Nov 2020, 17793 Bytes) of package /linux/misc/dns/AdGuardHome-0.104.3.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "dnsfilter_test.go": 0.104.1_vs_0.104.3.

    1 package dnsfilter
    2 
    3 import (
    4     "bytes"
    5     "fmt"
    6     "net"
    7     "strings"
    8     "testing"
    9 
   10     "github.com/AdguardTeam/AdGuardHome/internal/testutil"
   11     "github.com/AdguardTeam/golibs/log"
   12     "github.com/AdguardTeam/urlfilter/rules"
   13     "github.com/miekg/dns"
   14     "github.com/stretchr/testify/assert"
   15 )
   16 
   17 func TestMain(m *testing.M) {
   18     testutil.DiscardLogOutput(m)
   19 }
   20 
   21 var setts RequestFilteringSettings
   22 
   23 // HELPERS
   24 // SAFE BROWSING
   25 // SAFE SEARCH
   26 // PARENTAL
   27 // FILTERING
   28 // BENCHMARKS
   29 
   30 // HELPERS
   31 
   32 func purgeCaches() {
   33     if gctx.safebrowsingCache != nil {
   34         gctx.safebrowsingCache.Clear()
   35     }
   36     if gctx.parentalCache != nil {
   37         gctx.parentalCache.Clear()
   38     }
   39     if gctx.safeSearchCache != nil {
   40         gctx.safeSearchCache.Clear()
   41     }
   42 }
   43 
   44 func NewForTest(c *Config, filters []Filter) *Dnsfilter {
   45     setts = RequestFilteringSettings{}
   46     setts.FilteringEnabled = true
   47     if c != nil {
   48         c.SafeBrowsingCacheSize = 10000
   49         c.ParentalCacheSize = 10000
   50         c.SafeSearchCacheSize = 1000
   51         c.CacheTime = 30
   52         setts.SafeSearchEnabled = c.SafeSearchEnabled
   53         setts.SafeBrowsingEnabled = c.SafeBrowsingEnabled
   54         setts.ParentalEnabled = c.ParentalEnabled
   55     }
   56     d := New(c, filters)
   57     purgeCaches()
   58     return d
   59 }
   60 
   61 func (d *Dnsfilter) checkMatch(t *testing.T, hostname string) {
   62     t.Helper()
   63     ret, err := d.CheckHost(hostname, dns.TypeA, &setts)
   64     if err != nil {
   65         t.Errorf("Error while matching host %s: %s", hostname, err)
   66     }
   67     if !ret.IsFiltered {
   68         t.Errorf("Expected hostname %s to match", hostname)
   69     }
   70 }
   71 
   72 func (d *Dnsfilter) checkMatchIP(t *testing.T, hostname, ip string, qtype uint16) {
   73     t.Helper()
   74     ret, err := d.CheckHost(hostname, qtype, &setts)
   75     if err != nil {
   76         t.Errorf("Error while matching host %s: %s", hostname, err)
   77     }
   78     if !ret.IsFiltered {
   79         t.Errorf("Expected hostname %s to match", hostname)
   80     }
   81     if ret.IP == nil || ret.IP.String() != ip {
   82         t.Errorf("Expected ip %s to match, actual: %v", ip, ret.IP)
   83     }
   84 }
   85 
   86 func (d *Dnsfilter) checkMatchEmpty(t *testing.T, hostname string) {
   87     t.Helper()
   88     ret, err := d.CheckHost(hostname, dns.TypeA, &setts)
   89     if err != nil {
   90         t.Errorf("Error while matching host %s: %s", hostname, err)
   91     }
   92     if ret.IsFiltered {
   93         t.Errorf("Expected hostname %s to not match", hostname)
   94     }
   95 }
   96 
   97 func TestEtcHostsMatching(t *testing.T) {
   98     addr := "216.239.38.120"
   99     addr6 := "::1"
  100     text := fmt.Sprintf(`  %s  google.com www.google.com   # enforce google's safesearch
  101 %s  ipv6.com
  102 0.0.0.0 block.com
  103 0.0.0.1 host2
  104 0.0.0.2 host2
  105 ::1 host2
  106 `,
  107         addr, addr6)
  108     filters := []Filter{{
  109         ID: 0, Data: []byte(text),
  110     }}
  111     d := NewForTest(nil, filters)
  112     defer d.Close()
  113 
  114     d.checkMatchIP(t, "google.com", addr, dns.TypeA)
  115     d.checkMatchIP(t, "www.google.com", addr, dns.TypeA)
  116     d.checkMatchEmpty(t, "subdomain.google.com")
  117     d.checkMatchEmpty(t, "example.org")
  118 
  119     // IPv4
  120     d.checkMatchIP(t, "block.com", "0.0.0.0", dns.TypeA)
  121 
  122     // ...but empty IPv6
  123     ret, err := d.CheckHost("block.com", dns.TypeAAAA, &setts)
  124     assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
  125     assert.True(t, ret.Rule == "0.0.0.0 block.com")
  126 
  127     // IPv6
  128     d.checkMatchIP(t, "ipv6.com", addr6, dns.TypeAAAA)
  129 
  130     // ...but empty IPv4
  131     ret, err = d.CheckHost("ipv6.com", dns.TypeA, &setts)
  132     assert.True(t, err == nil && ret.IsFiltered && ret.IP != nil && len(ret.IP) == 0)
  133 
  134     // 2 IPv4 (return only the first one)
  135     ret, err = d.CheckHost("host2", dns.TypeA, &setts)
  136     assert.True(t, err == nil && ret.IsFiltered)
  137     assert.True(t, ret.IP != nil && ret.IP.Equal(net.ParseIP("0.0.0.1")))
  138 
  139     // ...and 1 IPv6 address
  140     ret, err = d.CheckHost("host2", dns.TypeAAAA, &setts)
  141     assert.True(t, err == nil && ret.IsFiltered)
  142     assert.True(t, ret.IP != nil && ret.IP.Equal(net.ParseIP("::1")))
  143 }
  144 
  145 // SAFE BROWSING
  146 
  147 func TestSafeBrowsing(t *testing.T) {
  148     logOutput := &bytes.Buffer{}
  149     testutil.ReplaceLogWriter(t, logOutput)
  150     testutil.ReplaceLogLevel(t, log.DEBUG)
  151 
  152     d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil)
  153     defer d.Close()
  154     gctx.stats.Safebrowsing.Requests = 0
  155     d.checkMatch(t, "wmconvirus.narod.ru")
  156 
  157     assert.True(t, strings.Contains(logOutput.String(), "SafeBrowsing lookup for wmconvirus.narod.ru"))
  158 
  159     d.checkMatch(t, "test.wmconvirus.narod.ru")
  160     d.checkMatchEmpty(t, "yandex.ru")
  161     d.checkMatchEmpty(t, "pornhub.com")
  162 
  163     // test cached result
  164     d.safeBrowsingServer = "127.0.0.1"
  165     d.checkMatch(t, "wmconvirus.narod.ru")
  166     d.checkMatchEmpty(t, "pornhub.com")
  167     d.safeBrowsingServer = defaultSafebrowsingServer
  168 }
  169 
  170 func TestParallelSB(t *testing.T) {
  171     d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil)
  172     defer d.Close()
  173     t.Run("group", func(t *testing.T) {
  174         for i := 0; i < 100; i++ {
  175             t.Run(fmt.Sprintf("aaa%d", i), func(t *testing.T) {
  176                 t.Parallel()
  177                 d.checkMatch(t, "wmconvirus.narod.ru")
  178                 d.checkMatch(t, "test.wmconvirus.narod.ru")
  179                 d.checkMatchEmpty(t, "yandex.ru")
  180                 d.checkMatchEmpty(t, "pornhub.com")
  181             })
  182         }
  183     })
  184 }
  185 
  186 // SAFE SEARCH
  187 
  188 func TestSafeSearch(t *testing.T) {
  189     d := NewForTest(&Config{SafeSearchEnabled: true}, nil)
  190     defer d.Close()
  191     val, ok := d.SafeSearchDomain("www.google.com")
  192     if !ok {
  193         t.Errorf("Expected safesearch to find result for www.google.com")
  194     }
  195     if val != "forcesafesearch.google.com" {
  196         t.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
  197     }
  198 }
  199 
  200 func TestCheckHostSafeSearchYandex(t *testing.T) {
  201     d := NewForTest(&Config{SafeSearchEnabled: true}, nil)
  202     defer d.Close()
  203 
  204     // Slice of yandex domains
  205     yandex := []string{"yAndeX.ru", "YANdex.COM", "yandex.ua", "yandex.by", "yandex.kz", "www.yandex.com"}
  206 
  207     // Check host for each domain
  208     for _, host := range yandex {
  209         result, err := d.CheckHost(host, dns.TypeA, &setts)
  210         if err != nil {
  211             t.Errorf("SafeSearch doesn't work for yandex domain `%s` cause %s", host, err)
  212         }
  213 
  214         if result.IP.String() != "213.180.193.56" {
  215             t.Errorf("SafeSearch doesn't work for yandex domain `%s`", host)
  216         }
  217     }
  218 }
  219 
  220 func TestCheckHostSafeSearchGoogle(t *testing.T) {
  221     d := NewForTest(&Config{SafeSearchEnabled: true}, nil)
  222     defer d.Close()
  223 
  224     // Slice of google domains
  225     googleDomains := []string{"www.google.com", "www.google.im", "www.google.co.in", "www.google.iq", "www.google.is", "www.google.it", "www.google.je"}
  226 
  227     // Check host for each domain
  228     for _, host := range googleDomains {
  229         result, err := d.CheckHost(host, dns.TypeA, &setts)
  230         if err != nil {
  231             t.Errorf("SafeSearch doesn't work for %s cause %s", host, err)
  232         }
  233 
  234         if result.IP == nil {
  235             t.Errorf("SafeSearch doesn't work for %s", host)
  236         }
  237     }
  238 }
  239 
  240 func TestSafeSearchCacheYandex(t *testing.T) {
  241     d := NewForTest(nil, nil)
  242     defer d.Close()
  243     domain := "yandex.ru"
  244 
  245     var result Result
  246     var err error
  247 
  248     // Check host with disabled safesearch
  249     result, err = d.CheckHost(domain, dns.TypeA, &setts)
  250     if err != nil {
  251         t.Fatalf("Cannot check host due to %s", err)
  252     }
  253     if result.IP != nil {
  254         t.Fatalf("SafeSearch is not enabled but there is an answer for `%s` !", domain)
  255     }
  256 
  257     d = NewForTest(&Config{SafeSearchEnabled: true}, nil)
  258     defer d.Close()
  259 
  260     result, err = d.CheckHost(domain, dns.TypeA, &setts)
  261     if err != nil {
  262         t.Fatalf("CheckHost for safesearh domain %s failed cause %s", domain, err)
  263     }
  264 
  265     // Fir yandex we already know valid ip
  266     if result.IP.String() != "213.180.193.56" {
  267         t.Fatalf("Wrong IP for %s safesearch: %s", domain, result.IP.String())
  268     }
  269 
  270     // Check cache
  271     cachedValue, isFound := getCachedResult(gctx.safeSearchCache, domain)
  272 
  273     if !isFound {
  274         t.Fatalf("Safesearch cache doesn't work for %s!", domain)
  275     }
  276 
  277     if cachedValue.IP.String() != "213.180.193.56" {
  278         t.Fatalf("Wrong IP in cache for %s safesearch: %s", domain, cachedValue.IP.String())
  279     }
  280 }
  281 
  282 func TestSafeSearchCacheGoogle(t *testing.T) {
  283     d := NewForTest(nil, nil)
  284     defer d.Close()
  285     domain := "www.google.ru"
  286     result, err := d.CheckHost(domain, dns.TypeA, &setts)
  287     if err != nil {
  288         t.Fatalf("Cannot check host due to %s", err)
  289     }
  290     if result.IP != nil {
  291         t.Fatalf("SafeSearch is not enabled but there is an answer!")
  292     }
  293 
  294     d = NewForTest(&Config{SafeSearchEnabled: true}, nil)
  295     defer d.Close()
  296 
  297     // Let's lookup for safesearch domain
  298     safeDomain, ok := d.SafeSearchDomain(domain)
  299     if !ok {
  300         t.Fatalf("Failed to get safesearch domain for %s", domain)
  301     }
  302 
  303     ips, err := net.LookupIP(safeDomain)
  304     if err != nil {
  305         t.Fatalf("Failed to lookup for %s", safeDomain)
  306     }
  307 
  308     ip := ips[0]
  309     for _, i := range ips {
  310         if i.To4() != nil {
  311             ip = i
  312             break
  313         }
  314     }
  315 
  316     result, err = d.CheckHost(domain, dns.TypeA, &setts)
  317     if err != nil {
  318         t.Fatalf("CheckHost for safesearh domain %s failed cause %s", domain, err)
  319     }
  320 
  321     if result.IP.String() != ip.String() {
  322         t.Fatalf("Wrong IP for %s safesearch: %s.  Should be: %s",
  323             domain, result.IP.String(), ip)
  324     }
  325 
  326     // Check cache
  327     cachedValue, isFound := getCachedResult(gctx.safeSearchCache, domain)
  328 
  329     if !isFound {
  330         t.Fatalf("Safesearch cache doesn't work for %s!", domain)
  331     }
  332 
  333     if cachedValue.IP.String() != ip.String() {
  334         t.Fatalf("Wrong IP in cache for %s safesearch: %s", domain, cachedValue.IP.String())
  335     }
  336 }
  337 
  338 // PARENTAL
  339 
  340 func TestParentalControl(t *testing.T) {
  341     logOutput := &bytes.Buffer{}
  342     testutil.ReplaceLogWriter(t, logOutput)
  343     testutil.ReplaceLogLevel(t, log.DEBUG)
  344 
  345     d := NewForTest(&Config{ParentalEnabled: true}, nil)
  346     defer d.Close()
  347     d.checkMatch(t, "pornhub.com")
  348     assert.True(t, strings.Contains(logOutput.String(), "Parental lookup for pornhub.com"))
  349     d.checkMatch(t, "www.pornhub.com")
  350     d.checkMatchEmpty(t, "www.yandex.ru")
  351     d.checkMatchEmpty(t, "yandex.ru")
  352     d.checkMatchEmpty(t, "api.jquery.com")
  353 
  354     // test cached result
  355     d.parentalServer = "127.0.0.1"
  356     d.checkMatch(t, "pornhub.com")
  357     d.checkMatchEmpty(t, "yandex.ru")
  358     d.parentalServer = defaultParentalServer
  359 }
  360 
  361 // FILTERING
  362 
  363 const nl = "\n"
  364 
  365 const (
  366     blockingRules  = `||example.org^` + nl
  367     whitelistRules = `||example.org^` + nl + `@@||test.example.org` + nl
  368     importantRules = `@@||example.org^` + nl + `||test.example.org^$important` + nl
  369     regexRules     = `/example\.org/` + nl + `@@||test.example.org^` + nl
  370     maskRules      = `test*.example.org^` + nl + `exam*.com` + nl
  371 )
  372 
  373 var tests = []struct {
  374     testname   string
  375     rules      string
  376     hostname   string
  377     isFiltered bool
  378     reason     Reason
  379 }{
  380     {"sanity", "||doubleclick.net^", "www.doubleclick.net", true, FilteredBlackList},
  381     {"sanity", "||doubleclick.net^", "nodoubleclick.net", false, NotFilteredNotFound},
  382     {"sanity", "||doubleclick.net^", "doubleclick.net.ru", false, NotFilteredNotFound},
  383     {"sanity", "||doubleclick.net^", "wmconvirus.narod.ru", false, NotFilteredNotFound},
  384 
  385     {"blocking", blockingRules, "example.org", true, FilteredBlackList},
  386     {"blocking", blockingRules, "test.example.org", true, FilteredBlackList},
  387     {"blocking", blockingRules, "test.test.example.org", true, FilteredBlackList},
  388     {"blocking", blockingRules, "testexample.org", false, NotFilteredNotFound},
  389     {"blocking", blockingRules, "onemoreexample.org", false, NotFilteredNotFound},
  390 
  391     {"whitelist", whitelistRules, "example.org", true, FilteredBlackList},
  392     {"whitelist", whitelistRules, "test.example.org", false, NotFilteredWhiteList},
  393     {"whitelist", whitelistRules, "test.test.example.org", false, NotFilteredWhiteList},
  394     {"whitelist", whitelistRules, "testexample.org", false, NotFilteredNotFound},
  395     {"whitelist", whitelistRules, "onemoreexample.org", false, NotFilteredNotFound},
  396 
  397     {"important", importantRules, "example.org", false, NotFilteredWhiteList},
  398     {"important", importantRules, "test.example.org", true, FilteredBlackList},
  399     {"important", importantRules, "test.test.example.org", true, FilteredBlackList},
  400     {"important", importantRules, "testexample.org", false, NotFilteredNotFound},
  401     {"important", importantRules, "onemoreexample.org", false, NotFilteredNotFound},
  402 
  403     {"regex", regexRules, "example.org", true, FilteredBlackList},
  404     {"regex", regexRules, "test.example.org", false, NotFilteredWhiteList},
  405     {"regex", regexRules, "test.test.example.org", false, NotFilteredWhiteList},
  406     {"regex", regexRules, "testexample.org", true, FilteredBlackList},
  407     {"regex", regexRules, "onemoreexample.org", true, FilteredBlackList},
  408 
  409     {"mask", maskRules, "test.example.org", true, FilteredBlackList},
  410     {"mask", maskRules, "test2.example.org", true, FilteredBlackList},
  411     {"mask", maskRules, "example.com", true, FilteredBlackList},
  412     {"mask", maskRules, "exampleeee.com", true, FilteredBlackList},
  413     {"mask", maskRules, "onemoreexamsite.com", true, FilteredBlackList},
  414     {"mask", maskRules, "example.org", false, NotFilteredNotFound},
  415     {"mask", maskRules, "testexample.org", false, NotFilteredNotFound},
  416     {"mask", maskRules, "example.co.uk", false, NotFilteredNotFound},
  417 }
  418 
  419 func TestMatching(t *testing.T) {
  420     for _, test := range tests {
  421         t.Run(fmt.Sprintf("%s-%s", test.testname, test.hostname), func(t *testing.T) {
  422             filters := []Filter{{
  423                 ID: 0, Data: []byte(test.rules),
  424             }}
  425             d := NewForTest(nil, filters)
  426             defer d.Close()
  427 
  428             ret, err := d.CheckHost(test.hostname, dns.TypeA, &setts)
  429             if err != nil {
  430                 t.Errorf("Error while matching host %s: %s", test.hostname, err)
  431             }
  432             if ret.IsFiltered != test.isFiltered {
  433                 t.Errorf("Hostname %s has wrong result (%v must be %v)", test.hostname, ret.IsFiltered, test.isFiltered)
  434             }
  435             if ret.Reason != test.reason {
  436                 t.Errorf("Hostname %s has wrong reason (%v must be %v)", test.hostname, ret.Reason.String(), test.reason.String())
  437             }
  438         })
  439     }
  440 }
  441 
  442 func TestWhitelist(t *testing.T) {
  443     rules := `||host1^
  444 ||host2^
  445 `
  446     filters := []Filter{{
  447         ID: 0, Data: []byte(rules),
  448     }}
  449 
  450     whiteRules := `||host1^
  451 ||host3^
  452 `
  453     whiteFilters := []Filter{{
  454         ID: 0, Data: []byte(whiteRules),
  455     }}
  456     d := NewForTest(nil, filters)
  457     d.SetFilters(filters, whiteFilters, false)
  458     defer d.Close()
  459 
  460     // matched by white filter
  461     ret, err := d.CheckHost("host1", dns.TypeA, &setts)
  462     assert.True(t, err == nil)
  463     assert.True(t, !ret.IsFiltered && ret.Reason == NotFilteredWhiteList)
  464     assert.True(t, ret.Rule == "||host1^")
  465 
  466     // not matched by white filter, but matched by block filter
  467     ret, err = d.CheckHost("host2", dns.TypeA, &setts)
  468     assert.True(t, err == nil)
  469     assert.True(t, ret.IsFiltered && ret.Reason == FilteredBlackList)
  470     assert.True(t, ret.Rule == "||host2^")
  471 }
  472 
  473 // CLIENT SETTINGS
  474 
  475 func applyClientSettings(setts *RequestFilteringSettings) {
  476     setts.FilteringEnabled = false
  477     setts.ParentalEnabled = false
  478     setts.SafeBrowsingEnabled = true
  479 
  480     rule, _ := rules.NewNetworkRule("||facebook.com^", 0)
  481     s := ServiceEntry{}
  482     s.Name = "facebook"
  483     s.Rules = []*rules.NetworkRule{rule}
  484     setts.ServicesRules = append(setts.ServicesRules, s)
  485 }
  486 
  487 // Check behaviour without any per-client settings,
  488 //  then apply per-client settings and check behaviour once again
  489 func TestClientSettings(t *testing.T) {
  490     var r Result
  491     filters := []Filter{{
  492         ID: 0, Data: []byte("||example.org^\n"),
  493     }}
  494     d := NewForTest(&Config{ParentalEnabled: true, SafeBrowsingEnabled: false}, filters)
  495     defer d.Close()
  496 
  497     // no client settings:
  498 
  499     // blocked by filters
  500     r, _ = d.CheckHost("example.org", dns.TypeA, &setts)
  501     if !r.IsFiltered || r.Reason != FilteredBlackList {
  502         t.Fatalf("CheckHost FilteredBlackList")
  503     }
  504 
  505     // blocked by parental
  506     r, _ = d.CheckHost("pornhub.com", dns.TypeA, &setts)
  507     if !r.IsFiltered || r.Reason != FilteredParental {
  508         t.Fatalf("CheckHost FilteredParental")
  509     }
  510 
  511     // safesearch is disabled
  512     r, _ = d.CheckHost("wmconvirus.narod.ru", dns.TypeA, &setts)
  513     if r.IsFiltered {
  514         t.Fatalf("CheckHost safesearch")
  515     }
  516 
  517     // not blocked
  518     r, _ = d.CheckHost("facebook.com", dns.TypeA, &setts)
  519     assert.True(t, !r.IsFiltered)
  520 
  521     // override client settings:
  522     applyClientSettings(&setts)
  523 
  524     // override filtering settings
  525     r, _ = d.CheckHost("example.org", dns.TypeA, &setts)
  526     if r.IsFiltered {
  527         t.Fatalf("CheckHost")
  528     }
  529 
  530     // override parental settings (force disable parental)
  531     r, _ = d.CheckHost("pornhub.com", dns.TypeA, &setts)
  532     if r.IsFiltered {
  533         t.Fatalf("CheckHost")
  534     }
  535 
  536     // override safesearch settings (force enable safesearch)
  537     r, _ = d.CheckHost("wmconvirus.narod.ru", dns.TypeA, &setts)
  538     if !r.IsFiltered || r.Reason != FilteredSafeBrowsing {
  539         t.Fatalf("CheckHost FilteredSafeBrowsing")
  540     }
  541 
  542     // blocked by additional rules
  543     r, _ = d.CheckHost("facebook.com", dns.TypeA, &setts)
  544     assert.True(t, r.IsFiltered && r.Reason == FilteredBlockedService)
  545 }
  546 
  547 // BENCHMARKS
  548 
  549 func BenchmarkSafeBrowsing(b *testing.B) {
  550     d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil)
  551     defer d.Close()
  552     for n := 0; n < b.N; n++ {
  553         hostname := "wmconvirus.narod.ru"
  554         ret, err := d.CheckHost(hostname, dns.TypeA, &setts)
  555         if err != nil {
  556             b.Errorf("Error while matching host %s: %s", hostname, err)
  557         }
  558         if !ret.IsFiltered {
  559             b.Errorf("Expected hostname %s to match", hostname)
  560         }
  561     }
  562 }
  563 
  564 func BenchmarkSafeBrowsingParallel(b *testing.B) {
  565     d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil)
  566     defer d.Close()
  567     b.RunParallel(func(pb *testing.PB) {
  568         for pb.Next() {
  569             hostname := "wmconvirus.narod.ru"
  570             ret, err := d.CheckHost(hostname, dns.TypeA, &setts)
  571             if err != nil {
  572                 b.Errorf("Error while matching host %s: %s", hostname, err)
  573             }
  574             if !ret.IsFiltered {
  575                 b.Errorf("Expected hostname %s to match", hostname)
  576             }
  577         }
  578     })
  579 }
  580 
  581 func BenchmarkSafeSearch(b *testing.B) {
  582     d := NewForTest(&Config{SafeSearchEnabled: true}, nil)
  583     defer d.Close()
  584     for n := 0; n < b.N; n++ {
  585         val, ok := d.SafeSearchDomain("www.google.com")
  586         if !ok {
  587             b.Errorf("Expected safesearch to find result for www.google.com")
  588         }
  589         if val != "forcesafesearch.google.com" {
  590             b.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
  591         }
  592     }
  593 }
  594 
  595 func BenchmarkSafeSearchParallel(b *testing.B) {
  596     d := NewForTest(&Config{SafeSearchEnabled: true}, nil)
  597     defer d.Close()
  598     b.RunParallel(func(pb *testing.PB) {
  599         for pb.Next() {
  600             val, ok := d.SafeSearchDomain("www.google.com")
  601             if !ok {
  602                 b.Errorf("Expected safesearch to find result for www.google.com")
  603             }
  604             if val != "forcesafesearch.google.com" {
  605                 b.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
  606             }
  607         }
  608     })
  609 }