forked from AdguardTeam/AdGuardHome
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
7077597
commit 120ba4b
Showing
3 changed files
with
178 additions
and
110 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
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": `splitting upstream line ` + | ||
`"[/domain.example/]/]1.2.3.4": duplicated separator`, | ||
}, | ||
}, { | ||
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: `splitting upstream line ` + | ||
`"[/example/]/]` + goodUps + `": duplicated separator`, | ||
`[/example/` + goodUps: `splitting upstream line ` + | ||
`"[/example/` + goodUps + `": missing separator`, | ||
`[/example//bad.123/]` + goodUps: `splitting upstream line ` + | ||
`"[/example//bad.123/]` + goodUps + `": domain at index 2: ` + | ||
`bad domain name "bad.123": ` + | ||
`bad top-level domain name label "123": all octets are numeric`, | ||
}, | ||
}, { | ||
name: "non-specific_default", | ||
general: []string{ | ||
"#", | ||
"[/example/]#", | ||
}, | ||
want: map[string]string{ | ||
"#": "not a domain-specific upstream", | ||
}, | ||
}, { | ||
name: "bad_proto", | ||
general: []string{ | ||
"bad://1.2.3.4", | ||
}, | ||
want: map[string]string{ | ||
"bad://1.2.3.4": `bad protocol "bad"`, | ||
}, | ||
}} | ||
|
||
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()) | ||
}) | ||
} | ||
} |