Add read-only source fetch smoke command · Entire

Add read-only source fetch smoke command

3752981→main·

Soph·3mo ago·3 files·+210 added/-0 removed

Sessions

01fbd070bdf2View transcript

Changes

3

Fetch from a source remote into memory without pushing anywhere:

go run ./cmd/git-sync fetch \
  --stats \
  --protocol auto \
  --branch main \
  <source-url>
Advertise an existing source ref as a synthetic `have` to exercise incremental negotiation:

go run ./cmd/git-sync fetch \
  --stats \
  --protocol auto \
  --branch main \
  --have-ref main \
  <source-url>

Dry run:

```bash
go run ./cmd/git-sync fetch --dry-run
func TestFetch_IntegrationProtocolV2Source(t *testing.T) {
    sourceRepo, sourceFS := newSourceRepo(t)
    makeCommits(t, sourceRepo, sourceFS, 4)

sourceServer := newSmartHTTPRepoServerV2(t, sourceRepo)
    defer sourceServer.Close()

result, err := Fetch(context.Background(), Config{
        Source:       Endpoint{URL: sourceServer.RepoURL()},
        ProtocolMode: protocolModeV2,
        Branches:     []string{testBranch},
        ShowStats:    true,
    }, nil, nil)
    if err != nil {
        t.Fatalf("fetch failed: %v", err)
    }
    if result.Protocol != protocolModeV2 {
        t.Fatalf("expected protocol v2, got %s", result.Protocol)
    }
    if len(result.Wants) != 1 {
        t.Fatalf("expected one wanted ref, got %#v", result.Wants)
    }
    if result.FetchedObjects == 0 {
        t.Fatalf("expected fetched objects")
    }
    if !result.Stats.Enabled || len(result.Stats.Items) == 0 {
        t.Fatalf("expected stats")
    }

sourceServer.ResetMetrics()
    result, err = Fetch(context.Background(), Config{
        Source:       Endpoint{URL: sourceServer.RepoURL()},
        ProtocolMode: protocolModeV2,
        Branches:     []string{testBranch},
        ShowStats:    true,
    }, []string{testBranch}, nil)
    if err != nil {
        t.Fatalf("fetch with haves failed: %v", err)
    }
    if len(result.Haves) != 1 {
        t.Fatalf("expected one have, got %#v", result.Haves)
    }
    if sourceServer.Haves(serviceUploadPack, metricPack) == 0 {
        t.Fatalf("expected source fetch to advertise haves")
    }
}

func TestRun_IntegrationTagsPruneAndForce(t *testing.T) {
    sourceRepo, sourceFS := newSourceRepo(t)
    makeCommits(t, sourceRepo, sourceFS, 2)
}
func (r FetchResult) Lines() []string {
    lines := []string{
        fmt.Sprintf("source: %s", r.SourceURL),
        fmt.Sprintf("requested-protocol: %s", r.RequestedMode),
        fmt.Sprintf("negotiated-protocol: %s", r.Protocol),
        fmt.Sprintf("wants: %d", len(r.Wants)),
        fmt.Sprintf("haves: %d", len(r.Haves)),
        fmt.Sprintf("fetched-objects: %d", r.FetchedObjects),
    }
    for _, want := range r.Wants {
        lines = append(lines, fmt.Sprintf("want: %s %s", want.Hash.String(), want.Name))
    }
    for _, have := range r.Haves {
        lines = append(lines, fmt.Sprintf("have: %s", have.String()))
    }
    if r.Stats.Enabled {
        keys := make([]string, 0, len(r.Stats.Items))
        for key := range r.Stats.Items {
            keys = append(keys, key)
        }
        sort.Strings(keys)
        for _, key := range keys {
            item := r.Stats.Items[key]
            lines = append(lines, fmt.Sprintf(
                "stats: %s requests=%d request-bytes=%d response-bytes=%d wants=%d haves=%d commands=%d",
                item.Name, item.Requests, item.RequestBytes, item.ResponseBytes, item.Wants, item.Haves, item.Commands,
            ))
        }
    }
    return lines
}