aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/bisect/bisect_test.go
diff options
context:
space:
mode:
authorZubin Mithra <zsm@chromium.org>2019-10-08 15:57:52 -0700
committerDmitry Vyukov <dvyukov@google.com>2019-10-22 10:09:57 +0200
commita2bdbd8c37841cc507a2ad59f25d90d6467e5858 (patch)
treebc4ad0e738a749c2321b7181e4ea04c5615738e7 /pkg/bisect/bisect_test.go
parent37dc03de04826cc0d5d1e3699832b0a3113d40af (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.go133
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")
+ }
+}