aboutsummaryrefslogtreecommitdiffstats
path: root/dashboard/app/api.go
diff options
context:
space:
mode:
authorAleksandr Nogikh <nogikh@google.com>2024-01-29 15:52:06 +0100
committerAleksandr Nogikh <nogikh@google.com>2024-01-30 10:29:21 +0000
commitfb343ecc19084bf98da750539377d508c9e077b3 (patch)
treea63a0d3ed4d1916a4b4e4128640384eb57b1e941 /dashboard/app/api.go
parent3c3c9007d75874c34398f9df1387c9eb8c54479e (diff)
all: record diverted bug reproductions
In some cases, we derail during bug reproduction and end up finding and reporting a reproducer for another issue. It causes no problems since it's bucketed using the new title, but it's difficult to trace such situations - on the original bug page, there are no failed reproduction logs and on the new bug page it looks as if we intended to find a reproducer for the bug with the new title. Let's record bug reproduction logs in this case, so that we'd also see a failed bug reproduction attempt on the original bug page.
Diffstat (limited to 'dashboard/app/api.go')
-rw-r--r--dashboard/app/api.go30
1 files changed, 24 insertions, 6 deletions
diff --git a/dashboard/app/api.go b/dashboard/app/api.go
index 63a41c6d8..ba6212da1 100644
--- a/dashboard/app/api.go
+++ b/dashboard/app/api.go
@@ -721,10 +721,25 @@ func apiReportCrash(c context.Context, ns string, r *http.Request, payload []byt
if !getNsConfig(c, ns).TransformCrash(build, req) {
return new(dashapi.ReportCrashResp), nil
}
+ var bug2 *Bug
+ if req.OriginalTitle != "" {
+ bug2, err = findExistingBugForCrash(c, ns, []string{req.OriginalTitle})
+ if err != nil {
+ return nil, fmt.Errorf("original bug query failed: %w", err)
+ }
+ }
bug, err := reportCrash(c, build, req)
if err != nil {
return nil, err
}
+ if bug2 != nil && bug2.Title != bug.Title && len(req.ReproLog) > 0 {
+ // During bug reproduction, we have diverted to another bug.
+ // Let's remember this.
+ err = saveFailedReproLog(c, bug2, build, req.ReproLog)
+ if err != nil {
+ return nil, fmt.Errorf("failed to save failed repro log: %w", err)
+ }
+ }
resp := &dashapi.ReportCrashResp{
NeedRepro: needRepro(c, bug),
}
@@ -1011,12 +1026,16 @@ func apiReportFailedRepro(c context.Context, ns string, r *http.Request, payload
if bug == nil {
return nil, fmt.Errorf("%v: can't find bug for crash %q", ns, req.Title)
}
- bugKey := bug.key(c)
build, err := loadBuild(c, ns, req.BuildID)
if err != nil {
return nil, err
}
+ return nil, saveFailedReproLog(c, bug, build, req.ReproLog)
+}
+
+func saveFailedReproLog(c context.Context, bug *Bug, build *Build, log []byte) error {
now := timeNow(c)
+ bugKey := bug.key(c)
tx := func(c context.Context) error {
bug := new(Bug)
if err := db.Get(c, bugKey, bug); err != nil {
@@ -1024,8 +1043,8 @@ func apiReportFailedRepro(c context.Context, ns string, r *http.Request, payload
}
bug.NumRepro++
bug.LastReproTime = now
- if len(req.ReproLog) > 0 {
- err := saveReproLog(c, bug, build, req.ReproLog)
+ if len(log) > 0 {
+ err := saveReproAttempt(c, bug, build, log)
if err != nil {
return fmt.Errorf("failed to save repro log: %w", err)
}
@@ -1035,16 +1054,15 @@ func apiReportFailedRepro(c context.Context, ns string, r *http.Request, payload
}
return nil
}
- err = db.RunInTransaction(c, tx, &db.TransactionOptions{
+ return db.RunInTransaction(c, tx, &db.TransactionOptions{
XG: true,
Attempts: 30,
})
- return nil, err
}
const maxReproLogs = 5
-func saveReproLog(c context.Context, bug *Bug, build *Build, log []byte) error {
+func saveReproAttempt(c context.Context, bug *Bug, build *Build, log []byte) error {
var deleteKeys []*db.Key
for len(bug.ReproAttempts)+1 > maxReproLogs {
deleteKeys = append(deleteKeys,