mirror of
https://github.com/folbricht/routedns.git
synced 2025-12-31 22:50:08 -06:00
117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
package rdns
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/miekg/dns"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestFailRotate(t *testing.T) {
|
|
// Build 2 resolvers that count the number of invocations
|
|
var ci ClientInfo
|
|
r1 := new(TestResolver)
|
|
r2 := new(TestResolver)
|
|
|
|
g := NewFailRotate("test-rotate", FailRotateOptions{}, r1, r2)
|
|
q := new(dns.Msg)
|
|
q.SetQuestion("test.com.", dns.TypeA)
|
|
|
|
// Send the first couple of queries. The first resolver should be active and be used for both
|
|
_, err := g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 2, r1.HitCount())
|
|
require.Equal(t, 0, r2.HitCount())
|
|
|
|
// Set the 1st to failure
|
|
r1.SetFail(true)
|
|
|
|
// The next one should hit both stores (1st will fail, 2nd succeed)
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 3, r1.HitCount())
|
|
require.Equal(t, 1, r2.HitCount())
|
|
|
|
// Fix the 1st resolver
|
|
r1.SetFail(false)
|
|
|
|
// Any further requests should only go to the 2nd
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 3, r1.HitCount())
|
|
require.Equal(t, 3, r2.HitCount())
|
|
|
|
// Break the 2nd
|
|
r2.SetFail(true)
|
|
|
|
// This request should go to the 2nd and then be retried on the first
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 4, r1.HitCount())
|
|
require.Equal(t, 4, r2.HitCount())
|
|
|
|
// Break both, requests should all fail now after trying both
|
|
r1.SetFail(true)
|
|
_, err = g.Resolve(q, ci)
|
|
require.Error(t, err)
|
|
require.Equal(t, 5, r1.HitCount())
|
|
require.Equal(t, 5, r2.HitCount())
|
|
}
|
|
|
|
func TestFailRotateSERVFAIL(t *testing.T) {
|
|
var ci ClientInfo
|
|
opt := StaticResolverOptions{
|
|
RCode: dns.RcodeServerFailure,
|
|
}
|
|
r1, err := NewStaticResolver("test-static", opt)
|
|
require.NoError(t, err)
|
|
|
|
r2 := new(TestResolver)
|
|
|
|
g := NewFailRotate("test-rotate", FailRotateOptions{ServfailError: true}, r1, r2)
|
|
q := new(dns.Msg)
|
|
q.SetQuestion("test.com.", dns.TypeA)
|
|
|
|
// Send the first query, the first resolver will return SERVFAIL and the request will go to the 2nd
|
|
_, err = g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 1, r2.HitCount())
|
|
}
|
|
|
|
func TestFailRotateDrop(t *testing.T) {
|
|
var ci ClientInfo
|
|
r1 := NewDropResolver("test-drop")
|
|
r2 := new(TestResolver)
|
|
|
|
g := NewFailRotate("test-rotate", FailRotateOptions{}, r1, r2)
|
|
q := new(dns.Msg)
|
|
q.SetQuestion("test.com.", dns.TypeA)
|
|
|
|
// The query should be dropped, so no failover
|
|
_, err := g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, 0, r2.HitCount())
|
|
}
|
|
|
|
// Return SERVFAIL if all available resolvers return that
|
|
func TestFailRotateSERVFAILAll(t *testing.T) {
|
|
var ci ClientInfo
|
|
opt := StaticResolverOptions{
|
|
RCode: dns.RcodeServerFailure,
|
|
}
|
|
r, err := NewStaticResolver("test-static", opt)
|
|
require.NoError(t, err)
|
|
|
|
g := NewFailRotate("test-rotate", FailRotateOptions{}, r, r)
|
|
q := new(dns.Msg)
|
|
q.SetQuestion("test.com.", dns.TypeA)
|
|
|
|
a, err := g.Resolve(q, ci)
|
|
require.NoError(t, err)
|
|
require.Equal(t, dns.RcodeServerFailure, a.Rcode)
|
|
}
|