Reducing the errors is not done in a perfect way. We have documented the most striking differences inside https://github.com/ooni/probe/issues/1707#issuecomment-942283746 and some attempts to improve the situation further inside https://github.com/ooni/probe/issues/1707#issuecomment-942341255. A better strategy for the future would be to introduce more specific timeout errors, such as dns_timeout_error, etc. More testing may be needed to further validate and compare the old and the new TH, but this requires Jafar improvements to more precisely simulate more complex censorship.
132 lines
3.6 KiB
Go
132 lines
3.6 KiB
Go
package webconnectivity
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/ooni/probe-cli/v3/internal/netxlite"
|
|
)
|
|
|
|
func TestHTTPDoWithInvalidURL(t *testing.T) {
|
|
ctx := context.Background()
|
|
wg := new(sync.WaitGroup)
|
|
httpch := make(chan CtrlHTTPResponse, 1)
|
|
wg.Add(1)
|
|
go HTTPDo(ctx, &HTTPConfig{
|
|
Client: http.DefaultClient,
|
|
Headers: nil,
|
|
MaxAcceptableBody: 1 << 24,
|
|
Out: httpch,
|
|
URL: "http://[::1]aaaa",
|
|
Wg: wg,
|
|
})
|
|
// wait for measurement steps to complete
|
|
wg.Wait()
|
|
resp := <-httpch
|
|
if resp.Failure == nil || *resp.Failure != "unknown_error" {
|
|
t.Fatal("not the failure we expected")
|
|
}
|
|
}
|
|
|
|
func TestHTTPDoWithHTTPTransportFailure(t *testing.T) {
|
|
expected := errors.New("mocked error")
|
|
ctx := context.Background()
|
|
wg := new(sync.WaitGroup)
|
|
httpch := make(chan CtrlHTTPResponse, 1)
|
|
wg.Add(1)
|
|
go HTTPDo(ctx, &HTTPConfig{
|
|
Client: &http.Client{
|
|
Transport: FakeTransport{
|
|
Err: expected,
|
|
},
|
|
},
|
|
Headers: nil,
|
|
MaxAcceptableBody: 1 << 24,
|
|
Out: httpch,
|
|
URL: "http://www.x.org",
|
|
Wg: wg,
|
|
})
|
|
// wait for measurement steps to complete
|
|
wg.Wait()
|
|
resp := <-httpch
|
|
if resp.Failure == nil || *resp.Failure != "unknown_error" {
|
|
t.Fatal("not the error we expected")
|
|
}
|
|
}
|
|
|
|
func newErrWrapper(failure, operation string) error {
|
|
return &netxlite.ErrWrapper{
|
|
Failure: failure,
|
|
Operation: operation,
|
|
WrappedErr: nil, // should not matter
|
|
}
|
|
}
|
|
|
|
func newErrWrapperTopLevel(failure string) error {
|
|
return newErrWrapper(failure, netxlite.TopLevelOperation)
|
|
}
|
|
|
|
func Test_httpMapFailure(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
failure error
|
|
want *string
|
|
}{{
|
|
name: "nil",
|
|
failure: nil,
|
|
want: nil,
|
|
}, {
|
|
name: "nxdomain",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSNXDOMAINError),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "no answer",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSNoAnswer),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "non recoverable failure",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSNonRecoverableFailure),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "refused",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSRefusedError),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "server misbehaving",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSServerMisbehaving),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "temporary failure",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureDNSTemporaryFailure),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "timeout outside of dns lookup",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureGenericTimeoutError),
|
|
want: stringPointerForString(netxlite.FailureGenericTimeoutError),
|
|
}, {
|
|
name: "timeout inside of dns lookup",
|
|
failure: newErrWrapper(netxlite.FailureGenericTimeoutError, netxlite.ResolveOperation),
|
|
want: stringPointerForString("dns_lookup_error"),
|
|
}, {
|
|
name: "connection refused",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureConnectionRefused),
|
|
want: stringPointerForString("connection_refused_error"),
|
|
}, {
|
|
name: "anything else",
|
|
failure: newErrWrapperTopLevel(netxlite.FailureEOFError),
|
|
want: stringPointerForString("unknown_error"),
|
|
}}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := httpMapFailure(tt.failure)
|
|
if diff := cmp.Diff(tt.want, got); diff != "" {
|
|
t.Fatal(diff)
|
|
}
|
|
})
|
|
}
|
|
}
|