1package nettests 2 3import ( 4 "context" 5 "sync" 6 "time" 7 8 "github.com/apex/log" 9 "github.com/ooni/probe-cli/v3/cmd/ooniprobe/internal/database" 10 "github.com/ooni/probe-cli/v3/cmd/ooniprobe/internal/ooni" 11 "github.com/pkg/errors" 12) 13 14// RunGroupConfig contains the settings for running a nettest group. 15type RunGroupConfig struct { 16 GroupName string 17 InputFiles []string 18 Inputs []string 19 Probe *ooni.Probe 20 RunType string // hint for check-in API 21} 22 23const websitesURLLimitRemoved = `WARNING: CONFIGURATION CHANGE REQUIRED: 24 25* Since ooniprobe 3.9.0, websites_url_limit has been replaced 26 by websites_max_runtime in the configuration 27 28* To silence this warning either set websites_url_limit to zero or 29 replace it with websites_max_runtime 30 31* For the rest of 2021, we will automatically convert websites_url_limit 32 to websites_max_runtime (if the latter is not already set) 33 34* We will consider that each URL in websites_url_limit takes five 35 seconds to run and thus calculate websites_max_runtime 36 37* Since 2022, we will start silently ignoring websites_url_limit 38` 39 40var deprecationWarningOnce sync.Once 41 42// RunGroup runs a group of nettests according to the specified config. 43func RunGroup(config RunGroupConfig) error { 44 if config.Probe.Config().Nettests.WebsitesURLLimit > 0 { 45 if config.Probe.Config().Nettests.WebsitesMaxRuntime <= 0 { 46 limit := config.Probe.Config().Nettests.WebsitesURLLimit 47 maxRuntime := 5 * limit 48 config.Probe.Config().Nettests.WebsitesMaxRuntime = maxRuntime 49 } 50 deprecationWarningOnce.Do(func() { 51 log.Warn(websitesURLLimitRemoved) 52 time.Sleep(30 * time.Second) 53 }) 54 } 55 56 if config.Probe.IsTerminated() { 57 log.Debugf("context is terminated, stopping runNettestGroup early") 58 return nil 59 } 60 61 sess, err := config.Probe.NewSession(context.Background()) 62 if err != nil { 63 log.WithError(err).Error("Failed to create a measurement session") 64 return err 65 } 66 defer sess.Close() 67 68 err = sess.MaybeLookupLocation() 69 if err != nil { 70 log.WithError(err).Error("Failed to lookup the location of the probe") 71 return err 72 } 73 network, err := database.CreateNetwork(config.Probe.DB(), sess) 74 if err != nil { 75 log.WithError(err).Error("Failed to create the network row") 76 return err 77 } 78 if err := sess.MaybeLookupBackends(); err != nil { 79 log.WithError(err).Warn("Failed to discover OONI backends") 80 return err 81 } 82 83 group, ok := All[config.GroupName] 84 if !ok { 85 log.Errorf("No test group named %s", config.GroupName) 86 return errors.New("invalid test group name") 87 } 88 log.Debugf("Running test group %s", group.Label) 89 90 result, err := database.CreateResult( 91 config.Probe.DB(), config.Probe.Home(), config.GroupName, network.ID) 92 if err != nil { 93 log.Errorf("DB result error: %s", err) 94 return err 95 } 96 97 config.Probe.ListenForSignals() 98 config.Probe.MaybeListenForStdinClosed() 99 for i, nt := range group.Nettests { 100 if config.Probe.IsTerminated() { 101 log.Debugf("context is terminated, stopping group.Nettests early") 102 break 103 } 104 log.Debugf("Running test %T", nt) 105 ctl := NewController(nt, config.Probe, result, sess) 106 ctl.InputFiles = config.InputFiles 107 ctl.Inputs = config.Inputs 108 ctl.RunType = config.RunType 109 ctl.SetNettestIndex(i, len(group.Nettests)) 110 if err = nt.Run(ctl); err != nil { 111 log.WithError(err).Errorf("Failed to run %s", group.Label) 112 } 113 } 114 115 if err = result.Finished(config.Probe.DB()); err != nil { 116 return err 117 } 118 return nil 119} 120