Keep track of the measurement state in the database
This commit is contained in:
@@ -43,7 +43,7 @@ func init() {
|
||||
fmt.Sprintf("msmt-%s-%T.jsonl", nt,
|
||||
time.Now().UTC().Format(time.RFC3339Nano)))
|
||||
|
||||
ctl := nettests.NewController(ctx, result, msmtPath)
|
||||
ctl := nettests.NewController(nt, ctx, result, msmtPath)
|
||||
if err := nt.Run(ctl); err != nil {
|
||||
log.WithError(err).Errorf("Failed to run %s", group.Label)
|
||||
return err
|
||||
|
||||
+96
-14
@@ -8,23 +8,41 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// 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)
|
||||
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating table")
|
||||
}
|
||||
count, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating table")
|
||||
}
|
||||
if count != 1 {
|
||||
return errors.New("inconsistent update count")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Measurement model
|
||||
type Measurement struct {
|
||||
ID int64 `db:"id"`
|
||||
Name string `db:"name"`
|
||||
StartTime time.Time `db:"start_time"`
|
||||
EndTime time.Time `db:"end_time"`
|
||||
Runtime float64 `db:"runtime"`
|
||||
Summary string `db:"summary"` // XXX this should be JSON
|
||||
ASN int64 `db:"asn"`
|
||||
ASN string `db:"asn"`
|
||||
IP string `db:"ip"`
|
||||
CountryCode string `db:"country"`
|
||||
State string `db:"state"`
|
||||
Failure string `db:"failure"`
|
||||
UploadFailure string `db:"upload_failure"`
|
||||
Uploaded bool `db:"uploaded"`
|
||||
ReportFilePath string `db:"report_file"`
|
||||
ReportID string `db:"report_id"`
|
||||
Input string `db:"input"`
|
||||
MeasurementID string `db:"measurement_id"`
|
||||
ResultID string `db:"result_id"`
|
||||
ResultID int64 `db:"result_id"`
|
||||
}
|
||||
|
||||
// SetGeoIPInfo for the Measurement
|
||||
@@ -32,12 +50,83 @@ func (m *Measurement) SetGeoIPInfo() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// Failed writes the error string to the measurement
|
||||
func (m *Measurement) Failed(db *sqlx.DB, failure string) error {
|
||||
m.Failure = failure
|
||||
|
||||
err := UpdateOne(db, `UPDATE measurements
|
||||
SET failure = :failure, state = :state
|
||||
WHERE id = :id`, m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating measurement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Done marks the measurement as completed
|
||||
func (m *Measurement) Done(db *sqlx.DB) error {
|
||||
m.State = "done"
|
||||
|
||||
err := UpdateOne(db, `UPDATE measurements
|
||||
SET state = :state
|
||||
WHERE id = :id`, m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating measurement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadFailed writes the error string for the upload failure to the measurement
|
||||
func (m *Measurement) UploadFailed(db *sqlx.DB, failure string) error {
|
||||
m.UploadFailure = failure
|
||||
m.Uploaded = false
|
||||
|
||||
err := UpdateOne(db, `UPDATE measurements
|
||||
SET upload_failure = :upload_failure
|
||||
WHERE id = :id`, m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating measurement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UploadSucceeded writes the error string for the upload failure to the measurement
|
||||
func (m *Measurement) UploadSucceeded(db *sqlx.DB) error {
|
||||
m.Uploaded = true
|
||||
|
||||
err := UpdateOne(db, `UPDATE measurements
|
||||
SET uploaded = :uploaded
|
||||
WHERE id = :id`, m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating measurement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteSummary writes the summary to the measurement
|
||||
func (m *Measurement) WriteSummary(db *sqlx.DB, summary string) error {
|
||||
m.Summary = summary
|
||||
|
||||
err := UpdateOne(db, `UPDATE measurements
|
||||
SET summary = :summary
|
||||
WHERE id = :id`, m)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating measurement")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CreateMeasurement writes the measurement to the database a returns a pointer
|
||||
// to the Measurement
|
||||
func CreateMeasurement(db *sqlx.DB, m Measurement) (*Measurement, error) {
|
||||
func CreateMeasurement(db *sqlx.DB, m Measurement, i string) (*Measurement, error) {
|
||||
// XXX Do we want to have this be part of something else?
|
||||
m.StartTime = time.Now().UTC()
|
||||
m.Input = i
|
||||
m.State = "active"
|
||||
|
||||
res, err := db.NamedExec(`INSERT INTO measurements
|
||||
(name, start_time,
|
||||
summary, asn, ip, country,
|
||||
asn, ip, country,
|
||||
state, failure, report_file,
|
||||
report_id, input, measurement_id,
|
||||
result_id)
|
||||
@@ -86,19 +175,12 @@ func (r *Result) Finished(db *sqlx.DB) error {
|
||||
r.Runtime = float64(time.Now().Sub(r.started)) / float64(time.Microsecond)
|
||||
r.Done = true
|
||||
|
||||
res, err := db.NamedExec(`UPDATE results
|
||||
err := UpdateOne(db, `UPDATE results
|
||||
SET done = true, runtime = :runtime
|
||||
WHERE id = :id`, r)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating result")
|
||||
}
|
||||
count, err := res.RowsAffected()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "updating result")
|
||||
}
|
||||
if count != 1 {
|
||||
return errors.New("inconsistent update count")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user