diff --git a/cmd/ooniprobe/internal/nettests/dnscheck.go b/cmd/ooniprobe/internal/nettests/dnscheck.go index 0054c39..7fed35f 100644 --- a/cmd/ooniprobe/internal/nettests/dnscheck.go +++ b/cmd/ooniprobe/internal/nettests/dnscheck.go @@ -4,7 +4,7 @@ import ( "context" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // DNSCheck nettest implementation. @@ -12,7 +12,7 @@ type DNSCheck struct{} func (n DNSCheck) lookupURLs(ctl *Controller) ([]string, error) { inputloader := &engine.InputLoader{ - CheckInConfig: &model.CheckInConfig{ + CheckInConfig: &model.OOAPICheckInConfig{ // not needed because we have default static input in the engine }, ExperimentName: "dnscheck", diff --git a/cmd/ooniprobe/internal/nettests/nettests.go b/cmd/ooniprobe/internal/nettests/nettests.go index 1176526..1756118 100644 --- a/cmd/ooniprobe/internal/nettests/nettests.go +++ b/cmd/ooniprobe/internal/nettests/nettests.go @@ -11,7 +11,7 @@ import ( "github.com/ooni/probe-cli/v3/cmd/ooniprobe/internal/ooni" "github.com/ooni/probe-cli/v3/cmd/ooniprobe/internal/output" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/pkg/errors" "upper.io/db.v3/lib/sqlbuilder" ) @@ -90,7 +90,7 @@ type Controller struct { // // - on failure, an error. func (c *Controller) BuildAndSetInputIdxMap( - db sqlbuilder.Database, testlist []model.URLInfo) ([]string, error) { + db sqlbuilder.Database, testlist []model.OOAPIURLInfo) ([]string, error) { var urls []string urlIDMap := make(map[int64]int64) for idx, url := range testlist { diff --git a/cmd/ooniprobe/internal/nettests/stunreachability.go b/cmd/ooniprobe/internal/nettests/stunreachability.go index 61adcc4..76baa29 100644 --- a/cmd/ooniprobe/internal/nettests/stunreachability.go +++ b/cmd/ooniprobe/internal/nettests/stunreachability.go @@ -4,7 +4,7 @@ import ( "context" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // STUNReachability nettest implementation. @@ -12,7 +12,7 @@ type STUNReachability struct{} func (n STUNReachability) lookupURLs(ctl *Controller) ([]string, error) { inputloader := &engine.InputLoader{ - CheckInConfig: &model.CheckInConfig{ + CheckInConfig: &model.OOAPICheckInConfig{ // not needed because we have default static input in the engine }, ExperimentName: "stunreachability", diff --git a/cmd/ooniprobe/internal/nettests/web_connectivity.go b/cmd/ooniprobe/internal/nettests/web_connectivity.go index ad113fc..9a89b5d 100644 --- a/cmd/ooniprobe/internal/nettests/web_connectivity.go +++ b/cmd/ooniprobe/internal/nettests/web_connectivity.go @@ -5,19 +5,19 @@ import ( "github.com/apex/log" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func (n WebConnectivity) lookupURLs(ctl *Controller, categories []string) ([]string, error) { inputloader := &engine.InputLoader{ - CheckInConfig: &model.CheckInConfig{ + CheckInConfig: &model.OOAPICheckInConfig{ // Setting Charging and OnWiFi to true causes the CheckIn // API to return to us as much URL as possible with the // given RunType hint. Charging: true, OnWiFi: true, RunType: ctl.RunType, - WebConnectivity: model.CheckInConfigWebConnectivity{ + WebConnectivity: model.OOAPICheckInConfigWebConnectivity{ CategoryCodes: categories, }, }, diff --git a/internal/README.md b/internal/README.md index 11d37e6..a70cb9c 100644 --- a/internal/README.md +++ b/internal/README.md @@ -13,6 +13,9 @@ where `$package` is the name of the package. Some notable packages: +- [model](model) contains the interfaces and data model shared +by most packages inside this directory; + - [netxlite](netxlite) is the underlying networking library; - [tutorial](tutorial) contains tutorials on writing new experiments, diff --git a/internal/bytecounter/conn_test.go b/internal/bytecounter/conn_test.go index 0b254bb..3c193fc 100644 --- a/internal/bytecounter/conn_test.go +++ b/internal/bytecounter/conn_test.go @@ -4,7 +4,7 @@ import ( "errors" "testing" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestConnWorksOnSuccess(t *testing.T) { diff --git a/internal/cmd/miniooni/libminiooni.go b/internal/cmd/miniooni/libminiooni.go index ea25898..5e39bf4 100644 --- a/internal/cmd/miniooni/libminiooni.go +++ b/internal/cmd/miniooni/libminiooni.go @@ -17,9 +17,9 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/engine" "github.com/ooni/probe-cli/v3/internal/engine/legacy/assetsdir" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/humanize" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/netxlite/filtering" "github.com/ooni/probe-cli/v3/internal/runtimex" @@ -377,7 +377,7 @@ func MainWithConfiguration(experimentName string, currentOptions Options) { TunnelDir: tunnelDir, } if currentOptions.ProbeServicesURL != "" { - config.AvailableProbeServices = []model.Service{{ + config.AvailableProbeServices = []model.OOAPIService{{ Address: currentOptions.ProbeServicesURL, Type: "https", }} @@ -411,7 +411,7 @@ func MainWithConfiguration(experimentName string, currentOptions Options) { fatalOnError(err, "cannot create experiment builder") inputLoader := &engine.InputLoader{ - CheckInConfig: &model.CheckInConfig{ + CheckInConfig: &model.OOAPICheckInConfig{ RunType: "manual", OnWiFi: true, // meaning: not on 4G Charging: true, diff --git a/internal/cmd/oohelperd/internal/webconnectivity/dns_test.go b/internal/cmd/oohelperd/internal/webconnectivity/dns_test.go index 1e51ea7..5848919 100644 --- a/internal/cmd/oohelperd/internal/webconnectivity/dns_test.go +++ b/internal/cmd/oohelperd/internal/webconnectivity/dns_test.go @@ -8,7 +8,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/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func stringPointerForString(s string) *string { diff --git a/internal/engine/experiment.go b/internal/engine/experiment.go index ccb7935..6b4bf12 100644 --- a/internal/engine/experiment.go +++ b/internal/engine/experiment.go @@ -11,10 +11,10 @@ import ( "github.com/ooni/probe-cli/v3/internal/bytecounter" "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/dialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/httptransport" "github.com/ooni/probe-cli/v3/internal/engine/probeservices" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/version" ) diff --git a/internal/engine/experiment/dash/collect.go b/internal/engine/experiment/dash/collect.go index 641e222..b3d919d 100644 --- a/internal/engine/experiment/dash/collect.go +++ b/internal/engine/experiment/dash/collect.go @@ -8,7 +8,7 @@ import ( "net/http" "net/url" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type collectDeps interface { diff --git a/internal/engine/experiment/dash/dash.go b/internal/engine/experiment/dash/dash.go index 6414085..460d250 100644 --- a/internal/engine/experiment/dash/dash.go +++ b/internal/engine/experiment/dash/dash.go @@ -14,10 +14,10 @@ import ( "time" "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/trace" "github.com/ooni/probe-cli/v3/internal/humanize" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/dash/dash_test.go b/internal/engine/experiment/dash/dash_test.go index 9dd290d..cd77c70 100644 --- a/internal/engine/experiment/dash/dash_test.go +++ b/internal/engine/experiment/dash/dash_test.go @@ -12,8 +12,8 @@ import ( "github.com/apex/log" "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/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/dash/fake_test.go b/internal/engine/experiment/dash/fake_test.go index 7f35618..5243018 100644 --- a/internal/engine/experiment/dash/fake_test.go +++ b/internal/engine/experiment/dash/fake_test.go @@ -7,7 +7,7 @@ import ( "time" "github.com/apex/log" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type FakeDeps struct { diff --git a/internal/engine/experiment/dash/locate.go b/internal/engine/experiment/dash/locate.go index 53a63fd..74f3320 100644 --- a/internal/engine/experiment/dash/locate.go +++ b/internal/engine/experiment/dash/locate.go @@ -4,8 +4,8 @@ import ( "context" "net/http" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/mlablocate" + "github.com/ooni/probe-cli/v3/internal/model" ) type locateDeps interface { diff --git a/internal/engine/experiment/dash/negotiate.go b/internal/engine/experiment/dash/negotiate.go index 1464099..5484290 100644 --- a/internal/engine/experiment/dash/negotiate.go +++ b/internal/engine/experiment/dash/negotiate.go @@ -8,7 +8,7 @@ import ( "net/http" "net/url" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type negotiateDeps interface { diff --git a/internal/engine/experiment/dnscheck/dnscheck.go b/internal/engine/experiment/dnscheck/dnscheck.go index 197ce09..778377f 100644 --- a/internal/engine/experiment/dnscheck/dnscheck.go +++ b/internal/engine/experiment/dnscheck/dnscheck.go @@ -15,10 +15,10 @@ import ( "github.com/ooni/probe-cli/v3/internal/atomicx" "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" "github.com/ooni/probe-cli/v3/internal/engine/netx/archival" "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) diff --git a/internal/engine/experiment/dnscheck/dnscheck_test.go b/internal/engine/experiment/dnscheck/dnscheck_test.go index 2500882..6f23e37 100644 --- a/internal/engine/experiment/dnscheck/dnscheck_test.go +++ b/internal/engine/experiment/dnscheck/dnscheck_test.go @@ -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/model" ) func TestHTTPHostWithOverride(t *testing.T) { diff --git a/internal/engine/experiment/example/example.go b/internal/engine/experiment/example/example.go index 658bc77..96ef4e8 100644 --- a/internal/engine/experiment/example/example.go +++ b/internal/engine/experiment/example/example.go @@ -9,7 +9,7 @@ import ( "errors" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) const testVersion = "0.1.0" diff --git a/internal/engine/experiment/example/example_test.go b/internal/engine/experiment/example/example_test.go index 7b60960..dc7e218 100644 --- a/internal/engine/experiment/example/example_test.go +++ b/internal/engine/experiment/example/example_test.go @@ -9,7 +9,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/engine/experiment/example" "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/model" ) func TestSuccess(t *testing.T) { diff --git a/internal/engine/experiment/fbmessenger/fbmessenger.go b/internal/engine/experiment/fbmessenger/fbmessenger.go index bb96455..2530f59 100644 --- a/internal/engine/experiment/fbmessenger/fbmessenger.go +++ b/internal/engine/experiment/fbmessenger/fbmessenger.go @@ -10,7 +10,7 @@ import ( "time" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/fbmessenger/fbmessenger_test.go b/internal/engine/experiment/fbmessenger/fbmessenger_test.go index 93b8613..72cf194 100644 --- a/internal/engine/experiment/fbmessenger/fbmessenger_test.go +++ b/internal/engine/experiment/fbmessenger/fbmessenger_test.go @@ -10,8 +10,8 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/fbmessenger" "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/archival" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -222,7 +222,7 @@ func TestComputeEndpointStatsDNSIsLying(t *testing.T) { func newsession(t *testing.T) model.ExperimentSession { sess, err := engine.NewSession(context.Background(), engine.SessionConfig{ - AvailableProbeServices: []model.Service{{ + AvailableProbeServices: []model.OOAPIService{{ Address: "https://ams-pg-test.ooni.org", Type: "https", }}, diff --git a/internal/engine/experiment/hhfm/hhfm.go b/internal/engine/experiment/hhfm/hhfm.go index 047ff03..7d916eb 100644 --- a/internal/engine/experiment/hhfm/hhfm.go +++ b/internal/engine/experiment/hhfm/hhfm.go @@ -17,9 +17,9 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" errorsxlegacy "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/randx" ) diff --git a/internal/engine/experiment/hhfm/hhfm_test.go b/internal/engine/experiment/hhfm/hhfm_test.go index a2e757e..827fa3a 100644 --- a/internal/engine/experiment/hhfm/hhfm_test.go +++ b/internal/engine/experiment/hhfm/hhfm_test.go @@ -16,8 +16,8 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/hhfm" "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/archival" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -36,7 +36,7 @@ func TestSuccess(t *testing.T) { ctx := context.Background() sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": {{ Address: "http://37.218.241.94:80", Type: "legacy", @@ -144,7 +144,7 @@ func TestCancelledContext(t *testing.T) { cancel() sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": {{ Address: "http://37.218.241.94:80", Type: "legacy", @@ -303,7 +303,7 @@ func TestNoActualHelpersInList(t *testing.T) { measurer := hhfm.NewExperimentMeasurer(hhfm.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": nil, }, } @@ -353,7 +353,7 @@ func TestWrongTestHelperType(t *testing.T) { measurer := hhfm.NewExperimentMeasurer(hhfm.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": {{ Address: "http://127.0.0.1", Type: "antani", @@ -406,7 +406,7 @@ func TestNewRequestFailure(t *testing.T) { measurer := hhfm.NewExperimentMeasurer(hhfm.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": {{ Address: "http://127.0.0.1\t\t\t", // invalid Type: "legacy", @@ -463,7 +463,7 @@ func TestInvalidJSONBody(t *testing.T) { measurer := hhfm.NewExperimentMeasurer(hhfm.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "http-return-json-headers": {{ Address: server.URL, Type: "legacy", diff --git a/internal/engine/experiment/hirl/hirl.go b/internal/engine/experiment/hirl/hirl.go index dd42020..b63501e 100644 --- a/internal/engine/experiment/hirl/hirl.go +++ b/internal/engine/experiment/hirl/hirl.go @@ -11,9 +11,9 @@ import ( "strings" "time" - "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/randx" ) diff --git a/internal/engine/experiment/hirl/hirl_test.go b/internal/engine/experiment/hirl/hirl_test.go index 6b99f2d..6c4afec 100644 --- a/internal/engine/experiment/hirl/hirl_test.go +++ b/internal/engine/experiment/hirl/hirl_test.go @@ -9,9 +9,9 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/engine/experiment/hirl" "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" "github.com/ooni/probe-cli/v3/internal/engine/netx/archival" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -30,7 +30,7 @@ func TestSuccess(t *testing.T) { ctx := context.Background() sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", @@ -79,7 +79,7 @@ func TestCancelledContext(t *testing.T) { cancel() sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", @@ -178,7 +178,7 @@ func TestWithFakeMethods(t *testing.T) { } ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "127.0.0.1", Type: "legacy", @@ -239,7 +239,7 @@ func TestWithNoMethods(t *testing.T) { } ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "127.0.0.1", Type: "legacy", @@ -302,7 +302,7 @@ func TestNoActualHelperInList(t *testing.T) { measurer := hirl.NewExperimentMeasurer(hirl.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": nil, }, } @@ -334,7 +334,7 @@ func TestWrongTestHelperType(t *testing.T) { measurer := hirl.NewExperimentMeasurer(hirl.Config{}) ctx := context.Background() sess := &mockable.Session{ - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "127.0.0.1", Type: "antani", @@ -368,7 +368,7 @@ func TestWrongTestHelperType(t *testing.T) { func TestRunMethodDialFailure(t *testing.T) { sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", @@ -415,7 +415,7 @@ func TestRunMethodDialFailure(t *testing.T) { func TestRunMethodSetDeadlineFailure(t *testing.T) { sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", @@ -464,7 +464,7 @@ func TestRunMethodSetDeadlineFailure(t *testing.T) { func TestRunMethodWriteFailure(t *testing.T) { sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", @@ -513,7 +513,7 @@ func TestRunMethodWriteFailure(t *testing.T) { func TestRunMethodReadEOFWithWrongData(t *testing.T) { sess := &mockable.Session{ MockableLogger: log.Log, - MockableTestHelpers: map[string][]model.Service{ + MockableTestHelpers: map[string][]model.OOAPIService{ "tcp-echo": {{ Address: "37.218.241.93", Type: "legacy", diff --git a/internal/engine/experiment/httphostheader/httphostheader.go b/internal/engine/experiment/httphostheader/httphostheader.go index 62380da..70eefb7 100644 --- a/internal/engine/experiment/httphostheader/httphostheader.go +++ b/internal/engine/experiment/httphostheader/httphostheader.go @@ -10,7 +10,7 @@ import ( "fmt" "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/model" ) const ( diff --git a/internal/engine/experiment/httphostheader/httphostheader_test.go b/internal/engine/experiment/httphostheader/httphostheader_test.go index 6185de6..efd88ce 100644 --- a/internal/engine/experiment/httphostheader/httphostheader_test.go +++ b/internal/engine/experiment/httphostheader/httphostheader_test.go @@ -8,7 +8,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/model" ) const ( diff --git a/internal/engine/experiment/ndt7/dial.go b/internal/engine/experiment/ndt7/dial.go index 95e41c5..80101aa 100644 --- a/internal/engine/experiment/ndt7/dial.go +++ b/internal/engine/experiment/ndt7/dial.go @@ -7,9 +7,9 @@ import ( "net/url" "github.com/gorilla/websocket" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/engine/netx/dialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/resolver" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/ndt7/ndt7.go b/internal/engine/experiment/ndt7/ndt7.go index c4cfa48..0eca0bc 100644 --- a/internal/engine/experiment/ndt7/ndt7.go +++ b/internal/engine/experiment/ndt7/ndt7.go @@ -11,10 +11,10 @@ import ( "net/http" "time" - "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/humanize" "github.com/ooni/probe-cli/v3/internal/mlablocatev2" + "github.com/ooni/probe-cli/v3/internal/model" ) const ( diff --git a/internal/engine/experiment/ndt7/ndt7_test.go b/internal/engine/experiment/ndt7/ndt7_test.go index 81dc06b..d9c4fd3 100644 --- a/internal/engine/experiment/ndt7/ndt7_test.go +++ b/internal/engine/experiment/ndt7/ndt7_test.go @@ -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/model" ) func TestNewExperimentMeasurer(t *testing.T) { diff --git a/internal/engine/experiment/psiphon/psiphon.go b/internal/engine/experiment/psiphon/psiphon.go index 79b42d8..3a09323 100644 --- a/internal/engine/experiment/psiphon/psiphon.go +++ b/internal/engine/experiment/psiphon/psiphon.go @@ -11,7 +11,7 @@ import ( "time" "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/model" ) const ( diff --git a/internal/engine/experiment/psiphon/psiphon_test.go b/internal/engine/experiment/psiphon/psiphon_test.go index 8ab004e..43aff1c 100644 --- a/internal/engine/experiment/psiphon/psiphon_test.go +++ b/internal/engine/experiment/psiphon/psiphon_test.go @@ -12,7 +12,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/psiphon" "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/model" ) // Implementation note: integration test performed by diff --git a/internal/engine/experiment/riseupvpn/riseupvpn.go b/internal/engine/experiment/riseupvpn/riseupvpn.go index 40cb3cf..dfddbc6 100644 --- a/internal/engine/experiment/riseupvpn/riseupvpn.go +++ b/internal/engine/experiment/riseupvpn/riseupvpn.go @@ -10,8 +10,8 @@ import ( "time" "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/archival" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/riseupvpn/riseupvpn_test.go b/internal/engine/experiment/riseupvpn/riseupvpn_test.go index c2eb9a4..5da3efe 100644 --- a/internal/engine/experiment/riseupvpn/riseupvpn_test.go +++ b/internal/engine/experiment/riseupvpn/riseupvpn_test.go @@ -15,8 +15,8 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/riseupvpn" "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/archival" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/run/dnscheck.go b/internal/engine/experiment/run/dnscheck.go index 0bdbea3..a116fb5 100644 --- a/internal/engine/experiment/run/dnscheck.go +++ b/internal/engine/experiment/run/dnscheck.go @@ -5,7 +5,7 @@ import ( "sync" "github.com/ooni/probe-cli/v3/internal/engine/experiment/dnscheck" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type dnsCheckMain struct { diff --git a/internal/engine/experiment/run/run.go b/internal/engine/experiment/run/run.go index b7e1cd9..d633a64 100644 --- a/internal/engine/experiment/run/run.go +++ b/internal/engine/experiment/run/run.go @@ -10,7 +10,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/dnscheck" "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/model" ) // Config contains settings. diff --git a/internal/engine/experiment/run/run_test.go b/internal/engine/experiment/run/run_test.go index 886aa79..df79e3c 100644 --- a/internal/engine/experiment/run/run_test.go +++ b/internal/engine/experiment/run/run_test.go @@ -9,7 +9,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/run" "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/model" ) func TestExperimentNameAndVersion(t *testing.T) { diff --git a/internal/engine/experiment/run/table.go b/internal/engine/experiment/run/table.go index d737992..b618399 100644 --- a/internal/engine/experiment/run/table.go +++ b/internal/engine/experiment/run/table.go @@ -4,7 +4,7 @@ import ( "context" "github.com/ooni/probe-cli/v3/internal/engine/experiment/dnscheck" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type experimentMain interface { diff --git a/internal/engine/experiment/run/urlgetter.go b/internal/engine/experiment/run/urlgetter.go index 70a96ef..085f78f 100644 --- a/internal/engine/experiment/run/urlgetter.go +++ b/internal/engine/experiment/run/urlgetter.go @@ -4,7 +4,7 @@ import ( "context" "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/model" ) type urlGetterMain struct{} diff --git a/internal/engine/experiment/signal/signal.go b/internal/engine/experiment/signal/signal.go index a13f73d..4aa9a2e 100644 --- a/internal/engine/experiment/signal/signal.go +++ b/internal/engine/experiment/signal/signal.go @@ -9,7 +9,7 @@ import ( "time" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/signal/signal_test.go b/internal/engine/experiment/signal/signal_test.go index d025db0..5c5f0f8 100644 --- a/internal/engine/experiment/signal/signal_test.go +++ b/internal/engine/experiment/signal/signal_test.go @@ -8,7 +8,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/signal" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/sniblocking/sniblocking.go b/internal/engine/experiment/sniblocking/sniblocking.go index f6adc0a..e1ab4a8 100644 --- a/internal/engine/experiment/sniblocking/sniblocking.go +++ b/internal/engine/experiment/sniblocking/sniblocking.go @@ -14,7 +14,7 @@ import ( "time" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/sniblocking/sniblocking_test.go b/internal/engine/experiment/sniblocking/sniblocking_test.go index 51fc1e9..bcbae62 100644 --- a/internal/engine/experiment/sniblocking/sniblocking_test.go +++ b/internal/engine/experiment/sniblocking/sniblocking_test.go @@ -8,7 +8,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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/stunreachability/fake_test.go b/internal/engine/experiment/stunreachability/fake_test.go index 47df024..cb9befa 100644 --- a/internal/engine/experiment/stunreachability/fake_test.go +++ b/internal/engine/experiment/stunreachability/fake_test.go @@ -6,7 +6,7 @@ import ( "time" ) -// TODO(bassosimone): we should use internal/netxlite/mocks rather +// TODO(bassosimone): we should use internal/model/mocks rather // than rolling out a custom type private to this package. type FakeConn struct { diff --git a/internal/engine/experiment/stunreachability/stunreachability.go b/internal/engine/experiment/stunreachability/stunreachability.go index e017701..d3c47c9 100644 --- a/internal/engine/experiment/stunreachability/stunreachability.go +++ b/internal/engine/experiment/stunreachability/stunreachability.go @@ -12,11 +12,11 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "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/dialer" "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/pion/stun" ) diff --git a/internal/engine/experiment/stunreachability/stunreachability_test.go b/internal/engine/experiment/stunreachability/stunreachability_test.go index 4ae8fe9..d928b73 100644 --- a/internal/engine/experiment/stunreachability/stunreachability_test.go +++ b/internal/engine/experiment/stunreachability/stunreachability_test.go @@ -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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/pion/stun" ) diff --git a/internal/engine/experiment/telegram/telegram.go b/internal/engine/experiment/telegram/telegram.go index b9faf3c..3b29cbe 100644 --- a/internal/engine/experiment/telegram/telegram.go +++ b/internal/engine/experiment/telegram/telegram.go @@ -10,7 +10,7 @@ import ( "time" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/telegram/telegram_test.go b/internal/engine/experiment/telegram/telegram_test.go index dfcd514..4d206bf 100644 --- a/internal/engine/experiment/telegram/telegram_test.go +++ b/internal/engine/experiment/telegram/telegram_test.go @@ -11,7 +11,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/telegram" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/tlstool/tlstool.go b/internal/engine/experiment/tlstool/tlstool.go index 3eee7e1..d61a844 100644 --- a/internal/engine/experiment/tlstool/tlstool.go +++ b/internal/engine/experiment/tlstool/tlstool.go @@ -16,9 +16,9 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine/experiment/tlstool/internal" - "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/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) diff --git a/internal/engine/experiment/tlstool/tlstool_test.go b/internal/engine/experiment/tlstool/tlstool_test.go index 1256ee1..6f95dde 100644 --- a/internal/engine/experiment/tlstool/tlstool_test.go +++ b/internal/engine/experiment/tlstool/tlstool_test.go @@ -7,7 +7,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/engine/experiment/tlstool" "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/model" ) func TestMeasurerExperimentNameVersion(t *testing.T) { diff --git a/internal/engine/experiment/tor/tor.go b/internal/engine/experiment/tor/tor.go index 3f22dbc..666ca41 100644 --- a/internal/engine/experiment/tor/tor.go +++ b/internal/engine/experiment/tor/tor.go @@ -17,7 +17,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/legacy/netxlogger" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/runtimex" "github.com/ooni/probe-cli/v3/internal/scrubber" @@ -144,14 +144,14 @@ func (tk *TestKeys) fillToplevelKeys() { // Measurer performs the measurement. type Measurer struct { config Config - fetchTorTargets func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.TorTarget, error) + fetchTorTargets func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.OOAPITorTarget, error) } // NewMeasurer creates a new Measurer func NewMeasurer(config Config) *Measurer { return &Measurer{ config: config, - fetchTorTargets: func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.TorTarget, error) { + fetchTorTargets: func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.OOAPITorTarget, error) { return sess.FetchTorTargets(ctx, cc) }, } @@ -189,7 +189,7 @@ func (m *Measurer) Run( func (m *Measurer) gimmeTargets( ctx context.Context, sess model.ExperimentSession, -) (map[string]model.TorTarget, error) { +) (map[string]model.OOAPITorTarget, error) { ctx, cancel := context.WithTimeout(ctx, 15*time.Second) defer cancel() return m.fetchTorTargets(ctx, sess, sess.ProbeCC()) @@ -198,7 +198,7 @@ func (m *Measurer) gimmeTargets( // keytarget contains a key and the related target type keytarget struct { key string - target model.TorTarget + target model.OOAPITorTarget } // private returns whether a target is private. We consider private @@ -222,7 +222,7 @@ func (m *Measurer) measureTargets( sess model.ExperimentSession, measurement *model.Measurement, callbacks model.ExperimentCallbacks, - targets map[string]model.TorTarget, + targets map[string]model.OOAPITorTarget, ) { // run measurements in parallel var waitgroup sync.WaitGroup @@ -327,7 +327,7 @@ func maybeScrubbingLogger(input model.Logger, kt keytarget) model.Logger { if !kt.private() { return input } - return &scrubber.Logger{UnderlyingLogger: input} + return &scrubber.Logger{Logger: input} } func (rc *resultsCollector) defaultFlexibleConnect( diff --git a/internal/engine/experiment/tor/tor_test.go b/internal/engine/experiment/tor/tor_test.go index fdf33ee..eba3437 100644 --- a/internal/engine/experiment/tor/tor_test.go +++ b/internal/engine/experiment/tor/tor_test.go @@ -16,7 +16,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/mockable" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/scrubber" ) @@ -34,7 +34,7 @@ func TestNewExperimentMeasurer(t *testing.T) { func TestMeasurerMeasureFetchTorTargetsError(t *testing.T) { measurer := NewMeasurer(Config{}) expected := errors.New("mocked error") - measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.TorTarget, error) { + measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.OOAPITorTarget, error) { return nil, expected } err := measurer.Run( @@ -52,7 +52,7 @@ func TestMeasurerMeasureFetchTorTargetsError(t *testing.T) { func TestMeasurerMeasureFetchTorTargetsEmptyList(t *testing.T) { measurer := NewMeasurer(Config{}) - measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.TorTarget, error) { + measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.OOAPITorTarget, error) { return nil, nil } measurement := new(model.Measurement) @@ -77,7 +77,7 @@ func TestMeasurerMeasureGoodWithMockedOrchestra(t *testing.T) { // This test mocks orchestra to return a nil list of targets, so the code runs // but we don't perform any actual network actions. measurer := NewMeasurer(Config{}) - measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.TorTarget, error) { + measurer.fetchTorTargets = func(ctx context.Context, sess model.ExperimentSession, cc string) (map[string]model.OOAPITorTarget, error) { return nil, nil } err := measurer.Run( @@ -120,7 +120,7 @@ func TestMeasurerMeasureGood(t *testing.T) { var staticPrivateTestingTargetEndpoint = "192.95.36.142:443" -var staticPrivateTestingTarget = model.TorTarget{ +var staticPrivateTestingTarget = model.OOAPITorTarget{ Address: staticPrivateTestingTargetEndpoint, Params: map[string][]string{ "cert": { @@ -139,7 +139,7 @@ func TestMeasurerMeasureSanitiseOutput(t *testing.T) { measurer := NewMeasurer(Config{}) sess := newsession() key := "xyz-xyz-xyz-theCh2ju-ahG4chei-Ai2eka0a" - sess.MockableFetchTorTargetsResult = map[string]model.TorTarget{ + sess.MockableFetchTorTargetsResult = map[string]model.OOAPITorTarget{ key: staticPrivateTestingTarget, } measurement := new(model.Measurement) @@ -172,7 +172,7 @@ func TestMeasurerMeasureSanitiseOutput(t *testing.T) { } } -var staticTestingTargets = []model.TorTarget{ +var staticTestingTargets = []model.OOAPITorTarget{ { Address: "192.95.36.142:443", Params: map[string][]string{ @@ -226,7 +226,7 @@ func TestMeasurerMeasureTargetsCanceledContext(t *testing.T) { }, &measurement, model.NewPrinterCallbacks(log.Log), - map[string]model.TorTarget{ + map[string]model.OOAPITorTarget{ "xx": staticTestingTargets[0], }, ) @@ -243,7 +243,7 @@ func TestMeasurerMeasureTargetsCanceledContext(t *testing.T) { } } -func wrapTestingTarget(tt model.TorTarget) keytarget { +func wrapTestingTarget(tt model.OOAPITorTarget) keytarget { return keytarget{ key: "xx", // using an super simple key; should work anyway target: tt, @@ -683,7 +683,7 @@ func TestMaybeSanitize(t *testing.T) { t.Fatal(err) } t.Run("nothing to do", func(t *testing.T) { - out := maybeSanitize(input, keytarget{target: model.TorTarget{Source: ""}}) + out := maybeSanitize(input, keytarget{target: model.OOAPITorTarget{Source: ""}}) diff := cmp.Diff(input, out) if diff != "" { t.Fatal(diff) @@ -694,7 +694,7 @@ func TestMaybeSanitize(t *testing.T) { if err := json.Unmarshal(scrubbedTargetResult, &expected); err != nil { t.Fatal(err) } - out := maybeSanitize(input, keytarget{target: model.TorTarget{ + out := maybeSanitize(input, keytarget{target: model.OOAPITorTarget{ Address: "85.31.186.98:443", Source: "bridgedb", }}) @@ -709,7 +709,7 @@ func TestMaybeScrubbingLogger(t *testing.T) { var input model.Logger = log.Log t.Run("for when we don't need to save", func(t *testing.T) { - kt := keytarget{target: model.TorTarget{ + kt := keytarget{target: model.OOAPITorTarget{ Source: "", }} out := maybeScrubbingLogger(input, kt) @@ -722,7 +722,7 @@ func TestMaybeScrubbingLogger(t *testing.T) { }) t.Run("for when we need to save", func(t *testing.T) { - kt := keytarget{target: model.TorTarget{ + kt := keytarget{target: model.OOAPITorTarget{ Source: "bridgedb", }} out := maybeScrubbingLogger(input, kt) diff --git a/internal/engine/experiment/torsf/integration_test.go b/internal/engine/experiment/torsf/integration_test.go index fe0ca51..80feb82 100644 --- a/internal/engine/experiment/torsf/integration_test.go +++ b/internal/engine/experiment/torsf/integration_test.go @@ -8,7 +8,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/engine/experiment/torsf" "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/model" "golang.org/x/sys/execabs" ) diff --git a/internal/engine/experiment/torsf/torsf.go b/internal/engine/experiment/torsf/torsf.go index aa2485e..7fee4b2 100644 --- a/internal/engine/experiment/torsf/torsf.go +++ b/internal/engine/experiment/torsf/torsf.go @@ -9,8 +9,8 @@ import ( "path" "time" - "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/model" "github.com/ooni/probe-cli/v3/internal/ptx" "github.com/ooni/probe-cli/v3/internal/tunnel" ) diff --git a/internal/engine/experiment/torsf/torsf_test.go b/internal/engine/experiment/torsf/torsf_test.go index 651062b..0a1d465 100644 --- a/internal/engine/experiment/torsf/torsf_test.go +++ b/internal/engine/experiment/torsf/torsf_test.go @@ -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/model" "github.com/ooni/probe-cli/v3/internal/tunnel" ) diff --git a/internal/engine/experiment/urlgetter/configurer.go b/internal/engine/experiment/urlgetter/configurer.go index 92056bb..ad405c2 100644 --- a/internal/engine/experiment/urlgetter/configurer.go +++ b/internal/engine/experiment/urlgetter/configurer.go @@ -8,9 +8,9 @@ import ( "regexp" "strings" - "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/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/urlgetter/getter.go b/internal/engine/experiment/urlgetter/getter.go index fbcedf4..2292a71 100644 --- a/internal/engine/experiment/urlgetter/getter.go +++ b/internal/engine/experiment/urlgetter/getter.go @@ -7,9 +7,9 @@ import ( "time" legacyerrorsx "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "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/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/tunnel" ) diff --git a/internal/engine/experiment/urlgetter/multi.go b/internal/engine/experiment/urlgetter/multi.go index 424cc43..6715143 100644 --- a/internal/engine/experiment/urlgetter/multi.go +++ b/internal/engine/experiment/urlgetter/multi.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // MultiInput is the input for Multi.Run(). diff --git a/internal/engine/experiment/urlgetter/multi_test.go b/internal/engine/experiment/urlgetter/multi_test.go index b5c161b..1b1b3a6 100644 --- a/internal/engine/experiment/urlgetter/multi_test.go +++ b/internal/engine/experiment/urlgetter/multi_test.go @@ -13,7 +13,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/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestMultiIntegration(t *testing.T) { diff --git a/internal/engine/experiment/urlgetter/urlgetter.go b/internal/engine/experiment/urlgetter/urlgetter.go index 735d67e..46c3495 100644 --- a/internal/engine/experiment/urlgetter/urlgetter.go +++ b/internal/engine/experiment/urlgetter/urlgetter.go @@ -8,8 +8,8 @@ import ( "crypto/x509" "time" - "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/model" ) const ( diff --git a/internal/engine/experiment/urlgetter/urlgetter_test.go b/internal/engine/experiment/urlgetter/urlgetter_test.go index c8897f8..a49ada1 100644 --- a/internal/engine/experiment/urlgetter/urlgetter_test.go +++ b/internal/engine/experiment/urlgetter/urlgetter_test.go @@ -8,7 +8,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/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestMeasurer(t *testing.T) { diff --git a/internal/engine/experiment/webconnectivity/connects.go b/internal/engine/experiment/webconnectivity/connects.go index 1500a95..fd3cf39 100644 --- a/internal/engine/experiment/webconnectivity/connects.go +++ b/internal/engine/experiment/webconnectivity/connects.go @@ -6,7 +6,7 @@ import ( "time" "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/model" ) // ConnectsConfig contains the config for Connects diff --git a/internal/engine/experiment/webconnectivity/control.go b/internal/engine/experiment/webconnectivity/control.go index 9c051ee..f6a990e 100644 --- a/internal/engine/experiment/webconnectivity/control.go +++ b/internal/engine/experiment/webconnectivity/control.go @@ -6,7 +6,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/geolocate" "github.com/ooni/probe-cli/v3/internal/engine/httpx" legacyerrorsx "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/webconnectivity/dnslookup.go b/internal/engine/experiment/webconnectivity/dnslookup.go index e5624d1..be435ad 100644 --- a/internal/engine/experiment/webconnectivity/dnslookup.go +++ b/internal/engine/experiment/webconnectivity/dnslookup.go @@ -8,7 +8,7 @@ import ( "time" "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/model" ) // DNSLookupConfig contains settings for the DNS lookup. diff --git a/internal/engine/experiment/webconnectivity/httpanalysis.go b/internal/engine/experiment/webconnectivity/httpanalysis.go index b8f3e00..346707f 100644 --- a/internal/engine/experiment/webconnectivity/httpanalysis.go +++ b/internal/engine/experiment/webconnectivity/httpanalysis.go @@ -7,7 +7,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter" "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/model" ) // HTTPAnalysisResult contains the results of the analysis performed on the diff --git a/internal/engine/experiment/webconnectivity/httpget.go b/internal/engine/experiment/webconnectivity/httpget.go index 0c06d84..84ebfdd 100644 --- a/internal/engine/experiment/webconnectivity/httpget.go +++ b/internal/engine/experiment/webconnectivity/httpget.go @@ -9,7 +9,7 @@ import ( "time" "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/model" ) // HTTPGetConfig contains the config for HTTPGet diff --git a/internal/engine/experiment/webconnectivity/summary.go b/internal/engine/experiment/webconnectivity/summary.go index 4ed2a8b..d6e8e2a 100644 --- a/internal/engine/experiment/webconnectivity/summary.go +++ b/internal/engine/experiment/webconnectivity/summary.go @@ -4,7 +4,7 @@ import ( "strings" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/webconnectivity/webconnectivity.go b/internal/engine/experiment/webconnectivity/webconnectivity.go index 9aaa568..b81a44c 100644 --- a/internal/engine/experiment/webconnectivity/webconnectivity.go +++ b/internal/engine/experiment/webconnectivity/webconnectivity.go @@ -13,8 +13,8 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/webconnectivity/internal" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" - "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/model" ) const ( @@ -149,7 +149,7 @@ func (m Measurer) Run( } // 1. find test helper testhelpers, _ := sess.GetTestHelpersByName("web-connectivity") - var testhelper *model.Service + var testhelper *model.OOAPIService for _, th := range testhelpers { if th.Type == "https" { testhelper = &th diff --git a/internal/engine/experiment/webconnectivity/webconnectivity_test.go b/internal/engine/experiment/webconnectivity/webconnectivity_test.go index cef81b3..4ce01dd 100644 --- a/internal/engine/experiment/webconnectivity/webconnectivity_test.go +++ b/internal/engine/experiment/webconnectivity/webconnectivity_test.go @@ -11,8 +11,8 @@ import ( "github.com/google/go-cmp/cmp" engine "github.com/ooni/probe-cli/v3/internal/engine" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -202,7 +202,7 @@ func TestMeasureWithNoAvailableTestHelpers(t *testing.T) { func newsession(t *testing.T, lookupBackends bool) model.ExperimentSession { sess, err := engine.NewSession(context.Background(), engine.SessionConfig{ - AvailableProbeServices: []model.Service{{ + AvailableProbeServices: []model.OOAPIService{{ Address: "https://ams-pg-test.ooni.org", Type: "https", }}, diff --git a/internal/engine/experiment/websteps/control.go b/internal/engine/experiment/websteps/control.go index b968bec..4c68b8e 100644 --- a/internal/engine/experiment/websteps/control.go +++ b/internal/engine/experiment/websteps/control.go @@ -5,7 +5,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/httpx" errorsxlegacy "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/experiment/websteps/factory.go b/internal/engine/experiment/websteps/factory.go index 5c835fc..44cc5c3 100644 --- a/internal/engine/experiment/websteps/factory.go +++ b/internal/engine/experiment/websteps/factory.go @@ -14,6 +14,7 @@ import ( oohttp "github.com/ooni/oohttp" "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" "github.com/ooni/probe-cli/v3/internal/engine/netx/quicdialer" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/runtimex" ) @@ -80,7 +81,7 @@ func NewSingleTransport(conn net.Conn) http.RoundTripper { } // NewSingleTransport creates a new HTTP transport with a custom dialer and handshaker. -func NewTransportWithDialer(dialer netxlite.DialerLegacy, tlsConfig *tls.Config, handshaker netxlite.TLSHandshaker) http.RoundTripper { +func NewTransportWithDialer(dialer netxlite.DialerLegacy, tlsConfig *tls.Config, handshaker model.TLSHandshaker) http.RoundTripper { transport := newBaseTransport() transport.DialContext = dialer.DialContext transport.DialTLSContext = (&netxlite.TLSDialerLegacy{ diff --git a/internal/engine/experiment/websteps/websteps.go b/internal/engine/experiment/websteps/websteps.go index 7bba6e6..0ff37e0 100644 --- a/internal/engine/experiment/websteps/websteps.go +++ b/internal/engine/experiment/websteps/websteps.go @@ -24,8 +24,8 @@ import ( "github.com/lucas-clemente/quic-go" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" - "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/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) @@ -111,7 +111,7 @@ func (m Measurer) Run( // 3. Find the testhelper // TODO(kelmenhorst,bassosimone): this is not used at the moment, but the hardcoded local address testhelpers, _ := sess.GetTestHelpersByName("web-connectivity") - var testhelper *model.Service + var testhelper *model.OOAPIService for _, th := range testhelpers { if th.Type == "https" { testhelper = &th diff --git a/internal/engine/experiment/webstepsx/measurer.go b/internal/engine/experiment/webstepsx/measurer.go index 5b08600..af4c43a 100644 --- a/internal/engine/experiment/webstepsx/measurer.go +++ b/internal/engine/experiment/webstepsx/measurer.go @@ -13,9 +13,9 @@ import ( "net/url" "time" - "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/measurex" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -85,7 +85,7 @@ func (mx *Measurer) RunAsync( } // 2. Find the testhelper testhelpers, _ := sess.GetTestHelpersByName("web-connectivity") - var testhelper *model.Service + var testhelper *model.OOAPIService for _, th := range testhelpers { if th.Type == "https" { testhelper = &th @@ -110,7 +110,7 @@ var measurerResolvers = []*measurex.ResolverInfo{{ }} func (mx *Measurer) runAsync(ctx context.Context, sess model.ExperimentSession, - URL string, th *model.Service, out chan<- *model.ExperimentAsyncTestKeys) { + URL string, th *model.OOAPIService, out chan<- *model.ExperimentAsyncTestKeys) { defer close(out) helper := &measurerMeasureURLHelper{ Clnt: sess.DefaultHTTPClient(), diff --git a/internal/engine/experiment/whatsapp/whatsapp.go b/internal/engine/experiment/whatsapp/whatsapp.go index cb560a9..bdc4538 100644 --- a/internal/engine/experiment/whatsapp/whatsapp.go +++ b/internal/engine/experiment/whatsapp/whatsapp.go @@ -14,7 +14,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter" "github.com/ooni/probe-cli/v3/internal/engine/internal/httpfailure" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) diff --git a/internal/engine/experiment/whatsapp/whatsapp_test.go b/internal/engine/experiment/whatsapp/whatsapp_test.go index 6831e27..70d1cf0 100644 --- a/internal/engine/experiment/whatsapp/whatsapp_test.go +++ b/internal/engine/experiment/whatsapp/whatsapp_test.go @@ -14,7 +14,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/experiment/whatsapp" "github.com/ooni/probe-cli/v3/internal/engine/internal/httpfailure" "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/model" ) func TestNewExperimentMeasurer(t *testing.T) { diff --git a/internal/engine/experiment_integration_test.go b/internal/engine/experiment_integration_test.go index d10aea4..21701b8 100644 --- a/internal/engine/experiment_integration_test.go +++ b/internal/engine/experiment_integration_test.go @@ -13,7 +13,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/engine/experiment/example" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestCreateAll(t *testing.T) { @@ -454,7 +454,7 @@ func TestOpenReportFailure(t *testing.T) { t.Fatal(err) } exp := builder.NewExperiment() - exp.session.selectedProbeService = &model.Service{ + exp.session.selectedProbeService = &model.OOAPIService{ Address: server.URL, Type: "https", } @@ -475,7 +475,7 @@ func TestOpenReportNewClientFailure(t *testing.T) { t.Fatal(err) } exp := builder.NewExperiment() - exp.session.selectedProbeService = &model.Service{ + exp.session.selectedProbeService = &model.OOAPIService{ Address: "antani:///", Type: "antani", } @@ -523,7 +523,7 @@ func TestOpenReportNonHTTPS(t *testing.T) { } sess := newSessionForTestingNoLookups(t) defer sess.Close() - sess.availableProbeServices = []model.Service{ + sess.availableProbeServices = []model.OOAPIService{ { Address: "antani", Type: "mascetti", diff --git a/internal/engine/experiment_internal_test.go b/internal/engine/experiment_internal_test.go index fa9d7e6..6adc11c 100644 --- a/internal/engine/experiment_internal_test.go +++ b/internal/engine/experiment_internal_test.go @@ -3,7 +3,7 @@ package engine import ( "os" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func (e *Experiment) SaveMeasurementEx( diff --git a/internal/engine/experiment_test.go b/internal/engine/experiment_test.go index 639ddbb..fe126d7 100644 --- a/internal/engine/experiment_test.go +++ b/internal/engine/experiment_test.go @@ -4,7 +4,7 @@ import ( "testing" "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/model" ) func TestExperimentHonoursSharingDefaults(t *testing.T) { diff --git a/internal/engine/experimentbuilder.go b/internal/engine/experimentbuilder.go index 0177d98..26fe32b 100644 --- a/internal/engine/experimentbuilder.go +++ b/internal/engine/experimentbuilder.go @@ -8,7 +8,7 @@ import ( "strconv" "github.com/iancoleman/strcase" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // InputPolicy describes the experiment policy with respect to input. That is diff --git a/internal/engine/geolocate/avast.go b/internal/engine/geolocate/avast.go index fb6f7fd..cf7986c 100644 --- a/internal/engine/geolocate/avast.go +++ b/internal/engine/geolocate/avast.go @@ -5,6 +5,7 @@ import ( "net/http" "github.com/ooni/probe-cli/v3/internal/engine/httpx" + "github.com/ooni/probe-cli/v3/internal/model" ) type avastResponse struct { @@ -14,7 +15,7 @@ type avastResponse struct { func avastIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { var v avastResponse diff --git a/internal/engine/geolocate/geolocate.go b/internal/engine/geolocate/geolocate.go index c75244b..ca81cba 100644 --- a/internal/engine/geolocate/geolocate.go +++ b/internal/engine/geolocate/geolocate.go @@ -6,6 +6,7 @@ import ( "fmt" "github.com/ooni/probe-cli/v3/internal/engine/netx" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/version" ) @@ -17,7 +18,7 @@ const ( DefaultProbeCC = "ZZ" // DefaultProbeIP is the default probe IP. - DefaultProbeIP = "127.0.0.1" + DefaultProbeIP = model.DefaultProbeIP // DefaultProbeNetworkName is the default probe network name. DefaultProbeNetworkName = "" @@ -40,13 +41,6 @@ var ( DefaultResolverASNString = fmt.Sprintf("AS%d", DefaultResolverASN) ) -// Logger is the definition of Logger used by this package. -type Logger interface { - Debug(msg string) - Debugf(format string, v ...interface{}) - Infof(format string, v ...interface{}) -} - // Results contains geolocate results. type Results struct { // ASN is the autonomous system number. @@ -111,26 +105,17 @@ type Config struct { // Logger is the logger to use. If not set, then we will // use a logger that discards all messages. - Logger Logger + Logger model.Logger // UserAgent is the user agent to use. If not set, then // we will use a default user agent. UserAgent string } -// discardLogger just ignores log messages thrown at it. -type discardLogger struct{} - -func (*discardLogger) Debug(msg string) {} - -func (*discardLogger) Debugf(format string, v ...interface{}) {} - -func (*discardLogger) Infof(format string, v ...interface{}) {} - // NewTask creates a new instance of Task from config. func NewTask(config Config) *Task { if config.Logger == nil { - config.Logger = &discardLogger{} + config.Logger = model.DiscardLogger } if config.UserAgent == "" { config.UserAgent = fmt.Sprintf("ooniprobe-engine/%s", version.Version) diff --git a/internal/engine/geolocate/invalid_test.go b/internal/engine/geolocate/invalid_test.go index ad4e08a..aade7c7 100644 --- a/internal/engine/geolocate/invalid_test.go +++ b/internal/engine/geolocate/invalid_test.go @@ -3,12 +3,14 @@ package geolocate import ( "context" "net/http" + + "github.com/ooni/probe-cli/v3/internal/model" ) func invalidIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { return "invalid IP", nil diff --git a/internal/engine/geolocate/ipconfig.go b/internal/engine/geolocate/ipconfig.go index b6baa8c..057ad68 100644 --- a/internal/engine/geolocate/ipconfig.go +++ b/internal/engine/geolocate/ipconfig.go @@ -7,12 +7,13 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/httpheader" "github.com/ooni/probe-cli/v3/internal/engine/httpx" + "github.com/ooni/probe-cli/v3/internal/model" ) func ipConfigIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { data, err := (httpx.Client{ diff --git a/internal/engine/geolocate/ipinfo.go b/internal/engine/geolocate/ipinfo.go index 5f43427..141c1ff 100644 --- a/internal/engine/geolocate/ipinfo.go +++ b/internal/engine/geolocate/ipinfo.go @@ -6,6 +6,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/httpheader" "github.com/ooni/probe-cli/v3/internal/engine/httpx" + "github.com/ooni/probe-cli/v3/internal/model" ) type ipInfoResponse struct { @@ -15,7 +16,7 @@ type ipInfoResponse struct { func ipInfoIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { var v ipInfoResponse diff --git a/internal/engine/geolocate/iplookup.go b/internal/engine/geolocate/iplookup.go index d9db4fe..03048e9 100644 --- a/internal/engine/geolocate/iplookup.go +++ b/internal/engine/geolocate/iplookup.go @@ -10,6 +10,7 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine/netx" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/multierror" ) @@ -25,7 +26,7 @@ var ( type lookupFunc func( ctx context.Context, client *http.Client, - logger Logger, userAgent string, + logger model.Logger, userAgent string, ) (string, error) type method struct { @@ -67,7 +68,7 @@ type ipLookupClient struct { Resolver Resolver // Logger is the logger to use - Logger Logger + Logger model.Logger // UserAgent is the user agent to use UserAgent string diff --git a/internal/engine/geolocate/stun.go b/internal/engine/geolocate/stun.go index 90332db..9e98dda 100644 --- a/internal/engine/geolocate/stun.go +++ b/internal/engine/geolocate/stun.go @@ -4,6 +4,7 @@ import ( "context" "net/http" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/pion/stun" ) @@ -20,7 +21,7 @@ type stunClient interface { type stunConfig struct { Dial func(network string, address string) (stunClient, error) Endpoint string - Logger Logger + Logger model.Logger } func stunDialer(network string, address string) (stunClient, error) { @@ -75,7 +76,7 @@ func stunIPLookup(ctx context.Context, config stunConfig) (string, error) { func stunEkigaIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { return stunIPLookup(ctx, stunConfig{ @@ -87,7 +88,7 @@ func stunEkigaIPLookup( func stunGoogleIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { return stunIPLookup(ctx, stunConfig{ diff --git a/internal/engine/geolocate/ubuntu.go b/internal/engine/geolocate/ubuntu.go index 6fecded..b820fc4 100644 --- a/internal/engine/geolocate/ubuntu.go +++ b/internal/engine/geolocate/ubuntu.go @@ -6,6 +6,7 @@ import ( "net/http" "github.com/ooni/probe-cli/v3/internal/engine/httpx" + "github.com/ooni/probe-cli/v3/internal/model" ) type ubuntuResponse struct { @@ -16,7 +17,7 @@ type ubuntuResponse struct { func ubuntuIPLookup( ctx context.Context, httpClient *http.Client, - logger Logger, + logger model.Logger, userAgent string, ) (string, error) { data, err := (httpx.Client{ diff --git a/internal/engine/httpx/jsonapi.go b/internal/engine/httpx/jsonapi.go index 76a2ae9..ec52f48 100644 --- a/internal/engine/httpx/jsonapi.go +++ b/internal/engine/httpx/jsonapi.go @@ -10,14 +10,10 @@ import ( "net/http" "net/url" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) -// Logger is the definition of Logger used by this package. -type Logger interface { - Debugf(format string, v ...interface{}) -} - // Client is an extended client. type Client struct { // Accept contains the accept header. @@ -37,7 +33,7 @@ type Client struct { Host string // Logger is the logger to use. - Logger Logger + Logger model.DebugLogger // UserAgent is the user agent to use. UserAgent string diff --git a/internal/engine/inputloader.go b/internal/engine/inputloader.go index 3e5792d..2539039 100644 --- a/internal/engine/inputloader.go +++ b/internal/engine/inputloader.go @@ -9,8 +9,8 @@ import ( "net/url" "github.com/apex/log" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/fsx" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/stuninput" ) @@ -27,7 +27,7 @@ var ( // introduce this abstraction because it helps us with testing. type InputLoaderSession interface { CheckIn(ctx context.Context, - config *model.CheckInConfig) (*model.CheckInInfo, error) + config *model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) } // InputLoaderLogger is the logger according to an InputLoader. @@ -76,7 +76,7 @@ type InputLoader struct { // not set, then we'll create a default config. If set but // there are fields inside it that are not set, then we // will set them to a default value. - CheckInConfig *model.CheckInConfig + CheckInConfig *model.OOAPICheckInConfig // ExperimentName is the name of the experiment. This field // is only used together with the InputOrStaticDefault policy. @@ -110,7 +110,7 @@ type InputLoader struct { // Load attempts to load input using the specified input loader. We will // return a list of URLs because this is the only input we support. -func (il *InputLoader) Load(ctx context.Context) ([]model.URLInfo, error) { +func (il *InputLoader) Load(ctx context.Context) ([]model.OOAPIURLInfo, error) { switch il.InputPolicy { case InputOptional: return il.loadOptional() @@ -126,26 +126,26 @@ func (il *InputLoader) Load(ctx context.Context) ([]model.URLInfo, error) { } // loadNone implements the InputNone policy. -func (il *InputLoader) loadNone() ([]model.URLInfo, error) { +func (il *InputLoader) loadNone() ([]model.OOAPIURLInfo, error) { if len(il.StaticInputs) > 0 || len(il.SourceFiles) > 0 { return nil, ErrNoInputExpected } // Note that we need to return a single empty entry. - return []model.URLInfo{{}}, nil + return []model.OOAPIURLInfo{{}}, nil } // loadOptional implements the InputOptional policy. -func (il *InputLoader) loadOptional() ([]model.URLInfo, error) { +func (il *InputLoader) loadOptional() ([]model.OOAPIURLInfo, error) { inputs, err := il.loadLocal() if err == nil && len(inputs) <= 0 { // Note that we need to return a single empty entry. - inputs = []model.URLInfo{{}} + inputs = []model.OOAPIURLInfo{{}} } return inputs, err } // loadStrictlyRequired implements the InputStrictlyRequired policy. -func (il *InputLoader) loadStrictlyRequired(ctx context.Context) ([]model.URLInfo, error) { +func (il *InputLoader) loadStrictlyRequired(ctx context.Context) ([]model.OOAPIURLInfo, error) { inputs, err := il.loadLocal() if err != nil || len(inputs) > 0 { return inputs, err @@ -154,7 +154,7 @@ func (il *InputLoader) loadStrictlyRequired(ctx context.Context) ([]model.URLInf } // loadOrQueryBackend implements the InputOrQueryBackend policy. -func (il *InputLoader) loadOrQueryBackend(ctx context.Context) ([]model.URLInfo, error) { +func (il *InputLoader) loadOrQueryBackend(ctx context.Context) ([]model.OOAPIURLInfo, error) { inputs, err := il.loadLocal() if err != nil || len(inputs) > 0 { return inputs, err @@ -202,12 +202,12 @@ func StaticBareInputForExperiment(name string) ([]string, error) { // staticInputForExperiment returns the static input for the given experiment // or an error if there's no static input for the experiment. -func staticInputForExperiment(name string) ([]model.URLInfo, error) { +func staticInputForExperiment(name string) ([]model.OOAPIURLInfo, error) { return stringListToModelURLInfo(StaticBareInputForExperiment(name)) } // loadOrStaticDefault implements the InputOrStaticDefault policy. -func (il *InputLoader) loadOrStaticDefault(ctx context.Context) ([]model.URLInfo, error) { +func (il *InputLoader) loadOrStaticDefault(ctx context.Context) ([]model.OOAPIURLInfo, error) { inputs, err := il.loadLocal() if err != nil || len(inputs) > 0 { return inputs, err @@ -216,10 +216,10 @@ func (il *InputLoader) loadOrStaticDefault(ctx context.Context) ([]model.URLInfo } // loadLocal loads inputs from StaticInputs and SourceFiles. -func (il *InputLoader) loadLocal() ([]model.URLInfo, error) { - inputs := []model.URLInfo{} +func (il *InputLoader) loadLocal() ([]model.OOAPIURLInfo, error) { + inputs := []model.OOAPIURLInfo{} for _, input := range il.StaticInputs { - inputs = append(inputs, model.URLInfo{URL: input}) + inputs = append(inputs, model.OOAPIURLInfo{URL: input}) } for _, filepath := range il.SourceFiles { extra, err := il.readfile(filepath, fsx.OpenFile) @@ -240,8 +240,8 @@ type inputLoaderOpenFn func(filepath string) (fs.File, error) // readfile reads inputs from the specified file. The open argument should be // compatible with stdlib's fs.Open and helps us with unit testing. -func (il *InputLoader) readfile(filepath string, open inputLoaderOpenFn) ([]model.URLInfo, error) { - inputs := []model.URLInfo{} +func (il *InputLoader) readfile(filepath string, open inputLoaderOpenFn) ([]model.OOAPIURLInfo, error) { + inputs := []model.OOAPIURLInfo{} filep, err := open(filepath) if err != nil { return nil, err @@ -254,7 +254,7 @@ func (il *InputLoader) readfile(filepath string, open inputLoaderOpenFn) ([]mode for scanner.Scan() { line := scanner.Text() if line != "" { - inputs = append(inputs, model.URLInfo{URL: line}) + inputs = append(inputs, model.OOAPIURLInfo{URL: line}) } } if scanner.Err() != nil { @@ -264,14 +264,14 @@ func (il *InputLoader) readfile(filepath string, open inputLoaderOpenFn) ([]mode } // loadRemote loads inputs from a remote source. -func (il *InputLoader) loadRemote(ctx context.Context) ([]model.URLInfo, error) { +func (il *InputLoader) loadRemote(ctx context.Context) ([]model.OOAPIURLInfo, error) { config := il.CheckInConfig if config == nil { // Note: Session.CheckIn documentation says it will fill in // any field with a required value with a reasonable default // if such value is missing. So, here we just need to be // concerned about NOT passing it a NULL pointer. - config = &model.CheckInConfig{} + config = &model.OOAPICheckInConfig{} } reply, err := il.checkIn(ctx, config) if err != nil { @@ -287,7 +287,7 @@ func (il *InputLoader) loadRemote(ctx context.Context) ([]model.URLInfo, error) // the URLs that are not part of the requested categories. This is done for // robustness, just in case we or the API do something wrong. func (il *InputLoader) checkIn( - ctx context.Context, config *model.CheckInConfig) (*model.CheckInInfo, error) { + ctx context.Context, config *model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) { reply, err := il.Session.CheckIn(ctx, config) if err != nil { return nil, err @@ -304,7 +304,7 @@ func (il *InputLoader) checkIn( // preventMistakes makes the code more robust with respect to any possible // integration issue where the backend returns to us URLs that don't // belong to the category codes we requested. -func (il *InputLoader) preventMistakes(input []model.URLInfo, categories []string) (output []model.URLInfo) { +func (il *InputLoader) preventMistakes(input []model.OOAPIURLInfo, categories []string) (output []model.OOAPIURLInfo) { if len(categories) <= 0 { return input } @@ -338,16 +338,16 @@ func (il *InputLoader) logger() InputLoaderLogger { // which would have been returned by an hypothetical backend // API serving input for a test for which we don't have an API // yet (e.g., stunreachability and dnscheck). -func stringListToModelURLInfo(input []string, err error) ([]model.URLInfo, error) { +func stringListToModelURLInfo(input []string, err error) ([]model.OOAPIURLInfo, error) { if err != nil { return nil, err } - var output []model.URLInfo + var output []model.OOAPIURLInfo for _, URL := range input { if _, err := url.Parse(URL); err != nil { return nil, err } - output = append(output, model.URLInfo{ + output = append(output, model.OOAPIURLInfo{ CategoryCode: "MISC", // hard to find a category CountryCode: "XX", // representing no country URL: URL, diff --git a/internal/engine/inputloader_network_test.go b/internal/engine/inputloader_network_test.go index 5fba6e4..5e82aa5 100644 --- a/internal/engine/inputloader_network_test.go +++ b/internal/engine/inputloader_network_test.go @@ -6,8 +6,8 @@ import ( "github.com/apex/log" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestInputLoaderInputOrQueryBackendWithNoInput(t *testing.T) { @@ -15,7 +15,7 @@ func TestInputLoaderInputOrQueryBackendWithNoInput(t *testing.T) { t.Skip("skip test in short mode") } sess, err := engine.NewSession(context.Background(), engine.SessionConfig{ - AvailableProbeServices: []model.Service{{ + AvailableProbeServices: []model.OOAPIService{{ Address: "https://ams-pg-test.ooni.org/", Type: "https", }}, diff --git a/internal/engine/inputloader_test.go b/internal/engine/inputloader_test.go index b74d4ca..bd0c6ce 100644 --- a/internal/engine/inputloader_test.go +++ b/internal/engine/inputloader_test.go @@ -12,8 +12,8 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestInputLoaderInputNoneWithStaticInputs(t *testing.T) { @@ -113,7 +113,7 @@ func TestInputLoaderInputOptionalWithInput(t *testing.T) { if len(out) != 5 { t.Fatal("not the output length we expected") } - expect := []model.URLInfo{ + expect := []model.OOAPIURLInfo{ {URL: "https://www.google.com/"}, {URL: "https://www.x.org/"}, {URL: "https://www.slashdot.org/"}, @@ -162,7 +162,7 @@ func TestInputLoaderInputStrictlyRequiredWithInput(t *testing.T) { if len(out) != 5 { t.Fatal("not the output length we expected") } - expect := []model.URLInfo{ + expect := []model.OOAPIURLInfo{ {URL: "https://www.google.com/"}, {URL: "https://www.x.org/"}, {URL: "https://www.slashdot.org/"}, @@ -225,7 +225,7 @@ func TestInputLoaderInputOrStaticDefaultWithInput(t *testing.T) { if len(out) != 5 { t.Fatal("not the output length we expected") } - expect := []model.URLInfo{ + expect := []model.OOAPIURLInfo{ {URL: "https://www.google.com/"}, {URL: "https://www.x.org/"}, {URL: "https://www.slashdot.org/"}, @@ -352,7 +352,7 @@ func TestInputLoaderInputOrQueryBackendWithInput(t *testing.T) { if len(out) != 5 { t.Fatal("not the output length we expected") } - expect := []model.URLInfo{ + expect := []model.OOAPIURLInfo{ {URL: "https://www.google.com/"}, {URL: "https://www.x.org/"}, {URL: "https://www.slashdot.org/"}, @@ -446,7 +446,7 @@ func TestInputLoaderReadfileScannerFailure(t *testing.T) { type InputLoaderMockableSession struct { // Output contains the output of CheckIn. It should // be nil when Error is not-nil. - Output *model.CheckInInfo + Output *model.OOAPICheckInInfo // Error is the error to be returned by CheckIn. It // should be nil when Output is not-nil. @@ -455,7 +455,7 @@ type InputLoaderMockableSession struct { // CheckIn implements InputLoaderSession.CheckIn. func (sess *InputLoaderMockableSession) CheckIn( - ctx context.Context, config *model.CheckInConfig) (*model.CheckInInfo, error) { + ctx context.Context, config *model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) { if sess.Output == nil && sess.Error == nil { return nil, errors.New("both Output and Error are nil") } @@ -480,7 +480,7 @@ func TestInputLoaderCheckInFailure(t *testing.T) { func TestInputLoaderCheckInSuccessWithNilWebConnectivity(t *testing.T) { il := &InputLoader{ Session: &InputLoaderMockableSession{ - Output: &model.CheckInInfo{}, + Output: &model.OOAPICheckInInfo{}, }, } out, err := il.loadRemote(context.Background()) @@ -495,8 +495,8 @@ func TestInputLoaderCheckInSuccessWithNilWebConnectivity(t *testing.T) { func TestInputLoaderCheckInSuccessWithNoURLs(t *testing.T) { il := &InputLoader{ Session: &InputLoaderMockableSession{ - Output: &model.CheckInInfo{ - WebConnectivity: &model.CheckInInfoWebConnectivity{}, + Output: &model.OOAPICheckInInfo{ + WebConnectivity: &model.OOAPICheckInInfoWebConnectivity{}, }, }, } @@ -510,7 +510,7 @@ func TestInputLoaderCheckInSuccessWithNoURLs(t *testing.T) { } func TestInputLoaderCheckInSuccessWithSomeURLs(t *testing.T) { - expect := []model.URLInfo{{ + expect := []model.OOAPIURLInfo{{ CategoryCode: "NEWS", CountryCode: "IT", URL: "https://repubblica.it", @@ -521,8 +521,8 @@ func TestInputLoaderCheckInSuccessWithSomeURLs(t *testing.T) { }} il := &InputLoader{ Session: &InputLoaderMockableSession{ - Output: &model.CheckInInfo{ - WebConnectivity: &model.CheckInInfoWebConnectivity{ + Output: &model.OOAPICheckInInfo{ + WebConnectivity: &model.OOAPICheckInInfoWebConnectivity{ URLs: expect, }, }, @@ -538,7 +538,7 @@ func TestInputLoaderCheckInSuccessWithSomeURLs(t *testing.T) { } func TestPreventMistakesWithCategories(t *testing.T) { - input := []model.URLInfo{{ + input := []model.OOAPIURLInfo{{ CategoryCode: "NEWS", URL: "https://repubblica.it/", CountryCode: "IT", @@ -551,7 +551,7 @@ func TestPreventMistakesWithCategories(t *testing.T) { URL: "https://addons.mozilla.org/", CountryCode: "XX", }} - desired := []model.URLInfo{{ + desired := []model.OOAPIURLInfo{{ CategoryCode: "NEWS", URL: "https://repubblica.it/", CountryCode: "IT", @@ -568,7 +568,7 @@ func TestPreventMistakesWithCategories(t *testing.T) { } func TestPreventMistakesWithoutCategoriesAndNil(t *testing.T) { - input := []model.URLInfo{{ + input := []model.OOAPIURLInfo{{ CategoryCode: "NEWS", URL: "https://repubblica.it/", CountryCode: "IT", @@ -589,7 +589,7 @@ func TestPreventMistakesWithoutCategoriesAndNil(t *testing.T) { } func TestPreventMistakesWithoutCategoriesAndEmpty(t *testing.T) { - input := []model.URLInfo{{ + input := []model.OOAPIURLInfo{{ CategoryCode: "NEWS", URL: "https://repubblica.it/", CountryCode: "IT", diff --git a/internal/engine/inputprocessor.go b/internal/engine/inputprocessor.go index b9e5651..ed33b3e 100644 --- a/internal/engine/inputprocessor.go +++ b/internal/engine/inputprocessor.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // InputProcessorExperiment is the Experiment @@ -49,7 +49,7 @@ type InputProcessor struct { Experiment InputProcessorExperimentWrapper // Inputs is the list of inputs to measure. - Inputs []model.URLInfo + Inputs []model.OOAPIURLInfo // MaxRuntime is the optional maximum runtime // when looping over a list of inputs (e.g. when diff --git a/internal/engine/inputprocessor_test.go b/internal/engine/inputprocessor_test.go index 3a2677f..ec1912a 100644 --- a/internal/engine/inputprocessor_test.go +++ b/internal/engine/inputprocessor_test.go @@ -6,7 +6,7 @@ import ( "testing" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type FakeInputProcessorExperiment struct { @@ -44,7 +44,7 @@ func TestInputProcessorMeasurementFailed(t *testing.T) { Experiment: NewInputProcessorExperimentWrapper( &FakeInputProcessorExperiment{Err: expected}, ), - Inputs: []model.URLInfo{{ + Inputs: []model.OOAPIURLInfo{{ URL: "https://www.kernel.org/", }}, } @@ -73,7 +73,7 @@ func TestInputProcessorSubmissionFailed(t *testing.T) { "foo": "bar", }, Experiment: NewInputProcessorExperimentWrapper(fipe), - Inputs: []model.URLInfo{{ + Inputs: []model.OOAPIURLInfo{{ URL: "https://www.kernel.org/", }}, Options: []string{"fake=true"}, @@ -122,7 +122,7 @@ func TestInputProcessorSaveOnDiskFailed(t *testing.T) { Experiment: NewInputProcessorExperimentWrapper( &FakeInputProcessorExperiment{}, ), - Inputs: []model.URLInfo{{ + Inputs: []model.OOAPIURLInfo{{ URL: "https://www.kernel.org/", }}, Options: []string{"fake=true"}, @@ -145,7 +145,7 @@ func TestInputProcessorGood(t *testing.T) { submitter := &FakeInputProcessorSubmitter{Err: nil} ip := &InputProcessor{ Experiment: NewInputProcessorExperimentWrapper(fipe), - Inputs: []model.URLInfo{{ + Inputs: []model.OOAPIURLInfo{{ URL: "https://www.kernel.org/", }, { URL: "https://www.slashdot.org/", @@ -187,7 +187,7 @@ func TestInputProcessorMaxRuntime(t *testing.T) { submitter := &FakeInputProcessorSubmitter{Err: nil} ip := &InputProcessor{ Experiment: NewInputProcessorExperimentWrapper(fipe), - Inputs: []model.URLInfo{{ + Inputs: []model.OOAPIURLInfo{{ URL: "https://www.kernel.org/", }, { URL: "https://www.slashdot.org/", diff --git a/internal/engine/internal/sessionresolver/dependencies.go b/internal/engine/internal/sessionresolver/dependencies.go deleted file mode 100644 index 1dd1515..0000000 --- a/internal/engine/internal/sessionresolver/dependencies.go +++ /dev/null @@ -1,32 +0,0 @@ -package sessionresolver - -// KVStore is a generic key-value store. We use it to store -// on disk persistent state used by this package. -type KVStore interface { - // Get gets the value for the given key. - Get(key string) ([]byte, error) - - // Set sets the value of the given key. - Set(key string, value []byte) error -} - -// Logger defines the common logger interface. -type Logger interface { - // Debug emits a debug message. - Debug(msg string) - - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Info emits an informational message. - Info(msg string) - - // Infof format and emits an informational message. - Infof(format string, v ...interface{}) - - // Warn emits a warning message. - Warn(msg string) - - // Warnf formats and emits a warning message. - Warnf(format string, v ...interface{}) -} diff --git a/internal/engine/internal/sessionresolver/resolvermaker.go b/internal/engine/internal/sessionresolver/resolvermaker.go index bb15318..1e97d73 100644 --- a/internal/engine/internal/sessionresolver/resolvermaker.go +++ b/internal/engine/internal/sessionresolver/resolvermaker.go @@ -8,6 +8,7 @@ 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/model" ) // resolvemaker contains rules for making a resolver. @@ -67,7 +68,7 @@ func (r *Resolver) byteCounter() *bytecounter.Counter { } // logger returns the configured logger or a default -func (r *Resolver) logger() Logger { +func (r *Resolver) logger() model.Logger { if r.Logger != nil { return r.Logger } diff --git a/internal/engine/internal/sessionresolver/sessionresolver.go b/internal/engine/internal/sessionresolver/sessionresolver.go index 1108fbe..48f930f 100644 --- a/internal/engine/internal/sessionresolver/sessionresolver.go +++ b/internal/engine/internal/sessionresolver/sessionresolver.go @@ -34,6 +34,7 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/bytecounter" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/multierror" "github.com/ooni/probe-cli/v3/internal/runtimex" ) @@ -63,11 +64,11 @@ type Resolver struct { // KVStore is the MANDATORY key-value store where you // want us to write statistics about which resolver is // working better in your network. - KVStore KVStore + KVStore model.KeyValueStore // Logger is the optional logger you want us to use // to emit log messages. - Logger Logger + Logger model.Logger // ProxyURL is the optional URL of the socks5 proxy // we should be using. If not set, then we WON'T use diff --git a/internal/engine/kvstore.go b/internal/engine/kvstore.go deleted file mode 100644 index c744de6..0000000 --- a/internal/engine/kvstore.go +++ /dev/null @@ -1,9 +0,0 @@ -package engine - -// KVStore is a simple, atomic key-value store. The user of -// probe-engine should supply an implementation of this interface, -// which will be used by probe-engine to store specific data. -type KVStore interface { - Get(key string) (value []byte, err error) - Set(key string, value []byte) (err error) -} diff --git a/internal/engine/legacy/errorsx/dialer_test.go b/internal/engine/legacy/errorsx/dialer_test.go index 2239862..48806d9 100644 --- a/internal/engine/legacy/errorsx/dialer_test.go +++ b/internal/engine/legacy/errorsx/dialer_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestErrorWrapperDialerFailure(t *testing.T) { diff --git a/internal/engine/legacy/errorsx/quic.go b/internal/engine/legacy/errorsx/quic.go index cf88d70..b1e5eb7 100644 --- a/internal/engine/legacy/errorsx/quic.go +++ b/internal/engine/legacy/errorsx/quic.go @@ -6,8 +6,8 @@ import ( "net" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" ) // QUICContextDialer is a dialer for QUIC using Context. @@ -22,7 +22,7 @@ type QUICContextDialer interface { // QUICListener listens for QUIC connections. type QUICListener interface { // Listen creates a new listening UDPConn. - Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, error) + Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) } // ErrorWrapperQUICListener is a QUICListener that wraps errors. @@ -34,7 +34,7 @@ type ErrorWrapperQUICListener struct { var _ QUICListener = &ErrorWrapperQUICListener{} // Listen implements QUICListener.Listen. -func (qls *ErrorWrapperQUICListener) Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { +func (qls *ErrorWrapperQUICListener) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { pconn, err := qls.QUICListener.Listen(addr) if err != nil { return nil, SafeErrWrapperBuilder{ @@ -45,15 +45,15 @@ func (qls *ErrorWrapperQUICListener) Listen(addr *net.UDPAddr) (quicx.UDPLikeCon return &errorWrapperUDPConn{pconn}, nil } -// errorWrapperUDPConn is a quicx.UDPLikeConn that wraps errors. +// errorWrapperUDPConn is a model.UDPLikeConn that wraps errors. type errorWrapperUDPConn struct { // UDPLikeConn is the underlying conn. - quicx.UDPLikeConn + model.UDPLikeConn } -var _ quicx.UDPLikeConn = &errorWrapperUDPConn{} +var _ model.UDPLikeConn = &errorWrapperUDPConn{} -// WriteTo implements quicx.UDPLikeConn.WriteTo. +// WriteTo implements model.UDPLikeConn.WriteTo. func (c *errorWrapperUDPConn) WriteTo(p []byte, addr net.Addr) (int, error) { count, err := c.UDPLikeConn.WriteTo(p, addr) if err != nil { @@ -65,7 +65,7 @@ func (c *errorWrapperUDPConn) WriteTo(p []byte, addr net.Addr) (int, error) { return count, nil } -// ReadFrom implements quicx.UDPLikeConn.ReadFrom. +// ReadFrom implements model.UDPLikeConn.ReadFrom. func (c *errorWrapperUDPConn) ReadFrom(b []byte) (int, net.Addr, error) { n, addr, err := c.UDPLikeConn.ReadFrom(b) if err != nil { diff --git a/internal/engine/legacy/errorsx/quic_test.go b/internal/engine/legacy/errorsx/quic_test.go index cc88822..d77379c 100644 --- a/internal/engine/legacy/errorsx/quic_test.go +++ b/internal/engine/legacy/errorsx/quic_test.go @@ -9,15 +9,16 @@ import ( "testing" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" + "github.com/ooni/probe-cli/v3/internal/model/mocks" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + nlmocks "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" ) func TestErrorWrapperQUICListenerSuccess(t *testing.T) { ql := &ErrorWrapperQUICListener{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return &net.UDPConn{}, nil }, }, @@ -32,7 +33,7 @@ func TestErrorWrapperQUICListenerSuccess(t *testing.T) { func TestErrorWrapperQUICListenerFailure(t *testing.T) { ql := &ErrorWrapperQUICListener{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return nil, io.EOF }, }, @@ -130,7 +131,7 @@ func TestErrorWrapperUDPConnReadFromFailure(t *testing.T) { func TestErrorWrapperQUICDialerFailure(t *testing.T) { ctx := context.Background() - d := &ErrorWrapperQUICDialer{Dialer: &mocks.QUICContextDialer{ + d := &ErrorWrapperQUICDialer{Dialer: &nlmocks.QUICContextDialer{ MockDialContext: func(ctx context.Context, network, address string, tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlySession, error) { return nil, io.EOF }, diff --git a/internal/engine/legacy/errorsx/resolver_test.go b/internal/engine/legacy/errorsx/resolver_test.go index 704508b..2e423d2 100644 --- a/internal/engine/legacy/errorsx/resolver_test.go +++ b/internal/engine/legacy/errorsx/resolver_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestErrorWrapperResolverSuccess(t *testing.T) { diff --git a/internal/engine/legacy/errorsx/tls_test.go b/internal/engine/legacy/errorsx/tls_test.go index fcc4e1d..2fc8007 100644 --- a/internal/engine/legacy/errorsx/tls_test.go +++ b/internal/engine/legacy/errorsx/tls_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestErrorWrapperTLSHandshakerFailure(t *testing.T) { diff --git a/internal/engine/legacy/netx/emitterdialer_test.go b/internal/engine/legacy/netx/emitterdialer_test.go index 155d632..d0576d2 100644 --- a/internal/engine/legacy/netx/emitterdialer_test.go +++ b/internal/engine/legacy/netx/emitterdialer_test.go @@ -10,7 +10,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/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestEmitterFailure(t *testing.T) { diff --git a/internal/engine/legacy/netxlogger/netxlogger.go b/internal/engine/legacy/netxlogger/netxlogger.go index 29b4c47..083fb6a 100644 --- a/internal/engine/legacy/netxlogger/netxlogger.go +++ b/internal/engine/legacy/netxlogger/netxlogger.go @@ -9,22 +9,17 @@ import ( "strings" "github.com/ooni/probe-cli/v3/internal/engine/legacy/netx/modelx" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) -// Logger is the interface we expect from a logger -type Logger interface { - Debug(msg string) - Debugf(format string, v ...interface{}) -} - // Handler is a handler that logs events. type Handler struct { - logger Logger + logger model.DebugLogger } // NewHandler returns a new logging handler. -func NewHandler(logger Logger) *Handler { +func NewHandler(logger model.DebugLogger) *Handler { return &Handler{logger: logger} } diff --git a/internal/engine/legacy/oonidatamodel/oonidatamodel.go b/internal/engine/legacy/oonidatamodel/oonidatamodel.go index ca6bd3b..0ae7e0d 100644 --- a/internal/engine/legacy/oonidatamodel/oonidatamodel.go +++ b/internal/engine/legacy/oonidatamodel/oonidatamodel.go @@ -18,7 +18,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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/mockable/mockable.go b/internal/engine/mockable/mockable.go index f63f50d..690a7c9 100644 --- a/internal/engine/mockable/mockable.go +++ b/internal/engine/mockable/mockable.go @@ -6,14 +6,14 @@ import ( "net/http" "net/url" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/engine/probeservices" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" ) // Session allows to mock sessions. type Session struct { - MockableTestHelpers map[string][]model.Service + MockableTestHelpers map[string][]model.OOAPIService MockableHTTPClient *http.Client MockableLogger model.Logger MockableMaybeResolverIP string @@ -24,9 +24,9 @@ type Session struct { MockableProxyURL *url.URL MockableFetchPsiphonConfigResult []byte MockableFetchPsiphonConfigErr error - MockableFetchTorTargetsResult map[string]model.TorTarget + MockableFetchTorTargetsResult map[string]model.OOAPITorTarget MockableFetchTorTargetsErr error - MockableFetchURLListResult []model.URLInfo + MockableFetchURLListResult []model.OOAPIURLInfo MockableFetchURLListErr error MockableResolverIP string MockableSoftwareName string @@ -38,7 +38,7 @@ type Session struct { } // GetTestHelpersByName implements ExperimentSession.GetTestHelpersByName -func (sess *Session) GetTestHelpersByName(name string) ([]model.Service, bool) { +func (sess *Session) GetTestHelpersByName(name string) ([]model.OOAPIService, bool) { services, okay := sess.MockableTestHelpers[name] return services, okay } @@ -55,13 +55,13 @@ func (sess *Session) FetchPsiphonConfig(ctx context.Context) ([]byte, error) { // FetchTorTargets implements ExperimentSession.TorTargets func (sess *Session) FetchTorTargets( - ctx context.Context, cc string) (map[string]model.TorTarget, error) { + ctx context.Context, cc string) (map[string]model.OOAPITorTarget, error) { return sess.MockableFetchTorTargetsResult, sess.MockableFetchTorTargetsErr } // FetchURLList implements ExperimentSession.FetchURLList. func (sess *Session) FetchURLList( - ctx context.Context, config model.URLListConfig) ([]model.URLInfo, error) { + ctx context.Context, config model.OOAPIURLListConfig) ([]model.OOAPIURLInfo, error) { return sess.MockableFetchURLListResult, sess.MockableFetchURLListErr } diff --git a/internal/engine/model/README.md b/internal/engine/model/README.md deleted file mode 100644 index a3cf1c1..0000000 --- a/internal/engine/model/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Package github.com/ooni/probe-engine/model - -Shared data structures and interfaces. diff --git a/internal/engine/model/checkinconfig.go b/internal/engine/model/checkinconfig.go deleted file mode 100644 index 1bdd646..0000000 --- a/internal/engine/model/checkinconfig.go +++ /dev/null @@ -1,19 +0,0 @@ -package model - -// CheckInConfigWebConnectivity is the configuration for the WebConnectivity test -type CheckInConfigWebConnectivity struct { - CategoryCodes []string `json:"category_codes"` // CategoryCodes is an array of category codes -} - -// CheckInConfig contains configuration for calling the checkin API. -type CheckInConfig struct { - Charging bool `json:"charging"` // Charging indicate if the phone is actually charging - OnWiFi bool `json:"on_wifi"` // OnWiFi indicate if the phone is actually connected to a WiFi network - Platform string `json:"platform"` // Platform of the probe - ProbeASN string `json:"probe_asn"` // ProbeASN is the probe country code - ProbeCC string `json:"probe_cc"` // ProbeCC is the probe country code - RunType string `json:"run_type"` // RunType - SoftwareName string `json:"software_name"` // SoftwareName of the probe - SoftwareVersion string `json:"software_version"` // SoftwareVersion of the probe - WebConnectivity CheckInConfigWebConnectivity `json:"web_connectivity"` // WebConnectivity class contain an array of categories -} diff --git a/internal/engine/model/checkininfo.go b/internal/engine/model/checkininfo.go deleted file mode 100644 index 211e45e..0000000 --- a/internal/engine/model/checkininfo.go +++ /dev/null @@ -1,12 +0,0 @@ -package model - -// CheckInInfoWebConnectivity contains the array of URLs returned by the checkin API -type CheckInInfoWebConnectivity struct { - ReportID string `json:"report_id"` - URLs []URLInfo `json:"urls"` -} - -// CheckInInfo contains the return test objects from the checkin API -type CheckInInfo struct { - WebConnectivity *CheckInInfoWebConnectivity `json:"web_connectivity"` -} diff --git a/internal/engine/model/keyvaluestore.go b/internal/engine/model/keyvaluestore.go deleted file mode 100644 index f10df93..0000000 --- a/internal/engine/model/keyvaluestore.go +++ /dev/null @@ -1,7 +0,0 @@ -package model - -// KeyValueStore is a key-value store used by the session. -type KeyValueStore interface { - Get(key string) (value []byte, err error) - Set(key string, value []byte) (err error) -} diff --git a/internal/engine/model/model.go b/internal/engine/model/model.go deleted file mode 100644 index ef72d88..0000000 --- a/internal/engine/model/model.go +++ /dev/null @@ -1,9 +0,0 @@ -// Package model defines shared data structures and interfaces. -package model - -import "github.com/ooni/probe-cli/v3/internal/engine/geolocate" - -const ( - // DefaultProbeIP is the default probe IP. - DefaultProbeIP = geolocate.DefaultProbeIP -) diff --git a/internal/engine/model/scrub.go b/internal/engine/model/scrub.go deleted file mode 100644 index da754d2..0000000 --- a/internal/engine/model/scrub.go +++ /dev/null @@ -1,49 +0,0 @@ -package model - -import ( - "bytes" - "encoding/json" - "errors" - "net" -) - -// ErrInvalidProbeIP indicates that we're dealing with a string that -// is not the valid serialization of an IP address. -var ErrInvalidProbeIP = errors.New("model: invalid probe IP") - -// Scrub scrubs the probeIP out of the measurement. -func (m *Measurement) Scrub(probeIP string) (err error) { - // We now behave like we can share everything except the - // probe IP, which we instead cannot ever share - m.ProbeIP = DefaultProbeIP - return m.MaybeRewriteTestKeys(probeIP, json.Marshal) -} - -// Scrubbed is the string that replaces IP addresses. -const Scrubbed = `[scrubbed]` - -// MaybeRewriteTestKeys is the function called by Scrub that -// ensures that m's serialization doesn't include the IP -func (m *Measurement) MaybeRewriteTestKeys( - currentIP string, marshal func(interface{}) ([]byte, error)) error { - if net.ParseIP(currentIP) == nil { - return ErrInvalidProbeIP - } - data, err := marshal(m.TestKeys) - if err != nil { - return err - } - // The check using Count is to save an unnecessary copy performed by - // ReplaceAll when there are no matches into the body. This is what - // we would like the common case to be, meaning that the code has done - // its job correctly and has not leaked the IP. - bpip := []byte(currentIP) - if bytes.Count(data, bpip) <= 0 { - return nil - } - data = bytes.ReplaceAll(data, bpip, []byte(Scrubbed)) - // We add an annotation such that hopefully later we can measure the - // number of cases where we failed to sanitize properly. - m.AddAnnotation("_probe_engine_sanitize_test_keys", "true") - return json.Unmarshal(data, &m.TestKeys) -} diff --git a/internal/engine/model/service.go b/internal/engine/model/service.go deleted file mode 100644 index 19fb186..0000000 --- a/internal/engine/model/service.go +++ /dev/null @@ -1,17 +0,0 @@ -package model - -// Service describes a backend service. -// -// The fields of this struct have the meaning described in v2.0.0 of the OONI -// bouncer specification defined by -// https://github.com/ooni/spec/blob/master/backends/bk-004-bouncer.md. -type Service struct { - // Address is the address of the server. - Address string `json:"address"` - - // Type is the type of the service. - Type string `json:"type"` - - // Front is the front to use with "cloudfront" type entries. - Front string `json:"front,omitempty"` -} diff --git a/internal/engine/model/tortarget.go b/internal/engine/model/tortarget.go deleted file mode 100644 index d64460e..0000000 --- a/internal/engine/model/tortarget.go +++ /dev/null @@ -1,21 +0,0 @@ -package model - -// TorTarget is a target for the tor experiment. -type TorTarget struct { - // Address is the address of the target. - Address string `json:"address"` - - // Name is the name of the target. - Name string `json:"name"` - - // Params contains optional params for, e.g., pluggable transports. - Params map[string][]string `json:"params"` - - // Protocol is the protocol to use with the target. - Protocol string `json:"protocol"` - - // Source is the source from which we fetched this specific - // target. Whenever the source is non-empty, we will treat - // this specific target as a private target. - Source string `json:"source"` -} diff --git a/internal/engine/model/urlinfo.go b/internal/engine/model/urlinfo.go deleted file mode 100644 index 79ec721..0000000 --- a/internal/engine/model/urlinfo.go +++ /dev/null @@ -1,8 +0,0 @@ -package model - -// URLInfo contains info on a test lists URL -type URLInfo struct { - CategoryCode string `json:"category_code"` - CountryCode string `json:"country_code"` - URL string `json:"url"` -} diff --git a/internal/engine/model/urllistconfig.go b/internal/engine/model/urllistconfig.go deleted file mode 100644 index f85c018..0000000 --- a/internal/engine/model/urllistconfig.go +++ /dev/null @@ -1,8 +0,0 @@ -package model - -// URLListConfig contains configuration for fetching the URL list. -type URLListConfig struct { - Categories []string // Categories to query for (empty means all) - CountryCode string // CountryCode is the optional country code - Limit int64 // Max number of URLs (<= 0 means no limit) -} diff --git a/internal/engine/netx/archival/archival.go b/internal/engine/netx/archival/archival.go index 576e31b..f930768 100644 --- a/internal/engine/netx/archival/archival.go +++ b/internal/engine/netx/archival/archival.go @@ -18,8 +18,8 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/geolocate" errorsxlegacy "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/netx/archival/archival_test.go b/internal/engine/netx/archival/archival_test.go index f531e4d..058da72 100644 --- a/internal/engine/netx/archival/archival_test.go +++ b/internal/engine/netx/archival/archival_test.go @@ -12,9 +12,9 @@ import ( "github.com/google/go-cmp/cmp" "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/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/netx/dialer/bytecounter_test.go b/internal/engine/netx/dialer/bytecounter_test.go index 2df3e07..7daffb9 100644 --- a/internal/engine/netx/dialer/bytecounter_test.go +++ b/internal/engine/netx/dialer/bytecounter_test.go @@ -10,7 +10,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/bytecounter" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func dorequest(ctx context.Context, url string) error { diff --git a/internal/engine/netx/dialer/dialer.go b/internal/engine/netx/dialer/dialer.go index 8e2976b..572dc0d 100644 --- a/internal/engine/netx/dialer/dialer.go +++ b/internal/engine/netx/dialer/dialer.go @@ -7,6 +7,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/legacy/errorsx" "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -22,15 +23,6 @@ type Resolver interface { LookupHost(ctx context.Context, hostname string) (addrs []string, err error) } -// Logger is the interface we expect from a logger. -type Logger interface { - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Debug emits a debug message. - Debug(msg string) -} - // Config contains the settings for New. type Config struct { // ContextByteCounting optionally configures context-based @@ -58,7 +50,7 @@ type Config struct { // Logger is the optional logger. If not set, there // will be no logging from the new dialer. - Logger Logger + Logger model.DebugLogger // ProxyURL is the optional proxy URL. ProxyURL *url.URL @@ -73,8 +65,8 @@ func New(config *Config, resolver Resolver) Dialer { d = &errorsx.ErrorWrapperDialer{Dialer: d} if config.Logger != nil { d = &netxlite.DialerLogger{ - Dialer: netxlite.NewDialerLegacyAdapter(d), - Logger: config.Logger, + Dialer: netxlite.NewDialerLegacyAdapter(d), + DebugLogger: config.Logger, } } if config.DialSaver != nil { diff --git a/internal/engine/netx/dialer/proxy_test.go b/internal/engine/netx/dialer/proxy_test.go index c67ff62..d4c82e5 100644 --- a/internal/engine/netx/dialer/proxy_test.go +++ b/internal/engine/netx/dialer/proxy_test.go @@ -8,7 +8,7 @@ import ( "net/url" "testing" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestProxyDialerDialContextNoProxyURL(t *testing.T) { diff --git a/internal/engine/netx/dialer/saver_test.go b/internal/engine/netx/dialer/saver_test.go index 167406d..2b72aff 100644 --- a/internal/engine/netx/dialer/saver_test.go +++ b/internal/engine/netx/dialer/saver_test.go @@ -10,7 +10,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestSaverDialerFailure(t *testing.T) { diff --git a/internal/engine/netx/netx.go b/internal/engine/netx/netx.go index d800f4e..f120a84 100644 --- a/internal/engine/netx/netx.go +++ b/internal/engine/netx/netx.go @@ -39,15 +39,10 @@ import ( "github.com/ooni/probe-cli/v3/internal/engine/netx/resolver" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) -// Logger is the logger assumed by this package -type Logger interface { - Debugf(format string, v ...interface{}) - Debug(message string) -} - // Dialer is the definition of dialer assumed by this package. type Dialer interface { DialContext(ctx context.Context, network, address string) (net.Conn, error) @@ -95,7 +90,7 @@ type Config struct { QUICDialer QUICDialer // default: quicdialer.DNSDialer HTTP3Enabled bool // default: disabled HTTPSaver *trace.Saver // default: not saving HTTP - Logger Logger // default: no logging + Logger model.DebugLogger // default: no logging NoTLSVerify bool // default: perform TLS verify ProxyURL *url.URL // default: no proxy ReadWriteSaver *trace.Saver // default: not saving read/write @@ -196,7 +191,7 @@ func NewTLSDialer(config Config) TLSDialer { var h tlsHandshaker = &netxlite.TLSHandshakerConfigurable{} h = &errorsx.ErrorWrapperTLSHandshaker{TLSHandshaker: h} if config.Logger != nil { - h = &netxlite.TLSHandshakerLogger{Logger: config.Logger, TLSHandshaker: h} + h = &netxlite.TLSHandshakerLogger{DebugLogger: config.Logger, TLSHandshaker: h} } if config.TLSSaver != nil { h = tlsdialer.SaverTLSHandshaker{TLSHandshaker: h, Saver: config.TLSSaver} diff --git a/internal/engine/netx/netx_test.go b/internal/engine/netx/netx_test.go index 9f1c0bf..3ab0989 100644 --- a/internal/engine/netx/netx_test.go +++ b/internal/engine/netx/netx_test.go @@ -18,7 +18,7 @@ import ( "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/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestNewResolverVanilla(t *testing.T) { @@ -367,7 +367,7 @@ func TestNewTLSDialerWithLogging(t *testing.T) { if !ok { t.Fatal("not the TLSHandshaker we expected") } - if lth.Logger != log.Log { + if lth.DebugLogger != log.Log { t.Fatal("not the Logger we expected") } ewth, ok := lth.TLSHandshaker.(*errorsx.ErrorWrapperTLSHandshaker) diff --git a/internal/engine/netx/quicdialer/system.go b/internal/engine/netx/quicdialer/system.go index 939cbe9..97d63dd 100644 --- a/internal/engine/netx/quicdialer/system.go +++ b/internal/engine/netx/quicdialer/system.go @@ -5,14 +5,14 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine/netx/trace" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" ) // QUICListener listens for QUIC connections. type QUICListener interface { // Listen creates a new listening UDPConn. - Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, error) + Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) } // QUICListenerSaver is a QUICListener that also implements saving events. @@ -25,7 +25,7 @@ type QUICListenerSaver struct { } // Listen implements QUICListener.Listen. -func (qls *QUICListenerSaver) Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { +func (qls *QUICListenerSaver) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { pconn, err := qls.QUICListener.Listen(addr) if err != nil { return nil, err @@ -37,11 +37,11 @@ func (qls *QUICListenerSaver) Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, erro } type saverUDPConn struct { - quicx.UDPLikeConn + model.UDPLikeConn saver *trace.Saver } -var _ quicx.UDPLikeConn = &saverUDPConn{} +var _ model.UDPLikeConn = &saverUDPConn{} func (c *saverUDPConn) WriteTo(p []byte, addr net.Addr) (int, error) { start := time.Now() diff --git a/internal/engine/netx/quicdialer/system_test.go b/internal/engine/netx/quicdialer/system_test.go index 0921628..9676def 100644 --- a/internal/engine/netx/quicdialer/system_test.go +++ b/internal/engine/netx/quicdialer/system_test.go @@ -10,17 +10,17 @@ import ( "github.com/lucas-clemente/quic-go" "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/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" "github.com/ooni/probe-cli/v3/internal/netxlite/quictesting" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" ) func TestQUICListenerSaverCannotListen(t *testing.T) { expected := errors.New("mocked error") qls := &quicdialer.QUICListenerSaver{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return nil, expected }, }, diff --git a/internal/engine/netx/resolver/emitter_test.go b/internal/engine/netx/resolver/emitter_test.go index a6bdd4c..84e8d26 100644 --- a/internal/engine/netx/resolver/emitter_test.go +++ b/internal/engine/netx/resolver/emitter_test.go @@ -13,7 +13,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/netx/resolver" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestEmitterTransportSuccess(t *testing.T) { diff --git a/internal/engine/netx/resolver/legacy.go b/internal/engine/netx/resolver/legacy.go index e73096a..bd47c0c 100644 --- a/internal/engine/netx/resolver/legacy.go +++ b/internal/engine/netx/resolver/legacy.go @@ -1,9 +1,12 @@ package resolver -import "github.com/ooni/probe-cli/v3/internal/netxlite" +import ( + "github.com/ooni/probe-cli/v3/internal/model" + "github.com/ooni/probe-cli/v3/internal/netxlite" +) // Variables that other packages expect to find here but have been -// moved into the internal/netxlite/dnsx package. +// moved into the internal/netxlite package. var ( NewSerialResolver = netxlite.NewSerialResolver NewDNSOverUDP = netxlite.NewDNSOverUDP @@ -14,15 +17,15 @@ var ( ) // Types that other packages expect to find here but have been -// moved into the internal/netxlite/dnsx package. +// moved into the internal/netxlite package. type ( DNSOverHTTPS = netxlite.DNSOverHTTPS DNSOverTCP = netxlite.DNSOverTCP DNSOverUDP = netxlite.DNSOverUDP MiekgEncoder = netxlite.DNSEncoderMiekg MiekgDecoder = netxlite.DNSDecoderMiekg - RoundTripper = netxlite.DNSTransport + RoundTripper = model.DNSTransport SerialResolver = netxlite.SerialResolver - Dialer = netxlite.Dialer + Dialer = model.Dialer DialContextFunc = netxlite.DialContextFunc ) diff --git a/internal/engine/netx/tlsdialer/integration_test.go b/internal/engine/netx/tlsdialer/integration_test.go index 7d7237d..6ab0d48 100644 --- a/internal/engine/netx/tlsdialer/integration_test.go +++ b/internal/engine/netx/tlsdialer/integration_test.go @@ -16,7 +16,7 @@ func TestTLSDialerSuccess(t *testing.T) { dialer := &netxlite.TLSDialerLegacy{Dialer: netxlite.DefaultDialer, TLSHandshaker: &netxlite.TLSHandshakerLogger{ TLSHandshaker: &netxlite.TLSHandshakerConfigurable{}, - Logger: log.Log, + DebugLogger: log.Log, }, } txp := &http.Transport{ diff --git a/internal/engine/netx/tlsdialer/logging.go b/internal/engine/netx/tlsdialer/logging.go deleted file mode 100644 index e55459d..0000000 --- a/internal/engine/netx/tlsdialer/logging.go +++ /dev/null @@ -1,7 +0,0 @@ -package tlsdialer - -// Logger is the logger assumed by this package -type Logger interface { - Debugf(format string, v ...interface{}) - Debug(message string) -} diff --git a/internal/engine/probeservices/benchselect.go b/internal/engine/probeservices/benchselect.go index 4f1a77d..c4be516 100644 --- a/internal/engine/probeservices/benchselect.go +++ b/internal/engine/probeservices/benchselect.go @@ -4,12 +4,12 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // Default returns the default probe services -func Default() []model.Service { - return []model.Service{{ +func Default() []model.OOAPIService { + return []model.OOAPIService{{ Address: "https://ps1.ooni.io", Type: "https", }, { @@ -23,7 +23,7 @@ func Default() []model.Service { } // SortEndpoints gives priority to https, then cloudfronted, then onion. -func SortEndpoints(in []model.Service) (out []model.Service) { +func SortEndpoints(in []model.OOAPIService) (out []model.OOAPIService) { for _, entry := range in { if entry.Type == "https" { out = append(out, entry) @@ -43,7 +43,7 @@ func SortEndpoints(in []model.Service) (out []model.Service) { } // OnlyHTTPS returns the HTTPS endpoints only. -func OnlyHTTPS(in []model.Service) (out []model.Service) { +func OnlyHTTPS(in []model.OOAPIService) (out []model.OOAPIService) { for _, entry := range in { if entry.Type == "https" { out = append(out, entry) @@ -53,7 +53,7 @@ func OnlyHTTPS(in []model.Service) (out []model.Service) { } // OnlyFallbacks returns the fallback endpoints only. -func OnlyFallbacks(in []model.Service) (out []model.Service) { +func OnlyFallbacks(in []model.OOAPIService) (out []model.OOAPIService) { for _, entry := range SortEndpoints(in) { if entry.Type != "https" { out = append(out, entry) @@ -71,10 +71,10 @@ type Candidate struct { Err error // Endpoint is the service endpoint. - Endpoint model.Service + Endpoint model.OOAPIService // TestHelpers contains the data returned by the endpoint. - TestHelpers map[string][]model.Service + TestHelpers map[string][]model.OOAPIService } func (c *Candidate) try(ctx context.Context, sess Session) { @@ -91,7 +91,7 @@ func (c *Candidate) try(ctx context.Context, sess Session) { sess.Logger().Debugf("probe services: %+v: %+v %s", c.Endpoint, err, c.Duration) } -func try(ctx context.Context, sess Session, svc model.Service) *Candidate { +func try(ctx context.Context, sess Session, svc model.OOAPIService) *Candidate { candidate := &Candidate{Endpoint: svc} candidate.try(ctx, sess) return candidate @@ -107,7 +107,7 @@ func try(ctx context.Context, sess Session, svc model.Service) *Candidate { // such case, you will see a list of N failing HTTPS candidates, followed by a single // successful fallback candidate (e.g. cloudfronted). If all candidates fail, you // see in output a list containing all entries where Err is not nil. -func TryAll(ctx context.Context, sess Session, in []model.Service) (out []*Candidate) { +func TryAll(ctx context.Context, sess Session, in []model.OOAPIService) (out []*Candidate) { var found bool for _, svc := range OnlyHTTPS(in) { candidate := try(ctx, sess, svc) diff --git a/internal/engine/probeservices/bouncer.go b/internal/engine/probeservices/bouncer.go index db66455..6c739cc 100644 --- a/internal/engine/probeservices/bouncer.go +++ b/internal/engine/probeservices/bouncer.go @@ -3,12 +3,12 @@ package probeservices import ( "context" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // GetTestHelpers is like GetCollectors but for test helpers. func (c Client) GetTestHelpers( - ctx context.Context) (output map[string][]model.Service, err error) { + ctx context.Context) (output map[string][]model.OOAPIService, err error) { err = c.Client.GetJSON(ctx, "/api/v1/test-helpers", &output) return } diff --git a/internal/engine/probeservices/checkin.go b/internal/engine/probeservices/checkin.go index 81be9ec..988e558 100644 --- a/internal/engine/probeservices/checkin.go +++ b/internal/engine/probeservices/checkin.go @@ -3,18 +3,18 @@ package probeservices import ( "context" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type checkInResult struct { - Tests model.CheckInInfo `json:"tests"` - V int `json:"v"` + Tests model.OOAPICheckInInfo `json:"tests"` + V int `json:"v"` } // CheckIn function is called by probes asking if there are tests to be run // The config argument contains the mandatory settings. // Returns the list of tests to run and the URLs, on success, or an explanatory error, in case of failure. -func (c Client) CheckIn(ctx context.Context, config model.CheckInConfig) (*model.CheckInInfo, error) { +func (c Client) CheckIn(ctx context.Context, config model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) { var response checkInResult if err := c.Client.PostJSON(ctx, "/api/v1/check-in", config, &response); err != nil { return nil, err diff --git a/internal/engine/probeservices/checkin_test.go b/internal/engine/probeservices/checkin_test.go index 427eb4f..b61214f 100644 --- a/internal/engine/probeservices/checkin_test.go +++ b/internal/engine/probeservices/checkin_test.go @@ -5,13 +5,13 @@ import ( "strings" "testing" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestCheckInSuccess(t *testing.T) { client := newclient() client.BaseURL = "https://ams-pg-test.ooni.org" - config := model.CheckInConfig{ + config := model.OOAPICheckInConfig{ Charging: true, OnWiFi: true, Platform: "android", @@ -20,7 +20,7 @@ func TestCheckInSuccess(t *testing.T) { RunType: "timed", SoftwareName: "ooniprobe-android", SoftwareVersion: "2.7.1", - WebConnectivity: model.CheckInConfigWebConnectivity{ + WebConnectivity: model.OOAPICheckInConfigWebConnectivity{ CategoryCodes: []string{"NEWS", "CULTR"}, }, } @@ -48,7 +48,7 @@ func TestCheckInSuccess(t *testing.T) { func TestCheckInFailure(t *testing.T) { client := newclient() client.BaseURL = "https://\t\t\t/" // cause test to fail - config := model.CheckInConfig{ + config := model.OOAPICheckInConfig{ Charging: true, OnWiFi: true, Platform: "android", @@ -57,7 +57,7 @@ func TestCheckInFailure(t *testing.T) { RunType: "timed", SoftwareName: "ooniprobe-android", SoftwareVersion: "2.7.1", - WebConnectivity: model.CheckInConfigWebConnectivity{ + WebConnectivity: model.OOAPICheckInConfigWebConnectivity{ CategoryCodes: []string{"NEWS", "CULTR"}, }, } diff --git a/internal/engine/probeservices/collector.go b/internal/engine/probeservices/collector.go index 35431ec..9af46d6 100644 --- a/internal/engine/probeservices/collector.go +++ b/internal/engine/probeservices/collector.go @@ -7,7 +7,7 @@ import ( "reflect" "sync" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) const ( diff --git a/internal/engine/probeservices/collector_test.go b/internal/engine/probeservices/collector_test.go index 71f6bfa..6decad1 100644 --- a/internal/engine/probeservices/collector_test.go +++ b/internal/engine/probeservices/collector_test.go @@ -13,8 +13,8 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/engine/probeservices" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) diff --git a/internal/engine/probeservices/probeservices.go b/internal/engine/probeservices/probeservices.go index a8b8a9e..1c8b029 100644 --- a/internal/engine/probeservices/probeservices.go +++ b/internal/engine/probeservices/probeservices.go @@ -30,7 +30,7 @@ import ( "github.com/ooni/probe-cli/v3/internal/atomicx" "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/model" ) var ( @@ -89,7 +89,7 @@ func (c Client) GetCredsAndAuth() (*LoginCredentials, *LoginAuth, error) { // NewClient creates a new client for the specified probe services endpoint. This // function fails, e.g., we don't support the specified endpoint. -func NewClient(sess Session, endpoint model.Service) (*Client, error) { +func NewClient(sess Session, endpoint model.OOAPIService) (*Client, error) { client := &Client{ Client: httpx.Client{ BaseURL: endpoint.Address, diff --git a/internal/engine/probeservices/probeservices_test.go b/internal/engine/probeservices/probeservices_test.go index 9551dfb..bd8c776 100644 --- a/internal/engine/probeservices/probeservices_test.go +++ b/internal/engine/probeservices/probeservices_test.go @@ -13,9 +13,9 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" "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/probeservices" "github.com/ooni/probe-cli/v3/internal/engine/probeservices/testorchestra" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -25,7 +25,7 @@ func newclient() *probeservices.Client { MockableHTTPClient: http.DefaultClient, MockableLogger: log.Log, }, - model.Service{ + model.OOAPIService{ Address: "https://ams-pg-test.ooni.org/", Type: "https", }, @@ -38,7 +38,7 @@ func newclient() *probeservices.Client { func TestNewClientHTTPS(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://x.org", Type: "https", }) @@ -52,7 +52,7 @@ func TestNewClientHTTPS(t *testing.T) { func TestNewClientUnsupportedEndpoint(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://x.org", Type: "onion", }) @@ -66,7 +66,7 @@ func TestNewClientUnsupportedEndpoint(t *testing.T) { func TestNewClientCloudfrontInvalidURL(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "\t\t\t", Type: "cloudfront", }) @@ -80,7 +80,7 @@ func TestNewClientCloudfrontInvalidURL(t *testing.T) { func TestNewClientCloudfrontInvalidURLScheme(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "http://x.org", Type: "cloudfront", }) @@ -94,7 +94,7 @@ func TestNewClientCloudfrontInvalidURLScheme(t *testing.T) { func TestNewClientCloudfrontInvalidURLWithPort(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://x.org:54321", Type: "cloudfront", }) @@ -108,7 +108,7 @@ func TestNewClientCloudfrontInvalidURLWithPort(t *testing.T) { func TestNewClientCloudfrontInvalidFront(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://x.org", Type: "cloudfront", Front: "\t\t\t", @@ -123,7 +123,7 @@ func TestNewClientCloudfrontInvalidFront(t *testing.T) { func TestNewClientCloudfrontGood(t *testing.T) { client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://x.org", Type: "cloudfront", Front: "google.com", @@ -144,7 +144,7 @@ func TestCloudfront(t *testing.T) { t.Skip("skip test in short mode") } client, err := probeservices.NewClient( - &mockable.Session{}, model.Service{ + &mockable.Session{}, model.OOAPIService{ Address: "https://meek.azureedge.net", Type: "cloudfront", Front: "ajax.aspnetcdn.com", @@ -197,7 +197,7 @@ func TestDefaultProbeServicesWorkAsIntended(t *testing.T) { } func TestSortEndpoints(t *testing.T) { - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -208,7 +208,7 @@ func TestSortEndpoints(t *testing.T) { Type: "https", Address: "https://ams-ps2.ooni.nu:443", }} - expect := []model.Service{{ + expect := []model.OOAPIService{{ Type: "https", Address: "https://ams-ps2.ooni.nu:443", }, { @@ -227,7 +227,7 @@ func TestSortEndpoints(t *testing.T) { } func TestOnlyHTTPS(t *testing.T) { - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -244,7 +244,7 @@ func TestOnlyHTTPS(t *testing.T) { Type: "https", Address: "https://mia-ps-nonexistent.ooni.io", }} - expect := []model.Service{{ + expect := []model.OOAPIService{{ Type: "https", Address: "https://ams-ps-nonexistent.ooni.io", }, { @@ -263,7 +263,7 @@ func TestOnlyHTTPS(t *testing.T) { func TestOnlyFallbacks(t *testing.T) { // put onion first so we also verify that we sort the endpoints - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -280,7 +280,7 @@ func TestOnlyFallbacks(t *testing.T) { Type: "https", Address: "https://mia-ps-nonexistent.ooni.io", }} - expect := []model.Service{{ + expect := []model.OOAPIService{{ Front: "dkyhjv0wpi2dk.cloudfront.net", Type: "cloudfront", Address: "https://dkyhjv0wpi2dk.cloudfront.net", @@ -297,7 +297,7 @@ func TestOnlyFallbacks(t *testing.T) { func TestTryAllCanceledContext(t *testing.T) { // put onion first so we also verify that we sort the endpoints - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -401,7 +401,7 @@ func TestTryAllIntegrationWeRaceForFastestHTTPS(t *testing.T) { } const pattern = "^https://ps[1-4].ooni.io$" // put onion first so we also verify that we sort the endpoints - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -472,7 +472,7 @@ func TestTryAllIntegrationWeFallback(t *testing.T) { t.Skip("skip test in short mode") } // put onion first so we also verify that we sort the endpoints - in := []model.Service{{ + in := []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }, { @@ -573,32 +573,32 @@ func TestSelectBestOnlyFailures(t *testing.T) { func TestSelectBestSelectsTheFastest(t *testing.T) { in := []*probeservices.Candidate{{ Duration: 10 * time.Millisecond, - Endpoint: model.Service{ + Endpoint: model.OOAPIService{ Address: "https://ps1.ooni.io", Type: "https", }, }, { Duration: 4 * time.Millisecond, - Endpoint: model.Service{ + Endpoint: model.OOAPIService{ Address: "https://ps2.ooni.io", Type: "https", }, }, { Duration: 7 * time.Millisecond, - Endpoint: model.Service{ + Endpoint: model.OOAPIService{ Address: "https://ps3.ooni.io", Type: "https", }, }, { Duration: 11 * time.Millisecond, - Endpoint: model.Service{ + Endpoint: model.OOAPIService{ Address: "https://ps4.ooni.io", Type: "https", }, }} expected := &probeservices.Candidate{ Duration: 4 * time.Millisecond, - Endpoint: model.Service{ + Endpoint: model.OOAPIService{ Address: "https://ps2.ooni.io", Type: "https", }, diff --git a/internal/engine/probeservices/statefile.go b/internal/engine/probeservices/statefile.go index a08939b..3e52af8 100644 --- a/internal/engine/probeservices/statefile.go +++ b/internal/engine/probeservices/statefile.go @@ -4,7 +4,7 @@ import ( "encoding/json" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // State is the state stored inside the state file diff --git a/internal/engine/probeservices/tor.go b/internal/engine/probeservices/tor.go index 3b480b2..33cae71 100644 --- a/internal/engine/probeservices/tor.go +++ b/internal/engine/probeservices/tor.go @@ -5,11 +5,11 @@ import ( "fmt" "net/url" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // FetchTorTargets returns the targets for the tor experiment. -func (c Client) FetchTorTargets(ctx context.Context, cc string) (result map[string]model.TorTarget, err error) { +func (c Client) FetchTorTargets(ctx context.Context, cc string) (result map[string]model.OOAPITorTarget, err error) { _, auth, err := c.GetCredsAndAuth() if err != nil { return nil, err diff --git a/internal/engine/probeservices/urls.go b/internal/engine/probeservices/urls.go index 7066b88..d99ec96 100644 --- a/internal/engine/probeservices/urls.go +++ b/internal/engine/probeservices/urls.go @@ -6,17 +6,17 @@ import ( "net/url" "strings" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type urlListResult struct { - Results []model.URLInfo `json:"results"` + Results []model.OOAPIURLInfo `json:"results"` } // FetchURLList fetches the list of URLs used by WebConnectivity. The config // argument contains the optional settings. Returns the list of URLs, on success, // or an explanatory error, in case of failure. -func (c Client) FetchURLList(ctx context.Context, config model.URLListConfig) ([]model.URLInfo, error) { +func (c Client) FetchURLList(ctx context.Context, config model.OOAPIURLListConfig) ([]model.OOAPIURLInfo, error) { query := url.Values{} if config.CountryCode != "" { query.Set("country_code", config.CountryCode) diff --git a/internal/engine/probeservices/urls_test.go b/internal/engine/probeservices/urls_test.go index 4ea12ff..53e6afc 100644 --- a/internal/engine/probeservices/urls_test.go +++ b/internal/engine/probeservices/urls_test.go @@ -5,7 +5,7 @@ import ( "strings" "testing" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestFetchURLListSuccess(t *testing.T) { @@ -14,7 +14,7 @@ func TestFetchURLListSuccess(t *testing.T) { } client := newclient() client.BaseURL = "https://ams-pg-test.ooni.org" - config := model.URLListConfig{ + config := model.OOAPIURLListConfig{ Categories: []string{"NEWS", "CULTR"}, CountryCode: "IT", Limit: 17, @@ -37,7 +37,7 @@ func TestFetchURLListSuccess(t *testing.T) { func TestFetchURLListFailure(t *testing.T) { client := newclient() client.BaseURL = "https://\t\t\t/" // cause test to fail - config := model.URLListConfig{ + config := model.OOAPIURLListConfig{ Categories: []string{"NEWS", "CULTR"}, CountryCode: "IT", Limit: 17, diff --git a/internal/engine/saver.go b/internal/engine/saver.go index b939482..471be32 100644 --- a/internal/engine/saver.go +++ b/internal/engine/saver.go @@ -3,7 +3,7 @@ package engine import ( "errors" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // Saver saves a measurement on some persistent storage. diff --git a/internal/engine/saver_test.go b/internal/engine/saver_test.go index 95f9307..afb5247 100644 --- a/internal/engine/saver_test.go +++ b/internal/engine/saver_test.go @@ -6,7 +6,7 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestNewSaverDisabled(t *testing.T) { diff --git a/internal/engine/session.go b/internal/engine/session.go index 8fcc7c5..037608a 100644 --- a/internal/engine/session.go +++ b/internal/engine/session.go @@ -14,10 +14,10 @@ import ( "github.com/ooni/probe-cli/v3/internal/bytecounter" "github.com/ooni/probe-cli/v3/internal/engine/geolocate" "github.com/ooni/probe-cli/v3/internal/engine/internal/sessionresolver" - "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/probeservices" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/platform" "github.com/ooni/probe-cli/v3/internal/tunnel" "github.com/ooni/probe-cli/v3/internal/version" @@ -25,8 +25,8 @@ import ( // SessionConfig contains the Session config type SessionConfig struct { - AvailableProbeServices []model.Service - KVStore KVStore + AvailableProbeServices []model.OOAPIService + KVStore model.KeyValueStore Logger model.Logger ProxyURL *url.URL SoftwareName string @@ -48,18 +48,18 @@ type SessionConfig struct { // of such resources. It is not possible to reuse a Session. You MUST // NOT attempt to use a Session again after Session.Close. type Session struct { - availableProbeServices []model.Service - availableTestHelpers map[string][]model.Service + availableProbeServices []model.OOAPIService + availableTestHelpers map[string][]model.OOAPIService byteCounter *bytecounter.Counter httpDefaultTransport netx.HTTPRoundTripper - kvStore KVStore + kvStore model.KeyValueStore location *geolocate.Results logger model.Logger proxyURL *url.URL queryProbeServicesCount *atomicx.Int64 resolver *sessionresolver.Resolver - selectedProbeServiceHook func(*model.Service) - selectedProbeService *model.Service + selectedProbeServiceHook func(*model.OOAPIService) + selectedProbeService *model.OOAPIService softwareName string softwareVersion string tempDir string @@ -103,7 +103,7 @@ type Session struct { // sessionProbeServicesClientForCheckIn returns the probe services // client that we should be using for performing the check-in. type sessionProbeServicesClientForCheckIn interface { - CheckIn(ctx context.Context, config model.CheckInConfig) (*model.CheckInInfo, error) + CheckIn(ctx context.Context, config model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) } // NewSession creates a new session. This factory function will @@ -243,7 +243,7 @@ func (s *Session) KibiBytesSent() float64 { // // The return value is either the check-in response or an error. func (s *Session) CheckIn( - ctx context.Context, config *model.CheckInConfig) (*model.CheckInInfo, error) { + ctx context.Context, config *model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) { if err := s.maybeLookupLocationContext(ctx); err != nil { return nil, err } @@ -323,7 +323,7 @@ func (s *Session) doClose() { // GetTestHelpersByName returns the available test helpers that // use the specified name, or false if there's none. -func (s *Session) GetTestHelpersByName(name string) ([]model.Service, bool) { +func (s *Session) GetTestHelpersByName(name string) ([]model.OOAPIService, bool) { defer s.mu.Unlock() s.mu.Lock() services, ok := s.availableTestHelpers[name] @@ -337,7 +337,7 @@ func (s *Session) DefaultHTTPClient() *http.Client { // FetchTorTargets fetches tor targets from the API. func (s *Session) FetchTorTargets( - ctx context.Context, cc string) (map[string]model.TorTarget, error) { + ctx context.Context, cc string) (map[string]model.OOAPITorTarget, error) { clnt, err := s.NewOrchestraClient(ctx) if err != nil { return nil, err @@ -347,7 +347,7 @@ func (s *Session) FetchTorTargets( // FetchURLList fetches the URL list from the API. func (s *Session) FetchURLList( - ctx context.Context, config model.URLListConfig) ([]model.URLInfo, error) { + ctx context.Context, config model.OOAPIURLListConfig) ([]model.OOAPIURLInfo, error) { clnt, err := s.NewOrchestraClient(ctx) if err != nil { return nil, err @@ -576,7 +576,7 @@ func (s *Session) UserAgent() (useragent string) { // getAvailableProbeServicesUnlocked returns the available probe // services. This function WILL NOT acquire the mu mutex, therefore, // you MUST ensure you are using it from a locked context. -func (s *Session) getAvailableProbeServicesUnlocked() []model.Service { +func (s *Session) getAvailableProbeServicesUnlocked() []model.OOAPIService { if len(s.availableProbeServices) > 0 { return s.availableProbeServices } diff --git a/internal/engine/session_integration_test.go b/internal/engine/session_integration_test.go index d1472dd..0700bd1 100644 --- a/internal/engine/session_integration_test.go +++ b/internal/engine/session_integration_test.go @@ -14,8 +14,8 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" "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/probeservices" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/version" ) @@ -90,7 +90,7 @@ func TestSessionTorArgsTorBinary(t *testing.T) { t.Skip("skip test in short mode") } sess, err := NewSession(context.Background(), SessionConfig{ - AvailableProbeServices: []model.Service{{ + AvailableProbeServices: []model.OOAPIService{{ Address: "https://ams-pg-test.ooni.org", Type: "https", }}, @@ -122,7 +122,7 @@ func TestSessionTorArgsTorBinary(t *testing.T) { func newSessionForTestingNoLookupsWithProxyURL(t *testing.T, URL *url.URL) *Session { sess, err := NewSession(context.Background(), SessionConfig{ - AvailableProbeServices: []model.Service{{ + AvailableProbeServices: []model.OOAPIService{{ Address: "https://ams-pg-test.ooni.org", Type: "https", }}, @@ -175,7 +175,7 @@ func TestInitOrchestraClientMaybeRegisterError(t *testing.T) { cancel() // so we fail immediately sess := newSessionForTestingNoLookups(t) defer sess.Close() - clnt, err := probeservices.NewClient(sess, model.Service{ + clnt, err := probeservices.NewClient(sess, model.OOAPIService{ Address: "https://ams-pg-test.ooni.org/", Type: "https", }) @@ -200,7 +200,7 @@ func TestInitOrchestraClientMaybeLoginError(t *testing.T) { ctx := context.Background() sess := newSessionForTestingNoLookups(t) defer sess.Close() - clnt, err := probeservices.NewClient(sess, model.Service{ + clnt, err := probeservices.NewClient(sess, model.OOAPIService{ Address: "https://ams-pg-test.ooni.org/", Type: "https", }) @@ -252,7 +252,7 @@ func TestMaybeLookupBackendsNewClientError(t *testing.T) { t.Skip("skip test in short mode") } sess := newSessionForTestingNoLookups(t) - sess.availableProbeServices = []model.Service{{ + sess.availableProbeServices = []model.OOAPIService{{ Type: "onion", Address: "httpo://jehhrikjjqrlpufu.onion", }} @@ -307,7 +307,7 @@ func TestSessionCheckInWithRealAPI(t *testing.T) { } sess := newSessionForTesting(t) defer sess.Close() - results, err := sess.CheckIn(context.Background(), &model.CheckInConfig{}) + results, err := sess.CheckIn(context.Background(), &model.OOAPICheckInConfig{}) if err != nil { t.Fatal(err) } @@ -412,7 +412,7 @@ func TestAllProbeServicesUnsupported(t *testing.T) { t.Fatal(err) } defer sess.Close() - sess.AppendAvailableProbeService(model.Service{ + sess.AppendAvailableProbeService(model.OOAPIService{ Address: "mascetti", Type: "antani", }) @@ -476,7 +476,7 @@ func TestNewOrchestraClientProbeServicesNewClientFailure(t *testing.T) { t.Skip("skip test in short mode") } sess := newSessionForTestingNoLookups(t) - sess.selectedProbeServiceHook = func(svc *model.Service) { + sess.selectedProbeServiceHook = func(svc *model.OOAPIService) { svc.Type = "antani" // should really not be supported for a long time } client, err := sess.NewOrchestraClient(context.Background()) @@ -504,7 +504,7 @@ func TestSessionFetchURLList(t *testing.T) { t.Skip("skip test in short mode") } sess := newSessionForTesting(t) - resp, err := sess.FetchURLList(context.Background(), model.URLListConfig{}) + resp, err := sess.FetchURLList(context.Background(), model.OOAPIURLListConfig{}) if err != nil { t.Fatal(err) } diff --git a/internal/engine/session_internal_test.go b/internal/engine/session_internal_test.go index a80f3dc..19e102a 100644 --- a/internal/engine/session_internal_test.go +++ b/internal/engine/session_internal_test.go @@ -10,14 +10,14 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" "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/model" ) -func (s *Session) GetAvailableProbeServices() []model.Service { +func (s *Session) GetAvailableProbeServices() []model.OOAPIService { return s.getAvailableProbeServicesUnlocked() } -func (s *Session) AppendAvailableProbeService(svc model.Service) { +func (s *Session) AppendAvailableProbeService(svc model.OOAPIService) { s.availableProbeServices = append(s.availableProbeServices, svc) } @@ -29,11 +29,11 @@ func (s *Session) QueryProbeServicesCount() int64 { // probeservices.Client used by Session.CheckIn. type mockableProbeServicesClientForCheckIn struct { // Config is the config passed to the call. - Config *model.CheckInConfig + Config *model.OOAPICheckInConfig // Results contains the results of the call. This field MUST be // non-nil if and only if Error is nil. - Results *model.CheckInInfo + Results *model.OOAPICheckInInfo // Error indicates whether the call failed. This field MUST be // non-nil if and only if Error is nil. @@ -45,7 +45,7 @@ type mockableProbeServicesClientForCheckIn struct { // CheckIn implements sessionProbeServicesClientForCheckIn.CheckIn. func (c *mockableProbeServicesClientForCheckIn) CheckIn( - ctx context.Context, config model.CheckInConfig) (*model.CheckInInfo, error) { + ctx context.Context, config model.OOAPICheckInConfig) (*model.OOAPICheckInInfo, error) { defer c.mu.Unlock() c.mu.Lock() if c.Config != nil { @@ -59,10 +59,10 @@ func (c *mockableProbeServicesClientForCheckIn) CheckIn( } func TestSessionCheckInSuccessful(t *testing.T) { - results := &model.CheckInInfo{ - WebConnectivity: &model.CheckInInfoWebConnectivity{ + results := &model.OOAPICheckInInfo{ + WebConnectivity: &model.OOAPICheckInInfoWebConnectivity{ ReportID: "xxx-x-xx", - URLs: []model.URLInfo{{ + URLs: []model.OOAPIURLInfo{{ CategoryCode: "NEWS", CountryCode: "IT", URL: "https://www.repubblica.it/", @@ -91,7 +91,7 @@ func TestSessionCheckInSuccessful(t *testing.T) { return mockedClnt, nil }, } - out, err := s.CheckIn(context.Background(), &model.CheckInConfig{}) + out, err := s.CheckIn(context.Background(), &model.OOAPICheckInConfig{}) if err != nil { t.Fatal(err) } @@ -128,7 +128,7 @@ func TestSessionCheckInCannotLookupLocation(t *testing.T) { return errMocked }, } - out, err := s.CheckIn(context.Background(), &model.CheckInConfig{}) + out, err := s.CheckIn(context.Background(), &model.OOAPICheckInConfig{}) if !errors.Is(err, errMocked) { t.Fatal("no the error we expected", err) } @@ -154,7 +154,7 @@ func TestSessionCheckInCannotCreateProbeServicesClient(t *testing.T) { return nil, errMocked }, } - out, err := s.CheckIn(context.Background(), &model.CheckInConfig{}) + out, err := s.CheckIn(context.Background(), &model.OOAPICheckInConfig{}) if !errors.Is(err, errMocked) { t.Fatal("no the error we expected", err) } @@ -215,7 +215,7 @@ func TestSessionFetchURLListWithCancelledContext(t *testing.T) { sess := &Session{} ctx, cancel := context.WithCancel(context.Background()) cancel() // cause failure - resp, err := sess.FetchURLList(ctx, model.URLListConfig{}) + resp, err := sess.FetchURLList(ctx, model.OOAPIURLListConfig{}) if !errors.Is(err, context.Canceled) { t.Fatal("not the error we expected", err) } diff --git a/internal/engine/submitter.go b/internal/engine/submitter.go index f5ee834..074b820 100644 --- a/internal/engine/submitter.go +++ b/internal/engine/submitter.go @@ -3,7 +3,7 @@ package engine import ( "context" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // TODO(bassosimone): maybe keep track of which measurements diff --git a/internal/engine/submitter_test.go b/internal/engine/submitter_test.go index a2f0795..ac0a2b9 100644 --- a/internal/engine/submitter_test.go +++ b/internal/engine/submitter_test.go @@ -7,7 +7,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestSubmitterNotEnabled(t *testing.T) { diff --git a/internal/kvstore/doc.go b/internal/kvstore/doc.go new file mode 100644 index 0000000..861ad21 --- /dev/null +++ b/internal/kvstore/doc.go @@ -0,0 +1,2 @@ +// Package kvstore implements model.KeyValueStore. +package kvstore diff --git a/internal/kvstore/fs.go b/internal/kvstore/fs.go index 483a625..423e857 100644 --- a/internal/kvstore/fs.go +++ b/internal/kvstore/fs.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/rogpeppe/go-internal/lockedfile" ) @@ -15,6 +16,8 @@ type FS struct { basedir string } +var _ model.KeyValueStore = &FS{} + // NewFS creates a new kvstore.FileSystem. func NewFS(basedir string) (kvs *FS, err error) { return newFileSystem(basedir, os.MkdirAll) diff --git a/internal/kvstore/memory.go b/internal/kvstore/memory.go index 88f81db..593bf13 100644 --- a/internal/kvstore/memory.go +++ b/internal/kvstore/memory.go @@ -1,9 +1,10 @@ -// Package kvstore contains key-value stores. package kvstore import ( "errors" "sync" + + "github.com/ooni/probe-cli/v3/internal/model" ) // ErrNoSuchKey indicates that there's no value for the given key. @@ -18,6 +19,8 @@ type Memory struct { mu sync.Mutex } +var _ model.KeyValueStore = &Memory{} + // Get returns the specified key's value. In case of error, the // error type is such that errors.Is(err, ErrNoSuchKey). func (kvs *Memory) Get(key string) ([]byte, error) { diff --git a/internal/measurex/dialer.go b/internal/measurex/dialer.go index 2920c10..d0fc2de 100644 --- a/internal/measurex/dialer.go +++ b/internal/measurex/dialer.go @@ -11,29 +11,27 @@ import ( "net" "time" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) // Conn is a network connection. type Conn = net.Conn -// Dialer dials network connections. -type Dialer = netxlite.Dialer - // WrapDialer creates a new dialer that writes events // into the given WritableDB. The net.Conns created by // a wrapped dialer also write into the WritableDB. -func (mx *Measurer) WrapDialer(db WritableDB, dialer netxlite.Dialer) Dialer { +func (mx *Measurer) WrapDialer(db WritableDB, dialer model.Dialer) model.Dialer { return WrapDialer(mx.Begin, db, dialer) } // WrapDialer wraps a dialer. -func WrapDialer(begin time.Time, db WritableDB, dialer netxlite.Dialer) Dialer { +func WrapDialer(begin time.Time, db WritableDB, dialer model.Dialer) model.Dialer { return &dialerDB{Dialer: dialer, db: db, begin: begin} } // NewDialerWithSystemResolver creates a -func (mx *Measurer) NewDialerWithSystemResolver(db WritableDB, logger Logger) Dialer { +func (mx *Measurer) NewDialerWithSystemResolver(db WritableDB, logger model.Logger) model.Dialer { r := mx.NewResolverSystem(db, logger) return mx.WrapDialer(db, netxlite.NewDialerWithResolver(logger, r)) } @@ -41,12 +39,12 @@ func (mx *Measurer) NewDialerWithSystemResolver(db WritableDB, logger Logger) Di // NewDialerWithoutResolver is a convenience factory for creating // a dialer that saves measurements into the DB and that is not attached // to any resolver (hence only works when passed IP addresses). -func (mx *Measurer) NewDialerWithoutResolver(db WritableDB, logger Logger) Dialer { +func (mx *Measurer) NewDialerWithoutResolver(db WritableDB, logger model.Logger) model.Dialer { return mx.WrapDialer(db, netxlite.NewDialerWithoutResolver(logger)) } type dialerDB struct { - netxlite.Dialer + model.Dialer begin time.Time db WritableDB } diff --git a/internal/measurex/dnsx.go b/internal/measurex/dnsx.go index 47db106..a82ecf3 100644 --- a/internal/measurex/dnsx.go +++ b/internal/measurex/dnsx.go @@ -10,22 +10,17 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/netxlite" + "github.com/ooni/probe-cli/v3/internal/model" ) -// DNSXRoundTripper is a transport for sending raw DNS queries -// and receiving raw DNS replies. The internal/netxlite/dnsx -// package implements a bunch of these transports. -type DNSTransport = netxlite.DNSTransport - // WrapDNSXRoundTripper creates a new DNSXRoundTripper that // saves events into the given WritableDB. -func (mx *Measurer) WrapDNSXRoundTripper(db WritableDB, rtx netxlite.DNSTransport) DNSTransport { +func (mx *Measurer) WrapDNSXRoundTripper(db WritableDB, rtx model.DNSTransport) model.DNSTransport { return &dnsxRoundTripperDB{db: db, DNSTransport: rtx, begin: mx.Begin} } type dnsxRoundTripperDB struct { - netxlite.DNSTransport + model.DNSTransport begin time.Time db WritableDB } diff --git a/internal/measurex/http.go b/internal/measurex/http.go index 9d0e4d9..ef75880 100644 --- a/internal/measurex/http.go +++ b/internal/measurex/http.go @@ -27,18 +27,16 @@ import ( "github.com/lucas-clemente/quic-go" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/runtimex" "golang.org/x/net/publicsuffix" ) -// HTTPTransport is the HTTP transport type we use. -type HTTPTransport = netxlite.HTTPTransport - // WrapHTTPTransport creates a new transport that saves // HTTP events into the WritableDB. func (mx *Measurer) WrapHTTPTransport( - db WritableDB, txp HTTPTransport) *HTTPTransportDB { + db WritableDB, txp model.HTTPTransport) *HTTPTransportDB { return WrapHTTPTransport(mx.Begin, db, txp) } @@ -48,7 +46,7 @@ func (mx *Measurer) WrapHTTPTransport( const httpMaxBodySnapshot = 1 << 11 func WrapHTTPTransport( - begin time.Time, db WritableDB, txp HTTPTransport) *HTTPTransportDB { + begin time.Time, db WritableDB, txp model.HTTPTransport) *HTTPTransportDB { return &HTTPTransportDB{ HTTPTransport: txp, Begin: begin, @@ -60,7 +58,7 @@ func WrapHTTPTransport( // NewHTTPTransportWithConn creates and wraps an HTTPTransport that // does not dial and only uses the given conn. func (mx *Measurer) NewHTTPTransportWithConn( - logger Logger, db WritableDB, conn Conn) *HTTPTransportDB { + logger model.Logger, db WritableDB, conn Conn) *HTTPTransportDB { return mx.WrapHTTPTransport(db, netxlite.NewHTTPTransport( logger, netxlite.NewSingleUseDialer(conn), netxlite.NewNullTLSDialer())) } @@ -68,7 +66,7 @@ func (mx *Measurer) NewHTTPTransportWithConn( // NewHTTPTransportWithTLSConn creates and wraps an HTTPTransport that // does not dial and only uses the given conn. func (mx *Measurer) NewHTTPTransportWithTLSConn( - logger Logger, db WritableDB, conn netxlite.TLSConn) *HTTPTransportDB { + logger model.Logger, db WritableDB, conn netxlite.TLSConn) *HTTPTransportDB { return mx.WrapHTTPTransport(db, netxlite.NewHTTPTransport( logger, netxlite.NewNullDialer(), netxlite.NewSingleUseTLSDialer(conn))) } @@ -76,7 +74,7 @@ func (mx *Measurer) NewHTTPTransportWithTLSConn( // NewHTTPTransportWithQUICSess creates and wraps an HTTPTransport that // does not dial and only uses the given QUIC session. func (mx *Measurer) NewHTTPTransportWithQUICSess( - logger Logger, db WritableDB, sess quic.EarlySession) *HTTPTransportDB { + logger model.Logger, db WritableDB, sess quic.EarlySession) *HTTPTransportDB { return mx.WrapHTTPTransport(db, netxlite.NewHTTP3Transport( logger, netxlite.NewSingleUseQUICDialer(sess), &tls.Config{})) } @@ -88,7 +86,7 @@ func (mx *Measurer) NewHTTPTransportWithQUICSess( // you can construct it manually. In which case, do not modify // public fields during usage, since this may cause a data race. type HTTPTransportDB struct { - netxlite.HTTPTransport + model.HTTPTransport // Begin is when we started measuring. Begin time.Time @@ -206,14 +204,14 @@ type HTTPClient interface { // NewHTTPClient creates a new HTTPClient instance that // does not automatically perform redirects. func NewHTTPClientWithoutRedirects( - db WritableDB, jar http.CookieJar, txp HTTPTransport) HTTPClient { + db WritableDB, jar http.CookieJar, txp model.HTTPTransport) HTTPClient { return newHTTPClient(db, jar, txp, http.ErrUseLastResponse) } // NewHTTPClientWithRedirects creates a new HTTPClient // instance that automatically perform redirects. func NewHTTPClientWithRedirects( - db WritableDB, jar http.CookieJar, txp HTTPTransport) HTTPClient { + db WritableDB, jar http.CookieJar, txp model.HTTPTransport) HTTPClient { return newHTTPClient(db, jar, txp, nil) } @@ -243,7 +241,7 @@ type HTTPRedirectEvent struct { var ErrHTTPTooManyRedirects = errors.New("stopped after 10 redirects") func newHTTPClient(db WritableDB, cookiejar http.CookieJar, - txp HTTPTransport, defaultErr error) HTTPClient { + txp model.HTTPTransport, defaultErr error) HTTPClient { return netxlite.WrapHTTPClient(&http.Client{ Transport: txp, Jar: cookiejar, diff --git a/internal/measurex/logger.go b/internal/measurex/logger.go index 12a2488..5dade55 100644 --- a/internal/measurex/logger.go +++ b/internal/measurex/logger.go @@ -11,24 +11,12 @@ import ( "sync" "time" - "github.com/ooni/probe-cli/v3/internal/netxlite" + "github.com/ooni/probe-cli/v3/internal/model" ) -// Logger is the logger type we use. This type is compatible -// with the logger type of github.com/apex/log. -type Logger interface { - netxlite.Logger - - Info(msg string) - Infof(format string, v ...interface{}) - - Warn(msg string) - Warnf(format string, v ...interface{}) -} - // NewOperationLogger creates a new logger that logs // about an in-progress operation. -func NewOperationLogger(logger Logger, format string, v ...interface{}) *OperationLogger { +func NewOperationLogger(logger model.Logger, format string, v ...interface{}) *OperationLogger { ol := &OperationLogger{ sighup: make(chan interface{}), logger: logger, @@ -43,7 +31,7 @@ func NewOperationLogger(logger Logger, format string, v ...interface{}) *Operati // OperationLogger logs about an in-progress operation type OperationLogger struct { - logger Logger + logger model.Logger message string once *sync.Once sighup chan interface{} diff --git a/internal/measurex/measurer.go b/internal/measurex/measurer.go index bccb7f5..4784b62 100644 --- a/internal/measurex/measurer.go +++ b/internal/measurex/measurer.go @@ -21,6 +21,7 @@ import ( "github.com/apex/log" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -34,7 +35,7 @@ type Measurer struct { HTTPClient HTTPClient // Logger is the MANDATORY logger to use. - Logger Logger + Logger model.Logger // MeasureURLHelper is the OPTIONAL test helper to use when // we're measuring using the MeasureURL function. If this field @@ -45,7 +46,7 @@ type Measurer struct { Resolvers []*ResolverInfo // TLSHandshaker is the MANDATORY TLS handshaker. - TLSHandshaker netxlite.TLSHandshaker + TLSHandshaker model.TLSHandshaker } // NewMeasurerWithDefaultSettings creates a new Measurer @@ -85,7 +86,7 @@ func (mx *Measurer) LookupHostSystem(ctx context.Context, domain string) *DNSMea // lookupHostForeign performs a LookupHost using a "foreign" resolver. func (mx *Measurer) lookupHostForeign( - ctx context.Context, domain string, r Resolver) *DNSMeasurement { + ctx context.Context, domain string, r model.Resolver) *DNSMeasurement { const timeout = 4 * time.Second ol := NewOperationLogger(mx.Logger, "LookupHost %s with %s", domain, r.Network()) ctx, cancel := context.WithTimeout(ctx, timeout) @@ -158,7 +159,7 @@ func (mx *Measurer) LookupHTTPSSvcUDP( // lookupHTTPSSvcUDPForeign is like LookupHTTPSSvcUDP // except that it uses a "foreign" resolver. func (mx *Measurer) lookupHTTPSSvcUDPForeign( - ctx context.Context, domain string, r Resolver) *DNSMeasurement { + ctx context.Context, domain string, r model.Resolver) *DNSMeasurement { const timeout = 4 * time.Second ol := NewOperationLogger(mx.Logger, "LookupHTTPSvc %s with %s", domain, r.Address()) ctx, cancel := context.WithTimeout(ctx, timeout) @@ -591,7 +592,7 @@ type ResolverInfo struct { // ForeignResolver is only used when Network's // value equals the ResolverForeign constant. - ForeignResolver Resolver + ForeignResolver model.Resolver } // LookupURLHostParallel performs an LookupHost-like operation for each diff --git a/internal/measurex/quic.go b/internal/measurex/quic.go index 18bd833..ea48375 100644 --- a/internal/measurex/quic.go +++ b/internal/measurex/quic.go @@ -13,26 +13,17 @@ import ( "time" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" ) -// QUICConn is the kind of conn used by QUIC. -type QUICConn = quicx.UDPLikeConn - -// QUICDialer creates QUICSesssions. -type QUICDialer = netxlite.QUICDialer - -// QUICListener creates listening connections for QUIC. -type QUICListener = netxlite.QUICListener - type quicListenerDB struct { - netxlite.QUICListener + model.QUICListener begin time.Time db WritableDB } -func (ql *quicListenerDB) Listen(addr *net.UDPAddr) (QUICConn, error) { +func (ql *quicListenerDB) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { pconn, err := ql.QUICListener.Listen(addr) if err != nil { return nil, err @@ -45,7 +36,7 @@ func (ql *quicListenerDB) Listen(addr *net.UDPAddr) (QUICConn, error) { } type udpLikeConnDB struct { - quicx.UDPLikeConn + model.UDPLikeConn begin time.Time db WritableDB } @@ -103,15 +94,15 @@ func (c *udpLikeConnDB) Close() error { // address containing a domain name will fail. This QUICDialer will // save any event into the WritableDB. Any QUICConn created by it will // likewise save any event into the WritableDB. -func (mx *Measurer) NewQUICDialerWithoutResolver(db WritableDB, logger Logger) QUICDialer { +func (mx *Measurer) NewQUICDialerWithoutResolver(db WritableDB, logger model.Logger) model.QUICDialer { return &quicDialerDB{db: db, logger: logger, begin: mx.Begin} } type quicDialerDB struct { - netxlite.QUICDialer + model.QUICDialer begin time.Time db WritableDB - logger Logger + logger model.Logger } func (qh *quicDialerDB) DialContext(ctx context.Context, network, address string, diff --git a/internal/measurex/resolver.go b/internal/measurex/resolver.go index b519cb7..0ce0b31 100644 --- a/internal/measurex/resolver.go +++ b/internal/measurex/resolver.go @@ -11,30 +11,23 @@ import ( "strings" "time" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/dnsx" ) -// HTTPSSvc is the result returned by HTTPSSvc queries. -type HTTPSSvc = dnsx.HTTPSSvc - -// Resolver is the resolver type we use. This resolver will -// store resolve events into the DB. -type Resolver = netxlite.Resolver - // WrapResolver creates a new Resolver that saves events into the WritableDB. -func (mx *Measurer) WrapResolver(db WritableDB, r netxlite.Resolver) Resolver { +func (mx *Measurer) WrapResolver(db WritableDB, r model.Resolver) model.Resolver { return WrapResolver(mx.Begin, db, r) } // WrapResolver wraps a resolver. -func WrapResolver(begin time.Time, db WritableDB, r netxlite.Resolver) Resolver { +func WrapResolver(begin time.Time, db WritableDB, r model.Resolver) model.Resolver { return &resolverDB{Resolver: r, db: db, begin: begin} } // NewResolverSystem creates a system resolver and then wraps // it using the WrapResolver function/ -func (mx *Measurer) NewResolverSystem(db WritableDB, logger Logger) Resolver { +func (mx *Measurer) NewResolverSystem(db WritableDB, logger model.Logger) model.Resolver { return mx.WrapResolver(db, netxlite.NewResolverStdlib(logger)) } @@ -48,7 +41,7 @@ func (mx *Measurer) NewResolverSystem(db WritableDB, logger Logger) Resolver { // - logger is the logger; // // - address is the resolver address (e.g., "1.1.1.1:53"). -func (mx *Measurer) NewResolverUDP(db WritableDB, logger Logger, address string) Resolver { +func (mx *Measurer) NewResolverUDP(db WritableDB, logger model.Logger, address string) model.Resolver { return mx.WrapResolver(db, netxlite.WrapResolver( logger, netxlite.NewSerialResolver( mx.WrapDNSXRoundTripper(db, netxlite.NewDNSOverUDP( @@ -59,7 +52,7 @@ func (mx *Measurer) NewResolverUDP(db WritableDB, logger Logger, address string) } type resolverDB struct { - netxlite.Resolver + model.Resolver begin time.Time db WritableDB } @@ -160,7 +153,7 @@ func (r *resolverDB) computeOddityLookupHost(addrs []string, err error) Oddity { return "" } -func (r *resolverDB) LookupHTTPS(ctx context.Context, domain string) (*HTTPSSvc, error) { +func (r *resolverDB) LookupHTTPS(ctx context.Context, domain string) (*model.HTTPSSvc, error) { started := time.Since(r.begin).Seconds() https, err := r.Resolver.LookupHTTPS(ctx, domain) finished := time.Since(r.begin).Seconds() @@ -183,7 +176,7 @@ func (r *resolverDB) LookupHTTPS(ctx context.Context, domain string) (*HTTPSSvc, return https, err } -func (r *resolverDB) computeOddityHTTPSSvc(https *HTTPSSvc, err error) Oddity { +func (r *resolverDB) computeOddityHTTPSSvc(https *model.HTTPSSvc, err error) Oddity { if err != nil { return r.computeOddityLookupHost(nil, err) } diff --git a/internal/measurex/tls.go b/internal/measurex/tls.go index afeada6..8ee1fd7 100644 --- a/internal/measurex/tls.go +++ b/internal/measurex/tls.go @@ -14,26 +14,24 @@ import ( "net" "time" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) -// TLSHandshaker performs TLS handshakes. -type TLSHandshaker = netxlite.TLSHandshaker - // WrapTLSHandshaker wraps a netxlite.TLSHandshaker to return a new // instance of TLSHandshaker that saves events into the DB. -func (mx *Measurer) WrapTLSHandshaker(db WritableDB, thx netxlite.TLSHandshaker) TLSHandshaker { +func (mx *Measurer) WrapTLSHandshaker(db WritableDB, thx model.TLSHandshaker) model.TLSHandshaker { return &tlsHandshakerDB{TLSHandshaker: thx, db: db, begin: mx.Begin} } // NewTLSHandshakerStdlib creates a new TLS handshaker that // saves results into the DB and uses the stdlib for TLS. -func (mx *Measurer) NewTLSHandshakerStdlib(db WritableDB, logger Logger) TLSHandshaker { +func (mx *Measurer) NewTLSHandshakerStdlib(db WritableDB, logger model.Logger) model.TLSHandshaker { return mx.WrapTLSHandshaker(db, netxlite.NewTLSHandshakerStdlib(logger)) } type tlsHandshakerDB struct { - netxlite.TLSHandshaker + model.TLSHandshaker begin time.Time db WritableDB } diff --git a/internal/measurex/tracing.go b/internal/measurex/tracing.go index 3d8850a..c558c0f 100644 --- a/internal/measurex/tracing.go +++ b/internal/measurex/tracing.go @@ -5,6 +5,7 @@ import ( "net/url" "time" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -25,8 +26,8 @@ import ( // - resolver is the underlying resolver to use // // - handshake is the TLS handshaker to use -func NewTracingHTTPTransport(logger Logger, begin time.Time, db WritableDB, - resolver Resolver, dialer Dialer, handshaker TLSHandshaker) *HTTPTransportDB { +func NewTracingHTTPTransport(logger model.Logger, begin time.Time, db WritableDB, + resolver model.Resolver, dialer model.Dialer, handshaker model.TLSHandshaker) *HTTPTransportDB { resolver = WrapResolver(begin, db, resolver) dialer = netxlite.WrapDialer(logger, resolver, WrapDialer(begin, db, dialer)) tlsDialer := netxlite.NewTLSDialer(dialer, handshaker) @@ -47,7 +48,7 @@ func NewTracingHTTPTransport(logger Logger, begin time.Time, db WritableDB, // eventually become the measurement // func NewTracingHTTPTransportWithDefaultSettings( - begin time.Time, logger Logger, db WritableDB) *HTTPTransportDB { + begin time.Time, logger model.Logger, db WritableDB) *HTTPTransportDB { return NewTracingHTTPTransport(logger, begin, db, netxlite.NewResolverStdlib(logger), netxlite.NewDialerWithoutResolver(logger), @@ -55,7 +56,7 @@ func NewTracingHTTPTransportWithDefaultSettings( } func (mx *Measurer) NewTracingHTTPTransportWithDefaultSettings( - logger Logger, db WritableDB) *HTTPTransportDB { + logger model.Logger, db WritableDB) *HTTPTransportDB { return NewTracingHTTPTransport( mx.Logger, mx.Begin, db, mx.NewResolverSystem(db, mx.Logger), mx.NewDialerWithoutResolver(db, mx.Logger), diff --git a/internal/mlablocate/mlablocate.go b/internal/mlablocate/mlablocate.go index e8b6708..9c3554a 100644 --- a/internal/mlablocate/mlablocate.go +++ b/internal/mlablocate/mlablocate.go @@ -12,15 +12,10 @@ import ( "net/http" "net/url" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) -// Logger is the logger expected by this package. -type Logger interface { - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) -} - // HTTPClient is anything that looks like an http.Client. type HTTPClient interface { // Do behaves like http.Client.Do. @@ -38,7 +33,7 @@ type Client struct { Hostname string // Logger is the MANDATORY logger to use. - Logger Logger + Logger model.DebugLogger // Scheme is the MANDATORY scheme to use (http or https). Scheme string @@ -48,7 +43,7 @@ type Client struct { } // NewClient creates a new locate.measurementlab.net client. -func NewClient(httpClient HTTPClient, logger Logger, userAgent string) *Client { +func NewClient(httpClient HTTPClient, logger model.DebugLogger, userAgent string) *Client { return &Client{ HTTPClient: httpClient, Hostname: "locate.measurementlab.net", diff --git a/internal/mlablocatev2/mlablocatev2.go b/internal/mlablocatev2/mlablocatev2.go index f3fe937..b811778 100644 --- a/internal/mlablocatev2/mlablocatev2.go +++ b/internal/mlablocatev2/mlablocatev2.go @@ -12,6 +12,7 @@ import ( "net/url" "regexp" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -28,12 +29,6 @@ var ( ErrEmptyResponse = errors.New("mlablocatev2: empty response") ) -// Logger is the logger expected by this package. -type Logger interface { - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) -} - // HTTPClient is anything that looks like an http.Client. type HTTPClient interface { // Do behaves like http.Client.Do. @@ -51,7 +46,7 @@ type Client struct { Hostname string // Logger is the MANDATORY logger to use. - Logger Logger + Logger model.DebugLogger // Scheme is the MANDATORY scheme to use (http or https). Scheme string @@ -61,7 +56,7 @@ type Client struct { } // NewClient creates a client for v2 of the locate services. -func NewClient(httpClient HTTPClient, logger Logger, userAgent string) Client { +func NewClient(httpClient HTTPClient, logger model.DebugLogger, userAgent string) Client { return Client{ HTTPClient: httpClient, Hostname: "locate.measurementlab.net", diff --git a/internal/model/README.md b/internal/model/README.md new file mode 100644 index 0000000..e92b7aa --- /dev/null +++ b/internal/model/README.md @@ -0,0 +1,6 @@ +# Package github.com/ooni/probe-engine/model + +Shared data structures and interfaces. We include in this +package the most fundamental types. Use `go doc` to get +more thorough documentation about what is inside this package +and when to put a type inside this package. diff --git a/internal/model/doc.go b/internal/model/doc.go new file mode 100644 index 0000000..b1242d2 --- /dev/null +++ b/internal/model/doc.go @@ -0,0 +1,40 @@ +// Package model contains the shared interfaces and data structures. +// +// Criteria for adding a type to this package +// +// This package should contain two types: +// +// 1. important interfaces that are shared by several packages +// within the codebase, with the objective of separating unrelated +// pieces of code and making unit testing easier; +// +// 2. important pieces of data that are shared across different +// packages (e.g., the representation of a Measurement). +// +// In general, this package should not contain logic, unless +// this logic is strictly related to data structures and we +// cannot implement this logic elsewhere. +// +// Content of this package +// +// The following list (which may not always be up-to-date) +// summarizes the categories of types that currently belong here +// and names the files in which they are implemented: +// +// - experiment.go: generic definition of a network experiment +// and all the required support types; +// +// - keyvaluestore.go: generic definition of a key-value store, +// used in several places across the codebase; +// +// - logger.go: generic definition of an apex/log compatible logger, +// used in several places across the codebase; +// +// - measurement.go: data type representing the result of +// a network measurement, used in many many places; +// +// - netx.go: network extension interfaces and data used everywhere +// we need to perform network operations; +// +// - ooapi.go: types to communicate with the OONI API. +package model diff --git a/internal/engine/model/experiment.go b/internal/model/experiment.go similarity index 91% rename from internal/engine/model/experiment.go rename to internal/model/experiment.go index 49e9e7f..36e30fe 100644 --- a/internal/engine/model/experiment.go +++ b/internal/model/experiment.go @@ -5,13 +5,18 @@ import ( "net/http" ) +// +// Definition of experiment and types used by the +// implemenation of all experiments. +// + // ExperimentSession is the experiment's view of a session. type ExperimentSession interface { - GetTestHelpersByName(name string) ([]Service, bool) + GetTestHelpersByName(name string) ([]OOAPIService, bool) DefaultHTTPClient() *http.Client FetchPsiphonConfig(ctx context.Context) ([]byte, error) - FetchTorTargets(ctx context.Context, cc string) (map[string]TorTarget, error) - FetchURLList(ctx context.Context, config URLListConfig) ([]URLInfo, error) + FetchTorTargets(ctx context.Context, cc string) (map[string]OOAPITorTarget, error) + FetchURLList(ctx context.Context, config OOAPIURLListConfig) ([]OOAPIURLInfo, error) Logger() Logger ProbeCC() string ResolverIP() string diff --git a/internal/engine/model/experiment_test.go b/internal/model/experiment_test.go similarity index 53% rename from internal/engine/model/experiment_test.go rename to internal/model/experiment_test.go index e1f1e96..8d59874 100644 --- a/internal/engine/model/experiment_test.go +++ b/internal/model/experiment_test.go @@ -1,13 +1,12 @@ -package model_test +package model import ( "testing" "github.com/apex/log" - "github.com/ooni/probe-cli/v3/internal/engine/model" ) func TestPrinterCallbacksCallbacks(t *testing.T) { - printer := model.NewPrinterCallbacks(log.Log) + printer := NewPrinterCallbacks(log.Log) printer.OnProgress(0.4, "progress") } diff --git a/internal/model/keyvaluestore.go b/internal/model/keyvaluestore.go new file mode 100644 index 0000000..5bbb9a0 --- /dev/null +++ b/internal/model/keyvaluestore.go @@ -0,0 +1,17 @@ +package model + +// +// Definition of a key-value store. +// + +// KeyValueStore is a generic key-value store. +type KeyValueStore interface { + // Get gets the value of the given key or returns an + // error if there is no such key or we cannot read + // from the key-value store. + Get(key string) (value []byte, err error) + + // Set sets the value of the given key and returns + // whether the operation was successful or not. + Set(key string, value []byte) (err error) +} diff --git a/internal/engine/model/logger.go b/internal/model/logger.go similarity index 61% rename from internal/engine/model/logger.go rename to internal/model/logger.go index d44fc4a..aa5448f 100644 --- a/internal/engine/model/logger.go +++ b/internal/model/logger.go @@ -1,19 +1,35 @@ package model -// Logger defines the common interface that a logger should have. It is -// out of the box compatible with `log.Log` in `apex/log`. -type Logger interface { +// +// Logger +// + +// DebugLogger is a logger emitting only debug messages. +type DebugLogger interface { // Debug emits a debug message. Debug(msg string) // Debugf formats and emits a debug message. Debugf(format string, v ...interface{}) +} + +// InfoLogger is a logger emitting debug and infor messages. +type InfoLogger interface { + // An InfoLogger is also a DebugLogger. + DebugLogger // Info emits an informational message. Info(msg string) // Infof formats and emits an informational message. Infof(format string, v ...interface{}) +} + +// Logger defines the common interface that a logger should have. It is +// out of the box compatible with `log.Log` in `apex/log`. +type Logger interface { + // A Logger is also an InfoLogger. + InfoLogger // Warn emits a warning message. Warn(msg string) @@ -22,19 +38,26 @@ type Logger interface { Warnf(format string, v ...interface{}) } -// DiscardLogger is a logger that discards its input +// DiscardLogger is the default logger that discards its input var DiscardLogger Logger = logDiscarder{} +// logDiscarder is a logger that discards its input type logDiscarder struct{} +// Debug implements DebugLogger.Debug func (logDiscarder) Debug(msg string) {} +// Debugf implements DebugLogger.Debugf func (logDiscarder) Debugf(format string, v ...interface{}) {} +// Info implements InfoLogger.Info func (logDiscarder) Info(msg string) {} +// Infov implements InfoLogger.Infov func (logDiscarder) Infof(format string, v ...interface{}) {} +// Warn implements Logger.Warn func (logDiscarder) Warn(msg string) {} +// Warnf implements Logger.Warnf func (logDiscarder) Warnf(format string, v ...interface{}) {} diff --git a/internal/model/logger_test.go b/internal/model/logger_test.go new file mode 100644 index 0000000..055e884 --- /dev/null +++ b/internal/model/logger_test.go @@ -0,0 +1,13 @@ +package model + +import "testing" + +func TestDiscardLoggerWorksAsIntended(t *testing.T) { + logger := DiscardLogger + logger.Debug("foo") + logger.Debugf("%s", "foo") + logger.Info("foo") + logger.Infof("%s", "foo") + logger.Warn("foo") + logger.Warnf("%s", "foo") +} diff --git a/internal/engine/model/measurement.go b/internal/model/measurement.go similarity index 70% rename from internal/engine/model/measurement.go rename to internal/model/measurement.go index 6ccad4a..58bd6b3 100644 --- a/internal/engine/model/measurement.go +++ b/internal/model/measurement.go @@ -1,10 +1,22 @@ package model import ( + "bytes" "encoding/json" + "errors" + "net" "time" ) +// +// Definition of the result of a network measurement. +// + +const ( + // DefaultProbeIP is the default probe IP. + DefaultProbeIP = "127.0.0.1" +) + // MeasurementTarget is the target of a OONI measurement. type MeasurementTarget string @@ -124,3 +136,44 @@ func (m *Measurement) AddAnnotation(key, value string) { } m.Annotations[key] = value } + +// ErrInvalidProbeIP indicates that we're dealing with a string that +// is not the valid serialization of an IP address. +var ErrInvalidProbeIP = errors.New("model: invalid probe IP") + +// Scrub scrubs the probeIP out of the measurement. +func (m *Measurement) Scrub(probeIP string) (err error) { + // We now behave like we can share everything except the + // probe IP, which we instead cannot ever share + m.ProbeIP = DefaultProbeIP + return m.MaybeRewriteTestKeys(probeIP, json.Marshal) +} + +// Scrubbed is the string that replaces IP addresses. +const Scrubbed = `[scrubbed]` + +// MaybeRewriteTestKeys is the function called by Scrub that +// ensures that m's serialization doesn't include the IP +func (m *Measurement) MaybeRewriteTestKeys( + currentIP string, marshal func(interface{}) ([]byte, error)) error { + if net.ParseIP(currentIP) == nil { + return ErrInvalidProbeIP + } + data, err := marshal(m.TestKeys) + if err != nil { + return err + } + // The check using Count is to save an unnecessary copy performed by + // ReplaceAll when there are no matches into the body. This is what + // we would like the common case to be, meaning that the code has done + // its job correctly and has not leaked the IP. + bpip := []byte(currentIP) + if bytes.Count(data, bpip) <= 0 { + return nil + } + data = bytes.ReplaceAll(data, bpip, []byte(Scrubbed)) + // We add an annotation such that hopefully later we can measure the + // number of cases where we failed to sanitize properly. + m.AddAnnotation("_probe_engine_sanitize_test_keys", "true") + return json.Unmarshal(data, &m.TestKeys) +} diff --git a/internal/engine/model/model_test.go b/internal/model/measurement_test.go similarity index 90% rename from internal/engine/model/model_test.go rename to internal/model/measurement_test.go index 18915be..efe7872 100644 --- a/internal/engine/model/model_test.go +++ b/internal/model/measurement_test.go @@ -1,4 +1,4 @@ -package model_test +package model import ( "bytes" @@ -6,12 +6,10 @@ import ( "errors" "fmt" "testing" - - "github.com/ooni/probe-cli/v3/internal/engine/model" ) func TestMeasurementTargetMarshalJSON(t *testing.T) { - var mt model.MeasurementTarget + var mt MeasurementTarget data, err := json.Marshal(mt) if err != nil { t.Fatal(err) @@ -35,7 +33,7 @@ type fakeTestKeys struct { } func TestAddAnnotations(t *testing.T) { - m := &model.Measurement{} + m := &Measurement{} m.AddAnnotations(map[string]string{ "foo": "bar", "f": "b", @@ -68,8 +66,8 @@ type makeMeasurementConfig struct { ResolverASN string } -func makeMeasurement(config makeMeasurementConfig) model.Measurement { - return model.Measurement{ +func makeMeasurement(config makeMeasurementConfig) Measurement { + return Measurement{ DataFormatVersion: "0.3.0", ID: "bdd20d7a-bba5-40dd-a111-9863d7908572", MeasurementStartTime: "2018-11-01 15:33:20", @@ -181,25 +179,25 @@ func TestScrubNoScrubbingRequired(t *testing.T) { if err != nil { t.Fatal(err) } - if bytes.Count(data, []byte(model.Scrubbed)) > 0 { + if bytes.Count(data, []byte(Scrubbed)) > 0 { t.Fatal("We should not see any scrubbing") } } func TestScrubInvalidIP(t *testing.T) { - m := &model.Measurement{ + m := &Measurement{ ProbeASN: "AS1234", ProbeCC: "IT", } err := m.Scrub("") // invalid IP - if !errors.Is(err, model.ErrInvalidProbeIP) { + if !errors.Is(err, ErrInvalidProbeIP) { t.Fatal("not the error we expected") } } func TestScrubMarshalError(t *testing.T) { expected := errors.New("mocked error") - m := &model.Measurement{ + m := &Measurement{ ProbeASN: "AS1234", ProbeCC: "IT", } @@ -211,13 +209,3 @@ func TestScrubMarshalError(t *testing.T) { t.Fatal("not the error we expected") } } - -func TestDiscardLoggerWorksAsIntended(t *testing.T) { - logger := model.DiscardLogger - logger.Debug("foo") - logger.Debugf("%s", "foo") - logger.Info("foo") - logger.Infof("%s", "foo") - logger.Warn("foo") - logger.Warnf("%s", "foo") -} diff --git a/internal/netxlite/mocks/dialer.go b/internal/model/mocks/dialer.go similarity index 100% rename from internal/netxlite/mocks/dialer.go rename to internal/model/mocks/dialer.go diff --git a/internal/netxlite/mocks/dialer_test.go b/internal/model/mocks/dialer_test.go similarity index 100% rename from internal/netxlite/mocks/dialer_test.go rename to internal/model/mocks/dialer_test.go diff --git a/internal/netxlite/mocks/dnsdecoder.go b/internal/model/mocks/dnsdecoder.go similarity index 61% rename from internal/netxlite/mocks/dnsdecoder.go rename to internal/model/mocks/dnsdecoder.go index 6e06916..fcff1c4 100644 --- a/internal/netxlite/mocks/dnsdecoder.go +++ b/internal/model/mocks/dnsdecoder.go @@ -1,15 +1,12 @@ package mocks -import "github.com/ooni/probe-cli/v3/internal/netxlite/dnsx" - -// HTTPSSvc is the result of HTTPS queries. -type HTTPSSvc = dnsx.HTTPSSvc +import "github.com/ooni/probe-cli/v3/internal/model" // DNSDecoder allows mocking dnsx.DNSDecoder. type DNSDecoder struct { MockDecodeLookupHost func(qtype uint16, reply []byte) ([]string, error) - MockDecodeHTTPS func(reply []byte) (*HTTPSSvc, error) + MockDecodeHTTPS func(reply []byte) (*model.HTTPSSvc, error) } // DecodeLookupHost calls MockDecodeLookupHost. @@ -18,6 +15,6 @@ func (e *DNSDecoder) DecodeLookupHost(qtype uint16, reply []byte) ([]string, err } // DecodeHTTPS calls MockDecodeHTTPS. -func (e *DNSDecoder) DecodeHTTPS(reply []byte) (*HTTPSSvc, error) { +func (e *DNSDecoder) DecodeHTTPS(reply []byte) (*model.HTTPSSvc, error) { return e.MockDecodeHTTPS(reply) } diff --git a/internal/netxlite/mocks/dnsdecoder_test.go b/internal/model/mocks/dnsdecoder_test.go similarity index 88% rename from internal/netxlite/mocks/dnsdecoder_test.go rename to internal/model/mocks/dnsdecoder_test.go index 0d646ff..3ca6d21 100644 --- a/internal/netxlite/mocks/dnsdecoder_test.go +++ b/internal/model/mocks/dnsdecoder_test.go @@ -5,6 +5,7 @@ import ( "testing" "github.com/miekg/dns" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestDNSDecoder(t *testing.T) { @@ -27,7 +28,7 @@ func TestDNSDecoder(t *testing.T) { t.Run("DecodeHTTPS", func(t *testing.T) { expected := errors.New("mocked error") e := &DNSDecoder{ - MockDecodeHTTPS: func(reply []byte) (*HTTPSSvc, error) { + MockDecodeHTTPS: func(reply []byte) (*model.HTTPSSvc, error) { return nil, expected }, } diff --git a/internal/netxlite/mocks/dnsencoder.go b/internal/model/mocks/dnsencoder.go similarity index 100% rename from internal/netxlite/mocks/dnsencoder.go rename to internal/model/mocks/dnsencoder.go diff --git a/internal/netxlite/mocks/dnsencoder_test.go b/internal/model/mocks/dnsencoder_test.go similarity index 100% rename from internal/netxlite/mocks/dnsencoder_test.go rename to internal/model/mocks/dnsencoder_test.go diff --git a/internal/netxlite/mocks/dnstransport.go b/internal/model/mocks/dnstransport.go similarity index 100% rename from internal/netxlite/mocks/dnstransport.go rename to internal/model/mocks/dnstransport.go diff --git a/internal/netxlite/mocks/dnstransport_test.go b/internal/model/mocks/dnstransport_test.go similarity index 100% rename from internal/netxlite/mocks/dnstransport_test.go rename to internal/model/mocks/dnstransport_test.go diff --git a/internal/model/mocks/doc.go b/internal/model/mocks/doc.go new file mode 100644 index 0000000..2ce3ff4 --- /dev/null +++ b/internal/model/mocks/doc.go @@ -0,0 +1,2 @@ +// Package mocks contains mocks for internal/model interfaces. +package mocks diff --git a/internal/netxlite/mocks/http.go b/internal/model/mocks/http.go similarity index 100% rename from internal/netxlite/mocks/http.go rename to internal/model/mocks/http.go diff --git a/internal/netxlite/mocks/http_test.go b/internal/model/mocks/http_test.go similarity index 100% rename from internal/netxlite/mocks/http_test.go rename to internal/model/mocks/http_test.go diff --git a/internal/netxlite/mocks/listener.go b/internal/model/mocks/listener.go similarity index 100% rename from internal/netxlite/mocks/listener.go rename to internal/model/mocks/listener.go diff --git a/internal/netxlite/mocks/listener_test.go b/internal/model/mocks/listener_test.go similarity index 100% rename from internal/netxlite/mocks/listener_test.go rename to internal/model/mocks/listener_test.go diff --git a/internal/netxlite/mocks/logger.go b/internal/model/mocks/logger.go similarity index 100% rename from internal/netxlite/mocks/logger.go rename to internal/model/mocks/logger.go diff --git a/internal/netxlite/mocks/logger_test.go b/internal/model/mocks/logger_test.go similarity index 100% rename from internal/netxlite/mocks/logger_test.go rename to internal/model/mocks/logger_test.go diff --git a/internal/netxlite/mocks/quic.go b/internal/model/mocks/quic.go similarity index 96% rename from internal/netxlite/mocks/quic.go rename to internal/model/mocks/quic.go index 6cac16c..23fe9a4 100644 --- a/internal/netxlite/mocks/quic.go +++ b/internal/model/mocks/quic.go @@ -8,16 +8,16 @@ import ( "time" "github.com/lucas-clemente/quic-go" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + "github.com/ooni/probe-cli/v3/internal/model" ) // QUICListener is a mockable netxlite.QUICListener. type QUICListener struct { - MockListen func(addr *net.UDPAddr) (quicx.UDPLikeConn, error) + MockListen func(addr *net.UDPAddr) (model.UDPLikeConn, error) } // Listen calls MockListen. -func (ql *QUICListener) Listen(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { +func (ql *QUICListener) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { return ql.MockListen(addr) } @@ -153,7 +153,7 @@ type QUICUDPLikeConn struct { MockSetReadBuffer func(n int) error } -var _ quicx.UDPLikeConn = &QUICUDPLikeConn{} +var _ model.UDPLikeConn = &QUICUDPLikeConn{} // WriteTo calls MockWriteTo. func (c *QUICUDPLikeConn) WriteTo(p []byte, addr net.Addr) (int, error) { diff --git a/internal/netxlite/mocks/quic_test.go b/internal/model/mocks/quic_test.go similarity index 98% rename from internal/netxlite/mocks/quic_test.go rename to internal/model/mocks/quic_test.go index 4403889..30066b0 100644 --- a/internal/netxlite/mocks/quic_test.go +++ b/internal/model/mocks/quic_test.go @@ -12,14 +12,14 @@ import ( "github.com/google/go-cmp/cmp" "github.com/lucas-clemente/quic-go" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestQUICListenerListen(t *testing.T) { t.Run("Listen", func(t *testing.T) { expected := errors.New("mocked error") ql := &QUICListener{ - MockListen: func(addr *net.UDPAddr) (quicx.UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return nil, expected }, } diff --git a/internal/netxlite/mocks/reader.go b/internal/model/mocks/reader.go similarity index 100% rename from internal/netxlite/mocks/reader.go rename to internal/model/mocks/reader.go diff --git a/internal/netxlite/mocks/reader_test.go b/internal/model/mocks/reader_test.go similarity index 100% rename from internal/netxlite/mocks/reader_test.go rename to internal/model/mocks/reader_test.go diff --git a/internal/netxlite/mocks/resolver.go b/internal/model/mocks/resolver.go similarity index 90% rename from internal/netxlite/mocks/resolver.go rename to internal/model/mocks/resolver.go index 592a26a..909e197 100644 --- a/internal/netxlite/mocks/resolver.go +++ b/internal/model/mocks/resolver.go @@ -2,6 +2,8 @@ package mocks import ( "context" + + "github.com/ooni/probe-cli/v3/internal/model" ) // Resolver is a mockable Resolver. @@ -10,7 +12,7 @@ type Resolver struct { MockNetwork func() string MockAddress func() string MockCloseIdleConnections func() - MockLookupHTTPS func(ctx context.Context, domain string) (*HTTPSSvc, error) + MockLookupHTTPS func(ctx context.Context, domain string) (*model.HTTPSSvc, error) } // LookupHost calls MockLookupHost. @@ -34,6 +36,6 @@ func (r *Resolver) CloseIdleConnections() { } // LookupHTTPS calls MockLookupHTTPS. -func (r *Resolver) LookupHTTPS(ctx context.Context, domain string) (*HTTPSSvc, error) { +func (r *Resolver) LookupHTTPS(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return r.MockLookupHTTPS(ctx, domain) } diff --git a/internal/netxlite/mocks/resolver_test.go b/internal/model/mocks/resolver_test.go similarity index 91% rename from internal/netxlite/mocks/resolver_test.go rename to internal/model/mocks/resolver_test.go index 5b6c144..4b6b4b8 100644 --- a/internal/netxlite/mocks/resolver_test.go +++ b/internal/model/mocks/resolver_test.go @@ -4,6 +4,8 @@ import ( "context" "errors" "testing" + + "github.com/ooni/probe-cli/v3/internal/model" ) func TestResolver(t *testing.T) { @@ -62,7 +64,7 @@ func TestResolver(t *testing.T) { t.Run("LookupHTTPS", func(t *testing.T) { expected := errors.New("mocked error") r := &Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, expected }, } diff --git a/internal/netxlite/mocks/tls.go b/internal/model/mocks/tls.go similarity index 100% rename from internal/netxlite/mocks/tls.go rename to internal/model/mocks/tls.go diff --git a/internal/netxlite/mocks/tls_test.go b/internal/model/mocks/tls_test.go similarity index 100% rename from internal/netxlite/mocks/tls_test.go rename to internal/model/mocks/tls_test.go diff --git a/internal/model/netx.go b/internal/model/netx.go new file mode 100644 index 0000000..fa21482 --- /dev/null +++ b/internal/model/netx.go @@ -0,0 +1,249 @@ +package model + +import ( + "context" + "crypto/tls" + "net" + "net/http" + "syscall" + "time" + + "github.com/lucas-clemente/quic-go" +) + +// +// Network extensions +// + +// The DNSDecoder decodes DNS replies. +type DNSDecoder interface { + // DecodeLookupHost decodes an A or AAAA reply. + // + // Arguments: + // + // - qtype is the query type (e.g., dns.TypeAAAA) + // + // - data contains the reply bytes read from a DNSTransport + // + // Returns: + // + // - on success, a list of IP addrs inside the reply and a nil error + // + // - on failure, a nil list and an error. + // + // Note that this function will return an error if there is no + // IP address inside of the reply. + DecodeLookupHost(qtype uint16, data []byte) ([]string, error) + + // DecodeHTTPS decodes an HTTPS reply. + // + // The argument is the reply as read by the DNSTransport. + // + // On success, this function returns an HTTPSSvc structure and + // a nil error. On failure, the HTTPSSvc pointer is nil and + // the error points to the error that occurred. + // + // This function will return an error if the HTTPS reply does not + // contain at least a valid ALPN entry. It will not return + // an error, though, when there are no IPv4/IPv6 hints in the reply. + DecodeHTTPS(data []byte) (*HTTPSSvc, error) +} + +// The DNSEncoder encodes DNS queries to bytes +type DNSEncoder interface { + // Encode transforms its arguments into a serialized DNS query. + // + // Arguments: + // + // - domain is the domain for the query (e.g., x.org); + // + // - qtype is the query type (e.g., dns.TypeA); + // + // - padding is whether to add padding to the query. + // + // On success, this function returns a valid byte array and + // a nil error. On failure, we have an error and the byte array is nil. + Encode(domain string, qtype uint16, padding bool) ([]byte, error) +} + +// DNSTransport represents an abstract DNS transport. +type DNSTransport interface { + // RoundTrip sends a DNS query and receives the reply. + RoundTrip(ctx context.Context, query []byte) (reply []byte, err error) + + // RequiresPadding returns whether this transport needs padding. + RequiresPadding() bool + + // Network is the network of the round tripper (e.g. "dot"). + Network() string + + // Address is the address of the round tripper (e.g. "1.1.1.1:853"). + Address() string + + // CloseIdleConnections closes idle connections, if any. + CloseIdleConnections() +} + +// SimpleDialer establishes network connections. +type SimpleDialer interface { + // DialContext behaves like net.Dialer.DialContext. + DialContext(ctx context.Context, network, address string) (net.Conn, error) +} + +// Dialer is a SimpleDialer with the possibility of closing open connections. +type Dialer interface { + // A Dialer is also a SimpleDialer. + SimpleDialer + + // CloseIdleConnections closes idle connections, if any. + CloseIdleConnections() +} + +// HTTPClient is an http.Client-like interface. +type HTTPClient interface { + Do(req *http.Request) (*http.Response, error) + CloseIdleConnections() +} + +// HTTPTransport is an http.Transport-like structure. +type HTTPTransport interface { + // RoundTrip performs the HTTP round trip. + RoundTrip(req *http.Request) (*http.Response, error) + + // CloseIdleConnections closes idle connections. + CloseIdleConnections() +} + +// HTTPSSvc is the reply to an HTTPS DNS query. +type HTTPSSvc struct { + // ALPN contains the ALPNs inside the HTTPS reply. + ALPN []string + + // IPv4 contains the IPv4 hints (which may be empty). + IPv4 []string + + // IPv6 contains the IPv6 hints (which may be empty). + IPv6 []string +} + +// QUICListener listens for QUIC connections. +type QUICListener interface { + // Listen creates a new listening UDPLikeConn. + Listen(addr *net.UDPAddr) (UDPLikeConn, error) +} + +// QUICDialer dials QUIC sessions. +type QUICDialer interface { + // DialContext establishes a new QUIC session using the given + // network and address. The tlsConfig and the quicConfig arguments + // MUST NOT be nil. Returns either the session or an error. + // + // Recommended tlsConfig setup: + // + // - set ServerName to be the SNI; + // + // - set RootCAs to NewDefaultCertPool(); + // + // - set NextProtos to []string{"h3"}. + // + // Typically, you want to pass `&quic.Config{}` as quicConfig. + DialContext(ctx context.Context, network, address string, + tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlySession, error) + + // CloseIdleConnections closes idle connections, if any. + CloseIdleConnections() +} + +// Resolver performs domain name resolutions. +type Resolver interface { + // LookupHost behaves like net.Resolver.LookupHost. + LookupHost(ctx context.Context, hostname string) (addrs []string, err error) + + // Network returns the resolver type (e.g., system, dot, doh). + Network() string + + // Address returns the resolver address (e.g., 8.8.8.8:53). + Address() string + + // CloseIdleConnections closes idle connections, if any. + CloseIdleConnections() + + // LookupHTTPS issues an HTTPS query for a domain. + LookupHTTPS( + ctx context.Context, domain string) (*HTTPSSvc, error) +} + +// TLSDialer is a Dialer dialing TLS connections. +type TLSDialer interface { + // CloseIdleConnections closes idle connections, if any. + CloseIdleConnections() + + // DialTLSContext dials a TLS connection. This method will always return + // to you a oohttp.TLSConn, so you can always safely cast to it. + DialTLSContext(ctx context.Context, network, address string) (net.Conn, error) +} + +// TLSHandshaker is the generic TLS handshaker. +type TLSHandshaker interface { + // Handshake creates a new TLS connection from the given connection and + // the given config. This function DOES NOT take ownership of the connection + // and it's your responsibility to close it on failure. + // + // Recommended tlsConfig setup: + // + // - set ServerName to be the SNI; + // + // - set RootCAs to NewDefaultCertPool(); + // + // - set NextProtos to []string{"h2", "http/1.1"} for HTTPS + // and []string{"dot"} for DNS-over-TLS. + // + // QUIRK: The returned connection will always implement the TLSConn interface + // exposed by ooni/oohttp. A future version of this interface may instead + // return directly a TLSConn to avoid unconditional castings. + Handshake(ctx context.Context, conn net.Conn, tlsConfig *tls.Config) ( + net.Conn, tls.ConnectionState, error) +} + +// UDPLikeConn is a net.PacketConn with some extra functions +// required to convince the QUIC library (lucas-clemente/quic-go) +// to inflate the receive buffer of the connection. +// +// The QUIC library will treat this connection as a "dumb" +// net.PacketConn, calling its ReadFrom and WriteTo methods +// as opposed to more efficient methods that are available +// under Linux and (maybe?) FreeBSD. +// +// It seems fine to avoid performance optimizations, because +// they would complicate the implementation on our side and +// our use cases (blocking and heavy throttling) do not seem +// to require such optimizations. +// +// See https://github.com/ooni/probe/issues/1754 for a more +// comprehensive discussion of UDPLikeConn. +type UDPLikeConn interface { + // An UDPLikeConn is a net.PacketConn conn. + net.PacketConn + + // SetReadBuffer allows setting the read buffer. + SetReadBuffer(bytes int) error + + // SyscallConn returns a conn suitable for calling syscalls, + // which is also instrumental to setting the read buffer. + SyscallConn() (syscall.RawConn, error) +} + +// UnderlyingNetworkLibrary defines the basic functionality from +// which the network extensions depend. By changing the default +// implementation of this interface, we can implement a wide array +// of tests, including self censorship tests. +type UnderlyingNetworkLibrary interface { + // ListenUDP creates a new model.UDPLikeConn conn. + ListenUDP(network string, laddr *net.UDPAddr) (UDPLikeConn, error) + + // LookupHost lookups a domain using the stdlib resolver. + LookupHost(ctx context.Context, domain string) ([]string, error) + + // NewSimpleDialer returns a new SimpleDialer. + NewSimpleDialer(timeout time.Duration) SimpleDialer +} diff --git a/internal/model/ooapi.go b/internal/model/ooapi.go new file mode 100644 index 0000000..6d43433 --- /dev/null +++ b/internal/model/ooapi.go @@ -0,0 +1,84 @@ +package model + +// +// Data structures used to speak with the OONI API. +// + +// OOAPICheckInConfigWebConnectivity is the configuration for the WebConnectivity test +type OOAPICheckInConfigWebConnectivity struct { + CategoryCodes []string `json:"category_codes"` // CategoryCodes is an array of category codes +} + +// OOAPICheckInConfig contains configuration for calling the checkin API. +type OOAPICheckInConfig struct { + Charging bool `json:"charging"` // Charging indicate if the phone is actually charging + OnWiFi bool `json:"on_wifi"` // OnWiFi indicate if the phone is actually connected to a WiFi network + Platform string `json:"platform"` // Platform of the probe + ProbeASN string `json:"probe_asn"` // ProbeASN is the probe country code + ProbeCC string `json:"probe_cc"` // ProbeCC is the probe country code + RunType string `json:"run_type"` // RunType + SoftwareName string `json:"software_name"` // SoftwareName of the probe + SoftwareVersion string `json:"software_version"` // SoftwareVersion of the probe + WebConnectivity OOAPICheckInConfigWebConnectivity `json:"web_connectivity"` // WebConnectivity class contain an array of categories +} + +// OOAPICheckInInfoWebConnectivity contains the array of URLs returned by the checkin API +type OOAPICheckInInfoWebConnectivity struct { + ReportID string `json:"report_id"` + URLs []OOAPIURLInfo `json:"urls"` +} + +// OOAPICheckInInfo contains the return test objects from the checkin API +type OOAPICheckInInfo struct { + WebConnectivity *OOAPICheckInInfoWebConnectivity `json:"web_connectivity"` +} + +// OOAPIService describes a backend service. +// +// The fields of this struct have the meaning described in v2.0.0 of the OONI +// bouncer specification defined by +// https://github.com/ooni/spec/blob/master/backends/bk-004-bouncer.md. +type OOAPIService struct { + // Address is the address of the server. + Address string `json:"address"` + + // Type is the type of the service. + Type string `json:"type"` + + // Front is the front to use with "cloudfront" type entries. + Front string `json:"front,omitempty"` +} + +// OOAPITorTarget is a target for the tor experiment. +type OOAPITorTarget struct { + // Address is the address of the target. + Address string `json:"address"` + + // Name is the name of the target. + Name string `json:"name"` + + // Params contains optional params for, e.g., pluggable transports. + Params map[string][]string `json:"params"` + + // Protocol is the protocol to use with the target. + Protocol string `json:"protocol"` + + // Source is the source from which we fetched this specific + // target. Whenever the source is non-empty, we will treat + // this specific target as a private target. + Source string `json:"source"` +} + +// OOAPIURLInfo contains info on a test lists URL +type OOAPIURLInfo struct { + CategoryCode string `json:"category_code"` + CountryCode string `json:"country_code"` + URL string `json:"url"` +} + +// OOAPIURLListConfig contains configuration for fetching the URL list. +type OOAPIURLListConfig struct { + Categories []string // Categories to query for (empty means all) + CountryCode string // CountryCode is the optional country code + Limit int64 // Max number of URLs (<= 0 means no limit) +} diff --git a/internal/netxlite/dialer.go b/internal/netxlite/dialer.go index 791a605..07eb2d0 100644 --- a/internal/netxlite/dialer.go +++ b/internal/netxlite/dialer.go @@ -6,19 +6,12 @@ import ( "net" "sync" "time" + + "github.com/ooni/probe-cli/v3/internal/model" ) -// Dialer establishes network connections. -type Dialer interface { - // DialContext behaves like net.Dialer.DialContext. - DialContext(ctx context.Context, network, address string) (net.Conn, error) - - // CloseIdleConnections closes idle connections, if any. - CloseIdleConnections() -} - // NewDialerWithResolver calls WrapDialer for the stdlib dialer. -func NewDialerWithResolver(logger Logger, resolver Resolver) Dialer { +func NewDialerWithResolver(logger model.DebugLogger, resolver model.Resolver) model.Dialer { return WrapDialer(logger, resolver, &dialerSystem{}) } @@ -51,26 +44,26 @@ func NewDialerWithResolver(logger Logger, resolver Resolver) Dialer { // // In general, do not use WrapDialer directly but try to use // more high-level factories, e.g., NewDialerWithResolver. -func WrapDialer(logger Logger, resolver Resolver, dialer Dialer) Dialer { +func WrapDialer(logger model.DebugLogger, resolver model.Resolver, dialer model.Dialer) model.Dialer { return &dialerLogger{ Dialer: &dialerResolver{ Dialer: &dialerLogger{ Dialer: &dialerErrWrapper{ Dialer: dialer, }, - Logger: logger, + DebugLogger: logger, operationSuffix: "_address", }, Resolver: resolver, }, - Logger: logger, + DebugLogger: logger, } } // NewDialerWithoutResolver calls NewDialerWithResolver with a "null" resolver. // // The returned dialer fails with ErrNoResolver if passed a domain name. -func NewDialerWithoutResolver(logger Logger) Dialer { +func NewDialerWithoutResolver(logger model.DebugLogger) model.Dialer { return NewDialerWithResolver(logger, &nullResolver{}) } @@ -81,16 +74,16 @@ type dialerSystem struct { timeout time.Duration } -var _ Dialer = &dialerSystem{} +var _ model.Dialer = &dialerSystem{} const dialerDefaultTimeout = 15 * time.Second -func (d *dialerSystem) newUnderlyingDialer() TProxyDialer { +func (d *dialerSystem) newUnderlyingDialer() model.SimpleDialer { t := d.timeout if t <= 0 { t = dialerDefaultTimeout } - return TProxy.NewTProxyDialer(t) + return TProxy.NewSimpleDialer(t) } func (d *dialerSystem) DialContext(ctx context.Context, network, address string) (net.Conn, error) { @@ -103,11 +96,11 @@ func (d *dialerSystem) CloseIdleConnections() { // dialerResolver combines dialing with domain name resolution. type dialerResolver struct { - Dialer - Resolver + model.Dialer + model.Resolver } -var _ Dialer = &dialerResolver{} +var _ model.Dialer = &dialerResolver{} func (d *dialerResolver) DialContext(ctx context.Context, network, address string) (net.Conn, error) { // QUIRK: this routine and the related routines in quirks.go cannot @@ -151,10 +144,10 @@ func (d *dialerResolver) CloseIdleConnections() { // dialerLogger is a Dialer with logging. type dialerLogger struct { // Dialer is the underlying dialer. - Dialer + model.Dialer // Logger is the underlying logger. - Logger + model.DebugLogger // operationSuffix is appended to the operation name. // @@ -165,19 +158,19 @@ type dialerLogger struct { operationSuffix string } -var _ Dialer = &dialerLogger{} +var _ model.Dialer = &dialerLogger{} func (d *dialerLogger) DialContext(ctx context.Context, network, address string) (net.Conn, error) { - d.Logger.Debugf("dial%s %s/%s...", d.operationSuffix, address, network) + d.DebugLogger.Debugf("dial%s %s/%s...", d.operationSuffix, address, network) start := time.Now() conn, err := d.Dialer.DialContext(ctx, network, address) elapsed := time.Since(start) if err != nil { - d.Logger.Debugf("dial%s %s/%s... %s in %s", d.operationSuffix, + d.DebugLogger.Debugf("dial%s %s/%s... %s in %s", d.operationSuffix, address, network, err, elapsed) return nil, err } - d.Logger.Debugf("dial%s %s/%s... ok in %s", d.operationSuffix, + d.DebugLogger.Debugf("dial%s %s/%s... ok in %s", d.operationSuffix, address, network, elapsed) return conn, nil } @@ -195,7 +188,7 @@ var ErrNoConnReuse = errors.New("cannot reuse connection") // dial will succed and return conn regardless of the network // and address arguments passed to DialContext. Any subsequent // dial returns ErrNoConnReuse. -func NewSingleUseDialer(conn net.Conn) Dialer { +func NewSingleUseDialer(conn net.Conn) model.Dialer { return &dialerSingleUse{conn: conn} } @@ -205,7 +198,7 @@ type dialerSingleUse struct { conn net.Conn } -var _ Dialer = &dialerSingleUse{} +var _ model.Dialer = &dialerSingleUse{} func (s *dialerSingleUse) DialContext(ctx context.Context, network string, addr string) (net.Conn, error) { defer s.Unlock() @@ -225,10 +218,10 @@ func (s *dialerSingleUse) CloseIdleConnections() { // dialerErrWrapper is a dialer that performs error wrapping. The connection // returned by the DialContext function will also perform error wrapping. type dialerErrWrapper struct { - Dialer + model.Dialer } -var _ Dialer = &dialerErrWrapper{} +var _ model.Dialer = &dialerErrWrapper{} func (d *dialerErrWrapper) DialContext(ctx context.Context, network, address string) (net.Conn, error) { conn, err := d.Dialer.DialContext(ctx, network, address) @@ -274,13 +267,13 @@ func (c *dialerErrWrapperConn) Close() error { var ErrNoDialer = errors.New("no configured dialer") // NewNullDialer returns a dialer that always fails with ErrNoDialer. -func NewNullDialer() Dialer { +func NewNullDialer() model.Dialer { return &nullDialer{} } type nullDialer struct{} -var _ Dialer = &nullDialer{} +var _ model.Dialer = &nullDialer{} func (*nullDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) { return nil, ErrNoDialer diff --git a/internal/netxlite/dialer_test.go b/internal/netxlite/dialer_test.go index cdd275f..2031046 100644 --- a/internal/netxlite/dialer_test.go +++ b/internal/netxlite/dialer_test.go @@ -11,14 +11,14 @@ import ( "time" "github.com/apex/log" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestNewDialer(t *testing.T) { t.Run("produces a chain with the expected types", func(t *testing.T) { d := NewDialerWithoutResolver(log.Log) logger := d.(*dialerLogger) - if logger.Logger != log.Log { + if logger.DebugLogger != log.Log { t.Fatal("invalid logger") } reso := logger.Dialer.(*dialerResolver) @@ -26,7 +26,7 @@ func TestNewDialer(t *testing.T) { t.Fatal("invalid Resolver type") } logger = reso.Dialer.(*dialerLogger) - if logger.Logger != log.Log { + if logger.DebugLogger != log.Log { t.Fatal("invalid logger") } errWrapper := logger.Dialer.(*dialerErrWrapper) @@ -406,7 +406,7 @@ func TestDialerLogger(t *testing.T) { }, nil }, }, - Logger: lo, + DebugLogger: lo, } conn, err := d.DialContext(context.Background(), "tcp", "www.google.com:443") if err != nil { @@ -434,7 +434,7 @@ func TestDialerLogger(t *testing.T) { return nil, io.EOF }, }, - Logger: lo, + DebugLogger: lo, } conn, err := d.DialContext(context.Background(), "tcp", "www.google.com:443") if !errors.Is(err, io.EOF) { diff --git a/internal/netxlite/dnsdecoder.go b/internal/netxlite/dnsdecoder.go index a7117b6..fda5a47 100644 --- a/internal/netxlite/dnsdecoder.go +++ b/internal/netxlite/dnsdecoder.go @@ -1,40 +1,9 @@ package netxlite -import "github.com/miekg/dns" - -// The DNSDecoder decodes DNS replies. -type DNSDecoder interface { - // DecodeLookupHost decodes an A or AAAA reply. - // - // Arguments: - // - // - qtype is the query type (e.g., dns.TypeAAAA) - // - // - data contains the reply bytes read from a DNSTransport - // - // Returns: - // - // - on success, a list of IP addrs inside the reply and a nil error - // - // - on failure, a nil list and an error. - // - // Note that this function will return an error if there is no - // IP address inside of the reply. - DecodeLookupHost(qtype uint16, data []byte) ([]string, error) - - // DecodeHTTPS decodes an HTTPS reply. - // - // The argument is the reply as read by the DNSTransport. - // - // On success, this function returns an HTTPSSvc structure and - // a nil error. On failure, the HTTPSSvc pointer is nil and - // the error points to the error that occurred. - // - // This function will return an error if the HTTPS reply does not - // contain at least a valid ALPN entry. It will not return - // an error, though, when there are no IPv4/IPv6 hints in the reply. - DecodeHTTPS(data []byte) (*HTTPSSvc, error) -} +import ( + "github.com/miekg/dns" + "github.com/ooni/probe-cli/v3/internal/model" +) // DNSDecoderMiekg uses github.com/miekg/dns to implement the Decoder. type DNSDecoderMiekg struct{} @@ -58,12 +27,12 @@ func (d *DNSDecoderMiekg) parseReply(data []byte) (*dns.Msg, error) { } } -func (d *DNSDecoderMiekg) DecodeHTTPS(data []byte) (*HTTPSSvc, error) { +func (d *DNSDecoderMiekg) DecodeHTTPS(data []byte) (*model.HTTPSSvc, error) { reply, err := d.parseReply(data) if err != nil { return nil, err } - out := &HTTPSSvc{} + out := &model.HTTPSSvc{} for _, answer := range reply.Answer { switch avalue := answer.(type) { case *dns.HTTPS: @@ -115,4 +84,4 @@ func (d *DNSDecoderMiekg) DecodeLookupHost(qtype uint16, data []byte) ([]string, return addrs, nil } -var _ DNSDecoder = &DNSDecoderMiekg{} +var _ model.DNSDecoder = &DNSDecoderMiekg{} diff --git a/internal/netxlite/dnsencoder.go b/internal/netxlite/dnsencoder.go index 08844e4..dc5cdf4 100644 --- a/internal/netxlite/dnsencoder.go +++ b/internal/netxlite/dnsencoder.go @@ -1,23 +1,9 @@ package netxlite -import "github.com/miekg/dns" - -// The DNSEncoder encodes DNS queries to bytes -type DNSEncoder interface { - // Encode transforms its arguments into a serialized DNS query. - // - // Arguments: - // - // - domain is the domain for the query (e.g., x.org); - // - // - qtype is the query type (e.g., dns.TypeA); - // - // - padding is whether to add padding to the query. - // - // On success, this function returns a valid byte array and - // a nil error. On failure, we have an error and the byte array is nil. - Encode(domain string, qtype uint16, padding bool) ([]byte, error) -} +import ( + "github.com/miekg/dns" + "github.com/ooni/probe-cli/v3/internal/model" +) // DNSEncoderMiekg uses github.com/miekg/dns to implement the Encoder. type DNSEncoderMiekg struct{} @@ -60,4 +46,4 @@ func (e *DNSEncoderMiekg) Encode(domain string, qtype uint16, padding bool) ([]b return query.Pack() } -var _ DNSEncoder = &DNSEncoderMiekg{} +var _ model.DNSEncoder = &DNSEncoderMiekg{} diff --git a/internal/netxlite/dnsoverhttps.go b/internal/netxlite/dnsoverhttps.go index e9caa27..5b049c6 100644 --- a/internal/netxlite/dnsoverhttps.go +++ b/internal/netxlite/dnsoverhttps.go @@ -8,12 +8,13 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" + "github.com/ooni/probe-cli/v3/internal/model" ) // DNSOverHTTPS is a DNS-over-HTTPS DNSTransport. type DNSOverHTTPS struct { // Client is the MANDATORY http client to use. - Client HTTPClient + Client model.HTTPClient // URL is the MANDATORY URL of the DNS-over-HTTPS server. URL string @@ -30,14 +31,14 @@ type DNSOverHTTPS struct { // - client in http.Client-like type (e.g., http.DefaultClient); // // - URL is the DoH resolver URL (e.g., https://1.1.1.1/dns-query). -func NewDNSOverHTTPS(client HTTPClient, URL string) *DNSOverHTTPS { +func NewDNSOverHTTPS(client model.HTTPClient, URL string) *DNSOverHTTPS { return NewDNSOverHTTPSWithHostOverride(client, URL, "") } // NewDNSOverHTTPSWithHostOverride creates a new DNSOverHTTPS // with the given Host header override. func NewDNSOverHTTPSWithHostOverride( - client HTTPClient, URL, hostOverride string) *DNSOverHTTPS { + client model.HTTPClient, URL, hostOverride string) *DNSOverHTTPS { return &DNSOverHTTPS{Client: client, URL: URL, HostOverride: hostOverride} } @@ -89,4 +90,4 @@ func (t *DNSOverHTTPS) CloseIdleConnections() { t.Client.CloseIdleConnections() } -var _ DNSTransport = &DNSOverHTTPS{} +var _ model.DNSTransport = &DNSOverHTTPS{} diff --git a/internal/netxlite/dnsoverhttps_test.go b/internal/netxlite/dnsoverhttps_test.go index c21b924..e750029 100644 --- a/internal/netxlite/dnsoverhttps_test.go +++ b/internal/netxlite/dnsoverhttps_test.go @@ -10,7 +10,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/engine/httpheader" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestDNSOverHTTPS(t *testing.T) { diff --git a/internal/netxlite/dnsovertcp.go b/internal/netxlite/dnsovertcp.go index 9f66a59..c9b5b5b 100644 --- a/internal/netxlite/dnsovertcp.go +++ b/internal/netxlite/dnsovertcp.go @@ -7,6 +7,8 @@ import ( "math" "net" "time" + + "github.com/ooni/probe-cli/v3/internal/model" ) // DialContextFunc is the type of net.Dialer.DialContext. @@ -108,4 +110,4 @@ func (t *DNSOverTCP) CloseIdleConnections() { // nothing to do } -var _ DNSTransport = &DNSOverTCP{} +var _ model.DNSTransport = &DNSOverTCP{} diff --git a/internal/netxlite/dnsovertcp_test.go b/internal/netxlite/dnsovertcp_test.go index 9c9c296..bdcd4e2 100644 --- a/internal/netxlite/dnsovertcp_test.go +++ b/internal/netxlite/dnsovertcp_test.go @@ -10,7 +10,7 @@ import ( "testing" "time" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestDNSOverTCP(t *testing.T) { diff --git a/internal/netxlite/dnsoverudp.go b/internal/netxlite/dnsoverudp.go index 2d66d4a..605149e 100644 --- a/internal/netxlite/dnsoverudp.go +++ b/internal/netxlite/dnsoverudp.go @@ -3,11 +3,13 @@ package netxlite import ( "context" "time" + + "github.com/ooni/probe-cli/v3/internal/model" ) // DNSOverUDP is a DNS-over-UDP DNSTransport. type DNSOverUDP struct { - dialer Dialer + dialer model.Dialer address string } @@ -18,7 +20,7 @@ type DNSOverUDP struct { // - dialer is any type that implements the Dialer interface; // // - address is the endpoint address (e.g., 8.8.8.8:53). -func NewDNSOverUDP(dialer Dialer, address string) *DNSOverUDP { +func NewDNSOverUDP(dialer model.Dialer, address string) *DNSOverUDP { return &DNSOverUDP{dialer: dialer, address: address} } @@ -66,4 +68,4 @@ func (t *DNSOverUDP) CloseIdleConnections() { // nothing to do } -var _ DNSTransport = &DNSOverUDP{} +var _ model.DNSTransport = &DNSOverUDP{} diff --git a/internal/netxlite/dnsoverudp_test.go b/internal/netxlite/dnsoverudp_test.go index ee3ca3b..2d8749e 100644 --- a/internal/netxlite/dnsoverudp_test.go +++ b/internal/netxlite/dnsoverudp_test.go @@ -9,7 +9,7 @@ import ( "time" "github.com/apex/log" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestDNSOverUDP(t *testing.T) { diff --git a/internal/netxlite/dnstransport.go b/internal/netxlite/dnstransport.go index cf7b8d5..33539e6 100644 --- a/internal/netxlite/dnstransport.go +++ b/internal/netxlite/dnstransport.go @@ -1,21 +1 @@ package netxlite - -import "context" - -// DNSTransport represents an abstract DNS transport. -type DNSTransport interface { - // RoundTrip sends a DNS query and receives the reply. - RoundTrip(ctx context.Context, query []byte) (reply []byte, err error) - - // RequiresPadding returns whether this transport needs padding. - RequiresPadding() bool - - // Network is the network of the round tripper (e.g. "dot"). - Network() string - - // Address is the address of the round tripper (e.g. "1.1.1.1:853"). - Address() string - - // CloseIdleConnections closes idle connections, if any. - CloseIdleConnections() -} diff --git a/internal/netxlite/dnsx/dnsx.go b/internal/netxlite/dnsx/dnsx.go deleted file mode 100644 index b78249f..0000000 --- a/internal/netxlite/dnsx/dnsx.go +++ /dev/null @@ -1,14 +0,0 @@ -// Package dnsx contains DNS extension types. -package dnsx - -// HTTPSSvc is the reply to an HTTPS DNS query. -type HTTPSSvc struct { - // ALPN contains the ALPNs inside the HTTPS reply. - ALPN []string - - // IPv4 contains the IPv4 hints (which may be empty). - IPv4 []string - - // IPv6 contains the IPv6 hints (which may be empty). - IPv6 []string -} diff --git a/internal/netxlite/doc.go b/internal/netxlite/doc.go index 2ce9e27..c5d01ed 100644 --- a/internal/netxlite/doc.go +++ b/internal/netxlite/doc.go @@ -3,6 +3,8 @@ // This package is the basic networking building block that you // should be using every time you need networking. // +// It implements interfaces defined in the internal/model package. +// // You should consider checking the tutorial explaining how to use this package // for network measurements: https://github.com/ooni/probe-cli/tree/master/internal/tutorial/netxlite. // diff --git a/internal/netxlite/filtering/dns_test.go b/internal/netxlite/filtering/dns_test.go index debd0a6..9e99a89 100644 --- a/internal/netxlite/filtering/dns_test.go +++ b/internal/netxlite/filtering/dns_test.go @@ -10,8 +10,9 @@ import ( "github.com/apex/log" "github.com/miekg/dns" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestDNSProxy(t *testing.T) { @@ -29,7 +30,7 @@ func TestDNSProxy(t *testing.T) { return newProxyWithCache(action, nil) } - newresolver := func(listener DNSListener) netxlite.Resolver { + newresolver := func(listener DNSListener) model.Resolver { dlr := netxlite.NewDialerWithoutResolver(log.Log) r := netxlite.NewResolverUDP(log.Log, dlr, listener.LocalAddr().String()) return r diff --git a/internal/netxlite/filtering/doc.go b/internal/netxlite/filtering/doc.go index 65018ab..e5febfa 100644 --- a/internal/netxlite/filtering/doc.go +++ b/internal/netxlite/filtering/doc.go @@ -1,7 +1,7 @@ // Package filtering allows to implement self-censorship. // -// The top-level struct is the TProxy. It implements netxlite's -// TProxable interface. Therefore, you can use TProxy to +// The top-level struct is the TProxy. It implements model's +// UnderlyingNetworkLibrary interface. Therefore, you can use TProxy to // implement filtering and blocking of TCP, TLS, QUIC, DNS, HTTP. // // We also expose proxies that implement filtering policies for diff --git a/internal/netxlite/filtering/logger.go b/internal/netxlite/filtering/logger.go deleted file mode 100644 index 65092d1..0000000 --- a/internal/netxlite/filtering/logger.go +++ /dev/null @@ -1,23 +0,0 @@ -package filtering - -// Logger defines the common interface that a logger should have. It is -// out of the box compatible with `log.Log` in `apex/log`. -type Logger interface { - // Debug emits a debug message. - Debug(msg string) - - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Info emits an informational message. - Info(msg string) - - // Infof formats and emits an informational message. - Infof(format string, v ...interface{}) - - // Warn emits a warning message. - Warn(msg string) - - // Warnf formats and emits a warning message. - Warnf(format string, v ...interface{}) -} diff --git a/internal/netxlite/filtering/tls_test.go b/internal/netxlite/filtering/tls_test.go index cbf25df..dded025 100644 --- a/internal/netxlite/filtering/tls_test.go +++ b/internal/netxlite/filtering/tls_test.go @@ -10,7 +10,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestTLSProxy(t *testing.T) { diff --git a/internal/netxlite/filtering/tproxy.go b/internal/netxlite/filtering/tproxy.go index 59fb03f..2ac3eec 100644 --- a/internal/netxlite/filtering/tproxy.go +++ b/internal/netxlite/filtering/tproxy.go @@ -10,8 +10,8 @@ import ( "time" "github.com/miekg/dns" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" ) // TProxyPolicy is a policy for TPRoxy. @@ -100,13 +100,13 @@ func (c *TProxyConfig) CanonicalizeDNS() { c.DNSCache = cache } -// TProxy is a netxlite.TProxable that implements self censorship. +// TProxy is a model.UnderlyingNetworkLibrary that implements self censorship. type TProxy struct { // config contains settings for TProxy. config *TProxyConfig // dnsClient is the DNS client we'll internally use. - dnsClient netxlite.Resolver + dnsClient model.Resolver // dnsListener is the DNS listener. dnsListener DNSListener @@ -115,10 +115,10 @@ type TProxy struct { httpListener net.Listener // listenUDP allows overriding net.ListenUDP calls in tests - listenUDP func(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) + listenUDP func(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) // logger is the underlying logger to use. - logger Logger + logger model.InfoLogger // tlsListener is the TLS listener. tlsListener net.Listener @@ -129,15 +129,15 @@ type TProxy struct { // // NewTProxy creates a new TProxy instance. -func NewTProxy(config *TProxyConfig, logger Logger) (*TProxy, error) { +func NewTProxy(config *TProxyConfig, logger model.InfoLogger) (*TProxy, error) { return newTProxy(config, logger, "127.0.0.1:0", "127.0.0.1:0", "127.0.0.1:0") } -func newTProxy(config *TProxyConfig, logger Logger, dnsListenerAddr, +func newTProxy(config *TProxyConfig, logger model.InfoLogger, dnsListenerAddr, tlsListenerAddr, httpListenerAddr string) (*TProxy, error) { p := &TProxy{ config: config, - listenUDP: func(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) { + listenUDP: func(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) { return net.ListenUDP(network, laddr) }, logger: logger, @@ -165,12 +165,12 @@ func (p *TProxy) newDNSListener(listenAddr string) error { return err } -func (p *TProxy) newDNSClient(logger Logger) { +func (p *TProxy) newDNSClient(logger model.DebugLogger) { dialer := netxlite.NewDialerWithoutResolver(logger) p.dnsClient = netxlite.NewResolverUDP(logger, dialer, p.dnsListener.LocalAddr().String()) } -func (p *TProxy) newTLSListener(listenAddr string, logger Logger) error { +func (p *TProxy) newTLSListener(listenAddr string, logger model.DebugLogger) error { var err error tlsProxy := &TLSProxy{OnIncomingSNI: p.onIncomingSNI} p.tlsListener, err = tlsProxy.Start(listenAddr) @@ -198,7 +198,7 @@ func (p *TProxy) Close() error { // // ListenUDP implements netxlite.TProxy.ListenUDP. -func (p *TProxy) ListenUDP(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) { +func (p *TProxy) ListenUDP(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) { pconn, err := p.listenUDP(network, laddr) if err != nil { return nil, err @@ -209,7 +209,7 @@ func (p *TProxy) ListenUDP(network string, laddr *net.UDPAddr) (quicx.UDPLikeCon // tProxyUDPLikeConn is a TProxy-aware UDPLikeConn. type tProxyUDPLikeConn struct { // UDPLikeConn is the underlying conn type. - quicx.UDPLikeConn + model.UDPLikeConn // proxy refers to the TProxy. proxy *TProxy @@ -242,8 +242,8 @@ func (p *TProxy) LookupHost(ctx context.Context, domain string) ([]string, error // Dialer // -// NewTProxyDialer implements netxlite.TProxy.NewTProxyDialer. -func (p *TProxy) NewTProxyDialer(timeout time.Duration) netxlite.TProxyDialer { +// NewSimpleDialer implements netxlite.TProxy.NewTProxyDialer. +func (p *TProxy) NewSimpleDialer(timeout time.Duration) model.SimpleDialer { return &tProxyDialer{ dialer: &net.Dialer{Timeout: timeout}, proxy: p, diff --git a/internal/netxlite/filtering/tproxy_test.go b/internal/netxlite/filtering/tproxy_test.go index aca4247..e4e99df 100644 --- a/internal/netxlite/filtering/tproxy_test.go +++ b/internal/netxlite/filtering/tproxy_test.go @@ -13,14 +13,14 @@ import ( "time" "github.com/apex/log" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) // tProxyDialerAdapter adapts a netxlite.TProxyDialer to be a netxlite.Dialer. type tProxyDialerAdapter struct { - netxlite.TProxyDialer + model.SimpleDialer } // CloseIdleConnections implements Dialer.CloseIdleConnections. @@ -158,7 +158,7 @@ func TestTProxyQUIC(t *testing.T) { } defer proxy.Close() var called bool - proxy.listenUDP = func(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) { + proxy.listenUDP = func(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) { return &mocks.QUICUDPLikeConn{ MockWriteTo: func(p []byte, addr net.Addr) (int, error) { called = true @@ -195,7 +195,7 @@ func TestTProxyQUIC(t *testing.T) { } defer proxy.Close() var called bool - proxy.listenUDP = func(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) { + proxy.listenUDP = func(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) { return &mocks.QUICUDPLikeConn{ MockWriteTo: func(p []byte, addr net.Addr) (int, error) { called = true @@ -280,7 +280,7 @@ func TestTProxyOnIncomingSNI(t *testing.T) { } defer proxy.Close() ctx := context.Background() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) conn, err := dialer.DialContext(ctx, "tcp", "8.8.8.8:443") if err != nil { t.Fatal(err) @@ -308,7 +308,7 @@ func TestTProxyOnIncomingSNI(t *testing.T) { } defer proxy.Close() ctx := context.Background() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) conn, err := dialer.DialContext(ctx, "tcp", "8.8.8.8:443") if err != nil { t.Fatal(err) @@ -337,7 +337,7 @@ func TestTProxyOnIncomingHost(t *testing.T) { t.Fatal(err) } defer proxy.Close() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) req, err := http.NewRequest("GET", "http://130.192.16.171:80", nil) if err != nil { t.Fatal(err) @@ -369,7 +369,7 @@ func TestTProxyOnIncomingHost(t *testing.T) { log.Log, netxlite.NewResolverStdlib(log.Log), &tProxyDialerAdapter{ - proxy.NewTProxyDialer(10 * time.Second), + proxy.NewSimpleDialer(10 * time.Second), }, ) req, err := http.NewRequest("GET", "http://130.192.16.171:80", nil) @@ -400,7 +400,7 @@ func TestTProxyDial(t *testing.T) { t.Fatal(err) } defer proxy.Close() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() req, err := http.NewRequestWithContext(ctx, "GET", "http://130.192.16.171:80", nil) @@ -432,7 +432,7 @@ func TestTProxyDial(t *testing.T) { dialer := netxlite.WrapDialer(log.Log, netxlite.NewResolverStdlib(log.Log), &tProxyDialerAdapter{ - proxy.NewTProxyDialer(10 * time.Second)}) + proxy.NewSimpleDialer(10 * time.Second)}) req, err := http.NewRequest("GET", "http://130.192.16.171:80", nil) if err != nil { t.Fatal(err) @@ -459,7 +459,7 @@ func TestTProxyDial(t *testing.T) { t.Fatal(err) } defer proxy.Close() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) defer cancel() req, err := http.NewRequestWithContext( @@ -492,7 +492,7 @@ func TestTProxyDial(t *testing.T) { t.Fatal(err) } defer proxy.Close() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) resolver := netxlite.NewResolverUDP( log.Log, &tProxyDialerAdapter{dialer}, "8.8.8.8:53") addrs, err := resolver.LookupHost(context.Background(), "example.com") @@ -511,7 +511,7 @@ func TestTProxyDial(t *testing.T) { t.Fatal(err) } defer proxy.Close() - dialer := proxy.NewTProxyDialer(10 * time.Second) + dialer := proxy.NewSimpleDialer(10 * time.Second) ctx := context.Background() conn, err := dialer.DialContext(ctx, "tcp", "127.0.0.1") if err == nil || !strings.HasSuffix(err.Error(), "missing port in address") { diff --git a/internal/netxlite/http.go b/internal/netxlite/http.go index fbd59d7..02ad5b8 100644 --- a/internal/netxlite/http.go +++ b/internal/netxlite/http.go @@ -8,20 +8,12 @@ import ( "time" oohttp "github.com/ooni/oohttp" + "github.com/ooni/probe-cli/v3/internal/model" ) -// HTTPTransport is an http.Transport-like structure. -type HTTPTransport interface { - // RoundTrip performs the HTTP round trip. - RoundTrip(req *http.Request) (*http.Response, error) - - // CloseIdleConnections closes idle connections. - CloseIdleConnections() -} - // httpTransportErrWrapper is an HTTPTransport with error wrapping. type httpTransportErrWrapper struct { - HTTPTransport + model.HTTPTransport } func (txp *httpTransportErrWrapper) RoundTrip(req *http.Request) (*http.Response, error) { @@ -35,13 +27,13 @@ func (txp *httpTransportErrWrapper) RoundTrip(req *http.Request) (*http.Response // httpTransportLogger is an HTTPTransport with logging. type httpTransportLogger struct { // HTTPTransport is the underlying HTTP transport. - HTTPTransport HTTPTransport + HTTPTransport model.HTTPTransport // Logger is the underlying logger. - Logger Logger + Logger model.DebugLogger } -var _ HTTPTransport = &httpTransportLogger{} +var _ model.HTTPTransport = &httpTransportLogger{} func (txp *httpTransportLogger) RoundTrip(req *http.Request) (*http.Response, error) { txp.Logger.Debugf("> %s %s", req.Method, req.URL.String()) @@ -73,9 +65,9 @@ func (txp *httpTransportLogger) CloseIdleConnections() { // httpTransportConnectionsCloser is an HTTPTransport that // correctly forwards CloseIdleConnections calls. type httpTransportConnectionsCloser struct { - HTTPTransport - Dialer - TLSDialer + model.HTTPTransport + model.Dialer + model.TLSDialer } // CloseIdleConnections forwards the CloseIdleConnections calls. @@ -89,7 +81,7 @@ func (txp *httpTransportConnectionsCloser) CloseIdleConnections() { // // This factory and NewHTTPTransportStdlib are the recommended // ways of creating a new HTTPTransport. -func NewHTTPTransport(logger Logger, dialer Dialer, tlsDialer TLSDialer) HTTPTransport { +func NewHTTPTransport(logger model.DebugLogger, dialer model.Dialer, tlsDialer model.TLSDialer) model.HTTPTransport { return WrapHTTPTransport(logger, NewOOHTTPBaseTransport(dialer, tlsDialer)) } @@ -117,7 +109,7 @@ func NewHTTPTransport(logger Logger, dialer Dialer, tlsDialer TLSDialer) HTTPTra // way in which we perform measurements. // // This is a low level factory. Consider not using it directly. -func NewOOHTTPBaseTransport(dialer Dialer, tlsDialer TLSDialer) HTTPTransport { +func NewOOHTTPBaseTransport(dialer model.Dialer, tlsDialer model.TLSDialer) model.HTTPTransport { // Using oohttp to support any TLS library. txp := oohttp.DefaultTransport.(*oohttp.Transport).Clone() @@ -158,7 +150,7 @@ func NewOOHTTPBaseTransport(dialer Dialer, tlsDialer TLSDialer) HTTPTransport { // and guarantees that returned errors are wrapped. // // This is a low level factory. Consider not using it directly. -func WrapHTTPTransport(logger Logger, txp HTTPTransport) HTTPTransport { +func WrapHTTPTransport(logger model.DebugLogger, txp model.HTTPTransport) model.HTTPTransport { return &httpTransportLogger{ HTTPTransport: &httpTransportErrWrapper{txp}, Logger: logger, @@ -168,7 +160,7 @@ func WrapHTTPTransport(logger Logger, txp HTTPTransport) HTTPTransport { // httpDialerWithReadTimeout enforces a read timeout for all HTTP // connections. See https://github.com/ooni/probe/issues/1609. type httpDialerWithReadTimeout struct { - Dialer + model.Dialer } // DialContext implements Dialer.DialContext. @@ -184,7 +176,7 @@ func (d *httpDialerWithReadTimeout) DialContext( // httpTLSDialerWithReadTimeout enforces a read timeout for all HTTP // connections. See https://github.com/ooni/probe/issues/1609. type httpTLSDialerWithReadTimeout struct { - TLSDialer + model.TLSDialer } // ErrNotTLSConn occur when an interface accepts a net.Conn but @@ -259,25 +251,19 @@ func (c *httpTLSConnWithReadTimeout) Read(b []byte) (int, error) { // // This factory and NewHTTPTransport are the recommended // ways of creating a new HTTPTransport. -func NewHTTPTransportStdlib(logger Logger) HTTPTransport { +func NewHTTPTransportStdlib(logger model.DebugLogger) model.HTTPTransport { dialer := NewDialerWithResolver(logger, NewResolverStdlib(logger)) tlsDialer := NewTLSDialer(dialer, NewTLSHandshakerStdlib(logger)) return NewHTTPTransport(logger, dialer, tlsDialer) } -// HTTPClient is an http.Client-like interface. -type HTTPClient interface { - Do(req *http.Request) (*http.Response, error) - CloseIdleConnections() -} - // WrapHTTPClient wraps an HTTP client to add error wrapping capabilities. -func WrapHTTPClient(clnt HTTPClient) HTTPClient { +func WrapHTTPClient(clnt model.HTTPClient) model.HTTPClient { return &httpClientErrWrapper{clnt} } type httpClientErrWrapper struct { - HTTPClient + model.HTTPClient } func (c *httpClientErrWrapper) Do(req *http.Request) (*http.Response, error) { diff --git a/internal/netxlite/http3.go b/internal/netxlite/http3.go index 69217d6..281e30f 100644 --- a/internal/netxlite/http3.go +++ b/internal/netxlite/http3.go @@ -8,13 +8,14 @@ import ( "github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go/http3" + "github.com/ooni/probe-cli/v3/internal/model" ) // http3Dialer adapts a QUICContextDialer to work with // an http3.RoundTripper. This is necessary because the // http3.RoundTripper does not support DialContext. type http3Dialer struct { - QUICDialer + model.QUICDialer } // dial is like QUICContextDialer.DialContext but without context. @@ -33,10 +34,10 @@ type http3RoundTripper interface { // http3Transport is an HTTPTransport using the http3 protocol. type http3Transport struct { child http3RoundTripper - dialer QUICDialer + dialer model.QUICDialer } -var _ HTTPTransport = &http3Transport{} +var _ model.HTTPTransport = &http3Transport{} // RoundTrip implements HTTPTransport.RoundTrip. func (txp *http3Transport) RoundTrip(req *http.Request) (*http.Response, error) { @@ -53,7 +54,7 @@ func (txp *http3Transport) CloseIdleConnections() { // dialer argument MUST NOT be nil. If the tlsConfig argument is nil, // then the code will use the default TLS configuration. func NewHTTP3Transport( - logger Logger, dialer QUICDialer, tlsConfig *tls.Config) HTTPTransport { + logger model.DebugLogger, dialer model.QUICDialer, tlsConfig *tls.Config) model.HTTPTransport { return &httpTransportLogger{ HTTPTransport: &http3Transport{ child: &http3.RoundTripper{ diff --git a/internal/netxlite/http3_test.go b/internal/netxlite/http3_test.go index c4e0bd2..d4a1af0 100644 --- a/internal/netxlite/http3_test.go +++ b/internal/netxlite/http3_test.go @@ -10,7 +10,8 @@ import ( "github.com/apex/log" "github.com/lucas-clemente/quic-go" "github.com/lucas-clemente/quic-go/http3" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" + nlmocks "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" ) func TestHTTP3Dialer(t *testing.T) { @@ -40,7 +41,7 @@ func TestHTTP3Transport(t *testing.T) { calledDialer bool ) txp := &http3Transport{ - child: &mocks.HTTP3RoundTripper{ + child: &nlmocks.HTTP3RoundTripper{ MockClose: func() error { calledHTTP3 = true return nil @@ -61,7 +62,7 @@ func TestHTTP3Transport(t *testing.T) { t.Run("RoundTrip", func(t *testing.T) { expected := errors.New("mocked error") txp := &http3Transport{ - child: &mocks.HTTP3RoundTripper{ + child: &nlmocks.HTTP3RoundTripper{ MockRoundTrip: func(req *http.Request) (*http.Response, error) { return nil, expected }, diff --git a/internal/netxlite/http_test.go b/internal/netxlite/http_test.go index 8009f60..a835af5 100644 --- a/internal/netxlite/http_test.go +++ b/internal/netxlite/http_test.go @@ -13,7 +13,7 @@ import ( "github.com/apex/log" oohttp "github.com/ooni/oohttp" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestHTTPTransportErrWrapper(t *testing.T) { diff --git a/internal/netxlite/integration_test.go b/internal/netxlite/integration_test.go index a1d6545..937e7c7 100644 --- a/internal/netxlite/integration_test.go +++ b/internal/netxlite/integration_test.go @@ -12,6 +12,7 @@ import ( "github.com/apex/log" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" "github.com/ooni/probe-cli/v3/internal/netxlite/filtering" "github.com/ooni/probe-cli/v3/internal/netxlite/quictesting" @@ -275,7 +276,7 @@ func TestMeasureWithTLSHandshaker(t *testing.T) { return d.DialContext(ctx, "tcp", address) } - successFlow := func(th netxlite.TLSHandshaker) error { + successFlow := func(th model.TLSHandshaker) error { ctx := context.Background() conn, err := dial(ctx, "8.8.4.4:443") if err != nil { @@ -295,7 +296,7 @@ func TestMeasureWithTLSHandshaker(t *testing.T) { return nil } - connectionResetFlow := func(th netxlite.TLSHandshaker) error { + connectionResetFlow := func(th model.TLSHandshaker) error { tlsProxy := &filtering.TLSProxy{ OnIncomingSNI: func(sni string) filtering.TLSAction { return filtering.TLSActionReset @@ -330,7 +331,7 @@ func TestMeasureWithTLSHandshaker(t *testing.T) { return nil } - timeoutFlow := func(th netxlite.TLSHandshaker) error { + timeoutFlow := func(th model.TLSHandshaker) error { tlsProxy := &filtering.TLSProxy{ OnIncomingSNI: func(sni string) filtering.TLSAction { return filtering.TLSActionTimeout diff --git a/internal/netxlite/iox_test.go b/internal/netxlite/iox_test.go index 908fddf..04f155c 100644 --- a/internal/netxlite/iox_test.go +++ b/internal/netxlite/iox_test.go @@ -8,7 +8,7 @@ import ( "sync" "testing" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestReadAllContext(t *testing.T) { diff --git a/internal/netxlite/legacy.go b/internal/netxlite/legacy.go index 7e5c0e1..9f79f61 100644 --- a/internal/netxlite/legacy.go +++ b/internal/netxlite/legacy.go @@ -6,6 +6,7 @@ import ( "net" "github.com/lucas-clemente/quic-go" + "github.com/ooni/probe-cli/v3/internal/model" ) // These vars export internal names to legacy ooni/probe-cli code. @@ -51,7 +52,7 @@ type ResolverLegacy interface { // NewResolverLegacyAdapter adapts a ResolverLegacy to // become compatible with the Resolver definition. -func NewResolverLegacyAdapter(reso ResolverLegacy) Resolver { +func NewResolverLegacyAdapter(reso ResolverLegacy) model.Resolver { return &ResolverLegacyAdapter{reso} } @@ -60,7 +61,7 @@ type ResolverLegacyAdapter struct { ResolverLegacy } -var _ Resolver = &ResolverLegacyAdapter{} +var _ model.Resolver = &ResolverLegacyAdapter{} type resolverLegacyNetworker interface { Network() string @@ -99,7 +100,7 @@ func (r *ResolverLegacyAdapter) CloseIdleConnections() { // LookupHTTPS always returns ErrDNSNoTransport. func (r *ResolverLegacyAdapter) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, ErrNoDNSTransport } @@ -118,7 +119,7 @@ type DialerLegacy interface { // become compatible with the Dialer definition. // // Deprecated: do not use this function in new code. -func NewDialerLegacyAdapter(d DialerLegacy) Dialer { +func NewDialerLegacyAdapter(d DialerLegacy) model.Dialer { return &DialerLegacyAdapter{d} } @@ -130,7 +131,7 @@ type DialerLegacyAdapter struct { DialerLegacy } -var _ Dialer = &DialerLegacyAdapter{} +var _ model.Dialer = &DialerLegacyAdapter{} type dialerLegacyIdleConnectionsCloser interface { CloseIdleConnections() @@ -159,7 +160,7 @@ type QUICContextDialer interface { // NewQUICDialerFromContextDialerAdapter creates a new // QUICDialer from a QUICContextDialer. -func NewQUICDialerFromContextDialerAdapter(d QUICContextDialer) QUICDialer { +func NewQUICDialerFromContextDialerAdapter(d QUICContextDialer) model.QUICDialer { return &QUICContextDialerAdapter{d} } diff --git a/internal/netxlite/legacy_test.go b/internal/netxlite/legacy_test.go index 550d1d5..5725f64 100644 --- a/internal/netxlite/legacy_test.go +++ b/internal/netxlite/legacy_test.go @@ -6,7 +6,8 @@ import ( "net" "testing" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" + nlmocks "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" ) func TestResolverLegacyAdapter(t *testing.T) { @@ -93,7 +94,7 @@ func TestQUICContextDialerAdapter(t *testing.T) { }) t.Run("with incompatible type", func(t *testing.T) { - d := NewQUICDialerFromContextDialerAdapter(&mocks.QUICContextDialer{}) + d := NewQUICDialerFromContextDialerAdapter(&nlmocks.QUICContextDialer{}) d.CloseIdleConnections() // does not crash }) } diff --git a/internal/netxlite/logger.go b/internal/netxlite/logger.go deleted file mode 100644 index 526f391..0000000 --- a/internal/netxlite/logger.go +++ /dev/null @@ -1,10 +0,0 @@ -package netxlite - -// Logger is the interface we expect from a logger. -type Logger interface { - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Debug emits a debug message. - Debug(msg string) -} diff --git a/internal/netxlite/mocks/doc.go b/internal/netxlite/mocks/doc.go deleted file mode 100644 index 7024ef3..0000000 --- a/internal/netxlite/mocks/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package mocks contains mocks for netx types. -package mocks diff --git a/internal/netxlite/quic.go b/internal/netxlite/quic.go index 2d9d4a0..14aea9a 100644 --- a/internal/netxlite/quic.go +++ b/internal/netxlite/quic.go @@ -9,56 +9,25 @@ import ( "sync" "github.com/lucas-clemente/quic-go" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + "github.com/ooni/probe-cli/v3/internal/model" ) -// UDPLikeConn is the kind of UDP socket used by QUIC. -type UDPLikeConn = quicx.UDPLikeConn - -// QUICListener listens for QUIC connections. -type QUICListener interface { - // Listen creates a new listening UDPLikeConn. - Listen(addr *net.UDPAddr) (UDPLikeConn, error) -} - // NewQUICListener creates a new QUICListener using the standard // library to create listening UDP sockets. -func NewQUICListener() QUICListener { +func NewQUICListener() model.QUICListener { return &quicListenerErrWrapper{&quicListenerStdlib{}} } // quicListenerStdlib is a QUICListener using the standard library. type quicListenerStdlib struct{} -var _ QUICListener = &quicListenerStdlib{} +var _ model.QUICListener = &quicListenerStdlib{} // Listen implements QUICListener.Listen. -func (qls *quicListenerStdlib) Listen(addr *net.UDPAddr) (UDPLikeConn, error) { +func (qls *quicListenerStdlib) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { return TProxy.ListenUDP("udp", addr) } -// QUICDialer dials QUIC sessions. -type QUICDialer interface { - // DialContext establishes a new QUIC session using the given - // network and address. The tlsConfig and the quicConfig arguments - // MUST NOT be nil. Returns either the session or an error. - // - // Recommended tlsConfig setup: - // - // - set ServerName to be the SNI; - // - // - set RootCAs to NewDefaultCertPool(); - // - // - set NextProtos to []string{"h3"}. - // - // Typically, you want to pass `&quic.Config{}` as quicConfig. - DialContext(ctx context.Context, network, address string, - tlsConfig *tls.Config, quicConfig *quic.Config) (quic.EarlySession, error) - - // CloseIdleConnections closes idle connections, if any. - CloseIdleConnections() -} - // NewQUICDialerWithResolver returns a QUICDialer using the given // QUICListener to create listening connections and the given Resolver // to resolve domain names (if needed). @@ -80,8 +49,8 @@ type QUICDialer interface { // 6. if a dialer wraps a resolver, the dialer will forward // the CloseIdleConnection call to its resolver (which is // instrumental to manage a DoH resolver connections properly). -func NewQUICDialerWithResolver(listener QUICListener, - logger Logger, resolver Resolver) QUICDialer { +func NewQUICDialerWithResolver(listener model.QUICListener, + logger model.DebugLogger, resolver model.Resolver) model.QUICDialer { return &quicDialerLogger{ Dialer: &quicDialerResolver{ Dialer: &quicDialerLogger{ @@ -102,14 +71,14 @@ func NewQUICDialerWithResolver(listener QUICListener, // except that there is no configured resolver. So, if you pass in // an address containing a domain name, the dial will fail with // the ErrNoResolver failure. -func NewQUICDialerWithoutResolver(listener QUICListener, logger Logger) QUICDialer { +func NewQUICDialerWithoutResolver(listener model.QUICListener, logger model.DebugLogger) model.QUICDialer { return NewQUICDialerWithResolver(listener, logger, &nullResolver{}) } // quicDialerQUICGo dials using the lucas-clemente/quic-go library. type quicDialerQUICGo struct { // QUICListener is the underlying QUICListener to use. - QUICListener QUICListener + QUICListener model.QUICListener // mockDialEarlyContext allows to mock quic.DialEarlyContext. mockDialEarlyContext func(ctx context.Context, pconn net.PacketConn, @@ -117,7 +86,7 @@ type quicDialerQUICGo struct { quicConfig *quic.Config) (quic.EarlySession, error) } -var _ QUICDialer = &quicDialerQUICGo{} +var _ model.QUICDialer = &quicDialerQUICGo{} // errInvalidIP indicates that a string is not a valid IP. var errInvalidIP = errors.New("netxlite: invalid IP") @@ -201,7 +170,7 @@ type quicSessionOwnsConn struct { quic.EarlySession // conn is the connection we own - conn UDPLikeConn + conn model.UDPLikeConn } // CloseWithError implements quic.EarlySession.CloseWithError. @@ -216,13 +185,13 @@ func (sess *quicSessionOwnsConn) CloseWithError( // to resolve a domain name to IP addrs. type quicDialerResolver struct { // Dialer is the underlying QUICDialer. - Dialer QUICDialer + Dialer model.QUICDialer // Resolver is the underlying Resolver. - Resolver Resolver + Resolver model.Resolver } -var _ QUICDialer = &quicDialerResolver{} +var _ model.QUICDialer = &quicDialerResolver{} // DialContext implements QUICDialer.DialContext. This function // will apply the following TLS defaults: @@ -284,10 +253,10 @@ func (d *quicDialerResolver) CloseIdleConnections() { // quicDialerLogger is a dialer with logging. type quicDialerLogger struct { // Dialer is the underlying QUIC dialer. - Dialer QUICDialer + Dialer model.QUICDialer // Logger is the underlying logger. - Logger Logger + Logger model.DebugLogger // operationSuffix is appended to the operation name. // @@ -298,7 +267,7 @@ type quicDialerLogger struct { operationSuffix string } -var _ QUICDialer = &quicDialerLogger{} +var _ model.QUICDialer = &quicDialerLogger{} // DialContext implements QUICContextDialer.DialContext. func (d *quicDialerLogger) DialContext( @@ -321,7 +290,7 @@ func (d *quicDialerLogger) CloseIdleConnections() { } // NewSingleUseQUICDialer is like NewSingleUseDialer but for QUIC. -func NewSingleUseQUICDialer(sess quic.EarlySession) QUICDialer { +func NewSingleUseQUICDialer(sess quic.EarlySession) model.QUICDialer { return &quicDialerSingleUse{sess: sess} } @@ -331,7 +300,7 @@ type quicDialerSingleUse struct { sess quic.EarlySession } -var _ QUICDialer = &quicDialerSingleUse{} +var _ model.QUICDialer = &quicDialerSingleUse{} // DialContext implements QUICDialer.DialContext. func (s *quicDialerSingleUse) DialContext( @@ -355,13 +324,13 @@ func (s *quicDialerSingleUse) CloseIdleConnections() { // quicListenerErrWrapper is a QUICListener that wraps errors. type quicListenerErrWrapper struct { // QUICListener is the underlying listener. - QUICListener + model.QUICListener } -var _ QUICListener = &quicListenerErrWrapper{} +var _ model.QUICListener = &quicListenerErrWrapper{} // Listen implements QUICListener.Listen. -func (qls *quicListenerErrWrapper) Listen(addr *net.UDPAddr) (UDPLikeConn, error) { +func (qls *quicListenerErrWrapper) Listen(addr *net.UDPAddr) (model.UDPLikeConn, error) { pconn, err := qls.QUICListener.Listen(addr) if err != nil { return nil, NewErrWrapper(ClassifyGenericError, QUICListenOperation, err) @@ -372,10 +341,10 @@ func (qls *quicListenerErrWrapper) Listen(addr *net.UDPAddr) (UDPLikeConn, error // quicErrWrapperUDPLikeConn is a UDPLikeConn that wraps errors. type quicErrWrapperUDPLikeConn struct { // UDPLikeConn is the underlying conn. - UDPLikeConn + model.UDPLikeConn } -var _ UDPLikeConn = &quicErrWrapperUDPLikeConn{} +var _ model.UDPLikeConn = &quicErrWrapperUDPLikeConn{} // WriteTo implements UDPLikeConn.WriteTo. func (c *quicErrWrapperUDPLikeConn) WriteTo(p []byte, addr net.Addr) (int, error) { @@ -406,7 +375,7 @@ func (c *quicErrWrapperUDPLikeConn) Close() error { // quicDialerErrWrapper is a dialer that performs quic err wrapping type quicDialerErrWrapper struct { - QUICDialer + model.QUICDialer } // DialContext implements ContextDialer.DialContext diff --git a/internal/netxlite/quic_test.go b/internal/netxlite/quic_test.go index 3188be6..8b9f2e9 100644 --- a/internal/netxlite/quic_test.go +++ b/internal/netxlite/quic_test.go @@ -12,7 +12,8 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" "github.com/lucas-clemente/quic-go" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestNewQUICListener(t *testing.T) { @@ -107,7 +108,7 @@ func TestQUICDialerQUICGo(t *testing.T) { } systemdialer := quicDialerQUICGo{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return nil, expected }, }, @@ -477,7 +478,7 @@ func TestQUICListenerErrWrapper(t *testing.T) { expectedConn := &mocks.QUICUDPLikeConn{} ql := &quicListenerErrWrapper{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return expectedConn, nil }, }, @@ -496,7 +497,7 @@ func TestQUICListenerErrWrapper(t *testing.T) { expectedErr := io.EOF ql := &quicListenerErrWrapper{ QUICListener: &mocks.QUICListener{ - MockListen: func(addr *net.UDPAddr) (UDPLikeConn, error) { + MockListen: func(addr *net.UDPAddr) (model.UDPLikeConn, error) { return nil, expectedErr }, }, diff --git a/internal/netxlite/quicx/quicx.go b/internal/netxlite/quicx/quicx.go deleted file mode 100644 index d8fe06d..0000000 --- a/internal/netxlite/quicx/quicx.go +++ /dev/null @@ -1,35 +0,0 @@ -// Package quicx contains lucas-clemente/quic-go extensions. -package quicx - -import ( - "net" - "syscall" -) - -// UDPLikeConn is a net.PacketConn with some extra functions -// required to convince the QUIC library (lucas-clemente/quic-go) -// to inflate the receive buffer of the connection. -// -// The QUIC library will treat this connection as a "dumb" -// net.PacketConn, calling its ReadFrom and WriteTo methods -// as opposed to more efficient methods that are available -// under Linux and (maybe?) FreeBSD. -// -// It seems fine to avoid performance optimizations, because -// they would complicate the implementation on our side and -// our use cases (blocking and heavy throttling) do not seem -// to require such optimizations. -// -// See https://github.com/ooni/probe/issues/1754 for a more -// comprehensive discussion of UDPLikeConn. -type UDPLikeConn interface { - // An UDPLikeConn is a net.PacketConn conn. - net.PacketConn - - // SetReadBuffer allows setting the read buffer. - SetReadBuffer(bytes int) error - - // SyscallConn returns a conn suitable for calling syscalls, - // which is also instrumental to setting the read buffer. - SyscallConn() (syscall.RawConn, error) -} diff --git a/internal/netxlite/resolver.go b/internal/netxlite/resolver.go index 4a0f674..5091f94 100644 --- a/internal/netxlite/resolver.go +++ b/internal/netxlite/resolver.go @@ -7,32 +7,10 @@ import ( "net" "time" - "github.com/ooni/probe-cli/v3/internal/netxlite/dnsx" + "github.com/ooni/probe-cli/v3/internal/model" "golang.org/x/net/idna" ) -// HTTPSSvc is the type returned for HTTPS queries. -type HTTPSSvc = dnsx.HTTPSSvc - -// Resolver performs domain name resolutions. -type Resolver interface { - // LookupHost behaves like net.Resolver.LookupHost. - LookupHost(ctx context.Context, hostname string) (addrs []string, err error) - - // Network returns the resolver type (e.g., system, dot, doh). - Network() string - - // Address returns the resolver address (e.g., 8.8.8.8:53). - Address() string - - // CloseIdleConnections closes idle connections, if any. - CloseIdleConnections() - - // LookupHTTPS issues an HTTPS query for a domain. - LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) -} - // ErrNoDNSTransport is the error returned when you attempt to perform // a DNS operation that requires a custom DNSTransport (e.g., DNSOverHTTPS) // but you are using the "system" resolver instead. @@ -40,7 +18,7 @@ var ErrNoDNSTransport = errors.New("operation requires a DNS transport") // NewResolverStdlib creates a new Resolver by combining WrapResolver // with an internal "system" resolver type. -func NewResolverStdlib(logger Logger) Resolver { +func NewResolverStdlib(logger model.DebugLogger) model.Resolver { return WrapResolver(logger, &resolverSystem{}) } @@ -53,7 +31,7 @@ func NewResolverStdlib(logger Logger) Resolver { // - dialer is the dialer to create and connect UDP conns // // - address is the server address (e.g., 1.1.1.1:53) -func NewResolverUDP(logger Logger, dialer Dialer, address string) Resolver { +func NewResolverUDP(logger model.DebugLogger, dialer model.Dialer, address string) model.Resolver { return WrapResolver(logger, NewSerialResolver( NewDNSOverUDP(dialer, address), )) @@ -75,7 +53,7 @@ func NewResolverUDP(logger Logger, dialer Dialer, address string) Resolver { // see https://github.com/ooni/probe/issues/1726). // // This is a low-level factory. Use only if out of alternatives. -func WrapResolver(logger Logger, resolver Resolver) Resolver { +func WrapResolver(logger model.DebugLogger, resolver model.Resolver) model.Resolver { return &resolverIDNA{ Resolver: &resolverLogger{ Resolver: &resolverShortCircuitIPAddr{ @@ -94,7 +72,7 @@ type resolverSystem struct { testableLookupHost func(ctx context.Context, domain string) ([]string, error) } -var _ Resolver = &resolverSystem{} +var _ model.Resolver = &resolverSystem{} func (r *resolverSystem) LookupHost(ctx context.Context, hostname string) ([]string, error) { // This code forces adding a shorter timeout to the domain name @@ -149,17 +127,17 @@ func (r *resolverSystem) CloseIdleConnections() { } func (r *resolverSystem) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, ErrNoDNSTransport } // resolverLogger is a resolver that emits events type resolverLogger struct { - Resolver - Logger Logger + model.Resolver + Logger model.DebugLogger } -var _ Resolver = &resolverLogger{} +var _ model.Resolver = &resolverLogger{} func (r *resolverLogger) LookupHost(ctx context.Context, hostname string) ([]string, error) { prefix := fmt.Sprintf("resolve[A,AAAA] %s with %s (%s)", hostname, r.Network(), r.Address()) @@ -176,7 +154,7 @@ func (r *resolverLogger) LookupHost(ctx context.Context, hostname string) ([]str } func (r *resolverLogger) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { prefix := fmt.Sprintf("resolve[HTTPS] %s with %s (%s)", domain, r.Network(), r.Address()) r.Logger.Debugf("%s...", prefix) start := time.Now() @@ -197,7 +175,7 @@ func (r *resolverLogger) LookupHTTPS( // // See RFC3492 for more information. type resolverIDNA struct { - Resolver + model.Resolver } func (r *resolverIDNA) LookupHost(ctx context.Context, hostname string) ([]string, error) { @@ -209,7 +187,7 @@ func (r *resolverIDNA) LookupHost(ctx context.Context, hostname string) ([]strin } func (r *resolverIDNA) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { host, err := idna.ToASCII(domain) if err != nil { return nil, err @@ -220,7 +198,7 @@ func (r *resolverIDNA) LookupHTTPS( // resolverShortCircuitIPAddr recognizes when the input hostname is an // IP address and returns it immediately to the caller. type resolverShortCircuitIPAddr struct { - Resolver + model.Resolver } func (r *resolverShortCircuitIPAddr) LookupHost(ctx context.Context, hostname string) ([]string, error) { @@ -256,16 +234,16 @@ func (r *nullResolver) CloseIdleConnections() { } func (r *nullResolver) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, ErrNoResolver } // resolverErrWrapper is a Resolver that knows about wrapping errors. type resolverErrWrapper struct { - Resolver + model.Resolver } -var _ Resolver = &resolverErrWrapper{} +var _ model.Resolver = &resolverErrWrapper{} func (r *resolverErrWrapper) LookupHost(ctx context.Context, hostname string) ([]string, error) { addrs, err := r.Resolver.LookupHost(ctx, hostname) @@ -276,7 +254,7 @@ func (r *resolverErrWrapper) LookupHost(ctx context.Context, hostname string) ([ } func (r *resolverErrWrapper) LookupHTTPS( - ctx context.Context, domain string) (*HTTPSSvc, error) { + ctx context.Context, domain string) (*model.HTTPSSvc, error) { out, err := r.Resolver.LookupHTTPS(ctx, domain) if err != nil { return nil, NewErrWrapper(ClassifyResolverError, ResolveOperation, err) diff --git a/internal/netxlite/resolver_test.go b/internal/netxlite/resolver_test.go index b20eca4..17a2677 100644 --- a/internal/netxlite/resolver_test.go +++ b/internal/netxlite/resolver_test.go @@ -11,7 +11,8 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestNewResolverSystem(t *testing.T) { @@ -246,14 +247,14 @@ func TestResolverLogger(t *testing.T) { count++ }, } - expected := &HTTPSSvc{ + expected := &model.HTTPSSvc{ ALPN: []string{"h3"}, IPv4: []string{"1.1.1.1"}, } r := &resolverLogger{ Logger: lo, Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return expected, nil }, MockNetwork: func() string { @@ -287,7 +288,7 @@ func TestResolverLogger(t *testing.T) { r := &resolverLogger{ Logger: lo, Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, expected }, MockNetwork: func() string { @@ -357,14 +358,14 @@ func TestResolverIDNA(t *testing.T) { t.Run("LookupHTTPS", func(t *testing.T) { t.Run("with valid IDNA in input", func(t *testing.T) { - expected := &HTTPSSvc{ + expected := &model.HTTPSSvc{ ALPN: []string{"h3"}, IPv4: []string{"1.1.1.1"}, IPv6: []string{}, } r := &resolverIDNA{ Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { if domain != "xn--d1acpjx3f.xn--p1ai" { return nil, errors.New("passed invalid domain") } @@ -384,7 +385,7 @@ func TestResolverIDNA(t *testing.T) { t.Run("with invalid punycode", func(t *testing.T) { r := &resolverIDNA{Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, errors.New("should not happen") }, }} @@ -567,12 +568,12 @@ func TestResolverErrWrapper(t *testing.T) { t.Run("LookupHTTPS", func(t *testing.T) { t.Run("on success", func(t *testing.T) { - expected := &HTTPSSvc{ + expected := &model.HTTPSSvc{ ALPN: []string{"h3"}, } reso := &resolverErrWrapper{ Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return expected, nil }, }, @@ -591,7 +592,7 @@ func TestResolverErrWrapper(t *testing.T) { expected := io.EOF reso := &resolverErrWrapper{ Resolver: &mocks.Resolver{ - MockLookupHTTPS: func(ctx context.Context, domain string) (*HTTPSSvc, error) { + MockLookupHTTPS: func(ctx context.Context, domain string) (*model.HTTPSSvc, error) { return nil, expected }, }, diff --git a/internal/netxlite/serialresolver.go b/internal/netxlite/serialresolver.go index 1466120..d662a31 100644 --- a/internal/netxlite/serialresolver.go +++ b/internal/netxlite/serialresolver.go @@ -7,6 +7,7 @@ import ( "github.com/miekg/dns" "github.com/ooni/probe-cli/v3/internal/atomicx" + "github.com/ooni/probe-cli/v3/internal/model" ) // SerialResolver uses a transport and sends performs a LookupHost @@ -16,20 +17,20 @@ import ( // You should probably use NewSerialResolver to create a new instance. type SerialResolver struct { // Encoder is the MANDATORY encoder to use. - Encoder DNSEncoder + Encoder model.DNSEncoder // Decoder is the MANDATORY decoder to use. - Decoder DNSDecoder + Decoder model.DNSDecoder // NumTimeouts is MANDATORY and counts the number of timeouts. NumTimeouts *atomicx.Int64 // Txp is the underlying DNS transport. - Txp DNSTransport + Txp model.DNSTransport } // NewSerialResolver creates a new SerialResolver instance. -func NewSerialResolver(t DNSTransport) *SerialResolver { +func NewSerialResolver(t model.DNSTransport) *SerialResolver { return &SerialResolver{ Encoder: &DNSEncoderMiekg{}, Decoder: &DNSDecoderMiekg{}, @@ -39,7 +40,7 @@ func NewSerialResolver(t DNSTransport) *SerialResolver { } // Transport returns the transport being used. -func (r *SerialResolver) Transport() DNSTransport { +func (r *SerialResolver) Transport() model.DNSTransport { return r.Txp } @@ -76,7 +77,7 @@ func (r *SerialResolver) LookupHost(ctx context.Context, hostname string) ([]str // LookupHTTPS implements Resolver.LookupHTTPS. func (r *SerialResolver) LookupHTTPS( - ctx context.Context, hostname string) (*HTTPSSvc, error) { + ctx context.Context, hostname string) (*model.HTTPSSvc, error) { querydata, err := r.Encoder.Encode( hostname, dns.TypeHTTPS, r.Txp.RequiresPadding()) if err != nil { diff --git a/internal/netxlite/serialresolver_test.go b/internal/netxlite/serialresolver_test.go index 4238176..7975298 100644 --- a/internal/netxlite/serialresolver_test.go +++ b/internal/netxlite/serialresolver_test.go @@ -9,7 +9,8 @@ import ( "github.com/miekg/dns" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) // errorWithTimeout is an error that golang will always consider @@ -248,7 +249,7 @@ func TestSerialResolver(t *testing.T) { }, }, Decoder: &mocks.DNSDecoder{ - MockDecodeHTTPS: func(reply []byte) (*mocks.HTTPSSvc, error) { + MockDecodeHTTPS: func(reply []byte) (*model.HTTPSSvc, error) { return nil, expected }, }, diff --git a/internal/netxlite/tls.go b/internal/netxlite/tls.go index 01ea167..ad51228 100644 --- a/internal/netxlite/tls.go +++ b/internal/netxlite/tls.go @@ -10,6 +10,7 @@ import ( "time" oohttp "github.com/ooni/oohttp" + "github.com/ooni/probe-cli/v3/internal/model" ) var ( @@ -124,28 +125,6 @@ type TLSConn = oohttp.TLSConn // Ensures that a tls.Conn implements the TLSConn interface. var _ TLSConn = &tls.Conn{} -// TLSHandshaker is the generic TLS handshaker. -type TLSHandshaker interface { - // Handshake creates a new TLS connection from the given connection and - // the given config. This function DOES NOT take ownership of the connection - // and it's your responsibility to close it on failure. - // - // Recommended tlsConfig setup: - // - // - set ServerName to be the SNI; - // - // - set RootCAs to NewDefaultCertPool(); - // - // - set NextProtos to []string{"h2", "http/1.1"} for HTTPS - // and []string{"dot"} for DNS-over-TLS. - // - // QUIRK: The returned connection will always implement the TLSConn interface - // exposed by this package. A future version of this interface will instead - // return directly a TLSConn to avoid unconditional castings. - Handshake(ctx context.Context, conn net.Conn, tlsConfig *tls.Config) ( - net.Conn, tls.ConnectionState, error) -} - // NewTLSHandshakerStdlib creates a new TLS handshaker using the // go standard library to manage TLS. // @@ -154,17 +133,17 @@ type TLSHandshaker interface { // 1. logging // // 2. error wrapping -func NewTLSHandshakerStdlib(logger Logger) TLSHandshaker { +func NewTLSHandshakerStdlib(logger model.DebugLogger) model.TLSHandshaker { return newTLSHandshaker(&tlsHandshakerConfigurable{}, logger) } // newTLSHandshaker is the common factory for creating a new TLSHandshaker -func newTLSHandshaker(th TLSHandshaker, logger Logger) TLSHandshaker { +func newTLSHandshaker(th model.TLSHandshaker, logger model.DebugLogger) model.TLSHandshaker { return &tlsHandshakerLogger{ TLSHandshaker: &tlsHandshakerErrWrapper{ TLSHandshaker: th, }, - Logger: logger, + DebugLogger: logger, } } @@ -180,7 +159,7 @@ type tlsHandshakerConfigurable struct { Timeout time.Duration } -var _ TLSHandshaker = &tlsHandshakerConfigurable{} +var _ model.TLSHandshaker = &tlsHandshakerConfigurable{} // defaultCertPool is the cert pool we use by default. We store this // value into a private variable to enable for unit testing. @@ -222,28 +201,28 @@ var defaultTLSHandshaker = &tlsHandshakerConfigurable{} // tlsHandshakerLogger is a TLSHandshaker with logging. type tlsHandshakerLogger struct { - TLSHandshaker - Logger + model.TLSHandshaker + model.DebugLogger } -var _ TLSHandshaker = &tlsHandshakerLogger{} +var _ model.TLSHandshaker = &tlsHandshakerLogger{} // Handshake implements Handshaker.Handshake func (h *tlsHandshakerLogger) Handshake( ctx context.Context, conn net.Conn, config *tls.Config, ) (net.Conn, tls.ConnectionState, error) { - h.Logger.Debugf( + h.DebugLogger.Debugf( "tls {sni=%s next=%+v}...", config.ServerName, config.NextProtos) start := time.Now() tlsconn, state, err := h.TLSHandshaker.Handshake(ctx, conn, config) elapsed := time.Since(start) if err != nil { - h.Logger.Debugf( + h.DebugLogger.Debugf( "tls {sni=%s next=%+v}... %s in %s", config.ServerName, config.NextProtos, err, elapsed) return nil, tls.ConnectionState{}, err } - h.Logger.Debugf( + h.DebugLogger.Debugf( "tls {sni=%s next=%+v}... ok in %s {next=%s cipher=%s v=%s}", config.ServerName, config.NextProtos, elapsed, state.NegotiatedProtocol, TLSCipherSuiteString(state.CipherSuite), @@ -251,23 +230,13 @@ func (h *tlsHandshakerLogger) Handshake( return tlsconn, state, nil } -// TLSDialer is a Dialer dialing TLS connections. -type TLSDialer interface { - // CloseIdleConnections closes idle connections, if any. - CloseIdleConnections() - - // DialTLSContext dials a TLS connection. This method will always - // return to you a TLSConn, so you can always safely cast to TLSConn. - DialTLSContext(ctx context.Context, network, address string) (net.Conn, error) -} - // NewTLSDialer creates a new TLS dialer using the given dialer and handshaker. -func NewTLSDialer(dialer Dialer, handshaker TLSHandshaker) TLSDialer { +func NewTLSDialer(dialer model.Dialer, handshaker model.TLSHandshaker) model.TLSDialer { return NewTLSDialerWithConfig(dialer, handshaker, &tls.Config{}) } // NewTLSDialerWithConfig is like NewTLSDialer with an optional config. -func NewTLSDialerWithConfig(d Dialer, h TLSHandshaker, c *tls.Config) TLSDialer { +func NewTLSDialerWithConfig(d model.Dialer, h model.TLSHandshaker, c *tls.Config) model.TLSDialer { return &tlsDialer{Config: c, Dialer: d, TLSHandshaker: h} } @@ -277,13 +246,13 @@ type tlsDialer struct { Config *tls.Config // Dialer is the MANDATORY dialer. - Dialer Dialer + Dialer model.Dialer // TLSHandshaker is the MANDATORY TLS handshaker. - TLSHandshaker TLSHandshaker + TLSHandshaker model.TLSHandshaker } -var _ TLSDialer = &tlsDialer{} +var _ model.TLSDialer = &tlsDialer{} // CloseIdleConnections implements TLSDialer.CloseIdleConnections. func (d *tlsDialer) CloseIdleConnections() { @@ -337,17 +306,17 @@ func (d *tlsDialer) config(host, port string) *tls.Config { // NewSingleUseTLSDialer is like NewSingleUseDialer but takes // in input a TLSConn rather than a net.Conn. -func NewSingleUseTLSDialer(conn TLSConn) TLSDialer { +func NewSingleUseTLSDialer(conn TLSConn) model.TLSDialer { return &tlsDialerSingleUseAdapter{NewSingleUseDialer(conn)} } // tlsDialerSingleUseAdapter adapts dialerSingleUse to // be a TLSDialer type rather than a Dialer type. type tlsDialerSingleUseAdapter struct { - Dialer + model.Dialer } -var _ TLSDialer = &tlsDialerSingleUseAdapter{} +var _ model.TLSDialer = &tlsDialerSingleUseAdapter{} // DialTLSContext implements TLSDialer.DialTLSContext. func (d *tlsDialerSingleUseAdapter) DialTLSContext(ctx context.Context, network, address string) (net.Conn, error) { @@ -356,7 +325,7 @@ func (d *tlsDialerSingleUseAdapter) DialTLSContext(ctx context.Context, network, // tlsHandshakerErrWrapper wraps the returned error to be an OONI error type tlsHandshakerErrWrapper struct { - TLSHandshaker + model.TLSHandshaker } // Handshake implements TLSHandshaker.Handshake @@ -376,13 +345,13 @@ func (h *tlsHandshakerErrWrapper) Handshake( var ErrNoTLSDialer = errors.New("no configured TLS dialer") // NewNullTLSDialer returns a TLS dialer that always fails with ErrNoTLSDialer. -func NewNullTLSDialer() TLSDialer { +func NewNullTLSDialer() model.TLSDialer { return &nullTLSDialer{} } type nullTLSDialer struct{} -var _ TLSDialer = &nullTLSDialer{} +var _ model.TLSDialer = &nullTLSDialer{} func (*nullTLSDialer) DialTLSContext(ctx context.Context, network, address string) (net.Conn, error) { return nil, ErrNoTLSDialer diff --git a/internal/netxlite/tls_test.go b/internal/netxlite/tls_test.go index 17ee0f5..2c17987 100644 --- a/internal/netxlite/tls_test.go +++ b/internal/netxlite/tls_test.go @@ -16,7 +16,7 @@ import ( "github.com/apex/log" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestVersionString(t *testing.T) { @@ -120,7 +120,7 @@ func TestConfigureTLSVersion(t *testing.T) { func TestNewTLSHandshakerStdlib(t *testing.T) { th := NewTLSHandshakerStdlib(log.Log) logger := th.(*tlsHandshakerLogger) - if logger.Logger != log.Log { + if logger.DebugLogger != log.Log { t.Fatal("invalid logger") } errWrapper := logger.TLSHandshaker.(*tlsHandshakerErrWrapper) @@ -253,7 +253,7 @@ func TestTLSHandshakerLogger(t *testing.T) { return tls.Client(conn, config), tls.ConnectionState{}, nil }, }, - Logger: lo, + DebugLogger: lo, } conn := &mocks.Conn{ MockClose: func() error { @@ -291,7 +291,7 @@ func TestTLSHandshakerLogger(t *testing.T) { return nil, tls.ConnectionState{}, expected }, }, - Logger: lo, + DebugLogger: lo, } conn := &mocks.Conn{ MockClose: func() error { diff --git a/internal/netxlite/tproxy.go b/internal/netxlite/tproxy.go index c7df553..f5cbf1b 100644 --- a/internal/netxlite/tproxy.go +++ b/internal/netxlite/tproxy.go @@ -5,46 +5,22 @@ import ( "net" "time" - "github.com/ooni/probe-cli/v3/internal/netxlite/quicx" + "github.com/ooni/probe-cli/v3/internal/model" ) -// TProxable is the fundamental type used by the netxlite package to perform -// low-level network operations for which, by default, we use the stdlib. -// -// The t stands for transparent. By using this type as the fundamental type, -// we can transparently intercept connections and implement censorship -// policies. The implementation of this functionality is not part of netxlite: -// here we only have the basic mechanism to make this possible. -type TProxable interface { - // ListenUDP creates a new quicx.UDPLikeConn conn. - ListenUDP(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) - - // LookupHost lookups a domain using the stdlib resolver. - LookupHost(ctx context.Context, domain string) ([]string, error) - - // NewTProxyDialer returns a new TProxyDialer. - NewTProxyDialer(timeout time.Duration) TProxyDialer -} - -// TProxyDialer is the dialer type returned by TProxable.NewDialer. -type TProxyDialer interface { - // DialContext behaves like net.Dialer.DialContext. - DialContext(ctx context.Context, network, address string) (net.Conn, error) -} - // TProxy is the fundamental variable controlling how netxlite creates -// net.Conn and quicx.UDPLikeConn, as well as how it uses the stdlib +// net.Conn and model.UDPLikeConn, as well as how it uses the stdlib // resolver. By modifying this variable, you can effectively transparently // proxy netxlite (and hence OONI) activities to other services. This is // quite convenient when performing quality assurance tests. -var TProxy TProxable = &TProxyStdlib{} +var TProxy model.UnderlyingNetworkLibrary = &TProxyStdlib{} -// TProxyStdlib is the default TProxable implementation that uses +// TProxyStdlib is the default model.UnderlyingNetworkLibrary using // the stdlib in the most obvious way for every functionality. type TProxyStdlib struct{} // ListenUDP calls net.ListenUDP. -func (*TProxyStdlib) ListenUDP(network string, laddr *net.UDPAddr) (quicx.UDPLikeConn, error) { +func (*TProxyStdlib) ListenUDP(network string, laddr *net.UDPAddr) (model.UDPLikeConn, error) { return net.ListenUDP(network, laddr) } @@ -53,7 +29,7 @@ func (*TProxyStdlib) LookupHost(ctx context.Context, domain string) ([]string, e return net.DefaultResolver.LookupHost(ctx, domain) } -// NewTProxyDialer returns a &net.Dialer{Timeout: timeout} instance. -func (*TProxyStdlib) NewTProxyDialer(timeout time.Duration) TProxyDialer { +// NewSimpleDialer returns a &net.Dialer{Timeout: timeout} instance. +func (*TProxyStdlib) NewSimpleDialer(timeout time.Duration) model.SimpleDialer { return &net.Dialer{Timeout: timeout} } diff --git a/internal/netxlite/utls.go b/internal/netxlite/utls.go index 0239782..5d668e2 100644 --- a/internal/netxlite/utls.go +++ b/internal/netxlite/utls.go @@ -6,6 +6,7 @@ import ( "errors" "net" + "github.com/ooni/probe-cli/v3/internal/model" utls "gitlab.com/yawning/utls.git" ) @@ -21,7 +22,7 @@ import ( // 2. error wrapping // // Passing a nil `id` will make this function panic. -func NewTLSHandshakerUTLS(logger Logger, id *utls.ClientHelloID) TLSHandshaker { +func NewTLSHandshakerUTLS(logger model.DebugLogger, id *utls.ClientHelloID) model.TLSHandshaker { return newTLSHandshaker(&tlsHandshakerConfigurable{ NewConn: newConnUTLS(id), }, logger) diff --git a/internal/netxlite/utls_test.go b/internal/netxlite/utls_test.go index 2b3a7ea..ce167e7 100644 --- a/internal/netxlite/utls_test.go +++ b/internal/netxlite/utls_test.go @@ -14,7 +14,7 @@ import ( func TestNewTLSHandshakerUTLS(t *testing.T) { th := NewTLSHandshakerUTLS(log.Log, &utls.HelloChrome_83) logger := th.(*tlsHandshakerLogger) - if logger.Logger != log.Log { + if logger.DebugLogger != log.Log { t.Fatal("invalid logger") } errWrapper := logger.TLSHandshaker.(*tlsHandshakerErrWrapper) diff --git a/internal/ooapi/dependencies.go b/internal/ooapi/dependencies.go index 9a66aa5..4e8598a 100644 --- a/internal/ooapi/dependencies.go +++ b/internal/ooapi/dependencies.go @@ -4,6 +4,8 @@ import ( "context" "io" "net/http" + + "github.com/ooni/probe-cli/v3/internal/model" ) // JSONCodec is a JSON encoder and decoder. Generally, we use a @@ -57,10 +59,4 @@ type GobCodec interface { // KVStore is a key-value store. This is the interface the // client expect for the key-value store used to save persistent // state (typically on the file system). -type KVStore interface { - // Get gets a value from the key-value store. - Get(key string) ([]byte, error) - - // Set stores a value into the key-value store. - Set(key string, value []byte) error -} +type KVStore = model.KeyValueStore diff --git a/internal/ooapi/doc.go b/internal/ooapi/doc.go index 79a47de..42cb218 100644 --- a/internal/ooapi/doc.go +++ b/internal/ooapi/doc.go @@ -2,6 +2,11 @@ // automatically generate the code in this package from the // apimodel and internal/generator packages. // +// Note +// +// This package is currrently unused. We plan on replacing +// existing code to speak with the OONI API with it. +// // Usage // // You need to create a Client. Make sure you set all diff --git a/internal/ptx/dependencies.go b/internal/ptx/dependencies.go index a2dd69f..40b4f44 100644 --- a/internal/ptx/dependencies.go +++ b/internal/ptx/dependencies.go @@ -3,6 +3,8 @@ package ptx import ( "context" "net" + + "github.com/ooni/probe-cli/v3/internal/model" ) // UnderlyingDialer is the underlying dialer used for dialing. @@ -11,29 +13,5 @@ type UnderlyingDialer interface { DialContext(ctx context.Context, network, address string) (net.Conn, error) } -// Logger allows us to log messages. -type Logger interface { - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Infof formats and emits an informational message. - Infof(format string, v ...interface{}) - - // Warnf formats and emits a warning message. - Warnf(format string, v ...interface{}) -} - -// silentLogger implements Logger. -type silentLogger struct{} - -// Debugf implements Logger.Debugf. -func (*silentLogger) Debugf(format string, v ...interface{}) {} - -// Infof implements Logger.Infof. -func (*silentLogger) Infof(format string, v ...interface{}) {} - -// Warnf implements Logger.Warnf. -func (*silentLogger) Warnf(format string, v ...interface{}) {} - // defaultLogger is the default silentLogger instance. -var defaultLogger Logger = &silentLogger{} +var defaultLogger model.Logger = model.DiscardLogger diff --git a/internal/ptx/obfs4_test.go b/internal/ptx/obfs4_test.go index e00d3c0..3f22653 100644 --- a/internal/ptx/obfs4_test.go +++ b/internal/ptx/obfs4_test.go @@ -9,7 +9,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestOBFS4DialerWorks(t *testing.T) { diff --git a/internal/ptx/ptx.go b/internal/ptx/ptx.go index 736c39d..da1b50c 100644 --- a/internal/ptx/ptx.go +++ b/internal/ptx/ptx.go @@ -45,6 +45,7 @@ import ( "sync" pt "git.torproject.org/pluggable-transports/goptlib.git" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/netxlite" ) @@ -75,7 +76,7 @@ type Listener struct { // Logger is the optional logger. When not set, this library // will not emit logs. (But the underlying pluggable transport // may still emit its own log messages.) - Logger Logger + Logger model.Logger // mu provides mutual exclusion for accessing internals. mu sync.Mutex @@ -94,7 +95,7 @@ type Listener struct { } // logger returns the Logger, if set, or the defaultLogger. -func (lst *Listener) logger() Logger { +func (lst *Listener) logger() model.Logger { if lst.Logger != nil { return lst.Logger } diff --git a/internal/ptx/ptx_test.go b/internal/ptx/ptx_test.go index 40c6048..59839d8 100644 --- a/internal/ptx/ptx_test.go +++ b/internal/ptx/ptx_test.go @@ -14,7 +14,7 @@ import ( "github.com/apex/log" "github.com/ooni/probe-cli/v3/internal/atomicx" "github.com/ooni/probe-cli/v3/internal/netxlite" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestListenerLoggerWorks(t *testing.T) { diff --git a/internal/ptx/snowflake_test.go b/internal/ptx/snowflake_test.go index 8e73215..844760e 100644 --- a/internal/ptx/snowflake_test.go +++ b/internal/ptx/snowflake_test.go @@ -7,7 +7,7 @@ import ( "testing" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/netxlite/mocks" + "github.com/ooni/probe-cli/v3/internal/model/mocks" ) func TestSnowflakeDialerWorks(t *testing.T) { diff --git a/internal/scrubber/logger.go b/internal/scrubber/logger.go index 813ad44..828374d 100644 --- a/internal/scrubber/logger.go +++ b/internal/scrubber/logger.go @@ -1,39 +1,21 @@ package scrubber -import "fmt" +import ( + "fmt" -// UnderlyingLogger defines the common interface that a logger should have. It is -// out of the box compatible with `log.Log` in `apex/log`. -type UnderlyingLogger interface { - // Debug emits a debug message. - Debug(msg string) - - // Debugf formats and emits a debug message. - Debugf(format string, v ...interface{}) - - // Info emits an informational message. - Info(msg string) - - // Infof formats and emits an informational message. - Infof(format string, v ...interface{}) - - // Warn emits a warning message. - Warn(msg string) - - // Warnf formats and emits a warning message. - Warnf(format string, v ...interface{}) -} + "github.com/ooni/probe-cli/v3/internal/model" +) // Logger is a Logger with scrubbing. All messages are scrubbed // including the ones that won't be emitted. As such, this logger // is less efficient than a logger without scrubbing. type Logger struct { - UnderlyingLogger + model.Logger } // Debug scrubs and emits a debug message. func (sl *Logger) Debug(message string) { - sl.UnderlyingLogger.Debug(Scrub(message)) + sl.Logger.Debug(Scrub(message)) } // Debugf scrubs, formats, and emits a debug message. @@ -43,7 +25,7 @@ func (sl *Logger) Debugf(format string, v ...interface{}) { // Info scrubs and emits an informational message. func (sl *Logger) Info(message string) { - sl.UnderlyingLogger.Info(Scrub(message)) + sl.Logger.Info(Scrub(message)) } // Infof scrubs, formats, and emits an informational message. @@ -53,7 +35,7 @@ func (sl *Logger) Infof(format string, v ...interface{}) { // Warn scrubs and emits a warning message. func (sl *Logger) Warn(message string) { - sl.UnderlyingLogger.Warn(Scrub(message)) + sl.Logger.Warn(Scrub(message)) } // Warnf scrubs, formats, and emits a warning message. diff --git a/internal/scrubber/logger_test.go b/internal/scrubber/logger_test.go index a90d760..1ffad86 100644 --- a/internal/scrubber/logger_test.go +++ b/internal/scrubber/logger_test.go @@ -41,7 +41,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for debug", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Debug(input) if len(logger.debug) != 1 && len(logger.info) != 0 && len(logger.warn) != 0 { t.Fatal("unexpected number of log lines written") @@ -53,7 +53,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for debugf", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Debugf("%s", input) if len(logger.debug) != 1 && len(logger.info) != 0 && len(logger.warn) != 0 { t.Fatal("unexpected number of log lines written") @@ -65,7 +65,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for info", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Info(input) if len(logger.debug) != 0 && len(logger.info) != 1 && len(logger.warn) != 0 { t.Fatal("unexpected number of log lines written") @@ -77,7 +77,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for infof", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Infof("%s", input) if len(logger.debug) != 0 && len(logger.info) != 1 && len(logger.warn) != 0 { t.Fatal("unexpected number of log lines written") @@ -89,7 +89,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for warn", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Warn(input) if len(logger.debug) != 0 && len(logger.info) != 0 && len(logger.warn) != 1 { t.Fatal("unexpected number of log lines written") @@ -101,7 +101,7 @@ func TestScrubLogger(t *testing.T) { t.Run("for warnf", func(t *testing.T) { logger := new(savingLogger) - scrubber := &Logger{UnderlyingLogger: logger} + scrubber := &Logger{Logger: logger} scrubber.Warnf("%s", input) if len(logger.debug) != 0 && len(logger.info) != 0 && len(logger.warn) != 1 { t.Fatal("unexpected number of log lines written") diff --git a/internal/shellx/shellx.go b/internal/shellx/shellx.go index 50ccf13..0f2f1c9 100644 --- a/internal/shellx/shellx.go +++ b/internal/shellx/shellx.go @@ -7,14 +7,10 @@ import ( "strings" "github.com/google/shlex" + "github.com/ooni/probe-cli/v3/internal/model" "golang.org/x/sys/execabs" ) -// Logger is the logger expected by this package. -type Logger interface { - Infof(format string, v ...interface{}) -} - // runconfig is the configuration for run. type runconfig struct { // args contains the command line arguments. @@ -48,7 +44,7 @@ func run(config runconfig) error { } // Run executes the specified command with the specified args. -func Run(logger Logger, name string, arg ...string) error { +func Run(logger model.InfoLogger, name string, arg ...string) error { return run(runconfig{ args: arg, command: name, @@ -76,7 +72,7 @@ func RunQuiet(name string, arg ...string) error { var ErrNoCommandToExecute = errors.New("shellx: no command to execute") // RunCommandline executes the given command line. -func RunCommandline(logger Logger, cmdline string) error { +func RunCommandline(logger model.InfoLogger, cmdline string) error { args, err := shlex.Split(cmdline) if err != nil { return err diff --git a/internal/tunnel/config.go b/internal/tunnel/config.go index f5fe1c8..812ccc5 100644 --- a/internal/tunnel/config.go +++ b/internal/tunnel/config.go @@ -8,17 +8,11 @@ import ( "github.com/armon/go-socks5" "github.com/cretz/bine/control" "github.com/cretz/bine/tor" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/psiphon/oopsi/github.com/Psiphon-Labs/psiphon-tunnel-core/ClientLibrary/clientlib" "golang.org/x/sys/execabs" ) -// Logger is the logger to use. Its signature is compatibile -// with the apex/log logger signature. -type Logger interface { - // Infof formats and emits an informative message - Infof(format string, v ...interface{}) -} - // Config contains the configuration for creating a Tunnel instance. You need // to fill all the mandatory fields. You SHOULD NOT modify the content of this // structure while in use, because that may lead to data races. @@ -41,7 +35,7 @@ type Config struct { // Logger is the optional logger to use. If empty we use a default // implementation that does not emit any output. - Logger Logger + Logger model.InfoLogger // TorArgs contains the optional arguments that you want us to pass // to the tor binary when invoking it. By default we do not @@ -81,21 +75,12 @@ type Config struct { testTorGetInfo func(ctrl *control.Conn, keys ...string) ([]*control.KeyVal, error) } -// silentLogger is a logger that does not emit output. -type silentLogger struct{} - -// Infof implements Logger.Infof. -func (sl *silentLogger) Infof(format string, v ...interface{}) {} - -// defaultLogger is the default logger. -var defaultLogger = &silentLogger{} - // logger returns the logger to use. -func (c *Config) logger() Logger { +func (c *Config) logger() model.InfoLogger { if c.Logger != nil { return c.Logger } - return defaultLogger + return model.DiscardLogger } // execabsLookPath calls either testExeabsLookPath or execabs.LookPath diff --git a/internal/tunnel/config_test.go b/internal/tunnel/config_test.go index 6861a42..9484da7 100644 --- a/internal/tunnel/config_test.go +++ b/internal/tunnel/config_test.go @@ -6,11 +6,12 @@ import ( "testing" "github.com/apex/log" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestConfigLoggerDefault(t *testing.T) { config := &Config{} - if config.logger() != defaultLogger { + if config.logger() != model.DiscardLogger { t.Fatal("not the logger we expected") } } diff --git a/internal/tutorial/experiment/torsf/chapter01/README.md b/internal/tutorial/experiment/torsf/chapter01/README.md index 4fd8a78..d357321 100644 --- a/internal/tutorial/experiment/torsf/chapter01/README.md +++ b/internal/tutorial/experiment/torsf/chapter01/README.md @@ -69,7 +69,7 @@ The mockable package contains widely used mocks. The model package contains the data model used by OONI experiments. ```Go - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ``` diff --git a/internal/tutorial/experiment/torsf/chapter01/main.go b/internal/tutorial/experiment/torsf/chapter01/main.go index 3f34c57..aef3716 100644 --- a/internal/tutorial/experiment/torsf/chapter01/main.go +++ b/internal/tutorial/experiment/torsf/chapter01/main.go @@ -70,7 +70,7 @@ import ( // The model package contains the data model used by OONI experiments. // // ```Go - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" // ``` // diff --git a/internal/tutorial/experiment/torsf/chapter02/README.md b/internal/tutorial/experiment/torsf/chapter02/README.md index 6ca8ce6..c9a2fbd 100644 --- a/internal/tutorial/experiment/torsf/chapter02/README.md +++ b/internal/tutorial/experiment/torsf/chapter02/README.md @@ -39,7 +39,7 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) ``` diff --git a/internal/tutorial/experiment/torsf/chapter02/main.go b/internal/tutorial/experiment/torsf/chapter02/main.go index d4e612b..4464bdc 100644 --- a/internal/tutorial/experiment/torsf/chapter02/main.go +++ b/internal/tutorial/experiment/torsf/chapter02/main.go @@ -8,7 +8,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/model" "golang.org/x/sys/execabs" ) diff --git a/internal/tutorial/experiment/torsf/chapter02/torsf.go b/internal/tutorial/experiment/torsf/chapter02/torsf.go index 298ec03..af3e0f6 100644 --- a/internal/tutorial/experiment/torsf/chapter02/torsf.go +++ b/internal/tutorial/experiment/torsf/chapter02/torsf.go @@ -15,7 +15,7 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // ``` diff --git a/internal/tutorial/experiment/torsf/chapter03/main.go b/internal/tutorial/experiment/torsf/chapter03/main.go index ae53ccf..a8dad28 100644 --- a/internal/tutorial/experiment/torsf/chapter03/main.go +++ b/internal/tutorial/experiment/torsf/chapter03/main.go @@ -8,7 +8,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/model" "golang.org/x/sys/execabs" ) diff --git a/internal/tutorial/experiment/torsf/chapter03/torsf.go b/internal/tutorial/experiment/torsf/chapter03/torsf.go index 1b9c611..97b7ae4 100644 --- a/internal/tutorial/experiment/torsf/chapter03/torsf.go +++ b/internal/tutorial/experiment/torsf/chapter03/torsf.go @@ -4,7 +4,7 @@ import ( "context" "time" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // Config contains config for the torsf experiment. diff --git a/internal/tutorial/experiment/torsf/chapter04/README.md b/internal/tutorial/experiment/torsf/chapter04/README.md index da937de..ff4713c 100644 --- a/internal/tutorial/experiment/torsf/chapter04/README.md +++ b/internal/tutorial/experiment/torsf/chapter04/README.md @@ -30,7 +30,7 @@ As we have already seen, the `model` package defines the generic data model used by all experiments. ```Go - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ``` diff --git a/internal/tutorial/experiment/torsf/chapter04/main.go b/internal/tutorial/experiment/torsf/chapter04/main.go index ae53ccf..a8dad28 100644 --- a/internal/tutorial/experiment/torsf/chapter04/main.go +++ b/internal/tutorial/experiment/torsf/chapter04/main.go @@ -8,7 +8,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/model" "golang.org/x/sys/execabs" ) diff --git a/internal/tutorial/experiment/torsf/chapter04/torsf.go b/internal/tutorial/experiment/torsf/chapter04/torsf.go index 1ba96d0..be9a498 100644 --- a/internal/tutorial/experiment/torsf/chapter04/torsf.go +++ b/internal/tutorial/experiment/torsf/chapter04/torsf.go @@ -33,7 +33,7 @@ import ( // generic data model used by all experiments. // // ```Go - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" // ``` // diff --git a/pkg/oonimkall/experiment.go b/pkg/oonimkall/experiment.go index 559af1c..117a3d0 100644 --- a/pkg/oonimkall/experiment.go +++ b/pkg/oonimkall/experiment.go @@ -4,7 +4,7 @@ import ( "context" "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // experimentSession is the abstract representation of diff --git a/pkg/oonimkall/experiment_test.go b/pkg/oonimkall/experiment_test.go index 8ff2779..5423693 100644 --- a/pkg/oonimkall/experiment_test.go +++ b/pkg/oonimkall/experiment_test.go @@ -5,7 +5,7 @@ import ( "sync" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // FakeExperimentCallbacks contains fake ExperimentCallbacks. diff --git a/pkg/oonimkall/session.go b/pkg/oonimkall/session.go index da63b02..955ccfb 100644 --- a/pkg/oonimkall/session.go +++ b/pkg/oonimkall/session.go @@ -11,9 +11,9 @@ import ( "github.com/ooni/probe-cli/v3/internal/atomicx" "github.com/ooni/probe-cli/v3/internal/engine" "github.com/ooni/probe-cli/v3/internal/engine/legacy/assetsdir" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/engine/probeservices" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) @@ -161,9 +161,9 @@ func newSessionWithContext(ctx context.Context, config *SessionConfig) (*Session // the return value as it does not matter to us here. _, _ = assetsdir.Cleanup(config.AssetsDir) - var availableps []model.Service + var availableps []model.OOAPIService if config.ProbeServicesURL != "" { - availableps = append(availableps, model.Service{ + availableps = append(availableps, model.OOAPIService{ Address: config.ProbeServicesURL, Type: "https", }) @@ -347,8 +347,8 @@ func (ckw *CheckInConfigWebConnectivity) Add(cat string) { ckw.CategoryCodes = append(ckw.CategoryCodes, cat) } -func (ckw *CheckInConfigWebConnectivity) toModel() model.CheckInConfigWebConnectivity { - return model.CheckInConfigWebConnectivity{ +func (ckw *CheckInConfigWebConnectivity) toModel() model.OOAPICheckInConfigWebConnectivity { + return model.OOAPICheckInConfigWebConnectivity{ CategoryCodes: ckw.CategoryCodes, } } @@ -386,7 +386,7 @@ type CheckInInfoWebConnectivity struct { ReportID string // URLs contains the list of URLs to measure. - URLs []model.URLInfo + URLs []model.OOAPIURLInfo } // URLInfo contains info on a specific URL to measure. @@ -421,7 +421,7 @@ func (ckw *CheckInInfoWebConnectivity) At(idx int64) *URLInfo { } } -func newCheckInInfoWebConnectivity(ckw *model.CheckInInfoWebConnectivity) *CheckInInfoWebConnectivity { +func newCheckInInfoWebConnectivity(ckw *model.OOAPICheckInInfoWebConnectivity) *CheckInInfoWebConnectivity { if ckw == nil { return nil } @@ -466,7 +466,7 @@ func (sess *Session) CheckIn(ctx *Context, config *CheckInConfig) (*CheckInInfo, if sess.TestingCheckInBeforeCheckIn != nil { sess.TestingCheckInBeforeCheckIn(ctx) // for testing } - cfg := model.CheckInConfig{ + cfg := model.OOAPICheckInConfig{ Charging: config.Charging, OnWiFi: config.OnWiFi, Platform: config.Platform, @@ -494,7 +494,7 @@ type URLListConfig struct { // URLListResult contains the URLs returned from the FetchURL API type URLListResult struct { - Results []model.URLInfo + Results []model.OOAPIURLInfo } // AddCategory adds category code to the array in URLListConfig @@ -538,7 +538,7 @@ func (sess *Session) FetchURLList(ctx *Context, config *URLListConfig) (*URLList config.CountryCode = info.CountryCode } } - cfg := model.URLListConfig{ + cfg := model.OOAPIURLListConfig{ Categories: config.Categories, CountryCode: config.CountryCode, Limit: config.Limit, diff --git a/pkg/oonimkall/session_integration_test.go b/pkg/oonimkall/session_integration_test.go index e725d98..8faf935 100644 --- a/pkg/oonimkall/session_integration_test.go +++ b/pkg/oonimkall/session_integration_test.go @@ -13,7 +13,7 @@ import ( "time" "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/model" "github.com/ooni/probe-cli/v3/pkg/oonimkall" ) diff --git a/pkg/oonimkall/sessionlogger.go b/pkg/oonimkall/sessionlogger.go index 9d9ab55..39066f3 100644 --- a/pkg/oonimkall/sessionlogger.go +++ b/pkg/oonimkall/sessionlogger.go @@ -3,7 +3,7 @@ package oonimkall import ( "fmt" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type loggerVerbose struct { diff --git a/pkg/oonimkall/sessionlogger_test.go b/pkg/oonimkall/sessionlogger_test.go index c0c4e08..fb107f8 100644 --- a/pkg/oonimkall/sessionlogger_test.go +++ b/pkg/oonimkall/sessionlogger_test.go @@ -8,7 +8,7 @@ import ( "testing" "github.com/google/go-cmp/cmp" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type RecordingLogger struct { diff --git a/pkg/oonimkall/task_test.go b/pkg/oonimkall/task_test.go index 034a1de..9b2b625 100644 --- a/pkg/oonimkall/task_test.go +++ b/pkg/oonimkall/task_test.go @@ -5,7 +5,7 @@ import ( "errors" "testing" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) type eventlike struct { diff --git a/pkg/oonimkall/tasklogger.go b/pkg/oonimkall/tasklogger.go index d50c970..b6550dd 100644 --- a/pkg/oonimkall/tasklogger.go +++ b/pkg/oonimkall/tasklogger.go @@ -3,7 +3,7 @@ package oonimkall import ( "fmt" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // diff --git a/pkg/oonimkall/tasklogger_test.go b/pkg/oonimkall/tasklogger_test.go index 240c711..b332e70 100644 --- a/pkg/oonimkall/tasklogger_test.go +++ b/pkg/oonimkall/tasklogger_test.go @@ -3,7 +3,7 @@ package oonimkall import ( "testing" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // diff --git a/pkg/oonimkall/taskmocks_test.go b/pkg/oonimkall/taskmocks_test.go index 8165916..8b551f6 100644 --- a/pkg/oonimkall/taskmocks_test.go +++ b/pkg/oonimkall/taskmocks_test.go @@ -6,7 +6,7 @@ import ( "sync" "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // diff --git a/pkg/oonimkall/taskmodel.go b/pkg/oonimkall/taskmodel.go index 5b75930..12dfdee 100644 --- a/pkg/oonimkall/taskmodel.go +++ b/pkg/oonimkall/taskmodel.go @@ -5,7 +5,7 @@ import ( "io" "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) // diff --git a/pkg/oonimkall/taskrunner.go b/pkg/oonimkall/taskrunner.go index ac45a9e..fcef32d 100644 --- a/pkg/oonimkall/taskrunner.go +++ b/pkg/oonimkall/taskrunner.go @@ -8,7 +8,7 @@ import ( "time" "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" "github.com/ooni/probe-cli/v3/internal/runtimex" ) @@ -68,7 +68,7 @@ func (r *runnerForTask) newsession(ctx context.Context, logger model.Logger) (ta TunnelDir: r.settings.TunnelDir, } if r.settings.Options.ProbeServicesBaseURL != "" { - config.AvailableProbeServices = []model.Service{{ + config.AvailableProbeServices = []model.OOAPIService{{ Type: "https", Address: r.settings.Options.ProbeServicesBaseURL, }} diff --git a/pkg/oonimkall/taskrunner_test.go b/pkg/oonimkall/taskrunner_test.go index e76f743..7acb6a3 100644 --- a/pkg/oonimkall/taskrunner_test.go +++ b/pkg/oonimkall/taskrunner_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" engine "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestMeasurementSubmissionEventName(t *testing.T) { diff --git a/pkg/oonimkall/tasksession.go b/pkg/oonimkall/tasksession.go index c6d31f7..1a785d9 100644 --- a/pkg/oonimkall/tasksession.go +++ b/pkg/oonimkall/tasksession.go @@ -4,8 +4,8 @@ import ( "context" "github.com/ooni/probe-cli/v3/internal/engine" - "github.com/ooni/probe-cli/v3/internal/engine/model" "github.com/ooni/probe-cli/v3/internal/kvstore" + "github.com/ooni/probe-cli/v3/internal/model" ) // diff --git a/pkg/oonimkall/webconnectivity_test.go b/pkg/oonimkall/webconnectivity_test.go index 795e3cc..552e1bc 100644 --- a/pkg/oonimkall/webconnectivity_test.go +++ b/pkg/oonimkall/webconnectivity_test.go @@ -8,7 +8,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/ooni/probe-cli/v3/internal/atomicx" - "github.com/ooni/probe-cli/v3/internal/engine/model" + "github.com/ooni/probe-cli/v3/internal/model" ) func TestWebConnectivityRunnerWithMaybeLookupBackendsFailure(t *testing.T) {