Improved mocks
This commit is contained in:
1 parent
2b6388359b
commit
267fddc474
2 files changed
+402
-82
No files matched your search
@@ -1,9 +1,15 @@
|
||||
package nameserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/miekg/dns"
|
||||
. "github.com/weaveworks/weave/common"
|
||||
wt "github.com/weaveworks/weave/testing"
|
||||
"net"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -89,3 +95,387 @@ func (mz *mockedZoneWithRecords) ObserveInaddr(inaddr string, observer ZoneRecor
|
||||
notImplWarn()
|
||||
return nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// A mocked mDNS server
|
||||
type mockedMDNSServer struct {
|
||||
zone Zone
|
||||
}
|
||||
|
||||
func newMockedMDNSServer(z Zone) *mockedMDNSServer { return &mockedMDNSServer{zone: z} }
|
||||
func (ms *mockedMDNSServer) Start(_ *net.Interface) error { return nil }
|
||||
func (ms *mockedMDNSServer) Stop() error { return nil }
|
||||
func (ms *mockedMDNSServer) Zone() Zone { return ms.zone }
|
||||
|
||||
// a useful mix of NewMockedZone and NewMockedMDNSServer
|
||||
func newMockedMDNSServerWithRecord(zr ZoneRecord) *mockedMDNSServer {
|
||||
return newMockedMDNSServer(newMockedZoneWithRecords([]ZoneRecord{zr}))
|
||||
}
|
||||
func newMockedMDNSServerWithRecords(zrs []ZoneRecord) *mockedMDNSServer {
|
||||
return newMockedMDNSServer(newMockedZoneWithRecords(zrs))
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// A mocked mDNS client.
|
||||
// This mock asks a group of (potentially mocked) mDNS servers
|
||||
type mockedMDNSClient struct {
|
||||
sync.RWMutex
|
||||
|
||||
servers map[ZoneMDNSServer]ZoneMDNSServer
|
||||
|
||||
// Statistics
|
||||
NumLookupsName int
|
||||
NumLookupsInaddr int
|
||||
NumInsLookupsName int
|
||||
NumInsLookupsInaddr int
|
||||
}
|
||||
|
||||
func newMockedMDNSClient(srvrs []*mockedMDNSServer) *mockedMDNSClient {
|
||||
r := mockedMDNSClient{
|
||||
servers: make(map[ZoneMDNSServer]ZoneMDNSServer),
|
||||
}
|
||||
if srvrs != nil {
|
||||
for _, server := range srvrs {
|
||||
r.servers[server] = server
|
||||
}
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) Start(ifi *net.Interface) error { return nil }
|
||||
func (mc *mockedMDNSClient) Stop() error { return nil }
|
||||
func (mc *mockedMDNSClient) Domain() string { return DefaultLocalDomain }
|
||||
func (mc *mockedMDNSClient) LookupName(name string) ([]ZoneRecord, error) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
|
||||
// get a random result
|
||||
mc.NumLookupsName += 1
|
||||
for _, server := range mc.servers {
|
||||
r, err := server.Zone().LookupName(name)
|
||||
if err == nil {
|
||||
return r, nil // return the first answer
|
||||
}
|
||||
}
|
||||
return nil, LookupError(name)
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) LookupInaddr(inaddr string) ([]ZoneRecord, error) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
|
||||
// get a random result
|
||||
mc.NumLookupsInaddr += 1
|
||||
for _, server := range mc.servers {
|
||||
r, err := server.Zone().LookupInaddr(inaddr)
|
||||
if err == nil {
|
||||
return r, nil // return the first answer
|
||||
}
|
||||
}
|
||||
return nil, LookupError(inaddr)
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) InsistentLookupName(name string) ([]ZoneRecord, error) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
|
||||
res := make([]ZoneRecord, 0)
|
||||
mc.NumInsLookupsName += 1
|
||||
for _, server := range mc.servers {
|
||||
r, err := server.Zone().LookupName(name)
|
||||
if err == nil {
|
||||
res = append(res, r...)
|
||||
}
|
||||
}
|
||||
if len(res) == 0 {
|
||||
return nil, LookupError(name)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) InsistentLookupInaddr(inaddr string) ([]ZoneRecord, error) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
|
||||
res := make([]ZoneRecord, 0)
|
||||
mc.NumInsLookupsInaddr += 1
|
||||
for _, server := range mc.servers {
|
||||
r, err := server.Zone().LookupInaddr(inaddr)
|
||||
if err == nil {
|
||||
res = append(res, r...)
|
||||
}
|
||||
}
|
||||
if len(res) == 0 {
|
||||
return nil, LookupError(inaddr)
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) AddServer(srv ZoneMDNSServer) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
mc.servers[srv] = srv
|
||||
}
|
||||
|
||||
func (mc *mockedMDNSClient) RemoveServer(srv ZoneMDNSServer) {
|
||||
mc.Lock()
|
||||
defer mc.Unlock()
|
||||
delete(mc.servers, srv)
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
type zbmEntry struct {
|
||||
Server *mockedMDNSServer
|
||||
Client *mockedMDNSClient
|
||||
Zone *zoneDb
|
||||
}
|
||||
type zoneDbsWithMockedMDns []*zbmEntry
|
||||
|
||||
// Creates a group of (real) zone databases linked through mocked mDNS servers and clients
|
||||
// This effectively creates a cluster of WeaveDNS peers
|
||||
func newZoneDbsWithMockedMDns(num int, config ZoneConfig) zoneDbsWithMockedMDns {
|
||||
res := make(zoneDbsWithMockedMDns, num)
|
||||
|
||||
for i := 0; i < num; i++ {
|
||||
res[i] = new(zbmEntry)
|
||||
|
||||
Debug.Printf("[test] Creating mocked mDNS server #%d", i)
|
||||
res[i].Server = newMockedMDNSServer(nil)
|
||||
|
||||
Debug.Printf("[test] Creating mocked mDNS client #%d", i)
|
||||
res[i].Client = newMockedMDNSClient([]*mockedMDNSServer{})
|
||||
|
||||
cfg := config
|
||||
cfg.MDNSClient = res[i].Client
|
||||
cfg.MDNSServer = res[i].Server
|
||||
|
||||
Debug.Printf("[test] Creating ZoneDb #%d", i)
|
||||
res[i].Zone, _ = NewZoneDb(cfg)
|
||||
|
||||
// link the mDNS server to its zone
|
||||
// ZoneDbs are connected to mDNS in two directions: they use their mDNS
|
||||
// clients for asking other peers about names/IPs, and export their records
|
||||
// through a mDNS server.
|
||||
res[i].Server.zone = res[i].Zone
|
||||
}
|
||||
|
||||
// link all the clients to all the servers
|
||||
for i := 0; i < num; i++ {
|
||||
for j := 0; j < num; j++ {
|
||||
// with this check, the local client will not ask to the local server
|
||||
// this is not what we currently do, but can be convenient in some cases
|
||||
// for finding some bugs...
|
||||
if i != j {
|
||||
Debug.Printf("[test] Linking mocked mDNS client #%d to server #%d", i, j)
|
||||
res[i].Client.AddServer(res[j].Server)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
func (zbs zoneDbsWithMockedMDns) Start() {
|
||||
for _, entry := range zbs {
|
||||
entry.Zone.Start()
|
||||
}
|
||||
}
|
||||
|
||||
func (zbs zoneDbsWithMockedMDns) Stop() {
|
||||
for _, entry := range zbs {
|
||||
entry.Zone.Stop()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// A mocked cache where we never find a single thing... ;)
|
||||
type mockedCache struct {
|
||||
NumGets int
|
||||
NumPuts int
|
||||
NumRemovals int
|
||||
}
|
||||
|
||||
func newMockedCache() *mockedCache { return &mockedCache{} }
|
||||
|
||||
func (c *mockedCache) Get(request *dns.Msg, maxLen int) (reply *dns.Msg, err error) {
|
||||
c.NumGets += 1
|
||||
return nil, nil
|
||||
}
|
||||
func (c *mockedCache) Put(request *dns.Msg, reply *dns.Msg, ttl int, flags uint8) int {
|
||||
c.NumPuts += 1
|
||||
return 0
|
||||
}
|
||||
func (c *mockedCache) Remove(question *dns.Question) { c.NumRemovals += 1 }
|
||||
func (c *mockedCache) Purge() {}
|
||||
func (c *mockedCache) Clear() {}
|
||||
func (c *mockedCache) Len() int { return 0 }
|
||||
func (c *mockedCache) Capacity() int { return DefaultCacheLen }
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// A mocked fallback server
|
||||
type mockedFallback struct {
|
||||
CliConfig *dns.ClientConfig
|
||||
Addr string
|
||||
Port int
|
||||
|
||||
udpSrv *dns.Server
|
||||
tcpSrv *dns.Server
|
||||
}
|
||||
|
||||
// Create a mocked fallback server
|
||||
// You can use the server's `CliConfig` as the `UpstreamCfg` of a `DNSServer`...
|
||||
func newMockedFallback(udpH dns.HandlerFunc, tcpH dns.HandlerFunc) (*mockedFallback, error) {
|
||||
udpSrv, fallbackAddr, err := runLocalUDPServer("127.0.0.1:0", udpH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
_, fallbackPort, err := net.SplitHostPort(fallbackAddr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fallbackPortI, _ := strconv.Atoi(fallbackPort)
|
||||
|
||||
res := mockedFallback{
|
||||
udpSrv: udpSrv,
|
||||
Addr: fallbackAddr,
|
||||
Port: fallbackPortI,
|
||||
CliConfig: &dns.ClientConfig{
|
||||
Servers: []string{"127.0.0.1"},
|
||||
Port: fallbackPort,
|
||||
},
|
||||
}
|
||||
|
||||
if tcpH != nil {
|
||||
fallbackTCPAddr := fmt.Sprintf("127.0.0.1:%s", fallbackPort)
|
||||
res.tcpSrv, _, err = runLocalTCPServer(fallbackTCPAddr, tcpH)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
// Start the fallback server
|
||||
func (mf *mockedFallback) Start() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Stop the fallback server
|
||||
func (mf *mockedFallback) Stop() error {
|
||||
if mf.tcpSrv != nil {
|
||||
mf.udpSrv.Shutdown()
|
||||
mf.udpSrv = nil
|
||||
}
|
||||
if mf.tcpSrv != nil {
|
||||
mf.tcpSrv.Shutdown()
|
||||
mf.udpSrv = nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run a UDP fallback server
|
||||
func runLocalUDPServer(laddr string, handler dns.HandlerFunc) (*dns.Server, string, error) {
|
||||
Debug.Printf("[mocked fallback] Starting fallback UDP server at %s", laddr)
|
||||
pc, err := net.ListenPacket("udp", laddr)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
server := &dns.Server{PacketConn: pc, Handler: handler, ReadTimeout: testSocketTimeout * time.Millisecond}
|
||||
|
||||
go func() {
|
||||
server.ActivateAndServe()
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
Debug.Printf("[mocked fallback] Fallback UDP server listening at %s", pc.LocalAddr())
|
||||
return server, pc.LocalAddr().String(), nil
|
||||
}
|
||||
|
||||
// Run a TCP fallback server
|
||||
func runLocalTCPServer(laddr string, handler dns.HandlerFunc) (*dns.Server, string, error) {
|
||||
Debug.Printf("[mocked fallback] Starting fallback TCP server at %s", laddr)
|
||||
laddrTCP, err := net.ResolveTCPAddr("tcp", laddr)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", laddrTCP)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
server := &dns.Server{Listener: l, Handler: handler, ReadTimeout: testSocketTimeout * time.Millisecond}
|
||||
|
||||
go func() {
|
||||
server.ActivateAndServe()
|
||||
l.Close()
|
||||
}()
|
||||
|
||||
Debug.Printf("[mocked fallback] Fallback TCP server listening at %s", l.Addr().String())
|
||||
return server, l.Addr().String(), nil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Perform a DNS query and assert the reply code, number or answers, etc
|
||||
func assertExchange(t *testing.T, z string, ty uint16, port int, minAnswers int, maxAnswers int, expErr int) (*dns.Msg, *dns.Msg) {
|
||||
wt.AssertNotEqualInt(t, port, 0, "invalid DNS server port")
|
||||
|
||||
c := &dns.Client{
|
||||
UDPSize: testUDPBufSize,
|
||||
}
|
||||
|
||||
m := new(dns.Msg)
|
||||
m.RecursionDesired = true
|
||||
m.SetQuestion(z, ty)
|
||||
m.SetEdns0(testUDPBufSize, false) // we don't want to play with truncation here...
|
||||
|
||||
lstAddr := fmt.Sprintf("127.0.0.1:%d", port)
|
||||
r, _, err := c.Exchange(m, lstAddr)
|
||||
t.Logf("Response from '%s':\n%+v\n", lstAddr, r)
|
||||
if err != nil {
|
||||
t.Fatalf("Error when querying DNS server at %s: %s", lstAddr, err)
|
||||
}
|
||||
wt.AssertNoErr(t, err)
|
||||
if minAnswers == 0 && maxAnswers == 0 {
|
||||
wt.AssertStatus(t, r.Rcode, expErr, "DNS response code")
|
||||
} else {
|
||||
wt.AssertStatus(t, r.Rcode, dns.RcodeSuccess, "DNS response code")
|
||||
}
|
||||
answers := len(r.Answer)
|
||||
if minAnswers >= 0 && answers < minAnswers {
|
||||
wt.Fatalf(t, "Number of answers >= %d", minAnswers)
|
||||
}
|
||||
if maxAnswers >= 0 && answers > maxAnswers {
|
||||
wt.Fatalf(t, "Number of answers <= %d", maxAnswers)
|
||||
}
|
||||
return m, r
|
||||
}
|
||||
|
||||
// Assert that we have a response in the cache for a query `q`
|
||||
func assertInCache(t *testing.T, cache ZoneCache, q *dns.Msg, desc string) {
|
||||
r, err := cache.Get(q, maxUDPSize)
|
||||
wt.AssertNoErr(t, err)
|
||||
wt.AssertNotNil(t, r, fmt.Sprintf("value in the cache: %s", desc))
|
||||
}
|
||||
|
||||
// Assert that we have a response in the cache for a query `q`
|
||||
func assertNotLocalInCache(t *testing.T, cache ZoneCache, q *dns.Msg, desc string) {
|
||||
r, err := cache.Get(q, maxUDPSize)
|
||||
if !(r == nil && err == errNoLocalReplies) {
|
||||
t.Fatalf("Cache does not return a noLocalReplies error for query %s", q)
|
||||
}
|
||||
}
|
||||
|
||||
// Assert that we do not have a response in the cache for a query `q`
|
||||
func assertNotInCache(t *testing.T, cache ZoneCache, q *dns.Msg, desc string) {
|
||||
r, err := cache.Get(q, maxUDPSize)
|
||||
wt.AssertNoErr(t, err)
|
||||
wt.AssertNil(t, r, fmt.Sprintf("value in the cache: %s\n%s", desc, r))
|
||||
}
|
||||
+12
-82
@@ -80,7 +80,7 @@ func TestUDPDNSServer(t *testing.T) {
|
||||
}
|
||||
|
||||
// Run another DNS server for fallback
|
||||
s, fallbackAddr, err := runLocalUDPServer(t, "127.0.0.1:0", fallbackHandler)
|
||||
s, fallbackAddr, err := runLocalUDPServer("127.0.0.1:0", fallbackHandler)
|
||||
wt.AssertNoErr(t, err)
|
||||
defer s.Shutdown()
|
||||
|
||||
@@ -96,29 +96,29 @@ func TestUDPDNSServer(t *testing.T) {
|
||||
|
||||
var r *dns.Msg
|
||||
|
||||
r = assertExchange(t, successTestName, dns.TypeA, 1, 1, 0)
|
||||
_, r = assertExchange(t, successTestName, dns.TypeA, testPort, 1, 1, 0)
|
||||
wt.AssertType(t, r.Answer[0], (*dns.A)(nil), "DNS record")
|
||||
wt.AssertEqualString(t, r.Answer[0].(*dns.A).A.String(), testAddr1, "IP address")
|
||||
|
||||
assertExchange(t, failTestName, dns.TypeA, 0, 0, dns.RcodeNameError)
|
||||
assertExchange(t, failTestName, dns.TypeA, testPort, 0, 0, dns.RcodeNameError)
|
||||
|
||||
r = assertExchange(t, testRDNSsuccess, dns.TypePTR, 1, 1, 0)
|
||||
_, r = assertExchange(t, testRDNSsuccess, dns.TypePTR, testPort, 1, 1, 0)
|
||||
wt.AssertType(t, r.Answer[0], (*dns.PTR)(nil), "DNS record")
|
||||
wt.AssertEqualString(t, r.Answer[0].(*dns.PTR).Ptr, successTestName, "IP address")
|
||||
|
||||
assertExchange(t, testRDNSfail, dns.TypePTR, 0, 0, dns.RcodeNameError)
|
||||
assertExchange(t, testRDNSfail, dns.TypePTR, testPort, 0, 0, dns.RcodeNameError)
|
||||
|
||||
// This should fail because we don't have information about MX records
|
||||
assertExchange(t, successTestName, dns.TypeMX, 0, 0, dns.RcodeNameError)
|
||||
// This should fail because we don't handle MX records
|
||||
assertExchange(t, successTestName, dns.TypeMX, testPort, 0, 0, dns.RcodeNameError)
|
||||
|
||||
// This non-local query for an MX record should succeed by being
|
||||
// passed on to the fallback server
|
||||
assertExchange(t, nonLocalName, dns.TypeMX, 1, -1, 0)
|
||||
assertExchange(t, nonLocalName, dns.TypeMX, testPort, 1, -1, 0)
|
||||
|
||||
// Now ask a query that we expect to return a lot of data.
|
||||
assertExchange(t, nonLocalName, dns.TypeANY, 5, -1, 0)
|
||||
assertExchange(t, nonLocalName, dns.TypeANY, testPort, 5, -1, 0)
|
||||
|
||||
assertExchange(t, testRDNSnonlocal, dns.TypePTR, 1, -1, 0)
|
||||
assertExchange(t, testRDNSnonlocal, dns.TypePTR, testPort, 1, -1, 0)
|
||||
|
||||
// Not testing MDNS functionality of server here (yet), since it
|
||||
// needs two servers, each listening on its own address
|
||||
@@ -173,7 +173,7 @@ func TestTCPDNSServer(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Logf("Running a DNS fallback server with UDP")
|
||||
us, fallbackUDPAddr, err := runLocalUDPServer(t, "127.0.0.1:0", fallbackUDPHandler)
|
||||
us, fallbackUDPAddr, err := runLocalUDPServer("127.0.0.1:0", fallbackUDPHandler)
|
||||
wt.AssertNoErr(t, err)
|
||||
defer us.Shutdown()
|
||||
|
||||
@@ -182,7 +182,7 @@ func TestTCPDNSServer(t *testing.T) {
|
||||
|
||||
t.Logf("Starting another fallback server, with TCP, on the same port as the UDP server")
|
||||
fallbackTCPAddr := fmt.Sprintf("127.0.0.1:%s", fallbackPort)
|
||||
ts, fallbackTCPAddr, err := runLocalTCPServer(t, fallbackTCPAddr, fallbackTCPHandler)
|
||||
ts, fallbackTCPAddr, err := runLocalTCPServer(fallbackTCPAddr, fallbackTCPHandler)
|
||||
wt.AssertNoErr(t, err)
|
||||
defer ts.Shutdown()
|
||||
|
||||
@@ -242,73 +242,3 @@ func TestTCPDNSServer(t *testing.T) {
|
||||
wt.AssertFalse(t, r.MsgHdr.Truncated, "DNS truncated response flag")
|
||||
wt.AssertEqualInt(t, len(r.Answer), numAnswers, "number of answers (UDP-long)")
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// perform a DNS query and assert the reply code, number or answers, etc
|
||||
func assertExchange(t *testing.T, z string, ty uint16, minAnswers int, maxAnswers int, expErr int) *dns.Msg {
|
||||
c := new(dns.Client)
|
||||
c.UDPSize = testUDPBufSize
|
||||
m := new(dns.Msg)
|
||||
m.RecursionDesired = true
|
||||
m.SetQuestion(z, ty)
|
||||
m.SetEdns0(testUDPBufSize, false) // we don't want to play with truncation here...
|
||||
|
||||
r, _, err := c.Exchange(m, fmt.Sprintf("127.0.0.1:%d", testPort))
|
||||
t.Logf("Response:\n%+v\n", r)
|
||||
wt.AssertNoErr(t, err)
|
||||
if minAnswers == 0 && maxAnswers == 0 {
|
||||
wt.AssertStatus(t, r.Rcode, expErr, "DNS response code")
|
||||
} else {
|
||||
wt.AssertStatus(t, r.Rcode, dns.RcodeSuccess, "DNS response code")
|
||||
}
|
||||
answers := len(r.Answer)
|
||||
if minAnswers >= 0 && answers < minAnswers {
|
||||
wt.Fatalf(t, "Number of answers >= %d", minAnswers)
|
||||
}
|
||||
if maxAnswers >= 0 && answers > maxAnswers {
|
||||
wt.Fatalf(t, "Number of answers <= %d", maxAnswers)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// run a UDP fallback server
|
||||
func runLocalUDPServer(t *testing.T, laddr string, handler dns.HandlerFunc) (*dns.Server, string, error) {
|
||||
t.Logf("Starting fallback UDP server at %s", laddr)
|
||||
pc, err := net.ListenPacket("udp", laddr)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
server := &dns.Server{PacketConn: pc, Handler: handler, ReadTimeout: 100 * time.Millisecond}
|
||||
|
||||
go func() {
|
||||
server.ActivateAndServe()
|
||||
pc.Close()
|
||||
}()
|
||||
|
||||
t.Logf("Fallback UDP server listening at %s", pc.LocalAddr())
|
||||
return server, pc.LocalAddr().String(), nil
|
||||
}
|
||||
|
||||
// run a TCP fallback server
|
||||
func runLocalTCPServer(t *testing.T, laddr string, handler dns.HandlerFunc) (*dns.Server, string, error) {
|
||||
t.Logf("Starting fallback TCP server at %s", laddr)
|
||||
laddrTCP, err := net.ResolveTCPAddr("tcp", laddr)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
l, err := net.ListenTCP("tcp", laddrTCP)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
server := &dns.Server{Listener: l, Handler: handler, ReadTimeout: 100 * time.Millisecond}
|
||||
|
||||
go func() {
|
||||
server.ActivateAndServe()
|
||||
l.Close()
|
||||
}()
|
||||
|
||||
t.Logf("Fallback TCP server listening at %s", l.Addr().String())
|
||||
return server, l.Addr().String(), nil
|
||||
}
|
||||
Reference in new issue
Block a user