ooni-probe-cli/internal/engine/experiment/ndt7/download_test.go
Simone Basso 3265bc670a
refactor(ndt7): use netxlite rather than netx (#768)
This diff required us to move some code around, but no major
change actually happened, except better tests.

While there, I also slightly refactored ndt7's implementation and
removed the ProxyURL setting, which was actually unused.

See https://github.com/ooni/probe/issues/2121
2022-05-30 23:14:07 +02:00

173 lines
3.8 KiB
Go

package ndt7
import (
"context"
"encoding/json"
"errors"
"io"
"strings"
"testing"
"time"
"github.com/gorilla/websocket"
)
func defaultCallbackJSON(data []byte) error {
return nil
}
func defaultCallbackPerformance(elapsed time.Duration, count int64) {
}
func TestDownloadSetReadDeadlineFailure(t *testing.T) {
expected := errors.New("mocked error")
mgr := newDownloadManager(
&mockableWSConn{
ReadDeadlineErr: expected,
},
defaultCallbackPerformance,
defaultCallbackJSON,
)
err := mgr.run(context.Background())
if !errors.Is(err, expected) {
t.Fatal("not the error we expected")
}
}
func TestDownloadNextReaderFailure(t *testing.T) {
expected := errors.New("mocked error")
mgr := newDownloadManager(
&mockableWSConn{
NextReaderErr: expected,
},
defaultCallbackPerformance,
defaultCallbackJSON,
)
err := mgr.run(context.Background())
if !errors.Is(err, expected) {
t.Fatal("not the error we expected")
}
}
func TestDownloadTextMessageReadAllFailure(t *testing.T) {
expected := errors.New("mocked error")
mgr := newDownloadManager(
&mockableWSConn{
NextReaderMsgType: websocket.TextMessage,
NextReaderReader: func() io.Reader {
return &alwaysFailingReader{
Err: expected,
}
},
},
defaultCallbackPerformance,
defaultCallbackJSON,
)
err := mgr.run(context.Background())
if !errors.Is(err, expected) {
t.Fatal("not the error we expected")
}
}
type alwaysFailingReader struct {
Err error
}
func (r *alwaysFailingReader) Read(p []byte) (int, error) {
return 0, r.Err
}
func TestDownloadBinaryMessageReadAllFailure(t *testing.T) {
expected := errors.New("mocked error")
mgr := newDownloadManager(
&mockableWSConn{
NextReaderMsgType: websocket.BinaryMessage,
NextReaderReader: func() io.Reader {
return &alwaysFailingReader{
Err: expected,
}
},
},
defaultCallbackPerformance,
defaultCallbackJSON,
)
err := mgr.run(context.Background())
if !errors.Is(err, expected) {
t.Fatal("not the error we expected")
}
}
func TestDownloadOnJSONCallbackError(t *testing.T) {
mgr := newDownloadManager(
&mockableWSConn{
NextReaderMsgType: websocket.TextMessage,
NextReaderReader: func() io.Reader {
return &invalidJSONReader{}
},
},
defaultCallbackPerformance,
func(data []byte) error {
var v interface{}
return json.Unmarshal(data, &v)
},
)
err := mgr.run(context.Background())
if err == nil || !strings.HasSuffix(err.Error(), "unexpected end of JSON input") {
t.Fatal("not the error we expected")
}
}
type invalidJSONReader struct{}
func (r *invalidJSONReader) Read(p []byte) (int, error) {
return copy(p, []byte(`{`)), io.EOF
}
func TestDownloadOnJSONLoop(t *testing.T) {
if testing.Short() {
t.Skip("skip test in short mode")
}
mgr := newDownloadManager(
&mockableWSConn{
NextReaderMsgType: websocket.TextMessage,
NextReaderReader: func() io.Reader {
return &goodJSONReader{}
},
},
defaultCallbackPerformance,
func(data []byte) error {
var v interface{}
return json.Unmarshal(data, &v)
},
)
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
defer cancel()
err := mgr.run(ctx)
if err != nil {
t.Fatal(err)
}
}
type goodJSONReader struct{}
func (r *goodJSONReader) Read(p []byte) (int, error) {
return copy(p, []byte(`{}`)), io.EOF
}
func TestDownloadReduceErr(t *testing.T) {
mgr := downloadManager{}
if mgr.reduceErr(context.Canceled) != nil {
t.Fatal("reduceErr not working as intended for context.Canceled")
}
if mgr.reduceErr(context.DeadlineExceeded) != nil {
t.Fatal("reduceErr not working as intended for context.DeadlineExceeded")
}
if mgr.reduceErr(nil) != nil {
t.Fatal("reduceErr not working as intended for nil")
}
expected := errors.New("mocked error")
if mgr.reduceErr(expected) != expected {
t.Fatal("reduceErr not working as intended for other errors")
}
}