From 273b70bacc5d68a6e5d58c02d558a5af4583513e Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Mon, 3 Jan 2022 13:53:23 +0100 Subject: [PATCH] refactor: interfaces and data types into the model package (#642) ## Checklist - [x] I have read the [contribution guidelines](https://github.com/ooni/probe-cli/blob/master/CONTRIBUTING.md) - [x] reference issue for this pull request: https://github.com/ooni/probe/issues/1885 - [x] related ooni/spec pull request: N/A Location of the issue tracker: https://github.com/ooni/probe ## Description This PR contains a set of changes to move important interfaces and data types into the `./internal/model` package. The criteria for including an interface or data type in here is roughly that the type should be important and used by several packages. We are especially interested to move more interfaces here to increase modularity. An additional side effect is that, by reading this package, one should be able to understand more quickly how different parts of the codebase interact with each other. This is what I want to move in `internal/model`: - [x] most important interfaces from `internal/netxlite` - [x] everything that was previously part of `internal/engine/model` - [x] mocks from `internal/netxlite/mocks` should also be moved in here as a subpackage --- cmd/ooniprobe/internal/nettests/dnscheck.go | 4 +- cmd/ooniprobe/internal/nettests/nettests.go | 4 +- .../internal/nettests/stunreachability.go | 4 +- .../internal/nettests/web_connectivity.go | 6 +- internal/README.md | 3 + internal/bytecounter/conn_test.go | 2 +- internal/cmd/miniooni/libminiooni.go | 6 +- .../internal/webconnectivity/dns_test.go | 2 +- internal/engine/experiment.go | 2 +- internal/engine/experiment/dash/collect.go | 2 +- internal/engine/experiment/dash/dash.go | 2 +- internal/engine/experiment/dash/dash_test.go | 2 +- internal/engine/experiment/dash/fake_test.go | 2 +- internal/engine/experiment/dash/locate.go | 2 +- internal/engine/experiment/dash/negotiate.go | 2 +- .../engine/experiment/dnscheck/dnscheck.go | 2 +- .../experiment/dnscheck/dnscheck_test.go | 2 +- internal/engine/experiment/example/example.go | 2 +- .../engine/experiment/example/example_test.go | 2 +- .../experiment/fbmessenger/fbmessenger.go | 2 +- .../fbmessenger/fbmessenger_test.go | 4 +- internal/engine/experiment/hhfm/hhfm.go | 2 +- internal/engine/experiment/hhfm/hhfm_test.go | 14 +- internal/engine/experiment/hirl/hirl.go | 2 +- internal/engine/experiment/hirl/hirl_test.go | 22 +- .../httphostheader/httphostheader.go | 2 +- .../httphostheader/httphostheader_test.go | 2 +- internal/engine/experiment/ndt7/dial.go | 2 +- internal/engine/experiment/ndt7/ndt7.go | 2 +- internal/engine/experiment/ndt7/ndt7_test.go | 2 +- internal/engine/experiment/psiphon/psiphon.go | 2 +- .../engine/experiment/psiphon/psiphon_test.go | 2 +- .../engine/experiment/riseupvpn/riseupvpn.go | 2 +- .../experiment/riseupvpn/riseupvpn_test.go | 2 +- internal/engine/experiment/run/dnscheck.go | 2 +- internal/engine/experiment/run/run.go | 2 +- internal/engine/experiment/run/run_test.go | 2 +- internal/engine/experiment/run/table.go | 2 +- internal/engine/experiment/run/urlgetter.go | 2 +- internal/engine/experiment/signal/signal.go | 2 +- .../engine/experiment/signal/signal_test.go | 2 +- .../experiment/sniblocking/sniblocking.go | 2 +- .../sniblocking/sniblocking_test.go | 2 +- .../experiment/stunreachability/fake_test.go | 2 +- .../stunreachability/stunreachability.go | 2 +- .../stunreachability/stunreachability_test.go | 2 +- .../engine/experiment/telegram/telegram.go | 2 +- .../experiment/telegram/telegram_test.go | 2 +- internal/engine/experiment/tlstool/tlstool.go | 2 +- .../engine/experiment/tlstool/tlstool_test.go | 2 +- internal/engine/experiment/tor/tor.go | 14 +- internal/engine/experiment/tor/tor_test.go | 26 +- .../experiment/torsf/integration_test.go | 2 +- internal/engine/experiment/torsf/torsf.go | 2 +- .../engine/experiment/torsf/torsf_test.go | 2 +- .../engine/experiment/urlgetter/configurer.go | 2 +- .../engine/experiment/urlgetter/getter.go | 2 +- internal/engine/experiment/urlgetter/multi.go | 2 +- .../engine/experiment/urlgetter/multi_test.go | 2 +- .../engine/experiment/urlgetter/urlgetter.go | 2 +- .../experiment/urlgetter/urlgetter_test.go | 2 +- .../experiment/webconnectivity/connects.go | 2 +- .../experiment/webconnectivity/control.go | 2 +- .../experiment/webconnectivity/dnslookup.go | 2 +- .../webconnectivity/httpanalysis.go | 2 +- .../experiment/webconnectivity/httpget.go | 2 +- .../experiment/webconnectivity/summary.go | 2 +- .../webconnectivity/webconnectivity.go | 4 +- .../webconnectivity/webconnectivity_test.go | 4 +- .../engine/experiment/websteps/control.go | 2 +- .../engine/experiment/websteps/factory.go | 3 +- .../engine/experiment/websteps/websteps.go | 4 +- .../engine/experiment/webstepsx/measurer.go | 6 +- .../engine/experiment/whatsapp/whatsapp.go | 2 +- .../experiment/whatsapp/whatsapp_test.go | 2 +- .../engine/experiment_integration_test.go | 8 +- internal/engine/experiment_internal_test.go | 2 +- internal/engine/experiment_test.go | 2 +- internal/engine/experimentbuilder.go | 2 +- internal/engine/geolocate/avast.go | 3 +- internal/engine/geolocate/geolocate.go | 23 +- internal/engine/geolocate/invalid_test.go | 4 +- internal/engine/geolocate/ipconfig.go | 3 +- internal/engine/geolocate/ipinfo.go | 3 +- internal/engine/geolocate/iplookup.go | 5 +- internal/engine/geolocate/stun.go | 7 +- internal/engine/geolocate/ubuntu.go | 3 +- internal/engine/httpx/jsonapi.go | 8 +- internal/engine/inputloader.go | 50 ++-- internal/engine/inputloader_network_test.go | 4 +- internal/engine/inputloader_test.go | 34 +-- internal/engine/inputprocessor.go | 4 +- internal/engine/inputprocessor_test.go | 12 +- .../internal/sessionresolver/dependencies.go | 32 --- .../internal/sessionresolver/resolvermaker.go | 3 +- .../sessionresolver/sessionresolver.go | 5 +- internal/engine/kvstore.go | 9 - internal/engine/legacy/errorsx/dialer_test.go | 2 +- internal/engine/legacy/errorsx/quic.go | 16 +- internal/engine/legacy/errorsx/quic_test.go | 11 +- .../engine/legacy/errorsx/resolver_test.go | 2 +- internal/engine/legacy/errorsx/tls_test.go | 2 +- .../engine/legacy/netx/emitterdialer_test.go | 2 +- .../engine/legacy/netxlogger/netxlogger.go | 11 +- .../legacy/oonidatamodel/oonidatamodel.go | 2 +- internal/engine/mockable/mockable.go | 14 +- internal/engine/model/README.md | 3 - internal/engine/model/checkinconfig.go | 19 -- internal/engine/model/checkininfo.go | 12 - internal/engine/model/keyvaluestore.go | 7 - internal/engine/model/model.go | 9 - internal/engine/model/scrub.go | 49 ---- internal/engine/model/service.go | 17 -- internal/engine/model/tortarget.go | 21 -- internal/engine/model/urlinfo.go | 8 - internal/engine/model/urllistconfig.go | 8 - internal/engine/netx/archival/archival.go | 2 +- .../engine/netx/archival/archival_test.go | 2 +- .../engine/netx/dialer/bytecounter_test.go | 2 +- internal/engine/netx/dialer/dialer.go | 16 +- internal/engine/netx/dialer/proxy_test.go | 2 +- internal/engine/netx/dialer/saver_test.go | 2 +- internal/engine/netx/netx.go | 11 +- internal/engine/netx/netx_test.go | 4 +- internal/engine/netx/quicdialer/system.go | 10 +- .../engine/netx/quicdialer/system_test.go | 6 +- internal/engine/netx/resolver/emitter_test.go | 2 +- internal/engine/netx/resolver/legacy.go | 13 +- .../engine/netx/tlsdialer/integration_test.go | 2 +- internal/engine/netx/tlsdialer/logging.go | 7 - internal/engine/probeservices/benchselect.go | 20 +- internal/engine/probeservices/bouncer.go | 4 +- internal/engine/probeservices/checkin.go | 8 +- internal/engine/probeservices/checkin_test.go | 10 +- internal/engine/probeservices/collector.go | 2 +- .../engine/probeservices/collector_test.go | 2 +- .../engine/probeservices/probeservices.go | 4 +- .../probeservices/probeservices_test.go | 48 ++-- internal/engine/probeservices/statefile.go | 2 +- internal/engine/probeservices/tor.go | 4 +- internal/engine/probeservices/urls.go | 6 +- internal/engine/probeservices/urls_test.go | 6 +- internal/engine/saver.go | 2 +- internal/engine/saver_test.go | 2 +- internal/engine/session.go | 28 +- internal/engine/session_integration_test.go | 20 +- internal/engine/session_internal_test.go | 26 +- internal/engine/submitter.go | 2 +- internal/engine/submitter_test.go | 2 +- internal/kvstore/doc.go | 2 + internal/kvstore/fs.go | 3 + internal/kvstore/memory.go | 5 +- internal/measurex/dialer.go | 14 +- internal/measurex/dnsx.go | 11 +- internal/measurex/http.go | 22 +- internal/measurex/logger.go | 18 +- internal/measurex/measurer.go | 11 +- internal/measurex/quic.go | 23 +- internal/measurex/resolver.go | 23 +- internal/measurex/tls.go | 10 +- internal/measurex/tracing.go | 9 +- internal/mlablocate/mlablocate.go | 11 +- internal/mlablocatev2/mlablocatev2.go | 11 +- internal/model/README.md | 6 + internal/model/doc.go | 40 +++ internal/{engine => }/model/experiment.go | 11 +- .../{engine => }/model/experiment_test.go | 5 +- internal/model/keyvaluestore.go | 17 ++ internal/{engine => }/model/logger.go | 31 ++- internal/model/logger_test.go | 13 + internal/{engine => }/model/measurement.go | 53 ++++ .../measurement_test.go} | 30 +-- internal/{netxlite => model}/mocks/dialer.go | 0 .../{netxlite => model}/mocks/dialer_test.go | 0 .../{netxlite => model}/mocks/dnsdecoder.go | 9 +- .../mocks/dnsdecoder_test.go | 3 +- .../{netxlite => model}/mocks/dnsencoder.go | 0 .../mocks/dnsencoder_test.go | 0 .../{netxlite => model}/mocks/dnstransport.go | 0 .../mocks/dnstransport_test.go | 0 internal/model/mocks/doc.go | 2 + internal/{netxlite => model}/mocks/http.go | 0 .../{netxlite => model}/mocks/http_test.go | 0 .../{netxlite => model}/mocks/listener.go | 0 .../mocks/listener_test.go | 0 internal/{netxlite => model}/mocks/logger.go | 0 .../{netxlite => model}/mocks/logger_test.go | 0 internal/{netxlite => model}/mocks/quic.go | 8 +- .../{netxlite => model}/mocks/quic_test.go | 4 +- internal/{netxlite => model}/mocks/reader.go | 0 .../{netxlite => model}/mocks/reader_test.go | 0 .../{netxlite => model}/mocks/resolver.go | 6 +- .../mocks/resolver_test.go | 4 +- internal/{netxlite => model}/mocks/tls.go | 0 .../{netxlite => model}/mocks/tls_test.go | 0 internal/model/netx.go | 249 ++++++++++++++++++ internal/model/ooapi.go | 84 ++++++ internal/netxlite/dialer.go | 57 ++-- internal/netxlite/dialer_test.go | 10 +- internal/netxlite/dnsdecoder.go | 45 +--- internal/netxlite/dnsencoder.go | 24 +- internal/netxlite/dnsoverhttps.go | 9 +- internal/netxlite/dnsoverhttps_test.go | 2 +- internal/netxlite/dnsovertcp.go | 4 +- internal/netxlite/dnsovertcp_test.go | 2 +- internal/netxlite/dnsoverudp.go | 8 +- internal/netxlite/dnsoverudp_test.go | 2 +- internal/netxlite/dnstransport.go | 20 -- internal/netxlite/dnsx/dnsx.go | 14 - internal/netxlite/doc.go | 2 + internal/netxlite/filtering/dns_test.go | 5 +- internal/netxlite/filtering/doc.go | 4 +- internal/netxlite/filtering/logger.go | 23 -- internal/netxlite/filtering/tls_test.go | 2 +- internal/netxlite/filtering/tproxy.go | 28 +- internal/netxlite/filtering/tproxy_test.go | 28 +- internal/netxlite/http.go | 46 ++-- internal/netxlite/http3.go | 9 +- internal/netxlite/http3_test.go | 7 +- internal/netxlite/http_test.go | 2 +- internal/netxlite/integration_test.go | 7 +- internal/netxlite/iox_test.go | 2 +- internal/netxlite/legacy.go | 13 +- internal/netxlite/legacy_test.go | 5 +- internal/netxlite/logger.go | 10 - internal/netxlite/mocks/doc.go | 2 - internal/netxlite/quic.go | 79 ++---- internal/netxlite/quic_test.go | 9 +- internal/netxlite/quicx/quicx.go | 35 --- internal/netxlite/resolver.go | 56 ++-- internal/netxlite/resolver_test.go | 21 +- internal/netxlite/serialresolver.go | 13 +- internal/netxlite/serialresolver_test.go | 5 +- internal/netxlite/tls.go | 75 ++---- internal/netxlite/tls_test.go | 8 +- internal/netxlite/tproxy.go | 38 +-- internal/netxlite/utls.go | 3 +- internal/netxlite/utls_test.go | 2 +- internal/ooapi/dependencies.go | 10 +- internal/ooapi/doc.go | 5 + internal/ptx/dependencies.go | 28 +- internal/ptx/obfs4_test.go | 2 +- internal/ptx/ptx.go | 5 +- internal/ptx/ptx_test.go | 2 +- internal/ptx/snowflake_test.go | 2 +- internal/scrubber/logger.go | 34 +-- internal/scrubber/logger_test.go | 12 +- internal/shellx/shellx.go | 10 +- internal/tunnel/config.go | 23 +- internal/tunnel/config_test.go | 3 +- .../experiment/torsf/chapter01/README.md | 2 +- .../experiment/torsf/chapter01/main.go | 2 +- .../experiment/torsf/chapter02/README.md | 2 +- .../experiment/torsf/chapter02/main.go | 2 +- .../experiment/torsf/chapter02/torsf.go | 2 +- .../experiment/torsf/chapter03/main.go | 2 +- .../experiment/torsf/chapter03/torsf.go | 2 +- .../experiment/torsf/chapter04/README.md | 2 +- .../experiment/torsf/chapter04/main.go | 2 +- .../experiment/torsf/chapter04/torsf.go | 2 +- pkg/oonimkall/experiment.go | 2 +- pkg/oonimkall/experiment_test.go | 2 +- pkg/oonimkall/session.go | 20 +- pkg/oonimkall/session_integration_test.go | 2 +- pkg/oonimkall/sessionlogger.go | 2 +- pkg/oonimkall/sessionlogger_test.go | 2 +- pkg/oonimkall/task_test.go | 2 +- pkg/oonimkall/tasklogger.go | 2 +- pkg/oonimkall/tasklogger_test.go | 2 +- pkg/oonimkall/taskmocks_test.go | 2 +- pkg/oonimkall/taskmodel.go | 2 +- pkg/oonimkall/taskrunner.go | 4 +- pkg/oonimkall/taskrunner_test.go | 2 +- pkg/oonimkall/tasksession.go | 2 +- pkg/oonimkall/webconnectivity_test.go | 2 +- 275 files changed, 1281 insertions(+), 1375 deletions(-) delete mode 100644 internal/engine/internal/sessionresolver/dependencies.go delete mode 100644 internal/engine/kvstore.go delete mode 100644 internal/engine/model/README.md delete mode 100644 internal/engine/model/checkinconfig.go delete mode 100644 internal/engine/model/checkininfo.go delete mode 100644 internal/engine/model/keyvaluestore.go delete mode 100644 internal/engine/model/model.go delete mode 100644 internal/engine/model/scrub.go delete mode 100644 internal/engine/model/service.go delete mode 100644 internal/engine/model/tortarget.go delete mode 100644 internal/engine/model/urlinfo.go delete mode 100644 internal/engine/model/urllistconfig.go delete mode 100644 internal/engine/netx/tlsdialer/logging.go create mode 100644 internal/kvstore/doc.go create mode 100644 internal/model/README.md create mode 100644 internal/model/doc.go rename internal/{engine => }/model/experiment.go (91%) rename internal/{engine => }/model/experiment_test.go (53%) create mode 100644 internal/model/keyvaluestore.go rename internal/{engine => }/model/logger.go (61%) create mode 100644 internal/model/logger_test.go rename internal/{engine => }/model/measurement.go (70%) rename internal/{engine/model/model_test.go => model/measurement_test.go} (90%) rename internal/{netxlite => model}/mocks/dialer.go (100%) rename internal/{netxlite => model}/mocks/dialer_test.go (100%) rename internal/{netxlite => model}/mocks/dnsdecoder.go (61%) rename internal/{netxlite => model}/mocks/dnsdecoder_test.go (88%) rename internal/{netxlite => model}/mocks/dnsencoder.go (100%) rename internal/{netxlite => model}/mocks/dnsencoder_test.go (100%) rename internal/{netxlite => model}/mocks/dnstransport.go (100%) rename internal/{netxlite => model}/mocks/dnstransport_test.go (100%) create mode 100644 internal/model/mocks/doc.go rename internal/{netxlite => model}/mocks/http.go (100%) rename internal/{netxlite => model}/mocks/http_test.go (100%) rename internal/{netxlite => model}/mocks/listener.go (100%) rename internal/{netxlite => model}/mocks/listener_test.go (100%) rename internal/{netxlite => model}/mocks/logger.go (100%) rename internal/{netxlite => model}/mocks/logger_test.go (100%) rename internal/{netxlite => model}/mocks/quic.go (96%) rename internal/{netxlite => model}/mocks/quic_test.go (98%) rename internal/{netxlite => model}/mocks/reader.go (100%) rename internal/{netxlite => model}/mocks/reader_test.go (100%) rename internal/{netxlite => model}/mocks/resolver.go (90%) rename internal/{netxlite => model}/mocks/resolver_test.go (91%) rename internal/{netxlite => model}/mocks/tls.go (100%) rename internal/{netxlite => model}/mocks/tls_test.go (100%) create mode 100644 internal/model/netx.go create mode 100644 internal/model/ooapi.go delete mode 100644 internal/netxlite/dnsx/dnsx.go delete mode 100644 internal/netxlite/filtering/logger.go delete mode 100644 internal/netxlite/logger.go delete mode 100644 internal/netxlite/mocks/doc.go delete mode 100644 internal/netxlite/quicx/quicx.go 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) {