4241ee4bc1
We're using a request-specific logger where we also print the ID of the request. This design helps to observe logs produced by concurrent requests. Part of https://github.com/ooni/probe/issues/2183 While there, fix https://github.com/ooni/probe/issues/2241
145 lines
3.9 KiB
Go
145 lines
3.9 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"sync"
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"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"
|
|
)
|
|
|
|
func TestHTTPDoWithInvalidURL(t *testing.T) {
|
|
ctx := context.Background()
|
|
wg := new(sync.WaitGroup)
|
|
httpch := make(chan ctrlHTTPResponse, 1)
|
|
wg.Add(1)
|
|
go httpDo(ctx, &httpConfig{
|
|
Headers: nil,
|
|
Logger: model.DiscardLogger,
|
|
MaxAcceptableBody: 1 << 24,
|
|
NewClient: func(model.Logger) model.HTTPClient {
|
|
return http.DefaultClient
|
|
},
|
|
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{
|
|
Headers: nil,
|
|
Logger: model.DiscardLogger,
|
|
MaxAcceptableBody: 1 << 24,
|
|
NewClient: func(model.Logger) model.HTTPClient {
|
|
return &http.Client{
|
|
Transport: &mocks.HTTPTransport{
|
|
MockRoundTrip: func(req *http.Request) (*http.Response, error) {
|
|
return nil, expected
|
|
},
|
|
MockCloseIdleConnections: func() {
|
|
// nothing
|
|
},
|
|
},
|
|
}
|
|
},
|
|
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)
|
|
}
|
|
})
|
|
}
|
|
}
|