diff --git a/internal/oonirun/experiment.go b/internal/oonirun/experiment.go index 25ee396..6dcd68b 100644 --- a/internal/oonirun/experiment.go +++ b/internal/oonirun/experiment.go @@ -8,6 +8,7 @@ import ( "context" "fmt" "math/rand" + "strings" "time" "github.com/ooni/probe-cli/v3/internal/engine" @@ -183,9 +184,16 @@ func (ed *Experiment) newInputLoader(inputPolicy model.InputPolicy) inputLoader } // experimentOptionsToStringList convers the options to []string, which is -// the format with which we include them into a OONI Measurement +// the format with which we include them into a OONI Measurement. The resulting +// []string will skip any option that is named with a `Safe` prefix (case +// sensitive). func experimentOptionsToStringList(options map[string]any) (out []string) { + // the prefix to skip inclusion in the string list + safeOptionPrefix := "Safe" for key, value := range options { + if strings.HasPrefix(key, safeOptionPrefix) { + continue + } out = append(out, fmt.Sprintf("%s=%v", key, value)) } return diff --git a/internal/oonirun/experiment_test.go b/internal/oonirun/experiment_test.go index 692312f..862c2ef 100644 --- a/internal/oonirun/experiment_test.go +++ b/internal/oonirun/experiment_test.go @@ -3,6 +3,8 @@ package oonirun import ( "context" "os" + "reflect" + "sort" "testing" "time" @@ -58,3 +60,45 @@ func TestExperimentRunWithExample(t *testing.T) { t.Fatal(err) } } + +func Test_experimentOptionsToStringList(t *testing.T) { + type args struct { + options map[string]any + } + tests := []struct { + name string + args args + wantOut []string + }{ + { + name: "happy path: a map with three entries returns three items", + args: args{ + map[string]any{ + "foo": 1, + "bar": 2, + "baaz": 3, + }, + }, + wantOut: []string{"baaz=3", "bar=2", "foo=1"}, + }, + { + name: "an option beginning with `Safe` is skipped from the output", + args: args{ + map[string]any{ + "foo": 1, + "Safefoo": 42, + }, + }, + wantOut: []string{"foo=1"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + gotOut := experimentOptionsToStringList(tt.args.options) + sort.Strings(gotOut) + if !reflect.DeepEqual(gotOut, tt.wantOut) { + t.Errorf("experimentOptionsToStringList() = %v, want %v", gotOut, tt.wantOut) + } + }) + } +} diff --git a/internal/oonirun/v2.go b/internal/oonirun/v2.go index b7455eb..5ad6789 100644 --- a/internal/oonirun/v2.go +++ b/internal/oonirun/v2.go @@ -46,7 +46,10 @@ type v2Nettest struct { // Inputs contains inputs for the experiment. Inputs []string `json:"inputs"` - // Options contains the experiment options. + // Options contains the experiment options. Any option name starting with + // `Safe` will be available for the experiment run, but omitted from + // the serialized Measurement that the experiment builder will submit + // to the OONI backend. Options map[string]any `json:"options"` // TestName contains the nettest name.