diff --git a/HACKING.md b/HACKING.md index 36a67ab8..8df23efd 100644 --- a/HACKING.md +++ b/HACKING.md @@ -34,6 +34,10 @@ find out about how we **want** our code to look like. * Document everything, including unexported top-level identifiers, to build a habit of writing documentation. + * Don't put variable names into any kind of quotes. + + * Don't use naked `return`s. + * Don't use underscores in file and package names, unless they're build tags or for tests. This is to prevent accidental build errors with weird tags. diff --git a/go.mod b/go.mod index 398c6961..467dfee6 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.14 require ( github.com/AdguardTeam/dnsproxy v0.33.2 - github.com/AdguardTeam/golibs v0.4.2 + github.com/AdguardTeam/golibs v0.4.3 github.com/AdguardTeam/urlfilter v0.12.3 github.com/NYTimes/gziphandler v1.1.1 github.com/beefsack/go-rate v0.0.0-20200827232406-6cde80facd47 // indirect diff --git a/go.sum b/go.sum index bfafb2f9..65a1fd0c 100644 --- a/go.sum +++ b/go.sum @@ -7,13 +7,13 @@ dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBr dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4= dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= -github.com/AdguardTeam/dnsproxy v0.33.1 h1:rEAS1fBEQ3JslzsfkcyMRV96OeBWFnKzXvksduI0ous= -github.com/AdguardTeam/dnsproxy v0.33.1/go.mod h1:kLi6lMpErnZThy5haiRSis4q0KTB8uPWO4JQsU1EDJA= github.com/AdguardTeam/dnsproxy v0.33.2 h1:k5aMcsw3TA/G2DR8EjIkwutDPuuRkKh8xij4cFWC6Fk= github.com/AdguardTeam/dnsproxy v0.33.2/go.mod h1:kLi6lMpErnZThy5haiRSis4q0KTB8uPWO4JQsU1EDJA= github.com/AdguardTeam/golibs v0.4.0/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/golibs v0.4.2 h1:7M28oTZFoFwNmp8eGPb3ImmYbxGaJLyQXeIFVHjME0o= github.com/AdguardTeam/golibs v0.4.2/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= +github.com/AdguardTeam/golibs v0.4.3 h1:nXTLLLlIyU4BSRF0An5azS0uimSK/YpIMOBAO0/v1RY= +github.com/AdguardTeam/golibs v0.4.3/go.mod h1:skKsDKIBB7kkFflLJBpfGX+G8QFTx0WKUzB6TIgtUj4= github.com/AdguardTeam/gomitmproxy v0.2.0/go.mod h1:Qdv0Mktnzer5zpdpi5rAwixNJzW2FN91LjKJCkVbYGU= github.com/AdguardTeam/urlfilter v0.12.3 h1:FMjQG0eTgrr8xA3z2zaLVcCgGdpzoECPGWwgPjtwPNs= github.com/AdguardTeam/urlfilter v0.12.3/go.mod h1:1fcCQx5TGJANrQN6sHNNM9KPBl7qx7BJml45ko6vru0= @@ -325,8 +325,6 @@ golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201016165138-7b1cca2348c0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102 h1:42cLlJJdEh+ySyeUUbEQ5bsTiq8voBeTuweGVkY6Puw= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b h1:uwuIcX0g4Yl1NC5XAz37xsr2lTtcqevgzYNVt49waME= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -370,8 +368,6 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf h1:kt3wY1Lu5MJAnKTfoMR52Cu4gwvna4VTzNOiT8tY73s= -golang.org/x/sys v0.0.0-20201107080550-4d91cf3a1aaf/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201109165425-215b40eba54c h1:+B+zPA6081G5cEb2triOIJpcvSW4AYzmIyWAqMn2JAc= golang.org/x/sys v0.0.0-20201109165425-215b40eba54c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/internal/dnsfilter/dnsfilter_test.go b/internal/dnsfilter/dnsfilter_test.go index 357e24c4..bfe06caa 100644 --- a/internal/dnsfilter/dnsfilter_test.go +++ b/internal/dnsfilter/dnsfilter_test.go @@ -1,11 +1,14 @@ package dnsfilter import ( + "bytes" "fmt" "net" + "strings" "testing" "github.com/AdguardTeam/AdGuardHome/internal/testutil" + "github.com/AdguardTeam/golibs/log" "github.com/AdguardTeam/urlfilter/rules" "github.com/miekg/dns" "github.com/stretchr/testify/assert" @@ -142,10 +145,17 @@ func TestEtcHostsMatching(t *testing.T) { // SAFE BROWSING func TestSafeBrowsing(t *testing.T) { + logOutput := &bytes.Buffer{} + testutil.ReplaceLogWriter(t, logOutput) + testutil.ReplaceLogLevel(t, log.DEBUG) + d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil) defer d.Close() gctx.stats.Safebrowsing.Requests = 0 d.checkMatch(t, "wmconvirus.narod.ru") + + assert.True(t, strings.Contains(logOutput.String(), "SafeBrowsing lookup for wmconvirus.narod.ru")) + d.checkMatch(t, "test.wmconvirus.narod.ru") d.checkMatchEmpty(t, "yandex.ru") d.checkMatchEmpty(t, "pornhub.com") @@ -328,9 +338,14 @@ func TestSafeSearchCacheGoogle(t *testing.T) { // PARENTAL func TestParentalControl(t *testing.T) { + logOutput := &bytes.Buffer{} + testutil.ReplaceLogWriter(t, logOutput) + testutil.ReplaceLogLevel(t, log.DEBUG) + d := NewForTest(&Config{ParentalEnabled: true}, nil) defer d.Close() d.checkMatch(t, "pornhub.com") + assert.True(t, strings.Contains(logOutput.String(), "Parental lookup for pornhub.com")) d.checkMatch(t, "www.pornhub.com") d.checkMatchEmpty(t, "www.yandex.ru") d.checkMatchEmpty(t, "yandex.ru") diff --git a/internal/dnsfilter/sb_pc_test.go b/internal/dnsfilter/sb_pc_test.go index 93746363..71e59446 100644 --- a/internal/dnsfilter/sb_pc_test.go +++ b/internal/dnsfilter/sb_pc_test.go @@ -5,7 +5,9 @@ import ( "strings" "testing" + "github.com/AdguardTeam/AdGuardHome/internal/agherr" "github.com/AdguardTeam/golibs/cache" + "github.com/miekg/dns" "github.com/stretchr/testify/assert" ) @@ -88,4 +90,47 @@ func TestSafeBrowsingCache(t *testing.T) { hash = sha256.Sum256([]byte("nonexisting.com")) _, ok = c.hashToHost[hash] assert.True(t, ok) + + c = &sbCtx{ + svc: "SafeBrowsing", + cacheTime: 100, + } + conf = cache.Config{} + c.cache = cache.New(conf) + + hash = sha256.Sum256([]byte("sub.host.com")) + c.hashToHost = make(map[[32]byte]string) + c.hashToHost[hash] = "sub.host.com" + + c.cache.Set(hash[0:2], make([]byte, 32)) + assert.Equal(t, 0, c.getCached()) +} + +// testErrUpstream implements upstream.Upstream interface for replacing real +// upstream in tests. +type testErrUpstream struct{} + +// Exchange always returns nil Msg and non-nil error. +func (teu *testErrUpstream) Exchange(*dns.Msg) (*dns.Msg, error) { + return nil, agherr.Error("bad") +} + +func (teu *testErrUpstream) Address() string { + return "" +} + +func TestSBPC_checkErrorUpstream(t *testing.T) { + d := NewForTest(&Config{SafeBrowsingEnabled: true}, nil) + defer d.Close() + + ups := &testErrUpstream{} + + d.safeBrowsingUpstream = ups + d.parentalUpstream = ups + + _, err := d.checkSafeBrowsing("smthng.com") + assert.NotNil(t, err) + + _, err = d.checkParental("smthng.com") + assert.NotNil(t, err) } diff --git a/internal/dnsforward/dnsforward_http_test.go b/internal/dnsforward/dnsforward_http_test.go new file mode 100644 index 00000000..19c4a0de --- /dev/null +++ b/internal/dnsforward/dnsforward_http_test.go @@ -0,0 +1,170 @@ +package dnsforward + +import ( + "io/ioutil" + "net/http" + "net/http/httptest" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestDNSForwardHTTTP_handleGetConfig(t *testing.T) { + s := createTestServer(t) + err := s.Start() + assert.Nil(t, err) + defer assert.Nil(t, s.Stop()) + + defaultConf := s.conf + + w := httptest.NewRecorder() + + testCases := []struct { + name string + conf func() ServerConfig + want string + }{{ + name: "all_right", + conf: func() ServerConfig { + return defaultConf + }, + want: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "fastest_addr", + conf: func() ServerConfig { + conf := defaultConf + conf.FastestAddr = true + return conf + }, + want: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"fastest_addr\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "parallel", + conf: func() ServerConfig { + conf := defaultConf + conf.AllServers = true + return conf + }, + want: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"parallel\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }} + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + s.conf = tc.conf() + s.handleGetConfig(w, nil) + assert.Equal(t, tc.want, w.Body.String()) + + assert.Equal(t, "application/json", w.Header().Get("Content-Type")) + }) + w.Body.Reset() + } +} + +func TestDNSForwardHTTTP_handleSetConfig(t *testing.T) { + s := createTestServer(t) + + defaultConf := s.conf + + err := s.Start() + assert.Nil(t, err) + defer func() { + assert.Nil(t, s.Stop()) + }() + + w := httptest.NewRecorder() + + const defaultConfJSON = "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}" + testCases := []struct { + name string + req string + wantSet string + wantGet string + }{{ + name: "upstream_dns", + req: "{\"upstream_dns\":[\"8.8.8.8:77\",\"8.8.4.4:77\"]}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:77\",\"8.8.4.4:77\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "bootstraps", + req: "{\"bootstrap_dns\":[\"9.9.9.10\"]}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "blocking_mode_good", + req: "{\"blocking_mode\":\"refused\"}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"refused\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "blocking_mode_bad", + req: "{\"blocking_mode\":\"custom_ip\"}", + wantSet: "blocking_mode: incorrect value\n", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "ratelimit", + req: "{\"ratelimit\":6}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":6,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "edns_cs_enabled", + req: "{\"edns_cs_enabled\":true}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":true,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "dnssec_enabled", + req: "{\"dnssec_enabled\":true}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":true,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "cache_size", + req: "{\"cache_size\":1024}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"\",\"cache_size\":1024,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "upstream_mode_parallel", + req: "{\"upstream_mode\":\"parallel\"}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"parallel\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "upstream_mode_fastest_addr", + req: "{\"upstream_mode\":\"fastest_addr\"}", + wantSet: "", + wantGet: "{\"upstream_dns\":[\"8.8.8.8:53\",\"8.8.4.4:53\"],\"upstream_dns_file\":\"\",\"bootstrap_dns\":[\"9.9.9.10\",\"149.112.112.10\",\"2620:fe::10\",\"2620:fe::fe:10\"],\"protection_enabled\":true,\"ratelimit\":0,\"blocking_mode\":\"\",\"blocking_ipv4\":\"\",\"blocking_ipv6\":\"\",\"edns_cs_enabled\":false,\"dnssec_enabled\":false,\"disable_ipv6\":false,\"upstream_mode\":\"fastest_addr\",\"cache_size\":0,\"cache_ttl_min\":0,\"cache_ttl_max\":0}", + }, { + name: "upstream_dns_bad", + req: "{\"upstream_dns\":[\"\"]}", + wantSet: "wrong upstreams specification: missing port in address\n", + wantGet: defaultConfJSON, + }, { + name: "bootstraps_bad", + req: "{\"bootstrap_dns\":[\"a\"]}", + wantSet: "a can not be used as bootstrap dns cause: invalid bootstrap server address: Resolver a is not eligible to be a bootstrap DNS server\n", + wantGet: defaultConfJSON, + }, { + name: "cache_bad_ttl", + req: "{\"cache_ttl_min\":1024,\"cache_ttl_max\":512}", + wantSet: "cache_ttl_min must be less or equal than cache_ttl_max\n", + wantGet: defaultConfJSON, + }, { + name: "upstream_mode_bad", + req: "{\"upstream_mode\":\"somethingelse\"}", + wantSet: "upstream_mode: incorrect value\n", + wantGet: defaultConfJSON, + }} + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + rBody := ioutil.NopCloser(strings.NewReader(tc.req)) + r, err := http.NewRequest(http.MethodPost, "http://example.com", rBody) + assert.Nil(t, err) + + s.handleSetConfig(w, r) + assert.Equal(t, tc.wantSet, w.Body.String()) + w.Body.Reset() + + s.handleGetConfig(w, nil) + assert.Equal(t, tc.wantGet, w.Body.String()) + w.Body.Reset() + }) + s.conf = defaultConf + } +} diff --git a/internal/dnsforward/dnsforward_test.go b/internal/dnsforward/dnsforward_test.go index ab2d1b72..327fbe82 100644 --- a/internal/dnsforward/dnsforward_test.go +++ b/internal/dnsforward/dnsforward_test.go @@ -756,11 +756,14 @@ func createTestServer(t *testing.T) *Server { c.CacheTime = 30 f := dnsfilter.New(&c, filters) + s := NewServer(DNSCreateParams{DNSFilter: f}) s.conf.UDPListenAddr = &net.UDPAddr{Port: 0} s.conf.TCPListenAddr = &net.TCPAddr{Port: 0} s.conf.UpstreamDNS = []string{"8.8.8.8:53", "8.8.4.4:53"} s.conf.FilteringConfig.ProtectionEnabled = true + s.conf.ConfigModified = func() {} + err := s.Prepare(nil) assert.True(t, err == nil) return s diff --git a/internal/querylog/decode_test.go b/internal/querylog/decode_test.go index 2b12313a..35863890 100644 --- a/internal/querylog/decode_test.go +++ b/internal/querylog/decode_test.go @@ -1,11 +1,54 @@ package querylog import ( + "bytes" + "strings" "testing" + "github.com/AdguardTeam/AdGuardHome/internal/testutil" + "github.com/AdguardTeam/golibs/log" "github.com/stretchr/testify/assert" ) +func TestDecode_decodeQueryLog(t *testing.T) { + logOutput := &bytes.Buffer{} + + testutil.ReplaceLogWriter(t, logOutput) + testutil.ReplaceLogLevel(t, log.DEBUG) + + testCases := []struct { + name string + log string + want string + }{{ + name: "back_compatibility_all_right", + log: `{"Question":"ULgBAAABAAAAAAAAC2FkZ3VhcmR0ZWFtBmdpdGh1YgJpbwAAHAAB","Answer":"ULiBgAABAAAAAQAAC2FkZ3VhcmR0ZWFtBmdpdGh1YgJpbwAAHAABwBgABgABAAADQgBLB25zLTE2MjIJYXdzZG5zLTEwAmNvAnVrABFhd3NkbnMtaG9zdG1hc3RlcgZhbWF6b24DY29tAAAAAAEAABwgAAADhAASdQAAAVGA","Result":{},"Time":"2020-11-13T12:41:25.970861+03:00","Elapsed":244066501,"IP":"127.0.0.1","Upstream":"https://1.1.1.1:443/dns-query"}`, + want: "default", + }, { + name: "back_compatibility_bad_msg", + log: `{"Question":"","Answer":"ULiBgAABAAAAAQAAC2FkZ3VhcmR0ZWFtBmdpdGh1YgJpbwAAHAABwBgABgABAAADQgBLB25zLTE2MjIJYXdzZG5zLTEwAmNvAnVrABFhd3NkbnMtaG9zdG1hc3RlcgZhbWF6b24DY29tAAAAAAEAABwgAAADhAASdQAAAVGA","Result":{},"Time":"2020-11-13T12:41:25.970861+03:00","Elapsed":244066501,"IP":"127.0.0.1","Upstream":"https://1.1.1.1:443/dns-query"}`, + want: "decodeLogEntry err: dns: overflow unpacking uint16\n", + }, { + name: "back_compatibility_bad_decoding", + log: `{"Question":"LgBAAABAAAAAAAAC2FkZ3VhcmR0ZWFtBmdpdGh1YgJpbwAAHAAB","Answer":"ULiBgAABAAAAAQAAC2FkZ3VhcmR0ZWFtBmdpdGh1YgJpbwAAHAABwBgABgABAAADQgBLB25zLTE2MjIJYXdzZG5zLTEwAmNvAnVrABFhd3NkbnMtaG9zdG1hc3RlcgZhbWF6b24DY29tAAAAAAEAABwgAAADhAASdQAAAVGA","Result":{},"Time":"2020-11-13T12:41:25.970861+03:00","Elapsed":244066501,"IP":"127.0.0.1","Upstream":"https://1.1.1.1:443/dns-query"}`, + want: "decodeLogEntry err: illegal base64 data at input byte 48\n", + }} + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + _, err := logOutput.Write([]byte("default")) + assert.Nil(t, err) + + l := &logEntry{} + decodeLogEntry(l, tc.log) + + assert.True(t, strings.HasSuffix(logOutput.String(), tc.want), logOutput.String()) + + logOutput.Reset() + }) + } +} + func TestJSON(t *testing.T) { s := ` {"keystr":"val","obj":{"keybool":true,"keyint":123456}} diff --git a/internal/querylog/qlog_test.go b/internal/querylog/qlog_test.go index 35f33b99..4dec5175 100644 --- a/internal/querylog/qlog_test.go +++ b/internal/querylog/qlog_test.go @@ -231,13 +231,20 @@ func addEntry(l *queryLog, host, answerStr, client string) { } answer.A = net.ParseIP(answerStr) a.Answer = append(a.Answer, answer) - res := dnsfilter.Result{} + res := dnsfilter.Result{ + IsFiltered: true, + Rule: "SomeRule", + Reason: dnsfilter.ReasonRewrite, + ServiceName: "SomeService", + FilterID: 1, + } params := AddParams{ - Question: &q, - Answer: &a, - Result: &res, - ClientIP: net.ParseIP(client), - Upstream: "upstream", + Question: &q, + Answer: &a, + OrigAnswer: &a, + Result: &res, + ClientIP: net.ParseIP(client), + Upstream: "upstream", } l.Add(params) } diff --git a/internal/testutil/testutil.go b/internal/testutil/testutil.go index f5106265..69187969 100644 --- a/internal/testutil/testutil.go +++ b/internal/testutil/testutil.go @@ -2,6 +2,7 @@ package testutil import ( + "io" "io/ioutil" "os" "testing" @@ -17,3 +18,30 @@ func DiscardLogOutput(m *testing.M) { os.Exit(m.Run()) } + +// ReplaceLogWriter moves logger output to w and uses Cleanup method of t to +// revert changes. +func ReplaceLogWriter(t *testing.T, w io.Writer) { + stdWriter := log.Writer() + t.Cleanup(func() { + log.SetOutput(stdWriter) + }) + log.SetOutput(w) +} + +// ReplaceLogLevel sets logging level to l and uses Cleanup method of t to +// revert changes. +func ReplaceLogLevel(t *testing.T, l int) { + switch l { + case log.INFO, log.DEBUG, log.ERROR: + // Go on. + default: + t.Fatalf("wrong l value (must be one of %v, %v, %v)", log.INFO, log.DEBUG, log.ERROR) + } + + stdLevel := log.GetLevel() + t.Cleanup(func() { + log.SetLevel(stdLevel) + }) + log.SetLevel(l) +}