mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-12-15 11:22:49 +03:00
34aa81ca99
Squashed commit of the following: commit e496653b10de52676826ed8e0c461e91405603a8 Merge: db2cd04e960a978c9a
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Feb 1 18:23:50 2024 +0300 Merge branch 'master' into AG-28327-upstream-config-parser commit db2cd04e981dd24998d87f4935ff6590ea7854cd Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Jan 31 16:21:53 2024 +0300 all: upd proxy commit e8878179b6d094321d56fb2b75c16c1ba8cf637d Merge: ccbbae6d6aa872dfe9
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Jan 31 16:17:34 2024 +0300 Merge branch 'master' into AG-28327-upstream-config-parser commit ccbbae6d615e110d7d2d4c2a6b35954311153bcf Merge: d947d900e8936c95ec
Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Jan 29 18:31:17 2024 +0300 Merge branch 'master' into AG-28327-upstream-config-parser commit d947d900e1f759159bc9068589ffe852483cfdd0 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Jan 29 18:26:01 2024 +0300 dnsforward: imp docs commit cf9678c098951e2a4bebae7a3a5808d7de4c14c6 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Jan 25 14:18:04 2024 +0300 dnsforward: imp code commit 22792a9311cb93b2bb3b804293f87f091b9b81e2 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Jan 24 13:59:28 2024 +0300 dnsforward: imp code commit 57ddaaaaaf1009c65f0d9d6b2b1671211f194c85 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Jan 22 20:19:44 2024 +0300 all: add tests commit d6732d13adae4ee46410252a33d092e67da3c34a Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Jan 22 18:44:57 2024 +0300 all: imp errors commit e14456571ce2ef43fb217f45445729ce6299daf6 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Jan 18 19:05:31 2024 +0300 dnsforward: imp code commit a5c106eae902fbc0a169ef9e4d7bf968f1e40bec Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Mon Jan 15 18:36:30 2024 +0300 dnsforward: imp logs commit 333b8561aa21d778007f808fb8e931ef3e95d721 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Thu Dec 21 15:06:42 2023 +0300 all: imp tests commit 5b19d6b039755577e03ffcc03952724a36f21aa4 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Fri Dec 15 14:21:58 2023 +0300 all: imp code commit 15fbd229de336425bde107a4f32175b8af41d876 Author: Stanislav Chzhen <s.chzhen@adguard.com> Date: Wed Dec 13 14:49:40 2023 +0300 all: upstream config parser
217 lines
5.8 KiB
Go
217 lines
5.8 KiB
Go
package dnsforward
|
|
|
|
import (
|
|
"net"
|
|
"net/url"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/AdguardTeam/dnsproxy/upstream"
|
|
"github.com/AdguardTeam/golibs/testutil"
|
|
"github.com/miekg/dns"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestUpstreamConfigValidator(t *testing.T) {
|
|
goodHandler := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
|
|
err := w.WriteMsg(new(dns.Msg).SetReply(m))
|
|
require.NoError(testutil.PanicT{}, err)
|
|
})
|
|
badHandler := dns.HandlerFunc(func(w dns.ResponseWriter, _ *dns.Msg) {
|
|
err := w.WriteMsg(new(dns.Msg))
|
|
require.NoError(testutil.PanicT{}, err)
|
|
})
|
|
|
|
goodUps := (&url.URL{
|
|
Scheme: "tcp",
|
|
Host: newLocalUpstreamListener(t, 0, goodHandler).String(),
|
|
}).String()
|
|
badUps := (&url.URL{
|
|
Scheme: "tcp",
|
|
Host: newLocalUpstreamListener(t, 0, badHandler).String(),
|
|
}).String()
|
|
|
|
goodAndBadUps := strings.Join([]string{goodUps, badUps}, " ")
|
|
|
|
// upsTimeout restricts the checking process to prevent the test from
|
|
// hanging.
|
|
const upsTimeout = 100 * time.Millisecond
|
|
|
|
testCases := []struct {
|
|
want map[string]string
|
|
name string
|
|
general []string
|
|
fallback []string
|
|
private []string
|
|
}{{
|
|
name: "success",
|
|
general: []string{goodUps},
|
|
want: map[string]string{
|
|
goodUps: "OK",
|
|
},
|
|
}, {
|
|
name: "broken",
|
|
general: []string{badUps},
|
|
want: map[string]string{
|
|
badUps: `couldn't communicate with upstream: exchanging with ` +
|
|
badUps + ` over tcp: dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "both",
|
|
general: []string{goodUps, badUps, goodUps},
|
|
want: map[string]string{
|
|
goodUps: "OK",
|
|
badUps: `couldn't communicate with upstream: exchanging with ` +
|
|
badUps + ` over tcp: dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "domain_specific_error",
|
|
general: []string{"[/domain.example/]" + badUps},
|
|
want: map[string]string{
|
|
badUps: `WARNING: couldn't communicate ` +
|
|
`with upstream: exchanging with ` + badUps + ` over tcp: ` +
|
|
`dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "fallback_success",
|
|
fallback: []string{goodUps},
|
|
want: map[string]string{
|
|
goodUps: "OK",
|
|
},
|
|
}, {
|
|
name: "fallback_broken",
|
|
fallback: []string{badUps},
|
|
want: map[string]string{
|
|
badUps: `couldn't communicate with upstream: exchanging with ` +
|
|
badUps + ` over tcp: dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "multiple_domain_specific_upstreams",
|
|
general: []string{"[/domain.example/]" + goodAndBadUps},
|
|
want: map[string]string{
|
|
goodUps: "OK",
|
|
badUps: `WARNING: couldn't communicate ` +
|
|
`with upstream: exchanging with ` + badUps + ` over tcp: ` +
|
|
`dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "bad_specification",
|
|
general: []string{"[/domain.example/]/]1.2.3.4"},
|
|
want: map[string]string{
|
|
"[/domain.example/]/]1.2.3.4": generalTextLabel + " 1: parsing error",
|
|
},
|
|
}, {
|
|
name: "all_different",
|
|
general: []string{"[/domain.example/]" + goodAndBadUps},
|
|
fallback: []string{"[/domain.example/]" + goodAndBadUps},
|
|
private: []string{"[/domain.example/]" + goodAndBadUps},
|
|
want: map[string]string{
|
|
goodUps: "OK",
|
|
badUps: `WARNING: couldn't communicate ` +
|
|
`with upstream: exchanging with ` + badUps + ` over tcp: ` +
|
|
`dns: id mismatch`,
|
|
},
|
|
}, {
|
|
name: "bad_specific_domains",
|
|
general: []string{"[/example/]/]" + goodUps},
|
|
fallback: []string{"[/example/" + goodUps},
|
|
private: []string{"[/example//bad.123/]" + goodUps},
|
|
want: map[string]string{
|
|
"[/example/]/]" + goodUps: generalTextLabel + " 1: parsing error",
|
|
"[/example/" + goodUps: fallbackTextLabel + " 1: parsing error",
|
|
"[/example//bad.123/]" + goodUps: privateTextLabel + " 1: parsing error",
|
|
},
|
|
}, {
|
|
name: "bad_proto",
|
|
general: []string{
|
|
"bad://1.2.3.4",
|
|
},
|
|
want: map[string]string{
|
|
"bad://1.2.3.4": generalTextLabel + " 1: parsing error",
|
|
},
|
|
}, {
|
|
name: "truncated_line",
|
|
general: []string{
|
|
"This is a very long line. It will cause a parsing error and will be truncated here.",
|
|
},
|
|
want: map[string]string{
|
|
"This is a very long line. It will cause a parsing error and will be truncated …": "upstream_dns 1: parsing error",
|
|
},
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
cv := newUpstreamConfigValidator(tc.general, tc.fallback, tc.private, &upstream.Options{
|
|
Timeout: upsTimeout,
|
|
Bootstrap: net.DefaultResolver,
|
|
})
|
|
cv.check()
|
|
cv.close()
|
|
|
|
assert.Equal(t, tc.want, cv.status())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpstreamConfigValidator_Check_once(t *testing.T) {
|
|
type signal = struct{}
|
|
|
|
reqCh := make(chan signal)
|
|
hdlr := dns.HandlerFunc(func(w dns.ResponseWriter, m *dns.Msg) {
|
|
pt := testutil.PanicT{}
|
|
|
|
err := w.WriteMsg(new(dns.Msg).SetReply(m))
|
|
require.NoError(pt, err)
|
|
|
|
testutil.RequireSend(pt, reqCh, signal{}, testTimeout)
|
|
})
|
|
|
|
addr := (&url.URL{
|
|
Scheme: "tcp",
|
|
Host: newLocalUpstreamListener(t, 0, hdlr).String(),
|
|
}).String()
|
|
twoAddrs := strings.Join([]string{addr, addr}, " ")
|
|
|
|
wantStatus := map[string]string{
|
|
addr: "OK",
|
|
}
|
|
|
|
testCases := []struct {
|
|
name string
|
|
ups []string
|
|
}{{
|
|
name: "common",
|
|
ups: []string{addr, addr, addr},
|
|
}, {
|
|
name: "domain-specific",
|
|
ups: []string{"[/one.example/]" + addr, "[/two.example/]" + twoAddrs},
|
|
}, {
|
|
name: "both",
|
|
ups: []string{addr, "[/one.example/]" + addr, addr, "[/two.example/]" + twoAddrs},
|
|
}}
|
|
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
cv := newUpstreamConfigValidator(tc.ups, nil, nil, &upstream.Options{
|
|
Timeout: testTimeout,
|
|
})
|
|
|
|
go func() {
|
|
cv.check()
|
|
testutil.RequireSend(testutil.PanicT{}, reqCh, signal{}, testTimeout)
|
|
}()
|
|
|
|
// Wait for the only request to be sent.
|
|
testutil.RequireReceive(t, reqCh, testTimeout)
|
|
|
|
// Wait for the check to finish.
|
|
testutil.RequireReceive(t, reqCh, testTimeout)
|
|
|
|
cv.close()
|
|
require.Equal(t, wantStatus, cv.status())
|
|
})
|
|
}
|
|
}
|