Best Syzkaller code snippet using main.pollJobs
bisect_test.go
Source:bisect_test.go
...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",...
jobs_test.go
Source:jobs_test.go
...60 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}...
pollJobs
Using AI Code Generation
1import (2func main() {3 jobs := make(chan int, 100)4 results := make(chan int, 100)5 go worker(jobs, results)6 go worker(jobs, results)7 go worker(jobs, results)8 go worker(jobs, results)9 for i := 0; i < 100; i++ {10 }11 close(jobs)12 for j := 0; j < 100; j++ {13 }14}15func worker(jobs <-chan int, results chan<- int) {16 for n := range jobs {17 time.Sleep(time.Millisecond * 1)18 }19 fmt.Println("Worker is done")20}21import (22func main() {23 jobs := make(chan int, 100)24 results := make(chan int, 100)25 go worker(jobs, results)26 go worker(jobs, results)27 go worker(jobs, results)28 go worker(jobs, results)29 for i := 0; i < 100; i++ {30 }31 close(jobs)32 for j := 0; j < 100; j++ {33 }34}35func worker(jobs <-chan int, results chan<- int) {36 for n := range jobs {37 time.Sleep(time.Millisecond * 1)38 }39 fmt.Println("Worker is done")40}41import (42func main() {43 jobs := make(chan int, 100)44 results := make(chan int, 100)45 go worker(jobs, results)46 go worker(jobs, results)47 go worker(jobs, results)48 go worker(jobs, results)49 for i := 0; i < 100; i++ {50 }51 close(jobs)52 for j := 0; j < 100; j++ {53 }54}55func worker(jobs <-chan int, results chan<- int) {56 for n := range jobs {57 time.Sleep(time.Millisecond * 1)
pollJobs
Using AI Code Generation
1import (2func main() {3 config := cluster.NewConfig()4 brokers := []string{"localhost:9092"}5 topics := []string{"example"}6 consumer, err := cluster.NewConsumer(brokers, "my-group", topics, config)7 if err != nil {8 panic(err)9 }10 defer consumer.Close()11 go func() {12 for err := range consumer.Errors() {13 fmt.Println(err)14 }15 }()16 go func() {17 for ntf := range consumer.Notifications() {18 fmt.Println(ntf)19 }20 }()21 for {22 select {23 case msg, ok := <-consumer.Messages():24 if ok {25 fmt.Printf("Message on %s: %s26", msg.Topic, string(msg.Value))27 }28 case <-time.After(60 * time.Second):29 fmt.Println("Timeout")30 }31 }32}
pollJobs
Using AI Code Generation
1import (2func main() {3 fmt.Println("Hello, playground")4 var mainClass = new(bookshelf.Main)5 mainClass.PollJobs()6}7./2.go:15: cannot use new(bookshelf.Main) (type *bookshelf.Main) as type bookshelf.Main in assignment
pollJobs
Using AI Code Generation
1func main() {2 client, err := pubsub.NewClient(context.Background(), "my-project")3 if err != nil {4 log.Fatal(err)5 }6 sub := client.Subscription("my-subscription")7 it, err := sub.Pull(context.Background())8 if err != nil {9 log.Fatal(err)10 }11 defer it.Stop()12 for {13 msg, err := it.Next()14 if err == iterator.Done {15 }16 if err != nil {17 log.Fatal(err)18 }19 fmt.Println(msg)20 msg.Done(true)21 }22}23func main() {24 client, err := pubsub.NewClient(context.Background(), "my-project")25 if err != nil {26 log.Fatal(err)27 }28 topic := client.Topic("my-topic")29 ok, err := topic.Exists(context.Background())30 if err != nil {31 log.Fatal(err)32 }33 if !ok {34 topic, err = client.CreateTopic(context.Background(), "my-topic")35 if err != nil {36 log.Fatal(err)37 }38 }39 res := topic.Publish(context.Background(), &pubsub.Message{40 Data: []byte("Hello World"),41 })42 id, err := res.Get(context.Background())43 if err != nil {44 log.Fatal(err)45 }46 fmt.Println(id)47}48func main() {49 client, err := pubsub.NewClient(context.Background(), "my-project")50 if err != nil {51 log.Fatal(err)52 }53 topic := client.Topic("my-topic")54 ok, err := topic.Exists(context.Background())55 if err != nil {56 log.Fatal(err)57 }58 if !ok {59 topic, err = client.CreateTopic(context.Background(), "my-topic")60 if err != nil {61 log.Fatal(err)62 }63 }64 sub := client.Subscription("my-subscription")65 ok, err = sub.Exists(context.Background())66 if err != nil {67 log.Fatal(err)68 }
pollJobs
Using AI Code Generation
1import (2func main() {3 m := new(main)4 c := make(chan int)5 go m.pollJobs(c)6 for {7 select {8 fmt.Println("Received on channel")9 case <-time.After(time.Second):10 fmt.Println("Waiting for value on channel")11 }12 }13}14import (15func main() {16 m := new(main)17 c := make(chan int)18 go m.pollJobs(c)19 for {20 select {21 fmt.Println("Received on channel")22 case <-time.After(time.Second):23 fmt.Println("Waiting for value on channel")24 }25 }26}27import (28func main() {29 m := new(main)30 c := make(chan int)31 go m.pollJobs(c)32 for {33 select {34 fmt.Println("Received on channel")35 case <-time.After(time.Second):36 fmt.Println("Waiting for value on channel")37 }38 }39}40import (41func main() {42 m := new(main)43 c := make(chan int)
pollJobs
Using AI Code Generation
1import "fmt"2func main() {3 fmt.Println("Hello, world.")4 pollJobs()5}6import "fmt"7func main() {8 fmt.Println("Hello, world.")9 pollJobs()10}11import "fmt"12func main() {13 fmt.Println("Hello, world.")14 pollJobs()15}16import "fmt"17func main() {18 fmt.Println("Hello, world.")19 pollJobs()20}21import "fmt"22func main() {23 fmt.Println("Hello, world.")24 pollJobs()25}26import "fmt"27func main() {28 fmt.Println("Hello, world.")29 pollJobs()30}31import "fmt"32func main() {33 fmt.Println("Hello, world.")34 pollJobs()35}36import "fmt"37func main() {38 fmt.Println("Hello, world.")39 pollJobs()40}41import "fmt"42func main() {43 fmt.Println("Hello, world.")44 pollJobs()45}46import "fmt"47func main() {48 fmt.Println("Hello, world.")49 pollJobs()50}
pollJobs
Using AI Code Generation
1import "fmt"2import "time"3func main() {4 fmt.Println("Starting the application...")5 for {6 time.Sleep(5 * time.Minute)7 fmt.Println("Polling jobs...")8 }9}
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!!