ooni-probe-cli/internal/netxlite/dnsovergetaddrinfo_test.go
Simone Basso da1c13e312
cleanup: remove UnderlyingNetworkLibrary and TProxy (#874)
* cleanup: remove UnderlyingNetworkLibrary and TProxy

While there, replace mixture of mocking and real connections inside
quicping with pure mocking of network connections.

Closes https://github.com/ooni/probe/issues/2224

* cleanup: we don't need a SimpleResolver now

This type was only used by UnderlyingNetworkLibrary and all the
rest of the code uses Resolver. So, let's avoid complexity by zapping
the SimpleResolver type and merging it inside Resolver.
2022-08-23 11:43:44 +02:00

190 lines
4.8 KiB
Go

package netxlite
import (
"context"
"errors"
"strings"
"sync"
"testing"
"time"
"github.com/miekg/dns"
)
func TestDNSOverGetaddrinfo(t *testing.T) {
t.Run("RequiresPadding", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
if txp.RequiresPadding() {
t.Fatal("expected false")
}
})
t.Run("Network", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
if txp.Network() != getaddrinfoResolverNetwork() {
t.Fatal("unexpected Network")
}
})
t.Run("Address", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
if txp.Address() != "" {
t.Fatal("unexpected Address")
}
})
t.Run("CloseIdleConnections", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
txp.CloseIdleConnections() // does not crash
})
t.Run("check default timeout", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
if txp.timeout() != 15*time.Second {
t.Fatal("unexpected default timeout")
}
})
t.Run("check default lookup host func not nil", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{}
if txp.lookupfn() == nil {
t.Fatal("expected non-nil func here")
}
})
t.Run("RoundTrip", func(t *testing.T) {
t.Run("with invalid query type", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{
testableLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return []string{"8.8.8.8"}, nil
},
}
encoder := &DNSEncoderMiekg{}
query := encoder.Encode("dns.google", dns.TypeA, false)
ctx := context.Background()
resp, err := txp.RoundTrip(ctx, query)
if !errors.Is(err, ErrNoDNSTransport) {
t.Fatal("unexpected err", err)
}
if resp != nil {
t.Fatal("expected nil resp")
}
})
t.Run("with success", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{
testableLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return []string{"8.8.8.8"}, nil
},
}
encoder := &DNSEncoderMiekg{}
query := encoder.Encode("dns.google", dns.TypeANY, false)
ctx := context.Background()
resp, err := txp.RoundTrip(ctx, query)
if err != nil {
t.Fatal(err)
}
addrs, err := resp.DecodeLookupHost()
if err != nil {
t.Fatal(err)
}
if len(addrs) != 1 || addrs[0] != "8.8.8.8" {
t.Fatal("invalid addrs")
}
if resp.Query() != query {
t.Fatal("invalid query")
}
if len(resp.Bytes()) != 0 {
t.Fatal("invalid response bytes")
}
if resp.Rcode() != 0 {
t.Fatal("invalid rcode")
}
https, err := resp.DecodeHTTPS()
if !errors.Is(err, ErrNoDNSTransport) {
t.Fatal("unexpected err", err)
}
if https != nil {
t.Fatal("expected nil https")
}
ns, err := resp.DecodeNS()
if !errors.Is(err, ErrNoDNSTransport) {
t.Fatal("unexpected err", err)
}
if len(ns) != 0 {
t.Fatal("expected zero-length ns")
}
})
t.Run("with timeout and success", func(t *testing.T) {
wg := &sync.WaitGroup{}
wg.Add(1)
done := make(chan interface{})
txp := &dnsOverGetaddrinfoTransport{
testableTimeout: 1 * time.Microsecond,
testableLookupHost: func(ctx context.Context, domain string) ([]string, error) {
defer wg.Done()
<-done
return []string{"8.8.8.8"}, nil
},
}
encoder := &DNSEncoderMiekg{}
query := encoder.Encode("dns.google", dns.TypeANY, false)
ctx := context.Background()
resp, err := txp.RoundTrip(ctx, query)
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatal("unexpected err", err)
}
if resp != nil {
t.Fatal("invalid resp")
}
close(done)
wg.Wait()
})
t.Run("with timeout and failure", func(t *testing.T) {
wg := &sync.WaitGroup{}
wg.Add(1)
done := make(chan interface{})
txp := &dnsOverGetaddrinfoTransport{
testableTimeout: 1 * time.Microsecond,
testableLookupHost: func(ctx context.Context, domain string) ([]string, error) {
defer wg.Done()
<-done
return nil, errors.New("no such host")
},
}
encoder := &DNSEncoderMiekg{}
query := encoder.Encode("dns.google", dns.TypeANY, false)
ctx := context.Background()
resp, err := txp.RoundTrip(ctx, query)
if !errors.Is(err, context.DeadlineExceeded) {
t.Fatal("not the error we expected", err)
}
if resp != nil {
t.Fatal("invalid resp")
}
close(done)
wg.Wait()
})
t.Run("with NXDOMAIN", func(t *testing.T) {
txp := &dnsOverGetaddrinfoTransport{
testableLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return nil, ErrOODNSNoSuchHost
},
}
encoder := &DNSEncoderMiekg{}
query := encoder.Encode("dns.google", dns.TypeANY, false)
ctx := context.Background()
resp, err := txp.RoundTrip(ctx, query)
if err == nil || !strings.HasSuffix(err.Error(), "no such host") {
t.Fatal("not the error we expected", err)
}
if resp != nil {
t.Fatal("invalid resp")
}
})
})
}