forwardport: pull the patches mentioned in ooni/probe#1908 (#629)
* [forwardport] fix(oonimkall): make logger used by tasks unit testable (#623)
This diff forward ports e4b04642c51e7461728b25941624e1b97ef0ec83.
Reference issue: https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): improve taskEmitter testability (#624)
This diff forward ports 3e0f01a389c1f4cdd7878ec151aff91870a0bdff.
1. rename eventemitter{,_test}.go => taskemitter{,_test}.go because
the new name is more proper after we merged the internal/task package
inside of the oonimkall package;
2. rename runner.go's `run` function to `runTask`;
3. modify `runTask` to use the new `taskEmitterUsingChan` abstraction
on which we will spend more works in a later point of this list;
4. introduce `runTaskWithEmitter` factory that is called by `runTask`
and allows us to more easily write unit tests;
5. acknowledge that `runner` was not using its `out` field;
6. use the new `taskEmitterWrapper` in `newRunner`;
7. acknowledge that `runnerCallbacks` could use a generic
`taskEmitter` as field type rather than a specific type;
8. rewrite tests to use `runTaskWithEmitter` which leads to
simpler code that does not require a goroutine;
9. acknowledge that the code has been ignoring the `DisabledEvents`
settings for quite some time, so stop supporting it;
10. refactor the `taskEmitter` implementation to be like:
1. we still have the `taskEmitter` interface;
2. `taskEmitterUsingChan` wraps the channel and allows for
emitting events using the channel;
3. `taskEmitterUsingChan` owns an `eof` channel that is
closed by `Close` (which is idempotent) and signals we
should be stop emitting;
4. make sure `runTask` creates a `taskEmitterUsingChan`
and calls its `Close` method when done;
5. completely remove the code for disabling events
since the code was actually ignoring the stting;
6. add a `taskEmitterWrapper` that adds common functions
for emitting events to _any_ `taskWrapper`;
7. write unit tests for `taskEmitterUsingChan` and
for `taskEmitterWrapper`;
11. acknowledge that the abstraction we need for testing is
actually a thread-safe thing that collects events into a
vector containing events and refactor all tests accordingly.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): make the runner unit-testable (#625)
This diff forward ports 9423947faf6980d92d2fe67efe3829e8fef76586.
See https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): write unit tests for the runner component (#626)
This diff forward ports 35dd0e3788b8fa99c541452bbb5e0ae4871239e1.
Forward porting note: compared to 35dd0e3788b8fa99c541452bbb5e0ae4871239e1,
the diff I'm committing here is slightly different. In `master` we do not
have the case where a measurement fails and a measurement is returned, thus
I needed to adapt the test to become like this:
```diff
diff --git a/pkg/oonimkall/runner_internal_test.go b/pkg/oonimkall/runner_internal_test.go
index 334b574..84c7436 100644
--- a/pkg/oonimkall/runner_internal_test.go
+++ b/pkg/oonimkall/runner_internal_test.go
@@ -568,15 +568,6 @@ func TestTaskRunnerRun(t *testing.T) {
}, {
Key: failureMeasurement,
Count: 1,
- }, {
- Key: measurement,
- Count: 1,
- }, {
- Key: statusMeasurementSubmission,
- Count: 1,
- }, {
- Key: statusMeasurementDone,
- Count: 1,
}, {
Key: statusEnd,
Count: 1,
```
I still need to write more assertions for each emitted event
but the code we've here is already a great starting point.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): merge files, use proper names, zap unneeded integration tests (#627)
This diff forward ports f894427d24edc9a03fc78306d0093e7b51c46c25.
Forward porting note: this diff is slightly different from the original
mentioned above because it carries forward changes mentioned in the
previous diff caused by a different way of handling a failed measurement
in the master branch compared to the release/3.11 branch.
Move everything that looked like "task's model" inside of the
taskmodel.go file, for consistency.
Make sure it's clear some variables are event types.
Rename the concrete `runner` as `runnerForTask`.
Also, remove now-unnecessary (and flaky!) integration tests
for the `runnerForTask` type.
While there, notice there were wrong URLs that were generated
during the probe-engine => probe-cli move and fix them.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): we can simplify StartTask tests (#628)
This diff forward ports dcf2986c2032d8185d58d24130a7f2c2d61ef2fb.
* refactor(oonimkall): we can simplify StartTask tests
We have enough checks for runnerForTask. So we do not need to
duplicate them when checking for StartTask.
While there, refactor how we start tasks to remove the need for
extra runner functions.
This is the objective I wanted to achieve for oonimkall:
1. less duplicate tests, and
2. more unit tests (which are less flaky)
At this point, we're basically done (pending forwardporting to
master) with https://github.com/ooni/probe/issues/1903.
* fix(oonimkall): TestStartTaskGood shouldn't cancel the test
This creates a race condition where the test may fail if we cannot
complete the whole "Example" test in less than one second.
This should explain the build failures I've seen so far and why
I didn't see those failures when running locally.
2021-12-02 12:47:07 +01:00
|
|
|
package oonimkall
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"io"
|
|
|
|
|
|
|
|
"github.com/ooni/probe-cli/v3/internal/engine"
|
2022-01-03 13:53:23 +01:00
|
|
|
"github.com/ooni/probe-cli/v3/internal/model"
|
forwardport: pull the patches mentioned in ooni/probe#1908 (#629)
* [forwardport] fix(oonimkall): make logger used by tasks unit testable (#623)
This diff forward ports e4b04642c51e7461728b25941624e1b97ef0ec83.
Reference issue: https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): improve taskEmitter testability (#624)
This diff forward ports 3e0f01a389c1f4cdd7878ec151aff91870a0bdff.
1. rename eventemitter{,_test}.go => taskemitter{,_test}.go because
the new name is more proper after we merged the internal/task package
inside of the oonimkall package;
2. rename runner.go's `run` function to `runTask`;
3. modify `runTask` to use the new `taskEmitterUsingChan` abstraction
on which we will spend more works in a later point of this list;
4. introduce `runTaskWithEmitter` factory that is called by `runTask`
and allows us to more easily write unit tests;
5. acknowledge that `runner` was not using its `out` field;
6. use the new `taskEmitterWrapper` in `newRunner`;
7. acknowledge that `runnerCallbacks` could use a generic
`taskEmitter` as field type rather than a specific type;
8. rewrite tests to use `runTaskWithEmitter` which leads to
simpler code that does not require a goroutine;
9. acknowledge that the code has been ignoring the `DisabledEvents`
settings for quite some time, so stop supporting it;
10. refactor the `taskEmitter` implementation to be like:
1. we still have the `taskEmitter` interface;
2. `taskEmitterUsingChan` wraps the channel and allows for
emitting events using the channel;
3. `taskEmitterUsingChan` owns an `eof` channel that is
closed by `Close` (which is idempotent) and signals we
should be stop emitting;
4. make sure `runTask` creates a `taskEmitterUsingChan`
and calls its `Close` method when done;
5. completely remove the code for disabling events
since the code was actually ignoring the stting;
6. add a `taskEmitterWrapper` that adds common functions
for emitting events to _any_ `taskWrapper`;
7. write unit tests for `taskEmitterUsingChan` and
for `taskEmitterWrapper`;
11. acknowledge that the abstraction we need for testing is
actually a thread-safe thing that collects events into a
vector containing events and refactor all tests accordingly.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): make the runner unit-testable (#625)
This diff forward ports 9423947faf6980d92d2fe67efe3829e8fef76586.
See https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): write unit tests for the runner component (#626)
This diff forward ports 35dd0e3788b8fa99c541452bbb5e0ae4871239e1.
Forward porting note: compared to 35dd0e3788b8fa99c541452bbb5e0ae4871239e1,
the diff I'm committing here is slightly different. In `master` we do not
have the case where a measurement fails and a measurement is returned, thus
I needed to adapt the test to become like this:
```diff
diff --git a/pkg/oonimkall/runner_internal_test.go b/pkg/oonimkall/runner_internal_test.go
index 334b574..84c7436 100644
--- a/pkg/oonimkall/runner_internal_test.go
+++ b/pkg/oonimkall/runner_internal_test.go
@@ -568,15 +568,6 @@ func TestTaskRunnerRun(t *testing.T) {
}, {
Key: failureMeasurement,
Count: 1,
- }, {
- Key: measurement,
- Count: 1,
- }, {
- Key: statusMeasurementSubmission,
- Count: 1,
- }, {
- Key: statusMeasurementDone,
- Count: 1,
}, {
Key: statusEnd,
Count: 1,
```
I still need to write more assertions for each emitted event
but the code we've here is already a great starting point.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): merge files, use proper names, zap unneeded integration tests (#627)
This diff forward ports f894427d24edc9a03fc78306d0093e7b51c46c25.
Forward porting note: this diff is slightly different from the original
mentioned above because it carries forward changes mentioned in the
previous diff caused by a different way of handling a failed measurement
in the master branch compared to the release/3.11 branch.
Move everything that looked like "task's model" inside of the
taskmodel.go file, for consistency.
Make sure it's clear some variables are event types.
Rename the concrete `runner` as `runnerForTask`.
Also, remove now-unnecessary (and flaky!) integration tests
for the `runnerForTask` type.
While there, notice there were wrong URLs that were generated
during the probe-engine => probe-cli move and fix them.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): we can simplify StartTask tests (#628)
This diff forward ports dcf2986c2032d8185d58d24130a7f2c2d61ef2fb.
* refactor(oonimkall): we can simplify StartTask tests
We have enough checks for runnerForTask. So we do not need to
duplicate them when checking for StartTask.
While there, refactor how we start tasks to remove the need for
extra runner functions.
This is the objective I wanted to achieve for oonimkall:
1. less duplicate tests, and
2. more unit tests (which are less flaky)
At this point, we're basically done (pending forwardporting to
master) with https://github.com/ooni/probe/issues/1903.
* fix(oonimkall): TestStartTaskGood shouldn't cancel the test
This creates a race condition where the test may fail if we cannot
complete the whole "Example" test in less than one second.
This should explain the build failures I've seen so far and why
I didn't see those failures when running locally.
2021-12-02 12:47:07 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Task Model
|
|
|
|
//
|
|
|
|
// The oonimkall package allows you to run OONI network
|
|
|
|
// experiments as "tasks". This file defines all the
|
|
|
|
// underlying model entailed by running such tasks.
|
|
|
|
//
|
|
|
|
// Logging
|
|
|
|
//
|
|
|
|
// This section of the file defines the types and the
|
|
|
|
// interfaces required to implement logging.
|
|
|
|
//
|
|
|
|
// The rest of the codebase will use a generic model.Logger
|
|
|
|
// as a logger. This is a pretty fundamental interface in
|
|
|
|
// ooni/probe-cli and so it's not defined in this file.
|
|
|
|
//
|
|
|
|
|
|
|
|
const taskABIVersion = 1
|
|
|
|
|
|
|
|
// Running tasks emit logs using different log levels. We
|
|
|
|
// define log levels with the usual semantics.
|
|
|
|
//
|
|
|
|
// The logger used by a task _may_ be configured to not
|
|
|
|
// emit log events that are less severe than a given
|
|
|
|
// severity.
|
|
|
|
//
|
|
|
|
// We use the following definitions both for defining the
|
|
|
|
// log level of a log and for configuring the maximum
|
|
|
|
// acceptable log level emitted by a logger.
|
|
|
|
const (
|
|
|
|
logLevelDebug2 = "DEBUG2"
|
|
|
|
logLevelDebug = "DEBUG"
|
|
|
|
logLevelInfo = "INFO"
|
|
|
|
logLevelErr = "ERR"
|
|
|
|
logLevelWarning = "WARNING"
|
|
|
|
)
|
|
|
|
|
|
|
|
//
|
|
|
|
// Emitting Events
|
|
|
|
//
|
|
|
|
// While it is running, a task emits events. This section
|
|
|
|
// of the file defines the types needed to emit events.
|
|
|
|
//
|
|
|
|
|
|
|
|
// type of emitted events.
|
|
|
|
const (
|
|
|
|
eventTypeFailureIPLookup = "failure.ip_lookup"
|
|
|
|
eventTypeFailureASNLookup = "failure.asn_lookup"
|
|
|
|
eventTypeFailureCCLookup = "failure.cc_lookup"
|
|
|
|
eventTypeFailureMeasurement = "failure.measurement"
|
|
|
|
eventTypeFailureMeasurementSubmission = "failure.measurement_submission"
|
|
|
|
eventTypeFailureReportCreate = "failure.report_create"
|
|
|
|
eventTypeFailureResolverLookup = "failure.resolver_lookup"
|
|
|
|
eventTypeFailureStartup = "failure.startup"
|
|
|
|
eventTypeLog = "log"
|
|
|
|
eventTypeMeasurement = "measurement"
|
|
|
|
eventTypeStatusEnd = "status.end"
|
|
|
|
eventTypeStatusGeoIPLookup = "status.geoip_lookup"
|
|
|
|
eventTypeStatusMeasurementDone = "status.measurement_done"
|
|
|
|
eventTypeStatusMeasurementStart = "status.measurement_start"
|
|
|
|
eventTypeStatusMeasurementSubmission = "status.measurement_submission"
|
|
|
|
eventTypeStatusProgress = "status.progress"
|
|
|
|
eventTypeStatusQueued = "status.queued"
|
|
|
|
eventTypeStatusReportCreate = "status.report_create"
|
|
|
|
eventTypeStatusResolverLookup = "status.resolver_lookup"
|
|
|
|
eventTypeStatusStarted = "status.started"
|
|
|
|
)
|
|
|
|
|
|
|
|
// taskEmitter is anything that allows us to
|
|
|
|
// emit events while running a task.
|
|
|
|
//
|
|
|
|
// Note that a task emitter _may_ be configured
|
|
|
|
// to ignore _some_ events though.
|
|
|
|
type taskEmitter interface {
|
|
|
|
// Emit emits the event (unless the emitter is
|
|
|
|
// configured to ignore this event key).
|
|
|
|
Emit(key string, value interface{})
|
|
|
|
}
|
|
|
|
|
|
|
|
// taskEmitterCloser is a closeable taskEmitter.
|
|
|
|
type taskEmitterCloser interface {
|
|
|
|
taskEmitter
|
|
|
|
io.Closer
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventEmpty struct{}
|
|
|
|
|
|
|
|
// eventFailure contains information on a failure.
|
|
|
|
type eventFailure struct {
|
|
|
|
Failure string `json:"failure"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// eventLog is an event containing a log message.
|
|
|
|
type eventLog struct {
|
|
|
|
LogLevel string `json:"log_level"`
|
|
|
|
Message string `json:"message"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventMeasurementGeneric struct {
|
|
|
|
Failure string `json:"failure,omitempty"`
|
|
|
|
Idx int64 `json:"idx"`
|
|
|
|
Input string `json:"input"`
|
|
|
|
JSONStr string `json:"json_str,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventStatusEnd struct {
|
|
|
|
DownloadedKB float64 `json:"downloaded_kb"`
|
|
|
|
Failure string `json:"failure"`
|
|
|
|
UploadedKB float64 `json:"uploaded_kb"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventStatusGeoIPLookup struct {
|
|
|
|
ProbeASN string `json:"probe_asn"`
|
|
|
|
ProbeCC string `json:"probe_cc"`
|
|
|
|
ProbeIP string `json:"probe_ip"`
|
|
|
|
ProbeNetworkName string `json:"probe_network_name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// eventStatusProgress reports progress information.
|
|
|
|
type eventStatusProgress struct {
|
|
|
|
Message string `json:"message"`
|
|
|
|
Percentage float64 `json:"percentage"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventStatusReportGeneric struct {
|
|
|
|
ReportID string `json:"report_id"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type eventStatusResolverLookup struct {
|
|
|
|
ResolverASN string `json:"resolver_asn"`
|
|
|
|
ResolverIP string `json:"resolver_ip"`
|
|
|
|
ResolverNetworkName string `json:"resolver_network_name"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// event is an event emitted by a task. This structure extends the event
|
|
|
|
// described by MK v0.10.9 FFI API (https://git.io/Jv4Rv).
|
|
|
|
type event struct {
|
|
|
|
Key string `json:"key"`
|
|
|
|
Value interface{} `json:"value"`
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// OONI Session
|
|
|
|
//
|
|
|
|
// For performing several operations, including running
|
|
|
|
// experiments, we need to create an OONI session.
|
|
|
|
//
|
|
|
|
// This section of the file defines the interface between
|
|
|
|
// our oonimkall API and the real session.
|
|
|
|
//
|
|
|
|
// The abstraction representing a OONI session is taskSession.
|
|
|
|
//
|
|
|
|
|
|
|
|
// taskKVStoreFSBuilder constructs a KVStore with
|
|
|
|
// filesystem backing for running tests.
|
|
|
|
type taskKVStoreFSBuilder interface {
|
|
|
|
// NewFS creates a new KVStore using the filesystem.
|
|
|
|
NewFS(path string) (model.KeyValueStore, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// taskSessionBuilder constructs a new Session.
|
|
|
|
type taskSessionBuilder interface {
|
|
|
|
// NewSession creates a new taskSession.
|
|
|
|
NewSession(ctx context.Context,
|
|
|
|
config engine.SessionConfig) (taskSession, error)
|
|
|
|
}
|
|
|
|
|
|
|
|
// taskSession abstracts a OONI session.
|
|
|
|
type taskSession interface {
|
|
|
|
// A session can be closed.
|
|
|
|
io.Closer
|
|
|
|
|
|
|
|
// NewExperimentBuilderByName creates the builder for constructing
|
|
|
|
// a new experiment given the experiment's name.
|
|
|
|
NewExperimentBuilderByName(name string) (taskExperimentBuilder, error)
|
|
|
|
|
|
|
|
// MaybeLookupBackendsContext lookups the OONI backend unless
|
|
|
|
// this operation has already been performed.
|
|
|
|
MaybeLookupBackendsContext(ctx context.Context) error
|
|
|
|
|
|
|
|
// MaybeLookupLocationContext lookups the probe location unless
|
|
|
|
// this operation has already been performed.
|
|
|
|
MaybeLookupLocationContext(ctx context.Context) error
|
|
|
|
|
|
|
|
// ProbeIP must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved probe IP.
|
|
|
|
ProbeIP() string
|
|
|
|
|
|
|
|
// ProbeASNString must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved probe ASN as a string.
|
|
|
|
ProbeASNString() string
|
|
|
|
|
|
|
|
// ProbeCC must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved probe country code.
|
|
|
|
ProbeCC() string
|
|
|
|
|
|
|
|
// ProbeNetworkName must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved probe country code.
|
|
|
|
ProbeNetworkName() string
|
|
|
|
|
|
|
|
// ResolverANSString must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved resolver's ASN as a string.
|
|
|
|
ResolverASNString() string
|
|
|
|
|
|
|
|
// ResolverIP must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved resolver's IP.
|
|
|
|
ResolverIP() string
|
|
|
|
|
|
|
|
// ResolverNetworkName must be called after MaybeLookupLocationContext
|
|
|
|
// and returns the resolved resolver's network name.
|
|
|
|
ResolverNetworkName() string
|
|
|
|
}
|
|
|
|
|
|
|
|
// taskExperimentBuilder builds a taskExperiment.
|
|
|
|
type taskExperimentBuilder interface {
|
|
|
|
// SetCallbacks sets the experiment callbacks.
|
|
|
|
SetCallbacks(callbacks model.ExperimentCallbacks)
|
|
|
|
|
|
|
|
// InputPolicy returns the experiment's input policy.
|
2022-08-17 10:57:03 +02:00
|
|
|
InputPolicy() model.InputPolicy
|
forwardport: pull the patches mentioned in ooni/probe#1908 (#629)
* [forwardport] fix(oonimkall): make logger used by tasks unit testable (#623)
This diff forward ports e4b04642c51e7461728b25941624e1b97ef0ec83.
Reference issue: https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): improve taskEmitter testability (#624)
This diff forward ports 3e0f01a389c1f4cdd7878ec151aff91870a0bdff.
1. rename eventemitter{,_test}.go => taskemitter{,_test}.go because
the new name is more proper after we merged the internal/task package
inside of the oonimkall package;
2. rename runner.go's `run` function to `runTask`;
3. modify `runTask` to use the new `taskEmitterUsingChan` abstraction
on which we will spend more works in a later point of this list;
4. introduce `runTaskWithEmitter` factory that is called by `runTask`
and allows us to more easily write unit tests;
5. acknowledge that `runner` was not using its `out` field;
6. use the new `taskEmitterWrapper` in `newRunner`;
7. acknowledge that `runnerCallbacks` could use a generic
`taskEmitter` as field type rather than a specific type;
8. rewrite tests to use `runTaskWithEmitter` which leads to
simpler code that does not require a goroutine;
9. acknowledge that the code has been ignoring the `DisabledEvents`
settings for quite some time, so stop supporting it;
10. refactor the `taskEmitter` implementation to be like:
1. we still have the `taskEmitter` interface;
2. `taskEmitterUsingChan` wraps the channel and allows for
emitting events using the channel;
3. `taskEmitterUsingChan` owns an `eof` channel that is
closed by `Close` (which is idempotent) and signals we
should be stop emitting;
4. make sure `runTask` creates a `taskEmitterUsingChan`
and calls its `Close` method when done;
5. completely remove the code for disabling events
since the code was actually ignoring the stting;
6. add a `taskEmitterWrapper` that adds common functions
for emitting events to _any_ `taskWrapper`;
7. write unit tests for `taskEmitterUsingChan` and
for `taskEmitterWrapper`;
11. acknowledge that the abstraction we need for testing is
actually a thread-safe thing that collects events into a
vector containing events and refactor all tests accordingly.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): make the runner unit-testable (#625)
This diff forward ports 9423947faf6980d92d2fe67efe3829e8fef76586.
See https://github.com/ooni/probe/issues/1903
* [forwardport] feat(oonimkall): write unit tests for the runner component (#626)
This diff forward ports 35dd0e3788b8fa99c541452bbb5e0ae4871239e1.
Forward porting note: compared to 35dd0e3788b8fa99c541452bbb5e0ae4871239e1,
the diff I'm committing here is slightly different. In `master` we do not
have the case where a measurement fails and a measurement is returned, thus
I needed to adapt the test to become like this:
```diff
diff --git a/pkg/oonimkall/runner_internal_test.go b/pkg/oonimkall/runner_internal_test.go
index 334b574..84c7436 100644
--- a/pkg/oonimkall/runner_internal_test.go
+++ b/pkg/oonimkall/runner_internal_test.go
@@ -568,15 +568,6 @@ func TestTaskRunnerRun(t *testing.T) {
}, {
Key: failureMeasurement,
Count: 1,
- }, {
- Key: measurement,
- Count: 1,
- }, {
- Key: statusMeasurementSubmission,
- Count: 1,
- }, {
- Key: statusMeasurementDone,
- Count: 1,
}, {
Key: statusEnd,
Count: 1,
```
I still need to write more assertions for each emitted event
but the code we've here is already a great starting point.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): merge files, use proper names, zap unneeded integration tests (#627)
This diff forward ports f894427d24edc9a03fc78306d0093e7b51c46c25.
Forward porting note: this diff is slightly different from the original
mentioned above because it carries forward changes mentioned in the
previous diff caused by a different way of handling a failed measurement
in the master branch compared to the release/3.11 branch.
Move everything that looked like "task's model" inside of the
taskmodel.go file, for consistency.
Make sure it's clear some variables are event types.
Rename the concrete `runner` as `runnerForTask`.
Also, remove now-unnecessary (and flaky!) integration tests
for the `runnerForTask` type.
While there, notice there were wrong URLs that were generated
during the probe-engine => probe-cli move and fix them.
See https://github.com/ooni/probe/issues/1903
* [forwardport] refactor(oonimkall): we can simplify StartTask tests (#628)
This diff forward ports dcf2986c2032d8185d58d24130a7f2c2d61ef2fb.
* refactor(oonimkall): we can simplify StartTask tests
We have enough checks for runnerForTask. So we do not need to
duplicate them when checking for StartTask.
While there, refactor how we start tasks to remove the need for
extra runner functions.
This is the objective I wanted to achieve for oonimkall:
1. less duplicate tests, and
2. more unit tests (which are less flaky)
At this point, we're basically done (pending forwardporting to
master) with https://github.com/ooni/probe/issues/1903.
* fix(oonimkall): TestStartTaskGood shouldn't cancel the test
This creates a race condition where the test may fail if we cannot
complete the whole "Example" test in less than one second.
This should explain the build failures I've seen so far and why
I didn't see those failures when running locally.
2021-12-02 12:47:07 +01:00
|
|
|
|
|
|
|
// NewExperiment creates the new experiment.
|
|
|
|
NewExperimentInstance() taskExperiment
|
|
|
|
|
|
|
|
// Interruptible returns whether this experiment is interruptible.
|
|
|
|
Interruptible() bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// taskExperiment is a runnable experiment.
|
|
|
|
type taskExperiment interface {
|
|
|
|
// KibiBytesReceived returns the KiB received by the experiment.
|
|
|
|
KibiBytesReceived() float64
|
|
|
|
|
|
|
|
// KibiBytesSent returns the KiB sent by the experiment.
|
|
|
|
KibiBytesSent() float64
|
|
|
|
|
|
|
|
// OpenReportContext opens a new report.
|
|
|
|
OpenReportContext(ctx context.Context) error
|
|
|
|
|
|
|
|
// ReportID must be called after a successful OpenReportContext
|
|
|
|
// and returns the report ID for this measurement.
|
|
|
|
ReportID() string
|
|
|
|
|
|
|
|
// MeasureWithContext runs the measurement.
|
|
|
|
MeasureWithContext(ctx context.Context, input string) (
|
|
|
|
measurement *model.Measurement, err error)
|
|
|
|
|
|
|
|
// SubmitAndUpdateMeasurementContext submits the measurement
|
|
|
|
// and updates its report ID on success.
|
|
|
|
SubmitAndUpdateMeasurementContext(
|
|
|
|
ctx context.Context, measurement *model.Measurement) error
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Task Running
|
|
|
|
//
|
|
|
|
// This section contains the interfaces allowing us
|
|
|
|
// to run a task until completion.
|
|
|
|
//
|
|
|
|
|
|
|
|
// taskRunner runs a task until completion.
|
|
|
|
type taskRunner interface {
|
|
|
|
// Run runs until completion.
|
|
|
|
Run(ctx context.Context)
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Task Settings
|
|
|
|
//
|
|
|
|
// This section defines the settings used by a task.
|
|
|
|
//
|
|
|
|
|
|
|
|
// Settings contains settings for a task. This structure derives from
|
|
|
|
// the one described by MK v0.10.9 FFI API (https://git.io/Jv4Rv), yet
|
|
|
|
// since 2020-12-03 we're not backwards compatible anymore.
|
|
|
|
type settings struct {
|
|
|
|
// Annotations contains the annotations to be added
|
|
|
|
// to every measurements performed by the task.
|
|
|
|
Annotations map[string]string `json:"annotations,omitempty"`
|
|
|
|
|
|
|
|
// AssetsDir is the directory where to store assets. This
|
|
|
|
// field is an extension of MK's specification. If
|
|
|
|
// this field is empty, the task won't start.
|
|
|
|
AssetsDir string `json:"assets_dir"`
|
|
|
|
|
|
|
|
// DisabledEvents contains disabled events. See
|
|
|
|
// https://git.io/Jv4Rv for the events names.
|
|
|
|
//
|
|
|
|
// This setting is currently ignored. We noticed the
|
|
|
|
// code was ignoring it on 2021-12-01.
|
|
|
|
DisabledEvents []string `json:"disabled_events,omitempty"`
|
|
|
|
|
|
|
|
// Inputs contains the inputs. The task will fail if it
|
|
|
|
// requires input and you provide no input.
|
|
|
|
Inputs []string `json:"inputs,omitempty"`
|
|
|
|
|
|
|
|
// LogLevel contains the logs level. See https://git.io/Jv4Rv
|
|
|
|
// for the names of the available log levels.
|
|
|
|
LogLevel string `json:"log_level,omitempty"`
|
|
|
|
|
|
|
|
// Name contains the task name. By https://git.io/Jv4Rv the
|
|
|
|
// names are in camel case, e.g. `Ndt`.
|
|
|
|
Name string `json:"name"`
|
|
|
|
|
|
|
|
// Options contains the task options.
|
|
|
|
Options settingsOptions `json:"options"`
|
|
|
|
|
|
|
|
// Proxy allows you to optionally force a specific proxy
|
|
|
|
// rather than using no proxy (the default).
|
|
|
|
//
|
|
|
|
// Use `psiphon:///` to force using Psiphon with the
|
|
|
|
// embedded configuration file. Not all builds have
|
|
|
|
// an embedded configuration file, but OONI builds have
|
|
|
|
// such a file, so they can use this functionality.
|
|
|
|
//
|
|
|
|
// Use `socks5://10.0.0.1:9050/` to connect to a SOCKS5
|
|
|
|
// proxy running on 10.0.0.1:9050. This could be, for
|
|
|
|
// example, a suitably configured `tor` instance.
|
|
|
|
Proxy string
|
|
|
|
|
|
|
|
// StateDir is the directory where to store persistent data. This
|
|
|
|
// field is an extension of MK's specification. If
|
|
|
|
// this field is empty, the task won't start.
|
|
|
|
StateDir string `json:"state_dir"`
|
|
|
|
|
|
|
|
// TempDir is the temporary directory. This field is an extension of MK's
|
|
|
|
// specification. If this field is empty, we will pick the tempdir that
|
|
|
|
// ioutil.TempDir uses by default, which may not work on mobile. According
|
|
|
|
// to our experiments as of 2020-06-10, leaving the TempDir empty works
|
|
|
|
// for iOS and does not work for Android.
|
|
|
|
TempDir string `json:"temp_dir"`
|
|
|
|
|
|
|
|
// TunnelDir is the directory where to store persistent state
|
|
|
|
// related to circumvention tunnels. This directory is required
|
|
|
|
// only if you want to use the tunnels. Added since 3.10.0.
|
|
|
|
TunnelDir string `json:"tunnel_dir"`
|
|
|
|
|
|
|
|
// Version indicates the version of this structure.
|
|
|
|
Version int64 `json:"version"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// settingsOptions contains the settings options
|
|
|
|
type settingsOptions struct {
|
|
|
|
// MaxRuntime is the maximum runtime expressed in seconds. A negative
|
|
|
|
// value for this field disables the maximum runtime. Using
|
|
|
|
// a zero value will also mean disabled. This is not the
|
|
|
|
// original behaviour of Measurement Kit, which used to run
|
|
|
|
// for zero time in such case.
|
|
|
|
MaxRuntime float64 `json:"max_runtime,omitempty"`
|
|
|
|
|
|
|
|
// NoCollector indicates whether to use a collector
|
|
|
|
NoCollector bool `json:"no_collector,omitempty"`
|
|
|
|
|
|
|
|
// ProbeServicesBaseURL contains the probe services base URL.
|
|
|
|
ProbeServicesBaseURL string `json:"probe_services_base_url,omitempty"`
|
|
|
|
|
|
|
|
// SoftwareName is the software name. If this option is not
|
|
|
|
// present, then the library startup will fail.
|
|
|
|
SoftwareName string `json:"software_name,omitempty"`
|
|
|
|
|
|
|
|
// SoftwareVersion is the software version. If this option is not
|
|
|
|
// present, then the library startup will fail.
|
|
|
|
SoftwareVersion string `json:"software_version,omitempty"`
|
|
|
|
}
|