Synchronization tool file history tests modified to set up a temporary git repo (#138)

This commit is contained in:
Domas Monkus 2020-11-03 11:19:36 +02:00 committed by GitHub
parent e8103502da
commit 54637e7313
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 122 additions and 46 deletions

View file

@ -133,8 +133,7 @@ func (f FileUnalteredChecker) Check(path string, setup Setup) error {
} else { } else {
return fmt.Errorf("failed to get stat for %q: %v", trgPath, err) return fmt.Errorf("failed to get stat for %q: %v", trgPath, err)
} }
} } else if srcInfo.IsDir() {
if srcInfo.IsDir() {
return fmt.Errorf("%q is a directory in source repository", path) return fmt.Errorf("%q is a directory in source repository", path)
} }

View file

@ -7,8 +7,10 @@ import (
"path" "path"
"path/filepath" "path/filepath"
"testing" "testing"
"time"
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/mattermost/mattermost-plugin-starter-template/build/sync/plan" "github.com/mattermost/mattermost-plugin-starter-template/build/sync/plan"
@ -48,7 +50,13 @@ func TestRepoIsCleanChecker(t *testing.T) {
func TestPathExistsChecker(t *testing.T) { func TestPathExistsChecker(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
wd, err := os.Getwd() // Set up a working directory.
wd, err := ioutil.TempDir("", "repo")
assert.Nil(err)
defer os.RemoveAll(wd)
err = os.Mkdir(filepath.Join(wd, "t"), 0755)
assert.Nil(err)
err = ioutil.WriteFile(filepath.Join(wd, "t", "test"), []byte("lorem ipsum"), 0644)
assert.Nil(err) assert.Nil(err)
checker := plan.PathExistsChecker{} checker := plan.PathExistsChecker{}
@ -61,30 +69,60 @@ func TestPathExistsChecker(t *testing.T) {
} }
// Check with existing directory. // Check with existing directory.
assert.Nil(checker.Check("testdata", ctx)) assert.Nil(checker.Check("t", ctx))
// Check with existing file. // Check with existing file.
assert.Nil(checker.Check("testdata/a", ctx)) assert.Nil(checker.Check("t/test", ctx))
err = checker.Check("nosuchpath", ctx) err = checker.Check("nosuchpath", ctx)
assert.NotNil(err) assert.NotNil(err)
assert.True(plan.IsCheckFail(err)) assert.True(plan.IsCheckFail(err))
} }
func tempGitRepo(assert *assert.Assertions) (string, *git.Repository, func()) {
// Setup repository.
wd, err := ioutil.TempDir("", "repo")
assert.Nil(err)
// Initialize a repository.
repo, err := git.PlainInit(wd, false)
assert.Nil(err)
w, err := repo.Worktree()
assert.Nil(err)
// Create repository files.
err = ioutil.WriteFile(filepath.Join(wd, "test"),
[]byte("lorem ipsum"), 0644)
assert.Nil(err)
sig := &object.Signature{
Name: "test",
Email: "test@example.com",
When: time.Now(),
}
_, err = w.Commit("initial commit", &git.CommitOptions{Author: sig})
assert.Nil(err)
pathA := "a.txt"
err = ioutil.WriteFile(filepath.Join(wd, pathA),
[]byte("lorem ipsum"), 0644)
assert.Nil(err)
_, err = w.Add(pathA)
assert.Nil(err)
_, err = w.Commit("add files", &git.CommitOptions{Author: sig})
assert.Nil(err)
return wd, repo, func() { os.RemoveAll(wd) }
}
func TestUnalteredCheckerSameFile(t *testing.T) { func TestUnalteredCheckerSameFile(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
// Path to the root of the repo. wd, repo, cleanup := tempGitRepo(assert)
wd, err := filepath.Abs("../../../") defer cleanup()
assert.Nil(err)
gitRepo, err := git.PlainOpen(wd)
assert.Nil(err)
ctx := plan.Setup{ ctx := plan.Setup{
Source: plan.RepoSetup{ Source: plan.RepoSetup{
Path: wd, Path: wd,
Git: gitRepo, Git: repo,
}, },
Target: plan.RepoSetup{ Target: plan.RepoSetup{
Path: wd, Path: wd,
@ -96,25 +134,21 @@ func TestUnalteredCheckerSameFile(t *testing.T) {
checker.Params.TargetRepo = plan.TargetRepo checker.Params.TargetRepo = plan.TargetRepo
// Check with the same file - check should succeed // Check with the same file - check should succeed
hashPath := "build/sync/plan/testdata/a" hashPath := "a.txt"
err = checker.Check(hashPath, ctx) err := checker.Check(hashPath, ctx)
assert.Nil(err) assert.Nil(err)
} }
func TestUnalteredCheckerDifferentContents(t *testing.T) { func TestUnalteredCheckerDifferentContents(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
// Path to the root of the repo. wd, repo, cleanup := tempGitRepo(assert)
wd, err := filepath.Abs("../../../") defer cleanup()
assert.Nil(err)
gitRepo, err := git.PlainOpen(wd)
assert.Nil(err)
ctx := plan.Setup{ ctx := plan.Setup{
Source: plan.RepoSetup{ Source: plan.RepoSetup{
Path: wd, Path: wd,
Git: gitRepo, Git: repo,
}, },
Target: plan.RepoSetup{ Target: plan.RepoSetup{
Path: wd, Path: wd,
@ -126,25 +160,18 @@ func TestUnalteredCheckerDifferentContents(t *testing.T) {
checker.Params.TargetRepo = plan.TargetRepo checker.Params.TargetRepo = plan.TargetRepo
// Create a file with the same suffix path, but different contents. // Create a file with the same suffix path, but different contents.
hashPath := "build/sync/plan/testdata/a"
tmpDir, err := ioutil.TempDir("", "test") tmpDir, err := ioutil.TempDir("", "test")
assert.Nil(err) assert.Nil(err)
defer os.RemoveAll(tmpDir) defer os.RemoveAll(tmpDir)
fullPath := filepath.Join(tmpDir, "build/sync/plan/testdata") err = ioutil.WriteFile(filepath.Join(tmpDir, "a.txt"),
err = os.MkdirAll(fullPath, 0777) []byte("not lorem ipsum"), 0644)
assert.Nil(err) assert.Nil(err)
file, err := os.OpenFile(filepath.Join(fullPath, "a"), os.O_CREATE|os.O_WRONLY, 0755)
assert.Nil(err)
_, err = file.WriteString("this file has different contents")
assert.Nil(err)
assert.Nil(file.Close())
// Set the plugin path to the temporary directory. // Set the plugin path to the temporary directory.
ctx.Target.Path = tmpDir ctx.Target.Path = tmpDir
err = checker.Check("a.txt", ctx)
err = checker.Check(hashPath, ctx)
assert.True(plan.IsCheckFail(err)) assert.True(plan.IsCheckFail(err))
assert.EqualError(err, fmt.Sprintf("file %q has been altered", filepath.Join(tmpDir, hashPath))) assert.EqualError(err, fmt.Sprintf("file %q has been altered", filepath.Join(tmpDir, "a.txt")))
} }
@ -153,13 +180,10 @@ func TestUnalteredCheckerDifferentContents(t *testing.T) {
// the checker should pass. // the checker should pass.
func TestUnalteredCheckerNonExistant(t *testing.T) { func TestUnalteredCheckerNonExistant(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
hashPath := "build/sync/plan/testdata/a" hashPath := "a.txt"
// Path to the root of the repo. wd, repo, cleanup := tempGitRepo(assert)
wd, err := filepath.Abs("../../../") defer cleanup()
assert.Nil(err)
gitRepo, err := git.PlainOpen(wd)
assert.Nil(err)
// Temporary repo. // Temporary repo.
tmpDir, err := ioutil.TempDir("", "test") tmpDir, err := ioutil.TempDir("", "test")
@ -172,7 +196,7 @@ func TestUnalteredCheckerNonExistant(t *testing.T) {
ctx := plan.Setup{ ctx := plan.Setup{
Source: plan.RepoSetup{ Source: plan.RepoSetup{
Path: wd, Path: wd,
Git: gitRepo, Git: repo,
}, },
Target: plan.RepoSetup{ Target: plan.RepoSetup{
Path: tmpDir, Path: tmpDir,

View file

@ -22,6 +22,7 @@ var ErrNotFound = fmt.Errorf("not found")
func FileHistory(path string, repo *git.Repository) ([]string, error) { func FileHistory(path string, repo *git.Repository) ([]string, error) {
logOpts := git.LogOptions{ logOpts := git.LogOptions{
FileName: &path, FileName: &path,
All: true,
} }
commits, err := repo.Log(&logOpts) commits, err := repo.Log(&logOpts)
if errors.Is(err, plumbing.ErrReferenceNotFound) { if errors.Is(err, plumbing.ErrReferenceNotFound) {
@ -31,7 +32,6 @@ func FileHistory(path string, repo *git.Repository) ([]string, error) {
return nil, fmt.Errorf("failed to get commits for path %q: %v", path, err) return nil, fmt.Errorf("failed to get commits for path %q: %v", path, err)
} }
defer commits.Close() defer commits.Close()
hashHistory := []string{} hashHistory := []string{}
cerr := commits.ForEach(func(c *object.Commit) error { cerr := commits.ForEach(func(c *object.Commit) error {
root, err := repo.TreeObject(c.TreeHash) root, err := repo.TreeObject(c.TreeHash)

View file

@ -1,28 +1,80 @@
package git_test package git_test
import ( import (
"io/ioutil"
"os"
"path/filepath"
"testing" "testing"
"time"
git "github.com/go-git/go-git/v5" git "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
gitutil "github.com/mattermost/mattermost-plugin-starter-template/build/sync/plan/git" gitutil "github.com/mattermost/mattermost-plugin-starter-template/build/sync/plan/git"
) )
var fileContents = []byte("abcdefg")
func TestFileHistory(t *testing.T) { func TestFileHistory(t *testing.T) {
assert := assert.New(t) assert := assert.New(t)
repo, err := git.PlainOpenWithOptions("./", &git.PlainOpenOptions{ dir, err := ioutil.TempDir("", "repo")
DetectDotGit: true, assert.Nil(err)
defer os.RemoveAll(dir)
// Initialize a repository.
repo, err := git.PlainInit(dir, false)
assert.Nil(err)
w, err := repo.Worktree()
assert.Nil(err)
// Create repository files.
err = ioutil.WriteFile(filepath.Join(dir, "test"), fileContents, 0644)
assert.Nil(err)
_, err = w.Add("test")
assert.Nil(err)
sig := &object.Signature{
Name: "test",
Email: "test@example.com",
When: time.Now(),
}
_, err = w.Commit("initial commit", &git.CommitOptions{Author: sig})
assert.Nil(err)
pathA := "a.txt"
err = ioutil.WriteFile(filepath.Join(dir, pathA), fileContents, 0644)
assert.Nil(err)
pathB := "b.txt"
err = ioutil.WriteFile(filepath.Join(dir, pathB), fileContents, 0644)
assert.Nil(err)
_, err = w.Add(pathA)
assert.Nil(err)
_, err = w.Add(pathB)
assert.Nil(err)
_, err = w.Commit("add files", &git.CommitOptions{Author: sig})
assert.Nil(err)
// Delete one of the files.
_, err = w.Remove(pathB)
assert.Nil(err)
_, err = w.Commit("remove file b.txt", &git.CommitOptions{
Author: sig,
All: true,
}) })
assert.Nil(err) assert.Nil(err)
sums, err := gitutil.FileHistory("build/sync/plan/git/testdata/testfile.txt", repo) repo, err = git.PlainOpen(dir)
assert.Nil(err) assert.Nil(err)
assert.Contains(sums, "ba7192052d7cf77c55d3b7bf40b350b8431b208b")
// Call file history on an existing file.
sums, err := gitutil.FileHistory("a.txt", repo)
assert.Nil(err)
assert.Equal([]string{"2fb5e13419fc89246865e7a324f476ec624e8740"}, sums)
// Calling with a non-existent file returns error. // Calling with a non-existent file returns error.
sums, err = gitutil.FileHistory("build/sync/plan/git/testdata/nosuch_testfile.txt", repo) sums, err = gitutil.FileHistory(filepath.Join(dir, "nosuch_testfile.txt"), repo)
assert.Equal(gitutil.ErrNotFound, err) assert.Equal(gitutil.ErrNotFound, err)
assert.Nil(sums) assert.Nil(sums)
// Calling with a non-existent file that was in git history returns no error.
_, err = gitutil.FileHistory(pathB, repo)
assert.Nil(err)
} }

View file

@ -1 +0,0 @@
This file is used to test file history tracking.

2
go.sum
View file

@ -477,6 +477,7 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0 h1:RR9dF3JtopPvtkroDZuVD7qquD0bnHlKSqaQhgwt8yk=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rudderlabs/analytics-go v3.2.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30= github.com/rudderlabs/analytics-go v3.2.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
@ -826,6 +827,7 @@ gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogR
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=