From f7b152f1262e5bec4f6aec061e2ded65d0b53893 Mon Sep 17 00:00:00 2001
From: zeripath <art27@cantab.net>
Date: Sat, 29 Jan 2022 12:41:44 +0000
Subject: [PATCH] Ensure git tag tests and others create test repos in tmpdir
 (#18447)

* Ensure git tag tests and other create test repos in tmpdir

There are a few places where tests appear to reuse testing repos which
causes random CI failures.

This PR simply changes these tests to ensure that cloning always happens
into new temporary directories.

Fix #18444

* Change log root for integration tests to use the REPO_TEST_DIR

There is a potential race in the drone integration tests whereby test-mysql etc
will start writing to log files causing make test-check fail.

Fix #18077

Signed-off-by: Andrew Thornton <art27@cantab.net>
---
 integrations/mssql.ini.tmpl      |   2 +-
 integrations/mysql.ini.tmpl      |   2 +-
 integrations/mysql8.ini.tmpl     |   2 +-
 integrations/pgsql.ini.tmpl      |   2 +-
 integrations/sqlite.ini.tmpl     |   2 +-
 modules/git/commit_info_test.go  |  83 ++++++++++++++++-------
 modules/git/repo_compare_test.go |  76 ++++++++++++++++-----
 modules/git/repo_tag_test.go     | 109 ++++++++++++++++++++++++-------
 8 files changed, 211 insertions(+), 67 deletions(-)

diff --git a/integrations/mssql.ini.tmpl b/integrations/mssql.ini.tmpl
index e97174ee85..00f55ec620 100644
--- a/integrations/mssql.ini.tmpl
+++ b/integrations/mssql.ini.tmpl
@@ -82,7 +82,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-mssql/data/sessions
 
 [log]
 MODE                 = test,file
-ROOT_PATH            = mssql-log
+ROOT_PATH            = {{REPO_TEST_DIR}}mssql-log
 ROUTER               = ,
 XORM                 = file
 ENABLE_SSH_LOG       = true
diff --git a/integrations/mysql.ini.tmpl b/integrations/mysql.ini.tmpl
index 6de2374277..c1780110a3 100644
--- a/integrations/mysql.ini.tmpl
+++ b/integrations/mysql.ini.tmpl
@@ -101,7 +101,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-mysql/data/sessions
 
 [log]
 MODE                 = test,file
-ROOT_PATH            = mysql-log
+ROOT_PATH            = {{REPO_TEST_DIR}}mysql-log
 ROUTER               = ,
 XORM                 = file
 ENABLE_SSH_LOG       = true
diff --git a/integrations/mysql8.ini.tmpl b/integrations/mysql8.ini.tmpl
index 606aa41d5c..0d898ac13d 100644
--- a/integrations/mysql8.ini.tmpl
+++ b/integrations/mysql8.ini.tmpl
@@ -79,7 +79,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-mysql8/data/sessions
 
 [log]
 MODE                 = test,file
-ROOT_PATH            = mysql8-log
+ROOT_PATH            = {{REPO_TEST_DIR}}mysql8-log
 ROUTER               = ,
 XORM                 = file
 ENABLE_SSH_LOG       = true
diff --git a/integrations/pgsql.ini.tmpl b/integrations/pgsql.ini.tmpl
index a325ea0286..1c4d843712 100644
--- a/integrations/pgsql.ini.tmpl
+++ b/integrations/pgsql.ini.tmpl
@@ -83,7 +83,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-pgsql/data/sessions
 
 [log]
 MODE                 = test,file
-ROOT_PATH            = pgsql-log
+ROOT_PATH            = {{REPO_TEST_DIR}}pgsql-log
 ROUTER               = ,
 XORM                 = file
 ENABLE_SSH_LOG       = true
diff --git a/integrations/sqlite.ini.tmpl b/integrations/sqlite.ini.tmpl
index e82780ad80..e2d999666a 100644
--- a/integrations/sqlite.ini.tmpl
+++ b/integrations/sqlite.ini.tmpl
@@ -78,7 +78,7 @@ PROVIDER_CONFIG = integrations/gitea-integration-sqlite/data/sessions
 
 [log]
 MODE                 = test,file
-ROOT_PATH            = sqlite-log
+ROOT_PATH            = {{REPO_TEST_DIR}}sqlite-log
 ROUTER               = ,
 XORM                 = file
 ENABLE_SSH_LOG       = true
diff --git a/modules/git/commit_info_test.go b/modules/git/commit_info_test.go
index 4cc207de64..42bed75a3d 100644
--- a/modules/git/commit_info_test.go
+++ b/modules/git/commit_info_test.go
@@ -17,21 +17,24 @@ import (
 )
 
 const (
-	testReposDir      = "tests/repos/"
-	benchmarkReposDir = "benchmark/repos/"
+	testReposDir = "tests/repos/"
 )
 
-func cloneRepo(url, dir, name string) (string, error) {
-	repoDir := filepath.Join(dir, name)
-	if _, err := os.Stat(repoDir); err == nil {
-		return repoDir, nil
+func cloneRepo(url, name string) (string, error) {
+	repoDir, err := os.MkdirTemp("", name)
+	if err != nil {
+		return "", err
 	}
-	return repoDir, Clone(DefaultContext, url, repoDir, CloneRepoOptions{
+	if err := Clone(DefaultContext, url, repoDir, CloneRepoOptions{
 		Mirror:  false,
 		Bare:    false,
 		Quiet:   true,
 		Timeout: 5 * time.Minute,
-	})
+	}); err != nil {
+		_ = util.RemoveAll(repoDir)
+		return "", err
+	}
+	return repoDir, nil
 }
 
 func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
@@ -61,20 +64,35 @@ func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
 	}
 	for _, testCase := range testCases {
 		commit, err := repo1.GetCommit(testCase.CommitID)
-		assert.NoError(t, err)
+		if err != nil {
+			assert.NoError(t, err, "Unable to get commit: %s from testcase due to error: %v", testCase.CommitID, err)
+			// no point trying to do anything else for this test.
+			continue
+		}
 		assert.NotNil(t, commit)
 		assert.NotNil(t, commit.Tree)
 		assert.NotNil(t, commit.Tree.repo)
 
 		tree, err := commit.Tree.SubTree(testCase.Path)
+		if err != nil {
+			assert.NoError(t, err, "Unable to get subtree: %s of commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
+			// no point trying to do anything else for this test.
+			continue
+		}
+
 		assert.NotNil(t, tree, "tree is nil for testCase CommitID %s in Path %s", testCase.CommitID, testCase.Path)
 		assert.NotNil(t, tree.repo, "repo is nil for testCase CommitID %s in Path %s", testCase.CommitID, testCase.Path)
 
-		assert.NoError(t, err)
 		entries, err := tree.ListEntries()
-		assert.NoError(t, err)
-		commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.Background(), commit, testCase.Path, nil)
-		assert.NoError(t, err)
+		if err != nil {
+			assert.NoError(t, err, "Unable to get entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
+			// no point trying to do anything else for this test.
+			continue
+		}
+
+		// FIXME: Context.TODO() - if graceful has started we should use its Shutdown context otherwise use install signals in TestMain.
+		commitsInfo, treeCommit, err := entries.GetCommitsInfo(context.TODO(), commit, testCase.Path, nil)
+		assert.NoError(t, err, "Unable to get commit information for entries of subtree: %s in commit: %s from testcase due to error: %v", testCase.Path, testCase.CommitID, err)
 		if err != nil {
 			t.FailNow()
 		}
@@ -100,40 +118,52 @@ func TestEntries_GetCommitsInfo(t *testing.T) {
 
 	testGetCommitsInfo(t, bareRepo1)
 
-	clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo")
-	assert.NoError(t, err)
+	clonedPath, err := cloneRepo(bareRepo1Path, "repo1_TestEntries_GetCommitsInfo")
+	if err != nil {
+		assert.NoError(t, err)
+	}
 	defer util.RemoveAll(clonedPath)
 	clonedRepo1, err := OpenRepository(clonedPath)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+	}
 	defer clonedRepo1.Close()
 
 	testGetCommitsInfo(t, clonedRepo1)
 }
 
 func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
-	benchmarks := []struct {
+	type benchmarkType struct {
 		url  string
 		name string
-	}{
+	}
+
+	benchmarks := []benchmarkType{
 		{url: "https://github.com/go-gitea/gitea.git", name: "gitea"},
 		{url: "https://github.com/ethantkoenig/manyfiles.git", name: "manyfiles"},
 		{url: "https://github.com/moby/moby.git", name: "moby"},
 		{url: "https://github.com/golang/go.git", name: "go"},
 		{url: "https://github.com/torvalds/linux.git", name: "linux"},
 	}
-	for _, benchmark := range benchmarks {
+
+	doBenchmark := func(benchmark benchmarkType) {
 		var commit *Commit
 		var entries Entries
 		var repo *Repository
-		if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil {
+		repoPath, err := cloneRepo(benchmark.url, benchmark.name)
+		if err != nil {
 			b.Fatal(err)
-		} else if repo, err = OpenRepository(repoPath); err != nil {
+		}
+		defer util.RemoveAll(repoPath)
+
+		if repo, err = OpenRepository(repoPath); err != nil {
 			b.Fatal(err)
-		} else if commit, err = repo.GetBranchCommit("master"); err != nil {
-			repo.Close()
+		}
+		defer repo.Close()
+
+		if commit, err = repo.GetBranchCommit("master"); err != nil {
 			b.Fatal(err)
 		} else if entries, err = commit.Tree.ListEntries(); err != nil {
-			repo.Close()
 			b.Fatal(err)
 		}
 		entries.Sort()
@@ -146,6 +176,9 @@ func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
 				}
 			}
 		})
-		repo.Close()
+	}
+
+	for _, benchmark := range benchmarks {
+		doBenchmark(benchmark)
 	}
 }
diff --git a/modules/git/repo_compare_test.go b/modules/git/repo_compare_test.go
index 301e085aae..82d3257c0f 100644
--- a/modules/git/repo_compare_test.go
+++ b/modules/git/repo_compare_test.go
@@ -17,17 +17,33 @@ import (
 
 func TestGetFormatPatch(t *testing.T) {
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
-	clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestGetFormatPatch")
+	clonedPath, err := cloneRepo(bareRepo1Path, "repo1_TestGetFormatPatch")
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer util.RemoveAll(clonedPath)
-	assert.NoError(t, err)
+
 	repo, err := OpenRepository(clonedPath)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer repo.Close()
-	assert.NoError(t, err)
+
 	rd := &bytes.Buffer{}
 	err = repo.GetPatch("8d92fc95^", "8d92fc95", rd)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+
 	patchb, err := io.ReadAll(rd)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+
 	patch := string(patchb)
 	assert.Regexp(t, "^From 8d92fc95", patch)
 	assert.Contains(t, patch, "Subject: [PATCH] Add file2.txt")
@@ -37,17 +53,25 @@ func TestReadPatch(t *testing.T) {
 	// Ensure we can read the patch files
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
 	repo, err := OpenRepository(bareRepo1Path)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer repo.Close()
-	assert.NoError(t, err)
 	// This patch doesn't exist
 	noFile, err := repo.ReadPatchCommit(0)
 	assert.Error(t, err)
+
 	// This patch is an empty one (sometimes it's a 404)
 	noCommit, err := repo.ReadPatchCommit(1)
 	assert.Error(t, err)
+
 	// This patch is legit and should return a commit
 	oldCommit, err := repo.ReadPatchCommit(2)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 
 	assert.Empty(t, noFile)
 	assert.Empty(t, noCommit)
@@ -58,23 +82,45 @@ func TestReadPatch(t *testing.T) {
 func TestReadWritePullHead(t *testing.T) {
 	// Ensure we can write SHA1 head corresponding to PR and open them
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
-	repo, err := OpenRepository(bareRepo1Path)
-	assert.NoError(t, err)
+
+	// As we are writing we should clone the repository first
+	clonedPath, err := cloneRepo(bareRepo1Path, "TestReadWritePullHead")
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+	defer util.RemoveAll(clonedPath)
+
+	repo, err := OpenRepository(clonedPath)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer repo.Close()
+
 	// Try to open non-existing Pull
 	_, err = repo.GetRefCommitID(PullPrefix + "0/head")
 	assert.Error(t, err)
+
 	// Write a fake sha1 with only 40 zeros
 	newCommit := "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"
 	err = repo.SetReference(PullPrefix+"1/head", newCommit)
-	assert.NoError(t, err)
-	// Remove file after the test
-	defer func() {
-		_ = repo.RemoveReference(PullPrefix + "1/head")
-	}()
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+
 	// Read the file created
 	headContents, err := repo.GetRefCommitID(PullPrefix + "1/head")
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+
 	assert.Len(t, string(headContents), 40)
 	assert.True(t, string(headContents) == newCommit)
+
+	// Remove file after the test
+	err = repo.RemoveReference(PullPrefix + "1/head")
+	assert.NoError(t, err)
 }
diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go
index f4d6726ea1..25fb8fcd9b 100644
--- a/modules/git/repo_tag_test.go
+++ b/modules/git/repo_tag_test.go
@@ -16,11 +16,17 @@ import (
 func TestRepository_GetTags(t *testing.T) {
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
 	bareRepo1, err := OpenRepository(bareRepo1Path)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer bareRepo1.Close()
 
 	tags, total, err := bareRepo1.GetTagInfos(0, 0)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	assert.Len(t, tags, 1)
 	assert.Equal(t, len(tags), total)
 	assert.EqualValues(t, "test", tags[0].Name)
@@ -31,40 +37,75 @@ func TestRepository_GetTags(t *testing.T) {
 func TestRepository_GetTag(t *testing.T) {
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
 
-	clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestRepository_GetTag")
-	assert.NoError(t, err)
+	clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetTag")
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer util.RemoveAll(clonedPath)
 
 	bareRepo1, err := OpenRepository(clonedPath)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer bareRepo1.Close()
 
+	// LIGHTWEIGHT TAGS
 	lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
 	lTagName := "lightweightTag"
-	bareRepo1.CreateTag(lTagName, lTagCommitID)
 
-	aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"
-	aTagName := "annotatedTag"
-	aTagMessage := "my annotated message \n - test two line"
-	bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID)
-	aTagID, _ := bareRepo1.GetTagID(aTagName)
+	// Create the lightweight tag
+	err = bareRepo1.CreateTag(lTagName, lTagCommitID)
+	if err != nil {
+		assert.NoError(t, err, "Unable to create the lightweight tag: %s for ID: %s. Error: %v", lTagName, lTagCommitID, err)
+		return
+	}
 
+	// and try to get the Tag for lightweight tag
 	lTag, err := bareRepo1.GetTag(lTagName)
-	assert.NoError(t, err)
-	assert.NotNil(t, lTag)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	if lTag == nil {
+		assert.NotNil(t, lTag)
 		assert.FailNow(t, "nil lTag: %s", lTagName)
+		return
 	}
 	assert.EqualValues(t, lTagName, lTag.Name)
 	assert.EqualValues(t, lTagCommitID, lTag.ID.String())
 	assert.EqualValues(t, lTagCommitID, lTag.Object.String())
 	assert.EqualValues(t, "commit", lTag.Type)
 
+	// ANNOTATED TAGS
+	aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"
+	aTagName := "annotatedTag"
+	aTagMessage := "my annotated message \n - test two line"
+
+	// Create the annotated tag
+	err = bareRepo1.CreateAnnotatedTag(aTagName, aTagMessage, aTagCommitID)
+	if err != nil {
+		assert.NoError(t, err, "Unable to create the annotated tag: %s for ID: %s. Error: %v", aTagName, aTagCommitID, err)
+		return
+	}
+
+	// Now try to get the tag for the annotated Tag
+	aTagID, err := bareRepo1.GetTagID(aTagName)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
+
 	aTag, err := bareRepo1.GetTag(aTagName)
-	assert.NoError(t, err)
-	assert.NotNil(t, aTag)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	if aTag == nil {
+		assert.NotNil(t, aTag)
 		assert.FailNow(t, "nil aTag: %s", aTagName)
+		return
 	}
 	assert.EqualValues(t, aTagName, aTag.Name)
 	assert.EqualValues(t, aTagID, aTag.ID.String())
@@ -72,26 +113,47 @@ func TestRepository_GetTag(t *testing.T) {
 	assert.EqualValues(t, aTagCommitID, aTag.Object.String())
 	assert.EqualValues(t, "tag", aTag.Type)
 
+	// RELEASE TAGS
+
 	rTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0"
 	rTagName := "release/" + lTagName
-	bareRepo1.CreateTag(rTagName, rTagCommitID)
+
+	err = bareRepo1.CreateTag(rTagName, rTagCommitID)
+	if err != nil {
+		assert.NoError(t, err, "Unable to create the  tag: %s for ID: %s. Error: %v", rTagName, rTagCommitID, err)
+		return
+	}
+
 	rTagID, err := bareRepo1.GetTagID(rTagName)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	assert.EqualValues(t, rTagCommitID, rTagID)
+
 	oTagID, err := bareRepo1.GetTagID(lTagName)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	assert.EqualValues(t, lTagCommitID, oTagID)
 }
 
 func TestRepository_GetAnnotatedTag(t *testing.T) {
 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
 
-	clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestRepository_GetTag")
-	assert.NoError(t, err)
+	clonedPath, err := cloneRepo(bareRepo1Path, "TestRepository_GetAnnotatedTag")
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer util.RemoveAll(clonedPath)
 
 	bareRepo1, err := OpenRepository(clonedPath)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	defer bareRepo1.Close()
 
 	lTagCommitID := "6fbd69e9823458e6c4a2fc5c0f6bc022b2f2acd1"
@@ -106,7 +168,10 @@ func TestRepository_GetAnnotatedTag(t *testing.T) {
 
 	// Try an annotated tag
 	tag, err := bareRepo1.GetAnnotatedTag(aTagID)
-	assert.NoError(t, err)
+	if err != nil {
+		assert.NoError(t, err)
+		return
+	}
 	assert.NotNil(t, tag)
 	assert.EqualValues(t, aTagName, tag.Name)
 	assert.EqualValues(t, aTagID, tag.ID.String())