3cb782f0a2
While there, modernize the way in which we run tests to avoid depending on the fake files scattered around the tree and to use some well defined mock structures instead. Part of https://github.com/ooni/probe/issues/1591
178 lines
4.4 KiB
Go
178 lines
4.4 KiB
Go
package dnsx
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"errors"
|
|
"io"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/ooni/probe-cli/v3/internal/engine/httpheader"
|
|
"github.com/ooni/probe-cli/v3/internal/netxlite/mocks"
|
|
)
|
|
|
|
func TestDNSOverHTTPSNewRequestFailure(t *testing.T) {
|
|
const invalidURL = "\t"
|
|
txp := NewDNSOverHTTPS(http.DefaultClient, invalidURL)
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if err == nil || !strings.HasSuffix(err.Error(), "invalid control character in URL") {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSClientDoFailure(t *testing.T) {
|
|
expected := errors.New("mocked error")
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(*http.Request) (*http.Response, error) {
|
|
return nil, expected
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if !errors.Is(err, expected) {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSHTTPFailure(t *testing.T) {
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: 500,
|
|
Body: io.NopCloser(strings.NewReader("")),
|
|
}, nil
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if err == nil || err.Error() != "doh: server returned error" {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSMissingContentType(t *testing.T) {
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: 200,
|
|
Body: io.NopCloser(strings.NewReader("")),
|
|
}, nil
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if err == nil || err.Error() != "doh: invalid content-type" {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSSuccess(t *testing.T) {
|
|
body := []byte("AAA")
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(*http.Request) (*http.Response, error) {
|
|
return &http.Response{
|
|
StatusCode: 200,
|
|
Body: io.NopCloser(bytes.NewReader(body)),
|
|
Header: http.Header{
|
|
"Content-Type": []string{"application/dns-message"},
|
|
},
|
|
}, nil
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !bytes.Equal(data, body) {
|
|
t.Fatal("not the response we expected")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPTransportOK(t *testing.T) {
|
|
const queryURL = "https://cloudflare-dns.com/dns-query"
|
|
txp := NewDNSOverHTTPS(http.DefaultClient, queryURL)
|
|
if txp.Network() != "doh" {
|
|
t.Fatal("invalid network")
|
|
}
|
|
if txp.RequiresPadding() != true {
|
|
t.Fatal("should require padding")
|
|
}
|
|
if txp.Address() != queryURL {
|
|
t.Fatal("invalid address")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSClientSetsUserAgent(t *testing.T) {
|
|
expected := errors.New("mocked error")
|
|
var correct bool
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(req *http.Request) (*http.Response, error) {
|
|
correct = req.Header.Get("User-Agent") == httpheader.UserAgent()
|
|
return nil, expected
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if !errors.Is(err, expected) {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
if !correct {
|
|
t.Fatal("did not see correct user agent")
|
|
}
|
|
}
|
|
|
|
func TestDNSOverHTTPSHostOverride(t *testing.T) {
|
|
var correct bool
|
|
expected := errors.New("mocked error")
|
|
|
|
hostOverride := "test.com"
|
|
txp := &DNSOverHTTPS{
|
|
Client: &mocks.HTTPClient{
|
|
MockDo: func(req *http.Request) (*http.Response, error) {
|
|
correct = req.Host == hostOverride
|
|
return nil, expected
|
|
},
|
|
},
|
|
URL: "https://cloudflare-dns.com/dns-query",
|
|
HostOverride: hostOverride,
|
|
}
|
|
data, err := txp.RoundTrip(context.Background(), nil)
|
|
if !errors.Is(err, expected) {
|
|
t.Fatal("expected an error here")
|
|
}
|
|
if data != nil {
|
|
t.Fatal("expected no response here")
|
|
}
|
|
if !correct {
|
|
t.Fatal("did not see correct host override")
|
|
}
|
|
}
|