From 15dac36fc1027808215b9d8c7219a0498cb996ec Mon Sep 17 00:00:00 2001 From: Simone Basso Date: Wed, 5 Jun 2024 20:02:21 +0200 Subject: [PATCH] fix(registry): instantiate factory for each invocation (#1614) The current structure of the `*registry.Factory` registry is that we register an experiment like this: ```Go func init() { AllExperiments["dnscheck"] = &Factory{ build: func(config interface{}) model.ExperimentMeasurer { return dnscheck.NewExperimentMeasurer( *config.(*dnscheck.Config), ) }, config: &dnscheck.Config{}, enabledByDefault: true, inputPolicy: model.InputOrStaticDefault, } } ``` Then, when we're setting options, we're modifying the `config` directly with code like this: ```Go // SetOptionAny sets an option given any value. func (b *Factory) SetOptionAny(key string, value any) error { field, err := b.fieldbyname(b.config, key) if err != nil { return err } switch field.Kind() { case reflect.Int64: return b.setOptionInt(field, value) case reflect.Bool: return b.setOptionBool(field, value) case reflect.String: return b.setOptionString(field, value) default: return fmt.Errorf("%w: %T", ErrUnsupportedOptionType, value) } } ``` Finally, we pass the modified config to a new experiment when we're creating it: ```Go func (b *Factory) NewExperimentMeasurer() model.ExperimentMeasurer { return b.build(b.config) } ``` This means that, if we run two back experiments that both require options, we're going to always reuse the same option structure. This feels wrong. We should instead construct a new factory each time, so we start from empty options: ```Go func init() { AllExperiments["dnscheck"] = func() *Factory { return &Factory{ build: func(config interface{}) model.ExperimentMeasurer { return dnscheck.NewExperimentMeasurer( *config.(*dnscheck.Config), ) }, config: &dnscheck.Config{}, enabledByDefault: true, inputPolicy: model.InputOrStaticDefault, } } } ``` This diff applies this very simple mechanical change. Note that so far we were ~good with the current codebase because we don't use options much and generally we invoke each experiment just once per run. This is going to change with OONI Run v2 and richer input. Therefore, it makes sense to tackle this issue now in the context of https://github.com/ooni/probe/issues/2607. --- internal/cmd/miniooni/main.go | 3 ++- internal/registry/allexperiments.go | 2 +- internal/registry/dash.go | 22 ++++++++++--------- internal/registry/dnscheck.go | 20 ++++++++++-------- internal/registry/dnsping.go | 20 ++++++++++-------- internal/registry/dslxtutorial.go | 18 +++++++++------- internal/registry/echcheck.go | 18 +++++++++------- internal/registry/example.go | 28 +++++++++++++------------ internal/registry/factory.go | 7 ++++--- internal/registry/fbmessenger.go | 20 ++++++++++-------- internal/registry/hhfm.go | 20 ++++++++++-------- internal/registry/hirl.go | 20 ++++++++++-------- internal/registry/httphostheader.go | 20 ++++++++++-------- internal/registry/ndt.go | 22 ++++++++++--------- internal/registry/portfiltering.go | 22 ++++++++++--------- internal/registry/psiphon.go | 20 ++++++++++-------- internal/registry/quicping.go | 20 ++++++++++-------- internal/registry/riseupvpn.go | 18 +++++++++------- internal/registry/signal.go | 20 ++++++++++-------- internal/registry/simplequicping.go | 20 ++++++++++-------- internal/registry/sniblocking.go | 20 ++++++++++-------- internal/registry/stunreachability.go | 20 ++++++++++-------- internal/registry/tcpping.go | 20 ++++++++++-------- internal/registry/telegram.go | 22 ++++++++++--------- internal/registry/tlsmiddlebox.go | 20 ++++++++++-------- internal/registry/tlsping.go | 20 ++++++++++-------- internal/registry/tlstool.go | 20 ++++++++++-------- internal/registry/tor.go | 20 ++++++++++-------- internal/registry/torsf.go | 20 ++++++++++-------- internal/registry/urlgetter.go | 20 ++++++++++-------- internal/registry/vanillator.go | 26 ++++++++++++----------- internal/registry/webconnectivity.go | 22 ++++++++++--------- internal/registry/webconnectivityv05.go | 22 ++++++++++--------- internal/registry/whatsapp.go | 20 ++++++++++-------- 34 files changed, 358 insertions(+), 294 deletions(-) diff --git a/internal/cmd/miniooni/main.go b/internal/cmd/miniooni/main.go index 4bab5d7340..db9e71da9b 100644 --- a/internal/cmd/miniooni/main.go +++ b/internal/cmd/miniooni/main.go @@ -232,7 +232,7 @@ func registerOONIRun(rootCmd *cobra.Command, globalOptions *Options) { // registerAllExperiments registers a subcommand for each experiment func registerAllExperiments(rootCmd *cobra.Command, globalOptions *Options) { - for name, factory := range registry.AllExperiments { + for name, ff := range registry.AllExperiments { subCmd := &cobra.Command{ Use: name, Short: fmt.Sprintf("Runs the %s experiment", name), @@ -243,6 +243,7 @@ func registerAllExperiments(rootCmd *cobra.Command, globalOptions *Options) { } rootCmd.AddCommand(subCmd) flags := subCmd.Flags() + factory := ff() switch factory.InputPolicy() { case model.InputOrQueryBackend, diff --git a/internal/registry/allexperiments.go b/internal/registry/allexperiments.go index 39ce61226b..8fe9edd334 100644 --- a/internal/registry/allexperiments.go +++ b/internal/registry/allexperiments.go @@ -3,7 +3,7 @@ package registry import "sort" // Where we register all the available experiments. -var AllExperiments = map[string]*Factory{} +var AllExperiments = map[string]func() *Factory{} // ExperimentNames returns the name of all experiments func ExperimentNames() (names []string) { diff --git a/internal/registry/dash.go b/internal/registry/dash.go index 59175fca0c..812619361b 100644 --- a/internal/registry/dash.go +++ b/internal/registry/dash.go @@ -10,15 +10,17 @@ import ( ) func init() { - AllExperiments["dash"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return dash.NewExperimentMeasurer( - *config.(*dash.Config), - ) - }, - config: &dash.Config{}, - enabledByDefault: true, - interruptible: true, - inputPolicy: model.InputNone, + AllExperiments["dash"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return dash.NewExperimentMeasurer( + *config.(*dash.Config), + ) + }, + config: &dash.Config{}, + enabledByDefault: true, + interruptible: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/dnscheck.go b/internal/registry/dnscheck.go index 3d474613a2..b9355773fc 100644 --- a/internal/registry/dnscheck.go +++ b/internal/registry/dnscheck.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["dnscheck"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return dnscheck.NewExperimentMeasurer( - *config.(*dnscheck.Config), - ) - }, - config: &dnscheck.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrStaticDefault, + AllExperiments["dnscheck"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return dnscheck.NewExperimentMeasurer( + *config.(*dnscheck.Config), + ) + }, + config: &dnscheck.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrStaticDefault, + } } } diff --git a/internal/registry/dnsping.go b/internal/registry/dnsping.go index 1ccb3122c0..92d52456ed 100644 --- a/internal/registry/dnsping.go +++ b/internal/registry/dnsping.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["dnsping"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return dnsping.NewExperimentMeasurer( - *config.(*dnsping.Config), - ) - }, - config: &dnsping.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrStaticDefault, + AllExperiments["dnsping"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return dnsping.NewExperimentMeasurer( + *config.(*dnsping.Config), + ) + }, + config: &dnsping.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrStaticDefault, + } } } diff --git a/internal/registry/dslxtutorial.go b/internal/registry/dslxtutorial.go index d74ca87405..41aef7d40c 100644 --- a/internal/registry/dslxtutorial.go +++ b/internal/registry/dslxtutorial.go @@ -10,13 +10,15 @@ import ( ) func init() { - AllExperiments["simple_sni"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return chapter02.NewExperimentMeasurer( - *config.(*chapter02.Config), - ) - }, - config: &chapter02.Config{}, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["simple_sni"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return chapter02.NewExperimentMeasurer( + *config.(*chapter02.Config), + ) + }, + config: &chapter02.Config{}, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/echcheck.go b/internal/registry/echcheck.go index d9826d3671..b091d58af9 100644 --- a/internal/registry/echcheck.go +++ b/internal/registry/echcheck.go @@ -10,13 +10,15 @@ import ( ) func init() { - AllExperiments["echcheck"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return echcheck.NewExperimentMeasurer( - *config.(*echcheck.Config), - ) - }, - config: &echcheck.Config{}, - inputPolicy: model.InputOptional, + AllExperiments["echcheck"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return echcheck.NewExperimentMeasurer( + *config.(*echcheck.Config), + ) + }, + config: &echcheck.Config{}, + inputPolicy: model.InputOptional, + } } } diff --git a/internal/registry/example.go b/internal/registry/example.go index e487b22f04..aa2d13ee11 100644 --- a/internal/registry/example.go +++ b/internal/registry/example.go @@ -12,18 +12,20 @@ import ( ) func init() { - AllExperiments["example"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return example.NewExperimentMeasurer( - *config.(*example.Config), "example", - ) - }, - config: &example.Config{ - Message: "Good day from the example experiment!", - SleepTime: int64(time.Second), - }, - enabledByDefault: true, - interruptible: true, - inputPolicy: model.InputNone, + AllExperiments["example"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return example.NewExperimentMeasurer( + *config.(*example.Config), "example", + ) + }, + config: &example.Config{ + Message: "Good day from the example experiment!", + SleepTime: int64(time.Second), + }, + enabledByDefault: true, + interruptible: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/factory.go b/internal/registry/factory.go index 937c22e979..f0baa34806 100644 --- a/internal/registry/factory.go +++ b/internal/registry/factory.go @@ -213,7 +213,7 @@ func (b *Factory) fieldbyname(v interface{}, key string) (reflect.Value, error) return field, nil } -// NewExperimentMeasurer creates the experiment +// NewExperimentMeasurer creates a new [model.ExperimentMeasurer] instance. func (b *Factory) NewExperimentMeasurer() model.ExperimentMeasurer { return b.build(b.config) } @@ -305,10 +305,11 @@ func NewFactory(name string, kvStore model.KeyValueStore, logger model.Logger) ( } // Obtain the factory for the canonical name. - factory := AllExperiments[name] - if factory == nil { + ff := AllExperiments[name] + if ff == nil { return nil, fmt.Errorf("%w: %s", ErrNoSuchExperiment, name) } + factory := ff() // Some experiments are not enabled by default. To enable them we use // the cached check-in response or an environment variable. diff --git a/internal/registry/fbmessenger.go b/internal/registry/fbmessenger.go index 0e3be67df0..d3f3233e3a 100644 --- a/internal/registry/fbmessenger.go +++ b/internal/registry/fbmessenger.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["facebook_messenger"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return fbmessenger.NewExperimentMeasurer( - *config.(*fbmessenger.Config), - ) - }, - config: &fbmessenger.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["facebook_messenger"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return fbmessenger.NewExperimentMeasurer( + *config.(*fbmessenger.Config), + ) + }, + config: &fbmessenger.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/hhfm.go b/internal/registry/hhfm.go index 44eb426e92..0820a86476 100644 --- a/internal/registry/hhfm.go +++ b/internal/registry/hhfm.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["http_header_field_manipulation"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return hhfm.NewExperimentMeasurer( - *config.(*hhfm.Config), - ) - }, - config: &hhfm.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["http_header_field_manipulation"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return hhfm.NewExperimentMeasurer( + *config.(*hhfm.Config), + ) + }, + config: &hhfm.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/hirl.go b/internal/registry/hirl.go index 1209052fc1..846493bc8f 100644 --- a/internal/registry/hirl.go +++ b/internal/registry/hirl.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["http_invalid_request_line"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return hirl.NewExperimentMeasurer( - *config.(*hirl.Config), - ) - }, - config: &hirl.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["http_invalid_request_line"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return hirl.NewExperimentMeasurer( + *config.(*hirl.Config), + ) + }, + config: &hirl.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/httphostheader.go b/internal/registry/httphostheader.go index 0eaa98c654..c1ecffd76f 100644 --- a/internal/registry/httphostheader.go +++ b/internal/registry/httphostheader.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["http_host_header"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return httphostheader.NewExperimentMeasurer( - *config.(*httphostheader.Config), - ) - }, - config: &httphostheader.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["http_host_header"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return httphostheader.NewExperimentMeasurer( + *config.(*httphostheader.Config), + ) + }, + config: &httphostheader.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/ndt.go b/internal/registry/ndt.go index c07d5ff7ff..e6891c7c7b 100644 --- a/internal/registry/ndt.go +++ b/internal/registry/ndt.go @@ -10,15 +10,17 @@ import ( ) func init() { - AllExperiments["ndt"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return ndt7.NewExperimentMeasurer( - *config.(*ndt7.Config), - ) - }, - config: &ndt7.Config{}, - enabledByDefault: true, - interruptible: true, - inputPolicy: model.InputNone, + AllExperiments["ndt"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return ndt7.NewExperimentMeasurer( + *config.(*ndt7.Config), + ) + }, + config: &ndt7.Config{}, + enabledByDefault: true, + interruptible: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/portfiltering.go b/internal/registry/portfiltering.go index 36e152f38b..56937eaca1 100644 --- a/internal/registry/portfiltering.go +++ b/internal/registry/portfiltering.go @@ -10,15 +10,17 @@ import ( ) func init() { - AllExperiments["portfiltering"] = &Factory{ - build: func(config any) model.ExperimentMeasurer { - return portfiltering.NewExperimentMeasurer( - config.(portfiltering.Config), - ) - }, - config: portfiltering.Config{}, - enabledByDefault: true, - interruptible: false, - inputPolicy: model.InputNone, + AllExperiments["portfiltering"] = func() *Factory { + return &Factory{ + build: func(config any) model.ExperimentMeasurer { + return portfiltering.NewExperimentMeasurer( + config.(portfiltering.Config), + ) + }, + config: portfiltering.Config{}, + enabledByDefault: true, + interruptible: false, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/psiphon.go b/internal/registry/psiphon.go index 46ff7e06ca..48dc7888a2 100644 --- a/internal/registry/psiphon.go +++ b/internal/registry/psiphon.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["psiphon"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return psiphon.NewExperimentMeasurer( - *config.(*psiphon.Config), - ) - }, - config: &psiphon.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOptional, + AllExperiments["psiphon"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return psiphon.NewExperimentMeasurer( + *config.(*psiphon.Config), + ) + }, + config: &psiphon.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOptional, + } } } diff --git a/internal/registry/quicping.go b/internal/registry/quicping.go index 67a87870c9..090037ad78 100644 --- a/internal/registry/quicping.go +++ b/internal/registry/quicping.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["quicping"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return quicping.NewExperimentMeasurer( - *config.(*quicping.Config), - ) - }, - config: &quicping.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["quicping"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return quicping.NewExperimentMeasurer( + *config.(*quicping.Config), + ) + }, + config: &quicping.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/riseupvpn.go b/internal/registry/riseupvpn.go index cb060ac195..950a86b79e 100644 --- a/internal/registry/riseupvpn.go +++ b/internal/registry/riseupvpn.go @@ -10,13 +10,15 @@ import ( ) func init() { - AllExperiments["riseupvpn"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return riseupvpn.NewExperimentMeasurer( - *config.(*riseupvpn.Config), - ) - }, - config: &riseupvpn.Config{}, - inputPolicy: model.InputNone, + AllExperiments["riseupvpn"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return riseupvpn.NewExperimentMeasurer( + *config.(*riseupvpn.Config), + ) + }, + config: &riseupvpn.Config{}, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/signal.go b/internal/registry/signal.go index 927630ff00..615d44b732 100644 --- a/internal/registry/signal.go +++ b/internal/registry/signal.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["signal"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return signal.NewExperimentMeasurer( - *config.(*signal.Config), - ) - }, - config: &signal.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["signal"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return signal.NewExperimentMeasurer( + *config.(*signal.Config), + ) + }, + config: &signal.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/simplequicping.go b/internal/registry/simplequicping.go index 6b56ad4ed7..8eb3e7c54e 100644 --- a/internal/registry/simplequicping.go +++ b/internal/registry/simplequicping.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["simplequicping"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return simplequicping.NewExperimentMeasurer( - *config.(*simplequicping.Config), - ) - }, - config: &simplequicping.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["simplequicping"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return simplequicping.NewExperimentMeasurer( + *config.(*simplequicping.Config), + ) + }, + config: &simplequicping.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/sniblocking.go b/internal/registry/sniblocking.go index a7f5fb7897..8af8214d68 100644 --- a/internal/registry/sniblocking.go +++ b/internal/registry/sniblocking.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["sni_blocking"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return sniblocking.NewExperimentMeasurer( - *config.(*sniblocking.Config), - ) - }, - config: &sniblocking.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["sni_blocking"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return sniblocking.NewExperimentMeasurer( + *config.(*sniblocking.Config), + ) + }, + config: &sniblocking.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/stunreachability.go b/internal/registry/stunreachability.go index 291f5bb6ac..dfa331c3fc 100644 --- a/internal/registry/stunreachability.go +++ b/internal/registry/stunreachability.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["stunreachability"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return stunreachability.NewExperimentMeasurer( - *config.(*stunreachability.Config), - ) - }, - config: &stunreachability.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrStaticDefault, + AllExperiments["stunreachability"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return stunreachability.NewExperimentMeasurer( + *config.(*stunreachability.Config), + ) + }, + config: &stunreachability.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrStaticDefault, + } } } diff --git a/internal/registry/tcpping.go b/internal/registry/tcpping.go index 89d01189dc..d0ca932494 100644 --- a/internal/registry/tcpping.go +++ b/internal/registry/tcpping.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["tcpping"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return tcpping.NewExperimentMeasurer( - *config.(*tcpping.Config), - ) - }, - config: &tcpping.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["tcpping"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return tcpping.NewExperimentMeasurer( + *config.(*tcpping.Config), + ) + }, + config: &tcpping.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/telegram.go b/internal/registry/telegram.go index d68ffea468..8f61d78baa 100644 --- a/internal/registry/telegram.go +++ b/internal/registry/telegram.go @@ -10,15 +10,17 @@ import ( ) func init() { - AllExperiments["telegram"] = &Factory{ - build: func(config any) model.ExperimentMeasurer { - return telegram.NewExperimentMeasurer( - config.(telegram.Config), - ) - }, - config: telegram.Config{}, - enabledByDefault: true, - interruptible: false, - inputPolicy: model.InputNone, + AllExperiments["telegram"] = func() *Factory { + return &Factory{ + build: func(config any) model.ExperimentMeasurer { + return telegram.NewExperimentMeasurer( + config.(telegram.Config), + ) + }, + config: telegram.Config{}, + enabledByDefault: true, + interruptible: false, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/tlsmiddlebox.go b/internal/registry/tlsmiddlebox.go index 132df65027..a97de82c89 100644 --- a/internal/registry/tlsmiddlebox.go +++ b/internal/registry/tlsmiddlebox.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["tlsmiddlebox"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return tlsmiddlebox.NewExperimentMeasurer( - *config.(*tlsmiddlebox.Config), - ) - }, - config: &tlsmiddlebox.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["tlsmiddlebox"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return tlsmiddlebox.NewExperimentMeasurer( + *config.(*tlsmiddlebox.Config), + ) + }, + config: &tlsmiddlebox.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/tlsping.go b/internal/registry/tlsping.go index 4d49fc59dc..a40723d20b 100644 --- a/internal/registry/tlsping.go +++ b/internal/registry/tlsping.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["tlsping"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return tlsping.NewExperimentMeasurer( - *config.(*tlsping.Config), - ) - }, - config: &tlsping.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["tlsping"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return tlsping.NewExperimentMeasurer( + *config.(*tlsping.Config), + ) + }, + config: &tlsping.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/tlstool.go b/internal/registry/tlstool.go index 8327a4ad7e..8bb70983f2 100644 --- a/internal/registry/tlstool.go +++ b/internal/registry/tlstool.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["tlstool"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return tlstool.NewExperimentMeasurer( - *config.(*tlstool.Config), - ) - }, - config: &tlstool.Config{}, - enabledByDefault: true, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["tlstool"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return tlstool.NewExperimentMeasurer( + *config.(*tlstool.Config), + ) + }, + config: &tlstool.Config{}, + enabledByDefault: true, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/tor.go b/internal/registry/tor.go index 02b6c9b2f9..73098bf770 100644 --- a/internal/registry/tor.go +++ b/internal/registry/tor.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["tor"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return tor.NewExperimentMeasurer( - *config.(*tor.Config), - ) - }, - config: &tor.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["tor"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return tor.NewExperimentMeasurer( + *config.(*tor.Config), + ) + }, + config: &tor.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/torsf.go b/internal/registry/torsf.go index 7e087f59c9..178f01d5e4 100644 --- a/internal/registry/torsf.go +++ b/internal/registry/torsf.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["torsf"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return torsf.NewExperimentMeasurer( - *config.(*torsf.Config), - ) - }, - config: &torsf.Config{}, - enabledByDefault: false, - inputPolicy: model.InputNone, + AllExperiments["torsf"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return torsf.NewExperimentMeasurer( + *config.(*torsf.Config), + ) + }, + config: &torsf.Config{}, + enabledByDefault: false, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/urlgetter.go b/internal/registry/urlgetter.go index 8f8c45985a..63dba20f9e 100644 --- a/internal/registry/urlgetter.go +++ b/internal/registry/urlgetter.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["urlgetter"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return urlgetter.NewExperimentMeasurer( - *config.(*urlgetter.Config), - ) - }, - config: &urlgetter.Config{}, - enabledByDefault: true, - inputPolicy: model.InputStrictlyRequired, + AllExperiments["urlgetter"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return urlgetter.NewExperimentMeasurer( + *config.(*urlgetter.Config), + ) + }, + config: &urlgetter.Config{}, + enabledByDefault: true, + inputPolicy: model.InputStrictlyRequired, + } } } diff --git a/internal/registry/vanillator.go b/internal/registry/vanillator.go index fabf801662..1af548660a 100644 --- a/internal/registry/vanillator.go +++ b/internal/registry/vanillator.go @@ -10,17 +10,19 @@ import ( ) func init() { - AllExperiments["vanilla_tor"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return vanillator.NewExperimentMeasurer( - *config.(*vanillator.Config), - ) - }, - config: &vanillator.Config{}, - // We discussed this topic with @aanorbel. On Android this experiment crashes - // frequently because of https://github.com/ooni/probe/issues/2406. So, it seems - // more cautious to disable it by default and let the check-in API decide. - enabledByDefault: false, - inputPolicy: model.InputNone, + AllExperiments["vanilla_tor"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return vanillator.NewExperimentMeasurer( + *config.(*vanillator.Config), + ) + }, + config: &vanillator.Config{}, + // We discussed this topic with @aanorbel. On Android this experiment crashes + // frequently because of https://github.com/ooni/probe/issues/2406. So, it seems + // more cautious to disable it by default and let the check-in API decide. + enabledByDefault: false, + inputPolicy: model.InputNone, + } } } diff --git a/internal/registry/webconnectivity.go b/internal/registry/webconnectivity.go index 2e8b857861..1ea720d581 100644 --- a/internal/registry/webconnectivity.go +++ b/internal/registry/webconnectivity.go @@ -10,15 +10,17 @@ import ( ) func init() { - AllExperiments["web_connectivity"] = &Factory{ - build: func(config any) model.ExperimentMeasurer { - return webconnectivity.NewExperimentMeasurer( - config.(webconnectivity.Config), - ) - }, - config: webconnectivity.Config{}, - enabledByDefault: true, - interruptible: false, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["web_connectivity"] = func() *Factory { + return &Factory{ + build: func(config any) model.ExperimentMeasurer { + return webconnectivity.NewExperimentMeasurer( + config.(webconnectivity.Config), + ) + }, + config: webconnectivity.Config{}, + enabledByDefault: true, + interruptible: false, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/webconnectivityv05.go b/internal/registry/webconnectivityv05.go index 28a5d3c8de..0881b4448f 100644 --- a/internal/registry/webconnectivityv05.go +++ b/internal/registry/webconnectivityv05.go @@ -12,15 +12,17 @@ import ( ) func init() { - AllExperiments["web_connectivity@v0.5"] = &Factory{ - build: func(config any) model.ExperimentMeasurer { - return webconnectivitylte.NewExperimentMeasurer( - config.(*webconnectivitylte.Config), - ) - }, - config: &webconnectivitylte.Config{}, - enabledByDefault: true, - interruptible: false, - inputPolicy: model.InputOrQueryBackend, + AllExperiments["web_connectivity@v0.5"] = func() *Factory { + return &Factory{ + build: func(config any) model.ExperimentMeasurer { + return webconnectivitylte.NewExperimentMeasurer( + config.(*webconnectivitylte.Config), + ) + }, + config: &webconnectivitylte.Config{}, + enabledByDefault: true, + interruptible: false, + inputPolicy: model.InputOrQueryBackend, + } } } diff --git a/internal/registry/whatsapp.go b/internal/registry/whatsapp.go index cac5efde0e..84acb57898 100644 --- a/internal/registry/whatsapp.go +++ b/internal/registry/whatsapp.go @@ -10,14 +10,16 @@ import ( ) func init() { - AllExperiments["whatsapp"] = &Factory{ - build: func(config interface{}) model.ExperimentMeasurer { - return whatsapp.NewExperimentMeasurer( - *config.(*whatsapp.Config), - ) - }, - config: &whatsapp.Config{}, - enabledByDefault: true, - inputPolicy: model.InputNone, + AllExperiments["whatsapp"] = func() *Factory { + return &Factory{ + build: func(config interface{}) model.ExperimentMeasurer { + return whatsapp.NewExperimentMeasurer( + *config.(*whatsapp.Config), + ) + }, + config: &whatsapp.Config{}, + enabledByDefault: true, + inputPolicy: model.InputNone, + } } }