From 2675701746806f74cea1c86ce3213e3886c0ce0e Mon Sep 17 00:00:00 2001 From: Dmitry Vyukov Date: Thu, 28 Dec 2017 10:43:17 +0100 Subject: [PATCH] dashboard/app: make reporting filtering more flexible Reporting statuses are not flexible as they can't encode all possible conditions. ReportingPassThrough is a good example. Replace Status with Filter which accepts bug and can contain arbitrary logic. --- dashboard/app/config.go | 31 ++++++++++++++++++------------- dashboard/app/reporting.go | 24 +++++------------------- 2 files changed, 23 insertions(+), 32 deletions(-) diff --git a/dashboard/app/config.go b/dashboard/app/config.go index f5d534cc..0d6234f3 100644 --- a/dashboard/app/config.go +++ b/dashboard/app/config.go @@ -47,8 +47,8 @@ type Config struct { type Reporting struct { // A unique name (the app does not care about exact contents). Name string - // See ReportingStatus below. - Status ReportingStatus + // Filter can be used to conditionally skip this reporting or hold off reporting. + Filter ReportingFilter // How many new bugs report per day. DailyLimit int // Type of reporting and its configuration. @@ -71,20 +71,21 @@ var ( clientKeyRe = regexp.MustCompile("^[a-zA-Z0-9]{16,128}$") ) -type ReportingStatus int +type ( + FilterResult int + ReportingFilter func(bug *Bug) FilterResult +) const ( - // Send reports to this reporting stage. - ReportingActive ReportingStatus = iota - // Don't send anything to this reporting, but don't skip it as well. - ReportingSuspended - // Skip this reporting entirely. - ReportingDisabled - // Skip this reporting except for special bugs - // (no report, corrupted report, build error, etc). - ReportingPassThrough + FilterReport FilterResult = iota // Report bug in this reporting (default). + FilterSkip // Skip this reporting and proceed to the next one. + FilterHold // Hold off with reporting this bug. ) +func reportAllFilter(bug *Bug) FilterResult { return FilterReport } +func reportSkipFilter(bug *Bug) FilterResult { return FilterSkip } +func reportHoldFilter(bug *Bug) FilterResult { return FilterHold } + func (cfg *Config) ReportingByName(name string) *Reporting { for i := range cfg.Reporting { reporting := &cfg.Reporting[i] @@ -119,13 +120,17 @@ func init() { panic(fmt.Sprintf("no reporting in namespace %q", ns)) } reportingNames := make(map[string]bool) - for _, reporting := range cfg.Reporting { + for ri := range cfg.Reporting { + reporting := &cfg.Reporting[ri] if reporting.Name == "" { panic(fmt.Sprintf("empty reporting name in namespace %q", ns)) } if reportingNames[reporting.Name] { panic(fmt.Sprintf("duplicate reporting name %q", reporting.Name)) } + if reporting.Filter == nil { + reporting.Filter = reportAllFilter + } reportingNames[reporting.Name] = true if reporting.Config.Type() == "" { panic(fmt.Sprintf("empty reporting type for %q", reporting.Name)) diff --git a/dashboard/app/reporting.go b/dashboard/app/reporting.go index 93aaf5ea..64ad663b 100644 --- a/dashboard/app/reporting.go +++ b/dashboard/app/reporting.go @@ -152,32 +152,18 @@ func currentReporting(c context.Context, bug *Bug) (*Reporting, *BugReporting, i if reporting == nil { return nil, nil, 0, "", fmt.Errorf("%v: missing in config", bugReporting.Name) } - switch reporting.Status { - case ReportingActive: - break - case ReportingSuspended: + switch reporting.Filter(bug) { + case FilterReport: + return reporting, bugReporting, i, "", nil + case FilterHold: return nil, nil, 0, fmt.Sprintf("%v: reporting suspended", bugReporting.Name), nil - case ReportingDisabled: + case FilterSkip: continue - case ReportingPassThrough: - if !isSpecialBug(bug) { - continue - } } - return reporting, bugReporting, i, "", nil } return nil, nil, 0, "", fmt.Errorf("no reporting left") } -func isSpecialBug(bug *Bug) bool { - // We may consider introducing a bug type, but for now we just look at some fields. - return !bug.HasReport || - bug.Title == corruptedReportTitle || - strings.Contains(bug.Title, "build error") || - strings.Contains(bug.Title, "boot error:") || - strings.Contains(bug.Title, "test error:") -} - func reproStr(level dashapi.ReproLevel) string { switch level { case ReproLevelSyz: