netxlite: improve docs, tests, and code quality (#493)
* netxlite: improve docs, tests, and code quality * better documentation * more strict testing of dialer (especially make sure we document the quirk in https://github.com/ooni/probe/issues/1779 and we have tests to guarantee we don't screw up here) * introduce NewErrWrapper factory for creating errors so we have confidence we are creating them correctly Part of https://github.com/ooni/probe/issues/1591
This commit is contained in:
parent
e68adec9a5
commit
3cd88debdc
12 changed files with 452 additions and 141 deletions
|
|
@ -67,3 +67,28 @@ func (e *ErrWrapper) Unwrap() error {
|
|||
func (e *ErrWrapper) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(e.Failure)
|
||||
}
|
||||
|
||||
// Classifier is the type of function that performs classification.
|
||||
type Classifier func(err error) string
|
||||
|
||||
// NewErrWrapper creates a new ErrWrapper using the given
|
||||
// classifier, operation name, and underlying error.
|
||||
//
|
||||
// This function panics if classifier is nil, or operation
|
||||
// is the empty string or error is nil.
|
||||
func NewErrWrapper(c Classifier, op string, err error) *ErrWrapper {
|
||||
if c == nil {
|
||||
panic("nil classifier")
|
||||
}
|
||||
if op == "" {
|
||||
panic("empty op")
|
||||
}
|
||||
if err == nil {
|
||||
panic("nil err")
|
||||
}
|
||||
return &ErrWrapper{
|
||||
Failure: c(err),
|
||||
Operation: op,
|
||||
WrappedErr: err,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"errors"
|
||||
"io"
|
||||
"testing"
|
||||
|
||||
"github.com/ooni/probe-cli/v3/internal/atomicx"
|
||||
)
|
||||
|
||||
func TestErrWrapper(t *testing.T) {
|
||||
|
|
@ -40,3 +42,63 @@ func TestErrWrapper(t *testing.T) {
|
|||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestNewErrWrapper(t *testing.T) {
|
||||
t.Run("panics if the classifier is nil", func(t *testing.T) {
|
||||
recovered := &atomicx.Int64{}
|
||||
func() {
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
recovered.Add(1)
|
||||
}
|
||||
}()
|
||||
NewErrWrapper(nil, CloseOperation, io.EOF)
|
||||
}()
|
||||
if recovered.Load() != 1 {
|
||||
t.Fatal("did not panic")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("panics if the operation is empty", func(t *testing.T) {
|
||||
recovered := &atomicx.Int64{}
|
||||
func() {
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
recovered.Add(1)
|
||||
}
|
||||
}()
|
||||
NewErrWrapper(ClassifyGenericError, "", io.EOF)
|
||||
}()
|
||||
if recovered.Load() != 1 {
|
||||
t.Fatal("did not panic")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("panics if the error is nil", func(t *testing.T) {
|
||||
recovered := &atomicx.Int64{}
|
||||
func() {
|
||||
defer func() {
|
||||
if recover() != nil {
|
||||
recovered.Add(1)
|
||||
}
|
||||
}()
|
||||
NewErrWrapper(ClassifyGenericError, CloseOperation, nil)
|
||||
}()
|
||||
if recovered.Load() != 1 {
|
||||
t.Fatal("did not panic")
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("otherwise, works as intended", func(t *testing.T) {
|
||||
ew := NewErrWrapper(ClassifyGenericError, CloseOperation, io.EOF)
|
||||
if ew.Failure != FailureEOFError {
|
||||
t.Fatal("unexpected failure")
|
||||
}
|
||||
if ew.Operation != CloseOperation {
|
||||
t.Fatal("unexpected operation")
|
||||
}
|
||||
if ew.WrappedErr != io.EOF {
|
||||
t.Fatal("unexpected WrappedErr")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue