ooni-probe-cli/internal/engine/sessionresolver/resolver_test.go

387 lines
9.2 KiB
Go
Raw Permalink Normal View History

package sessionresolver
import (
"context"
"errors"
"net"
"net/url"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
"github.com/ooni/probe-cli/v3/internal/atomicx"
"github.com/ooni/probe-cli/v3/internal/kvstore"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/model/mocks"
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
"github.com/ooni/probe-cli/v3/internal/multierror"
)
func TestNetworkWorks(t *testing.T) {
reso := &Resolver{}
if reso.Network() != "sessionresolver" {
t.Fatal("unexpected value returned by Network")
}
}
func TestAddressWorks(t *testing.T) {
reso := &Resolver{}
if reso.Address() != "" {
t.Fatal("unexpected value returned by Address")
}
}
func TestTypicalUsageWithFailure(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
cancel() // fail immediately
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
reso := &Resolver{KVStore: &kvstore.Memory{}}
addrs, err := reso.LookupHost(ctx, "ooni.org")
if !errors.Is(err, ErrLookupHost) {
t.Fatal("not the error we expected", err)
}
var me *multierror.Union
if !errors.As(err, &me) {
t.Fatal("cannot convert error")
}
for _, child := range me.Children {
// net.DNSError does not include the underlying error
// but just a string representing the error. This
// means that we need to go down hunting what's the
// real error that occurred and use more verbose code.
{
var ew *errWrapper
if !errors.As(child, &ew) {
t.Fatal("not an instance of errwrapper")
}
var de *net.DNSError
if errors.As(ew, &de) {
if !strings.HasSuffix(de.Err, "operation was canceled") {
t.Fatal("not the error we expected", de.Err)
}
continue
}
}
// otherwise just unwrap and check whether it's
// a real context.Canceled error.
if !errors.Is(child, context.Canceled) {
t.Fatal("unexpected sub-error", child)
}
}
if addrs != nil {
t.Fatal("expected nil here")
}
if len(reso.res) < 1 {
t.Fatal("expected to see some resolvers here")
}
if reso.Stats() == "" {
t.Fatal("expected to see some string returned by stats")
}
reso.CloseIdleConnections()
if len(reso.res) != 0 {
t.Fatal("expected to see no resolvers after CloseIdleConnections")
}
}
func TestTypicalUsageWithSuccess(t *testing.T) {
expected := []string{"8.8.8.8", "8.8.4.4"}
ctx := context.Background()
reso := &Resolver{
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
KVStore: &kvstore.Memory{},
newChildResolverFn: func(h3 bool, URL string) (model.Resolver, error) {
reso := &mocks.Resolver{
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return expected, nil
},
}
return reso, nil
},
}
addrs, err := reso.LookupHost(ctx, "dns.google")
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(expected, addrs); diff != "" {
t.Fatal(diff)
}
}
func TestLittleLLookupHostWithInvalidURL(t *testing.T) {
reso := &Resolver{}
ctx := context.Background()
ri := &resolverinfo{URL: "\t\t\t", Score: 0.99}
addrs, err := reso.lookupHost(ctx, ri, "ooni.org")
if err == nil || !strings.HasSuffix(err.Error(), "invalid control character in URL") {
t.Fatal("not the error we expected", err)
}
if addrs != nil {
t.Fatal("expected nil addrs here")
}
if ri.Score != 0 {
t.Fatal("unexpected ri.Score", ri.Score)
}
}
func TestLittleLLookupHostWithSuccess(t *testing.T) {
expected := []string{"8.8.8.8", "8.8.4.4"}
reso := &Resolver{
newChildResolverFn: func(h3 bool, URL string) (model.Resolver, error) {
reso := &mocks.Resolver{
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return expected, nil
},
}
return reso, nil
},
}
ctx := context.Background()
ri := &resolverinfo{URL: "dot://www.ooni.nonexistent", Score: 0.1}
addrs, err := reso.lookupHost(ctx, ri, "dns.google")
if err != nil {
t.Fatal(err)
}
if diff := cmp.Diff(expected, addrs); diff != "" {
t.Fatal(diff)
}
if ri.Score < 0.88 || ri.Score > 0.92 {
t.Fatal("unexpected score", ri.Score)
}
}
func TestLittleLLookupHostWithFailure(t *testing.T) {
errMocked := errors.New("mocked error")
reso := &Resolver{
newChildResolverFn: func(h3 bool, URL string) (model.Resolver, error) {
reso := &mocks.Resolver{
MockLookupHost: func(ctx context.Context, domain string) ([]string, error) {
return nil, errMocked
},
}
return reso, nil
},
}
ctx := context.Background()
ri := &resolverinfo{URL: "dot://www.ooni.nonexistent", Score: 0.95}
addrs, err := reso.lookupHost(ctx, ri, "dns.google")
if !errors.Is(err, errMocked) {
t.Fatal("not the error we expected", err)
}
if addrs != nil {
t.Fatal("expected nil addrs here")
}
if ri.Score < 0.094 || ri.Score > 0.096 {
t.Fatal("unexpected score", ri.Score)
}
}
func TestMaybeConfusionNoConfusion(t *testing.T) {
reso := &Resolver{}
rv := reso.maybeConfusion(nil, 0)
if rv != -1 {
t.Fatal("unexpected return value", rv)
}
}
func TestMaybeConfusionNoArray(t *testing.T) {
reso := &Resolver{}
rv := reso.maybeConfusion(nil, 11)
if rv != 0 {
t.Fatal("unexpected return value", rv)
}
}
func TestMaybeConfusionSingleEntry(t *testing.T) {
reso := &Resolver{}
state := []*resolverinfo{{}}
rv := reso.maybeConfusion(state, 11)
if rv != 0 {
t.Fatal("unexpected return value", rv)
}
}
func TestMaybeConfusionTwoEntries(t *testing.T) {
reso := &Resolver{}
state := []*resolverinfo{{
Score: 0.8,
URL: "https://dns.google/dns-query",
}, {
Score: 0.4,
URL: "http3://dns.google/dns-query",
}}
rv := reso.maybeConfusion(state, 11)
if rv != 2 {
t.Fatal("unexpected return value", rv)
}
if state[0].Score != 0.4 {
t.Fatal("unexpected state[0].Score")
}
if state[0].URL != "http3://dns.google/dns-query" {
t.Fatal("unexpected state[0].URL")
}
if state[1].Score != 0.8 {
t.Fatal("unexpected state[1].Score")
}
if state[1].URL != "https://dns.google/dns-query" {
t.Fatal("unexpected state[1].URL")
}
}
func TestMaybeConfusionManyEntries(t *testing.T) {
reso := &Resolver{}
state := []*resolverinfo{{
Score: 0.8,
URL: "https://dns.google/dns-query",
}, {
Score: 0.4,
URL: "http3://dns.google/dns-query",
}, {
Score: 0.1,
URL: "system:///",
}, {
Score: 0.01,
URL: "dot://dns.google",
}}
rv := reso.maybeConfusion(state, 11)
if rv != 3 {
t.Fatal("unexpected return value", rv)
}
if state[0].Score != 0.1 {
t.Fatal("unexpected state[0].Score")
}
if state[0].URL != "system:///" {
t.Fatal("unexpected state[0].URL")
}
if state[1].Score != 0.4 {
t.Fatal("unexpected state[1].Score")
}
if state[1].URL != "http3://dns.google/dns-query" {
t.Fatal("unexpected state[1].URL")
}
if state[2].Score != 0.8 {
t.Fatal("unexpected state[2].Score")
}
if state[2].URL != "https://dns.google/dns-query" {
t.Fatal("unexpected state[2].URL")
}
if state[3].Score != 0.01 {
t.Fatal("unexpected state[3].Score")
}
if state[3].URL != "dot://dns.google" {
t.Fatal("unexpected state[3].URL")
}
}
func TestResolverWorksWithProxy(t *testing.T) {
var (
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
works = &atomicx.Int64{}
startuperr = make(chan error)
listench = make(chan net.Listener)
done = make(chan interface{})
)
// proxy implementation
go func() {
defer close(done)
lconn, err := net.Listen("tcp", "127.0.0.1:0")
startuperr <- err
if err != nil {
return
}
listench <- lconn
for {
conn, err := lconn.Accept()
if err != nil {
// We assume this is when we were told to
// shutdown by the main goroutine.
return
}
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
works.Add(1)
conn.Close()
}
}()
// make sure we could start the proxy
if err := <-startuperr; err != nil {
t.Fatal(err)
}
listener := <-listench
// use the proxy
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
reso := &Resolver{
ProxyURL: &url.URL{
Scheme: "socks5",
Host: listener.Addr().String(),
},
KVStore: &kvstore.Memory{},
}
ctx := context.Background()
addrs, err := reso.LookupHost(ctx, "ooni.org")
// cleanly shutdown the listener
listener.Close()
<-done
// check results
if !errors.Is(err, ErrLookupHost) {
t.Fatal("not the error we expected", err)
}
if addrs != nil {
t.Fatal("expected nil addrs")
}
refactor: flatten and separate (#353) * refactor(atomicx): move outside the engine package After merging probe-engine into probe-cli, my impression is that we have too much unnecessary nesting of packages in this repository. The idea of this commit and of a bunch of following commits will instead be to reduce the nesting and simplify the structure. While there, improve the documentation. * fix: always use the atomicx package For consistency, never use sync/atomic and always use ./internal/atomicx so we can just grep and make sure we're not risking to crash if we make a subtle mistake on a 32 bit platform. While there, mention in the contributing guidelines that we want to always prefer the ./internal/atomicx package over sync/atomic. * fix(atomicx): remove unnecessary constructor We don't need a constructor here. The default constructed `&Int64{}` instance is already usable and the constructor does not add anything to what we are doing, rather it just creates extra confusion. * cleanup(atomicx): we are not using Float64 Because atomicx.Float64 is unused, we can safely zap it. * cleanup(atomicx): simplify impl and improve tests We can simplify the implementation by using defer and by letting the Load() method call Add(0). We can improve tests by making many goroutines updated the atomic int64 value concurrently. * refactor(fsx): can live in the ./internal pkg Let us reduce the amount of nesting. While there, ensure that the package only exports the bare minimum, and improve the documentation of the tests, to ease reading the code. * refactor: move runtimex to ./internal * refactor: move shellx into the ./internal package While there, remove unnecessary dependency between packages. While there, specify in the contributing guidelines that one should use x/sys/execabs instead of os/exec. * refactor: move ooapi into the ./internal pkg * refactor(humanize): move to ./internal and better docs * refactor: move platform to ./internal * refactor(randx): move to ./internal * refactor(multierror): move into the ./internal pkg * refactor(kvstore): all kvstores in ./internal Rather than having part of the kvstore inside ./internal/engine/kvstore and part in ./internal/engine/kvstore.go, let us put every piece of code that is kvstore related into the ./internal/kvstore package. * fix(kvstore): always return ErrNoSuchKey on Get() error It should help to use the kvstore everywhere removing all the copies that are lingering around the tree. * sessionresolver: make KVStore mandatory Simplifies implementation. While there, use the ./internal/kvstore package rather than having our private implementation. * fix(ooapi): use the ./internal/kvstore package * fix(platform): better documentation
2021-06-04 10:34:18 +02:00
if works.Load() < 1 {
t.Fatal("expected to see a positive number of entries here")
}
}
func TestShouldSkipWithProxyWorks(t *testing.T) {
expect := []struct {
url string
result bool
}{{
url: "\t",
result: true,
}, {
url: "https://dns.google/dns-query",
result: false,
}, {
url: "dot://dns.google/",
result: false,
}, {
url: "http3://dns.google/dns-query",
result: true,
}, {
url: "tcp://dns.google/",
result: false,
}, {
url: "udp://dns.google/",
result: true,
}, {
url: "system:///",
result: true,
}}
reso := &Resolver{}
for _, e := range expect {
out := reso.shouldSkipWithProxy(&resolverinfo{URL: e.url})
if out != e.result {
t.Fatal("unexpected result for", e)
}
}
}
func TestUnimplementedFunctions(t *testing.T) {
t.Run("LookupHTTPS", func(t *testing.T) {
r := &Resolver{}
https, err := r.LookupHTTPS(context.Background(), "dns.google")
if !errors.Is(err, errLookupNotImplemented) {
t.Fatal("unexpected error", err)
}
if https != nil {
t.Fatal("expected nil result")
}
})
t.Run("LookupNS", func(t *testing.T) {
r := &Resolver{}
ns, err := r.LookupNS(context.Background(), "dns.google")
if !errors.Is(err, errLookupNotImplemented) {
t.Fatal("unexpected error", err)
}
if len(ns) > 0 {
t.Fatal("expected empty result")
}
})
}