1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
// 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/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()
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))
}
}
}
if !originRepo.SupportsBisection() {
t.Skip("bisection is unsupported by git (probably too old version)")
}
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")
}
}
|