refactor: move i/e/n/errorx to i/errorsx (#416)

Still working towards https://github.com/ooni/probe/issues/1505
This commit is contained in:
Simone Basso
2021-07-01 16:34:36 +02:00
committed by GitHub
parent 6895946a34
commit 72acd175a0
58 changed files with 287 additions and 287 deletions
+2 -2
View File
@@ -16,8 +16,8 @@ import (
"github.com/montanaflynn/stats"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/humanize"
"github.com/ooni/probe-cli/v3/internal/iox"
)
@@ -172,7 +172,7 @@ func (r runner) measure(
// of the latest connect time. We should have one sample in most
// cases, because the connection should be persistent.
for _, ev := range r.saver.Read() {
if ev.Name == errorx.ConnectOperation {
if ev.Name == errorsx.ConnectOperation {
connectTime = ev.Duration.Seconds()
}
}
+3 -3
View File
@@ -13,8 +13,8 @@ import (
"github.com/montanaflynn/stats"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestRunnerLoopLocateFailure(t *testing.T) {
@@ -108,7 +108,7 @@ func TestRunnerLoopMeasureFailure(t *testing.T) {
func TestRunnerLoopCollectFailure(t *testing.T) {
expected := errors.New("mocked error")
saver := new(trace.Saver)
saver.Write(trace.Event{Name: errorx.ConnectOperation, Duration: 150 * time.Millisecond})
saver.Write(trace.Event{Name: errorsx.ConnectOperation, Duration: 150 * time.Millisecond})
r := runner{
callbacks: model.NewPrinterCallbacks(log.Log),
httpClient: &http.Client{
@@ -152,7 +152,7 @@ func TestRunnerLoopCollectFailure(t *testing.T) {
func TestRunnerLoopSuccess(t *testing.T) {
saver := new(trace.Saver)
saver.Write(trace.Event{Name: errorx.ConnectOperation, Duration: 150 * time.Millisecond})
saver.Write(trace.Event{Name: errorsx.ConnectOperation, Duration: 150 * time.Millisecond})
r := runner{
callbacks: model.NewPrinterCallbacks(log.Log),
httpClient: &http.Client{
@@ -11,7 +11,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
const (
@@ -111,7 +111,7 @@ func (tk *TestKeys) ComputeEndpointStatus(v urlgetter.MultiOutput, dns, tcp **bo
// start where all is unknown
*dns, *tcp = nil, nil
// process DNS first
if v.TestKeys.FailedOperation != nil && *v.TestKeys.FailedOperation == errorx.ResolveOperation {
if v.TestKeys.FailedOperation != nil && *v.TestKeys.FailedOperation == errorsx.ResolveOperation {
tk.FacebookDNSBlocking = &trueValue
*dns = &falseValue
return // we know that the DNS has failed
@@ -127,7 +127,7 @@ func (tk *TestKeys) ComputeEndpointStatus(v urlgetter.MultiOutput, dns, tcp **bo
}
*dns = &trueValue
// now process connect
if v.TestKeys.FailedOperation != nil && *v.TestKeys.FailedOperation == errorx.ConnectOperation {
if v.TestKeys.FailedOperation != nil && *v.TestKeys.FailedOperation == errorsx.ConnectOperation {
tk.FacebookTCPBlocking = &trueValue
*tcp = &falseValue
return // because connect failed
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -162,7 +162,7 @@ func TestWithCancelledContext(t *testing.T) {
func TestComputeEndpointStatsTCPBlocking(t *testing.T) {
failure := io.EOF.Error()
operation := errorx.ConnectOperation
operation := errorsx.ConnectOperation
tk := fbmessenger.TestKeys{}
tk.Update(urlgetter.MultiOutput{
Input: urlgetter.MultiInput{Target: fbmessenger.ServiceEdge},
@@ -192,7 +192,7 @@ func TestComputeEndpointStatsTCPBlocking(t *testing.T) {
func TestComputeEndpointStatsDNSIsLying(t *testing.T) {
failure := io.EOF.Error()
operation := errorx.ConnectOperation
operation := errorsx.ConnectOperation
tk := fbmessenger.TestKeys{}
tk.Update(urlgetter.MultiOutput{
Input: urlgetter.MultiInput{Target: fbmessenger.ServiceEdge},
+4 -4
View File
@@ -19,7 +19,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/iox"
"github.com/ooni/probe-cli/v3/internal/randx"
)
@@ -164,7 +164,7 @@ func (m Measurer) Run(
// parse response body
var jsonHeaders JSONHeaders
if err := json.Unmarshal(data, &jsonHeaders); err != nil {
failure := errorx.FailureJSONParseError
failure := errorsx.FailureJSONParseError
tk.Failure = &failure
tk.Tampering.Total = true
return nil // measurement did not fail, we measured tampering
@@ -180,8 +180,8 @@ func Transact(txp Transport, req *http.Request,
callbacks model.ExperimentCallbacks) (*http.Response, []byte, error) {
// make sure that we return a wrapped error here
resp, data, err := transact(txp, req, callbacks)
err = errorx.SafeErrWrapperBuilder{
Error: err, Operation: errorx.TopLevelOperation}.MaybeBuild()
err = errorsx.SafeErrWrapperBuilder{
Error: err, Operation: errorsx.TopLevelOperation}.MaybeBuild()
return resp, data, err
}
+4 -4
View File
@@ -18,7 +18,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -161,14 +161,14 @@ func TestCancelledContext(t *testing.T) {
if tk.Agent != "agent" {
t.Fatal("invalid Agent")
}
if *tk.Failure != errorx.FailureInterrupted {
if *tk.Failure != errorsx.FailureInterrupted {
t.Fatal("invalid Failure")
}
if len(tk.Requests) != 1 {
t.Fatal("invalid Requests")
}
request := tk.Requests[0]
if *request.Failure != errorx.FailureInterrupted {
if *request.Failure != errorsx.FailureInterrupted {
t.Fatal("invalid Requests[0].Failure")
}
if request.Request.Body.Value != "" {
@@ -480,7 +480,7 @@ func TestInvalidJSONBody(t *testing.T) {
if tk.Agent != "agent" {
t.Fatal("invalid Agent")
}
if *tk.Failure != errorx.FailureJSONParseError {
if *tk.Failure != errorsx.FailureJSONParseError {
t.Fatal("invalid Failure")
}
if len(tk.Requests) != 1 {
+2 -2
View File
@@ -14,7 +14,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/randx"
)
@@ -293,7 +293,7 @@ func RunMethod(ctx context.Context, config RunMethodConfig) {
count, err := conn.Read(data)
if err != nil {
// We expect this method to terminate w/ timeout
if err.Error() == errorx.FailureGenericTimeoutError {
if err.Error() == errorsx.FailureGenericTimeoutError {
err = nil
}
result.Err = err
+2 -2
View File
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -97,7 +97,7 @@ func TestCancelledContext(t *testing.T) {
t.Fatal("unexpected FailureList length")
}
for _, failure := range tk.FailureList {
if *failure != errorx.FailureInterrupted {
if *failure != errorsx.FailureInterrupted {
t.Fatal("unexpected failure")
}
}
@@ -17,7 +17,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
const (
@@ -270,11 +270,11 @@ func TestUpdateWithMixedResults(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.HTTPRoundTripOperation
s := errorsx.HTTPRoundTripOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -291,7 +291,7 @@ func TestUpdateWithMixedResults(t *testing.T) {
if tk.APIStatus != "blocked" {
t.Fatal("ApiStatus should be blocked")
}
if *tk.APIFailure != errorx.FailureEOFError {
if *tk.APIFailure != errorsx.FailureEOFError {
t.Fatal("invalid ApiFailure")
}
if tk.FailingGateways != nil {
@@ -730,7 +730,7 @@ func generateMockGetter(requestResponse map[string]string, responseStatus map[st
responseBody = ""
eofError := io.EOF.Error()
failure = &eofError
connectOperation := errorx.ConnectOperation
connectOperation := errorsx.ConnectOperation
failedOperation = &connectOperation
responseStatus = 0
}
@@ -9,7 +9,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -85,7 +85,7 @@ func TestUpdate(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -93,7 +93,7 @@ func TestUpdate(t *testing.T) {
if tk.SignalBackendStatus != "blocked" {
t.Fatal("SignalBackendStatus should be blocked")
}
if *tk.SignalBackendFailure != errorx.FailureEOFError {
if *tk.SignalBackendFailure != errorsx.FailureEOFError {
t.Fatal("invalid SignalBackendError")
}
}
@@ -15,7 +15,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
const (
@@ -64,24 +64,24 @@ func (tk *TestKeys) classify() string {
return classSuccessGotServerHello
}
switch *tk.Target.Failure {
case errorx.FailureConnectionRefused:
case errorsx.FailureConnectionRefused:
return classAnomalyTestHelperUnreachable
case errorx.FailureConnectionReset:
case errorsx.FailureConnectionReset:
return classInterferenceReset
case errorx.FailureDNSNXDOMAINError:
case errorsx.FailureDNSNXDOMAINError:
return classAnomalyTestHelperUnreachable
case errorx.FailureEOFError:
case errorsx.FailureEOFError:
return classInterferenceClosed
case errorx.FailureGenericTimeoutError:
case errorsx.FailureGenericTimeoutError:
if tk.Control.Failure != nil {
return classAnomalyTestHelperUnreachable
}
return classAnomalyTimeout
case errorx.FailureSSLInvalidCertificate:
case errorsx.FailureSSLInvalidCertificate:
return classInterferenceInvalidCertificate
case errorx.FailureSSLInvalidHostname:
case errorsx.FailureSSLInvalidHostname:
return classSuccessGotServerHello
case errorx.FailureSSLUnknownAuthority:
case errorsx.FailureSSLUnknownAuthority:
return classInterferenceUnknownAuthority
}
return classAnomalyUnexpectedFailure
@@ -117,8 +117,8 @@ func (m *Measurer) measureone(
select {
case <-time.After(sleeptime):
case <-ctx.Done():
s := errorx.FailureInterrupted
failedop := errorx.TopLevelOperation
s := errorsx.FailureInterrupted
failedop := errorsx.TopLevelOperation
return Subresult{
TestKeys: urlgetter.TestKeys{
FailedOperation: &failedop,
@@ -9,7 +9,7 @@ import (
"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
const (
@@ -29,64 +29,64 @@ func TestTestKeysClassify(t *testing.T) {
})
t.Run("with tk.Target.Failure == connection_refused", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureConnectionRefused)
tk.Target.Failure = asStringPtr(errorsx.FailureConnectionRefused)
if tk.classify() != classAnomalyTestHelperUnreachable {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == dns_nxdomain_error", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureDNSNXDOMAINError)
tk.Target.Failure = asStringPtr(errorsx.FailureDNSNXDOMAINError)
if tk.classify() != classAnomalyTestHelperUnreachable {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == connection_reset", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureConnectionReset)
tk.Target.Failure = asStringPtr(errorsx.FailureConnectionReset)
if tk.classify() != classInterferenceReset {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == eof_error", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureEOFError)
tk.Target.Failure = asStringPtr(errorsx.FailureEOFError)
if tk.classify() != classInterferenceClosed {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == ssl_invalid_hostname", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureSSLInvalidHostname)
tk.Target.Failure = asStringPtr(errorsx.FailureSSLInvalidHostname)
if tk.classify() != classSuccessGotServerHello {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == ssl_unknown_authority", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureSSLUnknownAuthority)
tk.Target.Failure = asStringPtr(errorsx.FailureSSLUnknownAuthority)
if tk.classify() != classInterferenceUnknownAuthority {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == ssl_invalid_certificate", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureSSLInvalidCertificate)
tk.Target.Failure = asStringPtr(errorsx.FailureSSLInvalidCertificate)
if tk.classify() != classInterferenceInvalidCertificate {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == generic_timeout_error #1", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureGenericTimeoutError)
tk.Target.Failure = asStringPtr(errorsx.FailureGenericTimeoutError)
if tk.classify() != classAnomalyTimeout {
t.Fatal("unexpected result")
}
})
t.Run("with tk.Target.Failure == generic_timeout_error #2", func(t *testing.T) {
tk := new(TestKeys)
tk.Target.Failure = asStringPtr(errorx.FailureGenericTimeoutError)
tk.Control.Failure = asStringPtr(errorx.FailureGenericTimeoutError)
tk.Target.Failure = asStringPtr(errorsx.FailureGenericTimeoutError)
tk.Control.Failure = asStringPtr(errorsx.FailureGenericTimeoutError)
if tk.classify() != classAnomalyTestHelperUnreachable {
t.Fatal("unexpected result")
}
@@ -191,10 +191,10 @@ func TestMeasureoneCancelledContext(t *testing.T) {
if result.DNSCache != nil {
t.Fatal("not the expected DNSCache")
}
if result.FailedOperation == nil || *result.FailedOperation != errorx.TopLevelOperation {
if result.FailedOperation == nil || *result.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the expected FailedOperation")
}
if result.Failure == nil || *result.Failure != errorx.FailureInterrupted {
if result.Failure == nil || *result.Failure != errorsx.FailureInterrupted {
t.Fatal("not the expected failure")
}
if result.NetworkEvents != nil {
@@ -295,10 +295,10 @@ func TestMeasureoneSuccess(t *testing.T) {
if result.DNSCache != nil {
t.Fatal("not the expected DNSCache")
}
if result.FailedOperation == nil || *result.FailedOperation != errorx.TLSHandshakeOperation {
if result.FailedOperation == nil || *result.FailedOperation != errorsx.TLSHandshakeOperation {
t.Fatal("not the expected FailedOperation")
}
if result.Failure == nil || *result.Failure != errorx.FailureSSLInvalidHostname {
if result.Failure == nil || *result.Failure != errorsx.FailureSSLInvalidHostname {
t.Fatal("unexpected failure")
}
if len(result.NetworkEvents) < 1 {
@@ -348,7 +348,7 @@ func TestMeasureonewithcacheWorks(t *testing.T) {
if result.Cached != expected {
t.Fatal("unexpected cached")
}
if *result.Failure != errorx.FailureSSLInvalidHostname {
if *result.Failure != errorsx.FailureSSLInvalidHostname {
t.Fatal("unexpected failure")
}
if result.SNI != "kernel.org" {
@@ -13,8 +13,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/pion/stun"
)
@@ -58,7 +58,7 @@ func (m *Measurer) ExperimentVersion() string {
}
func wrap(err error) error {
return errorx.SafeErrWrapperBuilder{
return errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: "stun",
}.MaybeBuild()
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/stunreachability"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/pion/stun"
)
@@ -213,7 +213,7 @@ func TestReadFailure(t *testing.T) {
t.Fatal("not the error we expected")
}
tk := measurement.TestKeys.(*stunreachability.TestKeys)
if *tk.Failure != errorx.FailureGenericTimeoutError {
if *tk.Failure != errorsx.FailureGenericTimeoutError {
t.Fatal("expected different failure here")
}
if tk.Endpoint != "stun.l.google.com:19302" {
@@ -11,7 +11,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
const (
@@ -56,7 +56,7 @@ func (tk *TestKeys) Update(v urlgetter.MultiOutput) {
tk.TelegramTCPBlocking = false
return // found successful access point connection
}
if v.TestKeys.FailedOperation == nil || *v.TestKeys.FailedOperation != errorx.ConnectOperation {
if v.TestKeys.FailedOperation == nil || *v.TestKeys.FailedOperation != errorsx.ConnectOperation {
tk.TelegramTCPBlocking = false
}
return
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -94,7 +94,7 @@ func TestUpdateWithNoAccessPointsBlocking(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -125,7 +125,7 @@ func TestUpdateWithNilFailedOperation(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -137,7 +137,7 @@ func TestUpdateWithNilFailedOperation(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -159,11 +159,11 @@ func TestUpdateWithNonConnectFailedOperation(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.ConnectOperation
s := errorsx.ConnectOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -175,11 +175,11 @@ func TestUpdateWithNonConnectFailedOperation(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.HTTPRoundTripOperation
s := errorsx.HTTPRoundTripOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -201,11 +201,11 @@ func TestUpdateWithAllConnectsFailed(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.ConnectOperation
s := errorsx.ConnectOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -217,11 +217,11 @@ func TestUpdateWithAllConnectsFailed(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.ConnectOperation
s := errorsx.ConnectOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -243,11 +243,11 @@ func TestUpdateWebWithMixedResults(t *testing.T) {
},
TestKeys: urlgetter.TestKeys{
FailedOperation: (func() *string {
s := errorx.HTTPRoundTripOperation
s := errorsx.HTTPRoundTripOperation
return &s
})(),
Failure: (func() *string {
s := errorx.FailureEOFError
s := errorsx.FailureEOFError
return &s
})(),
},
@@ -265,7 +265,7 @@ func TestUpdateWebWithMixedResults(t *testing.T) {
if tk.TelegramWebStatus != "blocked" {
t.Fatal("TelegramWebStatus should be blocked")
}
if *tk.TelegramWebFailure != errorx.FailureEOFError {
if *tk.TelegramWebFailure != errorsx.FailureEOFError {
t.Fatal("invalid TelegramWebFailure")
}
}
+2 -2
View File
@@ -18,7 +18,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonidatamodel"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonitemplates"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/runtimex"
"github.com/ooni/probe-cli/v3/internal/scrubber"
)
@@ -77,7 +77,7 @@ func (tr *TargetResults) fillSummary() {
if len(tr.TCPConnect) < 1 {
return
}
tr.Summary[errorx.ConnectOperation] = Summary{
tr.Summary[errorsx.ConnectOperation] = Summary{
Failure: tr.TCPConnect[0].Status.Failure,
}
switch tr.TargetProtocol {
+4 -4
View File
@@ -17,7 +17,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonitemplates"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/scrubber"
)
@@ -446,7 +446,7 @@ func TestSummary(t *testing.T) {
if len(tr.Summary) != 1 {
t.Fatal("cannot find expected entry")
}
if *tr.Summary[errorx.ConnectOperation].Failure != failure {
if *tr.Summary[errorsx.ConnectOperation].Failure != failure {
t.Fatal("invalid failure")
}
})
@@ -465,7 +465,7 @@ func TestSummary(t *testing.T) {
if len(tr.Summary) != 2 {
t.Fatal("cannot find expected entry")
}
if tr.Summary[errorx.ConnectOperation].Failure != nil {
if tr.Summary[errorsx.ConnectOperation].Failure != nil {
t.Fatal("invalid failure")
}
if *tr.Summary["handshake"].Failure != failure {
@@ -489,7 +489,7 @@ func TestSummary(t *testing.T) {
if len(tr.Summary) < 1 {
t.Fatal("cannot find expected entry")
}
if tr.Summary[errorx.ConnectOperation].Failure != nil {
if tr.Summary[errorsx.ConnectOperation].Failure != nil {
t.Fatal("invalid failure")
}
if handshake == nil {
@@ -8,8 +8,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/tunnel"
)
@@ -54,9 +54,9 @@ func (g Getter) Get(ctx context.Context) (TestKeys, error) {
tk, err := g.get(ctx, saver)
// Make sure we have an operation in cases where we fail before
// hitting our httptransport that does error wrapping.
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.TopLevelOperation,
Operation: errorsx.TopLevelOperation,
}.MaybeBuild()
tk.FailedOperation = archival.NewFailedOperation(err)
tk.Failure = archival.NewFailure(err)
@@ -10,7 +10,7 @@ import (
"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestGetterWithVeryShortTimeout(t *testing.T) {
@@ -31,7 +31,7 @@ func TestGetterWithVeryShortTimeout(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || *tk.Failure != "generic_timeout_error" {
@@ -98,7 +98,7 @@ func TestGetterWithCancelledContextVanilla(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || !strings.HasSuffix(*tk.Failure, "interrupted") {
@@ -166,7 +166,7 @@ func TestGetterWithCancelledContextAndMethod(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || !strings.HasSuffix(*tk.Failure, "interrupted") {
@@ -236,7 +236,7 @@ func TestGetterWithCancelledContextNoFollowRedirects(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || !strings.HasSuffix(*tk.Failure, "interrupted") {
@@ -306,7 +306,7 @@ func TestGetterWithCancelledContextCannotStartTunnel(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || *tk.Failure != "interrupted" {
@@ -361,7 +361,7 @@ func TestGetterWithCancelledContextUnknownResolverURL(t *testing.T) {
if tk.BootstrapTime != 0 {
t.Fatal("not the BootstrapTime we expected")
}
if tk.FailedOperation == nil || *tk.FailedOperation != errorx.TopLevelOperation {
if tk.FailedOperation == nil || *tk.FailedOperation != errorsx.TopLevelOperation {
t.Fatal("not the FailedOperation we expected")
}
if tk.Failure == nil || *tk.Failure != "unknown_failure: unsupported resolver scheme" {
@@ -446,7 +446,7 @@ func TestGetterIntegrationHTTPS(t *testing.T) {
resolveStart = true
case "resolve_done":
resolveDone = true
case errorx.ConnectOperation:
case errorsx.ConnectOperation:
connect = true
case "tls_handshake_start":
tlsHandshakeStart = true
@@ -587,7 +587,7 @@ func TestGetterIntegrationTLSHandshake(t *testing.T) {
resolveStart = true
case "resolve_done":
resolveDone = true
case errorx.ConnectOperation:
case errorsx.ConnectOperation:
connect = true
case "tls_handshake_start":
tlsHandshakeStart = true
@@ -705,7 +705,7 @@ func TestGetterHTTPSWithTunnel(t *testing.T) {
resolveStart = true
case "resolve_done":
resolveDone = true
case errorx.ConnectOperation:
case errorsx.ConnectOperation:
connect = true
case "tls_handshake_start":
tlsHandshakeStart = true
@@ -11,7 +11,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/httpheader"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/iox"
"github.com/ooni/probe-cli/v3/internal/runtimex"
)
@@ -19,9 +19,9 @@ import (
const httpRequestFailed = "http_request_failed"
// ErrHTTPRequestFailed indicates that the HTTP request failed.
var ErrHTTPRequestFailed = &errorx.ErrWrapper{
var ErrHTTPRequestFailed = &errorsx.ErrWrapper{
Failure: httpRequestFailed,
Operation: errorx.TopLevelOperation,
Operation: errorsx.TopLevelOperation,
WrappedErr: errors.New(httpRequestFailed),
}
@@ -6,7 +6,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/geolocate"
"github.com/ooni/probe-cli/v3/internal/engine/httpx"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// ControlRequest is the request that we send to the control
@@ -59,9 +59,9 @@ func Control(
}
sess.Logger().Infof("control for %s...", creq.HTTPRequest)
// make sure error is wrapped
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: clnt.PostJSON(ctx, "/", creq, &out),
Operation: errorx.TopLevelOperation,
Operation: errorsx.TopLevelOperation,
}.MaybeBuild()
sess.Logger().Infof("control for %s... %+v", creq.HTTPRequest, err)
(&out.DNS).FillASNs(sess)
@@ -4,7 +4,7 @@ import (
"net"
"net/url"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// DNSAnalysisResult contains the results of analysing comparing
@@ -44,7 +44,7 @@ func DNSAnalysis(URL *url.URL, measurement DNSLookupResult,
switch *control.DNS.Failure {
case DNSNameError: // the control returns this on NXDOMAIN error
switch *measurement.Failure {
case errorx.FailureDNSNXDOMAINError:
case errorsx.FailureDNSNXDOMAINError:
out.DNSConsistency = &DNSConsistent
}
}
@@ -7,11 +7,11 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestDNSAnalysis(t *testing.T) {
measurementFailure := errorx.FailureDNSNXDOMAINError
measurementFailure := errorsx.FailureDNSNXDOMAINError
controlFailure := webconnectivity.DNSNameError
eofFailure := io.EOF.Error()
type args struct {
@@ -5,7 +5,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity/internal"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// The following set of status flags identifies in a more nuanced way the
@@ -127,7 +127,7 @@ func Summarize(tk *TestKeys) (out Summary) {
// If DNS failed with NXDOMAIN and the control DNS is consistent, then it
// means this website does not exist anymore.
if tk.DNSExperimentFailure != nil &&
*tk.DNSExperimentFailure == errorx.FailureDNSNXDOMAINError &&
*tk.DNSExperimentFailure == errorsx.FailureDNSNXDOMAINError &&
tk.DNSConsistency != nil && *tk.DNSConsistency == DNSConsistent {
// TODO(bassosimone): MK flags this as accessible. This result is debatable. We
// are doing what MK does. But we most likely want to make it better later.
@@ -140,7 +140,7 @@ func Summarize(tk *TestKeys) (out Summary) {
// Otherwise, if DNS failed with NXDOMAIN, it's DNS based blocking.
// TODO(bassosimone): do we wanna include other errors here? Like timeout?
if tk.DNSExperimentFailure != nil &&
*tk.DNSExperimentFailure == errorx.FailureDNSNXDOMAINError {
*tk.DNSExperimentFailure == errorsx.FailureDNSNXDOMAINError {
out.Accessible = &inaccessible
out.BlockingReason = &dns
out.Status |= StatusAnomalyDNS | StatusExperimentDNS
@@ -184,41 +184,41 @@ func Summarize(tk *TestKeys) (out Summary) {
if tk.Requests[0].Failure != nil {
out.Status |= StatusExperimentHTTP
switch *tk.Requests[0].Failure {
case errorx.FailureConnectionRefused:
case errorsx.FailureConnectionRefused:
// This is possibly because a subsequent connection to some
// other endpoint has been blocked. We call this http-failure
// because this is what MK would actually do.
out.BlockingReason = &httpFailure
out.Accessible = &inaccessible
out.Status |= StatusAnomalyConnect
case errorx.FailureConnectionReset:
case errorsx.FailureConnectionReset:
// We don't currently support TLS failures and we don't have a
// way to know if it was during TLS or later. So, for now we are
// going to call this error condition an http-failure.
out.BlockingReason = &httpFailure
out.Accessible = &inaccessible
out.Status |= StatusAnomalyReadWrite
case errorx.FailureDNSNXDOMAINError:
case errorsx.FailureDNSNXDOMAINError:
// This is possibly because a subsequent resolution to
// some other domain name has been blocked.
out.BlockingReason = &dns
out.Accessible = &inaccessible
out.Status |= StatusAnomalyDNS
case errorx.FailureEOFError:
case errorsx.FailureEOFError:
// We have seen this happening with TLS handshakes as well as
// sometimes with HTTP blocking. So http-failure.
out.BlockingReason = &httpFailure
out.Accessible = &inaccessible
out.Status |= StatusAnomalyReadWrite
case errorx.FailureGenericTimeoutError:
case errorsx.FailureGenericTimeoutError:
// Alas, here we don't know whether it's connect or whether it's
// perhaps the TLS handshake. So use the same classification used by MK.
out.BlockingReason = &httpFailure
out.Accessible = &inaccessible
out.Status |= StatusAnomalyUnknown
case errorx.FailureSSLInvalidHostname,
errorx.FailureSSLInvalidCertificate,
errorx.FailureSSLUnknownAuthority:
case errorsx.FailureSSLInvalidHostname,
errorsx.FailureSSLInvalidCertificate,
errorsx.FailureSSLUnknownAuthority:
// We treat these three cases equally. Misconfiguration is a bit
// less likely since we also checked with the control. Since there
// is no TLS, for now we're going to call this http-failure.
@@ -7,7 +7,7 @@ import (
"github.com/google/go-cmp/cmp"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestSummarize(t *testing.T) {
@@ -18,14 +18,14 @@ func TestSummarize(t *testing.T) {
httpDiff = "http-diff"
httpFailure = "http-failure"
nilstring *string
probeConnectionRefused = errorx.FailureConnectionRefused
probeConnectionReset = errorx.FailureConnectionReset
probeEOFError = errorx.FailureEOFError
probeNXDOMAIN = errorx.FailureDNSNXDOMAINError
probeTimeout = errorx.FailureGenericTimeoutError
probeSSLInvalidHost = errorx.FailureSSLInvalidHostname
probeSSLInvalidCert = errorx.FailureSSLInvalidCertificate
probeSSLUnknownAuth = errorx.FailureSSLUnknownAuthority
probeConnectionRefused = errorsx.FailureConnectionRefused
probeConnectionReset = errorsx.FailureConnectionReset
probeEOFError = errorsx.FailureEOFError
probeNXDOMAIN = errorsx.FailureDNSNXDOMAINError
probeTimeout = errorsx.FailureGenericTimeoutError
probeSSLInvalidHost = errorsx.FailureSSLInvalidHostname
probeSSLInvalidCert = errorsx.FailureSSLInvalidCertificate
probeSSLUnknownAuth = errorsx.FailureSSLUnknownAuthority
tcpIP = "tcp_ip"
trueValue = true
)
@@ -13,7 +13,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewExperimentMeasurer(t *testing.T) {
@@ -69,10 +69,10 @@ func TestMeasureWithCancelledContext(t *testing.T) {
t.Fatal(err)
}
tk := measurement.TestKeys.(*webconnectivity.TestKeys)
if *tk.ControlFailure != errorx.FailureInterrupted {
if *tk.ControlFailure != errorsx.FailureInterrupted {
t.Fatal("unexpected control_failure")
}
if *tk.DNSExperimentFailure != errorx.FailureInterrupted {
if *tk.DNSExperimentFailure != errorsx.FailureInterrupted {
t.Fatal("unexpected dns_experiment_failure")
}
if tk.HTTPExperimentFailure != nil {
+4 -4
View File
@@ -8,7 +8,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/oldhttptransport"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"golang.org/x/net/http2"
)
@@ -81,10 +81,10 @@ func (t *HTTPTransport) RoundTrip(
resp, err = t.roundTripper.RoundTrip(req)
// For safety wrap the error as modelx.HTTPRoundTripOperation but this
// will only be used if the error chain does not contain any
// other major operation failure. See errorx.ErrWrapper.
err = errorx.SafeErrWrapperBuilder{
// other major operation failure. See errorsx.ErrWrapper.
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.HTTPRoundTripOperation,
Operation: errorsx.HTTPRoundTripOperation,
}.MaybeBuild()
return resp, err
}
+2 -2
View File
@@ -13,7 +13,7 @@ import (
"time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/iox"
)
@@ -148,7 +148,7 @@ func TestHTTPTransportTimeout(t *testing.T) {
if err == nil {
t.Fatal("expected an error here")
}
if !strings.HasSuffix(err.Error(), errorx.FailureGenericTimeoutError) {
if !strings.HasSuffix(err.Error(), errorsx.FailureGenericTimeoutError) {
t.Fatal("not the error we expected")
}
if resp != nil {
@@ -8,7 +8,7 @@ import (
"testing"
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewTLSConnectionState(t *testing.T) {
@@ -61,7 +61,7 @@ func TestMeasurementRootWithMeasurementRootPanic(t *testing.T) {
func TestErrWrapperPublicAPI(t *testing.T) {
child := errors.New("mocked error")
wrapper := &errorx.ErrWrapper{
wrapper := &errorsx.ErrWrapper{
Failure: "moobar",
WrappedErr: child,
}
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/atomicx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/iox"
)
@@ -83,7 +83,7 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
var (
err error
majorOp = errorx.HTTPRoundTripOperation
majorOp = errorsx.HTTPRoundTripOperation
majorOpMu sync.Mutex
requestBody []byte
requestHeaders = http.Header{}
@@ -103,7 +103,7 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
tracer := &httptrace.ClientTrace{
TLSHandshakeStart: func() {
majorOpMu.Lock()
majorOp = errorx.TLSHandshakeOperation
majorOp = errorsx.TLSHandshakeOperation
majorOpMu.Unlock()
// Event emitted by net/http when DialTLS is not
// configured in the http.Transport
@@ -116,9 +116,9 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
TLSHandshakeDone: func(state tls.ConnectionState, err error) {
// Wrapping the error even if we're not returning it because it may
// less confusing to users to see the wrapped name
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.TLSHandshakeOperation,
Operation: errorsx.TLSHandshakeOperation,
}.MaybeBuild()
durationSinceBeginning := time.Since(root.Beginning)
// Event emitted by net/http when DialTLS is not
@@ -133,7 +133,7 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
},
GotConn: func(info httptrace.GotConnInfo) {
majorOpMu.Lock()
majorOp = errorx.HTTPRoundTripOperation
majorOp = errorsx.HTTPRoundTripOperation
majorOpMu.Unlock()
root.Handler.OnMeasurement(modelx.Measurement{
HTTPConnectionReady: &modelx.HTTPConnectionReadyEvent{
@@ -171,9 +171,9 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
WroteRequest: func(info httptrace.WroteRequestInfo) {
// Wrapping the error even if we're not returning it because it may
// less confusing to users to see the wrapped name
err := errorx.SafeErrWrapperBuilder{
err := errorsx.SafeErrWrapperBuilder{
Error: info.Err,
Operation: errorx.HTTPRoundTripOperation,
Operation: errorsx.HTTPRoundTripOperation,
}.MaybeBuild()
root.Handler.OnMeasurement(modelx.Measurement{
HTTPRequestDone: &modelx.HTTPRequestDoneEvent{
@@ -207,7 +207,7 @@ func (t *TraceTripper) RoundTrip(req *http.Request) (*http.Response, error) {
}
resp, err := t.roundTripper.RoundTrip(req)
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: majorOp,
}.MaybeBuild()
@@ -19,7 +19,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonitemplates"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -418,7 +418,7 @@ func NewNetworkEventsList(results oonitemplates.Results) NetworkEventsList {
out = append(out, &NetworkEvent{
Address: in.Connect.RemoteAddress,
Failure: makeFailure(in.Connect.Error),
Operation: errorx.ConnectOperation,
Operation: errorsx.ConnectOperation,
T: in.Connect.DurationSinceBeginning.Seconds(),
})
// fallthrough
@@ -426,7 +426,7 @@ func NewNetworkEventsList(results oonitemplates.Results) NetworkEventsList {
if in.Read != nil {
out = append(out, &NetworkEvent{
Failure: makeFailure(in.Read.Error),
Operation: errorx.ReadOperation,
Operation: errorsx.ReadOperation,
NumBytes: in.Read.NumBytes,
T: in.Read.DurationSinceBeginning.Seconds(),
})
@@ -435,7 +435,7 @@ func NewNetworkEventsList(results oonitemplates.Results) NetworkEventsList {
if in.Write != nil {
out = append(out, &NetworkEvent{
Failure: makeFailure(in.Write.Error),
Operation: errorx.WriteOperation,
Operation: errorsx.WriteOperation,
NumBytes: in.Write.NumBytes,
T: in.Write.DurationSinceBeginning.Seconds(),
})
@@ -12,7 +12,7 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/oonitemplates"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewTCPConnectListEmpty(t *testing.T) {
@@ -67,7 +67,7 @@ func TestNewTCPConnectListFailure(t *testing.T) {
Connects: []*modelx.ConnectEvent{
{
RemoteAddress: "8.8.8.8:53",
Error: errors.New(errorx.FailureConnectionReset),
Error: errors.New(errorsx.FailureConnectionReset),
},
},
})
@@ -80,7 +80,7 @@ func TestNewTCPConnectListFailure(t *testing.T) {
if out[0].Port != 53 {
t.Fatal("unexpected out[0].Port")
}
if *out[0].Status.Failure != errorx.FailureConnectionReset {
if *out[0].Status.Failure != errorsx.FailureConnectionReset {
t.Fatal("unexpected out[0].Failure")
}
if out[0].Status.Success != false {
@@ -93,7 +93,7 @@ func TestNewTCPConnectListInvalidInput(t *testing.T) {
Connects: []*modelx.ConnectEvent{
{
RemoteAddress: "8.8.8.8",
Error: errors.New(errorx.FailureConnectionReset),
Error: errors.New(errorsx.FailureConnectionReset),
},
},
})
@@ -106,7 +106,7 @@ func TestNewTCPConnectListInvalidInput(t *testing.T) {
if out[0].Port != 0 {
t.Fatal("unexpected out[0].Port")
}
if *out[0].Status.Failure != errorx.FailureConnectionReset {
if *out[0].Status.Failure != errorsx.FailureConnectionReset {
t.Fatal("unexpected out[0].Failure")
}
if out[0].Status.Success != false {
@@ -649,7 +649,7 @@ func TestNewDNSQueriesListSuccess(t *testing.T) {
TransportNetwork: "system",
},
{
Error: errors.New(errorx.FailureDNSNXDOMAINError),
Error: errors.New(errorsx.FailureDNSNXDOMAINError),
Hostname: "dns.googlex",
TransportNetwork: "system",
},
@@ -768,7 +768,7 @@ func dnscheckbad(e DNSQueryEntry) error {
if e.Engine != "system" {
return errors.New("invalid engine")
}
if *e.Failure != errorx.FailureDNSNXDOMAINError {
if *e.Failure != errorsx.FailureDNSNXDOMAINError {
return errors.New("invalid failure")
}
if e.Hostname != "dns.googlex" {
@@ -854,7 +854,7 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[0].NumBytes != 0 {
t.Fatal("wrong out[0].NumBytes")
}
if out[0].Operation != errorx.ConnectOperation {
if out[0].Operation != errorsx.ConnectOperation {
t.Fatal("wrong out[0].Operation")
}
if !floatEquals(out[0].T, 0.010) {
@@ -870,7 +870,7 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[1].NumBytes != 1789 {
t.Fatal("wrong out[1].NumBytes")
}
if out[1].Operation != errorx.ReadOperation {
if out[1].Operation != errorsx.ReadOperation {
t.Fatal("wrong out[1].Operation")
}
if !floatEquals(out[1].T, 0.020) {
@@ -886,7 +886,7 @@ func TestNewNetworkEventsListGood(t *testing.T) {
if out[2].NumBytes != 17714 {
t.Fatal("wrong out[2].NumBytes")
}
if out[2].Operation != errorx.WriteOperation {
if out[2].Operation != errorsx.WriteOperation {
t.Fatal("wrong out[2].Operation")
}
if !floatEquals(out[2].T, 0.030) {
@@ -933,7 +933,7 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[0].NumBytes != 0 {
t.Fatal("wrong out[0].NumBytes")
}
if out[0].Operation != errorx.ConnectOperation {
if out[0].Operation != errorsx.ConnectOperation {
t.Fatal("wrong out[0].Operation")
}
if !floatEquals(out[0].T, 0.010) {
@@ -949,7 +949,7 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[1].NumBytes != 1789 {
t.Fatal("wrong out[1].NumBytes")
}
if out[1].Operation != errorx.ReadOperation {
if out[1].Operation != errorsx.ReadOperation {
t.Fatal("wrong out[1].Operation")
}
if !floatEquals(out[1].T, 0.020) {
@@ -965,7 +965,7 @@ func TestNewNetworkEventsListGoodUDPAndErrors(t *testing.T) {
if out[2].NumBytes != 17714 {
t.Fatal("wrong out[2].NumBytes")
}
if out[2].Operation != errorx.WriteOperation {
if out[2].Operation != errorsx.WriteOperation {
t.Fatal("wrong out[2].Operation")
}
if !floatEquals(out[2].T, 0.030) {
@@ -11,7 +11,7 @@ import (
goptlib "git.torproject.org/pluggable-transports/goptlib.git"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"gitlab.com/yawning/obfs4.git/transports"
obfs4base "gitlab.com/yawning/obfs4.git/transports/base"
)
@@ -55,7 +55,7 @@ func TestDNSLookupCancellation(t *testing.T) {
if results.Error == nil {
t.Fatal("expected an error here")
}
if results.Error.Error() != errorx.FailureGenericTimeoutError {
if results.Error.Error() != errorsx.FailureGenericTimeoutError {
t.Fatal("not the error we expected")
}
if len(results.Addresses) > 0 {
@@ -170,7 +170,7 @@ func TestTLSConnectCancellation(t *testing.T) {
if results.Error == nil {
t.Fatal("expected an error here")
}
if results.Error.Error() != errorx.FailureGenericTimeoutError {
if results.Error.Error() != errorsx.FailureGenericTimeoutError {
t.Fatal("not the error we expected")
}
}
+12 -12
View File
@@ -18,8 +18,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/geolocate"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// ExtSpec describes a data format extension
@@ -80,7 +80,7 @@ type TCPConnectEntry struct {
func NewTCPConnectList(begin time.Time, events []trace.Event) []TCPConnectEntry {
var out []TCPConnectEntry
for _, event := range events {
if event.Name != errorx.ConnectOperation {
if event.Name != errorsx.ConnectOperation {
continue
}
if event.Proto != "tcp" {
@@ -110,11 +110,11 @@ func NewFailure(err error) *string {
// The following code guarantees that the error is always wrapped even
// when we could not actually hit our code that does the wrapping. A case
// in which this happen is with context deadline for HTTP.
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.TopLevelOperation,
Operation: errorsx.TopLevelOperation,
}.MaybeBuild()
errWrapper := err.(*errorx.ErrWrapper)
errWrapper := err.(*errorsx.ErrWrapper)
s := errWrapper.Failure
if s == "" {
s = "unknown_failure: errWrapper.Failure is empty"
@@ -128,8 +128,8 @@ func NewFailedOperation(err error) *string {
return nil
}
var (
errWrapper *errorx.ErrWrapper
s = errorx.UnknownOperation
errWrapper *errorsx.ErrWrapper
s = errorsx.UnknownOperation
)
if errors.As(err, &errWrapper) && errWrapper.Operation != "" {
s = errWrapper.Operation
@@ -474,7 +474,7 @@ type NetworkEvent struct {
func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent {
var out []NetworkEvent
for _, ev := range events {
if ev.Name == errorx.ConnectOperation {
if ev.Name == errorsx.ConnectOperation {
out = append(out, NetworkEvent{
Address: ev.Address,
Failure: NewFailure(ev.Err),
@@ -484,7 +484,7 @@ func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent
})
continue
}
if ev.Name == errorx.ReadOperation {
if ev.Name == errorsx.ReadOperation {
out = append(out, NetworkEvent{
Failure: NewFailure(ev.Err),
Operation: ev.Name,
@@ -493,7 +493,7 @@ func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent
})
continue
}
if ev.Name == errorx.WriteOperation {
if ev.Name == errorsx.WriteOperation {
out = append(out, NetworkEvent{
Failure: NewFailure(ev.Err),
Operation: ev.Name,
@@ -502,7 +502,7 @@ func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent
})
continue
}
if ev.Name == errorx.ReadFromOperation {
if ev.Name == errorsx.ReadFromOperation {
out = append(out, NetworkEvent{
Address: ev.Address,
Failure: NewFailure(ev.Err),
@@ -512,7 +512,7 @@ func NewNetworkEventsList(begin time.Time, events []trace.Event) []NetworkEvent
})
continue
}
if ev.Name == errorx.WriteToOperation {
if ev.Name == errorsx.WriteToOperation {
out = append(out, NetworkEvent{
Address: ev.Address,
Failure: NewFailure(ev.Err),
+34 -34
View File
@@ -14,8 +14,8 @@ import (
"github.com/gorilla/websocket"
"github.com/ooni/probe-cli/v3/internal/engine/model"
"github.com/ooni/probe-cli/v3/internal/engine/netx/archival"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestNewTCPConnectList(t *testing.T) {
@@ -47,20 +47,20 @@ func TestNewTCPConnectList(t *testing.T) {
}, {
Address: "8.8.8.8:853",
Duration: 30 * time.Millisecond,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: "tcp",
Time: begin.Add(130 * time.Millisecond),
}, {
Address: "8.8.8.8:853",
Duration: 55 * time.Millisecond,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: "udp",
Time: begin.Add(130 * time.Millisecond),
}, {
Address: "8.8.4.4:53",
Duration: 50 * time.Millisecond,
Err: io.EOF,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: "tcp",
Time: begin.Add(180 * time.Millisecond),
}},
@@ -314,14 +314,14 @@ func TestNewDNSQueriesList(t *testing.T) {
}, {
Address: "8.8.8.8:853",
Duration: 30 * time.Millisecond,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: "tcp",
Time: begin.Add(130 * time.Millisecond),
}, {
Address: "8.8.4.4:53",
Duration: 50 * time.Millisecond,
Err: io.EOF,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: "tcp",
Time: begin.Add(180 * time.Millisecond),
}},
@@ -371,7 +371,7 @@ func TestNewDNSQueriesList(t *testing.T) {
args: args{
begin: begin,
events: []trace.Event{{
Err: &errorx.ErrWrapper{Failure: errorx.FailureDNSNXDOMAINError},
Err: &errorsx.ErrWrapper{Failure: errorsx.FailureDNSNXDOMAINError},
Hostname: "dns.google.com",
Name: "resolve_done",
Time: begin.Add(200 * time.Millisecond),
@@ -380,14 +380,14 @@ func TestNewDNSQueriesList(t *testing.T) {
want: []archival.DNSQueryEntry{{
Answers: nil,
Failure: archival.NewFailure(
&errorx.ErrWrapper{Failure: errorx.FailureDNSNXDOMAINError}),
&errorsx.ErrWrapper{Failure: errorsx.FailureDNSNXDOMAINError}),
Hostname: "dns.google.com",
QueryType: "A",
T: 0.2,
}, {
Answers: nil,
Failure: archival.NewFailure(
&errorx.ErrWrapper{Failure: errorx.FailureDNSNXDOMAINError}),
&errorsx.ErrWrapper{Failure: errorsx.FailureDNSNXDOMAINError}),
Hostname: "dns.google.com",
QueryType: "AAAA",
T: 0.2,
@@ -425,35 +425,35 @@ func TestNewNetworkEventsList(t *testing.T) {
args: args{
begin: begin,
events: []trace.Event{{
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Address: "8.8.8.8:853",
Err: io.EOF,
Proto: "tcp",
Time: begin.Add(7 * time.Millisecond),
}, {
Name: errorx.ReadOperation,
Name: errorsx.ReadOperation,
Err: context.Canceled,
NumBytes: 7117,
Time: begin.Add(11 * time.Millisecond),
}, {
Address: "8.8.8.8:853",
Name: errorx.ReadFromOperation,
Name: errorsx.ReadFromOperation,
Err: context.Canceled,
NumBytes: 7117,
Time: begin.Add(11 * time.Millisecond),
}, {
Name: errorx.WriteOperation,
Name: errorsx.WriteOperation,
Err: websocket.ErrBadHandshake,
NumBytes: 4114,
Time: begin.Add(14 * time.Millisecond),
}, {
Address: "8.8.8.8:853",
Name: errorx.WriteToOperation,
Name: errorsx.WriteToOperation,
Err: websocket.ErrBadHandshake,
NumBytes: 4114,
Time: begin.Add(14 * time.Millisecond),
}, {
Name: errorx.CloseOperation,
Name: errorsx.CloseOperation,
Err: websocket.ErrReadLimit,
Time: begin.Add(17 * time.Millisecond),
}},
@@ -461,34 +461,34 @@ func TestNewNetworkEventsList(t *testing.T) {
want: []archival.NetworkEvent{{
Address: "8.8.8.8:853",
Failure: archival.NewFailure(io.EOF),
Operation: errorx.ConnectOperation,
Operation: errorsx.ConnectOperation,
Proto: "tcp",
T: 0.007,
}, {
Failure: archival.NewFailure(context.Canceled),
NumBytes: 7117,
Operation: errorx.ReadOperation,
Operation: errorsx.ReadOperation,
T: 0.011,
}, {
Address: "8.8.8.8:853",
Failure: archival.NewFailure(context.Canceled),
NumBytes: 7117,
Operation: errorx.ReadFromOperation,
Operation: errorsx.ReadFromOperation,
T: 0.011,
}, {
Failure: archival.NewFailure(websocket.ErrBadHandshake),
NumBytes: 4114,
Operation: errorx.WriteOperation,
Operation: errorsx.WriteOperation,
T: 0.014,
}, {
Address: "8.8.8.8:853",
Failure: archival.NewFailure(websocket.ErrBadHandshake),
NumBytes: 4114,
Operation: errorx.WriteToOperation,
Operation: errorsx.WriteToOperation,
T: 0.014,
}, {
Failure: archival.NewFailure(websocket.ErrReadLimit),
Operation: errorx.CloseOperation,
Operation: errorsx.CloseOperation,
T: 0.017,
}},
}}
@@ -523,7 +523,7 @@ func TestNewTLSHandshakesList(t *testing.T) {
args: args{
begin: begin,
events: []trace.Event{{
Name: errorx.CloseOperation,
Name: errorsx.CloseOperation,
Err: websocket.ErrReadLimit,
Time: begin.Add(17 * time.Millisecond),
}, {
@@ -929,18 +929,18 @@ func TestNewFailure(t *testing.T) {
}, {
name: "when error is wrapped and failure meaningful",
args: args{
err: &errorx.ErrWrapper{
Failure: errorx.FailureConnectionRefused,
err: &errorsx.ErrWrapper{
Failure: errorsx.FailureConnectionRefused,
},
},
want: func() *string {
s := errorx.FailureConnectionRefused
s := errorsx.FailureConnectionRefused
return &s
}(),
}, {
name: "when error is wrapped and failure is not meaningful",
args: args{
err: &errorx.ErrWrapper{},
err: &errorsx.ErrWrapper{},
},
want: func() *string {
s := "unknown_failure: errWrapper.Failure is empty"
@@ -1002,24 +1002,24 @@ func TestNewFailedOperation(t *testing.T) {
}, {
name: "With wrapped error and non-empty operation",
args: args{
err: &errorx.ErrWrapper{
Failure: errorx.FailureConnectionRefused,
Operation: errorx.ConnectOperation,
err: &errorsx.ErrWrapper{
Failure: errorsx.FailureConnectionRefused,
Operation: errorsx.ConnectOperation,
},
},
want: (func() *string {
s := errorx.ConnectOperation
s := errorsx.ConnectOperation
return &s
})(),
}, {
name: "With wrapped error and empty operation",
args: args{
err: &errorx.ErrWrapper{
Failure: errorx.FailureConnectionRefused,
err: &errorsx.ErrWrapper{
Failure: errorsx.FailureConnectionRefused,
},
},
want: (func() *string {
s := errorx.UnknownOperation
s := errorsx.UnknownOperation
return &s
})(),
}, {
@@ -1028,7 +1028,7 @@ func TestNewFailedOperation(t *testing.T) {
err: io.EOF,
},
want: (func() *string {
s := errorx.UnknownOperation
s := errorsx.UnknownOperation
return &s
})(),
}}
+9 -9
View File
@@ -4,7 +4,7 @@ import (
"context"
"net"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// errorWrapperDialer is a dialer that performs err wrapping
@@ -15,9 +15,9 @@ type errorWrapperDialer struct {
// DialContext implements Dialer.DialContext
func (d *errorWrapperDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
conn, err := d.Dialer.DialContext(ctx, network, address)
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.ConnectOperation,
Operation: errorsx.ConnectOperation,
}.MaybeBuild()
if err != nil {
return nil, err
@@ -33,9 +33,9 @@ type errorWrapperConn struct {
// Read implements net.Conn.Read
func (c *errorWrapperConn) Read(b []byte) (n int, err error) {
n, err = c.Conn.Read(b)
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.ReadOperation,
Operation: errorsx.ReadOperation,
}.MaybeBuild()
return
}
@@ -43,9 +43,9 @@ func (c *errorWrapperConn) Read(b []byte) (n int, err error) {
// Write implements net.Conn.Write
func (c *errorWrapperConn) Write(b []byte) (n int, err error) {
n, err = c.Conn.Write(b)
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.WriteOperation,
Operation: errorsx.WriteOperation,
}.MaybeBuild()
return
}
@@ -53,9 +53,9 @@ func (c *errorWrapperConn) Write(b []byte) (n int, err error) {
// Close implements net.Conn.Close
func (c *errorWrapperConn) Close() (err error) {
err = c.Conn.Close()
err = errorx.SafeErrWrapperBuilder{
err = errorsx.SafeErrWrapperBuilder{
Error: err,
Operation: errorx.CloseOperation,
Operation: errorsx.CloseOperation,
}.MaybeBuild()
return
}
@@ -7,7 +7,7 @@ import (
"net"
"testing"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxmocks"
)
@@ -22,21 +22,21 @@ func TestErrorWrapperFailure(t *testing.T) {
if conn != nil {
t.Fatal("expected a nil conn here")
}
errorWrapperCheckErr(t, err, errorx.ConnectOperation)
errorWrapperCheckErr(t, err, errorsx.ConnectOperation)
}
func errorWrapperCheckErr(t *testing.T, err error, op string) {
if !errors.Is(err, io.EOF) {
t.Fatal("expected another error here")
}
var errWrapper *errorx.ErrWrapper
var errWrapper *errorsx.ErrWrapper
if !errors.As(err, &errWrapper) {
t.Fatal("cannot cast to ErrWrapper")
}
if errWrapper.Operation != op {
t.Fatal("unexpected Operation")
}
if errWrapper.Failure != errorx.FailureEOFError {
if errWrapper.Failure != errorsx.FailureEOFError {
t.Fatal("unexpected failure")
}
}
@@ -69,11 +69,11 @@ func TestErrorWrapperSuccess(t *testing.T) {
t.Fatal("expected non-nil conn here")
}
count, err := conn.Read(nil)
errorWrapperCheckIOResult(t, count, err, errorx.ReadOperation)
errorWrapperCheckIOResult(t, count, err, errorsx.ReadOperation)
count, err = conn.Write(nil)
errorWrapperCheckIOResult(t, count, err, errorx.WriteOperation)
errorWrapperCheckIOResult(t, count, err, errorsx.WriteOperation)
err = conn.Close()
errorWrapperCheckErr(t, err, errorx.CloseOperation)
errorWrapperCheckErr(t, err, errorsx.CloseOperation)
}
func errorWrapperCheckIOResult(t *testing.T, count int, err error, op string) {
+4 -4
View File
@@ -5,8 +5,8 @@ import (
"net"
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// saverDialer saves events occurring during the dial
@@ -24,7 +24,7 @@ func (d *saverDialer) DialContext(ctx context.Context, network, address string)
Address: address,
Duration: stop.Sub(start),
Err: err,
Name: errorx.ConnectOperation,
Name: errorsx.ConnectOperation,
Proto: network,
Time: stop,
})
@@ -61,7 +61,7 @@ func (c *saverConn) Read(p []byte) (int, error) {
Duration: stop.Sub(start),
Err: err,
NumBytes: count,
Name: errorx.ReadOperation,
Name: errorsx.ReadOperation,
Time: stop,
})
return count, err
@@ -76,7 +76,7 @@ func (c *saverConn) Write(p []byte) (int, error) {
Duration: stop.Sub(start),
Err: err,
NumBytes: count,
Name: errorx.WriteOperation,
Name: errorsx.WriteOperation,
Time: stop,
})
return count, err
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"testing"
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxmocks"
)
@@ -44,7 +44,7 @@ func TestSaverDialerFailure(t *testing.T) {
if !errors.Is(ev[0].Err, expected) {
t.Fatal("unexpected Err")
}
if ev[0].Name != errorx.ConnectOperation {
if ev[0].Name != errorsx.ConnectOperation {
t.Fatal("unexpected Name")
}
if ev[0].Proto != "tcp" {
-34
View File
@@ -1,34 +0,0 @@
package errorx
import "golang.org/x/sys/unix"
const (
ECANCELED = unix.ECANCELED
ECONNREFUSED = unix.ECONNREFUSED
ECONNRESET = unix.ECONNRESET
EHOSTUNREACH = unix.EHOSTUNREACH
ETIMEDOUT = unix.ETIMEDOUT
EAFNOSUPPORT = unix.EAFNOSUPPORT
EADDRINUSE = unix.EADDRINUSE
EADDRNOTAVAIL = unix.EADDRNOTAVAIL
EISCONN = unix.EISCONN
EFAULT = unix.EFAULT
EBADF = unix.EBADF
ECONNABORTED = unix.ECONNABORTED
EALREADY = unix.EALREADY
EDESTADDRREQ = unix.EDESTADDRREQ
EINTR = unix.EINTR
EINVAL = unix.EINVAL
EMSGSIZE = unix.EMSGSIZE
ENETDOWN = unix.ENETDOWN
ENETRESET = unix.ENETRESET
ENETUNREACH = unix.ENETUNREACH
ENOBUFS = unix.ENOBUFS
ENOPROTOOPT = unix.ENOPROTOOPT
ENOTSOCK = unix.ENOTSOCK
ENOTCONN = unix.ENOTCONN
EWOULDBLOCK = unix.EWOULDBLOCK
EACCES = unix.EACCES
EPROTONOSUPPORT = unix.EPROTONOSUPPORT
EPROTOTYPE = unix.EPROTOTYPE
)
@@ -1,34 +0,0 @@
package errorx
import "golang.org/x/sys/windows"
const (
ECANCELED = windows.ECANCELED
ECONNREFUSED = windows.ECONNREFUSED
ECONNRESET = windows.ECONNRESET
EHOSTUNREACH = windows.EHOSTUNREACH
ETIMEDOUT = windows.ETIMEDOUT
EAFNOSUPPORT = windows.EAFNOSUPPORT
EADDRINUSE = windows.EADDRINUSE
EADDRNOTAVAIL = windows.EADDRNOTAVAIL
EISCONN = windows.EISCONN
EFAULT = windows.EFAULT
EBADF = windows.EBADF
ECONNABORTED = windows.ECONNABORTED
EALREADY = windows.EALREADY
EDESTADDRREQ = windows.EDESTADDRREQ
EINTR = windows.EINTR
EINVAL = windows.EINVAL
EMSGSIZE = windows.EMSGSIZE
ENETDOWN = windows.ENETDOWN
ENETRESET = windows.ENETRESET
ENETUNREACH = windows.ENETUNREACH
ENOBUFS = windows.ENOBUFS
ENOPROTOOPT = windows.ENOPROTOOPT
ENOTSOCK = windows.ENOTSOCK
ENOTCONN = windows.ENOTCONN
EWOULDBLOCK = windows.EWOULDBLOCK
EACCES = windows.EACCES
EPROTONOSUPPORT = windows.EPROTONOSUPPORT
EPROTOTYPE = windows.EPROTOTYPE
)
-400
View File
@@ -1,400 +0,0 @@
// Package errorx contains error extensions
package errorx
// TODO: eventually we want to re-structure the error classification code by clearly separating the layers where the error occur:
//
// - errno.go and errno_test.go: contain only the errno classifier (for system errors)
// - qtls.go and qtls_test.go: contain qtls dialers, handshaker, classifier
// - tls.go and tls_test.go: contain tls dialers, handshaker, classifier
// - resolver.go and resolver_test.go: contain dialers and classifier for resolving
import (
"context"
"crypto/x509"
"errors"
"fmt"
"strings"
"syscall"
"github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/scrubber"
)
const (
// FailureConnectionRefused means ECONNREFUSED.
FailureConnectionRefused = "connection_refused"
// FailureConnectionReset means ECONNRESET.
FailureConnectionReset = "connection_reset"
// FailureDNSBogonError means we detected bogon in DNS reply.
FailureDNSBogonError = "dns_bogon_error"
// FailureDNSNXDOMAINError means we got NXDOMAIN in DNS reply.
FailureDNSNXDOMAINError = "dns_nxdomain_error"
// FailureEOFError means we got unexpected EOF on connection.
FailureEOFError = "eof_error"
// FailureGenericTimeoutError means we got some timer has expired.
FailureGenericTimeoutError = "generic_timeout_error"
// FailureHostUnreachable means that there is "no route to host".
FailureHostUnreachable = "host_unreachable"
// FailureInterrupted means that the user interrupted us.
FailureInterrupted = "interrupted"
// FailureNoCompatibleQUICVersion means that the server does not support the proposed QUIC version
FailureNoCompatibleQUICVersion = "quic_incompatible_version"
// FailureSSLHandshake means that the negotiation of cryptographic parameters failed
FailureSSLHandshake = "ssl_failed_handshake"
// FailureSSLInvalidHostname means we got certificate is not valid for SNI.
FailureSSLInvalidHostname = "ssl_invalid_hostname"
// FailureSSLUnknownAuthority means we cannot find CA validating certificate.
FailureSSLUnknownAuthority = "ssl_unknown_authority"
// FailureSSLInvalidCertificate means certificate experired or other
// sort of errors causing it to be invalid.
FailureSSLInvalidCertificate = "ssl_invalid_certificate"
// FailureJSONParseError indicates that we couldn't parse a JSON
FailureJSONParseError = "json_parse_error"
)
// TLS alert protocol as defined in RFC8446
const (
// Sender was unable to negotiate an acceptable set of security parameters given the options available.
TLSAlertHandshakeFailure = 40
// Certificate was corrupt, contained signatures that did not verify correctly, etc.
TLSAlertBadCertificate = 42
// Certificate was of an unsupported type.
TLSAlertUnsupportedCertificate = 43
// Certificate was revoked by its signer.
TLSAlertCertificateRevoked = 44
// Certificate has expired or is not currently valid.
TLSAlertCertificateExpired = 45
// Some unspecified issue arose in processing the certificate, rendering it unacceptable.
TLSAlertCertificateUnknown = 46
// Certificate was not accepted because the CA certificate could not be located or could not be matched with a known trust anchor.
TLSAlertUnknownCA = 48
// Handshake (not record layer) cryptographic operation failed.
TLSAlertDecryptError = 51
// Sent by servers when no server exists identified by the name provided by the client via the "server_name" extension.
TLSUnrecognizedName = 112
)
const (
// ResolveOperation is the operation where we resolve a domain name
ResolveOperation = "resolve"
// ConnectOperation is the operation where we do a TCP connect
ConnectOperation = "connect"
// TLSHandshakeOperation is the TLS handshake
TLSHandshakeOperation = "tls_handshake"
// QUICHandshakeOperation is the handshake to setup a QUIC connection
QUICHandshakeOperation = "quic_handshake"
// HTTPRoundTripOperation is the HTTP round trip
HTTPRoundTripOperation = "http_round_trip"
// CloseOperation is when we close a socket
CloseOperation = "close"
// ReadOperation is when we read from a socket
ReadOperation = "read"
// WriteOperation is when we write to a socket
WriteOperation = "write"
// ReadFromOperation is when we read from an UDP socket
ReadFromOperation = "read_from"
// WriteToOperation is when we write to an UDP socket
WriteToOperation = "write_to"
// UnknownOperation is when we cannot determine the operation
UnknownOperation = "unknown"
// TopLevelOperation is used when the failure happens at top level. This
// happens for example with urlgetter with a cancelled context.
TopLevelOperation = "top_level"
)
// ErrDNSBogon indicates that we found a bogon address. This is the
// correct value with which to initialize MeasurementRoot.ErrDNSBogon
// to tell this library to return an error when a bogon is found.
var ErrDNSBogon = errors.New("dns: detected bogon address")
// ErrWrapper is our error wrapper for Go errors. The key objective of
// this structure is to properly set Failure, which is also returned by
// the Error() method, so be one of the OONI defined strings.
type ErrWrapper struct {
// Failure is the OONI failure string. The failure strings are
// loosely backward compatible with Measurement Kit.
//
// This is either one of the FailureXXX strings or any other
// string like `unknown_failure ...`. The latter represents an
// error that we have not yet mapped to a failure.
Failure string
// Operation is the operation that failed. If possible, it
// SHOULD be a _major_ operation. Major operations are:
//
// - ResolveOperation: resolving a domain name failed
// - ConnectOperation: connecting to an IP failed
// - TLSHandshakeOperation: TLS handshaking failed
// - HTTPRoundTripOperation: other errors during round trip
//
// Because a network connection doesn't necessarily know
// what is the current major operation we also have the
// following _minor_ operations:
//
// - CloseOperation: CLOSE failed
// - ReadOperation: READ failed
// - WriteOperation: WRITE failed
//
// If an ErrWrapper referring to a major operation is wrapping
// another ErrWrapper and such ErrWrapper already refers to
// a major operation, then the new ErrWrapper should use the
// child ErrWrapper major operation. Otherwise, it should use
// its own major operation. This way, the topmost wrapper is
// supposed to refer to the major operation that failed.
Operation string
// WrappedErr is the error that we're wrapping.
WrappedErr error
}
// Error returns a description of the error that occurred.
func (e *ErrWrapper) Error() string {
return e.Failure
}
// Unwrap allows to access the underlying error
func (e *ErrWrapper) Unwrap() error {
return e.WrappedErr
}
// SafeErrWrapperBuilder contains a builder for ErrWrapper that
// is safe, i.e., behaves correctly when the error is nil.
type SafeErrWrapperBuilder struct {
// Error is the error, if any
Error error
// Classifier is the local error to string classifier. When there is no
// configured classifier we will use the generic classifier.
Classifier func(err error) string
// Operation is the operation that failed
Operation string
}
// MaybeBuild builds a new ErrWrapper, if b.Error is not nil, and returns
// a nil error value, instead, if b.Error is nil.
func (b SafeErrWrapperBuilder) MaybeBuild() (err error) {
if b.Error != nil {
classifier := b.Classifier
if classifier == nil {
classifier = toFailureString
}
err = &ErrWrapper{
Failure: classifier(b.Error),
Operation: toOperationString(b.Error, b.Operation),
WrappedErr: b.Error,
}
}
return
}
// TODO (kelmenhorst, bassosimone):
// Use errors.Is / errors.As more often, when possible, in this classifier.
// These methods are more robust to library changes than strings.
// errors.Is / errors.As can only be used when the error is exported.
func toFailureString(err error) string {
// The list returned here matches the values used by MK unless
// explicitly noted otherwise with a comment.
var errwrapper *ErrWrapper
if errors.As(err, &errwrapper) {
return errwrapper.Error() // we've already wrapped it
}
// filter out system errors: necessary to detect all windows errors
// https://github.com/ooni/probe/issues/1526 describes the problem of mapping localized windows errors
var errno syscall.Errno
if errors.As(err, &errno) {
switch errno {
case ECANCELED:
return FailureInterrupted
case ECONNRESET:
return FailureConnectionReset
case ECONNREFUSED:
return FailureConnectionRefused
case EHOSTUNREACH:
return FailureHostUnreachable
case ETIMEDOUT:
return FailureGenericTimeoutError
// TODO(kelmenhorst): find out if we need more system errors here
}
}
if errors.Is(err, context.Canceled) {
return FailureInterrupted
}
s := err.Error()
if strings.HasSuffix(s, "operation was canceled") {
return FailureInterrupted
}
if strings.HasSuffix(s, "EOF") {
return FailureEOFError
}
if strings.HasSuffix(s, "context deadline exceeded") {
return FailureGenericTimeoutError
}
if strings.HasSuffix(s, "transaction is timed out") {
return FailureGenericTimeoutError
}
if strings.HasSuffix(s, "i/o timeout") {
return FailureGenericTimeoutError
}
// TODO(kelmenhorst,bassosimone): this can probably be moved since it's TLS specific
if strings.HasSuffix(s, "TLS handshake timeout") {
return FailureGenericTimeoutError
}
if strings.HasSuffix(s, "no such host") {
// This is dns_lookup_error in MK but such error is used as a
// generic "hey, the lookup failed" error. Instead, this error
// that we return here is significantly more specific.
return FailureDNSNXDOMAINError
}
formatted := fmt.Sprintf("unknown_failure: %s", s)
return scrubber.Scrub(formatted) // scrub IP addresses in the error
}
// ClassifyQUICFailure is a classifier to translate QUIC errors to OONI error strings.
// TODO(kelmenhorst,bassosimone): Consider moving this into quicdialer.
func ClassifyQUICFailure(err error) string {
var versionNegotiation *quic.VersionNegotiationError
var statelessReset *quic.StatelessResetError
var handshakeTimeout *quic.HandshakeTimeoutError
var idleTimeout *quic.IdleTimeoutError
var transportError *quic.TransportError
if errors.As(err, &versionNegotiation) {
return FailureNoCompatibleQUICVersion
}
if errors.As(err, &statelessReset) {
return FailureConnectionReset
}
if errors.As(err, &handshakeTimeout) {
return FailureGenericTimeoutError
}
if errors.As(err, &idleTimeout) {
return FailureGenericTimeoutError
}
if errors.As(err, &transportError) {
if transportError.ErrorCode == quic.ConnectionRefused {
return FailureConnectionRefused
}
// the TLS Alert constants are taken from RFC8446
errCode := uint8(transportError.ErrorCode)
if isCertificateError(errCode) {
return FailureSSLInvalidCertificate
}
// TLSAlertDecryptError and TLSAlertHandshakeFailure are summarized to a FailureSSLHandshake error because both
// alerts are caused by a failed or corrupted parameter negotiation during the TLS handshake.
if errCode == TLSAlertDecryptError || errCode == TLSAlertHandshakeFailure {
return FailureSSLHandshake
}
if errCode == TLSAlertUnknownCA {
return FailureSSLUnknownAuthority
}
if errCode == TLSUnrecognizedName {
return FailureSSLInvalidHostname
}
}
return toFailureString(err)
}
// ClassifyResolveFailure is a classifier to translate DNS resolving errors to OONI error strings.
// TODO(kelmenhorst,bassosimone): Consider moving this into resolve.
func ClassifyResolveFailure(err error) string {
if errors.Is(err, ErrDNSBogon) {
return FailureDNSBogonError // not in MK
}
return toFailureString(err)
}
// ClassifyTLSFailure is a classifier to translate TLS errors to OONI error strings.
// TODO(kelmenhorst,bassosimone): Consider moving this into tlsdialer.
func ClassifyTLSFailure(err error) string {
var x509HostnameError x509.HostnameError
if errors.As(err, &x509HostnameError) {
// Test case: https://wrong.host.badssl.com/
return FailureSSLInvalidHostname
}
var x509UnknownAuthorityError x509.UnknownAuthorityError
if errors.As(err, &x509UnknownAuthorityError) {
// Test case: https://self-signed.badssl.com/. This error has
// never been among the ones returned by MK.
return FailureSSLUnknownAuthority
}
var x509CertificateInvalidError x509.CertificateInvalidError
if errors.As(err, &x509CertificateInvalidError) {
// Test case: https://expired.badssl.com/
return FailureSSLInvalidCertificate
}
return toFailureString(err)
}
func toOperationString(err error, operation string) string {
var errwrapper *ErrWrapper
if errors.As(err, &errwrapper) {
// Basically, as explained in ErrWrapper docs, let's
// keep the child major operation, if any.
if errwrapper.Operation == ConnectOperation {
return errwrapper.Operation
}
if errwrapper.Operation == HTTPRoundTripOperation {
return errwrapper.Operation
}
if errwrapper.Operation == ResolveOperation {
return errwrapper.Operation
}
if errwrapper.Operation == TLSHandshakeOperation {
return errwrapper.Operation
}
if errwrapper.Operation == QUICHandshakeOperation {
return errwrapper.Operation
}
if errwrapper.Operation == "quic_handshake_start" {
return QUICHandshakeOperation
}
if errwrapper.Operation == "quic_handshake_done" {
return QUICHandshakeOperation
}
// FALLTHROUGH
}
return operation
}
func isCertificateError(alert uint8) bool {
return (alert == TLSAlertBadCertificate ||
alert == TLSAlertUnsupportedCertificate ||
alert == TLSAlertCertificateExpired ||
alert == TLSAlertCertificateRevoked ||
alert == TLSAlertCertificateUnknown)
}
-290
View File
@@ -1,290 +0,0 @@
package errorx
import (
"context"
"crypto/tls"
"crypto/x509"
"errors"
"io"
"net"
"syscall"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/lucas-clemente/quic-go"
"github.com/pion/stun"
)
func TestMaybeBuildFactory(t *testing.T) {
err := SafeErrWrapperBuilder{
Error: errors.New("mocked error"),
}.MaybeBuild()
var target *ErrWrapper
if errors.As(err, &target) == false {
t.Fatal("not the expected error type")
}
if target.Failure != "unknown_failure: mocked error" {
t.Fatal("the failure string is wrong")
}
if target.WrappedErr.Error() != "mocked error" {
t.Fatal("the wrapped error is wrong")
}
}
func TestToFailureString(t *testing.T) {
t.Run("for already wrapped error", func(t *testing.T) {
err := SafeErrWrapperBuilder{Error: io.EOF}.MaybeBuild()
if toFailureString(err) != FailureEOFError {
t.Fatal("unexpected result")
}
})
t.Run("for context.Canceled", func(t *testing.T) {
if toFailureString(context.Canceled) != FailureInterrupted {
t.Fatal("unexpected result")
}
})
t.Run("for operation was canceled error", func(t *testing.T) {
if toFailureString(errors.New("operation was canceled")) != FailureInterrupted {
t.Fatal("unexpected result")
}
})
t.Run("for EOF", func(t *testing.T) {
if toFailureString(io.EOF) != FailureEOFError {
t.Fatal("unexpected results")
}
})
t.Run("for canceled", func(t *testing.T) {
if toFailureString(syscall.ECANCELED) != FailureInterrupted {
t.Fatal("unexpected results")
}
})
t.Run("for connection_refused", func(t *testing.T) {
if toFailureString(syscall.ECONNREFUSED) != FailureConnectionRefused {
t.Fatal("unexpected results")
}
})
t.Run("for connection_reset", func(t *testing.T) {
if toFailureString(syscall.ECONNRESET) != FailureConnectionReset {
t.Fatal("unexpected results")
}
})
t.Run("for host_unreachable", func(t *testing.T) {
if toFailureString(syscall.EHOSTUNREACH) != FailureHostUnreachable {
t.Fatal("unexpected results")
}
})
t.Run("for system timeout", func(t *testing.T) {
if toFailureString(syscall.ETIMEDOUT) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for context deadline exceeded", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1)
defer cancel()
<-ctx.Done()
if toFailureString(ctx.Err()) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for stun's transaction is timed out", func(t *testing.T) {
if toFailureString(stun.ErrTransactionTimeOut) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for i/o error", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1)
defer cancel() // fail immediately
conn, err := (&net.Dialer{}).DialContext(ctx, "tcp", "www.google.com:80")
if err == nil {
t.Fatal("expected an error here")
}
if conn != nil {
t.Fatal("expected nil connection here")
}
if toFailureString(err) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for TLS handshake timeout error", func(t *testing.T) {
err := errors.New("net/http: TLS handshake timeout")
if toFailureString(err) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for no such host", func(t *testing.T) {
if toFailureString(&net.DNSError{
Err: "no such host",
}) != FailureDNSNXDOMAINError {
t.Fatal("unexpected results")
}
})
t.Run("for errors including IPv4 address", func(t *testing.T) {
input := errors.New("read tcp 10.0.2.15:56948->93.184.216.34:443: use of closed network connection")
expected := "unknown_failure: read tcp [scrubbed]->[scrubbed]: use of closed network connection"
out := toFailureString(input)
if out != expected {
t.Fatal(cmp.Diff(expected, out))
}
})
t.Run("for errors including IPv6 address", func(t *testing.T) {
input := errors.New("read tcp [::1]:56948->[::1]:443: use of closed network connection")
expected := "unknown_failure: read tcp [scrubbed]->[scrubbed]: use of closed network connection"
out := toFailureString(input)
if out != expected {
t.Fatal(cmp.Diff(expected, out))
}
})
t.Run("for i/o error", func(t *testing.T) {
ctx, cancel := context.WithTimeout(context.Background(), 1)
defer cancel() // fail immediately
udpAddr := &net.UDPAddr{IP: net.ParseIP("216.58.212.164"), Port: 80, Zone: ""}
udpConn, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4zero, Port: 0})
if err != nil {
t.Fatal(err)
}
sess, err := quic.DialEarlyContext(ctx, udpConn, udpAddr, "google.com:80", &tls.Config{}, &quic.Config{})
if err == nil {
t.Fatal("expected an error here")
}
if sess != nil {
t.Fatal("expected nil session here")
}
if toFailureString(err) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
}
func TestClassifyQUICFailure(t *testing.T) {
t.Run("for connection_reset", func(t *testing.T) {
if ClassifyQUICFailure(&quic.StatelessResetError{}) != FailureConnectionReset {
t.Fatal("unexpected results")
}
})
t.Run("for incompatible quic version", func(t *testing.T) {
if ClassifyQUICFailure(&quic.VersionNegotiationError{}) != FailureNoCompatibleQUICVersion {
t.Fatal("unexpected results")
}
})
t.Run("for quic connection refused", func(t *testing.T) {
if ClassifyQUICFailure(&quic.TransportError{ErrorCode: quic.ConnectionRefused}) != FailureConnectionRefused {
t.Fatal("unexpected results")
}
})
t.Run("for quic handshake timeout", func(t *testing.T) {
if ClassifyQUICFailure(&quic.HandshakeTimeoutError{}) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for QUIC idle connection timeout", func(t *testing.T) {
if ClassifyQUICFailure(&quic.IdleTimeoutError{}) != FailureGenericTimeoutError {
t.Fatal("unexpected results")
}
})
t.Run("for QUIC CRYPTO Handshake", func(t *testing.T) {
var err quic.TransportErrorCode = TLSAlertHandshakeFailure
if ClassifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLHandshake {
t.Fatal("unexpected results")
}
})
t.Run("for QUIC CRYPTO Invalid Certificate", func(t *testing.T) {
var err quic.TransportErrorCode = TLSAlertBadCertificate
if ClassifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidCertificate {
t.Fatal("unexpected results")
}
})
t.Run("for QUIC CRYPTO Unknown CA", func(t *testing.T) {
var err quic.TransportErrorCode = TLSAlertUnknownCA
if ClassifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLUnknownAuthority {
t.Fatal("unexpected results")
}
})
t.Run("for QUIC CRYPTO Bad Hostname", func(t *testing.T) {
var err quic.TransportErrorCode = TLSUnrecognizedName
if ClassifyQUICFailure(&quic.TransportError{ErrorCode: err}) != FailureSSLInvalidHostname {
t.Fatal("unexpected results")
}
})
}
func TestClassifyResolveFailure(t *testing.T) {
t.Run("for ErrDNSBogon", func(t *testing.T) {
if ClassifyResolveFailure(ErrDNSBogon) != FailureDNSBogonError {
t.Fatal("unexpected result")
}
})
}
func TestClassifyTLSFailure(t *testing.T) {
t.Run("for x509.HostnameError", func(t *testing.T) {
var err x509.HostnameError
if ClassifyTLSFailure(err) != FailureSSLInvalidHostname {
t.Fatal("unexpected result")
}
})
t.Run("for x509.UnknownAuthorityError", func(t *testing.T) {
var err x509.UnknownAuthorityError
if ClassifyTLSFailure(err) != FailureSSLUnknownAuthority {
t.Fatal("unexpected result")
}
})
t.Run("for x509.CertificateInvalidError", func(t *testing.T) {
var err x509.CertificateInvalidError
if ClassifyTLSFailure(err) != FailureSSLInvalidCertificate {
t.Fatal("unexpected result")
}
})
}
func TestToOperationString(t *testing.T) {
t.Run("for connect", func(t *testing.T) {
// You're doing HTTP and connect fails. You want to know
// that connect failed not that HTTP failed.
err := &ErrWrapper{Operation: ConnectOperation}
if toOperationString(err, HTTPRoundTripOperation) != ConnectOperation {
t.Fatal("unexpected result")
}
})
t.Run("for http_round_trip", func(t *testing.T) {
// You're doing DoH and something fails inside HTTP. You want
// to know about the internal HTTP error, not resolve.
err := &ErrWrapper{Operation: HTTPRoundTripOperation}
if toOperationString(err, ResolveOperation) != HTTPRoundTripOperation {
t.Fatal("unexpected result")
}
})
t.Run("for resolve", func(t *testing.T) {
// You're doing HTTP and the DNS fails. You want to
// know that resolve failed.
err := &ErrWrapper{Operation: ResolveOperation}
if toOperationString(err, HTTPRoundTripOperation) != ResolveOperation {
t.Fatal("unexpected result")
}
})
t.Run("for tls_handshake", func(t *testing.T) {
// You're doing HTTP and the TLS handshake fails. You want
// to know about a TLS handshake error.
err := &ErrWrapper{Operation: TLSHandshakeOperation}
if toOperationString(err, HTTPRoundTripOperation) != TLSHandshakeOperation {
t.Fatal("unexpected result")
}
})
t.Run("for minor operation", func(t *testing.T) {
// You just noticed that TLS handshake failed and you
// have a child error telling you that read failed. Here
// you want to know about a TLS handshake error.
err := &ErrWrapper{Operation: ReadOperation}
if toOperationString(err, TLSHandshakeOperation) != TLSHandshakeOperation {
t.Fatal("unexpected result")
}
})
t.Run("for quic_handshake", func(t *testing.T) {
// You're doing HTTP and the TLS handshake fails. You want
// to know about a TLS handshake error.
err := &ErrWrapper{Operation: QUICHandshakeOperation}
if toOperationString(err, HTTPRoundTripOperation) != QUICHandshakeOperation {
t.Fatal("unexpected result")
}
})
}
+3 -3
View File
@@ -9,8 +9,8 @@ import (
"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/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/iox"
)
@@ -78,10 +78,10 @@ func TestBogonResolutionNotBroken(t *testing.T) {
Logger: log.Log,
})
addrs, err := r.LookupHost(context.Background(), "www.google.com")
if !errors.Is(err, errorx.ErrDNSBogon) {
if !errors.Is(err, errorsx.ErrDNSBogon) {
t.Fatal("not the error we expected")
}
if err.Error() != errorx.FailureDNSBogonError {
if err.Error() != errorsx.FailureDNSBogonError {
t.Fatal("error not correctly wrapped")
}
if len(addrs) > 0 {
@@ -5,7 +5,7 @@ import (
"crypto/tls"
"github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// ErrorWrapperDialer is a dialer that performs quic err wrapping
@@ -18,10 +18,10 @@ func (d ErrorWrapperDialer) DialContext(
ctx context.Context, network string, host string,
tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlySession, error) {
sess, err := d.Dialer.DialContext(ctx, network, host, tlsCfg, cfg)
err = errorx.SafeErrWrapperBuilder{
Classifier: errorx.ClassifyQUICFailure,
err = errorsx.SafeErrWrapperBuilder{
Classifier: errorsx.ClassifyQUICFailure,
Error: err,
Operation: errorx.QUICHandshakeOperation,
Operation: errorsx.QUICHandshakeOperation,
}.MaybeBuild()
if err != nil {
return nil, err
@@ -8,8 +8,8 @@ import (
"testing"
"github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -22,21 +22,21 @@ func TestErrorWrapperFailure(t *testing.T) {
if sess != nil {
t.Fatal("expected a nil sess here")
}
errorWrapperCheckErr(t, err, errorx.QUICHandshakeOperation)
errorWrapperCheckErr(t, err, errorsx.QUICHandshakeOperation)
}
func errorWrapperCheckErr(t *testing.T, err error, op string) {
if !errors.Is(err, io.EOF) {
t.Fatal("expected another error here")
}
var errWrapper *errorx.ErrWrapper
var errWrapper *errorsx.ErrWrapper
if !errors.As(err, &errWrapper) {
t.Fatal("cannot cast to ErrWrapper")
}
if errWrapper.Operation != op {
t.Fatal("unexpected Operation")
}
if errWrapper.Failure != errorx.FailureEOFError {
if errWrapper.Failure != errorsx.FailureEOFError {
t.Fatal("unexpected failure")
}
}
@@ -61,7 +61,7 @@ func TestErrorWrapperInvalidCertificate(t *testing.T) {
if sess != nil {
t.Fatal("expected nil sess here")
}
if err.Error() != errorx.FailureSSLInvalidCertificate {
if err.Error() != errorsx.FailureSSLInvalidCertificate {
t.Fatal("unexpected failure")
}
}
+3 -3
View File
@@ -5,8 +5,8 @@ import (
"net"
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// QUICListener listens for QUIC connections.
@@ -53,7 +53,7 @@ func (c saverUDPConn) WriteTo(p []byte, addr net.Addr) (int, error) {
Duration: stop.Sub(start),
Err: err,
NumBytes: count,
Name: errorx.WriteToOperation,
Name: errorsx.WriteToOperation,
Time: stop,
})
return count, err
@@ -73,7 +73,7 @@ func (c saverUDPConn) ReadMsgUDP(b, oob []byte) (int, int, int, *net.UDPAddr, er
Duration: stop.Sub(start),
Err: err,
NumBytes: n,
Name: errorx.ReadFromOperation,
Name: errorsx.ReadFromOperation,
Time: stop,
})
return n, oobn, flags, addr, err
@@ -6,9 +6,9 @@ import (
"testing"
"github.com/lucas-clemente/quic-go"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -49,7 +49,7 @@ func TestSystemDialerSuccessWithReadWrite(t *testing.T) {
t.Fatal("unexpected NumBytes")
}
switch ev[idx].Name {
case errorx.ReadFromOperation, errorx.WriteToOperation:
case errorsx.ReadFromOperation, errorsx.WriteToOperation:
default:
t.Fatal("unexpected Name")
}
+2 -2
View File
@@ -4,7 +4,7 @@ import (
"context"
"net"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/runtimex"
)
@@ -65,7 +65,7 @@ func (r BogonResolver) LookupHost(ctx context.Context, hostname string) ([]strin
addrs, err := r.Resolver.LookupHost(ctx, hostname)
for _, addr := range addrs {
if IsBogon(addr) {
return nil, errorx.ErrDNSBogon
return nil, errorsx.ErrDNSBogon
}
}
return addrs, err
+2 -2
View File
@@ -5,8 +5,8 @@ import (
"errors"
"testing"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestResolverIsBogon(t *testing.T) {
@@ -29,7 +29,7 @@ func TestBogonAwareResolverWithBogon(t *testing.T) {
Resolver: resolver.NewFakeResolverWithResult([]string{"127.0.0.1"}),
}
addrs, err := r.LookupHost(context.Background(), "dns.google.com")
if !errors.Is(err, errorx.ErrDNSBogon) {
if !errors.Is(err, errorsx.ErrDNSBogon) {
t.Fatal("not the error we expected")
}
if len(addrs) > 0 {
@@ -3,7 +3,7 @@ package resolver
import (
"context"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// ErrorWrapperResolver is a Resolver that knows about wrapping errors.
@@ -14,10 +14,10 @@ type ErrorWrapperResolver struct {
// LookupHost implements Resolver.LookupHost
func (r ErrorWrapperResolver) LookupHost(ctx context.Context, hostname string) ([]string, error) {
addrs, err := r.Resolver.LookupHost(ctx, hostname)
err = errorx.SafeErrWrapperBuilder{
Classifier: errorx.ClassifyResolveFailure,
err = errorsx.SafeErrWrapperBuilder{
Classifier: errorsx.ClassifyResolveFailure,
Error: err,
Operation: errorx.ResolveOperation,
Operation: errorsx.ResolveOperation,
}.MaybeBuild()
return addrs, err
}
@@ -5,8 +5,8 @@ import (
"errors"
"testing"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/resolver"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
func TestErrorWrapperSuccess(t *testing.T) {
@@ -32,14 +32,14 @@ func TestErrorWrapperFailure(t *testing.T) {
if addrs != nil {
t.Fatal("expected nil addr here")
}
var errWrapper *errorx.ErrWrapper
var errWrapper *errorsx.ErrWrapper
if !errors.As(err, &errWrapper) {
t.Fatal("cannot properly cast the returned error")
}
if errWrapper.Failure != errorx.FailureDNSNXDOMAINError {
if errWrapper.Failure != errorsx.FailureDNSNXDOMAINError {
t.Fatal("unexpected failure")
}
if errWrapper.Operation != errorx.ResolveOperation {
if errWrapper.Operation != errorsx.ResolveOperation {
t.Fatal("unexpected Operation")
}
}
+2 -2
View File
@@ -9,9 +9,9 @@ import (
"time"
"github.com/ooni/probe-cli/v3/internal/engine/netx/dialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
"github.com/ooni/probe-cli/v3/internal/engine/netx/trace"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -69,7 +69,7 @@ func TestSaverTLSHandshakerSuccessWithReadWrite(t *testing.T) {
t.Fatal("unexpected NumBytes")
}
switch ev[idx].Name {
case errorx.ReadOperation, errorx.WriteOperation:
case errorsx.ReadOperation, errorsx.WriteOperation:
default:
t.Fatal("unexpected Name")
}
+4 -4
View File
@@ -8,7 +8,7 @@ import (
"time"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/errorsx"
)
// UnderlyingDialer is the underlying dialer type.
@@ -32,10 +32,10 @@ func (h ErrorWrapperTLSHandshaker) Handshake(
ctx context.Context, conn net.Conn, config *tls.Config,
) (net.Conn, tls.ConnectionState, error) {
tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config)
err = errorx.SafeErrWrapperBuilder{
Classifier: errorx.ClassifyTLSFailure,
err = errorsx.SafeErrWrapperBuilder{
Classifier: errorsx.ClassifyTLSFailure,
Error: err,
Operation: errorx.TLSHandshakeOperation,
Operation: errorsx.TLSHandshakeOperation,
}.MaybeBuild()
return tlsconn, state, err
}
+4 -4
View File
@@ -10,8 +10,8 @@ import (
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/handlers"
"github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/errorx"
"github.com/ooni/probe-cli/v3/internal/engine/netx/tlsdialer"
"github.com/ooni/probe-cli/v3/internal/errorsx"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
@@ -48,14 +48,14 @@ func TestErrorWrapperTLSHandshakerFailure(t *testing.T) {
if conn != nil {
t.Fatal("expected nil con here")
}
var errWrapper *errorx.ErrWrapper
var errWrapper *errorsx.ErrWrapper
if !errors.As(err, &errWrapper) {
t.Fatal("cannot cast to ErrWrapper")
}
if errWrapper.Failure != errorx.FailureEOFError {
if errWrapper.Failure != errorsx.FailureEOFError {
t.Fatal("unexpected Failure")
}
if errWrapper.Operation != errorx.TLSHandshakeOperation {
if errWrapper.Operation != errorsx.TLSHandshakeOperation {
t.Fatal("unexpected Operation")
}
}