a3a27b1ebf
* fix(netxlite): make default resolver converge faster Closes https://github.com/ooni/probe/issues/1726 * Update internal/netxlite/resolver.go * fix(ndt7): adapt tests after previous change Because now we're running the DNS resolution inside a goroutine with a child context, the returned error string is different. The previous error said we canceled the whole dialing operation, while now we see directly that the context was canceled.
240 lines
5.8 KiB
Go
240 lines
5.8 KiB
Go
package ndt7
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/apex/log"
|
|
"github.com/ooni/probe-cli/v3/internal/engine/mockable"
|
|
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
|
)
|
|
|
|
func TestNewExperimentMeasurer(t *testing.T) {
|
|
measurer := NewExperimentMeasurer(Config{})
|
|
if measurer.ExperimentName() != "ndt" {
|
|
t.Fatal("unexpected name")
|
|
}
|
|
if measurer.ExperimentVersion() != "0.9.0" {
|
|
t.Fatal("unexpected version")
|
|
}
|
|
}
|
|
|
|
func TestDiscoverCancelledContext(t *testing.T) {
|
|
m := new(Measurer)
|
|
sess := &mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
MockableUserAgent: "miniooni/0.1.0-dev",
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // immediately cancel
|
|
locateResult, err := m.discover(ctx, sess)
|
|
if !errors.Is(err, context.Canceled) {
|
|
t.Fatal("not the error we expected")
|
|
}
|
|
if locateResult.Hostname != "" {
|
|
t.Fatal("not the Hostname we expected")
|
|
}
|
|
}
|
|
|
|
func TestDoDownloadWithCancelledContext(t *testing.T) {
|
|
m := new(Measurer)
|
|
sess := &mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
MockableUserAgent: "miniooni/0.1.0-dev",
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // immediately cancel
|
|
err := m.doDownload(
|
|
ctx, sess, model.NewPrinterCallbacks(log.Log), new(TestKeys),
|
|
"ws://host.name")
|
|
if err == nil || !strings.HasSuffix(err.Error(), "context canceled") {
|
|
t.Fatal("not the error we expected", err)
|
|
}
|
|
}
|
|
|
|
func TestDoUploadWithCancelledContext(t *testing.T) {
|
|
m := new(Measurer)
|
|
sess := &mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
MockableUserAgent: "miniooni/0.1.0-dev",
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // immediately cancel
|
|
err := m.doUpload(
|
|
ctx, sess, model.NewPrinterCallbacks(log.Log), new(TestKeys),
|
|
"ws://host.name")
|
|
if err == nil || !strings.HasSuffix(err.Error(), "context canceled") {
|
|
t.Fatal("not the error we expected", err)
|
|
}
|
|
}
|
|
|
|
func TestRunWithCancelledContext(t *testing.T) {
|
|
m := new(Measurer)
|
|
sess := &mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
MockableUserAgent: "miniooni/0.1.0-dev",
|
|
}
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
cancel() // immediately cancel
|
|
err := m.Run(ctx, sess, new(model.Measurement), model.NewPrinterCallbacks(log.Log))
|
|
if !errors.Is(err, context.Canceled) {
|
|
t.Fatal("not the error we expected")
|
|
}
|
|
}
|
|
|
|
func TestGood(t *testing.T) {
|
|
if testing.Short() {
|
|
t.Skip("skip test in short mode")
|
|
}
|
|
measurement := new(model.Measurement)
|
|
measurer := NewExperimentMeasurer(Config{})
|
|
err := measurer.Run(
|
|
context.Background(),
|
|
&mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
},
|
|
measurement,
|
|
model.NewPrinterCallbacks(log.Log),
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sk, err := measurer.GetSummaryKeys(measurement)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, ok := sk.(SummaryKeys); !ok {
|
|
t.Fatal("invalid type for summary keys")
|
|
}
|
|
}
|
|
|
|
func TestFailDownload(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
measurer := NewExperimentMeasurer(Config{}).(*Measurer)
|
|
measurer.preDownloadHook = func() {
|
|
cancel()
|
|
}
|
|
err := measurer.Run(
|
|
ctx,
|
|
&mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
},
|
|
new(model.Measurement),
|
|
model.NewPrinterCallbacks(log.Log),
|
|
)
|
|
if err == nil || !strings.HasSuffix(err.Error(), "context canceled") {
|
|
t.Fatal("not the error we expected", err)
|
|
}
|
|
}
|
|
|
|
func TestFailUpload(t *testing.T) {
|
|
ctx, cancel := context.WithCancel(context.Background())
|
|
defer cancel()
|
|
measurer := NewExperimentMeasurer(Config{noDownload: true}).(*Measurer)
|
|
measurer.preUploadHook = func() {
|
|
cancel()
|
|
}
|
|
err := measurer.Run(
|
|
ctx,
|
|
&mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
},
|
|
new(model.Measurement),
|
|
model.NewPrinterCallbacks(log.Log),
|
|
)
|
|
if err == nil || !strings.HasSuffix(err.Error(), "context canceled") {
|
|
t.Fatal("not the error we expected", err)
|
|
}
|
|
}
|
|
|
|
func TestDownloadJSONUnmarshalFail(t *testing.T) {
|
|
measurer := NewExperimentMeasurer(Config{noUpload: true}).(*Measurer)
|
|
var seenError bool
|
|
expected := errors.New("expected error")
|
|
measurer.jsonUnmarshal = func(data []byte, v interface{}) error {
|
|
seenError = true
|
|
return expected
|
|
}
|
|
err := measurer.Run(
|
|
context.Background(),
|
|
&mockable.Session{
|
|
MockableHTTPClient: http.DefaultClient,
|
|
MockableLogger: log.Log,
|
|
},
|
|
new(model.Measurement),
|
|
model.NewPrinterCallbacks(log.Log),
|
|
)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !seenError {
|
|
t.Fatal("did not see expected error")
|
|
}
|
|
}
|
|
|
|
func TestSummaryKeysInvalidType(t *testing.T) {
|
|
measurement := new(model.Measurement)
|
|
m := &Measurer{}
|
|
_, err := m.GetSummaryKeys(measurement)
|
|
if err.Error() != "invalid test keys type" {
|
|
t.Fatal("not the error we expected")
|
|
}
|
|
}
|
|
|
|
func TestSummaryKeysGood(t *testing.T) {
|
|
measurement := &model.Measurement{TestKeys: &TestKeys{Summary: Summary{
|
|
RetransmitRate: 1,
|
|
MSS: 2,
|
|
MinRTT: 3,
|
|
AvgRTT: 4,
|
|
MaxRTT: 5,
|
|
Ping: 6,
|
|
Download: 7,
|
|
Upload: 8,
|
|
}}}
|
|
m := &Measurer{}
|
|
osk, err := m.GetSummaryKeys(measurement)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
sk := osk.(SummaryKeys)
|
|
if sk.RetransmitRate != 1 {
|
|
t.Fatal("invalid retransmitRate")
|
|
}
|
|
if sk.MSS != 2 {
|
|
t.Fatal("invalid mss")
|
|
}
|
|
if sk.MinRTT != 3 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.AvgRTT != 4 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.MaxRTT != 5 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.Ping != 6 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.Download != 7 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.Upload != 8 {
|
|
t.Fatal("invalid minRTT")
|
|
}
|
|
if sk.IsAnomaly {
|
|
t.Fatal("invalid isAnomaly")
|
|
}
|
|
}
|