diff options
| author | Aleksandr Nogikh <nogikh@google.com> | 2023-08-24 15:19:24 +0200 |
|---|---|---|
| committer | Aleksandr Nogikh <nogikh@google.com> | 2023-08-24 14:19:23 +0000 |
| commit | f07d6eca461624040274bd37fbe312be276c3d12 (patch) | |
| tree | f8d546481fe972f7f31456b4632a3514341deec2 /pkg/bisect | |
| parent | 4d7ae7ab1c3ef41cc0e71fb19799dcec94213101 (diff) | |
pkg/bisect: test merge base for cross-tree bisections
Consider the following situation: we're fix bisecting an lts bug on the
mainline tree. Reproducer works on lts HEAD, but does not crash the
mainline.
If the bug was not introduced in the mainline, but it's a purely lts
bug, bisection would currently end up pointing to the mainline HEAD
(in #4123, we assume env.commit to be a commit on the tree we're
currently bisecting, otherwise we'd always hit the same merge base
commit).
Let's first determine 100% correct bisection range on the mainline tree
by testing that both the HEAD does not crash (we already do) and by
testing that the new starting commit (=merge base) can be crashed by the
reproducer.
Diffstat (limited to 'pkg/bisect')
| -rw-r--r-- | pkg/bisect/bisect.go | 29 | ||||
| -rw-r--r-- | pkg/bisect/bisect_test.go | 25 |
2 files changed, 50 insertions, 4 deletions
diff --git a/pkg/bisect/bisect.go b/pkg/bisect/bisect.go index fbb8d031c..9ea5a6c04 100644 --- a/pkg/bisect/bisect.go +++ b/pkg/bisect/bisect.go @@ -209,10 +209,11 @@ func runImpl(cfg *Config, repo vcs.Repo, inst instance.Env) (*Result, error) { } if len(res.Commits) == 0 { if cfg.Fix { - env.log("crash still not fixed on HEAD or HEAD had kernel test errors") + env.log("crash still not fixed or there were kernel test errors") } else { env.log("oldest tested release already had the bug or it had kernel test errors") } + env.log("commit msg: %v", res.Commit.Title) if res.Report != nil { env.log("crash: %v\n%s", res.Report.Title, res.Report.Report) @@ -466,6 +467,7 @@ func (env *env) commitRange() (*vcs.Commit, *vcs.Commit, []*testResult, *Result, } func (env *env) commitRangeForFix() (*vcs.Commit, *vcs.Commit, []*testResult, error) { + var results []*testResult startCommit := env.commit if env.cfg.CrossTree { env.log("determining the merge base between %v and %v", @@ -478,8 +480,19 @@ func (env *env) commitRangeForFix() (*vcs.Commit, *vcs.Commit, []*testResult, er env.log("expected 1 merge base, got %d", len(bases)) return nil, nil, nil, fmt.Errorf("expected 1 merge base, got %d", len(bases)) } - env.log("%s/%s is a merge base", bases[0].Hash, bases[0].Title) + env.log("%s/%s is a merge base, check if it has the bug", bases[0].Hash, bases[0].Title) startCommit = bases[0] + if _, err := env.repo.SwitchCommit(startCommit.Hash); err != nil { + return nil, nil, nil, err + } + res, err := env.test() + if err != nil { + return nil, nil, nil, err + } + results = append(results, res) + if res.verdict != vcs.BisectBad { + return nil, startCommit, results, nil + } } env.log("testing current HEAD %v", env.head.Hash) if _, err := env.repo.SwitchCommit(env.head.Hash); err != nil { @@ -489,10 +502,11 @@ func (env *env) commitRangeForFix() (*vcs.Commit, *vcs.Commit, []*testResult, er if err != nil { return nil, nil, nil, err } + results = append(results, res) if res.verdict != vcs.BisectGood { - return env.head, nil, []*testResult{res}, nil + return env.head, nil, results, nil } - return env.head, startCommit, []*testResult{res}, nil + return env.head, startCommit, results, nil } func (env *env) commitRangeForCause() (*vcs.Commit, *vcs.Commit, []*testResult, error) { @@ -533,6 +547,13 @@ func (env *env) validateCommitRange(bad, good *vcs.Commit, results []*testResult return nil, fmt.Errorf("commitRange returned no results") } + if env.cfg.Fix && env.cfg.CrossTree && len(results) < 2 { + // For cross-tree bisections, it can be the case that the bug was introduced + // after the merge base, so there's no sense to continue the fix bisection. + env.log("reproducer does not crash the merge base, so there's no known bad commit") + return &Result{Commit: good, Config: env.kernelConfig}, nil + } + finalResult := results[len(results)-1] // HEAD test for fix, oldest tested test for cause bisection if finalResult.verdict == vcs.BisectBad { // For cause bisection: Oldest tested release already had the bug. Giving up. diff --git a/pkg/bisect/bisect_test.go b/pkg/bisect/bisect_test.go index 95849e419..600a68b60 100644 --- a/pkg/bisect/bisect_test.go +++ b/pkg/bisect/bisect_test.go @@ -673,6 +673,31 @@ var bisectionTests = []BisectionTest{ introduced: "602", noFakeHashTest: true, }, + { + // There's no fix for the bug because it was introduced + // in another tree. + name: "no-fix-cross-tree", + fix: true, + startCommit: 852, + startCommitBranch: "v8-branch", + commitLen: 0, + crossTree: true, + introduced: "851", + oldestLatest: 800, + }, + { + // We are unable to test the merge base commit. + name: "fix-cross-tree-broken-start", + fix: true, + startCommit: 851, + startCommitBranch: "v8-branch", + commitLen: 0, + crossTree: true, + fixCommit: "903", + brokenStart: 800, + brokenEnd: 800, + oldestLatest: 800, + }, } func TestBisectionResults(t *testing.T) { |
