Strengthen in-flight cancellation coverage · Entire
Strengthen in-flight cancellation coverage
Sessions
bce3d316a633View transcript
Changes
3
docs
Mrewrite-issue-list.md+1/-1
internal
gitproto
Msmarthttp_test.go+55/-17
syncer
Mintegration_test.go+22/-3
414 unmodified lines
Current rewrite note:
- Some of these are now covered, including empty source repo, tag force-retarget, duplicate/conflicting mappings, and tag creation when target objects already exist.
- Context cancellation and some harder batch-failure/cutover paths still appear missing.
- Basic context cancellation coverage now exists, but in-flight cancellation and some harder batch-failure/cutover paths still need stronger coverage.
### 22. No benchmark coverage for the expensive paths
3 unmodified lines
package example
import (
"context"
"errors"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/go-git/go-git/v5/plumbing/transport"
transporthttp "github.com/go-git/go-git/v5/plumbing/transport/http"
)
func TestRequestInfoRefsContextCanceled(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
}))
defer server.Close()
ep, err := transport.NewEndpoint(server.URL + "/repo.git")
started := make(chan struct{}, 1)
ep, err = transport.NewEndpoint("https://example.com/repo.git")
if err != nil {
t.Fatalf("parse endpoint: %v", err)
}
conn := NewConn(ep, "source", nil, http.DefaultTransport)
conn := NewConn(ep, "source", nil, roundTripperFunc(func(req *http.Request) (*http.Response, error) {
started <- struct{}{}
<-req.Context().Done()
return nil, req.Context().Err()
}))
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() {
_, err := RequestInfoRefs(ctx, conn, "git-upload-pack", "version=2")
done <- err
}()
select {
case <-started:
case <-time.After(2 * time.Second):
t.Fatal("request did not reach server before timeout")
}
cancel()
_, err = RequestInfoRefs(ctx, conn, "git-upload-pack", "version=2")
select {
case err = <-done:
case <-time.After(2 * time.Second):
t.Fatal("request did not return after cancellation")
}
if err == nil {
t.Fatal("expected cancellation error, got nil")
}
}
func TestPostRPCStreamContextCanceled(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
<-r.Context().Done()
}))
defer server.Close()
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() {
_, err := PostRPCStream(ctx, conn, "git-upload-pack", []byte("0000"), true, "upload-pack fetch")
done <- err
}()
select {
case <-started:
case <-time.After(2 * time.Second):
t.Fatal("request did not reach server before timeout")
}
cancel()
_, err = PostRPCStream(ctx, conn, "git-upload-pack", []byte("0000"), true, "upload-pack fetch")
select {
case err = <-done:
case <-time.After(2 * time.Second):
t.Fatal("request did not return after cancellation")
}
if err == nil {
t.Fatalf("expected context.Canceled, got %v", err)
}
}
func (f roundTripperFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
package example
func TestProbe_ContextCanceled(t *testing.T) {
started := make(chan struct{}, 1)
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
started <- struct{}{}
<-r.Context().Done()
}))
defer server.Close()
ctx, cancel := context.WithCancel(context.Background())
done := make(chan error, 1)
go func() {
_, err := Probe(ctx, Config{
Source: Endpoint{URL: server.URL + "/repo.git"},
})
done <- err
}()
select {
case <-started:
case <-time.After(2 * time.Second):
t.Fatal("probe request did not reach server before timeout")
}
cancel()
_, err := Probe(ctx, Config{
Source: Endpoint{URL: server.URL + "/repo.git"},
})
var err error
select {
case err = <-done:
case <-time.After(2 * time.Second):
t.Fatal("probe did not return after cancellation")
}
if err == nil {
t.Fatal("expected context cancellation error")
}
}