diff options
| author | Zubin Mithra <zsm@chromium.org> | 2019-10-08 15:57:52 -0700 |
|---|---|---|
| committer | Dmitry Vyukov <dvyukov@google.com> | 2019-10-22 10:09:57 +0200 |
| commit | a2bdbd8c37841cc507a2ad59f25d90d6467e5858 (patch) | |
| tree | bc4ad0e738a749c2321b7181e4ea04c5615738e7 /pkg/vcs | |
| parent | 37dc03de04826cc0d5d1e3699832b0a3113d40af (diff) | |
pkg/bisect: add initial testing support for cause bisection
(note: incomplete change)
Refactor existing code as follows:
* Move reusable test utility functions from git_repo_test.go to
pkg/vcs/test_util.go and make them exported.
* Split Run() into Run()+runImpl().
* Change type of bisect.go:env.inst to `instance.BuilderTester`.
Change usage inside syz-testbuild/testbuild.go accordingly.
* Move most of linux.PreviousReleaseTags() into vcs/git.go as
git.previousReleaseTags().
* Allow build.CompilerIdentity to be mocked.
Introduce the following changes:
* instance.BuilderTester is an interface with methods
BuildSyzkaller()
BuildKernel()
Test()
NewEnv() now returns this interface.
* type testEnv implements instance.BuilderTester.
* type testBuilder implements builder interface. Add a entry into table
inside pkg/build/build.go:getBuilder() to return testBuilder object.
Diffstat (limited to 'pkg/vcs')
| -rw-r--r-- | pkg/vcs/git.go | 24 | ||||
| -rw-r--r-- | pkg/vcs/git_repo_test.go | 125 | ||||
| -rw-r--r-- | pkg/vcs/linux.go | 22 | ||||
| -rw-r--r-- | pkg/vcs/test_util.go | 116 | ||||
| -rw-r--r-- | pkg/vcs/testos.go | 23 | ||||
| -rw-r--r-- | pkg/vcs/vcs.go | 2 |
6 files changed, 186 insertions, 126 deletions
diff --git a/pkg/vcs/git.go b/pkg/vcs/git.go index 7b0a621b6..359c3d68e 100644 --- a/pkg/vcs/git.go +++ b/pkg/vcs/git.go @@ -450,3 +450,27 @@ func (git *git) bisectInconclusive(output []byte) ([]*Commit, error) { } return commits, nil } + +func (git *git) previousReleaseTags(commit string, self bool) ([]string, error) { + var tags []string + if self { + output, err := git.git("tag", "--list", "--points-at", commit, "--merged", commit, "v*.*") + if err != nil { + return nil, err + } + tags, err = gitParseReleaseTags(output) + if err != nil { + return nil, err + } + } + output, err := git.git("tag", "--no-contains", commit, "--merged", commit, "v*.*") + if err != nil { + return nil, err + } + tags1, err := gitParseReleaseTags(output) + if err != nil { + return nil, err + } + tags = append(tags, tags1...) + return tags, nil +} diff --git a/pkg/vcs/git_repo_test.go b/pkg/vcs/git_repo_test.go index 017aaa658..227834b71 100644 --- a/pkg/vcs/git_repo_test.go +++ b/pkg/vcs/git_repo_test.go @@ -10,10 +10,8 @@ import ( "path/filepath" "sort" "testing" - "time" "github.com/google/go-cmp/cmp" - "github.com/google/syzkaller/pkg/osutil" ) func init() { @@ -21,12 +19,6 @@ func init() { os.Setenv("SYZ_DISABLE_SANDBOXING", "yes") } -const ( - userEmail = `test@syzkaller.com` - userName = `Test Syzkaller` - extractFixTagsEmail = `"syzbot" <syzbot@my.mail.com>` -) - func TestGitRepo(t *testing.T) { t.Parallel() baseDir, err := ioutil.TempDir("", "syz-git-test") @@ -34,30 +26,30 @@ func TestGitRepo(t *testing.T) { t.Fatal(err) } defer os.RemoveAll(baseDir) - repo1 := createTestRepo(t, baseDir, "repo1") - repo2 := createTestRepo(t, baseDir, "repo2") + repo1 := CreateTestRepo(t, baseDir, "repo1") + repo2 := CreateTestRepo(t, baseDir, "repo2") repo := newGit(filepath.Join(baseDir, "repo"), nil) { - com, err := repo.Poll(repo1.dir, "master") + com, err := repo.Poll(repo1.Dir, "master") if err != nil { t.Fatal(err) } - if diff := cmp.Diff(com, repo1.commits["master"]["1"]); diff != "" { + if diff := cmp.Diff(com, repo1.Commits["master"]["1"]); diff != "" { t.Fatal(diff) } } { - com, err := repo.CheckoutBranch(repo1.dir, "branch1") + com, err := repo.CheckoutBranch(repo1.Dir, "branch1") if err != nil { t.Fatal(err) } - if diff := cmp.Diff(com, repo1.commits["branch1"]["1"]); diff != "" { + if diff := cmp.Diff(com, repo1.Commits["branch1"]["1"]); diff != "" { t.Fatal(diff) } } { - want := repo1.commits["branch1"]["0"] - com, err := repo.CheckoutCommit(repo1.dir, want.Hash) + want := repo1.Commits["branch1"]["0"] + com, err := repo.CheckoutCommit(repo1.Dir, want.Hash) if err != nil { t.Fatal(err) } @@ -66,7 +58,7 @@ func TestGitRepo(t *testing.T) { } } { - commits, err := repo.ListRecentCommits(repo1.commits["branch1"]["1"].Hash) + commits, err := repo.ListRecentCommits(repo1.Commits["branch1"]["1"].Hash) if err != nil { t.Fatal(err) } @@ -76,8 +68,8 @@ func TestGitRepo(t *testing.T) { } } { - want := repo2.commits["branch1"]["0"] - com, err := repo.CheckoutCommit(repo2.dir, want.Hash) + want := repo2.Commits["branch1"]["0"] + com, err := repo.CheckoutCommit(repo2.Dir, want.Hash) if err != nil { t.Fatal(err) } @@ -86,8 +78,8 @@ func TestGitRepo(t *testing.T) { } } { - want := repo2.commits["branch1"]["1"] - com, err := repo.CheckoutCommit(repo2.dir, want.Hash) + want := repo2.Commits["branch1"]["1"] + com, err := repo.CheckoutCommit(repo2.Dir, want.Hash) if err != nil { t.Fatal(err) } @@ -96,16 +88,16 @@ func TestGitRepo(t *testing.T) { } } { - com, err := repo.CheckoutBranch(repo2.dir, "branch2") + com, err := repo.CheckoutBranch(repo2.Dir, "branch2") if err != nil { t.Fatal(err) } - if diff := cmp.Diff(com, repo2.commits["branch2"]["1"]); diff != "" { + if diff := cmp.Diff(com, repo2.Commits["branch2"]["1"]); diff != "" { t.Fatal(diff) } } { - want := repo2.commits["branch2"]["0"] + want := repo2.Commits["branch2"]["0"] com, err := repo.SwitchCommit(want.Hash) if err != nil { t.Fatal(err) @@ -123,9 +115,9 @@ func TestMetadata(t *testing.T) { t.Fatal(err) } defer os.RemoveAll(repoDir) - repo := makeTestRepo(t, repoDir) + repo := MakeTestRepo(t, repoDir) for i, test := range metadataTests { - repo.commitChange(test.description) + repo.CommitChange(test.description) com, err := repo.repo.HeadCommit() if err != nil { t.Fatal(err) @@ -297,10 +289,10 @@ func TestBisect(t *testing.T) { t.Fatal(err) } defer os.RemoveAll(repoDir) - repo := makeTestRepo(t, repoDir) + repo := MakeTestRepo(t, repoDir) var commits []string for i := 0; i < 5; i++ { - repo.commitChange(fmt.Sprintf("commit %v", i)) + repo.CommitChange(fmt.Sprintf("commit %v", i)) com, err := repo.repo.HeadCommit() if err != nil { t.Fatal(err) @@ -413,80 +405,3 @@ func TestBisect(t *testing.T) { } } } - -type testWriter testing.T - -func (t *testWriter) Write(data []byte) (int, error) { - (*testing.T)(t).Log(string(data)) - return len(data), nil -} - -func createTestRepo(t *testing.T, baseDir, name string) *testRepo { - repo := makeTestRepo(t, filepath.Join(baseDir, name)) - repo.git("checkout", "-b", "master") - repo.commitFileChange("master", "0") - for _, branch := range []string{"branch1", "branch2"} { - repo.git("checkout", "-b", branch, "master") - repo.commitFileChange(branch, "0") - repo.commitFileChange(branch, "1") - } - repo.git("checkout", "master") - repo.commitFileChange("master", "1") - return repo -} - -type testRepo struct { - t *testing.T - dir string - name string - commits map[string]map[string]*Commit - repo *git -} - -func makeTestRepo(t *testing.T, dir string) *testRepo { - if err := osutil.MkdirAll(dir); err != nil { - t.Fatal(err) - } - ignoreCC := map[string]bool{ - "stable@vger.kernel.org": true, - } - repo := &testRepo{ - t: t, - dir: dir, - name: filepath.Base(dir), - commits: make(map[string]map[string]*Commit), - repo: newGit(dir, ignoreCC), - } - repo.git("init") - repo.git("config", "--add", "user.email", userEmail) - repo.git("config", "--add", "user.name", userName) - return repo -} - -func (repo *testRepo) git(args ...string) { - if _, err := osutil.RunCmd(time.Minute, repo.dir, "git", args...); err != nil { - repo.t.Fatal(err) - } -} - -func (repo *testRepo) commitFileChange(branch, change string) { - id := fmt.Sprintf("%v-%v-%v", repo.name, branch, change) - file := filepath.Join(repo.dir, "file") - if err := osutil.WriteFile(file, []byte(id)); err != nil { - repo.t.Fatal(err) - } - repo.git("add", file) - repo.git("commit", "-m", id) - if repo.commits[branch] == nil { - repo.commits[branch] = make(map[string]*Commit) - } - com, err := repo.repo.HeadCommit() - if err != nil { - repo.t.Fatal(err) - } - repo.commits[branch][change] = com -} - -func (repo *testRepo) commitChange(description string) { - repo.git("commit", "--allow-empty", "-m", description) -} diff --git a/pkg/vcs/linux.go b/pkg/vcs/linux.go index e12682277..aaca97fe7 100644 --- a/pkg/vcs/linux.go +++ b/pkg/vcs/linux.go @@ -31,30 +31,10 @@ func newLinux(dir string) *linux { } func (ctx *linux) PreviousReleaseTags(commit string) ([]string, error) { - return ctx.previousReleaseTags(commit, false) -} - -func (ctx *linux) previousReleaseTags(commit string, self bool) ([]string, error) { - var tags []string - if self { - output, err := ctx.git.git("tag", "--list", "--points-at", commit, "--merged", commit, "v*.*") - if err != nil { - return nil, err - } - tags, err = gitParseReleaseTags(output) - if err != nil { - return nil, err - } - } - output, err := ctx.git.git("tag", "--no-contains", commit, "--merged", commit, "v*.*") - if err != nil { - return nil, err - } - tags1, err := gitParseReleaseTags(output) + tags, err := ctx.git.previousReleaseTags(commit, false) if err != nil { return nil, err } - tags = append(tags, tags1...) for i, tag := range tags { if tag == "v4.0" { // Initially we tried to stop at 3.8 because: diff --git a/pkg/vcs/test_util.go b/pkg/vcs/test_util.go new file mode 100644 index 000000000..55bd7bccd --- /dev/null +++ b/pkg/vcs/test_util.go @@ -0,0 +1,116 @@ +package vcs + +import ( + "fmt" + "path/filepath" + "testing" + "time" + + "github.com/google/syzkaller/pkg/osutil" +) + +const ( + userEmail = `test@syzkaller.com` + userName = `Test Syzkaller` + extractFixTagsEmail = `"syzbot" <syzbot@my.mail.com>` +) + +type testWriter testing.T + +func (t *testWriter) Write(data []byte) (int, error) { + (*testing.T)(t).Log(string(data)) + return len(data), nil +} + +type TestRepo struct { + t *testing.T + Dir string + name string + Commits map[string]map[string]*Commit + repo *git +} + +func (repo *TestRepo) git(args ...string) { + if _, err := osutil.RunCmd(time.Minute, repo.Dir, "git", args...); err != nil { + repo.t.Fatal(err) + } +} + +func MakeTestRepo(t *testing.T, dir string) *TestRepo { + if err := osutil.MkdirAll(dir); err != nil { + t.Fatal(err) + } + ignoreCC := map[string]bool{ + "stable@vger.kernel.org": true, + } + repo := &TestRepo{ + t: t, + Dir: dir, + name: filepath.Base(dir), + Commits: make(map[string]map[string]*Commit), + repo: newGit(dir, ignoreCC), + } + repo.git("init") + repo.git("config", "--add", "user.email", userEmail) + repo.git("config", "--add", "user.name", userName) + return repo +} + +func (repo *TestRepo) CommitFileChange(branch, change string) { + id := fmt.Sprintf("%v-%v-%v", repo.name, branch, change) + file := filepath.Join(repo.Dir, "file") + if err := osutil.WriteFile(file, []byte(id)); err != nil { + repo.t.Fatal(err) + } + repo.git("add", file) + repo.git("commit", "-m", id) + if repo.Commits[branch] == nil { + repo.Commits[branch] = make(map[string]*Commit) + } + com, err := repo.repo.HeadCommit() + if err != nil { + repo.t.Fatal(err) + } + repo.Commits[branch][change] = com +} + +func (repo *TestRepo) CommitChange(description string) { + repo.git("commit", "--allow-empty", "-m", description) +} + +func (repo *TestRepo) SetTag(tag string) { + repo.git("tag", tag) +} + +func CreateTestRepo(t *testing.T, baseDir, name string) *TestRepo { + repo := MakeTestRepo(t, filepath.Join(baseDir, name)) + repo.git("checkout", "-b", "master") + repo.CommitFileChange("master", "0") + for _, branch := range []string{"branch1", "branch2"} { + repo.git("checkout", "-b", branch, "master") + repo.CommitFileChange(branch, "0") + repo.CommitFileChange(branch, "1") + } + repo.git("checkout", "master") + repo.CommitFileChange("master", "1") + return repo +} + +func CloneTestRepo(t *testing.T, baseDir string, name string, originRepo *TestRepo) *TestRepo { + dir := filepath.Join(baseDir, name) + if err := osutil.MkdirAll(dir); err != nil { + t.Fatal(err) + } + ignoreCC := map[string]bool{ + "stable@vger.kernel.org": true, + } + repo := &TestRepo{ + t: t, + Dir: dir, + name: filepath.Base(dir), + Commits: make(map[string]map[string]*Commit), + repo: newGit(dir, ignoreCC), + } + repo.git("clone", originRepo.Dir, repo.Dir) + return repo +} diff --git a/pkg/vcs/testos.go b/pkg/vcs/testos.go new file mode 100644 index 000000000..f30dd0799 --- /dev/null +++ b/pkg/vcs/testos.go @@ -0,0 +1,23 @@ +// Copyright 2019 syzkaller project authors. All rights reserved. +// Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. + +package vcs + +type testos struct { + *git +} + +func newTestos(dir string) *testos { + return &testos{ + git: newGit(dir, nil), + } +} + +func (ctx *testos) PreviousReleaseTags(commit string) ([]string, error) { + return ctx.git.previousReleaseTags(commit, false) +} +func (ctx *testos) EnvForCommit(commit string, kernelConfig []byte) (*BisectEnv, error) { + return &BisectEnv{ + Compiler: "test-compiler-dont-use", + }, nil +} diff --git a/pkg/vcs/vcs.go b/pkg/vcs/vcs.go index 77b919d4b..28264522f 100644 --- a/pkg/vcs/vcs.go +++ b/pkg/vcs/vcs.go @@ -104,6 +104,8 @@ func NewRepo(os, vm, dir string) (Repo, error) { return newNetBSD(vm, dir), nil case "freebsd": return newFreeBSD(vm, dir), nil + case "test": + return newTestos(dir), nil } return nil, fmt.Errorf("vcs is unsupported for %v", os) } |
