Commit 41660338 authored by Miek Gieben's avatar Miek Gieben Committed by GitHub

Cleanup and fixes (#223)

* Set version to 001
* Remove k8stest, test fails is k8s is not there: touch luck
* Remove server directory: not used anymore
* Disable k8s test (for now)
* gometalinter changes
parent 9ac3cab1
......@@ -6,21 +6,19 @@ import (
// plug in the standard directives
_ "github.com/miekg/coredns/middleware/bind"
_ "github.com/miekg/coredns/middleware/health"
_ "github.com/miekg/coredns/middleware/pprof"
_ "github.com/miekg/coredns/middleware/errors"
_ "github.com/miekg/coredns/middleware/loadbalance"
_ "github.com/miekg/coredns/middleware/log"
_ "github.com/miekg/coredns/middleware/metrics"
_ "github.com/miekg/coredns/middleware/rewrite"
_ "github.com/miekg/coredns/middleware/cache"
_ "github.com/miekg/coredns/middleware/chaos"
_ "github.com/miekg/coredns/middleware/dnssec"
_ "github.com/miekg/coredns/middleware/errors"
_ "github.com/miekg/coredns/middleware/etcd"
_ "github.com/miekg/coredns/middleware/file"
_ "github.com/miekg/coredns/middleware/health"
_ "github.com/miekg/coredns/middleware/kubernetes"
_ "github.com/miekg/coredns/middleware/loadbalance"
_ "github.com/miekg/coredns/middleware/log"
_ "github.com/miekg/coredns/middleware/metrics"
_ "github.com/miekg/coredns/middleware/pprof"
_ "github.com/miekg/coredns/middleware/proxy"
_ "github.com/miekg/coredns/middleware/rewrite"
_ "github.com/miekg/coredns/middleware/secondary"
)
......@@ -9,7 +9,7 @@ package dnsserver
// feel the effects of all other middleware below
// (after) them during a request, but they must not
// care what middleware above them are doing.
var Directives = []string{
var directives = []string{
"bind",
"health",
"pprof",
......
......@@ -13,7 +13,7 @@ const serverType = "dns"
func init() {
caddy.RegisterServerType(serverType, caddy.ServerType{
Directives: Directives,
Directives: directives,
DefaultInput: func() caddy.Input {
if Port == DefaultPort && Zone != "" {
return caddy.CaddyfileInput{
......@@ -32,8 +32,6 @@ func init() {
})
}
var TestNewContext = newContext
func newContext() caddy.Context {
return &dnsContext{keysToConfigs: make(map[string]*Config)}
}
......@@ -103,8 +101,8 @@ func (h *dnsContext) MakeServers() ([]caddy.Server, error) {
}
// AddMiddleware adds a middleware to a site's middleware stack.
func (sc *Config) AddMiddleware(m Middleware) {
sc.Middleware = append(sc.Middleware, m)
func (c *Config) AddMiddleware(m Middleware) {
c.Middleware = append(c.Middleware, m)
}
// groupSiteConfigsByListenAddr groups site configs by their listen
......
......@@ -32,6 +32,7 @@ type Server struct {
connTimeout time.Duration // the maximum duration of a graceful shutdown
}
// NewServer returns a new CoreDNS server and compiles all middleware in to it.
func NewServer(addr string, group []*Config) (*Server, error) {
s := &Server{
......@@ -65,20 +66,6 @@ func NewServer(addr string, group []*Config) (*Server, error) {
return s, nil
}
// LocalAddr return the addresses where the server is bound to.
func (s *Server) LocalAddr() net.Addr {
s.m.Lock()
defer s.m.Unlock()
return s.l.Addr()
}
// LocalAddrPacket return the net.PacketConn address where the server is bound to.
func (s *Server) LocalAddrPacket() net.Addr {
s.m.Lock()
defer s.m.Unlock()
return s.p.LocalAddr()
}
// Serve starts the server with an existing listener. It blocks until the server stops.
func (s *Server) Serve(l net.Listener) error {
s.m.Lock()
......@@ -97,6 +84,7 @@ func (s *Server) ServePacket(p net.PacketConn) error {
return s.server[udp].ActivateAndServe()
}
// Listen implements caddy.TCPServer interface.
func (s *Server) Listen() (net.Listener, error) {
l, err := net.Listen("tcp", s.Addr)
if err != nil {
......@@ -108,6 +96,7 @@ func (s *Server) Listen() (net.Listener, error) {
return l, nil
}
// ListenPacket implements caddy.UDPServer interface.
func (s *Server) ListenPacket() (net.PacketConn, error) {
p, err := net.ListenPacket("udp", s.Addr)
if err != nil {
......@@ -197,7 +186,7 @@ func (s *Server) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
if h, ok := s.zones[string(b[:l])]; ok {
if r.Question[0].Qtype != dns.TypeDS {
rcode, _ := h.middlewareChain.ServeDNS(ctx, w, r)
if RcodeNoClientWrite(rcode) {
if rcodeNoClientWrite(rcode) {
DefaultErrorFunc(w, r, rcode)
}
return
......@@ -211,7 +200,7 @@ func (s *Server) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
// Wildcard match, if we have found nothing try the root zone as a last resort.
if h, ok := s.zones["."]; ok {
rcode, _ := h.middlewareChain.ServeDNS(ctx, w, r)
if RcodeNoClientWrite(rcode) {
if rcodeNoClientWrite(rcode) {
DefaultErrorFunc(w, r, rcode)
}
return
......@@ -234,7 +223,7 @@ func DefaultErrorFunc(w dns.ResponseWriter, r *dns.Msg, rcode int) {
w.WriteMsg(answer)
}
func RcodeNoClientWrite(rcode int) bool {
func rcodeNoClientWrite(rcode int) bool {
switch rcode {
case dns.RcodeServerFailure:
fallthrough
......
......@@ -10,9 +10,15 @@ import (
//go:generate go run plugin_generate.go
func main() {
// Set some flags/options specific for CoreDNS.
// Default values for flags for CoreDNS.
flag.Set("type", "dns")
// Values specific for CoreDNS.
caddy.DefaultConfigFile = "Corefile"
caddy.AppName = "coredns"
caddy.AppVersion = version
caddymain.Run()
}
const version = "001"
......@@ -56,4 +56,4 @@ func doDDD(b []byte) {
}
func isDigit(b byte) bool { return b >= '0' && b <= '9' }
func dddToByte(s []byte) byte { return byte((s[1]-'0')*100 + (s[2]-'0')*10 + (s[3] - '0')) }
func dddToByte(s []byte) byte { return (s[1]-'0')*100 + (s[2]-'0')*10 + (s[3] - '0') }
package middleware
import (
"errors"
"runtime"
"unicode"
"github.com/flynn/go-shlex"
)
var runtimeGoos = runtime.GOOS
// SplitCommandAndArgs takes a command string and parses it
// shell-style into the command and its separate arguments.
func SplitCommandAndArgs(command string) (cmd string, args []string, err error) {
var parts []string
if runtimeGoos == "windows" {
parts = parseWindowsCommand(command) // parse it Windows-style
} else {
parts, err = parseUnixCommand(command) // parse it Unix-style
if err != nil {
err = errors.New("error parsing command: " + err.Error())
return
}
}
if len(parts) == 0 {
err = errors.New("no command contained in '" + command + "'")
return
}
cmd = parts[0]
if len(parts) > 1 {
args = parts[1:]
}
return
}
// parseUnixCommand parses a unix style command line and returns the
// command and its arguments or an error
func parseUnixCommand(cmd string) ([]string, error) {
return shlex.Split(cmd)
}
// parseWindowsCommand parses windows command lines and
// returns the command and the arguments as an array. It
// should be able to parse commonly used command lines.
// Only basic syntax is supported:
// - spaces in double quotes are not token delimiters
// - double quotes are escaped by either backspace or another double quote
// - except for the above case backspaces are path separators (not special)
//
// Many sources point out that escaping quotes using backslash can be unsafe.
// Use two double quotes when possible. (Source: http://stackoverflow.com/a/31413730/2616179 )
//
// This function has to be used on Windows instead
// of the shlex package because this function treats backslash
// characters properly.
func parseWindowsCommand(cmd string) []string {
const backslash = '\\'
const quote = '"'
var parts []string
var part string
var inQuotes bool
var lastRune rune
for i, ch := range cmd {
if i != 0 {
lastRune = rune(cmd[i-1])
}
if ch == backslash {
// put it in the part - for now we don't know if it's an
// escaping char or path separator
part += string(ch)
continue
}
if ch == quote {
if lastRune == backslash {
// remove the backslash from the part and add the escaped quote instead
part = part[:len(part)-1]
part += string(ch)
continue
}
if lastRune == quote {
// revert the last change of the inQuotes state
// it was an escaping quote
inQuotes = !inQuotes
part += string(ch)
continue
}
// normal escaping quotes
inQuotes = !inQuotes
continue
}
if unicode.IsSpace(ch) && !inQuotes && len(part) > 0 {
parts = append(parts, part)
part = ""
continue
}
part += string(ch)
}
if len(part) > 0 {
parts = append(parts, part)
part = ""
}
return parts
}
package middleware
import (
"fmt"
"runtime"
"strings"
"testing"
)
func TestParseUnixCommand(t *testing.T) {
tests := []struct {
input string
expected []string
}{
// 0 - emtpy command
{
input: ``,
expected: []string{},
},
// 1 - command without arguments
{
input: `command`,
expected: []string{`command`},
},
// 2 - command with single argument
{
input: `command arg1`,
expected: []string{`command`, `arg1`},
},
// 3 - command with multiple arguments
{
input: `command arg1 arg2`,
expected: []string{`command`, `arg1`, `arg2`},
},
// 4 - command with single argument with space character - in quotes
{
input: `command "arg1 arg1"`,
expected: []string{`command`, `arg1 arg1`},
},
// 5 - command with multiple spaces and tab character
{
input: "command arg1 arg2\targ3",
expected: []string{`command`, `arg1`, `arg2`, `arg3`},
},
// 6 - command with single argument with space character - escaped with backspace
{
input: `command arg1\ arg2`,
expected: []string{`command`, `arg1 arg2`},
},
// 7 - single quotes should escape special chars
{
input: `command 'arg1\ arg2'`,
expected: []string{`command`, `arg1\ arg2`},
},
}
for i, test := range tests {
errorPrefix := fmt.Sprintf("Test [%d]: ", i)
errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
actual, _ := parseUnixCommand(test.input)
if len(actual) != len(test.expected) {
t.Errorf(errorPrefix+"Expected %d parts, got %d: %#v."+errorSuffix, len(test.expected), len(actual), actual)
continue
}
for j := 0; j < len(actual); j++ {
if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
t.Errorf(errorPrefix+"Expected: %v Actual: %v (index %d)."+errorSuffix, expectedPart, actualPart, j)
}
}
}
}
func TestParseWindowsCommand(t *testing.T) {
tests := []struct {
input string
expected []string
}{
{ // 0 - empty command - do not fail
input: ``,
expected: []string{},
},
{ // 1 - cmd without args
input: `cmd`,
expected: []string{`cmd`},
},
{ // 2 - multiple args
input: `cmd arg1 arg2`,
expected: []string{`cmd`, `arg1`, `arg2`},
},
{ // 3 - multiple args with space
input: `cmd "combined arg" arg2`,
expected: []string{`cmd`, `combined arg`, `arg2`},
},
{ // 4 - path without spaces
input: `mkdir C:\Windows\foo\bar`,
expected: []string{`mkdir`, `C:\Windows\foo\bar`},
},
{ // 5 - command with space in quotes
input: `"command here"`,
expected: []string{`command here`},
},
{ // 6 - argument with escaped quotes (two quotes)
input: `cmd ""arg""`,
expected: []string{`cmd`, `"arg"`},
},
{ // 7 - argument with escaped quotes (backslash)
input: `cmd \"arg\"`,
expected: []string{`cmd`, `"arg"`},
},
{ // 8 - two quotes (escaped) inside an inQuote element
input: `cmd "a ""quoted value"`,
expected: []string{`cmd`, `a "quoted value`},
},
// TODO - see how many quotes are dislayed if we use "", """, """""""
{ // 9 - two quotes outside an inQuote element
input: `cmd a ""quoted value`,
expected: []string{`cmd`, `a`, `"quoted`, `value`},
},
{ // 10 - path with space in quotes
input: `mkdir "C:\directory name\foobar"`,
expected: []string{`mkdir`, `C:\directory name\foobar`},
},
{ // 11 - space without quotes
input: `mkdir C:\ space`,
expected: []string{`mkdir`, `C:\`, `space`},
},
{ // 12 - space in quotes
input: `mkdir "C:\ space"`,
expected: []string{`mkdir`, `C:\ space`},
},
{ // 13 - UNC
input: `mkdir \\?\C:\Users`,
expected: []string{`mkdir`, `\\?\C:\Users`},
},
{ // 14 - UNC with space
input: `mkdir "\\?\C:\Program Files"`,
expected: []string{`mkdir`, `\\?\C:\Program Files`},
},
{ // 15 - unclosed quotes - treat as if the path ends with quote
input: `mkdir "c:\Program files`,
expected: []string{`mkdir`, `c:\Program files`},
},
{ // 16 - quotes used inside the argument
input: `mkdir "c:\P"rogra"m f"iles`,
expected: []string{`mkdir`, `c:\Program files`},
},
}
for i, test := range tests {
errorPrefix := fmt.Sprintf("Test [%d]: ", i)
errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
actual := parseWindowsCommand(test.input)
if len(actual) != len(test.expected) {
t.Errorf(errorPrefix+"Expected %d parts, got %d: %#v."+errorSuffix, len(test.expected), len(actual), actual)
continue
}
for j := 0; j < len(actual); j++ {
if expectedPart, actualPart := test.expected[j], actual[j]; expectedPart != actualPart {
t.Errorf(errorPrefix+"Expected: %v Actual: %v (index %d)."+errorSuffix, expectedPart, actualPart, j)
}
}
}
}
func TestSplitCommandAndArgs(t *testing.T) {
// force linux parsing. It's more robust and covers error cases
runtimeGoos = "linux"
defer func() {
runtimeGoos = runtime.GOOS
}()
var parseErrorContent = "error parsing command:"
var noCommandErrContent = "no command contained in"
tests := []struct {
input string
expectedCommand string
expectedArgs []string
expectedErrContent string
}{
// 0 - emtpy command
{
input: ``,
expectedCommand: ``,
expectedArgs: nil,
expectedErrContent: noCommandErrContent,
},
// 1 - command without arguments
{
input: `command`,
expectedCommand: `command`,
expectedArgs: nil,
expectedErrContent: ``,
},
// 2 - command with single argument
{
input: `command arg1`,
expectedCommand: `command`,
expectedArgs: []string{`arg1`},
expectedErrContent: ``,
},
// 3 - command with multiple arguments
{
input: `command arg1 arg2`,
expectedCommand: `command`,
expectedArgs: []string{`arg1`, `arg2`},
expectedErrContent: ``,
},
// 4 - command with unclosed quotes
{
input: `command "arg1 arg2`,
expectedCommand: "",
expectedArgs: nil,
expectedErrContent: parseErrorContent,
},
// 5 - command with unclosed quotes
{
input: `command 'arg1 arg2"`,
expectedCommand: "",
expectedArgs: nil,
expectedErrContent: parseErrorContent,
},
}
for i, test := range tests {
errorPrefix := fmt.Sprintf("Test [%d]: ", i)
errorSuffix := fmt.Sprintf(" Command to parse: [%s]", test.input)
actualCommand, actualArgs, actualErr := SplitCommandAndArgs(test.input)
// test if error matches expectation
if test.expectedErrContent != "" {
if actualErr == nil {
t.Errorf(errorPrefix+"Expected error with content [%s], found no error."+errorSuffix, test.expectedErrContent)
} else if !strings.Contains(actualErr.Error(), test.expectedErrContent) {
t.Errorf(errorPrefix+"Expected error with content [%s], found [%v]."+errorSuffix, test.expectedErrContent, actualErr)
}
} else if actualErr != nil {
t.Errorf(errorPrefix+"Expected no error, found [%v]."+errorSuffix, actualErr)
}
// test if command matches
if test.expectedCommand != actualCommand {
t.Errorf(errorPrefix+"Expected command: [%s], actual: [%s]."+errorSuffix, test.expectedCommand, actualCommand)
}
// test if arguments match
if len(test.expectedArgs) != len(actualArgs) {
t.Errorf(errorPrefix+"Wrong number of arguments! Expected [%v], actual [%v]."+errorSuffix, test.expectedArgs, actualArgs)
} else {
// test args only if the count matches.
for j, actualArg := range actualArgs {
expectedArg := test.expectedArgs[j]
if actualArg != expectedArg {
t.Errorf(errorPrefix+"Argument at position [%d] differ! Expected [%s], actual [%s]"+errorSuffix, j, expectedArg, actualArg)
}
}
}
}
}
func ExampleSplitCommandAndArgs() {
var commandLine string
var command string
var args []string
// just for the test - change GOOS and reset it at the end of the test
runtimeGoos = "windows"
defer func() {
runtimeGoos = runtime.GOOS
}()
commandLine = `mkdir /P "C:\Program Files"`
command, args, _ = SplitCommandAndArgs(commandLine)
fmt.Printf("Windows: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))
// set GOOS to linux
runtimeGoos = "linux"
commandLine = `mkdir -p /path/with\ space`
command, args, _ = SplitCommandAndArgs(commandLine)
fmt.Printf("Linux: %s: %s [%s]\n", commandLine, command, strings.Join(args, ","))
// Output:
// Windows: mkdir /P "C:\Program Files": mkdir [/P,C:\Program Files]
// Linux: mkdir -p /path/with\ space: mkdir [-p,/path/with space]
}
package k8stest
import (
"net/http"
)
// checkKubernetesRunning performs a basic
func CheckKubernetesRunning() bool {
_, err := http.Get("http://localhost:8080/api/v1")
return err == nil
}
......@@ -7,7 +7,6 @@ import (
"github.com/miekg/coredns/core/dnsserver"
"github.com/miekg/coredns/middleware"
"github.com/miekg/coredns/server"
"github.com/hashicorp/go-syslog"
"github.com/mholt/caddy"
......@@ -64,7 +63,7 @@ func setup(c *caddy.Controller) error {
})
dnsserver.GetConfig(c).AddMiddleware(func(next dnsserver.Handler) dnsserver.Handler {
return Logger{Next: next, Rules: rules, ErrorFunc: server.DefaultErrorFunc}
return Logger{Next: next, Rules: rules, ErrorFunc: dnsserver.DefaultErrorFunc}
})
return nil
......
package server
import (
"net"
"github.com/miekg/coredns/middleware"
)
// Config configuration for a single server.
type Config struct {
// The hostname or IP on which to serve
Host string
// The host address to bind on - defaults to (virtual) Host if empty
BindHost string
// The port to listen on
Port string
// The directory from which to parse db files
Root string
// HTTPS configuration
TLS TLSConfig
// Middleware stack
Middleware []middleware.Middleware
// Startup is a list of functions (or methods) to execute at
// server startup and restart; these are executed before any
// parts of the server are configured, and the functions are
// blocking. These are good for setting up middlewares and
// starting goroutines.
Startup []func() error
// FirstStartup is like Startup but these functions only execute
// during the initial startup, not on subsequent restarts.
//
// (Note: The server does not ever run these on its own; it is up
// to the calling application to do so, and do so only once, as the
// server itself has no notion whether it's a restart or not.)
FirstStartup []func() error
// Functions (or methods) to execute when the server quits;
// these are executed in response to SIGINT and are blocking. These
// function are *also* called when we are restarting.
Shutdown []func() error
// The path to the configuration file from which this was loaded
ConfigFile string
// The name of the application
AppName string
// The application's version
AppVersion string
}
// Address returns the host:port of c as a string.
func (c Config) Address() string {
return net.JoinHostPort(c.Host, c.Port)
}
// TLSConfig describes how TLS should be configured and used.
type TLSConfig struct {
Enabled bool // will be set to true if TLS is enabled
LetsEncryptEmail string
Manual bool // will be set to true if user provides own certs and keys
Managed bool // will be set to true if config qualifies for implicit automatic/managed HTTPS
OnDemand bool // will be set to true if user enables on-demand TLS (obtain certs during handshakes)
Ciphers []uint16
ProtocolMinVersion uint16
ProtocolMaxVersion uint16
PreferServerCipherSuites bool
ClientCerts []string
}
package server
import "testing"
func TestConfigAddress(t *testing.T) {
cfg := Config{Host: "foobar", Port: "1234"}
if actual, expected := cfg.Address(), "foobar:1234"; expected != actual {
t.Errorf("Expected '%s' but got '%s'", expected, actual)
}
cfg = Config{Host: "", Port: "1234"}
if actual, expected := cfg.Address(), ":1234"; expected != actual {
t.Errorf("Expected '%s' but got '%s'", expected, actual)
}
cfg = Config{Host: "foobar", Port: ""}
if actual, expected := cfg.Address(), "foobar:"; expected != actual {
t.Errorf("Expected '%s' but got '%s'", expected, actual)
}
cfg = Config{Host: "::1", Port: "443"}
if actual, expected := cfg.Address(), "[::1]:443"; expected != actual {
t.Errorf("Expected '%s' but got '%s'", expected, actual)
}
}
This diff is collapsed.
package server
import "github.com/miekg/coredns/middleware"
// zone represents a DNS zone. While a Server
// is what actually binds to the address, a user may want to serve
// multiple zones on a single address, and this is what a
// zone allows us to do.
type zone struct {
config Config
stack middleware.Handler
}
// buildStack builds the server's middleware stack based
// on its config. This method should be called last before
// ListenAndServe begins.
func (z *zone) buildStack() error {
z.compile(z.config.Middleware)
return nil
}
// compile is an elegant alternative to nesting middleware function
// calls like handler1(handler2(handler3(finalHandler))).
func (z *zone) compile(layers []middleware.Middleware) {
for i := len(layers) - 1; i >= 0; i-- {
z.stack = layers[i](z.stack)
}
}
......@@ -77,10 +77,10 @@ func TestEtcdStubAndProxyLookup(t *testing.T) {
t.Error("Expected to at least one RR in the answer section, got none")
}
if resp.Answer[0].Header().Rrtype != dns.TypeA {
t.Error("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype)
t.Errorf("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype)
}
if resp.Answer[0].(*dns.A).A.String() != "93.184.216.34" {
t.Error("Expected 93.184.216.34, got: %d", resp.Answer[0].(*dns.A).A.String())
t.Errorf("Expected 93.184.216.34, got: %d", resp.Answer[0].(*dns.A).A.String())
}
}
......
......@@ -7,8 +7,6 @@ import (
"log"
"testing"
"github.com/miekg/coredns/middleware/kubernetes/k8stest"
"github.com/miekg/dns"
)
......@@ -63,17 +61,13 @@ var testdataLookupSRV = []struct {
{"*.*.coredns.local.", 1, 1}, // One SRV record, via namespace and service wildcard
}
func TestK8sIntegration(t *testing.T) {
func testK8sIntegration(t *testing.T) {
// subtests here (Go 1.7 feature).
testLookupA(t)
testLookupSRV(t)
}
func testLookupA(t *testing.T) {
if !k8stest.CheckKubernetesRunning() {
t.Skip("Skipping Kubernetes Integration tests. Kubernetes is not running")
}
corefile :=
`.:0 {
kubernetes coredns.local {
......@@ -104,7 +98,7 @@ func testLookupA(t *testing.T) {
res, _, err := dnsClient.Exchange(dnsMessage, udp)
if err != nil {
t.Fatal("Could not send query: %s", err)
t.Fatalf("Could not send query: %s", err)
}
// Count A records in the answer section
ARecordCount := 0
......@@ -124,10 +118,6 @@ func testLookupA(t *testing.T) {
}
func testLookupSRV(t *testing.T) {
if !k8stest.CheckKubernetesRunning() {
t.Skip("Skipping Kubernetes Integration tests. Kubernetes is not running")
}
corefile :=
`.:0 {
kubernetes coredns.local {
......@@ -159,7 +149,7 @@ func testLookupSRV(t *testing.T) {
res, _, err := dnsClient.Exchange(dnsMessage, udp)
if err != nil {
t.Fatal("Could not send query: %s", err)
t.Fatalf("Could not send query: %s", err)
}
// Count SRV records in the answer section
srvRecordCount := 0
......
......@@ -56,9 +56,9 @@ func TestLookupProxy(t *testing.T) {
t.Error("Expected to at least one RR in the answer section, got none")
}
if resp.Answer[0].Header().Rrtype != dns.TypeA {
t.Error("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype)
t.Errorf("Expected RR to A, got: %d", resp.Answer[0].Header().Rrtype)
}
if resp.Answer[0].(*dns.A).A.String() != "127.0.0.1" {
t.Error("Expected 127.0.0.1, got: %d", resp.Answer[0].(*dns.A).A.String())
t.Errorf("Expected 127.0.0.1, got: %d", resp.Answer[0].(*dns.A).A.String())
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment