boulder/cdr/resolver_test.go

161 lines
4.8 KiB
Go

package cdr
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"net/url"
"sync"
"testing"
"time"
"github.com/miekg/dns"
"golang.org/x/net/context"
"github.com/letsencrypt/boulder/core"
blog "github.com/letsencrypt/boulder/log"
"github.com/letsencrypt/boulder/metrics"
"github.com/letsencrypt/boulder/mocks"
"github.com/letsencrypt/boulder/test"
)
var log = blog.UseMock()
func TestParseAnswer(t *testing.T) {
as := []core.GPDNSAnswer{
{Name: "a", Type: 257, TTL: 10, Data: "0 issue \"ca.com\""},
{Name: "b", Type: 1, TTL: 10, Data: "1.1.1.1"},
}
r, err := parseAnswer(as)
test.AssertNotError(t, err, "Failed to parse records")
test.AssertEquals(t, len(r), 1)
test.AssertEquals(t, r[0].Hdr.Name, "a.")
test.AssertEquals(t, r[0].Hdr.Ttl, uint32(10))
test.AssertEquals(t, r[0].Flag, uint8(0))
test.AssertEquals(t, r[0].Tag, "issue")
test.AssertEquals(t, r[0].Value, "ca.com")
}
func TestQueryCAA(t *testing.T) {
testServ := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
// TODO(#1989): Close testServ
req, err := http.NewRequest("GET", testServ.URL, nil)
test.AssertNotError(t, err, "Failed to create request")
query := make(url.Values)
query.Add("name", "test-domain")
query.Add("type", "257") // CAA
req.URL.RawQuery = query.Encode()
client := new(http.Client)
cpr := CAADistributedResolver{logger: log}
set, err := cpr.queryCAA(context.Background(), testServ.URL+"?name=test-domain", client)
test.AssertNotError(t, err, "queryCAA failed")
test.AssertEquals(t, len(set), 1)
test.AssertEquals(t, set[0].Hdr.Name, "test-domain.")
test.AssertEquals(t, set[0].Hdr.Ttl, uint32(10))
test.AssertEquals(t, set[0].Flag, uint8(0))
test.AssertEquals(t, set[0].Tag, "issue")
test.AssertEquals(t, set[0].Value, "ca.com")
}
func TestLookupCAA(t *testing.T) {
testSrv := httptest.NewServer(http.HandlerFunc(mocks.GPDNSHandler))
// TODO(#1989): Close testServ
cpr := CAADistributedResolver{
logger: log,
Clients: map[string]*http.Client{
"1.1.1.1": new(http.Client),
"2.2.2.2": new(http.Client),
"3.3.3.3": new(http.Client),
},
stats: metrics.NewNoopScope(),
maxFailures: 1,
timeout: time.Second,
URI: testSrv.URL,
}
set, err := cpr.LookupCAA(context.Background(), "test-domain")
test.AssertNotError(t, err, "LookupCAA method failed")
test.AssertEquals(t, len(set), 1)
test.AssertEquals(t, set[0].Hdr.Name, "test-domain.")
test.AssertEquals(t, set[0].Hdr.Ttl, uint32(10))
test.AssertEquals(t, set[0].Flag, uint8(0))
test.AssertEquals(t, set[0].Tag, "issue")
test.AssertEquals(t, set[0].Value, "ca.com")
set, err = cpr.LookupCAA(context.Background(), "break")
test.AssertError(t, err, "LookupCAA should've failed")
test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
set, err = cpr.LookupCAA(context.Background(), "break-rcode")
test.AssertError(t, err, "LookupCAA should've failed")
test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
set, err = cpr.LookupCAA(context.Background(), "break-dns-quorum")
test.AssertError(t, err, "LookupCAA should've failed")
test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
}
type slightlyBrokenHandler struct {
broken bool
mu sync.Mutex
}
func (sbh *slightlyBrokenHandler) Handler(w http.ResponseWriter, r *http.Request) {
sbh.mu.Lock()
defer sbh.mu.Unlock()
if sbh.broken {
w.WriteHeader(400)
return
}
sbh.broken = true
mocks.GPDNSHandler(w, r)
}
func TestHTTPQuorum(t *testing.T) {
sbh := &slightlyBrokenHandler{}
testSrv := httptest.NewServer(http.HandlerFunc(sbh.Handler))
// TODO(#1989): Close testServ
cpr := CAADistributedResolver{
logger: log,
Clients: map[string]*http.Client{
"1.1.1.1": new(http.Client),
"2.2.2.2": new(http.Client),
"3.3.3.3": new(http.Client),
},
stats: metrics.NewNoopScope(),
maxFailures: 1,
timeout: time.Second,
URI: testSrv.URL,
}
set, err := cpr.LookupCAA(context.Background(), "test-domain")
test.AssertError(t, err, "LookupCAA should've failed")
test.Assert(t, set == nil, "LookupCAA returned non-nil CAA set")
}
func TestMarshalCanonicalCAASet(t *testing.T) {
a, b := new(dns.CAA), new(dns.CAA)
a.Value, b.Value = "a", "b"
setA := []*dns.CAA{a, b}
setB := []*dns.CAA{b, a}
canonA, err := marshalCanonicalCAASet(setA)
test.AssertNotError(t, err, "marshalCanonicalCAASet failed")
canonB, err := marshalCanonicalCAASet(setB)
test.AssertNotError(t, err, "marshalCanonicalCAASet failed")
test.Assert(t, bytes.Equal(canonA, canonB), "sets do not match")
cRR := dns.Copy(b)
c := cRR.(*dns.CAA)
c.Value = "c"
c.Hdr.Ttl = 100
hashC, err := marshalCanonicalCAASet([]*dns.CAA{c, a})
test.AssertNotError(t, err, "marshalCanonicalCAASet failed")
test.AssertEquals(t, c.Hdr.Ttl, uint32(100))
test.Assert(t, bytes.Equal(canonA, canonB), fmt.Sprintf("Mismatching sets had same bytes: %x == %x", hashC, canonB))
}