Add hooks for generating result summaries
This commit is contained in:
parent
a747b76ecf
commit
ce0e077175
|
@ -44,12 +44,12 @@ func init() {
|
|||
time.Now().UTC().Format(time.RFC3339Nano)))
|
||||
|
||||
ctl := nettests.NewController(nt, ctx, result, msmtPath)
|
||||
if err := nt.Run(ctl); err != nil {
|
||||
if err = nt.Run(ctl); err != nil {
|
||||
log.WithError(err).Errorf("Failed to run %s", group.Label)
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err = result.Finished(ctx.DB); err != nil {
|
||||
if err = result.Finished(ctx.DB, group.Summary); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -12,6 +12,12 @@ import (
|
|||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ResultSummaryFunc is the function used to generate result summaries
|
||||
type ResultSummaryFunc func(SummaryMap) (string, error)
|
||||
|
||||
// SummaryMap contains a mapping from test name to serialized summary for it
|
||||
type SummaryMap map[string]string
|
||||
|
||||
// UpdateOne will run the specified update query and check that it only affected one row
|
||||
func UpdateOne(db *sqlx.DB, query string, arg interface{}) error {
|
||||
res, err := db.NamedExec(query, arg)
|
||||
|
@ -187,17 +193,43 @@ type Result struct {
|
|||
MeasurementDir string `db:"measurement_dir"`
|
||||
}
|
||||
|
||||
// MakeSummaryMap return a mapping of test names to summaries for the given
|
||||
// result
|
||||
func MakeSummaryMap(db *sqlx.DB, r *Result) (SummaryMap, error) {
|
||||
summaryMap := SummaryMap{}
|
||||
|
||||
msmts := []Measurement{}
|
||||
// XXX maybe we only want to select some of the columns
|
||||
err := db.Select(&msmts, "SELECT name, summary FROM measurements WHERE result_id = $1", r.ID)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "failed to get measurements")
|
||||
}
|
||||
for _, msmt := range msmts {
|
||||
summaryMap[msmt.Name] = msmt.Summary
|
||||
}
|
||||
return summaryMap, nil
|
||||
}
|
||||
|
||||
// Finished marks the result as done and sets the runtime
|
||||
func (r *Result) Finished(db *sqlx.DB) error {
|
||||
func (r *Result) Finished(db *sqlx.DB, makeSummary ResultSummaryFunc) error {
|
||||
if r.Done == true || r.Runtime != 0 {
|
||||
return errors.New("Result is already finished")
|
||||
}
|
||||
r.Runtime = time.Now().UTC().Sub(r.StartTime).Seconds()
|
||||
r.Done = true
|
||||
// XXX add in here functionality to compute the summary
|
||||
summaryMap, err := MakeSummaryMap(db, r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err := UpdateOne(db, `UPDATE results
|
||||
SET done = :done, runtime = :runtime
|
||||
r.Summary, err = makeSummary(summaryMap)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = UpdateOne(db, `UPDATE results
|
||||
SET done = :done, runtime = :runtime, summary = :summary
|
||||
WHERE id = :id`, r)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating finished result")
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package groups
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/apex/log"
|
||||
"github.com/openobservatory/gooni/internal/database"
|
||||
"github.com/openobservatory/gooni/nettests"
|
||||
"github.com/openobservatory/gooni/nettests/performance"
|
||||
"github.com/openobservatory/gooni/nettests/websites"
|
||||
|
@ -10,7 +14,15 @@ import (
|
|||
type NettestGroup struct {
|
||||
Label string
|
||||
Nettests []nettests.Nettest
|
||||
Summary func(s string) string
|
||||
Summary database.ResultSummaryFunc
|
||||
}
|
||||
|
||||
// PerformanceSummary is the result summary for a performance test
|
||||
type PerformanceSummary struct {
|
||||
Upload int64
|
||||
Download int64
|
||||
Ping float64
|
||||
Bitrate int64
|
||||
}
|
||||
|
||||
// NettestGroups that can be run by the user
|
||||
|
@ -20,8 +32,8 @@ var NettestGroups = map[string]NettestGroup{
|
|||
Nettests: []nettests.Nettest{
|
||||
websites.WebConnectivity{},
|
||||
},
|
||||
Summary: func(s string) string {
|
||||
return "{}"
|
||||
Summary: func(m database.SummaryMap) (string, error) {
|
||||
return "{}", nil
|
||||
},
|
||||
},
|
||||
"performance": NettestGroup{
|
||||
|
@ -30,22 +42,46 @@ var NettestGroups = map[string]NettestGroup{
|
|||
performance.Dash{},
|
||||
performance.NDT{},
|
||||
},
|
||||
Summary: func(s string) string {
|
||||
return "{}"
|
||||
Summary: func(m database.SummaryMap) (string, error) {
|
||||
var (
|
||||
err error
|
||||
ndtSummary performance.NDTSummary
|
||||
dashSummary performance.DashSummary
|
||||
summary PerformanceSummary
|
||||
)
|
||||
err = json.Unmarshal([]byte(m["Dash"]), &dashSummary)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to unmarshal Dash summary")
|
||||
return "", err
|
||||
}
|
||||
err = json.Unmarshal([]byte(m["Ndt"]), &ndtSummary)
|
||||
if err != nil {
|
||||
log.WithError(err).Error("failed to unmarshal Dash summary")
|
||||
return "", err
|
||||
}
|
||||
summary.Bitrate = dashSummary.Bitrate
|
||||
summary.Download = ndtSummary.Download
|
||||
summary.Upload = ndtSummary.Upload
|
||||
summary.Ping = ndtSummary.AvgRTT
|
||||
summaryBytes, err := json.Marshal(summary)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(summaryBytes), nil
|
||||
},
|
||||
},
|
||||
"middleboxes": NettestGroup{
|
||||
Label: "Middleboxes",
|
||||
Nettests: []nettests.Nettest{},
|
||||
Summary: func(s string) string {
|
||||
return "{}"
|
||||
Summary: func(m database.SummaryMap) (string, error) {
|
||||
return "{}", nil
|
||||
},
|
||||
},
|
||||
"im": NettestGroup{
|
||||
Label: "Instant Messaging",
|
||||
Nettests: []nettests.Nettest{},
|
||||
Summary: func(s string) string {
|
||||
return "{}"
|
||||
Summary: func(m database.SummaryMap) (string, error) {
|
||||
return "{}", nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -21,9 +21,9 @@ type NDTSummary struct {
|
|||
Upload int64
|
||||
Download int64
|
||||
Ping int64
|
||||
MaxRTT int64
|
||||
AvgRTT int64
|
||||
MinRTT int64
|
||||
MaxRTT float64
|
||||
AvgRTT float64
|
||||
MinRTT float64
|
||||
MSS int64
|
||||
OutOfOrder int64
|
||||
PacketLoss float64
|
||||
|
@ -39,9 +39,9 @@ func (n NDT) Summary(tk map[string]interface{}) interface{} {
|
|||
Upload: int64(simple["upload"].(float64)),
|
||||
Download: int64(simple["download"].(float64)),
|
||||
Ping: int64(simple["ping"].(float64)),
|
||||
MaxRTT: int64(advanced["max_rtt"].(float64)),
|
||||
AvgRTT: int64(advanced["avg_rtt"].(float64)),
|
||||
MinRTT: int64(advanced["min_rtt"].(float64)),
|
||||
MaxRTT: advanced["max_rtt"].(float64),
|
||||
AvgRTT: advanced["avg_rtt"].(float64),
|
||||
MinRTT: advanced["min_rtt"].(float64),
|
||||
MSS: int64(advanced["mss"].(float64)),
|
||||
OutOfOrder: int64(advanced["out_of_order"].(float64)),
|
||||
PacketLoss: advanced["packet_loss"].(float64),
|
||||
|
|
Loading…
Reference in New Issue
Block a user