refactor(engine): allow scripts to register experiments (#860)
See https://github.com/ooni/probe/issues/2216
This commit is contained in:
@@ -141,3 +141,143 @@ type ExperimentMeasurer interface {
|
||||
// GetSummaryKeys returns summary keys expected by ooni/probe-cli.
|
||||
GetSummaryKeys(*Measurement) (interface{}, error)
|
||||
}
|
||||
|
||||
// Experiment is an experiment instance.
|
||||
type Experiment interface {
|
||||
// KibiBytesReceived accounts for the KibiBytes received by the experiment.
|
||||
KibiBytesReceived() float64
|
||||
|
||||
// KibiBytesSent is like KibiBytesReceived but for the bytes sent.
|
||||
KibiBytesSent() float64
|
||||
|
||||
// Name returns the experiment name.
|
||||
Name() string
|
||||
|
||||
// GetSummaryKeys returns a data structure containing a
|
||||
// summary of the test keys for ooniprobe.
|
||||
GetSummaryKeys(m *Measurement) (any, error)
|
||||
|
||||
// ReportID returns the open report's ID, if we have opened a report
|
||||
// successfully before, or an empty string, otherwise.
|
||||
//
|
||||
// Deprecated: new code should use a Submitter.
|
||||
ReportID() string
|
||||
|
||||
// MeasureAsync runs an async measurement. This operation could post
|
||||
// one or more measurements onto the returned channel. We'll close the
|
||||
// channel when we've emitted all the measurements.
|
||||
//
|
||||
// Arguments:
|
||||
//
|
||||
// - ctx is the context for deadline/cancellation/timeout;
|
||||
//
|
||||
// - input is the input (typically a URL but it could also be
|
||||
// just an endpoint or an empty string for input-less experiments
|
||||
// such as, e.g., ndt7 and dash).
|
||||
//
|
||||
// Return value:
|
||||
//
|
||||
// - on success, channel where to post measurements (the channel
|
||||
// will be closed when done) and nil error;
|
||||
//
|
||||
// - on failure, nil channel and non-nil error.
|
||||
MeasureAsync(ctx context.Context, input string) (<-chan *Measurement, error)
|
||||
|
||||
// MeasureWithContext performs a synchronous measurement.
|
||||
//
|
||||
// Return value: strictly either a non-nil measurement and
|
||||
// a nil error or a nil measurement and a non-nil error.
|
||||
//
|
||||
// CAVEAT: while this API is perfectly fine for experiments that
|
||||
// return a single measurement, it will only return the first measurement
|
||||
// when used with an asynchronous experiment.
|
||||
MeasureWithContext(ctx context.Context, input string) (measurement *Measurement, err error)
|
||||
|
||||
// SaveMeasurement saves a measurement on the specified file path.
|
||||
//
|
||||
// Deprecated: new code should use a Saver.
|
||||
SaveMeasurement(measurement *Measurement, filePath string) error
|
||||
|
||||
// SubmitAndUpdateMeasurementContext submits a measurement and updates the
|
||||
// fields whose value has changed as part of the submission.
|
||||
//
|
||||
// Deprecated: new code should use a Submitter.
|
||||
SubmitAndUpdateMeasurementContext(
|
||||
ctx context.Context, measurement *Measurement) error
|
||||
|
||||
// OpenReportContext will open a report using the given context
|
||||
// to possibly limit the lifetime of this operation.
|
||||
//
|
||||
// Deprecated: new code should use a Submitter.
|
||||
OpenReportContext(ctx context.Context) error
|
||||
}
|
||||
|
||||
// InputPolicy describes the experiment policy with respect to input. That is
|
||||
// whether it requires input, optionally accepts input, does not want input.
|
||||
type InputPolicy string
|
||||
|
||||
const (
|
||||
// InputOrQueryBackend indicates that the experiment requires
|
||||
// external input to run and that this kind of input is URLs
|
||||
// from the citizenlab/test-lists repository. If this input
|
||||
// not provided to the experiment, then the code that runs the
|
||||
// experiment is supposed to fetch from URLs from OONI's backends.
|
||||
InputOrQueryBackend = InputPolicy("or_query_backend")
|
||||
|
||||
// InputStrictlyRequired indicates that the experiment
|
||||
// requires input and we currently don't have an API for
|
||||
// fetching such input. Therefore, either the user specifies
|
||||
// input or the experiment will fail for the lack of input.
|
||||
InputStrictlyRequired = InputPolicy("strictly_required")
|
||||
|
||||
// InputOptional indicates that the experiment handles input,
|
||||
// if any; otherwise it fetchs input/uses a default.
|
||||
InputOptional = InputPolicy("optional")
|
||||
|
||||
// InputNone indicates that the experiment does not want any
|
||||
// input and ignores the input if provided with it.
|
||||
InputNone = InputPolicy("none")
|
||||
|
||||
// We gather input from StaticInput and SourceFiles. If there is
|
||||
// input, we return it. Otherwise, we return an internal static
|
||||
// list of inputs to be used with this experiment.
|
||||
InputOrStaticDefault = InputPolicy("or_static_default")
|
||||
)
|
||||
|
||||
// ExperimentBuilder builds an experiment.
|
||||
type ExperimentBuilder interface {
|
||||
// Interruptible tells you whether this is an interruptible experiment. This kind
|
||||
// of experiments (e.g. ndt7) may be interrupted mid way.
|
||||
Interruptible() bool
|
||||
|
||||
// InputPolicy returns the experiment input policy.
|
||||
InputPolicy() InputPolicy
|
||||
|
||||
// Options returns information about the experiment's options.
|
||||
Options() (map[string]ExperimentOptionInfo, error)
|
||||
|
||||
// SetOptionAny sets an option whose value is an any value. We will use reasonable
|
||||
// heuristics to convert the any value to the proper type of the field whose name is
|
||||
// contained by the key variable. If we cannot convert the provided any value to
|
||||
// the proper type, then this function returns an error.
|
||||
SetOptionAny(key string, value any) error
|
||||
|
||||
// SetOptionsAny sets options from a map[string]any. See the documentation of
|
||||
// the SetOptionAny method for more information.
|
||||
SetOptionsAny(options map[string]any) error
|
||||
|
||||
// SetCallbacks sets the experiment's interactive callbacks.
|
||||
SetCallbacks(callbacks ExperimentCallbacks)
|
||||
|
||||
// NewExperiment creates the experiment instance.
|
||||
NewExperiment() Experiment
|
||||
}
|
||||
|
||||
// ExperimentOptionInfo contains info about an experiment option.
|
||||
type ExperimentOptionInfo struct {
|
||||
// Doc contains the documentation.
|
||||
Doc string
|
||||
|
||||
// Type contains the type.
|
||||
Type string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user