feat(ooniprobe): propagate the RunType CheckIn hint (#274)
This diff propagates the RunType CheckIn hint such that we run using less URLs when running in the background. Part of https://github.com/ooni/probe/issues/1299.
This commit is contained in:
parent
c264f61536
commit
dae02ce5b6
|
@ -26,19 +26,23 @@ func init() {
|
||||||
log.WithError(err).Error("failed to perform onboarding")
|
log.WithError(err).Error("failed to perform onboarding")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if *noCollector == true {
|
if *noCollector {
|
||||||
probe.Config().Sharing.UploadResults = false
|
probe.Config().Sharing.UploadResults = false
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
functionalRun := func(pred func(name string, gr nettests.Group) bool) error {
|
functionalRun := func(runType string, pred func(name string, gr nettests.Group) bool) error {
|
||||||
for name, group := range nettests.All {
|
for name, group := range nettests.All {
|
||||||
if pred(name, group) != true {
|
if !pred(name, group) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
log.Infof("Running %s tests", color.BlueString(name))
|
log.Infof("Running %s tests", color.BlueString(name))
|
||||||
conf := nettests.RunGroupConfig{GroupName: name, Probe: probe}
|
conf := nettests.RunGroupConfig{
|
||||||
|
GroupName: name,
|
||||||
|
Probe: probe,
|
||||||
|
RunType: runType,
|
||||||
|
}
|
||||||
if err := nettests.RunGroup(conf); err != nil {
|
if err := nettests.RunGroup(conf); err != nil {
|
||||||
log.WithError(err).Errorf("failed to run %s", name)
|
log.WithError(err).Errorf("failed to run %s", name)
|
||||||
}
|
}
|
||||||
|
@ -48,7 +52,7 @@ func init() {
|
||||||
|
|
||||||
genRunWithGroupName := func(targetName string) func(*kingpin.ParseContext) error {
|
genRunWithGroupName := func(targetName string) func(*kingpin.ParseContext) error {
|
||||||
return func(*kingpin.ParseContext) error {
|
return func(*kingpin.ParseContext) error {
|
||||||
return functionalRun(func(groupName string, gr nettests.Group) bool {
|
return functionalRun("manual", func(groupName string, gr nettests.Group) bool {
|
||||||
return groupName == targetName
|
return groupName == targetName
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -75,14 +79,14 @@ func init() {
|
||||||
|
|
||||||
unattendedCmd := cmd.Command("unattended", "")
|
unattendedCmd := cmd.Command("unattended", "")
|
||||||
unattendedCmd.Action(func(_ *kingpin.ParseContext) error {
|
unattendedCmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
return functionalRun(func(name string, gr nettests.Group) bool {
|
return functionalRun("timed", func(name string, gr nettests.Group) bool {
|
||||||
return gr.UnattendedOK == true
|
return gr.UnattendedOK
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
allCmd := cmd.Command("all", "").Default()
|
allCmd := cmd.Command("all", "").Default()
|
||||||
allCmd.Action(func(_ *kingpin.ParseContext) error {
|
allCmd.Action(func(_ *kingpin.ParseContext) error {
|
||||||
return functionalRun(func(name string, gr nettests.Group) bool {
|
return functionalRun("manual", func(name string, gr nettests.Group) bool {
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -53,6 +53,10 @@ type Controller struct {
|
||||||
// using the command line using the --input flag.
|
// using the command line using the --input flag.
|
||||||
Inputs []string
|
Inputs []string
|
||||||
|
|
||||||
|
// RunType contains the run_type hint for the CheckIn API. If
|
||||||
|
// not set, the underlying code defaults to "timed".
|
||||||
|
RunType string
|
||||||
|
|
||||||
// numInputs is the total number of inputs
|
// numInputs is the total number of inputs
|
||||||
numInputs int
|
numInputs int
|
||||||
|
|
||||||
|
@ -115,6 +119,8 @@ func (c *Controller) Run(builder *engine.ExperimentBuilder, inputs []string) err
|
||||||
start := time.Now()
|
start := time.Now()
|
||||||
c.ntStartTime = start
|
c.ntStartTime = start
|
||||||
for idx, input := range inputs {
|
for idx, input := range inputs {
|
||||||
|
// TODO(bassosimone): should we allow for interruption when running
|
||||||
|
// in unattended mode? Likewise, should we honor MaxRuntime?
|
||||||
if c.Probe.IsTerminated() {
|
if c.Probe.IsTerminated() {
|
||||||
log.Info("user requested us to terminate using Ctrl-C")
|
log.Info("user requested us to terminate using Ctrl-C")
|
||||||
break
|
break
|
||||||
|
@ -172,7 +178,7 @@ func (c *Controller) Run(builder *engine.ExperimentBuilder, inputs []string) err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We only save the measurement to disk if we failed to upload the measurement
|
// We only save the measurement to disk if we failed to upload the measurement
|
||||||
if saveToDisk == true {
|
if saveToDisk {
|
||||||
if err := exp.SaveMeasurement(measurement, msmt.MeasurementFilePath.String); err != nil {
|
if err := exp.SaveMeasurement(measurement, msmt.MeasurementFilePath.String); err != nil {
|
||||||
return errors.Wrap(err, "failed to save measurement on disk")
|
return errors.Wrap(err, "failed to save measurement on disk")
|
||||||
}
|
}
|
||||||
|
@ -204,6 +210,8 @@ func (c *Controller) Run(builder *engine.ExperimentBuilder, inputs []string) err
|
||||||
|
|
||||||
// OnProgress should be called when a new progress event is available.
|
// OnProgress should be called when a new progress event is available.
|
||||||
func (c *Controller) OnProgress(perc float64, msg string) {
|
func (c *Controller) OnProgress(perc float64, msg string) {
|
||||||
|
// TODO(bassosimone): should we adjust this algorithm when we have a
|
||||||
|
// maximum runtime that we would like to honor?
|
||||||
log.Debugf("OnProgress: %f - %s", perc, msg)
|
log.Debugf("OnProgress: %f - %s", perc, msg)
|
||||||
var eta float64
|
var eta float64
|
||||||
eta = -1.0
|
eta = -1.0
|
||||||
|
@ -213,7 +221,7 @@ func (c *Controller) OnProgress(perc float64, msg string) {
|
||||||
step := 1.0 / float64(c.numInputs)
|
step := 1.0 / float64(c.numInputs)
|
||||||
perc = floor + perc*step
|
perc = floor + perc*step
|
||||||
if c.curInputIdx > 0 {
|
if c.curInputIdx > 0 {
|
||||||
eta = (time.Now().Sub(c.ntStartTime).Seconds() / float64(c.curInputIdx)) * float64(c.numInputs-c.curInputIdx)
|
eta = (time.Since(c.ntStartTime).Seconds() / float64(c.curInputIdx)) * float64(c.numInputs-c.curInputIdx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if c.ntCount > 0 {
|
if c.ntCount > 0 {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package nettests
|
package nettests
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/apex/log"
|
"github.com/apex/log"
|
||||||
|
@ -12,9 +13,10 @@ import (
|
||||||
// RunGroupConfig contains the settings for running a nettest group.
|
// RunGroupConfig contains the settings for running a nettest group.
|
||||||
type RunGroupConfig struct {
|
type RunGroupConfig struct {
|
||||||
GroupName string
|
GroupName string
|
||||||
Probe *ooni.Probe
|
|
||||||
InputFiles []string
|
InputFiles []string
|
||||||
Inputs []string
|
Inputs []string
|
||||||
|
Probe *ooni.Probe
|
||||||
|
RunType string // hint for check-in API
|
||||||
}
|
}
|
||||||
|
|
||||||
const websitesURLLimitRemoved = `WARNING: CONFIGURATION CHANGE REQUIRED:
|
const websitesURLLimitRemoved = `WARNING: CONFIGURATION CHANGE REQUIRED:
|
||||||
|
@ -34,16 +36,20 @@ const websitesURLLimitRemoved = `WARNING: CONFIGURATION CHANGE REQUIRED:
|
||||||
* Since 2022, we will start silently ignoring websites_url_limit
|
* Since 2022, we will start silently ignoring websites_url_limit
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var deprecationWarningOnce sync.Once
|
||||||
|
|
||||||
// RunGroup runs a group of nettests according to the specified config.
|
// RunGroup runs a group of nettests according to the specified config.
|
||||||
func RunGroup(config RunGroupConfig) error {
|
func RunGroup(config RunGroupConfig) error {
|
||||||
if config.Probe.Config().Nettests.WebsitesURLLimit > 0 {
|
if config.Probe.Config().Nettests.WebsitesURLLimit > 0 {
|
||||||
log.Warn(websitesURLLimitRemoved)
|
|
||||||
if config.Probe.Config().Nettests.WebsitesMaxRuntime <= 0 {
|
if config.Probe.Config().Nettests.WebsitesMaxRuntime <= 0 {
|
||||||
limit := config.Probe.Config().Nettests.WebsitesURLLimit
|
limit := config.Probe.Config().Nettests.WebsitesURLLimit
|
||||||
maxRuntime := 5 * limit
|
maxRuntime := 5 * limit
|
||||||
config.Probe.Config().Nettests.WebsitesMaxRuntime = maxRuntime
|
config.Probe.Config().Nettests.WebsitesMaxRuntime = maxRuntime
|
||||||
}
|
}
|
||||||
time.Sleep(30 * time.Second)
|
deprecationWarningOnce.Do(func() {
|
||||||
|
log.Warn(websitesURLLimitRemoved)
|
||||||
|
time.Sleep(30 * time.Second)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if config.Probe.IsTerminated() {
|
if config.Probe.IsTerminated() {
|
||||||
|
@ -90,7 +96,7 @@ func RunGroup(config RunGroupConfig) error {
|
||||||
config.Probe.ListenForSignals()
|
config.Probe.ListenForSignals()
|
||||||
config.Probe.MaybeListenForStdinClosed()
|
config.Probe.MaybeListenForStdinClosed()
|
||||||
for i, nt := range group.Nettests {
|
for i, nt := range group.Nettests {
|
||||||
if config.Probe.IsTerminated() == true {
|
if config.Probe.IsTerminated() {
|
||||||
log.Debugf("context is terminated, stopping group.Nettests early")
|
log.Debugf("context is terminated, stopping group.Nettests early")
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -98,6 +104,7 @@ func RunGroup(config RunGroupConfig) error {
|
||||||
ctl := NewController(nt, config.Probe, result, sess)
|
ctl := NewController(nt, config.Probe, result, sess)
|
||||||
ctl.InputFiles = config.InputFiles
|
ctl.InputFiles = config.InputFiles
|
||||||
ctl.Inputs = config.Inputs
|
ctl.Inputs = config.Inputs
|
||||||
|
ctl.RunType = config.RunType
|
||||||
ctl.SetNettestIndex(i, len(group.Nettests))
|
ctl.SetNettestIndex(i, len(group.Nettests))
|
||||||
if err = nt.Run(ctl); err != nil {
|
if err = nt.Run(ctl); err != nil {
|
||||||
log.WithError(err).Errorf("Failed to run %s", group.Label)
|
log.WithError(err).Errorf("Failed to run %s", group.Label)
|
||||||
|
|
|
@ -9,12 +9,15 @@ import (
|
||||||
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
"github.com/ooni/probe-cli/v3/internal/engine/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(bassosimone): we should propagate the kind of run
|
|
||||||
// to here such that we get the right runType.
|
|
||||||
|
|
||||||
func lookupURLs(ctl *Controller, categories []string) ([]string, map[int64]int64, error) {
|
func lookupURLs(ctl *Controller, categories []string) ([]string, map[int64]int64, error) {
|
||||||
inputloader := &engine.InputLoader{
|
inputloader := &engine.InputLoader{
|
||||||
CheckInConfig: &model.CheckInConfig{
|
CheckInConfig: &model.CheckInConfig{
|
||||||
|
// Setting Charging and OnWiFi to true causes the CheckIn
|
||||||
|
// API to return to us as much URL as possible with the
|
||||||
|
// given RunType hint.
|
||||||
|
Charging: true,
|
||||||
|
OnWiFi: true,
|
||||||
|
RunType: ctl.RunType,
|
||||||
WebConnectivity: model.CheckInConfigWebConnectivity{
|
WebConnectivity: model.CheckInConfigWebConnectivity{
|
||||||
CategoryCodes: categories,
|
CategoryCodes: categories,
|
||||||
},
|
},
|
||||||
|
@ -24,6 +27,7 @@ func lookupURLs(ctl *Controller, categories []string) ([]string, map[int64]int64
|
||||||
SourceFiles: ctl.InputFiles,
|
SourceFiles: ctl.InputFiles,
|
||||||
StaticInputs: ctl.Inputs,
|
StaticInputs: ctl.Inputs,
|
||||||
}
|
}
|
||||||
|
log.Infof("Calling CheckIn API with %s runType", ctl.RunType)
|
||||||
testlist, err := inputloader.Load(context.Background())
|
testlist, err := inputloader.Load(context.Background())
|
||||||
var urls []string
|
var urls []string
|
||||||
urlIDMap := make(map[int64]int64)
|
urlIDMap := make(map[int64]int64)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user