cleanup(netx): remove subpackages and unnecessary code (#788)
This pull request consists of several small and obvious cleanups in the netx directory. See https://github.com/ooni/probe/issues/2121
This commit is contained in:
parent
9354191b85
commit
1cb820b19d
|
@ -1,4 +1,4 @@
|
||||||
package resolver
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
|
@ -1,17 +1,21 @@
|
||||||
package resolver_test
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestCacheFailure(t *testing.T) {
|
func TestCacheResolverFailure(t *testing.T) {
|
||||||
expected := errors.New("mocked error")
|
expected := errors.New("mocked error")
|
||||||
r := resolver.NewFakeResolverWithExplicitError(expected)
|
r := &mocks.Resolver{
|
||||||
cache := &resolver.CacheResolver{Resolver: r}
|
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||||
|
return nil, expected
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cache := &CacheResolver{Resolver: r}
|
||||||
addrs, err := cache.LookupHost(context.Background(), "www.google.com")
|
addrs, err := cache.LookupHost(context.Background(), "www.google.com")
|
||||||
if !errors.Is(err, expected) {
|
if !errors.Is(err, expected) {
|
||||||
t.Fatal("not the error we expected")
|
t.Fatal("not the error we expected")
|
||||||
|
@ -24,10 +28,14 @@ func TestCacheFailure(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCacheHitSuccess(t *testing.T) {
|
func TestCacheResolverHitSuccess(t *testing.T) {
|
||||||
expected := errors.New("mocked error")
|
expected := errors.New("mocked error")
|
||||||
r := resolver.NewFakeResolverWithExplicitError(expected)
|
r := &mocks.Resolver{
|
||||||
cache := &resolver.CacheResolver{Resolver: r}
|
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||||
|
return nil, expected
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cache := &CacheResolver{Resolver: r}
|
||||||
cache.Set("dns.google.com", []string{"8.8.8.8"})
|
cache.Set("dns.google.com", []string{"8.8.8.8"})
|
||||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -38,9 +46,13 @@ func TestCacheHitSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCacheMissSuccess(t *testing.T) {
|
func TestCacheResolverMissSuccess(t *testing.T) {
|
||||||
r := resolver.NewFakeResolverWithResult([]string{"8.8.8.8"})
|
r := &mocks.Resolver{
|
||||||
cache := &resolver.CacheResolver{Resolver: r}
|
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||||
|
return []string{"8.8.8.8"}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cache := &CacheResolver{Resolver: r}
|
||||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -53,9 +65,13 @@ func TestCacheMissSuccess(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCacheReadonlySuccess(t *testing.T) {
|
func TestCacheResolverReadonlySuccess(t *testing.T) {
|
||||||
r := resolver.NewFakeResolverWithResult([]string{"8.8.8.8"})
|
r := &mocks.Resolver{
|
||||||
cache := &resolver.CacheResolver{Resolver: r, ReadOnly: true}
|
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
||||||
|
return []string{"8.8.8.8"}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
cache := &CacheResolver{Resolver: r, ReadOnly: true}
|
||||||
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
addrs, err := cache.LookupHost(context.Background(), "dns.google.com")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
|
@ -1,7 +1,4 @@
|
||||||
// Package dialer allows you to create a net.Dialer-compatible
|
package netx
|
||||||
// DialContext-enabled dialer with error wrapping, optional logging,
|
|
||||||
// optional network-events saving, and optional proxying.
|
|
||||||
package dialer
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -12,8 +9,8 @@ import (
|
||||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config contains the settings for New.
|
// dialerConfig contains the settings for New.
|
||||||
type Config struct {
|
type dialerConfig struct {
|
||||||
// ContextByteCounting optionally configures context-based
|
// ContextByteCounting optionally configures context-based
|
||||||
// byte counting. By default we don't do that.
|
// byte counting. By default we don't do that.
|
||||||
//
|
//
|
||||||
|
@ -48,8 +45,8 @@ type Config struct {
|
||||||
ReadWriteSaver *tracex.Saver
|
ReadWriteSaver *tracex.Saver
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Dialer from the specified config and resolver.
|
// newDialer creates a new Dialer from the specified config and resolver.
|
||||||
func New(config *Config, resolver model.Resolver) model.Dialer {
|
func newDialer(config *dialerConfig, resolver model.Resolver) model.Dialer {
|
||||||
var logger model.DebugLogger = model.DiscardLogger
|
var logger model.DebugLogger = model.DiscardLogger
|
||||||
if config.Logger != nil {
|
if config.Logger != nil {
|
||||||
logger = config.Logger
|
logger = config.Logger
|
|
@ -1,4 +1,4 @@
|
||||||
package dialer
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -13,7 +13,7 @@ import (
|
||||||
|
|
||||||
func TestNewCreatesTheExpectedChain(t *testing.T) {
|
func TestNewCreatesTheExpectedChain(t *testing.T) {
|
||||||
saver := &tracex.Saver{}
|
saver := &tracex.Saver{}
|
||||||
dlr := New(&Config{
|
dlr := newDialer(&dialerConfig{
|
||||||
ContextByteCounting: true,
|
ContextByteCounting: true,
|
||||||
DialSaver: saver,
|
DialSaver: saver,
|
||||||
Logger: log.Log,
|
Logger: log.Log,
|
||||||
|
@ -37,7 +37,7 @@ func TestDialerNewSuccess(t *testing.T) {
|
||||||
t.Skip("skip test in short mode")
|
t.Skip("skip test in short mode")
|
||||||
}
|
}
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
d := New(&Config{Logger: log.Log}, netxlite.DefaultResolver)
|
d := newDialer(&dialerConfig{Logger: log.Log}, netxlite.DefaultResolver)
|
||||||
txp := &http.Transport{DialContext: d.DialContext}
|
txp := &http.Transport{DialContext: d.DialContext}
|
||||||
client := &http.Client{Transport: txp}
|
client := &http.Client{Transport: txp}
|
||||||
resp, err := client.Get("http://www.google.com")
|
resp, err := client.Get("http://www.google.com")
|
|
@ -1,59 +0,0 @@
|
||||||
package netx
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FakeDialer struct {
|
|
||||||
Conn net.Conn
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return d.Conn, d.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d FakeDialer) CloseIdleConnections() {}
|
|
||||||
|
|
||||||
type FakeTransport struct {
|
|
||||||
Err error
|
|
||||||
Func func(*http.Request) (*http.Response, error)
|
|
||||||
Resp *http.Response
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txp FakeTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
if txp.Func != nil {
|
|
||||||
return txp.Func(req)
|
|
||||||
}
|
|
||||||
if req.Body != nil {
|
|
||||||
netxlite.ReadAllContext(req.Context(), req.Body)
|
|
||||||
req.Body.Close()
|
|
||||||
}
|
|
||||||
if txp.Err != nil {
|
|
||||||
return nil, txp.Err
|
|
||||||
}
|
|
||||||
txp.Resp.Request = req // non thread safe but it doesn't matter
|
|
||||||
return txp.Resp, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (txp FakeTransport) CloseIdleConnections() {}
|
|
||||||
|
|
||||||
type FakeBody struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fb FakeBody) Read(p []byte) (int, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return 0, fb.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (fb FakeBody) Close() error {
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,5 +1,4 @@
|
||||||
// Package httptransport contains HTTP transport extensions.
|
package netx
|
||||||
package httptransport
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
|
@ -8,32 +7,32 @@ import (
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config contains the configuration required for constructing an HTTP transport
|
// httpTransportConfig contains the configuration required for constructing an HTTP transport
|
||||||
type Config struct {
|
type httpTransportConfig struct {
|
||||||
Dialer model.Dialer
|
Dialer model.Dialer
|
||||||
QUICDialer model.QUICDialer
|
QUICDialer model.QUICDialer
|
||||||
TLSDialer model.TLSDialer
|
TLSDialer model.TLSDialer
|
||||||
TLSConfig *tls.Config
|
TLSConfig *tls.Config
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHTTP3Transport creates a new HTTP3Transport instance.
|
// newHTTP3Transport creates a new HTTP3Transport instance.
|
||||||
//
|
//
|
||||||
// Deprecation warning
|
// Deprecation warning
|
||||||
//
|
//
|
||||||
// New code should use netxlite.NewHTTP3Transport instead.
|
// New code should use netxlite.NewHTTP3Transport instead.
|
||||||
func NewHTTP3Transport(config Config) model.HTTPTransport {
|
func newHTTP3Transport(config httpTransportConfig) model.HTTPTransport {
|
||||||
// Rationale for using NoLogger here: previously this code did
|
// Rationale for using NoLogger here: previously this code did
|
||||||
// not use a logger as well, so it's fine to keep it as is.
|
// not use a logger as well, so it's fine to keep it as is.
|
||||||
return netxlite.NewHTTP3Transport(model.DiscardLogger,
|
return netxlite.NewHTTP3Transport(model.DiscardLogger,
|
||||||
config.QUICDialer, config.TLSConfig)
|
config.QUICDialer, config.TLSConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSystemTransport creates a new "system" HTTP transport. That is a transport
|
// newSystemTransport creates a new "system" HTTP transport. That is a transport
|
||||||
// using the Go standard library with custom dialer and TLS dialer.
|
// using the Go standard library with custom dialer and TLS dialer.
|
||||||
//
|
//
|
||||||
// Deprecation warning
|
// Deprecation warning
|
||||||
//
|
//
|
||||||
// New code should use netxlite.NewHTTPTransport instead.
|
// New code should use netxlite.NewHTTPTransport instead.
|
||||||
func NewSystemTransport(config Config) model.HTTPTransport {
|
func newSystemTransport(config httpTransportConfig) model.HTTPTransport {
|
||||||
return netxlite.NewOOHTTPBaseTransport(config.Dialer, config.TLSDialer)
|
return netxlite.NewOOHTTPBaseTransport(config.Dialer, config.TLSDialer)
|
||||||
}
|
}
|
|
@ -1,89 +0,0 @@
|
||||||
package netx_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/apex/log"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSuccess(t *testing.T) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("skip test in short mode")
|
|
||||||
}
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
counter := bytecounter.New()
|
|
||||||
config := netx.Config{
|
|
||||||
BogonIsError: true,
|
|
||||||
ByteCounter: counter,
|
|
||||||
CacheResolutions: true,
|
|
||||||
ContextByteCounting: true,
|
|
||||||
DialSaver: &tracex.Saver{},
|
|
||||||
HTTPSaver: &tracex.Saver{},
|
|
||||||
Logger: log.Log,
|
|
||||||
ReadWriteSaver: &tracex.Saver{},
|
|
||||||
ResolveSaver: &tracex.Saver{},
|
|
||||||
TLSSaver: &tracex.Saver{},
|
|
||||||
}
|
|
||||||
txp := netx.NewHTTPTransport(config)
|
|
||||||
client := &http.Client{Transport: txp}
|
|
||||||
resp, err := client.Get("https://www.google.com")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if _, err = netxlite.ReadAllContext(context.Background(), resp.Body); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if err = resp.Body.Close(); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if counter.Sent.Load() <= 0 {
|
|
||||||
t.Fatal("no bytes sent?!")
|
|
||||||
}
|
|
||||||
if counter.Received.Load() <= 0 {
|
|
||||||
t.Fatal("no bytes received?!")
|
|
||||||
}
|
|
||||||
if ev := config.DialSaver.Read(); len(ev) <= 0 {
|
|
||||||
t.Fatal("no dial events?!")
|
|
||||||
}
|
|
||||||
if ev := config.HTTPSaver.Read(); len(ev) <= 0 {
|
|
||||||
t.Fatal("no HTTP events?!")
|
|
||||||
}
|
|
||||||
if ev := config.ReadWriteSaver.Read(); len(ev) <= 0 {
|
|
||||||
t.Fatal("no R/W events?!")
|
|
||||||
}
|
|
||||||
if ev := config.ResolveSaver.Read(); len(ev) <= 0 {
|
|
||||||
t.Fatal("no resolver events?!")
|
|
||||||
}
|
|
||||||
if ev := config.TLSSaver.Read(); len(ev) <= 0 {
|
|
||||||
t.Fatal("no TLS events?!")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBogonResolutionNotBroken(t *testing.T) {
|
|
||||||
saver := new(tracex.Saver)
|
|
||||||
r := netx.NewResolver(netx.Config{
|
|
||||||
BogonIsError: true,
|
|
||||||
DNSCache: map[string][]string{
|
|
||||||
"www.google.com": {"127.0.0.1"},
|
|
||||||
},
|
|
||||||
ResolveSaver: saver,
|
|
||||||
Logger: log.Log,
|
|
||||||
})
|
|
||||||
addrs, err := r.LookupHost(context.Background(), "www.google.com")
|
|
||||||
if !errors.Is(err, netxlite.ErrDNSBogon) {
|
|
||||||
t.Fatal("not the error we expected")
|
|
||||||
}
|
|
||||||
if err.Error() != netxlite.FailureDNSBogonError {
|
|
||||||
t.Fatal("error not correctly wrapped")
|
|
||||||
}
|
|
||||||
if len(addrs) > 0 {
|
|
||||||
t.Fatal("expected no addresses here")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -31,9 +31,6 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/httptransport"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/model"
|
"github.com/ooni/probe-cli/v3/internal/model"
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||||
|
@ -85,10 +82,10 @@ func NewResolver(config Config) model.Resolver {
|
||||||
Resolver: r,
|
Resolver: r,
|
||||||
}
|
}
|
||||||
if config.CacheResolutions {
|
if config.CacheResolutions {
|
||||||
r = &resolver.CacheResolver{Resolver: r}
|
r = &CacheResolver{Resolver: r}
|
||||||
}
|
}
|
||||||
if config.DNSCache != nil {
|
if config.DNSCache != nil {
|
||||||
cache := &resolver.CacheResolver{Resolver: r, ReadOnly: true}
|
cache := &CacheResolver{Resolver: r, ReadOnly: true}
|
||||||
for key, values := range config.DNSCache {
|
for key, values := range config.DNSCache {
|
||||||
cache.Set(key, values)
|
cache.Set(key, values)
|
||||||
}
|
}
|
||||||
|
@ -113,7 +110,7 @@ func NewDialer(config Config) model.Dialer {
|
||||||
if config.FullResolver == nil {
|
if config.FullResolver == nil {
|
||||||
config.FullResolver = NewResolver(config)
|
config.FullResolver = NewResolver(config)
|
||||||
}
|
}
|
||||||
return dialer.New(&dialer.Config{
|
return newDialer(&dialerConfig{
|
||||||
ContextByteCounting: config.ContextByteCounting,
|
ContextByteCounting: config.ContextByteCounting,
|
||||||
DialSaver: config.DialSaver,
|
DialSaver: config.DialSaver,
|
||||||
Logger: config.Logger,
|
Logger: config.Logger,
|
||||||
|
@ -175,7 +172,7 @@ func NewHTTPTransport(config Config) model.HTTPTransport {
|
||||||
}
|
}
|
||||||
|
|
||||||
tInfo := allTransportsInfo[config.HTTP3Enabled]
|
tInfo := allTransportsInfo[config.HTTP3Enabled]
|
||||||
txp := tInfo.Factory(httptransport.Config{
|
txp := tInfo.Factory(httpTransportConfig{
|
||||||
Dialer: config.Dialer, QUICDialer: config.QUICDialer, TLSDialer: config.TLSDialer,
|
Dialer: config.Dialer, QUICDialer: config.QUICDialer, TLSDialer: config.TLSDialer,
|
||||||
TLSConfig: config.TLSConfig})
|
TLSConfig: config.TLSConfig})
|
||||||
|
|
||||||
|
@ -195,17 +192,17 @@ func NewHTTPTransport(config Config) model.HTTPTransport {
|
||||||
|
|
||||||
// httpTransportInfo contains the constructing function as well as the transport name
|
// httpTransportInfo contains the constructing function as well as the transport name
|
||||||
type httpTransportInfo struct {
|
type httpTransportInfo struct {
|
||||||
Factory func(httptransport.Config) model.HTTPTransport
|
Factory func(httpTransportConfig) model.HTTPTransport
|
||||||
TransportName string
|
TransportName string
|
||||||
}
|
}
|
||||||
|
|
||||||
var allTransportsInfo = map[bool]httpTransportInfo{
|
var allTransportsInfo = map[bool]httpTransportInfo{
|
||||||
false: {
|
false: {
|
||||||
Factory: httptransport.NewSystemTransport,
|
Factory: newSystemTransport,
|
||||||
TransportName: "tcp",
|
TransportName: "tcp",
|
||||||
},
|
},
|
||||||
true: {
|
true: {
|
||||||
Factory: httptransport.NewHTTP3Transport,
|
Factory: newHTTP3Transport,
|
||||||
TransportName: "quic",
|
TransportName: "quic",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
package netx
|
|
||||||
|
|
||||||
import "crypto/x509"
|
|
||||||
|
|
||||||
// DefaultCertPool allows tests to access the default cert pool.
|
|
||||||
func DefaultCertPool() *x509.CertPool {
|
|
||||||
return defaultCertPool
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
package netx_test
|
package netx
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -11,15 +11,13 @@ import (
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
"github.com/ooni/probe-cli/v3/internal/bytecounter"
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
||||||
"github.com/ooni/probe-cli/v3/internal/tracex"
|
"github.com/ooni/probe-cli/v3/internal/tracex"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestNewResolverVanilla(t *testing.T) {
|
func TestNewResolverVanilla(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{})
|
r := NewResolver(Config{})
|
||||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the resolver we expected")
|
t.Fatal("not the resolver we expected")
|
||||||
|
@ -39,7 +37,7 @@ func TestNewResolverVanilla(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewResolverSpecificResolver(t *testing.T) {
|
func TestNewResolverSpecificResolver(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
BaseResolver: &netxlite.BogonResolver{
|
BaseResolver: &netxlite.BogonResolver{
|
||||||
// not initialized because it doesn't matter in this context
|
// not initialized because it doesn't matter in this context
|
||||||
},
|
},
|
||||||
|
@ -63,7 +61,7 @@ func TestNewResolverSpecificResolver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewResolverWithBogonFilter(t *testing.T) {
|
func TestNewResolverWithBogonFilter(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
BogonIsError: true,
|
BogonIsError: true,
|
||||||
})
|
})
|
||||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||||
|
@ -89,7 +87,7 @@ func TestNewResolverWithBogonFilter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewResolverWithLogging(t *testing.T) {
|
func TestNewResolverWithLogging(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
Logger: log.Log,
|
Logger: log.Log,
|
||||||
})
|
})
|
||||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||||
|
@ -119,7 +117,7 @@ func TestNewResolverWithLogging(t *testing.T) {
|
||||||
|
|
||||||
func TestNewResolverWithSaver(t *testing.T) {
|
func TestNewResolverWithSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
ResolveSaver: saver,
|
ResolveSaver: saver,
|
||||||
})
|
})
|
||||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||||
|
@ -148,7 +146,7 @@ func TestNewResolverWithSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewResolverWithReadWriteCache(t *testing.T) {
|
func TestNewResolverWithReadWriteCache(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
CacheResolutions: true,
|
CacheResolutions: true,
|
||||||
})
|
})
|
||||||
ir, ok := r.(*netxlite.ResolverIDNA)
|
ir, ok := r.(*netxlite.ResolverIDNA)
|
||||||
|
@ -159,7 +157,7 @@ func TestNewResolverWithReadWriteCache(t *testing.T) {
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the resolver we expected")
|
t.Fatal("not the resolver we expected")
|
||||||
}
|
}
|
||||||
cr, ok := ewr.Resolver.(*resolver.CacheResolver)
|
cr, ok := ewr.Resolver.(*CacheResolver)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the resolver we expected")
|
t.Fatal("not the resolver we expected")
|
||||||
}
|
}
|
||||||
|
@ -177,7 +175,7 @@ func TestNewResolverWithReadWriteCache(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
||||||
r := netx.NewResolver(netx.Config{
|
r := NewResolver(Config{
|
||||||
DNSCache: map[string][]string{
|
DNSCache: map[string][]string{
|
||||||
"dns.google.com": {"8.8.8.8"},
|
"dns.google.com": {"8.8.8.8"},
|
||||||
},
|
},
|
||||||
|
@ -190,7 +188,7 @@ func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the resolver we expected")
|
t.Fatal("not the resolver we expected")
|
||||||
}
|
}
|
||||||
cr, ok := ewr.Resolver.(*resolver.CacheResolver)
|
cr, ok := ewr.Resolver.(*CacheResolver)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the resolver we expected")
|
t.Fatal("not the resolver we expected")
|
||||||
}
|
}
|
||||||
|
@ -211,7 +209,7 @@ func TestNewResolverWithPrefilledReadonlyCache(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTLSDialerVanilla(t *testing.T) {
|
func TestNewTLSDialerVanilla(t *testing.T) {
|
||||||
td := netx.NewTLSDialer(netx.Config{})
|
td := NewTLSDialer(Config{})
|
||||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Fatal("not the TLSDialer we expected")
|
t.Fatal("not the TLSDialer we expected")
|
||||||
|
@ -222,7 +220,7 @@ func TestNewTLSDialerVanilla(t *testing.T) {
|
||||||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||||
t.Fatal("invalid Config.NextProtos")
|
t.Fatal("invalid Config.NextProtos")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -241,7 +239,7 @@ func TestNewTLSDialerVanilla(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTLSDialerWithConfig(t *testing.T) {
|
func TestNewTLSDialerWithConfig(t *testing.T) {
|
||||||
td := netx.NewTLSDialer(netx.Config{
|
td := NewTLSDialer(Config{
|
||||||
TLSConfig: new(tls.Config),
|
TLSConfig: new(tls.Config),
|
||||||
})
|
})
|
||||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||||
|
@ -251,7 +249,7 @@ func TestNewTLSDialerWithConfig(t *testing.T) {
|
||||||
if len(rtd.Config.NextProtos) != 0 {
|
if len(rtd.Config.NextProtos) != 0 {
|
||||||
t.Fatal("invalid len(config.NextProtos)")
|
t.Fatal("invalid len(config.NextProtos)")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -270,7 +268,7 @@ func TestNewTLSDialerWithConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTLSDialerWithLogging(t *testing.T) {
|
func TestNewTLSDialerWithLogging(t *testing.T) {
|
||||||
td := netx.NewTLSDialer(netx.Config{
|
td := NewTLSDialer(Config{
|
||||||
Logger: log.Log,
|
Logger: log.Log,
|
||||||
})
|
})
|
||||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||||
|
@ -283,7 +281,7 @@ func TestNewTLSDialerWithLogging(t *testing.T) {
|
||||||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||||
t.Fatal("invalid Config.NextProtos")
|
t.Fatal("invalid Config.NextProtos")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -310,7 +308,7 @@ func TestNewTLSDialerWithLogging(t *testing.T) {
|
||||||
|
|
||||||
func TestNewTLSDialerWithSaver(t *testing.T) {
|
func TestNewTLSDialerWithSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
td := netx.NewTLSDialer(netx.Config{
|
td := NewTLSDialer(Config{
|
||||||
TLSSaver: saver,
|
TLSSaver: saver,
|
||||||
})
|
})
|
||||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||||
|
@ -323,7 +321,7 @@ func TestNewTLSDialerWithSaver(t *testing.T) {
|
||||||
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
if rtd.Config.NextProtos[0] != "h2" || rtd.Config.NextProtos[1] != "http/1.1" {
|
||||||
t.Fatal("invalid Config.NextProtos")
|
t.Fatal("invalid Config.NextProtos")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -349,7 +347,7 @@ func TestNewTLSDialerWithSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
||||||
td := netx.NewTLSDialer(netx.Config{
|
td := NewTLSDialer(Config{
|
||||||
TLSConfig: new(tls.Config),
|
TLSConfig: new(tls.Config),
|
||||||
NoTLSVerify: true,
|
NoTLSVerify: true,
|
||||||
})
|
})
|
||||||
|
@ -363,7 +361,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
||||||
if rtd.Config.InsecureSkipVerify != true {
|
if rtd.Config.InsecureSkipVerify != true {
|
||||||
t.Fatal("expected true InsecureSkipVerify")
|
t.Fatal("expected true InsecureSkipVerify")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -382,7 +380,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
||||||
td := netx.NewTLSDialer(netx.Config{
|
td := NewTLSDialer(Config{
|
||||||
NoTLSVerify: true,
|
NoTLSVerify: true,
|
||||||
})
|
})
|
||||||
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
rtd, ok := td.(*netxlite.TLSDialerLegacy)
|
||||||
|
@ -398,7 +396,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
||||||
if rtd.Config.InsecureSkipVerify != true {
|
if rtd.Config.InsecureSkipVerify != true {
|
||||||
t.Fatal("expected true InsecureSkipVerify")
|
t.Fatal("expected true InsecureSkipVerify")
|
||||||
}
|
}
|
||||||
if rtd.Config.RootCAs != netx.DefaultCertPool() {
|
if rtd.Config.RootCAs != defaultCertPool {
|
||||||
t.Fatal("invalid Config.RootCAs")
|
t.Fatal("invalid Config.RootCAs")
|
||||||
}
|
}
|
||||||
if rtd.Dialer == nil {
|
if rtd.Dialer == nil {
|
||||||
|
@ -417,7 +415,7 @@ func TestNewTLSDialerWithNoTLSVerifyAndNoConfig(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewVanilla(t *testing.T) {
|
func TestNewVanilla(t *testing.T) {
|
||||||
txp := netx.NewHTTPTransport(netx.Config{})
|
txp := NewHTTPTransport(Config{})
|
||||||
if _, ok := txp.(*netxlite.HTTPTransportWrapper); !ok {
|
if _, ok := txp.(*netxlite.HTTPTransportWrapper); !ok {
|
||||||
t.Fatal("not the transport we expected")
|
t.Fatal("not the transport we expected")
|
||||||
}
|
}
|
||||||
|
@ -425,8 +423,12 @@ func TestNewVanilla(t *testing.T) {
|
||||||
|
|
||||||
func TestNewWithDialer(t *testing.T) {
|
func TestNewWithDialer(t *testing.T) {
|
||||||
expected := errors.New("mocked error")
|
expected := errors.New("mocked error")
|
||||||
dialer := netx.FakeDialer{Err: expected}
|
dialer := &mocks.Dialer{
|
||||||
txp := netx.NewHTTPTransport(netx.Config{
|
MockDialContext: func(ctx context.Context, network, address string) (net.Conn, error) {
|
||||||
|
return nil, expected
|
||||||
|
},
|
||||||
|
}
|
||||||
|
txp := NewHTTPTransport(Config{
|
||||||
Dialer: dialer,
|
Dialer: dialer,
|
||||||
})
|
})
|
||||||
client := &http.Client{Transport: txp}
|
client := &http.Client{Transport: txp}
|
||||||
|
@ -453,7 +455,7 @@ func TestNewWithTLSDialer(t *testing.T) {
|
||||||
},
|
},
|
||||||
TLSHandshaker: &netxlite.TLSHandshakerConfigurable{},
|
TLSHandshaker: &netxlite.TLSHandshakerConfigurable{},
|
||||||
}
|
}
|
||||||
txp := netx.NewHTTPTransport(netx.Config{
|
txp := NewHTTPTransport(Config{
|
||||||
TLSDialer: tlsDialer,
|
TLSDialer: tlsDialer,
|
||||||
})
|
})
|
||||||
client := &http.Client{Transport: txp}
|
client := &http.Client{Transport: txp}
|
||||||
|
@ -468,7 +470,7 @@ func TestNewWithTLSDialer(t *testing.T) {
|
||||||
|
|
||||||
func TestNewWithByteCounter(t *testing.T) {
|
func TestNewWithByteCounter(t *testing.T) {
|
||||||
counter := bytecounter.New()
|
counter := bytecounter.New()
|
||||||
txp := netx.NewHTTPTransport(netx.Config{
|
txp := NewHTTPTransport(Config{
|
||||||
ByteCounter: counter,
|
ByteCounter: counter,
|
||||||
})
|
})
|
||||||
bctxp, ok := txp.(*bytecounter.HTTPTransport)
|
bctxp, ok := txp.(*bytecounter.HTTPTransport)
|
||||||
|
@ -484,7 +486,7 @@ func TestNewWithByteCounter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewWithLogger(t *testing.T) {
|
func TestNewWithLogger(t *testing.T) {
|
||||||
txp := netx.NewHTTPTransport(netx.Config{
|
txp := NewHTTPTransport(Config{
|
||||||
Logger: log.Log,
|
Logger: log.Log,
|
||||||
})
|
})
|
||||||
ltxp, ok := txp.(*netxlite.HTTPTransportLogger)
|
ltxp, ok := txp.(*netxlite.HTTPTransportLogger)
|
||||||
|
@ -501,7 +503,7 @@ func TestNewWithLogger(t *testing.T) {
|
||||||
|
|
||||||
func TestNewWithSaver(t *testing.T) {
|
func TestNewWithSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
txp := netx.NewHTTPTransport(netx.Config{
|
txp := NewHTTPTransport(Config{
|
||||||
HTTPSaver: saver,
|
HTTPSaver: saver,
|
||||||
})
|
})
|
||||||
stxptxp, ok := txp.(*tracex.HTTPTransportSaver)
|
stxptxp, ok := txp.(*tracex.HTTPTransportSaver)
|
||||||
|
@ -520,7 +522,7 @@ func TestNewWithSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientInvalidURL(t *testing.T) {
|
func TestNewDNSClientInvalidURL(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(netx.Config{}, "\t\t\t")
|
dnsclient, err := NewDNSClient(Config{}, "\t\t\t")
|
||||||
if err == nil || !strings.HasSuffix(err.Error(), "invalid control character in URL") {
|
if err == nil || !strings.HasSuffix(err.Error(), "invalid control character in URL") {
|
||||||
t.Fatal("not the error we expected")
|
t.Fatal("not the error we expected")
|
||||||
}
|
}
|
||||||
|
@ -530,7 +532,7 @@ func TestNewDNSClientInvalidURL(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientUnsupportedScheme(t *testing.T) {
|
func TestNewDNSClientUnsupportedScheme(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(netx.Config{}, "antani:///")
|
dnsclient, err := NewDNSClient(Config{}, "antani:///")
|
||||||
if err == nil || err.Error() != "unsupported resolver scheme" {
|
if err == nil || err.Error() != "unsupported resolver scheme" {
|
||||||
t.Fatal("not the error we expected")
|
t.Fatal("not the error we expected")
|
||||||
}
|
}
|
||||||
|
@ -540,8 +542,8 @@ func TestNewDNSClientUnsupportedScheme(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientSystemResolver(t *testing.T) {
|
func TestNewDNSClientSystemResolver(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "system:///")
|
Config{}, "system:///")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -552,8 +554,8 @@ func TestNewDNSClientSystemResolver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientEmpty(t *testing.T) {
|
func TestNewDNSClientEmpty(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "")
|
Config{}, "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -564,8 +566,8 @@ func TestNewDNSClientEmpty(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientPowerdnsDoH(t *testing.T) {
|
func TestNewDNSClientPowerdnsDoH(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "doh://powerdns")
|
Config{}, "doh://powerdns")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -580,8 +582,8 @@ func TestNewDNSClientPowerdnsDoH(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientGoogleDoH(t *testing.T) {
|
func TestNewDNSClientGoogleDoH(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "doh://google")
|
Config{}, "doh://google")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -596,8 +598,8 @@ func TestNewDNSClientGoogleDoH(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientCloudflareDoH(t *testing.T) {
|
func TestNewDNSClientCloudflareDoH(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "doh://cloudflare")
|
Config{}, "doh://cloudflare")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -613,8 +615,8 @@ func TestNewDNSClientCloudflareDoH(t *testing.T) {
|
||||||
|
|
||||||
func TestNewDNSClientCloudflareDoHSaver(t *testing.T) {
|
func TestNewDNSClientCloudflareDoHSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{ResolveSaver: saver}, "doh://cloudflare")
|
Config{ResolveSaver: saver}, "doh://cloudflare")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -633,8 +635,8 @@ func TestNewDNSClientCloudflareDoHSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientUDP(t *testing.T) {
|
func TestNewDNSClientUDP(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "udp://8.8.8.8:53")
|
Config{}, "udp://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -650,8 +652,8 @@ func TestNewDNSClientUDP(t *testing.T) {
|
||||||
|
|
||||||
func TestNewDNSClientUDPDNSSaver(t *testing.T) {
|
func TestNewDNSClientUDPDNSSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{ResolveSaver: saver}, "udp://8.8.8.8:53")
|
Config{ResolveSaver: saver}, "udp://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -670,8 +672,8 @@ func TestNewDNSClientUDPDNSSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientTCP(t *testing.T) {
|
func TestNewDNSClientTCP(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "tcp://8.8.8.8:53")
|
Config{}, "tcp://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -691,8 +693,8 @@ func TestNewDNSClientTCP(t *testing.T) {
|
||||||
|
|
||||||
func TestNewDNSClientTCPDNSSaver(t *testing.T) {
|
func TestNewDNSClientTCPDNSSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{ResolveSaver: saver}, "tcp://8.8.8.8:53")
|
Config{ResolveSaver: saver}, "tcp://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -715,8 +717,8 @@ func TestNewDNSClientTCPDNSSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientDoT(t *testing.T) {
|
func TestNewDNSClientDoT(t *testing.T) {
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{}, "dot://8.8.8.8:53")
|
Config{}, "dot://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -736,8 +738,8 @@ func TestNewDNSClientDoT(t *testing.T) {
|
||||||
|
|
||||||
func TestNewDNSClientDoTDNSSaver(t *testing.T) {
|
func TestNewDNSClientDoTDNSSaver(t *testing.T) {
|
||||||
saver := new(tracex.Saver)
|
saver := new(tracex.Saver)
|
||||||
dnsclient, err := netx.NewDNSClient(
|
dnsclient, err := NewDNSClient(
|
||||||
netx.Config{ResolveSaver: saver}, "dot://8.8.8.8:53")
|
Config{ResolveSaver: saver}, "dot://8.8.8.8:53")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -760,8 +762,8 @@ func TestNewDNSClientDoTDNSSaver(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSCLientDoTWithoutPort(t *testing.T) {
|
func TestNewDNSCLientDoTWithoutPort(t *testing.T) {
|
||||||
c, err := netx.NewDNSClientWithOverrides(
|
c, err := NewDNSClientWithOverrides(
|
||||||
netx.Config{}, "dot://8.8.8.8", "", "8.8.8.8", "")
|
Config{}, "dot://8.8.8.8", "", "8.8.8.8", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -771,8 +773,8 @@ func TestNewDNSCLientDoTWithoutPort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSCLientTCPWithoutPort(t *testing.T) {
|
func TestNewDNSCLientTCPWithoutPort(t *testing.T) {
|
||||||
c, err := netx.NewDNSClientWithOverrides(
|
c, err := NewDNSClientWithOverrides(
|
||||||
netx.Config{}, "tcp://8.8.8.8", "", "8.8.8.8", "")
|
Config{}, "tcp://8.8.8.8", "", "8.8.8.8", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -782,8 +784,8 @@ func TestNewDNSCLientTCPWithoutPort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSCLientUDPWithoutPort(t *testing.T) {
|
func TestNewDNSCLientUDPWithoutPort(t *testing.T) {
|
||||||
c, err := netx.NewDNSClientWithOverrides(
|
c, err := NewDNSClientWithOverrides(
|
||||||
netx.Config{}, "udp://8.8.8.8", "", "8.8.8.8", "")
|
Config{}, "udp://8.8.8.8", "", "8.8.8.8", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -793,33 +795,108 @@ func TestNewDNSCLientUDPWithoutPort(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientBadDoTEndpoint(t *testing.T) {
|
func TestNewDNSClientBadDoTEndpoint(t *testing.T) {
|
||||||
_, err := netx.NewDNSClient(
|
_, err := NewDNSClient(
|
||||||
netx.Config{}, "dot://bad:endpoint:53")
|
Config{}, "dot://bad:endpoint:53")
|
||||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||||
t.Fatal("expected error with bad endpoint")
|
t.Fatal("expected error with bad endpoint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientBadTCPEndpoint(t *testing.T) {
|
func TestNewDNSClientBadTCPEndpoint(t *testing.T) {
|
||||||
_, err := netx.NewDNSClient(
|
_, err := NewDNSClient(
|
||||||
netx.Config{}, "tcp://bad:endpoint:853")
|
Config{}, "tcp://bad:endpoint:853")
|
||||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||||
t.Fatal("expected error with bad endpoint")
|
t.Fatal("expected error with bad endpoint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSClientBadUDPEndpoint(t *testing.T) {
|
func TestNewDNSClientBadUDPEndpoint(t *testing.T) {
|
||||||
_, err := netx.NewDNSClient(
|
_, err := NewDNSClient(
|
||||||
netx.Config{}, "udp://bad:endpoint:853")
|
Config{}, "udp://bad:endpoint:853")
|
||||||
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
if err == nil || !strings.Contains(err.Error(), "too many colons in address") {
|
||||||
t.Fatal("expected error with bad endpoint")
|
t.Fatal("expected error with bad endpoint")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNewDNSCLientWithInvalidTLSVersion(t *testing.T) {
|
func TestNewDNSCLientWithInvalidTLSVersion(t *testing.T) {
|
||||||
_, err := netx.NewDNSClientWithOverrides(
|
_, err := NewDNSClientWithOverrides(
|
||||||
netx.Config{}, "dot://8.8.8.8", "", "", "TLSv999")
|
Config{}, "dot://8.8.8.8", "", "", "TLSv999")
|
||||||
if !errors.Is(err, netxlite.ErrInvalidTLSVersion) {
|
if !errors.Is(err, netxlite.ErrInvalidTLSVersion) {
|
||||||
t.Fatalf("not the error we expected: %+v", err)
|
t.Fatalf("not the error we expected: %+v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSuccess(t *testing.T) {
|
||||||
|
if testing.Short() {
|
||||||
|
t.Skip("skip test in short mode")
|
||||||
|
}
|
||||||
|
log.SetLevel(log.DebugLevel)
|
||||||
|
counter := bytecounter.New()
|
||||||
|
config := Config{
|
||||||
|
BogonIsError: true,
|
||||||
|
ByteCounter: counter,
|
||||||
|
CacheResolutions: true,
|
||||||
|
ContextByteCounting: true,
|
||||||
|
DialSaver: &tracex.Saver{},
|
||||||
|
HTTPSaver: &tracex.Saver{},
|
||||||
|
Logger: log.Log,
|
||||||
|
ReadWriteSaver: &tracex.Saver{},
|
||||||
|
ResolveSaver: &tracex.Saver{},
|
||||||
|
TLSSaver: &tracex.Saver{},
|
||||||
|
}
|
||||||
|
txp := NewHTTPTransport(config)
|
||||||
|
client := &http.Client{Transport: txp}
|
||||||
|
resp, err := client.Get("https://www.google.com")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err = netxlite.ReadAllContext(context.Background(), resp.Body); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err = resp.Body.Close(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if counter.Sent.Load() <= 0 {
|
||||||
|
t.Fatal("no bytes sent?!")
|
||||||
|
}
|
||||||
|
if counter.Received.Load() <= 0 {
|
||||||
|
t.Fatal("no bytes received?!")
|
||||||
|
}
|
||||||
|
if ev := config.DialSaver.Read(); len(ev) <= 0 {
|
||||||
|
t.Fatal("no dial events?!")
|
||||||
|
}
|
||||||
|
if ev := config.HTTPSaver.Read(); len(ev) <= 0 {
|
||||||
|
t.Fatal("no HTTP events?!")
|
||||||
|
}
|
||||||
|
if ev := config.ReadWriteSaver.Read(); len(ev) <= 0 {
|
||||||
|
t.Fatal("no R/W events?!")
|
||||||
|
}
|
||||||
|
if ev := config.ResolveSaver.Read(); len(ev) <= 0 {
|
||||||
|
t.Fatal("no resolver events?!")
|
||||||
|
}
|
||||||
|
if ev := config.TLSSaver.Read(); len(ev) <= 0 {
|
||||||
|
t.Fatal("no TLS events?!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBogonResolutionNotBroken(t *testing.T) {
|
||||||
|
saver := new(tracex.Saver)
|
||||||
|
r := NewResolver(Config{
|
||||||
|
BogonIsError: true,
|
||||||
|
DNSCache: map[string][]string{
|
||||||
|
"www.google.com": {"127.0.0.1"},
|
||||||
|
},
|
||||||
|
ResolveSaver: saver,
|
||||||
|
Logger: log.Log,
|
||||||
|
})
|
||||||
|
addrs, err := r.LookupHost(context.Background(), "www.google.com")
|
||||||
|
if !errors.Is(err, netxlite.ErrDNSBogon) {
|
||||||
|
t.Fatal("not the error we expected")
|
||||||
|
}
|
||||||
|
if err.Error() != netxlite.FailureDNSBogonError {
|
||||||
|
t.Fatal("error not correctly wrapped")
|
||||||
|
}
|
||||||
|
if len(addrs) > 0 {
|
||||||
|
t.Fatal("expected no addresses here")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/model"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/model/mocks"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/runtimex"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FakeDialer struct {
|
|
||||||
Conn net.Conn
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return d.Conn, d.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
type FakeConn struct {
|
|
||||||
ReadError error
|
|
||||||
ReadData []byte
|
|
||||||
SetDeadlineError error
|
|
||||||
SetReadDeadlineError error
|
|
||||||
SetWriteDeadlineError error
|
|
||||||
WriteError error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) Read(b []byte) (int, error) {
|
|
||||||
if len(c.ReadData) > 0 {
|
|
||||||
n := copy(b, c.ReadData)
|
|
||||||
c.ReadData = c.ReadData[n:]
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if c.ReadError != nil {
|
|
||||||
return 0, c.ReadError
|
|
||||||
}
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) Write(b []byte) (n int, err error) {
|
|
||||||
if c.WriteError != nil {
|
|
||||||
return 0, c.WriteError
|
|
||||||
}
|
|
||||||
n = len(b)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) Close() (err error) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) LocalAddr() net.Addr {
|
|
||||||
return &net.TCPAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) RemoteAddr() net.Addr {
|
|
||||||
return &net.TCPAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetDeadlineError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetReadDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetReadDeadlineError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetWriteDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetWriteDeadlineError
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeResolverThatFails() model.Resolver {
|
|
||||||
return NewFakeResolverWithExplicitError(netxlite.ErrOODNSNoSuchHost)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeResolverWithExplicitError(err error) model.Resolver {
|
|
||||||
runtimex.PanicIfNil(err, "passed nil error")
|
|
||||||
return &mocks.Resolver{
|
|
||||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
|
||||||
return nil, err
|
|
||||||
},
|
|
||||||
MockNetwork: func() string {
|
|
||||||
return "fake"
|
|
||||||
},
|
|
||||||
MockAddress: func() string {
|
|
||||||
return ""
|
|
||||||
},
|
|
||||||
MockCloseIdleConnections: func() {
|
|
||||||
// nothing
|
|
||||||
},
|
|
||||||
MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) {
|
|
||||||
return nil, errors.New("not implemented")
|
|
||||||
},
|
|
||||||
MockLookupNS: func(ctx context.Context, domain string) ([]*net.NS, error) {
|
|
||||||
return nil, errors.New("not implemented")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewFakeResolverWithResult(r []string) model.Resolver {
|
|
||||||
return &mocks.Resolver{
|
|
||||||
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
|
|
||||||
return r, nil
|
|
||||||
},
|
|
||||||
MockNetwork: func() string {
|
|
||||||
return "fake"
|
|
||||||
},
|
|
||||||
MockAddress: func() string {
|
|
||||||
return ""
|
|
||||||
},
|
|
||||||
MockCloseIdleConnections: func() {
|
|
||||||
// nothing
|
|
||||||
},
|
|
||||||
MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) {
|
|
||||||
return nil, errors.New("not implemented")
|
|
||||||
},
|
|
||||||
MockLookupNS: func(ctx context.Context, domain string) ([]*net.NS, error) {
|
|
||||||
return nil, errors.New("not implemented")
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +0,0 @@
|
||||||
package resolver
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
|
||||||
)
|
|
||||||
|
|
||||||
func GenReplyError(t *testing.T, code int) []byte {
|
|
||||||
question := dns.Question{
|
|
||||||
Name: dns.Fqdn("x.org"),
|
|
||||||
Qtype: dns.TypeA,
|
|
||||||
Qclass: dns.ClassINET,
|
|
||||||
}
|
|
||||||
query := new(dns.Msg)
|
|
||||||
query.Id = dns.Id()
|
|
||||||
query.RecursionDesired = true
|
|
||||||
query.Question = make([]dns.Question, 1)
|
|
||||||
query.Question[0] = question
|
|
||||||
reply := new(dns.Msg)
|
|
||||||
reply.Compress = true
|
|
||||||
reply.MsgHdr.RecursionAvailable = true
|
|
||||||
reply.SetRcode(query, code)
|
|
||||||
data, err := reply.Pack()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
|
|
||||||
func GenReplySuccess(t *testing.T, qtype uint16, ips ...string) []byte {
|
|
||||||
question := dns.Question{
|
|
||||||
Name: dns.Fqdn("x.org"),
|
|
||||||
Qtype: qtype,
|
|
||||||
Qclass: dns.ClassINET,
|
|
||||||
}
|
|
||||||
query := new(dns.Msg)
|
|
||||||
query.Id = dns.Id()
|
|
||||||
query.RecursionDesired = true
|
|
||||||
query.Question = make([]dns.Question, 1)
|
|
||||||
query.Question[0] = question
|
|
||||||
reply := new(dns.Msg)
|
|
||||||
reply.Compress = true
|
|
||||||
reply.MsgHdr.RecursionAvailable = true
|
|
||||||
reply.SetReply(query)
|
|
||||||
for _, ip := range ips {
|
|
||||||
switch qtype {
|
|
||||||
case dns.TypeA:
|
|
||||||
reply.Answer = append(reply.Answer, &dns.A{
|
|
||||||
Hdr: dns.RR_Header{
|
|
||||||
Name: dns.Fqdn("x.org"),
|
|
||||||
Rrtype: qtype,
|
|
||||||
Class: dns.ClassINET,
|
|
||||||
Ttl: 0,
|
|
||||||
},
|
|
||||||
A: net.ParseIP(ip),
|
|
||||||
})
|
|
||||||
case dns.TypeAAAA:
|
|
||||||
reply.Answer = append(reply.Answer, &dns.AAAA{
|
|
||||||
Hdr: dns.RR_Header{
|
|
||||||
Name: dns.Fqdn("x.org"),
|
|
||||||
Rrtype: qtype,
|
|
||||||
Class: dns.ClassINET,
|
|
||||||
Ttl: 0,
|
|
||||||
},
|
|
||||||
AAAA: net.ParseIP(ip),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
data, err := reply.Pack()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
return data
|
|
||||||
}
|
|
|
@ -1,119 +0,0 @@
|
||||||
package resolver_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"net"
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/apex/log"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/model"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
}
|
|
||||||
|
|
||||||
func testresolverquick(t *testing.T, reso model.Resolver) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("skip test in short mode")
|
|
||||||
}
|
|
||||||
reso = &netxlite.ResolverLogger{
|
|
||||||
Logger: log.Log,
|
|
||||||
Resolver: reso,
|
|
||||||
}
|
|
||||||
addrs, err := reso.LookupHost(context.Background(), "dns.google.com")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if addrs == nil {
|
|
||||||
t.Fatal("expected non-nil addrs here")
|
|
||||||
}
|
|
||||||
var foundquad8 bool
|
|
||||||
for _, addr := range addrs {
|
|
||||||
// See https://github.com/ooni/probe-engine/pull/954/checks?check_run_id=1182269025
|
|
||||||
if addr == "8.8.8.8" || addr == "2001:4860:4860::8888" {
|
|
||||||
foundquad8 = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if !foundquad8 {
|
|
||||||
t.Fatalf("did not find 8.8.8.8 in output; output=%+v", addrs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensuring we can handle Internationalized Domain Names (IDNs) without issues
|
|
||||||
func testresolverquickidna(t *testing.T, reso model.Resolver) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("skip test in short mode")
|
|
||||||
}
|
|
||||||
reso = &netxlite.ResolverIDNA{
|
|
||||||
Resolver: &netxlite.ResolverLogger{
|
|
||||||
Logger: log.Log,
|
|
||||||
Resolver: reso,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
addrs, err := reso.LookupHost(context.Background(), "яндекс.рф")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if addrs == nil {
|
|
||||||
t.Fatal("expected non-nil addrs here")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverSystem(t *testing.T) {
|
|
||||||
reso := netxlite.NewResolverSystem()
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverUDPAddress(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverUDPTransport(netxlite.DefaultDialer, "8.8.8.8:53"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverUDPDomain(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverUDPTransport(netxlite.DefaultDialer, "dns.google.com:53"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverTCPAddress(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverTCPTransport(new(net.Dialer).DialContext, "8.8.8.8:53"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverTCPDomain(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverTCPTransport(new(net.Dialer).DialContext, "dns.google.com:53"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverDoTAddress(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverTLSTransport(new(tls.Dialer).DialContext, "8.8.8.8:853"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverDoTDomain(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverTLSTransport(new(tls.Dialer).DialContext, "dns.google.com:853"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNewResolverDoH(t *testing.T) {
|
|
||||||
reso := netxlite.NewUnwrappedSerialResolver(
|
|
||||||
netxlite.NewUnwrappedDNSOverHTTPSTransport(http.DefaultClient, "https://cloudflare-dns.com/dns-query"))
|
|
||||||
testresolverquick(t, reso)
|
|
||||||
testresolverquickidna(t, reso)
|
|
||||||
}
|
|
|
@ -1,80 +0,0 @@
|
||||||
package tlsdialer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type EOFDialer struct{}
|
|
||||||
|
|
||||||
func (EOFDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return nil, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
type EOFConnDialer struct{}
|
|
||||||
|
|
||||||
func (EOFConnDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
return EOFConn{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type EOFConn struct {
|
|
||||||
net.Conn
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) Read(p []byte) (int, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) Write(p []byte) (int, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) Close() error {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) LocalAddr() net.Addr {
|
|
||||||
return EOFAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) RemoteAddr() net.Addr {
|
|
||||||
return EOFAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) SetDeadline(t time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) SetReadDeadline(t time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFConn) SetWriteDeadline(t time.Time) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type EOFAddr struct{}
|
|
||||||
|
|
||||||
func (EOFAddr) Network() string {
|
|
||||||
return "tcp"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EOFAddr) String() string {
|
|
||||||
return "127.0.0.1:1234"
|
|
||||||
}
|
|
||||||
|
|
||||||
type EOFTLSHandshaker struct{}
|
|
||||||
|
|
||||||
func (EOFTLSHandshaker) Handshake(
|
|
||||||
ctx context.Context, conn net.Conn, config *tls.Config,
|
|
||||||
) (net.Conn, tls.ConnectionState, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return nil, tls.ConnectionState{}, io.EOF
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package tlsdialer
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"io"
|
|
||||||
"net"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type FakeDialer struct {
|
|
||||||
Conn net.Conn
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d FakeDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
|
||||||
time.Sleep(10 * time.Microsecond)
|
|
||||||
return d.Conn, d.Err
|
|
||||||
}
|
|
||||||
|
|
||||||
type FakeConn struct {
|
|
||||||
ReadError error
|
|
||||||
ReadData []byte
|
|
||||||
SetDeadlineError error
|
|
||||||
SetReadDeadlineError error
|
|
||||||
SetWriteDeadlineError error
|
|
||||||
WriteError error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) Read(b []byte) (int, error) {
|
|
||||||
if len(c.ReadData) > 0 {
|
|
||||||
n := copy(b, c.ReadData)
|
|
||||||
c.ReadData = c.ReadData[n:]
|
|
||||||
return n, nil
|
|
||||||
}
|
|
||||||
if c.ReadError != nil {
|
|
||||||
return 0, c.ReadError
|
|
||||||
}
|
|
||||||
return 0, io.EOF
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) Write(b []byte) (n int, err error) {
|
|
||||||
if c.WriteError != nil {
|
|
||||||
return 0, c.WriteError
|
|
||||||
}
|
|
||||||
n = len(b)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) Close() (err error) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) LocalAddr() net.Addr {
|
|
||||||
return &net.TCPAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (*FakeConn) RemoteAddr() net.Addr {
|
|
||||||
return &net.TCPAddr{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetDeadlineError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetReadDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetReadDeadlineError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *FakeConn) SetWriteDeadline(t time.Time) (err error) {
|
|
||||||
return c.SetWriteDeadlineError
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package tlsdialer_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/apex/log"
|
|
||||||
oohttp "github.com/ooni/oohttp"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestTLSDialerSuccess(t *testing.T) {
|
|
||||||
if testing.Short() {
|
|
||||||
t.Skip("skip test in short mode")
|
|
||||||
}
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
dialer := &netxlite.TLSDialerLegacy{Dialer: netxlite.DefaultDialer,
|
|
||||||
TLSHandshaker: &netxlite.TLSHandshakerLogger{
|
|
||||||
TLSHandshaker: &netxlite.TLSHandshakerConfigurable{},
|
|
||||||
DebugLogger: log.Log,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
txp := &oohttp.StdlibTransport{
|
|
||||||
Transport: &oohttp.Transport{
|
|
||||||
DialTLSContext: dialer.DialTLSContext,
|
|
||||||
ForceAttemptHTTP2: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
client := &http.Client{Transport: txp}
|
|
||||||
resp, err := client.Get("https://www.google.com")
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
resp.Body.Close()
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package tlsdialer_test
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/tls"
|
|
||||||
"io"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
|
|
||||||
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestSystemTLSHandshakerEOFError(t *testing.T) {
|
|
||||||
h := &netxlite.TLSHandshakerConfigurable{}
|
|
||||||
conn, _, err := h.Handshake(context.Background(), tlsdialer.EOFConn{}, &tls.Config{
|
|
||||||
ServerName: "x.org",
|
|
||||||
})
|
|
||||||
if err != io.EOF {
|
|
||||||
t.Fatal("not the error that we expected")
|
|
||||||
}
|
|
||||||
if conn != nil {
|
|
||||||
t.Fatal("expected nil con here")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type SetDeadlineConn struct {
|
|
||||||
tlsdialer.EOFConn
|
|
||||||
deadlines []time.Time
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *SetDeadlineConn) SetDeadline(t time.Time) error {
|
|
||||||
c.deadlines = append(c.deadlines, t)
|
|
||||||
return nil
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user