github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/pkg/vcs/git_test_util.go (about)

     1  // Copyright 2019 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  package vcs
     5  
     6  import (
     7  	"fmt"
     8  	"path/filepath"
     9  	"strings"
    10  	"testing"
    11  	"time"
    12  
    13  	"github.com/google/syzkaller/pkg/osutil"
    14  )
    15  
    16  const (
    17  	userEmail           = `test@syzkaller.com`
    18  	userName            = `Test Syzkaller`
    19  	extractFixTagsEmail = `"syzbot" <syzbot@my.mail.com>`
    20  )
    21  
    22  type TestRepo struct {
    23  	t       *testing.T
    24  	Dir     string
    25  	name    string
    26  	Commits map[string]map[string]*Commit
    27  	repo    *git
    28  }
    29  
    30  func (repo *TestRepo) Git(args ...string) {
    31  	repo.t.Helper()
    32  	cmd := osutil.Command("git", args...)
    33  	cmd.Dir = repo.Dir
    34  	cmd.Env = filterEnv()
    35  
    36  	if _, err := osutil.Run(time.Minute, cmd); err != nil {
    37  		repo.t.Fatal(err)
    38  	}
    39  }
    40  
    41  func MakeTestRepo(t *testing.T, dir string) *TestRepo {
    42  	if err := osutil.MkdirAll(dir); err != nil {
    43  		t.Fatal(err)
    44  	}
    45  	ignoreCC := map[string]bool{
    46  		"stable@vger.kernel.org": true,
    47  	}
    48  	repo := &TestRepo{
    49  		t:       t,
    50  		Dir:     dir,
    51  		name:    filepath.Base(dir),
    52  		Commits: make(map[string]map[string]*Commit),
    53  		repo:    newGit(dir, ignoreCC, []RepoOpt{OptPrecious, OptDontSandbox}),
    54  	}
    55  	repo.Git("init")
    56  	repo.Git("config", "--add", "user.email", userEmail)
    57  	repo.Git("config", "--add", "user.name", userName)
    58  	return repo
    59  }
    60  
    61  func (repo *TestRepo) CommitFileChange(branch, change string) {
    62  	id := fmt.Sprintf("%v-%v-%v", repo.name, branch, change)
    63  	file := filepath.Join(repo.Dir, "file")
    64  	if err := osutil.WriteFile(file, []byte(id)); err != nil {
    65  		repo.t.Fatal(err)
    66  	}
    67  	repo.Git("add", file)
    68  	repo.Git("commit", "-m", id)
    69  	if repo.Commits[branch] == nil {
    70  		repo.Commits[branch] = make(map[string]*Commit)
    71  	}
    72  	com, err := repo.repo.HeadCommit()
    73  	if err != nil {
    74  		repo.t.Fatal(err)
    75  	}
    76  	repo.Commits[branch][change] = com
    77  }
    78  
    79  func (repo *TestRepo) CommitChange(description string) *Commit {
    80  	repo.Git("commit", "--allow-empty", "-m", description)
    81  	com, err := repo.repo.HeadCommit()
    82  	if err != nil {
    83  		repo.t.Fatal(err)
    84  	}
    85  	return com
    86  }
    87  
    88  func (repo *TestRepo) SetTag(tag string) {
    89  	repo.Git("tag", tag)
    90  }
    91  
    92  func (repo *TestRepo) SupportsBisection() bool {
    93  	// Detect too old git binary. --no-contains appeared in git 2.13.
    94  	_, err := repo.repo.previousReleaseTags("HEAD", true, false, false)
    95  	return err == nil ||
    96  		!strings.Contains(err.Error(), "usage: git tag") &&
    97  			!strings.Contains(err.Error(), "error: unknown option")
    98  }
    99  
   100  func CreateTestRepo(t *testing.T, baseDir, name string) *TestRepo {
   101  	repo := MakeTestRepo(t, filepath.Join(baseDir, name))
   102  	repo.Git("checkout", "-b", "master")
   103  	repo.CommitFileChange("master", "0")
   104  	for _, branch := range []string{"branch1", "branch2"} {
   105  		repo.Git("checkout", "-b", branch, "master")
   106  		repo.CommitFileChange(branch, "0")
   107  		repo.CommitFileChange(branch, "1")
   108  	}
   109  	repo.Git("checkout", "master")
   110  	repo.CommitFileChange("master", "1")
   111  	return repo
   112  }
   113  
   114  func CloneTestRepo(t *testing.T, baseDir, name string, originRepo *TestRepo) *TestRepo {
   115  	dir := filepath.Join(baseDir, name)
   116  	if err := osutil.MkdirAll(dir); err != nil {
   117  		t.Fatal(err)
   118  	}
   119  	ignoreCC := map[string]bool{
   120  		"stable@vger.kernel.org": true,
   121  	}
   122  	repo := &TestRepo{
   123  		t:       t,
   124  		Dir:     dir,
   125  		name:    filepath.Base(dir),
   126  		Commits: make(map[string]map[string]*Commit),
   127  		repo:    newGit(dir, ignoreCC, []RepoOpt{OptPrecious, OptDontSandbox}),
   128  	}
   129  	repo.Git("clone", originRepo.Dir, repo.Dir)
   130  	return repo
   131  }