In investigating #7947 it has become clear that the storage component of go-git repositories needs closing. This PR adds this Close function and adds the Close functions as necessary. In TransferOwnership the ctx.Repo.GitRepo is closed if it is open to help prevent the risk of multiple open files. Fixes #7947
		
			
				
	
	
		
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			133 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package git
 | |
| 
 | |
| import (
 | |
| 	"os"
 | |
| 	"path/filepath"
 | |
| 	"testing"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/stretchr/testify/assert"
 | |
| )
 | |
| 
 | |
| const testReposDir = "tests/repos/"
 | |
| const benchmarkReposDir = "benchmark/repos/"
 | |
| 
 | |
| func cloneRepo(url, dir, name string) (string, error) {
 | |
| 	repoDir := filepath.Join(dir, name)
 | |
| 	if _, err := os.Stat(repoDir); err == nil {
 | |
| 		return repoDir, nil
 | |
| 	}
 | |
| 	return repoDir, Clone(url, repoDir, CloneRepoOptions{
 | |
| 		Mirror:  false,
 | |
| 		Bare:    false,
 | |
| 		Quiet:   true,
 | |
| 		Timeout: 5 * time.Minute,
 | |
| 	})
 | |
| }
 | |
| 
 | |
| func testGetCommitsInfo(t *testing.T, repo1 *Repository) {
 | |
| 	// these test case are specific to the repo1 test repo
 | |
| 	testCases := []struct {
 | |
| 		CommitID           string
 | |
| 		Path               string
 | |
| 		ExpectedIDs        map[string]string
 | |
| 		ExpectedTreeCommit string
 | |
| 	}{
 | |
| 		{"8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2", "", map[string]string{
 | |
| 			"file1.txt": "95bb4d39648ee7e325106df01a621c530863a653",
 | |
| 			"file2.txt": "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
 | |
| 		}, "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2"},
 | |
| 		{"2839944139e0de9737a044f78b0e4b40d989a9e3", "", map[string]string{
 | |
| 			"file1.txt":   "2839944139e0de9737a044f78b0e4b40d989a9e3",
 | |
| 			"branch1.txt": "9c9aef8dd84e02bc7ec12641deb4c930a7c30185",
 | |
| 		}, "2839944139e0de9737a044f78b0e4b40d989a9e3"},
 | |
| 		{"5c80b0245c1c6f8343fa418ec374b13b5d4ee658", "branch2", map[string]string{
 | |
| 			"branch2.txt": "5c80b0245c1c6f8343fa418ec374b13b5d4ee658",
 | |
| 		}, "5c80b0245c1c6f8343fa418ec374b13b5d4ee658"},
 | |
| 		{"feaf4ba6bc635fec442f46ddd4512416ec43c2c2", "", map[string]string{
 | |
| 			"file1.txt": "95bb4d39648ee7e325106df01a621c530863a653",
 | |
| 			"file2.txt": "8d92fc957a4d7cfd98bc375f0b7bb189a0d6c9f2",
 | |
| 			"foo":       "37991dec2c8e592043f47155ce4808d4580f9123",
 | |
| 		}, "feaf4ba6bc635fec442f46ddd4512416ec43c2c2"},
 | |
| 	}
 | |
| 	for _, testCase := range testCases {
 | |
| 		commit, err := repo1.GetCommit(testCase.CommitID)
 | |
| 		assert.NoError(t, err)
 | |
| 		tree, err := commit.Tree.SubTree(testCase.Path)
 | |
| 		assert.NoError(t, err)
 | |
| 		entries, err := tree.ListEntries()
 | |
| 		assert.NoError(t, err)
 | |
| 		commitsInfo, treeCommit, err := entries.GetCommitsInfo(commit, testCase.Path, nil)
 | |
| 		assert.Equal(t, testCase.ExpectedTreeCommit, treeCommit.ID.String())
 | |
| 		assert.NoError(t, err)
 | |
| 		assert.Len(t, commitsInfo, len(testCase.ExpectedIDs))
 | |
| 		for _, commitInfo := range commitsInfo {
 | |
| 			entry := commitInfo[0].(*TreeEntry)
 | |
| 			commit := commitInfo[1].(*Commit)
 | |
| 			expectedID, ok := testCase.ExpectedIDs[entry.Name()]
 | |
| 			if !assert.True(t, ok) {
 | |
| 				continue
 | |
| 			}
 | |
| 			assert.Equal(t, expectedID, commit.ID.String())
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func TestEntries_GetCommitsInfo(t *testing.T) {
 | |
| 	bareRepo1Path := filepath.Join(testReposDir, "repo1_bare")
 | |
| 	bareRepo1, err := OpenRepository(bareRepo1Path)
 | |
| 	assert.NoError(t, err)
 | |
| 	defer bareRepo1.Close()
 | |
| 
 | |
| 	testGetCommitsInfo(t, bareRepo1)
 | |
| 
 | |
| 	clonedPath, err := cloneRepo(bareRepo1Path, testReposDir, "repo1_TestEntries_GetCommitsInfo")
 | |
| 	assert.NoError(t, err)
 | |
| 	defer os.RemoveAll(clonedPath)
 | |
| 	clonedRepo1, err := OpenRepository(clonedPath)
 | |
| 	assert.NoError(t, err)
 | |
| 	defer clonedRepo1.Close()
 | |
| 
 | |
| 	testGetCommitsInfo(t, clonedRepo1)
 | |
| }
 | |
| 
 | |
| func BenchmarkEntries_GetCommitsInfo(b *testing.B) {
 | |
| 	benchmarks := []struct {
 | |
| 		url  string
 | |
| 		name string
 | |
| 	}{
 | |
| 		{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 {
 | |
| 		var commit *Commit
 | |
| 		var entries Entries
 | |
| 		var repo *Repository
 | |
| 		if repoPath, err := cloneRepo(benchmark.url, benchmarkReposDir, benchmark.name); err != nil {
 | |
| 			b.Fatal(err)
 | |
| 		} else if repo, err = OpenRepository(repoPath); err != nil {
 | |
| 			b.Fatal(err)
 | |
| 		} else if commit, err = repo.GetBranchCommit("master"); err != nil {
 | |
| 			repo.Close()
 | |
| 			b.Fatal(err)
 | |
| 		} else if entries, err = commit.Tree.ListEntries(); err != nil {
 | |
| 			repo.Close()
 | |
| 			b.Fatal(err)
 | |
| 		}
 | |
| 		entries.Sort()
 | |
| 		b.ResetTimer()
 | |
| 		b.Run(benchmark.name, func(b *testing.B) {
 | |
| 			for i := 0; i < b.N; i++ {
 | |
| 				_, _, err := entries.GetCommitsInfo(commit, "", nil)
 | |
| 				if err != nil {
 | |
| 					b.Fatal(err)
 | |
| 				}
 | |
| 			}
 | |
| 		})
 | |
| 		repo.Close()
 | |
| 	}
 | |
| }
 |