aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/vcs/git_test_util.go
blob: 9d5ef1edc301396ca95ae4b7e23d1333df7d5f8d (plain)
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
// 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

import (
	"fmt"
	"path/filepath"
	"strings"
	"testing"
	"time"

	"github.com/google/syzkaller/pkg/osutil"
)

const (
	userEmail           = `test@syzkaller.com`
	userName            = `Test Syzkaller`
	extractFixTagsEmail = `"syzbot" <syzbot@my.mail.com>`
)

type TestRepo struct {
	t       *testing.T
	Dir     string
	name    string
	Commits map[string]map[string]*Commit
	repo    *gitRepo
}

func (repo *TestRepo) Git(args ...string) {
	repo.t.Helper()
	cmd := osutil.Command("git", args...)
	cmd.Dir = repo.Dir
	cmd.Env = filterEnv()

	if _, err := osutil.Run(time.Minute, cmd); 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:    newGitRepo(dir, ignoreCC, []RepoOpt{OptPrecious, OptDontSandbox}),
	}
	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.Commit(HEAD)
	if err != nil {
		repo.t.Fatal(err)
	}
	repo.Commits[branch][change] = com
}

func (repo *TestRepo) CommitChange(description string) *Commit {
	repo.Git("commit", "--allow-empty", "-m", description)
	com, err := repo.repo.Commit(HEAD)
	if err != nil {
		repo.t.Fatal(err)
	}
	return com
}

func (repo *TestRepo) SetTag(tag string) {
	repo.Git("tag", tag)
}

func (repo *TestRepo) SupportsBisection() bool {
	// Detect too old git binary. --no-contains appeared in git 2.13.
	_, err := repo.repo.previousReleaseTags("HEAD", true, false, false)
	return err == nil ||
		!strings.Contains(err.Error(), "usage: git tag") &&
			!strings.Contains(err.Error(), "error: unknown option")
}

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
}