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/bisect/bisect_test.go | |
| 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/bisect/bisect_test.go')
| -rw-r--r-- | pkg/bisect/bisect_test.go | 133 |
1 files changed, 133 insertions, 0 deletions
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") + } +} |
