Add stream close coverage for pack push paths · Entire

Add stream close coverage for pack push paths

74213a2→main·Soph·3mo ago·2 files·+120 added/-1 removed

Sessions

6bda93bfe6b6View transcript

[?
Can you take a look at the go code (wasm) in /Users/soph/Work/entire/devenv/entire-io-worktree1 based a bit on that I wonder if something like this can be build:Codex·GPT-5.4·1 step](/content/gh/entireio/git-sync/session/019d6d29-8cf7-7fe3-adc9-8c3e4d9d5603#timeline-6bda93bfe6b6/index.html)

Changes

2

155 unmodified lines

156
157
158
159
159
160
161
162
163

155 unmodified lines

- Failing batch pushes must not leak HTTP response bodies.

Current rewrite note:
- Ownership of stream lifecycle is clearer than on `main`, but this still wants an explicit close-audit and tests around failing push paths.
- Ownership of stream lifecycle is clearer than on `main`, and the rewrite now has direct tests for key pack-stream close behavior on success and error paths.
- This still wants a fuller close-audit around all strategy-level failure paths before it should be considered fully done.

### 6. Protocol v2 tag fetches request `include-tag` without capability gating

Mdocs/rewrite-issue-list.md+2/-1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118

package gitproto

import (
    "bytes"
    "context"
    "errors"
    "io"
    "testing"

"github.com/go-git/go-git/v5/plumbing/protocol/packp"
    "github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
    "github.com/go-git/go-git/v5/plumbing/transport"
)

func TestOpenV2PackStreamCloseClosesBody(t *testing.T) {
    body := &trackingReadCloser{
        ReadCloser: io.NopCloser(bytes.NewBufferString(
            FormatPktLine("packfile\n"),
        )),
    }

rc, err := openV2PackStream(body)
    if err != nil {
        t.Fatalf("openV2PackStream: %v", err)
    }
    if err := rc.Close(); err != nil {
        t.Fatalf("close pack stream: %v", err)
    }
    if !body.closed {
        t.Fatal("expected underlying body to be closed")
    }
}

func TestPushPackClosesPackOnSuccess(t *testing.T) {
    pack := &trackingReadCloser{ReadCloser: io.NopCloser(bytes.NewBufferString("PACK"))}
    conn := &Conn{
        Transport: fakeTransport{receivePackSession: &fakeReceivePackSession{}},
    }
    adv := packp.NewAdvRefs()
    adv.Capabilities = capability.NewList()

err := PushPack(context.Background(), conn, adv, []PushCommand{{
        Name: "refs/heads/main",
    }}, pack, false)
    if err != nil {
        t.Fatalf("PushPack returned error: %v", err)
    }
    if !pack.closed {
        t.Fatal("expected pack to be closed on success")
    }
}

func TestPushPackClosesPackOnReceivePackError(t *testing.T) {
    pack := &trackingReadCloser{ReadCloser: io.NopCloser(bytes.NewBufferString("PACK"))}
    conn := &Conn{
        Transport: fakeTransport{receivePackSession: &fakeReceivePackSession{
            err: errors.New("receive-pack failed"),
        }},
    }
    adv := packp.NewAdvRefs()
    adv.Capabilities = capability.NewList()

err := PushPack(context.Background(), conn, adv, []PushCommand{{
        Name: "refs/heads/main",
    }}, pack, false)
    if err == nil {
        t.Fatal("expected PushPack to return an error")
    }
    if !pack.closed {
        t.Fatal("expected pack to be closed on error")
    }
}

type trackingReadCloser struct {
    io.ReadCloser
    closed bool
}

func (r *trackingReadCloser) Close() error {
    r.closed = true
    if r.ReadCloser != nil {
        return r.ReadCloser.Close()
    }
    return nil
}

type fakeTransport struct {
    receivePackSession transport.ReceivePackSession
}

func (t fakeTransport) NewUploadPackSession(*transport.Endpoint, transport.AuthMethod) (transport.UploadPackSession, error) {
    return nil, errors.New("not implemented")
}

func (t fakeTransport) NewReceivePackSession(*transport.Endpoint, transport.AuthMethod) (transport.ReceivePackSession, error) {
    return t.receivePackSession, nil
}

type fakeReceivePackSession struct {
    err error
}

func (s *fakeReceivePackSession) AdvertisedReferences() (*packp.AdvRefs, error) {
    return packp.NewAdvRefs(), nil
}

func (s *fakeReceivePackSession) AdvertisedReferencesContext(context.Context) (*packp.AdvRefs, error) {
    return s.AdvertisedReferences()
}

func (s *fakeReceivePackSession) ReceivePack(context.Context, *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) {
    if s.err != nil {
        return nil, s.err
    }
    return nil, nil
}

func (s *fakeReceivePackSession) Close() error { return nil }