2018-08-30 17:25:33 +03:00
|
|
|
package dnsfilter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
"net/http/httptest"
|
2018-09-14 16:50:56 +03:00
|
|
|
"path"
|
|
|
|
"strings"
|
2018-08-30 17:25:33 +03:00
|
|
|
"testing"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"bufio"
|
|
|
|
"fmt"
|
|
|
|
"os"
|
|
|
|
"runtime"
|
|
|
|
|
|
|
|
"go.uber.org/goleak"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestRuleToRegexp(t *testing.T) {
|
|
|
|
tests := []struct {
|
|
|
|
rule string
|
|
|
|
result string
|
|
|
|
err error
|
|
|
|
}{
|
|
|
|
{"/doubleclick/", "doubleclick", nil},
|
|
|
|
{"/", "", ErrInvalidSyntax},
|
|
|
|
{`|double*?.+[]|(){}#$\|`, `^double.*\?\.\+\[\]\|\(\)\{\}\#\$\\$`, nil},
|
|
|
|
{`||doubleclick.net^`, `^([a-z0-9-_.]+\.)?doubleclick\.net([^ a-zA-Z0-9.%]|$)`, nil},
|
|
|
|
}
|
|
|
|
for _, testcase := range tests {
|
|
|
|
converted, err := ruleToRegexp(testcase.rule)
|
|
|
|
if err != testcase.err {
|
|
|
|
t.Error("Errors do not match, got ", err, " expected ", testcase.err)
|
|
|
|
}
|
|
|
|
if converted != testcase.result {
|
|
|
|
t.Error("Results do not match, got ", converted, " expected ", testcase.result)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// helper functions
|
|
|
|
//
|
|
|
|
func (d *Dnsfilter) checkAddRule(t *testing.T, rule string) {
|
|
|
|
t.Helper()
|
|
|
|
err := d.AddRule(rule, 0)
|
|
|
|
if err == nil {
|
|
|
|
// nothing to report
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err == ErrInvalidSyntax {
|
|
|
|
t.Errorf("This rule has invalid syntax: %s", rule)
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while adding rule %s: %s", rule, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Dnsfilter) checkAddRuleFail(t *testing.T, rule string) {
|
|
|
|
t.Helper()
|
|
|
|
err := d.AddRule(rule, 0)
|
|
|
|
if err == ErrInvalidSyntax {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while adding rule %s: %s", rule, err)
|
|
|
|
}
|
|
|
|
t.Errorf("Adding this rule should have failed: %s", rule)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Dnsfilter) checkMatch(t *testing.T, hostname string) {
|
|
|
|
t.Helper()
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if !ret.IsFiltered {
|
|
|
|
t.Errorf("Expected hostname %s to match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *Dnsfilter) checkMatchEmpty(t *testing.T, hostname string) {
|
|
|
|
t.Helper()
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if ret.IsFiltered {
|
|
|
|
t.Errorf("Expected hostname %s to not match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadTestRules(d *Dnsfilter) error {
|
|
|
|
filterFileName := "../tests/dns.txt"
|
|
|
|
file, err := os.Open(filterFileName)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
|
|
|
|
scanner := bufio.NewScanner(file)
|
|
|
|
for scanner.Scan() {
|
|
|
|
rule := scanner.Text()
|
|
|
|
err = d.AddRule(rule, 0)
|
|
|
|
if err == ErrInvalidSyntax {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = scanner.Err()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewForTest() *Dnsfilter {
|
|
|
|
d := New()
|
|
|
|
purgeCaches()
|
|
|
|
return d
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// tests
|
|
|
|
//
|
|
|
|
func TestSanityCheck(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "||doubleclick.net^")
|
|
|
|
d.checkMatch(t, "www.doubleclick.net")
|
|
|
|
d.checkMatchEmpty(t, "nodoubleclick.net")
|
|
|
|
d.checkMatchEmpty(t, "doubleclick.net.ru")
|
|
|
|
d.checkMatchEmpty(t, "wmconvirus.narod.ru")
|
|
|
|
d.checkAddRuleFail(t, "lkfaojewhoawehfwacoefawr$@#$@3413841384")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCount(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
count := d.Count()
|
|
|
|
expected := 12747
|
|
|
|
if count != expected {
|
|
|
|
t.Fatalf("Number of rules parsed should be %d, but it is %d\n", expected, count)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDnsFilterBlocking(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "||example.org^")
|
|
|
|
|
|
|
|
d.checkMatch(t, "example.org")
|
|
|
|
d.checkMatch(t, "test.example.org")
|
|
|
|
d.checkMatch(t, "test.test.example.org")
|
|
|
|
d.checkMatchEmpty(t, "testexample.org")
|
|
|
|
d.checkMatchEmpty(t, "onemoreexample.org")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDnsFilterWhitelist(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "||example.org^")
|
|
|
|
d.checkAddRule(t, "@@||test.example.org")
|
|
|
|
|
|
|
|
d.checkMatch(t, "example.org")
|
|
|
|
d.checkMatchEmpty(t, "test.example.org")
|
|
|
|
d.checkMatchEmpty(t, "test.test.example.org")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDnsFilterImportant(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "@@||example.org^")
|
|
|
|
d.checkAddRule(t, "||test.example.org^$important")
|
|
|
|
|
|
|
|
d.checkMatchEmpty(t, "example.org")
|
|
|
|
d.checkMatch(t, "test.example.org")
|
|
|
|
d.checkMatch(t, "test.test.example.org")
|
|
|
|
d.checkMatchEmpty(t, "testexample.org")
|
|
|
|
d.checkMatchEmpty(t, "onemoreexample.org")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDnsFilterRegexrule(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "/example\\.org/")
|
|
|
|
d.checkAddRule(t, "@@||test.example.org^")
|
|
|
|
|
|
|
|
d.checkMatch(t, "example.org")
|
|
|
|
d.checkMatchEmpty(t, "test.example.org")
|
|
|
|
d.checkMatchEmpty(t, "test.test.example.org")
|
|
|
|
d.checkMatch(t, "testexample.org")
|
|
|
|
d.checkMatch(t, "onemoreexample.org")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestDomainMask(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRule(t, "test*.example.org^")
|
|
|
|
d.checkAddRule(t, "exam*.com")
|
|
|
|
|
|
|
|
d.checkMatch(t, "test.example.org")
|
|
|
|
d.checkMatch(t, "test2.example.org")
|
|
|
|
d.checkMatch(t, "example.com")
|
|
|
|
d.checkMatch(t, "exampleeee.com")
|
|
|
|
|
|
|
|
d.checkMatchEmpty(t, "example.org")
|
|
|
|
d.checkMatchEmpty(t, "testexample.org")
|
|
|
|
d.checkMatchEmpty(t, "example.co.uk")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestAddRuleFail(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.checkAddRuleFail(t, "lkfaojewhoawehfwacoefawr$@#$@3413841384")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestLotsOfRulesMemoryUsage(t *testing.T) {
|
|
|
|
var start, afterLoad, end runtime.MemStats
|
|
|
|
runtime.GC()
|
|
|
|
runtime.ReadMemStats(&start)
|
|
|
|
fmt.Printf("Memory usage before loading rules - %d kB alloc, %d kB sys\n", start.Alloc/1024, start.Sys/1024)
|
|
|
|
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
t.Error(err)
|
|
|
|
}
|
|
|
|
runtime.GC()
|
|
|
|
runtime.ReadMemStats(&afterLoad)
|
|
|
|
fmt.Printf("Memory usage after loading rules - %d kB alloc, %d kB sys\n", afterLoad.Alloc/1024, afterLoad.Sys/1024)
|
|
|
|
|
|
|
|
tests := []struct {
|
|
|
|
host string
|
|
|
|
match bool
|
|
|
|
}{
|
|
|
|
{"asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.thisistesthost.com", false},
|
|
|
|
{"asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.ad.doubleclick.net", true},
|
|
|
|
}
|
|
|
|
for _, testcase := range tests {
|
|
|
|
ret, err := d.CheckHost(testcase.host)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while matching host %s: %s", testcase.host, err)
|
|
|
|
}
|
2018-09-14 16:50:56 +03:00
|
|
|
if !ret.IsFiltered && ret.IsFiltered != testcase.match {
|
2018-08-30 17:25:33 +03:00
|
|
|
t.Errorf("Expected hostname %s to not match", testcase.host)
|
|
|
|
}
|
2018-09-14 16:50:56 +03:00
|
|
|
if ret.IsFiltered && ret.IsFiltered != testcase.match {
|
2018-08-30 17:25:33 +03:00
|
|
|
t.Errorf("Expected hostname %s to match", testcase.host)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
runtime.GC()
|
|
|
|
runtime.ReadMemStats(&end)
|
|
|
|
fmt.Printf("Memory usage after matching - %d kB alloc, %d kB sys\n", afterLoad.Alloc/1024, afterLoad.Sys/1024)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSafeBrowsing(t *testing.T) {
|
|
|
|
testCases := []string{
|
|
|
|
"",
|
|
|
|
"sb.adtidy.org",
|
|
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
|
|
t.Run(fmt.Sprintf("%s in %s", tc, _Func()), func(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeBrowsing()
|
|
|
|
stats.Safebrowsing.Requests = 0
|
|
|
|
d.checkMatch(t, "wmconvirus.narod.ru")
|
|
|
|
d.checkMatch(t, "wmconvirus.narod.ru")
|
|
|
|
if stats.Safebrowsing.Requests != 1 {
|
|
|
|
t.Errorf("Safebrowsing lookup positive cache is not working: %v", stats.Safebrowsing.Requests)
|
|
|
|
}
|
|
|
|
d.checkMatch(t, "WMconvirus.narod.ru")
|
|
|
|
if stats.Safebrowsing.Requests != 1 {
|
|
|
|
t.Errorf("Safebrowsing lookup positive cache is not working: %v", stats.Safebrowsing.Requests)
|
|
|
|
}
|
|
|
|
d.checkMatch(t, "wmconvirus.narod.ru.")
|
|
|
|
d.checkMatch(t, "test.wmconvirus.narod.ru")
|
|
|
|
d.checkMatch(t, "test.wmconvirus.narod.ru.")
|
|
|
|
d.checkMatchEmpty(t, "yandex.ru")
|
|
|
|
d.checkMatchEmpty(t, "pornhub.com")
|
|
|
|
l := stats.Safebrowsing.Requests
|
|
|
|
d.checkMatchEmpty(t, "pornhub.com")
|
|
|
|
if stats.Safebrowsing.Requests != l {
|
|
|
|
t.Errorf("Safebrowsing lookup negative cache is not working: %v", stats.Safebrowsing.Requests)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParallelSB(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeBrowsing()
|
|
|
|
t.Run("group", func(t *testing.T) {
|
|
|
|
for i := 0; i < 100; i++ {
|
|
|
|
t.Run(fmt.Sprintf("aaa%d", i), func(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
d.checkMatch(t, "wmconvirus.narod.ru")
|
|
|
|
d.checkMatch(t, "wmconvirus.narod.ru.")
|
|
|
|
d.checkMatch(t, "test.wmconvirus.narod.ru")
|
|
|
|
d.checkMatch(t, "test.wmconvirus.narod.ru.")
|
|
|
|
d.checkMatchEmpty(t, "yandex.ru")
|
|
|
|
d.checkMatchEmpty(t, "pornhub.com")
|
|
|
|
})
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
// the only way to verify that custom server option is working is to point it at a server that does serve safebrowsing
|
|
|
|
func TestSafeBrowsingCustomServerFail(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
|
|
// w.Write("Hello, client")
|
|
|
|
fmt.Fprintln(w, "Hello, client")
|
|
|
|
}))
|
|
|
|
defer ts.Close()
|
|
|
|
address := ts.Listener.Addr().String()
|
|
|
|
|
|
|
|
d.EnableSafeBrowsing()
|
|
|
|
d.SetHTTPTimeout(time.Second * 5)
|
|
|
|
d.SetSafeBrowsingServer(address) // this will ensure that test fails
|
|
|
|
d.checkMatchEmpty(t, "wmconvirus.narod.ru")
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestParentalControl(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableParental(3)
|
|
|
|
d.checkMatch(t, "pornhub.com")
|
|
|
|
d.checkMatch(t, "pornhub.com")
|
|
|
|
if stats.Parental.Requests != 1 {
|
|
|
|
t.Errorf("Parental lookup positive cache is not working")
|
|
|
|
}
|
|
|
|
d.checkMatch(t, "PORNhub.com")
|
|
|
|
if stats.Parental.Requests != 1 {
|
|
|
|
t.Errorf("Parental lookup positive cache is not working")
|
|
|
|
}
|
|
|
|
d.checkMatch(t, "www.pornhub.com")
|
|
|
|
d.checkMatch(t, "pornhub.com.")
|
|
|
|
d.checkMatch(t, "www.pornhub.com.")
|
|
|
|
d.checkMatchEmpty(t, "www.yandex.ru")
|
|
|
|
d.checkMatchEmpty(t, "yandex.ru")
|
|
|
|
l := stats.Parental.Requests
|
|
|
|
d.checkMatchEmpty(t, "yandex.ru")
|
|
|
|
if stats.Parental.Requests != l {
|
|
|
|
t.Errorf("Parental lookup negative cache is not working")
|
|
|
|
}
|
2018-09-17 01:41:39 +03:00
|
|
|
|
|
|
|
d.checkMatchEmpty(t, "api.jquery.com")
|
2018-08-30 17:25:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestSafeSearch(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
_, ok := d.SafeSearchDomain("www.google.com")
|
|
|
|
if ok {
|
|
|
|
t.Errorf("Expected safesearch to error when disabled")
|
|
|
|
}
|
|
|
|
d.EnableSafeSearch()
|
|
|
|
val, ok := d.SafeSearchDomain("www.google.com")
|
|
|
|
if !ok {
|
|
|
|
t.Errorf("Expected safesearch to find result for www.google.com")
|
|
|
|
}
|
|
|
|
if val != "forcesafesearch.google.com" {
|
|
|
|
t.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// parametrized testing
|
|
|
|
//
|
|
|
|
var blockingRules = []string{"||example.org^"}
|
|
|
|
var whitelistRules = []string{"||example.org^", "@@||test.example.org"}
|
|
|
|
var importantRules = []string{"@@||example.org^", "||test.example.org^$important"}
|
|
|
|
var regexRules = []string{"/example\\.org/", "@@||test.example.org^"}
|
|
|
|
var maskRules = []string{"test*.example.org^", "exam*.com"}
|
|
|
|
|
|
|
|
var tests = []struct {
|
2018-09-06 02:06:40 +03:00
|
|
|
testname string
|
|
|
|
rules []string
|
|
|
|
hostname string
|
|
|
|
isFiltered bool
|
|
|
|
reason Reason
|
2018-08-30 17:25:33 +03:00
|
|
|
}{
|
2018-09-06 02:06:40 +03:00
|
|
|
{"sanity", []string{"||doubleclick.net^"}, "www.doubleclick.net", true, FilteredBlackList},
|
|
|
|
{"sanity", []string{"||doubleclick.net^"}, "nodoubleclick.net", false, NotFilteredNotFound},
|
|
|
|
{"sanity", []string{"||doubleclick.net^"}, "doubleclick.net.ru", false, NotFilteredNotFound},
|
|
|
|
{"sanity", []string{"||doubleclick.net^"}, "wmconvirus.narod.ru", false, NotFilteredNotFound},
|
|
|
|
{"blocking", blockingRules, "example.org", true, FilteredBlackList},
|
|
|
|
{"blocking", blockingRules, "test.example.org", true, FilteredBlackList},
|
|
|
|
{"blocking", blockingRules, "test.test.example.org", true, FilteredBlackList},
|
|
|
|
{"blocking", blockingRules, "testexample.org", false, NotFilteredNotFound},
|
|
|
|
{"blocking", blockingRules, "onemoreexample.org", false, NotFilteredNotFound},
|
|
|
|
{"whitelist", whitelistRules, "example.org", true, FilteredBlackList},
|
|
|
|
{"whitelist", whitelistRules, "test.example.org", false, NotFilteredWhiteList},
|
|
|
|
{"whitelist", whitelistRules, "test.test.example.org", false, NotFilteredWhiteList},
|
|
|
|
{"whitelist", whitelistRules, "testexample.org", false, NotFilteredNotFound},
|
|
|
|
{"whitelist", whitelistRules, "onemoreexample.org", false, NotFilteredNotFound},
|
|
|
|
{"important", importantRules, "example.org", false, NotFilteredWhiteList},
|
|
|
|
{"important", importantRules, "test.example.org", true, FilteredBlackList},
|
|
|
|
{"important", importantRules, "test.test.example.org", true, FilteredBlackList},
|
|
|
|
{"important", importantRules, "testexample.org", false, NotFilteredNotFound},
|
|
|
|
{"important", importantRules, "onemoreexample.org", false, NotFilteredNotFound},
|
|
|
|
{"regex", regexRules, "example.org", true, FilteredBlackList},
|
|
|
|
{"regex", regexRules, "test.example.org", false, NotFilteredWhiteList},
|
|
|
|
{"regex", regexRules, "test.test.example.org", false, NotFilteredWhiteList},
|
|
|
|
{"regex", regexRules, "testexample.org", true, FilteredBlackList},
|
|
|
|
{"regex", regexRules, "onemoreexample.org", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "test.example.org", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "test2.example.org", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "example.com", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "exampleeee.com", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "onemoreexamsite.com", true, FilteredBlackList},
|
|
|
|
{"mask", maskRules, "example.org", false, NotFilteredNotFound},
|
|
|
|
{"mask", maskRules, "testexample.org", false, NotFilteredNotFound},
|
|
|
|
{"mask", maskRules, "example.co.uk", false, NotFilteredNotFound},
|
2018-08-30 17:25:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestMatching(t *testing.T) {
|
|
|
|
for _, test := range tests {
|
|
|
|
t.Run(fmt.Sprintf("%s-%s", test.testname, test.hostname), func(t *testing.T) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
for _, rule := range test.rules {
|
|
|
|
err := d.AddRule(rule, 0)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ret, err := d.CheckHost(test.hostname)
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("Error while matching host %s: %s", test.hostname, err)
|
|
|
|
}
|
2018-09-06 02:06:40 +03:00
|
|
|
if ret.IsFiltered != test.isFiltered {
|
|
|
|
t.Errorf("Hostname %s has wrong result (%v must be %v)", test.hostname, ret.IsFiltered, test.isFiltered)
|
|
|
|
}
|
|
|
|
if ret.Reason != test.reason {
|
|
|
|
t.Errorf("Hostname %s has wrong reason (%v must be %v)", test.hostname, ret.Reason.String(), test.reason.String())
|
2018-08-30 17:25:33 +03:00
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// benchmarks
|
|
|
|
//
|
|
|
|
func BenchmarkAddRule(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
rule := "||doubleclick.net^"
|
|
|
|
err := d.AddRule(rule, 0)
|
|
|
|
switch err {
|
|
|
|
case nil:
|
|
|
|
case ErrInvalidSyntax: // ignore invalid syntax
|
|
|
|
default:
|
|
|
|
b.Fatalf("Error while adding rule %s: %s", rule, err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkAddRuleParallel(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
rule := "||doubleclick.net^"
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
var err error
|
|
|
|
for pb.Next() {
|
|
|
|
err = d.AddRule(rule, 0)
|
|
|
|
}
|
|
|
|
switch err {
|
|
|
|
case nil:
|
|
|
|
case ErrInvalidSyntax: // ignore invalid syntax
|
|
|
|
default:
|
|
|
|
b.Fatalf("Error while adding rule %s: %s", rule, err)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkLotsOfRulesNoMatch(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
hostname := "asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.thisistesthost.com"
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to not match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkLotsOfRulesNoMatchParallel(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
hostname := "asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.thisistesthost.com"
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to not match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkLotsOfRulesMatch(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
const hostname = "asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.ad.doubleclick.net"
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if !ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkLotsOfRulesMatchParallel(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
err := loadTestRules(d)
|
|
|
|
if err != nil {
|
|
|
|
b.Fatal(err)
|
|
|
|
}
|
|
|
|
b.ResetTimer()
|
|
|
|
const hostname = "asdasdasd_adsajdasda_asdasdjashdkasdasdasdasd_adsajdasda_asdasdjashdkasd.ad.doubleclick.net"
|
|
|
|
b.ResetTimer()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if !ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSafeBrowsing(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeBrowsing()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
hostname := "wmconvirus.narod.ru"
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if !ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSafeBrowsingParallel(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeBrowsing()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
hostname := "wmconvirus.narod.ru"
|
|
|
|
ret, err := d.CheckHost(hostname)
|
|
|
|
if err != nil {
|
|
|
|
b.Errorf("Error while matching host %s: %s", hostname, err)
|
|
|
|
}
|
|
|
|
if !ret.IsFiltered {
|
|
|
|
b.Errorf("Expected hostname %s to match", hostname)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSafeSearch(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeSearch()
|
|
|
|
for n := 0; n < b.N; n++ {
|
|
|
|
val, ok := d.SafeSearchDomain("www.google.com")
|
|
|
|
if !ok {
|
|
|
|
b.Errorf("Expected safesearch to find result for www.google.com")
|
|
|
|
}
|
|
|
|
if val != "forcesafesearch.google.com" {
|
|
|
|
b.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func BenchmarkSafeSearchParallel(b *testing.B) {
|
|
|
|
d := NewForTest()
|
|
|
|
defer d.Destroy()
|
|
|
|
d.EnableSafeSearch()
|
|
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
|
|
for pb.Next() {
|
|
|
|
val, ok := d.SafeSearchDomain("www.google.com")
|
|
|
|
if !ok {
|
|
|
|
b.Errorf("Expected safesearch to find result for www.google.com")
|
|
|
|
}
|
|
|
|
if val != "forcesafesearch.google.com" {
|
|
|
|
b.Errorf("Expected safesearch for google.com to be forcesafesearch.google.com")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestMain(m *testing.M) {
|
|
|
|
goleak.VerifyTestMain(m)
|
|
|
|
}
|
2018-09-14 16:50:56 +03:00
|
|
|
|
|
|
|
//
|
|
|
|
// helper functions for debugging and testing
|
|
|
|
//
|
|
|
|
func purgeCaches() {
|
|
|
|
safebrowsingCache.Purge()
|
|
|
|
parentalCache.Purge()
|
|
|
|
}
|
|
|
|
|
|
|
|
func _Func() string {
|
|
|
|
pc := make([]uintptr, 10) // at least 1 entry needed
|
|
|
|
runtime.Callers(2, pc)
|
|
|
|
f := runtime.FuncForPC(pc[0])
|
|
|
|
return path.Base(f.Name())
|
|
|
|
}
|
|
|
|
|
|
|
|
func trace(format string, args ...interface{}) {
|
|
|
|
pc := make([]uintptr, 10) // at least 1 entry needed
|
|
|
|
runtime.Callers(2, pc)
|
|
|
|
f := runtime.FuncForPC(pc[0])
|
|
|
|
var buf strings.Builder
|
|
|
|
buf.WriteString(fmt.Sprintf("%s(): ", path.Base(f.Name())))
|
|
|
|
text := fmt.Sprintf(format, args...)
|
|
|
|
buf.WriteString(text)
|
|
|
|
if len(text) == 0 || text[len(text)-1] != '\n' {
|
|
|
|
buf.WriteRune('\n')
|
|
|
|
}
|
|
|
|
fmt.Print(buf.String())
|
|
|
|
}
|