/
githubmirror
/
client
Обзор
Документация
Войти
/
githubmirror
/
client
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
go/kbfs/libgit/browser_test.go
244 строки
8 KB
zoom-ua
go-git v5 (#29408)
14 июл 2026, 00:27
Не верифицирован
14 июл 2026, 00:27
f6785dd
Код
Авторство
О чём код?
// Copyright 2018 Keybase Inc. All rights reserved. // Use of this source code is governed by a BSD // license that can be found in the LICENSE file. package libgit import ( "io" "os" "path" "testing" "time" gogit "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/keybase/client/go/kbfs/data" "github.com/keybase/client/go/kbfs/libfs" "github.com/keybase/client/go/kbfs/libkbfs" "github.com/keybase/client/go/kbfs/tlf" "github.com/keybase/client/go/kbfs/tlfhandle" "github.com/keybase/client/go/protocol/keybase1" "github.com/stretchr/testify/require" ) func testBrowser(t *testing.T, sharedCache sharedInBrowserCache) { ctx, config, cancel, tempdir := initConfigForAutogit(t) defer cancel() defer func() { _ = os.RemoveAll(tempdir) }() defer libkbfs.CheckConfigAndShutdown(ctx, t, config) h, err := tlfhandle.ParseHandle( ctx, config.KBPKI(), config.MDOps(), nil, "user1", tlf.Private) require.NoError(t, err) rootFS, err := libfs.NewFS( ctx, config, h, data.MasterBranch, "", "", keybase1.MDPriorityNormal) require.NoError(t, err) t.Log("Init a new repo directly into KBFS.") dotgitFS, _, err := GetOrCreateRepoAndID(ctx, config, h, "test", "") require.NoError(t, err) t.Log("Check that the browser for an uninitialized repo works.") b, err := NewBrowser(dotgitFS, config.Clock(), "", sharedCache) require.NoError(t, err) fis, err := b.ReadDir("") require.NoError(t, err) require.Len(t, fis, 0) err = rootFS.MkdirAll("worktree", 0o600) require.NoError(t, err) worktreeFS, err := rootFS.Chroot("worktree") require.NoError(t, err) dotgitStorage, err := NewGitConfigWithoutRemotesStorer(dotgitFS) require.NoError(t, err) repo, err := gogit.Init(dotgitStorage, worktreeFS) require.NoError(t, err) t.Log("Check that the browser for an empty master branch works.") b, err = NewBrowser(dotgitFS, config.Clock(), "", sharedCache) require.NoError(t, err) fis, err = b.ReadDir("") require.NoError(t, err) require.Len(t, fis, 0) addFileToWorktreeAndCommit( ctx, t, config, h, repo, worktreeFS, "foo", "hello") addFileToWorktreeAndCommit( ctx, t, config, h, repo, worktreeFS, "dir/foo", "olleh") t.Log("Browse the repo and verify the data.") b, err = NewBrowser(dotgitFS, config.Clock(), "", sharedCache) require.NoError(t, err) if sharedCache != (noopSharedInBrowserCache{}) { t.Log("Before anything, cache should be empty") _, ok := sharedCache.getFileInfo(b.commitHash, path.Join(b.root, "foo")) require.False(t, ok) } fi, err := b.Stat("foo") require.NoError(t, err) require.Equal(t, "foo", fi.Name()) if sharedCache != (noopSharedInBrowserCache{}) { t.Log("After a Stat call, make sure cache is populated for foo") fi, ok := sharedCache.getFileInfo( b.commitHash, path.Join(b.root, "foo")) require.True(t, ok) require.Equal(t, "foo", fi.Name()) } t.Log("Verify the data in foo.") f, err := b.Open("foo") require.NoError(t, err) defer func() { _ = f.Close() }() data, err := io.ReadAll(f) require.NoError(t, err) require.Equal(t, "hello", string(data)) fis, err = b.ReadDir("dir") require.NoError(t, err) require.Len(t, fis, 1) if sharedCache != (noopSharedInBrowserCache{}) { t.Logf("After a ReadDir, " + "make sure cache is populated for dir and dir/foo") childrenPaths, ok := sharedCache.getChildrenFileInfos( b.commitHash, path.Join(b.root, "dir")) require.True(t, ok) require.Len(t, childrenPaths, 1) require.Equal(t, "foo", childrenPaths[0].Name()) fi, ok := sharedCache.getFileInfo( b.commitHash, path.Join(b.root, "dir", "foo")) require.True(t, ok) require.Equal(t, "foo", fi.Name()) } t.Log("Use ReadAt with a small buffer.") bf, ok := f.(*browserFile) require.True(t, ok) bf.maxBufSize = 1 buf := make([]byte, 3) n, err := f.ReadAt(buf, 2) require.NoError(t, err) require.Equal(t, 3, n) require.Equal(t, "llo", string(buf)) addSymlink := func(target, link string) { err = worktreeFS.Symlink(target, link) require.NoError(t, err) wt, err := repo.Worktree() require.NoError(t, err) _, err = wt.Add(link) require.NoError(t, err) _, err = wt.Commit("sym commit", &gogit.CommitOptions{ Author: &object.Signature{ Name: "me", Email: "me@keyba.se", When: time.Now(), }, }) require.NoError(t, err) b, err = NewBrowser(dotgitFS, config.Clock(), "", sharedCache) require.NoError(t, err) fi, err := b.Lstat(link) require.NoError(t, err) require.NotZero(t, fi.Mode()&os.ModeSymlink) fi, err = b.Stat(link) require.NoError(t, err) readTarget, err := b.Readlink(link) require.NoError(t, err) require.Equal(t, target, readTarget) require.Zero(t, fi.Mode()&os.ModeSymlink) f2, err := b.Open(link) require.NoError(t, err) defer func() { _ = f2.Close() }() data, err = io.ReadAll(f2) require.NoError(t, err) require.Equal(t, "hello", string(data)) } t.Log("Add and read a symlink.") addSymlink("foo", "symfoo") t.Log("Add and read a second symlink in a chain.") err = worktreeFS.MkdirAll("dir", 0o700) require.NoError(t, err) addSymlink("../symfoo", "dir/symfoo") } func TestBrowserNoCache(t *testing.T) { testBrowser(t, noopSharedInBrowserCache{}) } func TestBrowserWithCache(t *testing.T) { cache, err := newLRUSharedInBrowserCache() require.NoError(t, err) testBrowser(t, cache) } func TestBrowserHeadResolution(t *testing.T) { ctx, config, cancel, tempdir := initConfigForAutogit(t) defer cancel() defer func() { _ = os.RemoveAll(tempdir) }() defer libkbfs.CheckConfigAndShutdown(ctx, t, config) h, err := tlfhandle.ParseHandle( ctx, config.KBPKI(), config.MDOps(), nil, "user1", tlf.Private) require.NoError(t, err) rootFS, err := libfs.NewFS( ctx, config, h, data.MasterBranch, "", "", keybase1.MDPriorityNormal) require.NoError(t, err) t.Log("Init a new repo directly into KBFS.") dotgitFS, _, err := GetOrCreateRepoAndID(ctx, config, h, "test-head", "") require.NoError(t, err) err = rootFS.MkdirAll("worktree-head", 0o600) require.NoError(t, err) worktreeFS, err := rootFS.Chroot("worktree-head") require.NoError(t, err) dotgitStorage, err := NewGitConfigWithoutRemotesStorer(dotgitFS) require.NoError(t, err) repo, err := gogit.Init(dotgitStorage, worktreeFS) require.NoError(t, err) t.Log("Set HEAD to point to refs/heads/main instead of master.") newHead := plumbing.NewSymbolicReference( plumbing.HEAD, "refs/heads/main") err = repo.Storer.SetReference(newHead) require.NoError(t, err) t.Log("Commit a file — go-git creates the main branch since HEAD points there.") addFileToWorktreeAndCommit( ctx, t, config, h, repo, worktreeFS, "hello.txt", "world") t.Log("NewBrowser with empty branch should resolve HEAD to main.") b, err := NewBrowser(dotgitFS, config.Clock(), "", noopSharedInBrowserCache{}) require.NoError(t, err) require.NotNil(t, b.tree, "browser should have a non-nil tree") fi, err := b.Stat("hello.txt") require.NoError(t, err) require.Equal(t, "hello.txt", fi.Name()) f, err := b.Open("hello.txt") require.NoError(t, err) defer func() { _ = f.Close() }() fileData, err := io.ReadAll(f) require.NoError(t, err) require.Equal(t, "world", string(fileData)) t.Log("Test stale HEAD: point HEAD to a nonexistent ref.") staleHead := plumbing.NewSymbolicReference( plumbing.HEAD, "refs/heads/nonexistent") err = repo.Storer.SetReference(staleHead) require.NoError(t, err) t.Log("NewBrowser should return an empty browser without error.") b, err = NewBrowser(dotgitFS, config.Clock(), "", noopSharedInBrowserCache{}) require.NoError(t, err) fis, err := b.ReadDir("") require.NoError(t, err) require.Len(t, fis, 0) }