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 | |
| 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')
| -rw-r--r-- | pkg/bisect/bisect.go | 27 | ||||
| -rw-r--r-- | pkg/bisect/bisect_test.go | 133 | ||||
| -rw-r--r-- | pkg/build/build.go | 3 | ||||
| -rw-r--r-- | pkg/build/testlinux.go | 16 | ||||
| -rw-r--r-- | pkg/instance/instance.go | 18 | ||||
| -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 |
11 files changed, 369 insertions, 140 deletions
diff --git a/pkg/bisect/bisect.go b/pkg/bisect/bisect.go index 78cb58bd4..904be4b53 100644 --- a/pkg/bisect/bisect.go +++ b/pkg/bisect/bisect.go @@ -55,7 +55,7 @@ type env struct { repo vcs.Repo bisecter vcs.Bisecter head *vcs.Commit - inst *instance.Env + inst instance.BuilderTester numTests int buildTime time.Duration testTime time.Duration @@ -85,11 +85,30 @@ func Run(cfg *Config) ([]*vcs.Commit, *report.Report, error) { if !ok { return nil, nil, fmt.Errorf("bisection is not implemented for %v", cfg.Manager.TargetOS) } + inst, err := instance.NewEnv(&cfg.Manager) + if err != nil { + return nil, nil, err + } + if _, err = repo.CheckoutBranch(cfg.Kernel.Repo, cfg.Kernel.Branch); err != nil { + return nil, nil, err + } + + return runImpl(cfg, repo, bisecter, inst) +} + +func runImpl(cfg *Config, repo vcs.Repo, bisecter vcs.Bisecter, inst instance.BuilderTester) ( + []*vcs.Commit, *report.Report, error) { env := &env{ cfg: cfg, repo: repo, bisecter: bisecter, + inst: inst, } + head, err := repo.HeadCommit() + if err != nil { + return nil, nil, err + } + env.head = head if cfg.Fix { env.log("bisecting fixing commit since %v", cfg.Kernel.Commit) } else { @@ -135,12 +154,6 @@ func Run(cfg *Config) ([]*vcs.Commit, *report.Report, error) { func (env *env) bisect() ([]*vcs.Commit, *report.Report, error) { cfg := env.cfg var err error - if env.inst, err = instance.NewEnv(&cfg.Manager); err != nil { - return nil, nil, err - } - if env.head, err = env.repo.CheckoutBranch(cfg.Kernel.Repo, cfg.Kernel.Branch); err != nil { - return nil, nil, err - } if err := build.Clean(cfg.Manager.TargetOS, cfg.Manager.TargetVMArch, cfg.Manager.Type, cfg.Manager.KernelSrc); err != nil { return nil, nil, fmt.Errorf("kernel clean failed: %v", err) diff --git a/pkg/bisect/bisect_test.go b/pkg/bisect/bisect_test.go new file mode 100644 index 000000000..472fde289 --- /dev/null +++ b/pkg/bisect/bisect_test.go @@ -0,0 +1,133 @@ +// 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 bisect + +import ( + "bytes" + "fmt" + "io/ioutil" + "os" + "strconv" + "testing" + + "github.com/google/syzkaller/pkg/build" + "github.com/google/syzkaller/pkg/instance" + "github.com/google/syzkaller/pkg/mgrconfig" + "github.com/google/syzkaller/pkg/report" + "github.com/google/syzkaller/pkg/vcs" +) + +// testEnv will implement instance.BuilderTester. This allows us to +// set bisect.env.inst to a testEnv object. +type testEnv struct { + repo *vcs.TestRepo + r vcs.Repo + t *testing.T + // TODO: add a "fix bool" here so that Test() can return results according to + // whether fix/cause bisection is happening. +} + +func (env *testEnv) BuildSyzkaller(repo, commit string) error { + return nil +} + +func (env *testEnv) BuildKernel(compilerBin, userspaceDir, cmdlineFile, sysctlFile string, + kernelConfig []byte) (string, error) { + return "", nil +} + +func (env *testEnv) Test(numVMs int, reproSyz, reproOpts, reproC []byte) ([]error, error) { + hc, err := env.r.HeadCommit() + if err != nil { + env.t.Fatal(err) + } + // For cause bisection, if newer than or equal to 602, it crashes. + // -- 602 is the cause commit. + // TODO: for fix bisection(check env.fix), if older than 602, it crashes. + // -- 602 is the fix commit. + val, err := strconv.Atoi(hc.Title) + if err != nil { + env.t.Fatalf("invalid commit title: %v", val) + } + if val >= 602 { + var errors []error + for i := 0; i < numVMs; i++ { + errors = append(errors, &instance.CrashError{ + Report: &report.Report{ + Title: fmt.Sprintf("crashes at %v", hc.Title), + }, + }) + } + return errors, nil + } + var errors []error + for i := 0; i < numVMs; i++ { + errors = append(errors, nil) + } + return errors, nil +} + +// TestBisectCause tests that bisection returns the correct cause +// commit. +func TestBisectCause(t *testing.T) { + t.Parallel() + build.CompilerIdentity = func(_ string) (string, error) { + return "unused-compiler-identity", nil + } + baseDir, err := ioutil.TempDir("", "syz-git-test") + if err != nil { + t.Fatal(err) + } + defer os.RemoveAll(baseDir) + originRepo := vcs.CreateTestRepo(t, baseDir, "originRepo") + for rv := 4; rv < 10; rv++ { + for i := 0; i < 6; i++ { + originRepo.CommitChange(fmt.Sprintf("%v", rv*100+i)) + if i == 0 { + originRepo.SetTag(fmt.Sprintf("v%v.0", rv)) + } + } + } + repo := vcs.CloneTestRepo(t, baseDir, "repo", originRepo) + r, err := vcs.NewRepo("test", "64", repo.Dir) + if err != nil { + t.Fatal(err) + } + head, err := r.HeadCommit() + if err != nil { + t.Fatal(err) + } + cfg := &Config{ + Fix: false, + Trace: new(bytes.Buffer), + Manager: mgrconfig.Config{ + TargetOS: "test", + TargetVMArch: "64", + Type: "qemu", + KernelSrc: repo.Dir, + }, + Kernel: KernelConfig{ + Commit: head.Hash, + Repo: originRepo.Dir, + }, + } + inst := &testEnv{ + repo: repo, + r: r, + t: t, + } + commits, rep, err := runImpl(cfg, r, r.(vcs.Bisecter), inst) + if err != nil { + t.Fatalf("returned error: '%v'", err) + } + if len(commits) != 1 { + t.Fatalf("Got %d commits: %v", len(commits), commits) + } + if commits[0].Title != "602" { + t.Fatalf("Expected commit '602' got '%v'", commits[0].Title) + } + if rep == nil { + t.Fatal("returned rep==nil, report should not be empty") + } +} diff --git a/pkg/build/build.go b/pkg/build/build.go index 7e2a71ae4..7fce681df 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -79,6 +79,7 @@ func getBuilder(targetOS, targetArch, vmType string) (builder, error) { {"openbsd", "amd64", []string{"gce", "vmm"}, openbsd{}}, {"netbsd", "amd64", []string{"gce", "qemu"}, netbsd{}}, {"freebsd", "amd64", []string{"gce", "qemu"}, freebsd{}}, + {"test", "64", []string{"qemu"}, testBuilder{}}, } for _, s := range supported { if targetOS == s.OS && targetArch == s.arch { @@ -92,7 +93,7 @@ func getBuilder(targetOS, targetArch, vmType string) (builder, error) { return nil, fmt.Errorf("unsupported image type %v/%v/%v", targetOS, targetArch, vmType) } -func CompilerIdentity(compiler string) (string, error) { +var CompilerIdentity = func(compiler string) (string, error) { if compiler == "" { return "", nil } diff --git a/pkg/build/testlinux.go b/pkg/build/testlinux.go new file mode 100644 index 000000000..482c162c5 --- /dev/null +++ b/pkg/build/testlinux.go @@ -0,0 +1,16 @@ +// 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 build + +// TypeBuilder implements the builder interface. +type testBuilder struct{} + +func (tb testBuilder) build(targetArch, vmType, kernelDir, outputDir, compiler, userspaceDir, + cmdlineFile, sysctlFile string, config []byte) error { + return nil +} + +func (tb testBuilder) clean(string, string) error { + return nil +} diff --git a/pkg/instance/instance.go b/pkg/instance/instance.go index cc1b147f1..b3e24aace 100644 --- a/pkg/instance/instance.go +++ b/pkg/instance/instance.go @@ -27,11 +27,17 @@ import ( "github.com/google/syzkaller/vm" ) -type Env struct { +type BuilderTester interface { + BuildSyzkaller(string, string) error + BuildKernel(string, string, string, string, []byte) (string, error) + Test(numVMs int, reproSyz, reproOpts, reproC []byte) ([]error, error) +} + +type env struct { cfg *mgrconfig.Config } -func NewEnv(cfg *mgrconfig.Config) (*Env, error) { +func NewEnv(cfg *mgrconfig.Config) (BuilderTester, error) { if !vm.AllowsOvercommit(cfg.Type) { return nil, fmt.Errorf("test instances are not supported for %v VMs", cfg.Type) } @@ -47,13 +53,13 @@ func NewEnv(cfg *mgrconfig.Config) (*Env, error) { if err := osutil.MkdirAll(cfg.Workdir); err != nil { return nil, fmt.Errorf("failed to create tmp dir: %v", err) } - env := &Env{ + env := &env{ cfg: cfg, } return env, nil } -func (env *Env) BuildSyzkaller(repo, commit string) error { +func (env *env) BuildSyzkaller(repo, commit string) error { cfg := env.cfg srcIndex := strings.LastIndex(cfg.Syzkaller, "/src/") if srcIndex == -1 { @@ -82,7 +88,7 @@ func (env *Env) BuildSyzkaller(repo, commit string) error { return nil } -func (env *Env) BuildKernel(compilerBin, userspaceDir, cmdlineFile, sysctlFile string, +func (env *env) BuildKernel(compilerBin, userspaceDir, cmdlineFile, sysctlFile string, kernelConfig []byte) (string, error) { cfg := env.cfg imageDir := filepath.Join(cfg.Workdir, "image") @@ -170,7 +176,7 @@ func (err *CrashError) Error() string { // Test boots numVMs VMs, tests basic kernel operation, and optionally tests the provided reproducer. // TestError is returned if there is a problem with kernel/image (crash, reboot loop, etc). // CrashError is returned if the reproducer crashes kernel. -func (env *Env) Test(numVMs int, reproSyz, reproOpts, reproC []byte) ([]error, error) { +func (env *env) Test(numVMs int, reproSyz, reproOpts, reproC []byte) ([]error, error) { if err := mgrconfig.Complete(env.cfg); err != nil { return nil, err } 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) } |
