1// Package run contains code to run other experiments.
2//
3// This code is currently alpha.
4package run
5
6import (
7	"context"
8	"encoding/json"
9	"fmt"
10
11	"github.com/ooni/probe-engine/experiment/dnscheck"
12	"github.com/ooni/probe-engine/experiment/urlgetter"
13	"github.com/ooni/probe-engine/model"
14)
15
16// Config contains settings.
17type Config struct{}
18
19// Measurer runs the measurement.
20type Measurer struct{}
21
22// ExperimentName implements ExperimentMeasurer.ExperimentName.
23func (Measurer) ExperimentName() string {
24	return "run"
25}
26
27// ExperimentVersion implements ExperimentMeasurer.ExperimentVersion.
28func (Measurer) ExperimentVersion() string {
29	return "0.2.0"
30}
31
32// StructuredInput contains structured input for this experiment.
33type StructuredInput struct {
34	// Annotations contains extra annotations to add to the
35	// final measurement.
36	Annotations map[string]string `json:"annotations"`
37
38	// DNSCheck contains settings for the dnscheck experiment.
39	DNSCheck dnscheck.Config `json:"dnscheck"`
40
41	// URLGetter contains settings for the urlgetter experiment.
42	URLGetter urlgetter.Config `json:"urlgetter"`
43
44	// Name is the name of the experiment to run.
45	Name string `json:"name"`
46
47	// Input is the input for this experiment.
48	Input string `json:"input"`
49}
50
51// Run implements ExperimentMeasurer.ExperimentVersion.
52func (Measurer) Run(
53	ctx context.Context, sess model.ExperimentSession,
54	measurement *model.Measurement, callbacks model.ExperimentCallbacks,
55) error {
56	var input StructuredInput
57	if err := json.Unmarshal([]byte(measurement.Input), &input); err != nil {
58		return err
59	}
60	exprun, found := table[input.Name]
61	if !found {
62		return fmt.Errorf("no such experiment: %s", input.Name)
63	}
64	measurement.AddAnnotations(input.Annotations)
65	return exprun.do(ctx, input, sess, measurement, callbacks)
66}
67
68// GetSummaryKeys implements ExperimentMeasurer.GetSummaryKeys
69func (Measurer) GetSummaryKeys(*model.Measurement) (interface{}, error) {
70	// TODO(bassosimone): we could extend this interface to call the
71	// specific GetSummaryKeys of the experiment we're running.
72	return dnscheck.SummaryKeys{IsAnomaly: false}, nil
73}
74
75// NewExperimentMeasurer creates a new model.ExperimentMeasurer
76// implementing the run experiment.
77func NewExperimentMeasurer(config Config) model.ExperimentMeasurer {
78	return Measurer{}
79}
80