mirror of
https://github.com/hanzoai/forge.git
synced 2026-10-30 15:00:39 +00:00
2978 files. The fork is 2026-07-15 (rebrand: gitea.dev -> github.com/hanzoai/git), so 2026 is the year, and "Copyright 2026 Hanzo AI, Inc." was already the form used by the handful of files that had ours. Shape is now: // Copyright 2026 Hanzo AI, Inc. All rights reserved. // Copyright 2015 The Gogs Authors. All rights reserved. // Copyright 2019 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT Ours on top, theirs retained verbatim. Retained because MIT requires it, and separately because they are true — those authors did write that code. Not renamed to "The Git Authors": Git is a different project under a different license, and putting its name here would attribute this code to people who have nothing to do with it. Adding our line is the fix; overwriting theirs would have been both a licence violation and a false statement. gofmt still reports import-order drift in some of these files. It predates this change (verified against a stash) and is left alone rather than burying a one-line-per-file legal change under 3000 files of unrelated reordering. Build clean. Co-authored-by: Hanzo Dev <[email protected]>
107 lines
3.7 KiB
Go
107 lines
3.7 KiB
Go
// Copyright 2026 Hanzo AI, Inc. All rights reserved.
|
|
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package git
|
|
|
|
import (
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/hanzoai/git/modules/test"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestCatFileBatch(t *testing.T) {
|
|
defer test.MockVariableValue(&DefaultFeatures().SupportCatFileBatchCommand)()
|
|
DefaultFeatures().SupportCatFileBatchCommand = false
|
|
t.Run("LegacyCheck", testCatFileBatch)
|
|
DefaultFeatures().SupportCatFileBatchCommand = true
|
|
t.Run("BatchCommand", testCatFileBatch)
|
|
}
|
|
|
|
func testCatFileBatch(t *testing.T) {
|
|
t.Run("CorruptedGitRepo", func(t *testing.T) {
|
|
tmpDir := t.TempDir()
|
|
batch, err := NewBatch(t.Context(), tmpDir)
|
|
// as long as the directory exists, no error, because we can't really know whether the git repo is valid until we run commands
|
|
require.NoError(t, err)
|
|
defer batch.Close()
|
|
|
|
_, err = batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
|
require.Error(t, err)
|
|
_, err = batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
|
require.Error(t, err)
|
|
})
|
|
|
|
simulateQueryTerminated := func(t *testing.T, errBeforePipeClose, errAfterPipeClose error) {
|
|
readError := func(t *testing.T, r io.Reader, expectedErr error) {
|
|
if expectedErr == nil {
|
|
return // expectedErr == nil means this read should be skipped
|
|
}
|
|
n, err := r.Read(make([]byte, 100))
|
|
assert.Zero(t, n)
|
|
assert.ErrorIs(t, err, expectedErr)
|
|
}
|
|
|
|
batch, err := NewBatch(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
|
|
require.NoError(t, err)
|
|
defer batch.Close()
|
|
_, err = batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
|
require.NoError(t, err)
|
|
|
|
var c *catFileBatchCommunicator
|
|
switch b := batch.(type) {
|
|
case *catFileBatchLegacy:
|
|
c = b.batchCheck
|
|
_, _ = c.reqWriter.Write([]byte("in-complete-line-"))
|
|
case *catFileBatchCommand:
|
|
c = b.batch
|
|
_, _ = c.reqWriter.Write([]byte("info"))
|
|
default:
|
|
t.FailNow()
|
|
}
|
|
|
|
require.NotEqual(t, errBeforePipeClose == nil, errAfterPipeClose == nil, "must set exactly one of the expected errors")
|
|
|
|
inceptor := c.debugKill()
|
|
<-inceptor.beforeClose // wait for the command's Close to be called, the pipe is not closed yet
|
|
readError(t, c.respReader, errBeforePipeClose) // then caller will read on an open pipe which will be closed soon
|
|
close(inceptor.blockClose) // continue to close the pipe
|
|
<-inceptor.afterClose // wait for the pipe to be closed
|
|
readError(t, c.respReader, errAfterPipeClose) // then caller will read on a closed pipe
|
|
}
|
|
t.Run("QueryTerminated", func(t *testing.T) {
|
|
simulateQueryTerminated(t, io.EOF, nil) // reader is faster
|
|
simulateQueryTerminated(t, nil, os.ErrClosed) // pipes are closed faster
|
|
})
|
|
|
|
batch, err := NewBatch(t.Context(), filepath.Join(testReposDir, "repo1_bare"))
|
|
require.NoError(t, err)
|
|
defer batch.Close()
|
|
|
|
t.Run("QueryInfo", func(t *testing.T) {
|
|
info, err := batch.QueryInfo("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "e2129701f1a4d54dc44f03c93bca0a2aec7c5449", info.ID)
|
|
assert.Equal(t, "blob", info.Type)
|
|
assert.EqualValues(t, 6, info.Size)
|
|
})
|
|
|
|
t.Run("QueryContent", func(t *testing.T) {
|
|
info, rd, err := batch.QueryContent("e2129701f1a4d54dc44f03c93bca0a2aec7c5449")
|
|
require.NoError(t, err)
|
|
assert.Equal(t, "e2129701f1a4d54dc44f03c93bca0a2aec7c5449", info.ID)
|
|
assert.Equal(t, "blob", info.Type)
|
|
assert.EqualValues(t, 6, info.Size)
|
|
|
|
content, err := io.ReadAll(io.LimitReader(rd, info.Size))
|
|
require.NoError(t, err)
|
|
require.Equal(t, "file1\n", string(content))
|
|
})
|
|
}
|