Best Syzkaller code snippet using bisect.build
bisect_test.go
Source:bisect_test.go
...14// nolint: funlen15func TestBisectCause(t *testing.T) {16 c := NewCtx(t)17 defer c.Close()18 build := testBuild(1)19 c.client2.UploadBuild(build)20 crash := testCrash(build, 1)21 c.client2.ReportCrash(crash)22 c.client2.pollEmailBug()23 // No repro - no bisection.24 pollResp := c.client2.pollJobs(build.Manager)25 c.expectEQ(pollResp.ID, "")26 // Now upload 4 crashes with repros.27 crash2 := testCrashWithRepro(build, 2)28 c.client2.ReportCrash(crash2)29 msg2 := c.client2.pollEmailBug()30 // This is later, so will be bisected before the previous crash.31 c.advanceTime(time.Hour)32 crash3 := testCrashWithRepro(build, 3)33 c.client2.ReportCrash(crash3)34 c.client2.pollEmailBug()35 // This does not have C repro, so will be bisected after the previous ones.36 c.advanceTime(time.Hour)37 crash4 := testCrashWithRepro(build, 4)38 crash4.Title = "skip reporting2 with repro"39 crash4.ReproC = nil40 c.client2.ReportCrash(crash4)41 msg4 := c.client2.pollEmailBug()42 // This is from a different manager, so won't be bisected.43 c.advanceTime(time.Hour)44 build2 := testBuild(2)45 c.client2.UploadBuild(build2)46 crash5 := testCrashWithRepro(build2, 5)47 c.client2.ReportCrash(crash5)48 c.client2.pollEmailBug()49 // When polling for jobs the expected order is as follows :=50 // BisectCause #351 // BisectCause #252 // BisectCause #453 // After advancing time by 30 days, we get :=54 // BisectFix #255 // BisectFix #356 // BisectFix #457 // BisectCause #358 pollResp = c.client2.pollJobs(build.Manager)59 c.expectNE(pollResp.ID, "")60 c.expectEQ(pollResp.Type, dashapi.JobBisectCause)61 c.expectEQ(pollResp.Manager, build.Manager)62 c.expectEQ(pollResp.KernelConfig, build.KernelConfig)63 c.expectEQ(pollResp.SyzkallerCommit, build.SyzkallerCommit)64 c.expectEQ(pollResp.ReproOpts, []byte("repro opts 3"))65 c.expectEQ(pollResp.ReproSyz, []byte("syncfs(3)"))66 c.expectEQ(pollResp.ReproC, []byte("int main() { return 3; }"))67 // Since we did not reply, we should get the same response.68 c.advanceTime(5 * 24 * time.Hour)69 pollResp2 := c.client2.pollJobs(build.Manager)70 c.expectEQ(pollResp, pollResp2)71 // Bisection failed with an error.72 done := &dashapi.JobDoneReq{73 ID: pollResp.ID,74 Log: []byte("bisect log 3"),75 Error: []byte("bisect error 3"),76 }77 c.expectOK(c.client2.JobDone(done))78 c.expectNoEmail()79 // BisectCause #280 pollResp = c.client2.pollJobs(build.Manager)81 c.expectNE(pollResp.ID, pollResp2.ID)82 c.expectEQ(pollResp.ReproOpts, []byte("repro opts 2"))83 // Bisection succeeded.84 jobID := pollResp.ID85 done = &dashapi.JobDoneReq{86 ID: jobID,87 Build: *build,88 Log: []byte("bisect log 2"),89 CrashTitle: "bisect crash title",90 CrashLog: []byte("bisect crash log"),91 CrashReport: []byte("bisect crash report"),92 Commits: []dashapi.Commit{93 {94 Hash: "36e65cb4a0448942ec316b24d60446bbd5cc7827",95 Title: "kernel: add a bug",96 Author: "author@kernel.org",97 AuthorName: "Author Kernelov",98 CC: []string{99 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",100 // These must be filtered out:101 "syzbot@testapp.appspotmail.com",102 "syzbot+1234@testapp.appspotmail.com",103 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",104 },105 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),106 },107 },108 }109 done.Build.ID = jobID110 c.expectOK(c.client2.JobDone(done))111 _, extBugID, err := email.RemoveAddrContext(msg2.Sender)112 c.expectOK(err)113 dbBug, dbCrash, _ := c.loadBug(extBugID)114 reproSyzLink := externalLink(c.ctx, textReproSyz, dbCrash.ReproSyz)115 reproCLink := externalLink(c.ctx, textReproC, dbCrash.ReproC)116 dbJob, dbBuild, dbJobCrash := c.loadJob(jobID)117 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)118 bisectCrashReportLink := externalLink(c.ctx, textCrashReport, dbJob.CrashReport)119 bisectCrashLogLink := externalLink(c.ctx, textCrashLog, dbJob.CrashLog)120 bisectLogLink := externalLink(c.ctx, textLog, dbJob.Log)121 crashLogLink := externalLink(c.ctx, textCrashLog, dbJobCrash.Log)122 {123 msg := c.pollEmailBug()124 // Not mailed to commit author/cc because !MailMaintainers.125 c.expectEQ(msg.To, []string{"test@syzkaller.com"})126 c.expectEQ(msg.Subject, crash2.Title)127 c.expectEQ(len(msg.Attachments), 0)128 c.expectEQ(msg.Body, fmt.Sprintf(`syzbot has bisected this bug to:129commit 36e65cb4a0448942ec316b24d60446bbd5cc7827130Author: Author Kernelov <author@kernel.org>131Date: Wed Feb 9 04:05:06 2000 +0000132 kernel: add a bug133bisection log: %[2]v134start commit: 11111111 kernel_commit_title1135git tree: repo1 branch1136final crash: %[3]v137console output: %[4]v138kernel config: %[5]v139dashboard link: https://testapp.appspot.com/bug?extid=%[1]v140syz repro: %[6]v141C reproducer: %[7]v142Reported-by: syzbot+%[1]v@testapp.appspotmail.com143Fixes: 36e65cb4a044 ("kernel: add a bug")144For information about bisection process see: https://goo.gl/tpsmEJ#bisection145`, extBugID, bisectLogLink, bisectCrashReportLink, bisectCrashLogLink, kernelConfigLink, reproSyzLink, reproCLink))146 syzRepro := []byte(fmt.Sprintf("# https://testapp.appspot.com/bug?id=%v\n%s#%s\n%s",147 dbBug.keyHash(), syzReproPrefix, crash2.ReproOpts, crash2.ReproSyz))148 cRepro := []byte(fmt.Sprintf("// https://testapp.appspot.com/bug?id=%v\n%s",149 dbBug.keyHash(), crash2.ReproC))150 c.checkURLContents(bisectLogLink, []byte("bisect log 2"))151 c.checkURLContents(bisectCrashReportLink, []byte("bisect crash report"))152 c.checkURLContents(bisectCrashLogLink, []byte("bisect crash log"))153 c.checkURLContents(kernelConfigLink, []byte("config1"))154 c.checkURLContents(reproSyzLink, syzRepro)155 c.checkURLContents(reproCLink, cRepro)156 }157 // The next reporting must get bug report with bisection results.158 c.incomingEmail(msg2.Sender, "#syz upstream")159 {160 msg := c.pollEmailBug()161 _, extBugID2, err := email.RemoveAddrContext(msg.Sender)162 c.expectOK(err)163 c.expectEQ(msg.To, []string{164 "author@kernel.org",165 "bugs@syzkaller.com",166 "default@maintainers.com",167 "reviewer1@kernel.org",168 "reviewer2@kernel.org",169 })170 c.expectEQ(msg.Subject, crash2.Title)171 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,172syzbot found the following crash on:173HEAD commit: 11111111 kernel_commit_title1174git tree: repo1 branch1175console output: %[2]v176kernel config: %[3]v177dashboard link: https://testapp.appspot.com/bug?extid=%[1]v178compiler: compiler1179syz repro: %[4]v180C reproducer: %[5]v181CC: [author@kernel.org reviewer1@kernel.org reviewer2@kernel.org]182The bug was bisected to:183commit 36e65cb4a0448942ec316b24d60446bbd5cc7827184Author: Author Kernelov <author@kernel.org>185Date: Wed Feb 9 04:05:06 2000 +0000186 kernel: add a bug187bisection log: %[6]v188final crash: %[7]v189console output: %[8]v190IMPORTANT: if you fix the bug, please add the following tag to the commit:191Reported-by: syzbot+%[1]v@testapp.appspotmail.com192Fixes: 36e65cb4a044 ("kernel: add a bug")193report2194---195This bug is generated by a bot. It may contain errors.196See https://goo.gl/tpsmEJ for more information about syzbot.197syzbot engineers can be reached at syzkaller@googlegroups.com.198syzbot will keep track of this bug report. See:199https://goo.gl/tpsmEJ#status for how to communicate with syzbot.200For information about bisection process see: https://goo.gl/tpsmEJ#bisection201syzbot can test patches for this bug, for details see:202https://goo.gl/tpsmEJ#testing-patches`,203 extBugID2, crashLogLink, kernelConfigLink, reproSyzLink, reproCLink,204 bisectLogLink, bisectCrashReportLink, bisectCrashLogLink))205 }206 // BisectCause #4207 // Crash 4 is bisected in reporting with MailMaintainers.208 // It also skipped second reporting because of the title.209 c.incomingEmail(msg4.Sender, "#syz upstream")210 msg4 = c.pollEmailBug()211 c.expectEQ(msg4.To, []string{212 "bugs2@syzkaller.com",213 "default2@maintainers.com",214 })215 pollResp = c.client2.pollJobs(build.Manager)216 // Bisection succeeded.217 jobID = pollResp.ID218 done = &dashapi.JobDoneReq{219 ID: jobID,220 Build: *build,221 Log: []byte("bisectcause log 4"),222 CrashTitle: "bisectcause crash title 4",223 CrashLog: []byte("bisectcause crash log 4"),224 CrashReport: []byte("bisectcause crash report 4"),225 Commits: []dashapi.Commit{226 {227 Hash: "36e65cb4a0448942ec316b24d60446bbd5cc7827",228 Title: "kernel: add a bug",229 Author: "author@kernel.org",230 AuthorName: "Author Kernelov",231 CC: []string{232 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",233 // These must be filtered out:234 "syzbot@testapp.appspotmail.com",235 "syzbot+1234@testapp.appspotmail.com",236 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",237 },238 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),239 },240 },241 }242 done.Build.ID = jobID243 c.expectOK(c.client2.JobDone(done))244 {245 msg := c.pollEmailBug()246 c.expectEQ(msg.Subject, crash4.Title)247 c.expectEQ(msg.To, []string{248 "author@kernel.org",249 "bugs2@syzkaller.com",250 "default2@maintainers.com",251 "reviewer1@kernel.org",252 "reviewer2@kernel.org",253 })254 }255 {256 c.advanceTime(30 * 24 * time.Hour)257 subjects := []string{"title3", "title1", "title5", "title3", "title5", "title1"}258 for i := 0; i < 6; i++ {259 msg := c.pollEmailBug()260 c.expectEQ(msg.Subject, subjects[i])261 if i < 3 {262 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))263 } else {264 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash on"))265 }266 }267 }268 // BisectFix #2269 pollResp = c.client2.pollJobs(build.Manager)270 c.expectNE(pollResp.ID, "")271 c.expectEQ(pollResp.Type, dashapi.JobBisectFix)272 c.expectEQ(pollResp.ReproOpts, []byte("repro opts 2"))273 c.advanceTime(5 * 24 * time.Hour)274 pollResp2 = c.client2.pollJobs(build.Manager)275 c.expectEQ(pollResp, pollResp2)276 done = &dashapi.JobDoneReq{277 ID: pollResp.ID,278 Log: []byte("bisect log 2"),279 Error: []byte("bisect error 2"),280 }281 c.expectOK(c.client2.JobDone(done))282 // BisectFix #3283 pollResp = c.client2.pollJobs(build.Manager)284 c.expectNE(pollResp.ID, "")285 c.expectEQ(pollResp.Type, dashapi.JobBisectFix)286 c.expectEQ(pollResp.ReproOpts, []byte("repro opts 3"))287 done = &dashapi.JobDoneReq{288 ID: pollResp.ID,289 Log: []byte("bisect log 3"),290 Error: []byte("bisect error 3"),291 }292 c.expectOK(c.client2.JobDone(done))293 // BisectFix #4294 pollResp = c.client2.pollJobs(build.Manager)295 c.expectNE(pollResp.ID, "")296 c.expectEQ(pollResp.Type, dashapi.JobBisectFix)297 c.expectEQ(pollResp.ReproOpts, []byte("repro opts 4"))298 jobID = pollResp.ID299 done = &dashapi.JobDoneReq{300 ID: jobID,301 Build: *build,302 Log: []byte("bisectfix log 4"),303 CrashTitle: "bisectfix crash title 4",304 CrashLog: []byte("bisectfix crash log 4"),305 CrashReport: []byte("bisectfix crash report 4"),306 Commits: []dashapi.Commit{307 {308 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",309 Title: "kernel: add a fix",310 Author: "author@kernel.org",311 AuthorName: "Author Kernelov",312 CC: []string{313 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",314 // These must be filtered out:315 "syzbot@testapp.appspotmail.com",316 "syzbot+1234@testapp.appspotmail.com",317 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",318 },319 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),320 },321 },322 }323 done.Build.ID = jobID324 c.expectOK(c.client2.JobDone(done))325 _, extBugID, err = email.RemoveAddrContext(msg4.Sender)326 c.expectOK(err)327 dbBug, dbCrash, _ = c.loadBug(extBugID)328 reproSyzLink = externalLink(c.ctx, textReproSyz, dbCrash.ReproSyz)329 reproCLink = externalLink(c.ctx, textReproC, dbCrash.ReproC)330 dbJob, dbBuild, _ = c.loadJob(jobID)331 kernelConfigLink = externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)332 bisectCrashReportLink = externalLink(c.ctx, textCrashReport, dbJob.CrashReport)333 bisectCrashLogLink = externalLink(c.ctx, textCrashLog, dbJob.CrashLog)334 bisectLogLink = externalLink(c.ctx, textLog, dbJob.Log)335 {336 msg := c.pollEmailBug()337 // Not mailed to commit author/cc because !MailMaintainers.338 // c.expectEQ(msg.To, []string{"test@syzkaller.com"})339 c.expectEQ(msg.Subject, crash4.Title)340 c.expectEQ(len(msg.Attachments), 0)341 c.expectEQ(msg.Body, fmt.Sprintf(`syzbot suspects this bug was fixed by commit:342commit 46e65cb4a0448942ec316b24d60446bbd5cc7827343Author: Author Kernelov <author@kernel.org>344Date: Wed Feb 9 04:05:06 2000 +0000345 kernel: add a fix346bisection log: %[2]v347start commit: 11111111 kernel_commit_title1348git tree: repo1 branch1349final crash: %[3]v350console output: %[4]v351kernel config: %[5]v352dashboard link: https://testapp.appspot.com/bug?extid=%[1]v353syz repro: %[6]v354If the result looks correct, please mark the bug fixed by replying with:355#syz fix: kernel: add a fix356For information about bisection process see: https://goo.gl/tpsmEJ#bisection357`, extBugID, bisectLogLink, bisectCrashReportLink, bisectCrashLogLink, kernelConfigLink, reproSyzLink, reproCLink))358 syzRepro := []byte(fmt.Sprintf("# https://testapp.appspot.com/bug?id=%v\n%s#%s\n%s",359 dbBug.keyHash(), syzReproPrefix, crash4.ReproOpts, crash4.ReproSyz))360 c.checkURLContents(bisectLogLink, []byte("bisectfix log 4"))361 c.checkURLContents(bisectCrashReportLink, []byte("bisectfix crash report 4"))362 c.checkURLContents(bisectCrashLogLink, []byte("bisectfix crash log 4"))363 c.checkURLContents(kernelConfigLink, []byte("config1"))364 c.checkURLContents(reproSyzLink, syzRepro)365 }366 // No more bisection jobs.367 pollResp = c.client2.pollJobs(build.Manager)368 c.expectEQ(pollResp.ID, "")369}370func TestBisectCauseInconclusive(t *testing.T) {371 c := NewCtx(t)372 defer c.Close()373 build := testBuild(1)374 c.client2.UploadBuild(build)375 crash := testCrashWithRepro(build, 1)376 c.client2.ReportCrash(crash)377 msg := c.client2.pollEmailBug()378 pollResp := c.client2.pollJobs(build.Manager)379 jobID := pollResp.ID380 done := &dashapi.JobDoneReq{381 ID: jobID,382 Build: *build,383 Log: []byte("bisect log"),384 Commits: []dashapi.Commit{385 {386 Hash: "111111111111111111111111",387 Title: "kernel: break build",388 Author: "hacker@kernel.org",389 AuthorName: "Hacker Kernelov",390 CC: []string{"reviewer1@kernel.org", "reviewer2@kernel.org"},391 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),392 },393 {394 Hash: "222222222222222222222222",395 Title: "kernel: now add a bug to the broken build",396 Author: "author@kernel.org",397 AuthorName: "Author Kernelov",398 CC: []string{"reviewer3@kernel.org", "reviewer4@kernel.org"},399 Date: time.Date(2001, 2, 9, 4, 5, 6, 7, time.UTC),400 },401 },402 }403 done.Build.ID = jobID404 c.expectOK(c.client2.JobDone(done))405 _, extBugID, err := email.RemoveAddrContext(msg.Sender)406 c.expectOK(err)407 _, dbCrash, _ := c.loadBug(extBugID)408 reproSyzLink := externalLink(c.ctx, textReproSyz, dbCrash.ReproSyz)409 reproCLink := externalLink(c.ctx, textReproC, dbCrash.ReproC)410 dbJob, dbBuild, dbJobCrash := c.loadJob(jobID)411 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)412 bisectLogLink := externalLink(c.ctx, textLog, dbJob.Log)413 crashLogLink := externalLink(c.ctx, textCrashLog, dbJobCrash.Log)414 {415 msg := c.pollEmailBug()416 // Not mailed to commit author/cc because !MailMaintainers.417 c.expectEQ(msg.To, []string{"test@syzkaller.com"})418 c.expectEQ(msg.Subject, crash.Title)419 c.expectEQ(len(msg.Attachments), 0)420 c.expectEQ(msg.Body, fmt.Sprintf(`Bisection is inconclusive: the first bad commit could be any of:42111111111 kernel: break build42222222222 kernel: now add a bug to the broken build423bisection log: %[2]v424start commit: 11111111 kernel_commit_title1425git tree: repo1 branch1426kernel config: %[3]v427dashboard link: https://testapp.appspot.com/bug?extid=%[1]v428syz repro: %[4]v429C reproducer: %[5]v430For information about bisection process see: https://goo.gl/tpsmEJ#bisection431`, extBugID, bisectLogLink, kernelConfigLink, reproSyzLink, reproCLink))432 }433 // The next reporting must get bug report with bisection results.434 c.incomingEmail(msg.Sender, "#syz upstream")435 {436 msg := c.pollEmailBug()437 _, extBugID2, err := email.RemoveAddrContext(msg.Sender)438 c.expectOK(err)439 c.expectEQ(msg.To, []string{440 "bugs@syzkaller.com",441 "default@maintainers.com",442 })443 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,444syzbot found the following crash on:445HEAD commit: 11111111 kernel_commit_title1446git tree: repo1 branch1447console output: %[2]v448kernel config: %[3]v449dashboard link: https://testapp.appspot.com/bug?extid=%[1]v450compiler: compiler1451syz repro: %[4]v452C reproducer: %[5]v453Bisection is inconclusive: the first bad commit could be any of:45411111111 kernel: break build45522222222 kernel: now add a bug to the broken build456bisection log: %[6]v457IMPORTANT: if you fix the bug, please add the following tag to the commit:458Reported-by: syzbot+%[1]v@testapp.appspotmail.com459report1460---461This bug is generated by a bot. It may contain errors.462See https://goo.gl/tpsmEJ for more information about syzbot.463syzbot engineers can be reached at syzkaller@googlegroups.com.464syzbot will keep track of this bug report. See:465https://goo.gl/tpsmEJ#status for how to communicate with syzbot.466For information about bisection process see: https://goo.gl/tpsmEJ#bisection467syzbot can test patches for this bug, for details see:468https://goo.gl/tpsmEJ#testing-patches`,469 extBugID2, crashLogLink, kernelConfigLink, reproSyzLink, reproCLink, bisectLogLink))470 }471}472func TestBisectWrong(t *testing.T) {473 // Test bisection results with BisectResultMerge/BisectResultNoop flags set.474 // If any of these set, the result must not be reported separately,475 // as part of bug report during upstreamming, nor should affect CC list.476 c := NewCtx(t)477 defer c.Close()478 build := testBuild(1)479 c.client2.UploadBuild(build)480 for i := 0; i < 6; i++ {481 var flags dashapi.JobDoneFlags482 switch i {483 case 0:484 case 1:485 flags = dashapi.BisectResultMerge486 case 2:487 flags = dashapi.BisectResultNoop488 case 3:489 flags = dashapi.BisectResultMerge | dashapi.BisectResultNoop490 case 4:491 flags = dashapi.BisectResultRelease492 case 5:493 flags = dashapi.BisectResultIgnore494 default:495 t.Fatalf("assign flags")496 }497 t.Logf("iteration %v: flags=%v", i, flags)498 crash := testCrashWithRepro(build, i)499 c.client2.ReportCrash(crash)500 c.client2.pollEmailBug()501 {502 pollResp := c.client2.pollJobs(build.Manager)503 done := &dashapi.JobDoneReq{504 ID: pollResp.ID,505 Flags: flags,506 Build: *build,507 Log: []byte("bisect log"),508 Commits: []dashapi.Commit{509 {510 Hash: "111111111111111111111111",511 Title: "kernel: break build",512 Author: "hacker@kernel.org",513 AuthorName: "Hacker Kernelov",514 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),515 },516 },517 }518 done.Build.ID = pollResp.ID519 c.expectOK(c.client2.JobDone(done))520 if i == 0 {521 msg := c.pollEmailBug()522 c.expectTrue(strings.Contains(msg.Body, "syzbot has bisected this bug to:"))523 } else {524 c.expectNoEmail()525 }526 }527 {528 c.advanceTime(31 * 24 * time.Hour)529 pollResp := c.client2.pollJobs(build.Manager)530 done := &dashapi.JobDoneReq{531 ID: pollResp.ID,532 Flags: flags,533 Build: *build,534 Log: []byte("bisectfix log 4"),535 CrashTitle: "bisectfix crash title 4",536 CrashLog: []byte("bisectfix crash log 4"),537 CrashReport: []byte("bisectfix crash report 4"),538 Commits: []dashapi.Commit{539 {540 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",541 Title: "kernel: add a fix",542 Author: "fixer@kernel.org",543 AuthorName: "Author Kernelov",544 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),545 },546 },547 }548 done.Build.ID = pollResp.ID549 c.expectOK(c.client2.JobDone(done))550 if i == 0 {551 msg := c.pollEmailBug()552 c.expectTrue(strings.Contains(msg.Body, "syzbot suspects this bug was fixed by commit:"))553 }554 }555 {556 // Auto-upstreamming.557 c.advanceTime(31 * 24 * time.Hour)558 msg := c.pollEmailBug()559 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream"))560 msg = c.pollEmailBug()561 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash on:"))562 if i == 0 {563 c.expectTrue(strings.Contains(msg.Body, "The bug was bisected to:"))564 c.expectEQ(msg.To, []string{565 "bugs@syzkaller.com",566 "default@maintainers.com",567 "hacker@kernel.org",568 })569 } else {570 c.expectTrue(!strings.Contains(msg.Body, "The bug was bisected to:"))571 c.expectEQ(msg.To, []string{572 "bugs@syzkaller.com",573 "default@maintainers.com",574 })575 }576 }577 c.expectNoEmail()578 }579}580func TestBisectCauseAncient(t *testing.T) {581 c := NewCtx(t)582 defer c.Close()583 build := testBuild(1)584 c.client2.UploadBuild(build)585 crash := testCrashWithRepro(build, 1)586 c.client2.ReportCrash(crash)587 msg := c.client2.pollEmailBug()588 pollResp := c.client2.pollJobs(build.Manager)589 jobID := pollResp.ID590 done := &dashapi.JobDoneReq{591 ID: jobID,592 Build: *build,593 Log: []byte("bisect log"),594 CrashTitle: "bisect crash title",595 CrashLog: []byte("bisect crash log"),596 CrashReport: []byte("bisect crash report"),597 }598 done.Build.ID = jobID599 c.expectOK(c.client2.JobDone(done))600 _, extBugID, err := email.RemoveAddrContext(msg.Sender)601 c.expectOK(err)602 _, dbCrash, _ := c.loadBug(extBugID)603 reproSyzLink := externalLink(c.ctx, textReproSyz, dbCrash.ReproSyz)604 reproCLink := externalLink(c.ctx, textReproC, dbCrash.ReproC)605 dbJob, dbBuild, dbJobCrash := c.loadJob(jobID)606 bisectCrashReportLink := externalLink(c.ctx, textCrashReport, dbJob.CrashReport)607 bisectCrashLogLink := externalLink(c.ctx, textCrashLog, dbJob.CrashLog)608 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)609 bisectLogLink := externalLink(c.ctx, textLog, dbJob.Log)610 crashLogLink := externalLink(c.ctx, textCrashLog, dbJobCrash.Log)611 {612 msg := c.pollEmailBug()613 // Not mailed to commit author/cc because !MailMaintainers.614 c.expectEQ(msg.To, []string{"test@syzkaller.com"})615 c.expectEQ(msg.Subject, crash.Title)616 c.expectEQ(len(msg.Attachments), 0)617 c.expectEQ(msg.Body, fmt.Sprintf(`Bisection is inconclusive: the bug happens on the oldest tested release.618bisection log: %[2]v619oldest commit: 11111111 kernel_commit_title1620git tree: repo1 branch1621final crash: %[3]v622console output: %[4]v623kernel config: %[5]v624dashboard link: https://testapp.appspot.com/bug?extid=%[1]v625syz repro: %[6]v626C reproducer: %[7]v627For information about bisection process see: https://goo.gl/tpsmEJ#bisection628`, extBugID, bisectLogLink, bisectCrashReportLink, bisectCrashLogLink,629 kernelConfigLink, reproSyzLink, reproCLink))630 }631 // The next reporting must get bug report with bisection results.632 c.incomingEmail(msg.Sender, "#syz upstream")633 {634 msg := c.pollEmailBug()635 _, extBugID2, err := email.RemoveAddrContext(msg.Sender)636 c.expectOK(err)637 c.expectEQ(msg.To, []string{638 "bugs@syzkaller.com",639 "default@maintainers.com",640 })641 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,642syzbot found the following crash on:643HEAD commit: 11111111 kernel_commit_title1644git tree: repo1 branch1645console output: %[2]v646kernel config: %[3]v647dashboard link: https://testapp.appspot.com/bug?extid=%[1]v648compiler: compiler1649syz repro: %[4]v650C reproducer: %[5]v651Bisection is inconclusive: the bug happens on the oldest tested release.652bisection log: %[6]v653final crash: %[7]v654console output: %[8]v655IMPORTANT: if you fix the bug, please add the following tag to the commit:656Reported-by: syzbot+%[1]v@testapp.appspotmail.com657report1658---659This bug is generated by a bot. It may contain errors.660See https://goo.gl/tpsmEJ for more information about syzbot.661syzbot engineers can be reached at syzkaller@googlegroups.com.662syzbot will keep track of this bug report. See:663https://goo.gl/tpsmEJ#status for how to communicate with syzbot.664For information about bisection process see: https://goo.gl/tpsmEJ#bisection665syzbot can test patches for this bug, for details see:666https://goo.gl/tpsmEJ#testing-patches`,667 extBugID2, crashLogLink, kernelConfigLink, reproSyzLink, reproCLink,668 bisectLogLink, bisectCrashReportLink, bisectCrashLogLink))669 }670}671func TestBisectCauseExternal(t *testing.T) {672 c := NewCtx(t)673 defer c.Close()674 build := testBuild(1)675 c.client.UploadBuild(build)676 crash := testCrashWithRepro(build, 1)677 c.client.ReportCrash(crash)678 rep := c.client.pollBug()679 pollResp := c.client.pollJobs(build.Manager)680 c.expectNE(pollResp.ID, "")681 jobID := pollResp.ID682 done := &dashapi.JobDoneReq{683 ID: jobID,684 Build: *build,685 Log: []byte("bisect log"),686 Commits: []dashapi.Commit{687 {688 Hash: "111111111111111111111111",689 Title: "kernel: break build",690 Author: "hacker@kernel.org",691 AuthorName: "Hacker Kernelov",692 CC: []string{"reviewer1@kernel.org", "reviewer2@kernel.org"},693 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),694 },695 },696 }697 done.Build.ID = jobID698 c.expectOK(c.client.JobDone(done))699 resp, _ := c.client.ReportingPollBugs("test")700 c.expectEQ(len(resp.Reports), 1)701 // Still reported because we did not ack.702 bisect := c.client.pollBug()703 // pollBug acks, must not be reported after that.704 c.client.pollBugs(0)705 c.expectEQ(bisect.Type, dashapi.ReportBisectCause)706 c.expectEQ(bisect.Title, rep.Title)707}708func TestBisectFixExternal(t *testing.T) {709 c := NewCtx(t)710 defer c.Close()711 build := testBuild(1)712 c.client.UploadBuild(build)713 crash := testCrashWithRepro(build, 1)714 c.client.ReportCrash(crash)715 rep := c.client.pollBug()716 {717 // Cause bisection fails.718 pollResp := c.client.pollJobs(build.Manager)719 done := &dashapi.JobDoneReq{720 ID: pollResp.ID,721 Log: []byte("bisect log"),722 Error: []byte("bisect error"),723 }724 c.expectOK(c.client.JobDone(done))725 }726 c.advanceTime(31 * 24 * time.Hour)727 {728 // Fix bisection succeeds.729 pollResp := c.client.pollJobs(build.Manager)730 done := &dashapi.JobDoneReq{731 ID: pollResp.ID,732 Build: *build,733 Log: []byte("bisectfix log"),734 CrashTitle: "bisectfix crash title",735 CrashLog: []byte("bisectfix crash log"),736 CrashReport: []byte("bisectfix crash report"),737 Commits: []dashapi.Commit{738 {739 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",740 Title: "kernel: add a fix",741 Author: "fixer@kernel.org",742 AuthorName: "Author Kernelov",743 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),744 },745 },746 }747 done.Build.ID = pollResp.ID748 c.expectOK(c.client.JobDone(done))749 rep := c.client.pollBug()750 c.expectEQ(rep.Type, dashapi.ReportBisectFix)751 }752 {753 // At this point the bug should be marked as fixed by the commit754 // because the namespace has FixBisectionAutoClose set.755 dbBug, _, _ := c.loadBug(rep.ID)756 c.expectEQ(dbBug.Commits, []string{"kernel: add a fix"})757 }758}759func TestBisectCauseReproSyz(t *testing.T) {760 c := NewCtx(t)761 defer c.Close()762 build := testBuild(1)763 c.client2.UploadBuild(build)764 crash := testCrashWithRepro(build, 1)765 crash.ReproC = nil766 c.client2.ReportCrash(crash)767 pollResp := c.client2.pollJobs(build.Manager)768 jobID := pollResp.ID769 done := &dashapi.JobDoneReq{770 ID: jobID,771 Build: *build,772 Log: []byte("bisect log"),773 CrashTitle: "bisect crash title",774 CrashLog: []byte("bisect crash log"),775 }776 done.Build.ID = jobID777 c.expectOK(c.client2.JobDone(done))778 crash.ReproC = []byte("int main")779 c.client2.ReportCrash(crash)780 msg := c.client2.pollEmailBug()781 if !strings.Contains(msg.Body, "syzbot found the following crash") {782 t.Fatalf("wrong email header:\n%v", msg.Body)783 }784 if !strings.Contains(msg.Body, "Bisection is inconclusive") {785 t.Fatalf("report does not contain bisection results:\n%v", msg.Body)786 }787}788func TestBisectCauseReproSyz2(t *testing.T) {789 c := NewCtx(t)790 defer c.Close()791 build := testBuild(1)792 c.client2.UploadBuild(build)793 crash := testCrashWithRepro(build, 1)794 crash.ReproC = nil795 c.client2.ReportCrash(crash)796 pollResp := c.client2.pollJobs(build.Manager)797 jobID := pollResp.ID798 done := &dashapi.JobDoneReq{799 ID: jobID,800 Build: *build,801 Log: []byte("bisect log"),802 CrashTitle: "bisect crash title",803 CrashLog: []byte("bisect crash log"),804 }805 done.Build.ID = jobID806 c.expectOK(c.client2.JobDone(done))807 msg := c.client2.pollEmailBug()808 if !strings.Contains(msg.Body, "syzbot found the following crash") {809 t.Fatalf("wrong email header:\n%v", msg.Body)810 }811 if !strings.Contains(msg.Body, "Bisection is inconclusive") {812 t.Fatalf("report does not contain bisection results:\n%v", msg.Body)813 }814 crash.ReproC = []byte("int main")815 c.client2.ReportCrash(crash)816 msg = c.client2.pollEmailBug()817 if !strings.Contains(msg.Body, "syzbot has found a reproducer for the following crash") {818 t.Fatalf("wrong email header:\n%v", msg.Body)819 }820 // Do we need bisection results in this email as well?821 // We already mailed them, so we could not mail them here.822 // But if we don't include bisection results, need to check that CC is correct823 // (includes bisection CC).824 if !strings.Contains(msg.Body, "Bisection is inconclusive") {825 t.Fatalf("report still contains bisection results:\n%v", msg.Body)826 }827}828// Test that bisection results show up on UI.829func TestBugBisectionResults(t *testing.T) {830 c := NewCtx(t)831 defer c.Close()832 // Upload a crash report833 build := testBuild(1)834 c.client2.UploadBuild(build)835 crash := testCrashWithRepro(build, 1)836 c.client2.ReportCrash(crash)837 c.client2.pollEmailBug()838 // Receive the JobBisectCause and send cause information839 resp := c.client2.pollJobs(build.Manager)840 c.client2.expectNE(resp.ID, "")841 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)842 jobID := resp.ID843 done := &dashapi.JobDoneReq{844 ID: jobID,845 Build: *build,846 Log: []byte("bisectfix log 4"),847 CrashTitle: "bisectfix crash title 4",848 CrashLog: []byte("bisectfix crash log 4"),849 CrashReport: []byte("bisectfix crash report 4"),850 Commits: []dashapi.Commit{851 {852 Hash: "36e65cb4a0448942ec316b24d60446bbd5cc7827",853 Title: "kernel: add a bug",854 Author: "author@kernel.org",855 AuthorName: "Author Kernelov",856 CC: []string{857 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",858 // These must be filtered out:859 "syzbot@testapp.appspotmail.com",860 "syzbot+1234@testapp.appspotmail.com",861 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",862 },863 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),864 },865 },866 }867 c.expectOK(c.client2.JobDone(done))868 // Advance time by 30 days and read out any notification emails869 {870 c.advanceTime(30 * 24 * time.Hour)871 msg := c.client2.pollEmailBug()872 c.expectTrue(strings.Contains(msg.Body, "syzbot has bisected this bug to:"))873 msg = c.client2.pollEmailBug()874 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))875 msg = c.client2.pollEmailBug()876 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))877 }878 // Receive a JobBisectfix and send fix information.879 resp = c.client2.pollJobs(build.Manager)880 c.client2.expectNE(resp.ID, "")881 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)882 jobID = resp.ID883 done = &dashapi.JobDoneReq{884 ID: jobID,885 Build: *build,886 Log: []byte("bisectfix log 4"),887 CrashTitle: "bisectfix crash title 4",888 CrashLog: []byte("bisectfix crash log 4"),889 CrashReport: []byte("bisectfix crash report 4"),890 Commits: []dashapi.Commit{891 {892 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",893 Title: "kernel: add a fix",894 Author: "author@kernel.org",895 AuthorName: "Author Kernelov",896 CC: []string{897 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",898 // These must be filtered out:899 "syzbot@testapp.appspotmail.com",900 "syzbot+1234@testapp.appspotmail.com",901 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",902 },903 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),904 },905 },906 }907 c.expectOK(c.client2.JobDone(done))908 msg := c.client2.pollEmailBug()909 c.expectTrue(strings.Contains(msg.Body, "syzbot suspects this bug was fixed by commit:"))910 // Fetch bug details911 var bugs []*Bug912 keys, err := db.NewQuery("Bug").GetAll(c.ctx, &bugs)913 c.expectEQ(err, nil)914 c.expectEQ(len(bugs), 1)915 // Ensure expected results show up on web UI916 url := fmt.Sprintf("/bug?id=%v", keys[0].StringID())917 content, err := c.httpRequest("GET", url, "", AccessAdmin)918 c.expectEQ(err, nil)919 c.expectTrue(bytes.Contains(content, []byte("Cause bisection: introduced by")))920 c.expectTrue(bytes.Contains(content, []byte("kernel: add a bug")))921 c.expectTrue(bytes.Contains(content, []byte("Fix bisection: fixed by")))922 c.expectTrue(bytes.Contains(content, []byte("kernel: add a fix")))923}924// Test that bisection status shows up on main page.925func TestBugBisectionStatus(t *testing.T) {926 c := NewCtx(t)927 defer c.Close()928 // Upload a crash report929 build := testBuild(1)930 c.client2.UploadBuild(build)931 crash := testCrashWithRepro(build, 1)932 c.client2.ReportCrash(crash)933 c.client2.pollEmailBug()934 // Receive the JobBisectCause and send cause information935 resp := c.client2.pollJobs(build.Manager)936 c.client2.expectNE(resp.ID, "")937 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)938 jobID := resp.ID939 done := &dashapi.JobDoneReq{940 ID: jobID,941 Build: *build,942 Log: []byte("bisectfix log 4"),943 CrashTitle: "bisectfix crash title 4",944 CrashLog: []byte("bisectfix crash log 4"),945 CrashReport: []byte("bisectfix crash report 4"),946 Commits: []dashapi.Commit{947 {948 Hash: "36e65cb4a0448942ec316b24d60446bbd5cc7827",949 Title: "kernel: add a bug",950 Author: "author@kernel.org",951 AuthorName: "Author Kernelov",952 CC: []string{953 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",954 // These must be filtered out:955 "syzbot@testapp.appspotmail.com",956 "syzbot+1234@testapp.appspotmail.com",957 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",958 },959 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),960 },961 },962 }963 c.expectOK(c.client2.JobDone(done))964 // Fetch bug, namespace details965 var bugs []*Bug966 _, err := db.NewQuery("Bug").GetAll(c.ctx, &bugs)967 c.expectEQ(err, nil)968 c.expectEQ(len(bugs), 1)969 url := fmt.Sprintf("/%v", bugs[0].Namespace)970 content, err := c.httpRequest("GET", url, "", AccessAdmin)971 c.expectEQ(err, nil)972 c.expectTrue(bytes.Contains(content, []byte("cause")))973 // Advance time by 30 days and read out any notification emails974 {975 c.advanceTime(30 * 24 * time.Hour)976 msg := c.client2.pollEmailBug()977 c.expectTrue(strings.Contains(msg.Body, "syzbot has bisected this bug to:"))978 msg = c.client2.pollEmailBug()979 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))980 msg = c.client2.pollEmailBug()981 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))982 }983 // Receive a JobBisectfix and send fix information.984 resp = c.client2.pollJobs(build.Manager)985 c.client2.expectNE(resp.ID, "")986 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)987 jobID = resp.ID988 done = &dashapi.JobDoneReq{989 ID: jobID,990 Build: *build,991 Log: []byte("bisectfix log 4"),992 CrashTitle: "bisectfix crash title 4",993 CrashLog: []byte("bisectfix crash log 4"),994 CrashReport: []byte("bisectfix crash report 4"),995 Commits: []dashapi.Commit{996 {997 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",998 Title: "kernel: add a fix",999 Author: "author@kernel.org",1000 AuthorName: "Author Kernelov",1001 CC: []string{1002 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",1003 // These must be filtered out:1004 "syzbot@testapp.appspotmail.com",...
jobs.go
Source:jobs.go
...299 return nil, nil, nil300}301func createBisectJobForBug(c context.Context, bug0 *Bug, crash *Crash, bugKey, crashKey *db.Key, jobType JobType) (302 *Job, *db.Key, error) {303 build, err := loadBuild(c, bug0.Namespace, crash.BuildID)304 if err != nil {305 return nil, nil, err306 }307 now := timeNow(c)308 job := &Job{309 Type: jobType,310 Created: now,311 Namespace: bug0.Namespace,312 Manager: crash.Manager,313 KernelRepo: build.KernelRepo,314 KernelBranch: build.KernelBranch,315 BugTitle: bug0.displayTitle(),316 CrashID: crashKey.IntID(),317 }318 var jobKey *db.Key319 tx := func(c context.Context) error {320 jobKey = nil321 bug := new(Bug)322 if err := db.Get(c, bugKey, bug); err != nil {323 return fmt.Errorf("failed to get bug %v: %v", bugKey.StringID(), err)324 }325 if jobType == JobBisectFix && bug.BisectFix != BisectNot ||326 jobType == JobBisectCause && bug.BisectCause != BisectNot {327 // Race, we could do a more complex retry, but we just rely on the next poll.328 job = nil329 return nil330 }331 if jobType == JobBisectCause {332 bug.BisectCause = BisectPending333 } else {334 bug.BisectFix = BisectPending335 }336 // Create a new job.337 var err error338 jobKey = db.NewIncompleteKey(c, "Job", bugKey)339 if jobKey, err = db.Put(c, jobKey, job); err != nil {340 return fmt.Errorf("failed to put job: %v", err)341 }342 if _, err := db.Put(c, bugKey, bug); err != nil {343 return fmt.Errorf("failed to put bug: %v", err)344 }345 return markCrashReported(c, job.CrashID, bugKey, now)346 }347 if err := db.RunInTransaction(c, tx, nil); err != nil {348 return nil, nil, fmt.Errorf("create bisect job tx failed: %v", err)349 }350 return job, jobKey, nil351}352func createJobResp(c context.Context, job *Job, jobKey *db.Key) (*dashapi.JobPollResp, bool, error) {353 jobID := extJobID(jobKey)354 patch, _, err := getText(c, textPatch, job.Patch)355 if err != nil {356 return nil, false, err357 }358 bugKey := jobKey.Parent()359 crashKey := db.NewKey(c, "Crash", "", job.CrashID, bugKey)360 crash := new(Crash)361 if err := db.Get(c, crashKey, crash); err != nil {362 return nil, false, fmt.Errorf("job %v: failed to get crash: %v", jobID, err)363 }364 build, err := loadBuild(c, job.Namespace, crash.BuildID)365 if err != nil {366 return nil, false, err367 }368 kernelConfig, _, err := getText(c, textKernelConfig, build.KernelConfig)369 if err != nil {370 return nil, false, err371 }372 reproC, _, err := getText(c, textReproC, crash.ReproC)373 if err != nil {374 return nil, false, err375 }376 reproSyz, _, err := getText(c, textReproSyz, crash.ReproSyz)377 if err != nil {378 return nil, false, err379 }380 now := timeNow(c)381 stale := false382 tx := func(c context.Context) error {383 stale = false384 job = new(Job)385 if err := db.Get(c, jobKey, job); err != nil {386 return fmt.Errorf("job %v: failed to get in tx: %v", jobID, err)387 }388 if !job.Finished.IsZero() {389 // This happens sometimes due to inconsistent db.390 stale = true391 return nil392 }393 job.Attempts++394 job.Started = now395 if _, err := db.Put(c, jobKey, job); err != nil {396 return fmt.Errorf("job %v: failed to put: %v", jobID, err)397 }398 return nil399 }400 if err := db.RunInTransaction(c, tx, nil); err != nil {401 return nil, false, err402 }403 if stale {404 return nil, true, nil405 }406 resp := &dashapi.JobPollResp{407 ID: jobID,408 Manager: job.Manager,409 KernelRepo: job.KernelRepo,410 KernelBranch: job.KernelBranch,411 KernelCommit: build.KernelCommit,412 KernelCommitTitle: build.KernelCommitTitle,413 KernelCommitDate: build.KernelCommitDate,414 KernelConfig: kernelConfig,415 SyzkallerCommit: build.SyzkallerCommit,416 Patch: patch,417 ReproOpts: crash.ReproOpts,418 ReproSyz: reproSyz,419 ReproC: reproC,420 }421 switch job.Type {422 case JobTestPatch:423 resp.Type = dashapi.JobTestPatch424 case JobBisectCause:425 resp.Type = dashapi.JobBisectCause426 case JobBisectFix:427 resp.Type = dashapi.JobBisectFix428 default:429 return nil, false, fmt.Errorf("bad job type %v", job.Type)430 }431 return resp, false, nil432}433// doneJob is called by syz-ci to mark completion of a job.434func doneJob(c context.Context, req *dashapi.JobDoneReq) error {435 jobID := req.ID436 jobKey, err := jobID2Key(c, req.ID)437 if err != nil {438 return err439 }440 now := timeNow(c)441 tx := func(c context.Context) error {442 job := new(Job)443 if err := db.Get(c, jobKey, job); err != nil {444 return fmt.Errorf("job %v: failed to get job: %v", jobID, err)445 }446 if !job.Finished.IsZero() {447 return fmt.Errorf("job %v: already finished", jobID)448 }449 ns := job.Namespace450 if req.Build.ID != "" {451 if _, isNewBuild, err := uploadBuild(c, now, ns, &req.Build, BuildJob); err != nil {452 return err453 } else if !isNewBuild {454 log.Errorf(c, "job %v: duplicate build %v", jobID, req.Build.ID)455 }456 }457 if job.Log, err = putText(c, ns, textLog, req.Log, false); err != nil {458 return err459 }460 if job.Error, err = putText(c, ns, textError, req.Error, false); err != nil {461 return err462 }463 if job.CrashLog, err = putText(c, ns, textCrashLog, req.CrashLog, false); err != nil {464 return err465 }466 if job.CrashReport, err = putText(c, ns, textCrashReport, req.CrashReport, false); err != nil {467 return err468 }469 for _, com := range req.Commits {470 job.Commits = append(job.Commits, Commit{471 Hash: com.Hash,472 Title: com.Title,473 Author: com.Author,474 AuthorName: com.AuthorName,475 CC: strings.Join(sanitizeCC(c, com.CC), "|"),476 Date: com.Date,477 })478 }479 job.BuildID = req.Build.ID480 job.CrashTitle = req.CrashTitle481 job.Finished = now482 job.Flags = JobFlags(req.Flags)483 if job.Type == JobBisectCause || job.Type == JobBisectFix {484 // Update bug.BisectCause/Fix status and also remember current bug reporting to send results.485 if err := updateBugBisection(c, job, jobKey, req, now); err != nil {486 return err487 }488 }489 if _, err := db.Put(c, jobKey, job); err != nil {490 return fmt.Errorf("failed to put job: %v", err)491 }492 log.Infof(c, "DONE JOB %v: reported=%v reporting=%v", jobID, job.Reported, job.Reporting)493 return nil494 }495 return db.RunInTransaction(c, tx, &db.TransactionOptions{XG: true, Attempts: 30})496}497func updateBugBisection(c context.Context, job *Job, jobKey *db.Key, req *dashapi.JobDoneReq, now time.Time) error {498 bug := new(Bug)499 bugKey := jobKey.Parent()500 if err := db.Get(c, bugKey, bug); err != nil {501 return fmt.Errorf("job %v: failed to get bug: %v", req.ID, err)502 }503 result := BisectYes504 if len(req.Error) != 0 {505 result = BisectError506 }507 if job.Type == JobBisectCause {508 bug.BisectCause = result509 } else {510 bug.BisectFix = result511 }512 // If the crash still occurs on HEAD, update the bug's LastTime so that it will be513 // retried after 30 days.514 if job.Type == JobBisectFix && req.Error == nil && len(req.Commits) == 0 && len(req.CrashLog) != 0 {515 bug.BisectFix = BisectNot516 bug.LastTime = now517 }518 if _, err := db.Put(c, bugKey, bug); err != nil {519 return fmt.Errorf("failed to put bug: %v", err)520 }521 _, bugReporting, _, _, _ := currentReporting(c, bug)522 // The bug is either already closed or not yet reported in the current reporting,523 // either way we don't need to report it. If it wasn't reported, it will be reported524 // with the bisection results.525 if bugReporting == nil || bugReporting.Reported.IsZero() ||526 // Don't report errors for non-user-initiated jobs.527 job.Error != 0 ||528 // Don't report unreliable/wrong bisections.529 job.isUnreliableBisect() {530 job.Reported = true531 } else {532 job.Reporting = bugReporting.Name533 }534 return nil535}536// TODO: this is temporal for gradual bisection rollout.537// Notify only about successful cause bisection for now.538// For now we only enable this in tests.539var notifyAboutUnsuccessfulBisections = false540func pollCompletedJobs(c context.Context, typ string) ([]*dashapi.BugReport, error) {541 var jobs []*Job542 keys, err := db.NewQuery("Job").543 Filter("Finished>", time.Time{}).544 Filter("Reported=", false).545 GetAll(c, &jobs)546 if err != nil {547 return nil, fmt.Errorf("failed to query jobs: %v", err)548 }549 var reports []*dashapi.BugReport550 for i, job := range jobs {551 if job.Reporting == "" {552 log.Criticalf(c, "no reporting for job %v", extJobID(keys[i]))553 continue554 }555 reporting := config.Namespaces[job.Namespace].ReportingByName(job.Reporting)556 if reporting.Config.Type() != typ {557 continue558 }559 if job.Type == JobBisectCause && !notifyAboutUnsuccessfulBisections && len(job.Commits) != 1 {560 continue561 }562 // If BisectFix results in a crash on HEAD, no notification is sent out.563 if job.Type == JobBisectFix && len(job.Commits) != 1 {564 continue565 }566 // If the bug is already known to be fixed, invalid or duplicate, do not report the bisection results.567 if job.Type == JobBisectCause || job.Type == JobBisectFix {568 bug := new(Bug)569 bugKey := keys[i].Parent()570 if err := db.Get(c, bugKey, bug); err != nil {571 return nil, fmt.Errorf("job %v: failed to get bug: %v", extJobID(keys[i]), err)572 }573 if len(bug.Commits) != 0 || bug.Status != BugStatusOpen {574 jobReported(c, extJobID(keys[i]))575 continue576 }577 }578 rep, err := createBugReportForJob(c, job, keys[i], reporting.Config)579 if err != nil {580 log.Errorf(c, "failed to create report for job: %v", err)581 continue582 }583 reports = append(reports, rep)584 }585 return reports, nil586}587func createBugReportForJob(c context.Context, job *Job, jobKey *db.Key, config interface{}) (588 *dashapi.BugReport, error) {589 reportingConfig, err := json.Marshal(config)590 if err != nil {591 return nil, err592 }593 crashLog, _, err := getText(c, textCrashLog, job.CrashLog)594 if err != nil {595 return nil, err596 }597 if len(crashLog) > maxMailLogLen {598 crashLog = crashLog[len(crashLog)-maxMailLogLen:]599 }600 report, _, err := getText(c, textCrashReport, job.CrashReport)601 if err != nil {602 return nil, err603 }604 if len(report) > maxMailReportLen {605 report = report[:maxMailReportLen]606 }607 jobError, _, err := getText(c, textError, job.Error)608 if err != nil {609 return nil, err610 }611 build, err := loadBuild(c, job.Namespace, job.BuildID)612 if err != nil {613 return nil, err614 }615 bugKey := jobKey.Parent()616 crashKey := db.NewKey(c, "Crash", "", job.CrashID, bugKey)617 crash := new(Crash)618 if err := db.Get(c, crashKey, crash); err != nil {619 return nil, fmt.Errorf("failed to get crash: %v", err)620 }621 bug := new(Bug)622 if err := db.Get(c, bugKey, bug); err != nil {623 return nil, fmt.Errorf("failed to load job parent bug: %v", err)624 }625 bugReporting := bugReportingByName(bug, job.Reporting)626 if bugReporting == nil {627 return nil, fmt.Errorf("job bug has no reporting %q", job.Reporting)628 }629 var typ dashapi.ReportType630 switch job.Type {631 case JobTestPatch:632 typ = dashapi.ReportTestPatch633 case JobBisectCause:634 typ = dashapi.ReportBisectCause635 case JobBisectFix:636 typ = dashapi.ReportBisectFix637 default:638 return nil, fmt.Errorf("unknown job type %v", job.Type)639 }640 kernelRepo := kernelRepoInfo(build)641 rep := &dashapi.BugReport{642 Type: typ,643 Config: reportingConfig,644 JobID: extJobID(jobKey),645 ExtID: job.ExtID,646 CC: append(job.CC, kernelRepo.CC...),647 Log: crashLog,648 LogLink: externalLink(c, textCrashLog, job.CrashLog),649 Report: report,650 ReportLink: externalLink(c, textCrashReport, job.CrashReport),651 ReproCLink: externalLink(c, textReproC, crash.ReproC),652 ReproSyzLink: externalLink(c, textReproSyz, crash.ReproSyz),653 CrashTitle: job.CrashTitle,654 Error: jobError,655 ErrorLink: externalLink(c, textError, job.Error),656 PatchLink: externalLink(c, textPatch, job.Patch),657 }658 if job.Type == JobBisectCause || job.Type == JobBisectFix {659 rep.Maintainers = append(crash.Maintainers, kernelRepo.Maintainers...)660 rep.ExtID = bugReporting.ExtID661 if bugReporting.CC != "" {662 rep.CC = strings.Split(bugReporting.CC, "|")663 }664 switch job.Type {665 case JobBisectCause:666 rep.BisectCause = bisectFromJob(c, rep, job)667 case JobBisectFix:668 rep.BisectFix = bisectFromJob(c, rep, job)669 }670 }671 // Build error output and failing VM boot log can be way too long to inline.672 if len(rep.Error) > maxInlineError {673 rep.Error = rep.Error[len(rep.Error)-maxInlineError:]674 rep.ErrorTruncated = true675 }676 if err := fillBugReport(c, rep, bug, bugReporting, build); err != nil {677 return nil, err678 }679 return rep, nil680}681func bisectFromJob(c context.Context, rep *dashapi.BugReport, job *Job) *dashapi.BisectResult {682 bisect := &dashapi.BisectResult{683 LogLink: externalLink(c, textLog, job.Log),684 CrashLogLink: externalLink(c, textCrashLog, job.CrashLog),685 CrashReportLink: externalLink(c, textCrashReport, job.CrashReport),686 Fix: job.Type == JobBisectFix,687 }688 for _, com := range job.Commits {689 bisect.Commits = append(bisect.Commits, &dashapi.Commit{690 Hash: com.Hash,...
jobs_test.go
Source:jobs_test.go
...14// nolint: funlen15func TestJob(t *testing.T) {16 c := NewCtx(t)17 defer c.Close()18 build := testBuild(1)19 c.client2.UploadBuild(build)20 patch := `--- a/mm/kasan/kasan.c21+++ b/mm/kasan/kasan.c22- current->kasan_depth++;23+ current->kasan_depth--;24`25 // Report crash without repro, check that test requests are not accepted.26 crash := testCrash(build, 1)27 crash.Maintainers = []string{"maintainer@kernel.org"}28 c.client2.ReportCrash(crash)29 sender := c.pollEmailBug().Sender30 c.incomingEmail(sender, "#syz upstream\n")31 sender = c.pollEmailBug().Sender32 _, extBugID, err := email.RemoveAddrContext(sender)33 c.expectOK(err)34 mailingList := config.Namespaces["test2"].Reporting[1].Config.(*EmailConfig).Email35 c.incomingEmail(sender, "bla-bla-bla", EmailOptFrom("maintainer@kernel.org"),36 EmailOptCC([]string{mailingList, "kernel@mailing.list"}))37 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch,38 EmailOptFrom("test@requester.com"), EmailOptCC([]string{mailingList}))39 body := c.pollEmailBug().Body40 c.expectEQ(strings.Contains(body, "This crash does not have a reproducer"), true)41 // Report crash with repro.42 crash.ReproOpts = []byte("repro opts")43 crash.ReproSyz = []byte("repro syz")44 crash.ReproC = []byte("repro C")45 c.client2.ReportCrash(crash)46 c.client2.pollAndFailBisectJob(build.Manager)47 body = c.pollEmailBug().Body48 c.expectEQ(strings.Contains(body, "syzbot has found a reproducer"), true)49 c.incomingEmail(sender, "#syz test: repo",50 EmailOptFrom("test@requester.com"), EmailOptCC([]string{mailingList}))51 body = c.pollEmailBug().Body52 c.expectEQ(strings.Contains(body, "want 2 args"), true)53 c.incomingEmail(sender, "#syz test: repo branch commit",54 EmailOptFrom("test@requester.com"), EmailOptCC([]string{mailingList}))55 body = c.pollEmailBug().Body56 c.expectEQ(strings.Contains(body, "want 2 args"), true)57 c.incomingEmail(sender, "#syz test: repo branch",58 EmailOptFrom("test@requester.com"), EmailOptCC([]string{mailingList}))59 body = c.pollEmailBug().Body60 c.expectEQ(strings.Contains(body, "does not look like a valid git repo"), true)61 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch,62 EmailOptFrom("\"foo\" <blOcKed@dOmain.COM>"))63 c.expectNoEmail()64 pollResp := c.client2.pollJobs(build.Manager)65 c.expectEQ(pollResp.ID, "")66 // This submits actual test request.67 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch,68 EmailOptMessageID(1), EmailOptFrom("test@requester.com"),69 EmailOptCC([]string{"somebody@else.com"}))70 c.expectNoEmail()71 // A dup of the same request with the same Message-ID.72 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch,73 EmailOptMessageID(1), EmailOptFrom("test@requester.com"),74 EmailOptCC([]string{"somebody@else.com"}))75 c.expectNoEmail()76 pollResp = c.client2.pollJobs("foobar")77 c.expectEQ(pollResp.ID, "")78 pollResp = c.client2.pollJobs(build.Manager)79 c.expectNE(pollResp.ID, "")80 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)81 c.expectEQ(pollResp.Manager, build.Manager)82 c.expectEQ(pollResp.KernelRepo, "git://git.git/git.git")83 c.expectEQ(pollResp.KernelBranch, "kernel-branch")84 c.expectEQ(pollResp.KernelConfig, build.KernelConfig)85 c.expectEQ(pollResp.SyzkallerCommit, build.SyzkallerCommit)86 c.expectEQ(pollResp.Patch, []byte(patch))87 c.expectEQ(pollResp.ReproOpts, []byte("repro opts"))88 c.expectEQ(pollResp.ReproSyz, []byte("repro syz"))89 c.expectEQ(pollResp.ReproC, []byte("repro C"))90 pollResp2 := c.client2.pollJobs(build.Manager)91 c.expectEQ(pollResp2, pollResp)92 jobDoneReq := &dashapi.JobDoneReq{93 ID: pollResp.ID,94 Build: *build,95 CrashTitle: "test crash title",96 CrashLog: []byte("test crash log"),97 CrashReport: []byte("test crash report"),98 }99 c.client2.JobDone(jobDoneReq)100 {101 dbJob, dbBuild, _ := c.loadJob(pollResp.ID)102 patchLink := externalLink(c.ctx, textPatch, dbJob.Patch)103 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)104 logLink := externalLink(c.ctx, textCrashLog, dbJob.CrashLog)105 msg := c.pollEmailBug()106 to := email.MergeEmailLists([]string{"test@requester.com", "somebody@else.com", mailingList})107 c.expectEQ(msg.To, to)108 c.expectEQ(msg.Subject, "Re: "+crash.Title)109 c.expectEQ(len(msg.Attachments), 0)110 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,111syzbot has tested the proposed patch but the reproducer still triggered crash:112test crash title113test crash report114Tested on:115commit: 11111111 kernel_commit_title1116git tree: repo1 branch1117console output: %[3]v118kernel config: %[2]v119dashboard link: https://testapp.appspot.com/bug?extid=%[4]v120compiler: compiler1121patch: %[1]v122`, patchLink, kernelConfigLink, logLink, extBugID))123 c.checkURLContents(patchLink, []byte(patch))124 c.checkURLContents(kernelConfigLink, build.KernelConfig)125 c.checkURLContents(logLink, jobDoneReq.CrashLog)126 }127 // Testing fails with an error.128 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(2))129 pollResp = c.client2.pollJobs(build.Manager)130 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)131 jobDoneReq = &dashapi.JobDoneReq{132 ID: pollResp.ID,133 Build: *build,134 Error: []byte("failed to apply patch"),135 }136 c.client2.JobDone(jobDoneReq)137 {138 dbJob, dbBuild, _ := c.loadJob(pollResp.ID)139 patchLink := externalLink(c.ctx, textPatch, dbJob.Patch)140 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)141 msg := c.pollEmailBug()142 c.expectEQ(len(msg.Attachments), 0)143 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,144syzbot tried to test the proposed patch but build/boot failed:145failed to apply patch146Tested on:147commit: 11111111 kernel_commit_title1148git tree: repo1 branch1149kernel config: %[2]v150dashboard link: https://testapp.appspot.com/bug?extid=%[3]v151compiler: compiler1152patch: %[1]v153`, patchLink, kernelConfigLink, extBugID))154 c.checkURLContents(patchLink, []byte(patch))155 c.checkURLContents(kernelConfigLink, build.KernelConfig)156 }157 // Testing fails with a huge error that can't be inlined in email.158 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(3))159 pollResp = c.client2.pollJobs(build.Manager)160 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)161 jobDoneReq = &dashapi.JobDoneReq{162 ID: pollResp.ID,163 Build: *build,164 Error: bytes.Repeat([]byte{'a', 'b', 'c'}, (maxInlineError+100)/3),165 }166 c.client2.JobDone(jobDoneReq)167 {168 dbJob, dbBuild, _ := c.loadJob(pollResp.ID)169 patchLink := externalLink(c.ctx, textPatch, dbJob.Patch)170 errorLink := externalLink(c.ctx, textError, dbJob.Error)171 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)172 msg := c.pollEmailBug()173 c.expectEQ(len(msg.Attachments), 0)174 truncatedError := string(jobDoneReq.Error[len(jobDoneReq.Error)-maxInlineError:])175 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,176syzbot tried to test the proposed patch but build/boot failed:177%[1]v178Error text is too large and was truncated, full error text is at:179%[2]v180Tested on:181commit: 11111111 kernel_commit_title1182git tree: repo1 branch1183kernel config: %[4]v184dashboard link: https://testapp.appspot.com/bug?extid=%[5]v185compiler: compiler1186patch: %[3]v187`, truncatedError, errorLink, patchLink, kernelConfigLink, extBugID))188 c.checkURLContents(patchLink, []byte(patch))189 c.checkURLContents(errorLink, jobDoneReq.Error)190 c.checkURLContents(kernelConfigLink, build.KernelConfig)191 }192 c.incomingEmail(sender, "#syz test: git://git.git/git.git kernel-branch\n"+patch, EmailOptMessageID(4))193 pollResp = c.client2.pollJobs(build.Manager)194 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)195 jobDoneReq = &dashapi.JobDoneReq{196 ID: pollResp.ID,197 Build: *build,198 }199 c.client2.JobDone(jobDoneReq)200 {201 dbJob, dbBuild, _ := c.loadJob(pollResp.ID)202 patchLink := externalLink(c.ctx, textPatch, dbJob.Patch)203 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)204 msg := c.pollEmailBug()205 c.expectEQ(len(msg.Attachments), 0)206 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,207syzbot has tested the proposed patch and the reproducer did not trigger crash:208Reported-and-tested-by: syzbot+%v@testapp.appspotmail.com209Tested on:210commit: 11111111 kernel_commit_title1211git tree: repo1 branch1212kernel config: %[3]v213dashboard link: https://testapp.appspot.com/bug?extid=%[1]v214compiler: compiler1215patch: %[2]v216Note: testing is done by a robot and is best-effort only.217`, extBugID, patchLink, kernelConfigLink))218 c.checkURLContents(patchLink, []byte(patch))219 c.checkURLContents(kernelConfigLink, build.KernelConfig)220 }221 pollResp = c.client2.pollJobs(build.Manager)222 c.expectEQ(pollResp.ID, "")223}224// Test on particular commit and without a patch.225func TestJobWithoutPatch(t *testing.T) {226 c := NewCtx(t)227 defer c.Close()228 build := testBuild(1)229 c.client2.UploadBuild(build)230 crash := testCrash(build, 1)231 crash.ReproOpts = []byte("repro opts")232 crash.ReproSyz = []byte("repro syz")233 c.client2.ReportCrash(crash)234 c.client2.pollAndFailBisectJob(build.Manager)235 sender := c.pollEmailBug().Sender236 _, extBugID, err := email.RemoveAddrContext(sender)237 c.expectOK(err)238 // Patch testing should happen for bugs with fix commits too.239 c.incomingEmail(sender, "#syz fix: some commit title\n")240 c.incomingEmail(sender, "#syz test git://mygit.com/git.git 5e6a2eea\n", EmailOptMessageID(1))241 c.expectNoEmail()242 pollResp := c.client2.pollJobs(build.Manager)243 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)244 testBuild := testBuild(2)245 testBuild.KernelRepo = "git://mygit.com/git.git"246 testBuild.KernelBranch = ""247 testBuild.KernelCommit = "5e6a2eea5e6a2eea5e6a2eea5e6a2eea5e6a2eea"248 jobDoneReq := &dashapi.JobDoneReq{249 ID: pollResp.ID,250 Build: *testBuild,251 }252 c.client2.JobDone(jobDoneReq)253 {254 _, dbBuild, _ := c.loadJob(pollResp.ID)255 kernelConfigLink := externalLink(c.ctx, textKernelConfig, dbBuild.KernelConfig)256 msg := c.pollEmailBug()257 c.expectEQ(len(msg.Attachments), 0)258 c.expectEQ(msg.Body, fmt.Sprintf(`Hello,259syzbot has tested the proposed patch and the reproducer did not trigger crash:260Reported-and-tested-by: syzbot+%v@testapp.appspotmail.com261Tested on:262commit: 5e6a2eea kernel_commit_title2263git tree: git://mygit.com/git.git264kernel config: %[2]v265dashboard link: https://testapp.appspot.com/bug?extid=%[1]v266compiler: compiler2267Note: testing is done by a robot and is best-effort only.268`, extBugID, kernelConfigLink))269 c.checkURLContents(kernelConfigLink, testBuild.KernelConfig)270 }271 pollResp = c.client2.pollJobs(build.Manager)272 c.expectEQ(pollResp.ID, "")273}274// Test on a restricted manager.275func TestJobRestrictedManager(t *testing.T) {276 c := NewCtx(t)277 defer c.Close()278 build := testBuild(1)279 build.Manager = "restricted-manager"280 c.client2.UploadBuild(build)281 crash := testCrash(build, 1)282 crash.ReproSyz = []byte("repro syz")283 c.client2.ReportCrash(crash)284 c.client2.pollAndFailBisectJob(build.Manager)285 sender := c.pollEmailBug().Sender286 // Testing on a wrong repo must fail and no test jobs passed to manager.287 c.incomingEmail(sender, "#syz test: git://mygit.com/git.git master\n", EmailOptMessageID(1))288 c.expectEQ(strings.Contains((<-c.emailSink).Body, "you should test only on restricted.git"), true)289 pollResp := c.client2.pollJobs(build.Manager)290 c.expectEQ(pollResp.ID, "")291 // Testing on the right repo must succeed.292 c.incomingEmail(sender, "#syz test: git://restricted.git/restricted.git master\n", EmailOptMessageID(2))293 pollResp = c.client2.pollJobs(build.Manager)294 c.expectNE(pollResp.ID, "")295 c.expectEQ(pollResp.Type, dashapi.JobTestPatch)296 c.expectEQ(pollResp.Manager, build.Manager)297 c.expectEQ(pollResp.KernelRepo, "git://restricted.git/restricted.git")298}299// Test that JobBisectFix is returned only after 30 days.300func TestBisectFixJob(t *testing.T) {301 c := NewCtx(t)302 defer c.Close()303 // Upload a crash report304 build := testBuild(1)305 c.client2.UploadBuild(build)306 crash := testCrashWithRepro(build, 1)307 c.client2.ReportCrash(crash)308 c.client2.pollEmailBug()309 // Receive the JobBisectCause310 resp := c.client2.pollJobs(build.Manager)311 c.client2.expectNE(resp.ID, "")312 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)313 done := &dashapi.JobDoneReq{314 ID: resp.ID,315 Error: []byte("testBisectFixJob:JobBisectCause"),316 }317 c.client2.expectOK(c.client2.JobDone(done))318 // Ensure no more jobs319 resp = c.client2.pollJobs(build.Manager)320 c.client2.expectEQ(resp.ID, "")321 // Advance time by 30 days and read out any notification emails322 {323 c.advanceTime(30 * 24 * time.Hour)324 msg := c.client2.pollEmailBug()325 c.expectEQ(msg.Subject, "title1")326 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))327 msg = c.client2.pollEmailBug()328 c.expectEQ(msg.Subject, "title1")329 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))330 }331 // Ensure that we get a JobBisectFix332 resp = c.client2.pollJobs(build.Manager)333 c.client2.expectNE(resp.ID, "")334 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)335 done = &dashapi.JobDoneReq{336 ID: resp.ID,337 Error: []byte("testBisectFixJob:JobBisectFix"),338 }339 c.client2.expectOK(c.client2.JobDone(done))340}341// Test that JobBisectFix jobs are re-tried if crash occurs on ToT.342func TestBisectFixRetry(t *testing.T) {343 c := NewCtx(t)344 defer c.Close()345 // Upload a crash report346 build := testBuild(1)347 c.client2.UploadBuild(build)348 crash := testCrashWithRepro(build, 1)349 c.client2.ReportCrash(crash)350 c.client2.pollEmailBug()351 // Receive the JobBisectCause352 resp := c.client2.pollJobs(build.Manager)353 c.client2.expectNE(resp.ID, "")354 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)355 done := &dashapi.JobDoneReq{356 ID: resp.ID,357 Error: []byte("testBisectFixRetry:JobBisectCause"),358 }359 c.client2.expectOK(c.client2.JobDone(done))360 // Advance time by 30 days and read out any notification emails361 {362 c.advanceTime(30 * 24 * time.Hour)363 msg := c.client2.pollEmailBug()364 c.expectEQ(msg.Subject, "title1")365 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))366 msg = c.client2.pollEmailBug()367 c.expectEQ(msg.Subject, "title1")368 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))369 }370 // Ensure that we get a JobBisectFix. We send back a crashlog, no error, no commits371 resp = c.client2.pollJobs(build.Manager)372 c.client2.expectNE(resp.ID, "")373 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)374 done = &dashapi.JobDoneReq{375 Build: dashapi.Build{376 ID: "build1",377 },378 ID: resp.ID,379 CrashLog: []byte("this is a crashlog"),380 CrashReport: []byte("this is a crashreport"),381 }382 c.client2.expectOK(c.client2.JobDone(done))383 // Advance time by 30 days. No notification emails384 {385 c.advanceTime(30 * 24 * time.Hour)386 }387 // Ensure that we get a JobBisectFix retry388 resp = c.client2.pollJobs(build.Manager)389 c.client2.expectNE(resp.ID, "")390 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)391 done = &dashapi.JobDoneReq{392 ID: resp.ID,393 Error: []byte("testBisectFixRetry:JobBisectFix"),394 }395 c.client2.expectOK(c.client2.JobDone(done))396}397// Test that bisection results are not reported for bugs that are already marked as fixed.398func TestNotReportingAlreadyFixed(t *testing.T) {399 c := NewCtx(t)400 defer c.Close()401 // Upload a crash report.402 build := testBuild(1)403 c.client2.UploadBuild(build)404 crash := testCrashWithRepro(build, 1)405 c.client2.ReportCrash(crash)406 c.client2.pollEmailBug()407 // Receive the JobBisectCause.408 resp := c.client2.pollJobs(build.Manager)409 c.client2.expectNE(resp.ID, "")410 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)411 done := &dashapi.JobDoneReq{412 ID: resp.ID,413 Error: []byte("testBisectFixRetry:JobBisectCause"),414 }415 c.client2.expectOK(c.client2.JobDone(done))416 sender := ""417 // Advance time by 30 days and read out any notification emails.418 {419 c.advanceTime(30 * 24 * time.Hour)420 msg := c.client2.pollEmailBug()421 c.expectEQ(msg.Subject, "title1")422 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))423 msg = c.client2.pollEmailBug()424 c.expectEQ(msg.Subject, "title1")425 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))426 sender = msg.Sender427 }428 // Poll for a BisectFix job.429 resp = c.client2.pollJobs(build.Manager)430 c.client2.expectNE(resp.ID, "")431 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)432 // Meanwhile, the bug is marked as fixed separately.433 c.incomingEmail(sender, "#syz fix: kernel: add a fix", EmailOptCC(nil))434 {435 // Email notification of "Your 'fix:' command is accepted, but please keep436 // bugs@syzkaller.com mailing list in CC next time."437 c.client2.pollEmailBug()438 }439 // At this point, send back the results for the BisectFix job also.440 done = &dashapi.JobDoneReq{441 ID: resp.ID,442 Build: *build,443 Log: []byte("bisectfix log 4"),444 CrashTitle: "bisectfix crash title 4",445 CrashLog: []byte("bisectfix crash log 4"),446 CrashReport: []byte("bisectfix crash report 4"),447 Commits: []dashapi.Commit{448 {449 Hash: "46e65cb4a0448942ec316b24d60446bbd5cc7827",450 Title: "kernel: add a fix",451 Author: "author@kernel.org",452 AuthorName: "Author Kernelov",453 CC: []string{454 "reviewer1@kernel.org", "\"Reviewer2\" <reviewer2@kernel.org>",455 // These must be filtered out:456 "syzbot@testapp.appspotmail.com",457 "syzbot+1234@testapp.appspotmail.com",458 "\"syzbot\" <syzbot+1234@testapp.appspotmail.com>",459 },460 Date: time.Date(2000, 2, 9, 4, 5, 6, 7, time.UTC),461 },462 },463 }464 c.expectOK(c.client2.JobDone(done))465 // No reporting should come in at this point. If there is reporting, c.Close()466 // will fail.467}468// Test that fix bisections are listed on the bug page if the bug.BisectFix469// is not BisectYes.470func TestFixBisectionsListed(t *testing.T) {471 c := NewCtx(t)472 defer c.Close()473 // Upload a crash report474 build := testBuild(1)475 c.client2.UploadBuild(build)476 crash := testCrashWithRepro(build, 1)477 c.client2.ReportCrash(crash)478 c.client2.pollEmailBug()479 // Receive the JobBisectCause.480 resp := c.client2.pollJobs(build.Manager)481 c.client2.expectNE(resp.ID, "")482 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)483 done := &dashapi.JobDoneReq{484 ID: resp.ID,485 Error: []byte("testBisectFixRetry:JobBisectCause"),486 }487 c.client2.expectOK(c.client2.JobDone(done))488 // At this point, no fix bisections should be listed out.489 var bugs []*Bug490 keys, err := db.NewQuery("Bug").GetAll(c.ctx, &bugs)491 c.expectEQ(err, nil)492 c.expectEQ(len(bugs), 1)493 url := fmt.Sprintf("/bug?id=%v", keys[0].StringID())494 content, err := c.httpRequest("GET", url, "", AccessAdmin)495 c.expectEQ(err, nil)496 c.expectTrue(!bytes.Contains(content, []byte("All fix bisections")))497 // Advance time by 30 days and read out any notification emails.498 {499 c.advanceTime(30 * 24 * time.Hour)500 msg := c.client2.pollEmailBug()501 c.expectEQ(msg.Subject, "title1")502 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))503 msg = c.client2.pollEmailBug()504 c.expectEQ(msg.Subject, "title1")505 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))506 }507 // Ensure that we get a JobBisectFix. We send back a crashlog, no error,508 // no commits.509 resp = c.client2.pollJobs(build.Manager)510 c.client2.expectNE(resp.ID, "")511 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)512 done = &dashapi.JobDoneReq{513 Build: dashapi.Build{514 ID: "build1",515 },516 ID: resp.ID,517 CrashTitle: "this is a crashtitle",518 CrashLog: []byte("this is a crashlog"),519 CrashReport: []byte("this is a crashreport"),520 Log: []byte("this is a log"),521 }522 c.client2.expectOK(c.client2.JobDone(done))523 // Check the bug page and ensure that a bisection is listed out.524 content, err = c.httpRequest("GET", url, "", AccessAdmin)525 c.expectEQ(err, nil)526 c.expectTrue(bytes.Contains(content, []byte("Fix bisection attempts")))527 // Advance time by 30 days. No notification emails.528 {529 c.advanceTime(30 * 24 * time.Hour)530 }531 // Ensure that we get a JobBisectFix retry.532 resp = c.client2.pollJobs(build.Manager)533 c.client2.expectNE(resp.ID, "")534 c.client2.expectEQ(resp.Type, dashapi.JobBisectFix)535 done = &dashapi.JobDoneReq{536 ID: resp.ID,537 Error: []byte("testBisectFixRetry:JobBisectFix"),538 }539 c.client2.expectOK(c.client2.JobDone(done))540 // Check the bug page and ensure that no bisections are listed out.541 content, err = c.httpRequest("GET", url, "", AccessAdmin)542 c.expectEQ(err, nil)543 c.expectTrue(!bytes.Contains(content, []byte("All fix bisections")))544}545// Test that fix bisections do not occur if Repo has NoFixBisections set.546func TestFixBisectionsDisabled(t *testing.T) {547 c := NewCtx(t)548 defer c.Close()549 // Upload a crash report550 build := testBuild(1)551 build.Manager = "no-fix-bisection-manager"552 c.client2.UploadBuild(build)553 crash := testCrashWithRepro(build, 20)554 c.client2.ReportCrash(crash)555 c.client2.pollEmailBug()556 // Receive the JobBisectCause.557 resp := c.client2.pollJobs(build.Manager)558 c.client2.expectNE(resp.ID, "")559 c.client2.expectEQ(resp.Type, dashapi.JobBisectCause)560 done := &dashapi.JobDoneReq{561 ID: resp.ID,562 Error: []byte("testBisectFixRetry:JobBisectCause"),563 }564 c.client2.expectOK(c.client2.JobDone(done))565 // Advance time by 30 days and read out any notification emails.566 {567 c.advanceTime(30 * 24 * time.Hour)568 msg := c.client2.pollEmailBug()569 c.expectEQ(msg.Subject, "title20")570 c.expectTrue(strings.Contains(msg.Body, "Sending this report upstream."))571 msg = c.client2.pollEmailBug()572 c.expectEQ(msg.Subject, "title20")573 c.expectTrue(strings.Contains(msg.Body, "syzbot found the following crash"))574 }575 // Ensure that we do not get a JobBisectFix.576 resp = c.client2.pollJobs(build.Manager)577 c.client2.expectEQ(resp.ID, "")578}...
build
Using AI Code Generation
1import (2type Bisect struct {3}4func (b Bisect) Build(a, b, c float64) {5}6func (b Bisect) Solve() float64 {7 return (-b.b + math.Sqrt(b.b*b.b-4*b.a*b.c)) / (2 * b.a)8}9func main() {10 a.Build(1, 2, 1)11 fmt.Println(a.Solve())12}13import (14type Bisect struct {15}16func (b *Bisect) Build(a, b, c float64) {17}18func (b Bisect) Solve() float64 {19 return (-b.b + math.Sqrt(b.b*b.b-4*b.a*b.c)) / (2 * b.a)20}21func main() {22 a.Build(1, 2, 1)23 fmt.Println(a.Solve())24}
build
Using AI Code Generation
1import java.util.Scanner;2public class Main{3 public static void main(String[] args){4 Scanner sc = new Scanner(System.in);5 int n = sc.nextInt();6 int[] arr = new int[n];7 for(int i=0;i<n;i++)8 arr[i] = sc.nextInt();9 Bisect b = new Bisect();10 b.build(arr);11 int q = sc.nextInt();12 while(q-->0){13 int x = sc.nextInt();14 int y = sc.nextInt();15 System.out.println(b.query(x,y));16 }17 }18}19import java.util.Scanner;20public class Main{21 public static void main(String[] args){22 Scanner sc = new Scanner(System.in);23 int n = sc.nextInt();24 int[] arr = new int[n];25 for(int i=0;i<n;i++)26 arr[i] = sc.nextInt();27 SegmentTree st = new SegmentTree();28 st.build(arr);29 int q = sc.nextInt();30 while(q-->0){31 int x = sc.nextInt();32 int y = sc.nextInt();33 System.out.println(st.query(x,y));34 }35 }36}37import java.util.Scanner;38public class Main{39 public static void main(String[] args){40 Scanner sc = new Scanner(System.in);41 int n = sc.nextInt();42 int[] arr = new int[n];43 for(int i=0;i<n;i++)44 arr[i] = sc.nextInt();45 SegmentTree st = new SegmentTree();46 st.build(arr);47 int q = sc.nextInt();48 while(q-->0){49 int x = sc.nextInt();50 int y = sc.nextInt();51 System.out.println(st.query(x,y));52 }53 }54}55import java.util.Scanner;56public class Main{57 public static void main(String[] args){58 Scanner sc = new Scanner(System.in);59 int n = sc.nextInt();60 int[] arr = new int[n];61 for(int i=0;i<n;i++)62 arr[i] = sc.nextInt();63 SegmentTree st = new SegmentTree();64 st.build(arr);65 int q = sc.nextInt();66 while(q-->0){
build
Using AI Code Generation
1import java.util.Scanner;2{3 public static void main(String[] args) 4 {5 Scanner sc=new Scanner(System.in);6 System.out.println("Enter the number of elements");7 int n=sc.nextInt();8 System.out.println("Enter the elements");9 int[] a=new int[n];10 for(int i=0;i<n;i++)11 a[i]=sc.nextInt();12 Bisect b=new Bisect();13 b.build(a,n);14 }15}
build
Using AI Code Generation
1import (2func f(x float64) float64 {3}4func f1(x float64) float64 {5}6func f2(x float64) float64 {7}8func f3(x float64) float64 {9}10func f4(x float64) float64 {11}12func main() {13 fmt.Println("Enter the value of a")14 _, err = fmt.Scanf("%f", &a)15 fmt.Println("Enter the value of b")16 _, err = fmt.Scanf("%f", &b)17 fmt.Println("Enter the value of tolerance")18 _, err = fmt.Scanf("%f", &c)19 d, e, n = Bisection(a, b, c, f, f1, f2, f3, f4)20 fmt.Println("The root of the equation is", d)21 fmt.Println("The value of the function at the root is", e)22 fmt.Println("The number of iterations required to find the root is", n)23 fmt.Println("Enter the value of a")24 _, err = fmt.Scanf("%f", &a)25 fmt.Println("Enter the value of b")26 _, err = fmt.Scanf("%f", &b)27 fmt.Println("Enter the value of tolerance")28 _, err = fmt.Scanf("%f", &c)29 f, g, n = Bisection(a, b, c, f, f1, f2,
build
Using AI Code Generation
1import java.util.*;2import java.io.*;3{4 static int a[] = new int[100];5 static int n;6 static int x;7 static int p;8 static int q;9 static int r;10 static int s;11 static int t;12 static int u;13 static int v;14 static int w;15 static int i;16 static int j;17 static int k;18 static int l;19 static int m;20 static int y;21 static int z;22 static int b;23 static int c;24 static int d;25 static int e;26 static int f;27 static int g;28 static int h;29 static int bisect(int a[],int n,int x)30 {31 p=0;32 q=n-1;33 while(p<=q)34 {35 r=(p+q)/2;36 if(a[r]==x)37 return r;38 else if(a[r]<x)39 p=r+1;40 q=r-1;41 }42 return -1;43 }44 public static void main(String args[])45 {46 Scanner sc = new Scanner(System.in);47 System.out.println("Enter number of elements in array");48 n=sc.nextInt();49 System.out.println("Enter elements of array");50 for(i=0;i<n;i++)51 a[i]=sc.nextInt();52 System.out.println("Enter element to be searched");53 x=sc.nextInt();54 y=bisect(a,n,x);55 if(y==-1)56 System.out.println("Element not found");57 System.out.println("Element found at index " + y);58 }59}
build
Using AI Code Generation
1using namespace std;2double f(double x)3{4 return (x*x*x) - (x*x) - 1;5}6int main()7{8 Bisect b;9 double a = 1, b = 2, tol = 0.000001, root;10 root = b.build(f, a, b, tol);11 cout << "The root of the function f(x) = x^3 - x^2 - 1 is: " << root << endl;12 return 0;13}
build
Using AI Code Generation
1using namespace std;2const double EPS = 1e-6;3const double PI = 3.1415926535897932384626433832795;4int main()5{6 return 0;7}
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!