Files

145 lines
4.9 KiB
Go

package executor
import (
"context"
"errors"
"strings"
"testing"
)
func TestForcePushUsesLease(t *testing.T) {
runner := &fakeGitRunner{responses: map[string]gitResponse{
"push --force-with-lease origin main": {out: "ok"},
}}
if err := forcePush(context.Background(), runner, "origin", "main"); err != nil {
t.Fatalf("forcePush: %v", err)
}
// Never a bare --force: the lease protects concurrent pushes.
if len(runner.calls) != 1 || runner.calls[0] != "push --force-with-lease origin main" {
t.Fatalf("calls = %v", runner.calls)
}
for _, call := range runner.calls {
if strings.Contains(call, "--force ") || strings.HasSuffix(call, " --force") {
t.Fatalf("unexpected bare --force: %q", call)
}
}
}
// lfsAdvisory is the git-lfs note that used to be mistaken for the cause.
const lfsAdvisory = `Locking support detected on remote "origin". Consider enabling it with:
$ git config lfs.https://gitea.example.com/a/b.git/info/lfs.locksverify true
`
func TestForcePushExplainsLeaseRejection(t *testing.T) {
runner := &fakeGitRunner{responses: map[string]gitResponse{
"push --force-with-lease origin main": {
errOut: lfsAdvisory + " ! [rejected] main -> main (stale info)\n",
err: errors.New("exit status 1"),
},
}}
err := forcePush(context.Background(), runner, "origin", "main")
if err == nil {
t.Fatal("expected an error")
}
msg := err.Error()
for _, want := range []string{"租约校验失败", "--force-with-lease=main:", "回滚"} {
if !strings.Contains(msg, want) {
t.Errorf("message missing %q:\n%s", want, msg)
}
}
// The git-lfs advice is noise here and must not lead the message.
if strings.Contains(msg, "Locking support detected") {
t.Errorf("LFS advisory leaked into the lease message:\n%s", msg)
}
}
func TestForcePushExplainsLFSMissing(t *testing.T) {
stderr := lfsAdvisory +
"Git LFS upload failed: 0% (0/1)\n" +
" (missing) doc/ffmpeg.zip (6080e34165fcb0261f979bb1cef26c5fce616e2a416384b50bcce956aa265018)\n" +
"hint: Your push was rejected due to missing or corrupt local objects.\n" +
"hint: You can disable this check with: `git config lfs.allowincompletepush true`\n"
runner := &fakeGitRunner{responses: map[string]gitResponse{
"push --force-with-lease origin main": {errOut: stderr, err: errors.New("exit status 1")},
}}
err := forcePush(context.Background(), runner, "origin", "main")
if err == nil {
t.Fatal("expected an error")
}
msg := err.Error()
for _, want := range []string{
"LFS 完整性检查",
"doc/ffmpeg.zip",
"lfs.allowincompletepush=true",
} {
if !strings.Contains(msg, want) {
t.Errorf("message missing %q:\n%s", want, msg)
}
}
// The lease wording would mislead: LFS, not the remote, blocked this push.
if strings.Contains(msg, "租约") {
t.Errorf("LFS failure was reported as a lease problem:\n%s", msg)
}
if strings.Contains(msg, "Locking support detected") {
t.Errorf("LFS advisory leaked into the message:\n%s", msg)
}
}
func TestForcePushExplainsProtectedBranch(t *testing.T) {
runner := &fakeGitRunner{responses: map[string]gitResponse{
"push --force-with-lease origin main": {
errOut: "remote: error: GH006: protected branch update failed\nremote: pre-receive hook declined\n",
err: errors.New("exit status 1"),
},
}}
err := forcePush(context.Background(), runner, "origin", "main")
if err == nil || !strings.Contains(err.Error(), "分支保护") {
t.Fatalf("err = %v, want a branch-protection message", err)
}
if strings.Contains(err.Error(), "租约") {
t.Errorf("protected branch was reported as a lease problem: %v", err)
}
}
func TestIsRejectedPush(t *testing.T) {
yes := []string{
"! [rejected] main -> main (stale info)",
"remote: pre-receive hook declined",
"protected branch hook declined",
}
for _, s := range yes {
if !isRejectedPush(s) {
t.Errorf("isRejectedPush(%q) = false, want true", s)
}
}
if isRejectedPush("fatal: unable to access remote") {
t.Error("network errors are not lease rejections")
}
// An LFS failure is not a remote-side rejection.
if isRejectedPush("Git LFS upload failed:\n (missing) a.zip (abc)") {
t.Error("LFS failures must not be classified as lease rejections")
}
}
func TestForcePushReportsNetworkError(t *testing.T) {
runner := &fakeGitRunner{responses: map[string]gitResponse{
"push --force-with-lease origin main": {
errOut: "fatal: unable to access remote", err: errors.New("exit 128"),
},
}}
err := forcePush(context.Background(), runner, "origin", "main")
if err == nil || !strings.Contains(err.Error(), "git push 失败") {
t.Fatalf("err = %v, want a git push failure", err)
}
}
func TestFirstMissingObject(t *testing.T) {
stderr := "Git LFS upload failed:\n (missing) doc/a.zip (abc123)\n (missing) upx.exe (def456)"
if got := firstMissingObject(stderr); got != "doc/a.zip" {
t.Errorf("firstMissingObject = %q", got)
}
if got := firstMissingObject("no entries"); got != "未知对象" {
t.Errorf("firstMissingObject = %q, want a placeholder", got)
}
}