refactor(engine): allow scripts to register experiments (#860)

See https://github.com/ooni/probe/issues/2216
This commit is contained in:
Simone Basso
2022-08-17 10:57:03 +02:00
committed by GitHub
parent 69602abe8a
commit 6a0ae5c70b
53 changed files with 1438 additions and 1200 deletions
+1 -2
View File
@@ -3,7 +3,6 @@ package oonimkall
import (
"context"
"github.com/ooni/probe-cli/v3/internal/engine"
"github.com/ooni/probe-cli/v3/internal/model"
)
@@ -67,7 +66,7 @@ type experimentBuilder interface {
// experimentBuilderWrapper wraps *ExperimentBuilder
type experimentBuilderWrapper struct {
eb engine.ExperimentBuilder
eb model.ExperimentBuilder
}
// newExperiment implements experimentBuilder.newExperiment
+2 -2
View File
@@ -87,7 +87,7 @@ type MockableTaskRunnerDependencies struct {
// taskExperimentBuilder:
MockableSetCallbacks func(callbacks model.ExperimentCallbacks)
MockableInputPolicy func() engine.InputPolicy
MockableInputPolicy func() model.InputPolicy
MockableNewExperimentInstance func() taskExperiment
MockableInterruptible func() bool
@@ -169,7 +169,7 @@ func (dep *MockableTaskRunnerDependencies) SetCallbacks(callbacks model.Experime
dep.MockableSetCallbacks(callbacks)
}
func (dep *MockableTaskRunnerDependencies) InputPolicy() engine.InputPolicy {
func (dep *MockableTaskRunnerDependencies) InputPolicy() model.InputPolicy {
return dep.MockableInputPolicy()
}
+1 -1
View File
@@ -227,7 +227,7 @@ type taskExperimentBuilder interface {
SetCallbacks(callbacks model.ExperimentCallbacks)
// InputPolicy returns the experiment's input policy.
InputPolicy() engine.InputPolicy
InputPolicy() model.InputPolicy
// NewExperiment creates the new experiment.
NewExperimentInstance() taskExperiment
+4 -4
View File
@@ -184,12 +184,12 @@ func (r *runnerForTask) Run(rootCtx context.Context) {
// In fact, our current app assumes that it's its
// responsibility to load the inputs, not oonimkall's.
switch builder.InputPolicy() {
case engine.InputOrQueryBackend, engine.InputStrictlyRequired:
case model.InputOrQueryBackend, model.InputStrictlyRequired:
if len(r.settings.Inputs) <= 0 {
r.emitter.EmitFailureStartup("no input provided")
return
}
case engine.InputOrStaticDefault:
case model.InputOrStaticDefault:
if len(r.settings.Inputs) <= 0 {
inputs, err := engine.StaticBareInputForExperiment(r.settings.Name)
if err != nil {
@@ -198,7 +198,7 @@ func (r *runnerForTask) Run(rootCtx context.Context) {
}
r.settings.Inputs = inputs
}
case engine.InputOptional:
case model.InputOptional:
if len(r.settings.Inputs) <= 0 {
r.settings.Inputs = append(r.settings.Inputs, "")
}
@@ -240,7 +240,7 @@ func (r *runnerForTask) Run(rootCtx context.Context) {
// this policy in the future, but for now this covers in a
// reasonable way web connectivity, so we should be ok.
switch builder.InputPolicy() {
case engine.InputOrQueryBackend, engine.InputStrictlyRequired:
case model.InputOrQueryBackend, model.InputStrictlyRequired:
var (
cancelMeas context.CancelFunc
cancelSubmit context.CancelFunc
+30 -30
View File
@@ -204,8 +204,8 @@ func TestTaskRunnerRun(t *testing.T) {
},
MockableSetCallbacks: func(callbacks model.ExperimentCallbacks) {
},
MockableInputPolicy: func() engine.InputPolicy {
return engine.InputNone
MockableInputPolicy: func() model.InputPolicy {
return model.InputNone
},
MockableInterruptible: func() bool {
return false
@@ -310,8 +310,8 @@ func TestTaskRunnerRun(t *testing.T) {
t.Run("with missing input and InputOrQueryBackend policy", func(t *testing.T) {
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputOrQueryBackend
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputOrQueryBackend
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -331,8 +331,8 @@ func TestTaskRunnerRun(t *testing.T) {
t.Run("with missing input and InputStrictlyRequired policy", func(t *testing.T) {
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputStrictlyRequired
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputStrictlyRequired
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -355,8 +355,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Name = "Antani" // no input for this experiment
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputOrStaticDefault
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputOrStaticDefault
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -377,8 +377,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Inputs = append(runner.settings.Inputs, "https://x.org/")
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputNone
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputNone
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -419,8 +419,8 @@ func TestTaskRunnerRun(t *testing.T) {
t.Run("with success and InputNone policy", func(t *testing.T) {
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputNone
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputNone
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -445,8 +445,8 @@ func TestTaskRunnerRun(t *testing.T) {
t.Run("with measurement failure and InputNone policy", func(t *testing.T) {
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputNone
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputNone
}
fake.MockableMeasureWithContext = func(ctx context.Context, input string) (measurement *model.Measurement, err error) {
return nil, errors.New("preconditions error")
@@ -475,8 +475,8 @@ func TestTaskRunnerRun(t *testing.T) {
// which is what was happening in the above referenced issue.
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputNone
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputNone
}
fake.MockableMeasureWithContext = func(ctx context.Context, input string) (measurement *model.Measurement, err error) {
return nil, errors.New("preconditions error")
@@ -506,8 +506,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Inputs = []string{"a", "b", "c", "d"}
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputStrictlyRequired
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputStrictlyRequired
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -554,8 +554,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Inputs = []string{"a", "b", "c", "d"}
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputOptional
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputOptional
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -601,8 +601,8 @@ func TestTaskRunnerRun(t *testing.T) {
t.Run("with success and InputOptional and no input", func(t *testing.T) {
runner, emitter := newRunnerForTesting()
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputOptional
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputOptional
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -631,8 +631,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Name = experimentName
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputOrStaticDefault
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputOrStaticDefault
}
runner.sessionBuilder = fake
events := runAndCollect(runner, emitter)
@@ -667,8 +667,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner.settings.Inputs = []string{"a", "b", "c", "d"}
runner.settings.Options.MaxRuntime = 2
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputStrictlyRequired
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputStrictlyRequired
}
fake.MockableMeasureWithContext = func(ctx context.Context, input string) (measurement *model.Measurement, err error) {
time.Sleep(1 * time.Second)
@@ -708,8 +708,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner.settings.Inputs = []string{"a", "b", "c", "d"}
runner.settings.Options.MaxRuntime = 2
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputStrictlyRequired
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputStrictlyRequired
}
fake.MockableInterruptible = func() bool {
return true
@@ -743,8 +743,8 @@ func TestTaskRunnerRun(t *testing.T) {
runner, emitter := newRunnerForTesting()
runner.settings.Inputs = []string{"a"}
fake := fakeSuccessfulRun()
fake.MockableInputPolicy = func() engine.InputPolicy {
return engine.InputStrictlyRequired
fake.MockableInputPolicy = func() model.InputPolicy {
return model.InputStrictlyRequired
}
fake.MockableSubmitAndUpdateMeasurementContext = func(ctx context.Context, measurement *model.Measurement) error {
return errors.New("cannot submit")
+2 -2
View File
@@ -59,7 +59,7 @@ func (sess *taskSessionEngine) NewExperimentBuilderByName(
// taskExperimentBuilderEngine wraps ./internal/engine's
// ExperimentBuilder type.
type taskExperimentBuilderEngine struct {
engine.ExperimentBuilder
model.ExperimentBuilder
}
var _ taskExperimentBuilder = &taskExperimentBuilderEngine{}
@@ -72,7 +72,7 @@ func (b *taskExperimentBuilderEngine) NewExperimentInstance() taskExperiment {
// taskExperimentEngine wraps ./internal/engine's Experiment.
type taskExperimentEngine struct {
engine.Experiment
model.Experiment
}
var _ taskExperiment = &taskExperimentEngine{}