diff options
| author | 2026-03-07 14:24:32 +0800 | |
|---|---|---|
| committer | 2026-03-07 17:21:05 +0800 | |
| commit | 175c8ed3c342f34110cdca42dc4027050b39d7fb (patch) | |
| tree | 8e0ddddc5b7146816f859c2013c7fb7909807e03 /receivepack/int_test.go | |
| parent | receivepack: Add service semantics thingy (diff) | |
| signature | No signature | |
receivepack: Connect protocol with service v0.1.72
Diffstat (limited to 'receivepack/int_test.go')
| -rw-r--r-- | receivepack/int_test.go | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/receivepack/int_test.go b/receivepack/int_test.go new file mode 100644 index 00000000..a790741b --- /dev/null +++ b/receivepack/int_test.go @@ -0,0 +1,234 @@ +package receivepack_test + +import ( + "context" + "fmt" + "strings" + "testing" + + "codeberg.org/lindenii/furgit/internal/testgit" + "codeberg.org/lindenii/furgit/objectid" + receivepack "codeberg.org/lindenii/furgit/receivepack" +) + +// TODO: actually test with send-pack + +func TestReceivePackDeleteOnlyReportsNotImplemented(t *testing.T) { + t.Parallel() + + //nolint:thelper + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + t.Parallel() + + testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo}) + _, _, commitID := testRepo.MakeCommit(t, "base") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + + repo := testRepo.OpenRepository(t) + + var ( + input strings.Builder + output bufferWriteFlusher + ) + + input.WriteString(pktlineData( + commitID.String() + " " + objectid.Zero(algo).String() + " refs/heads/main\x00report-status delete-refs object-format=" + algo.String() + "\n", + )) + input.WriteString("0000") + + err := receivepack.ReceivePack(context.Background(), &output, &strings.Builder{}, strings.NewReader(input.String()), receivepack.Options{ + GitProtocol: "", + Algorithm: algo, + Refs: repo.Refs(), + ExistingObjects: repo.Objects(), + }) + if err != nil { + t.Fatalf("ReceivePack: %v", err) + } + + got := output.String() + if !strings.Contains(got, "ng refs/heads/main ref updates not implemented yet\n") { + t.Fatalf("unexpected receive-pack output %q", got) + } + }) +} + +func TestReceivePackAdvertisesResolvedHEAD(t *testing.T) { + t.Parallel() + + //nolint:thelper + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + t.Parallel() + + testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo}) + _, _, commitID := testRepo.MakeCommit(t, "base") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + testRepo.SymbolicRef(t, "HEAD", "refs/heads/main") + + repo := testRepo.OpenRepository(t) + + var ( + input strings.Builder + output bufferWriteFlusher + ) + + input.WriteString("0000") + + err := receivepack.ReceivePack(context.Background(), &output, &strings.Builder{}, strings.NewReader(input.String()), receivepack.Options{ + Algorithm: algo, + Refs: repo.Refs(), + ExistingObjects: repo.Objects(), + }) + if err != nil { + t.Fatalf("ReceivePack: %v", err) + } + + got := output.String() + + want := commitID.String() + " HEAD" + if !strings.Contains(got, want) { + t.Fatalf("HEAD advertisement missing %q in %q", want, got) + } + }) +} + +func TestReceivePackVersion2FallsBackToV0(t *testing.T) { + t.Parallel() + + testReceivePackProtocolFallback(t, "version=2") +} + +func TestReceivePackHighestRequestedVersionFallsBackToV0ForV2(t *testing.T) { + t.Parallel() + + testReceivePackProtocolFallback(t, "version=1:version=2") +} + +func TestReceivePackWithoutReportStatusWritesNoStatusPayload(t *testing.T) { + t.Parallel() + + //nolint:thelper + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + t.Parallel() + + testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo}) + _, _, commitID := testRepo.MakeCommit(t, "base") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + + repo := testRepo.OpenRepository(t) + + var ( + input strings.Builder + output bufferWriteFlusher + ) + + input.WriteString(pktlineData( + commitID.String() + " " + objectid.Zero(algo).String() + " refs/heads/main\x00delete-refs object-format=" + algo.String() + "\n", + )) + input.WriteString("0000") + + err := receivepack.ReceivePack(context.Background(), &output, &strings.Builder{}, strings.NewReader(input.String()), receivepack.Options{ + Algorithm: algo, + Refs: repo.Refs(), + ExistingObjects: repo.Objects(), + }) + if err != nil { + t.Fatalf("ReceivePack: %v", err) + } + + got := output.String() + if strings.Contains(got, "unpack ") || strings.Contains(got, "ng refs/heads/main ") || strings.Contains(got, "ok refs/heads/main\n") { + t.Fatalf("unexpected status payload %q", got) + } + }) +} + +func testReceivePackProtocolFallback(t *testing.T, gitProtocol string) { + t.Helper() + + //nolint:thelper + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + t.Parallel() + + testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo}) + _, _, commitID := testRepo.MakeCommit(t, "base") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + + repo := testRepo.OpenRepository(t) + + var ( + input strings.Builder + output bufferWriteFlusher + ) + + input.WriteString(pktlineData( + commitID.String() + " " + objectid.Zero(algo).String() + " refs/heads/main\x00report-status delete-refs object-format=" + algo.String() + "\n", + )) + input.WriteString("0000") + + err := receivepack.ReceivePack(context.Background(), &output, &strings.Builder{}, strings.NewReader(input.String()), receivepack.Options{ + GitProtocol: gitProtocol, + Algorithm: algo, + Refs: repo.Refs(), + ExistingObjects: repo.Objects(), + }) + if err != nil { + t.Fatalf("ReceivePack: %v", err) + } + + if strings.HasPrefix(output.String(), pktlineData("version 1\n")) { + t.Fatalf("receive-pack output started with protocol v1 preface for %q: %q", gitProtocol, output.String()) + } + }) +} + +func TestReceivePackPackRequestWithoutObjectsRootReportsNotConfigured(t *testing.T) { + t.Parallel() + + //nolint:thelper + testgit.ForEachAlgorithm(t, func(t *testing.T, algo objectid.Algorithm) { + t.Parallel() + + testRepo := testgit.NewRepo(t, testgit.RepoOptions{ObjectFormat: algo}) + _, _, commitID := testRepo.MakeCommit(t, "base") + testRepo.UpdateRef(t, "refs/heads/main", commitID) + + repo := testRepo.OpenRepository(t) + + var ( + input strings.Builder + output bufferWriteFlusher + ) + + input.WriteString(pktlineData( + commitID.String() + " " + commitID.String() + " refs/heads/main\x00report-status object-format=" + algo.String() + "\n", + )) + input.WriteString("0000") + + err := receivepack.ReceivePack(context.Background(), &output, &strings.Builder{}, strings.NewReader(input.String()), receivepack.Options{ + Algorithm: algo, + Refs: repo.Refs(), + ExistingObjects: repo.Objects(), + }) + if err != nil { + t.Fatalf("ReceivePack: %v", err) + } + + got := output.String() + if !strings.Contains(got, "unpack objects root not configured\n") { + t.Fatalf("unexpected receive-pack output %q", got) + } + }) +} + +type bufferWriteFlusher struct { + strings.Builder +} + +func (bufferWriteFlusher) Flush() error { + return nil +} + +func pktlineData(payload string) string { + return fmt.Sprintf("%04x%s", len(payload)+4, payload) +} |
