Skip to content

Commit

Permalink
Add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
fortuna committed Dec 19, 2023
1 parent 96883e8 commit 9e5e16d
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 1 deletion.
7 changes: 6 additions & 1 deletion dns/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,13 @@ func (f FuncResolver) Query(ctx context.Context, q dnsmessage.Question) (*dnsmes
}

// NewQuestion is a convenience function to create a [dnsmessage.Question].
// The input domain is interpreted as fully-qualified. If the end "." is missing, it's added.
func NewQuestion(domain string, qtype dnsmessage.Type) (*dnsmessage.Question, error) {
name, err := dnsmessage.NewName(domain)
fullDomain := domain
if len(domain) == 0 || domain[len(domain)-1] != '.' {
fullDomain += "."
}
name, err := dnsmessage.NewName(fullDomain)
if err != nil {
return nil, fmt.Errorf("cannot parse domain name: %w", err)
}
Expand Down
97 changes: 97 additions & 0 deletions dns/resolver_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Copyright 2023 Jigsaw Operations LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package dns

import (
"encoding/binary"
"testing"

"github.com/stretchr/testify/require"
"golang.org/x/net/dns/dnsmessage"
)

func TestNewQuestionTypes(t *testing.T) {
testDomain := "example.com."
qname, err := dnsmessage.NewName(testDomain)
require.NoError(t, err)
for _, qtype := range []dnsmessage.Type{dnsmessage.TypeA, dnsmessage.TypeAAAA, dnsmessage.TypeCNAME} {
t.Run(qtype.String(), func(t *testing.T) {
q, err := NewQuestion(testDomain, qtype)
require.NoError(t, err)
require.Equal(t, qname, q.Name)
require.Equal(t, qtype, q.Type)
require.Equal(t, dnsmessage.ClassINET, q.Class)
})
}
}

func TestNewQuestionNotFQDN(t *testing.T) {
testDomain := "example.com"
q, err := NewQuestion(testDomain, dnsmessage.TypeAAAA)
require.NoError(t, err)
require.Equal(t, dnsmessage.MustNewName("example.com."), q.Name)
}

func TestNewQuestionRoot(t *testing.T) {
testDomain := "."
qname, err := dnsmessage.NewName(testDomain)
require.NoError(t, err)
q, err := NewQuestion(testDomain, dnsmessage.TypeAAAA)
require.NoError(t, err)
require.Equal(t, qname, q.Name)
}

func TestNewQuestionEmpty(t *testing.T) {
testDomain := ""
q, err := NewQuestion(testDomain, dnsmessage.TypeAAAA)
require.NoError(t, err)
require.Equal(t, dnsmessage.MustNewName("."), q.Name)
}

func Test_appendRequest(t *testing.T) {
q, err := NewQuestion(".", dnsmessage.TypeAAAA)
require.NoError(t, err)

id := uint16(1234)
buf, err := appendRequest(id, *q, []byte{})
require.NoError(t, err)

// 12 bytes header + 5 question + 11 EDNS(0) OPT RR
require.Equal(t, 28, len(buf))

require.Equal(t, id, binary.BigEndian.Uint16(buf))

var request dnsmessage.Message
err = request.Unpack(buf)
require.NoError(t, err)
require.Equal(t, id, request.ID)
require.Equal(t, 1, len(request.Questions))
require.Equal(t, *q, request.Questions[0])
require.Equal(t, 0, len(request.Answers))
require.Equal(t, 0, len(request.Authorities))
// ENDS(0) OPT resource record.
require.Equal(t, 1, len(request.Additionals))
optRR := dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: dnsmessage.MustNewName("."),
Type: dnsmessage.TypeOPT,
Class: maxDNSPacketSize,
TTL: 0,
Length: 0,
},
Body: &dnsmessage.OPTResource{},
}
require.Equal(t, optRR, request.Additionals[0])
}

0 comments on commit 9e5e16d

Please sign in to comment.