From af3f5e2b9139674b49c5caf0bc06e93cbc426727 Mon Sep 17 00:00:00 2001 From: Máximo Cuadros Date: Tue, 25 Jul 2017 14:26:17 +0200 Subject: transport: context package support --- plumbing/transport/common.go | 5 +- plumbing/transport/file/client.go | 10 +++- plumbing/transport/file/upload_pack_test.go | 6 +++ plumbing/transport/http/receive_pack.go | 12 +++-- plumbing/transport/http/upload_pack.go | 15 ++++-- plumbing/transport/internal/common/common.go | 54 ++++++++++++++++---- plumbing/transport/internal/common/server.go | 5 +- plumbing/transport/server/server.go | 13 +++-- plumbing/transport/server/upload_pack_test.go | 4 ++ plumbing/transport/test/receive_pack.go | 30 ++++++++++- plumbing/transport/test/upload_pack.go | 72 +++++++++++++++++++++++---- 11 files changed, 187 insertions(+), 39 deletions(-) (limited to 'plumbing') diff --git a/plumbing/transport/common.go b/plumbing/transport/common.go index d6594ca..2088500 100644 --- a/plumbing/transport/common.go +++ b/plumbing/transport/common.go @@ -13,6 +13,7 @@ package transport import ( + "context" "errors" "fmt" "io" @@ -72,7 +73,7 @@ type UploadPackSession interface { // including a packfile. Don't be confused by terminology, the client // side of a git-upload-pack is called git-fetch-pack, although here // the same interface is used to make it RPC-like. - UploadPack(*packp.UploadPackRequest) (*packp.UploadPackResponse, error) + UploadPack(context.Context, *packp.UploadPackRequest) (*packp.UploadPackResponse, error) } // ReceivePackSession represents a git-receive-pack session. @@ -86,7 +87,7 @@ type ReceivePackSession interface { // terminology, the client side of a git-receive-pack is called // git-send-pack, although here the same interface is used to make it // RPC-like. - ReceivePack(*packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) + ReceivePack(context.Context, *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) } // Endpoint represents a Git URL in any supported protocol. diff --git a/plumbing/transport/file/client.go b/plumbing/transport/file/client.go index b6d60c1..0b42abf 100644 --- a/plumbing/transport/file/client.go +++ b/plumbing/transport/file/client.go @@ -30,7 +30,9 @@ func NewClient(uploadPackBin, receivePackBin string) transport.Transport { }) } -func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod) (common.Command, error) { +func (r *runner) Command(cmd string, ep transport.Endpoint, auth transport.AuthMethod, +) (common.Command, error) { + switch cmd { case transport.UploadPackServiceName: cmd = r.UploadPackBin @@ -72,6 +74,11 @@ func (c *command) StdoutPipe() (io.Reader, error) { return c.cmd.StdoutPipe() } +func (c *command) Kill() error { + c.cmd.Process.Kill() + return c.Close() +} + // Close waits for the command to exit. func (c *command) Close() error { if c.closed { @@ -81,6 +88,7 @@ func (c *command) Close() error { defer func() { c.closed = true _ = c.stderrCloser.Close() + }() err := c.cmd.Wait() diff --git a/plumbing/transport/file/upload_pack_test.go b/plumbing/transport/file/upload_pack_test.go index f894935..9a922d1 100644 --- a/plumbing/transport/file/upload_pack_test.go +++ b/plumbing/transport/file/upload_pack_test.go @@ -78,3 +78,9 @@ func (s *UploadPackSuite) TestNonExistentCommand(c *C) { c.Assert(err, ErrorMatches, ".*file.*") c.Assert(session, IsNil) } + +func (s *UploadPackSuite) TestUploadPackWithContextOnRead(c *C) { + // TODO: Fix race condition when Session.Close and the read failed due to a + // canceled context when the packfile is being read. + c.Skip("UploadPack has a race condition when we Close the session") +} diff --git a/plumbing/transport/http/receive_pack.go b/plumbing/transport/http/receive_pack.go index b8489a7..b54b70f 100644 --- a/plumbing/transport/http/receive_pack.go +++ b/plumbing/transport/http/receive_pack.go @@ -2,6 +2,7 @@ package http import ( "bytes" + "context" "fmt" "io" "net/http" @@ -25,7 +26,7 @@ func (s *rpSession) AdvertisedReferences() (*packp.AdvRefs, error) { return advertisedReferences(s.session, transport.ReceivePackServiceName) } -func (s *rpSession) ReceivePack(req *packp.ReferenceUpdateRequest) ( +func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) ( *packp.ReportStatus, error) { url := fmt.Sprintf( "%s/%s", @@ -37,7 +38,7 @@ func (s *rpSession) ReceivePack(req *packp.ReferenceUpdateRequest) ( return nil, err } - res, err := s.doRequest(http.MethodPost, url, buf) + res, err := s.doRequest(ctx, http.MethodPost, url, buf) if err != nil { return nil, err } @@ -61,7 +62,10 @@ func (s *rpSession) ReceivePack(req *packp.ReferenceUpdateRequest) ( return report, report.Error() } -func (s *rpSession) doRequest(method, url string, content *bytes.Buffer) (*http.Response, error) { +func (s *rpSession) doRequest( + ctx context.Context, method, url string, content *bytes.Buffer, +) (*http.Response, error) { + var body io.Reader if content != nil { body = content @@ -75,7 +79,7 @@ func (s *rpSession) doRequest(method, url string, content *bytes.Buffer) (*http. applyHeadersToRequest(req, content, s.endpoint.Host(), transport.ReceivePackServiceName) s.applyAuthToRequest(req) - res, err := s.client.Do(req) + res, err := s.client.Do(req.WithContext(ctx)) if err != nil { return nil, plumbing.NewUnexpectedError(err) } diff --git a/plumbing/transport/http/upload_pack.go b/plumbing/transport/http/upload_pack.go index b1181b6..c5ac325 100644 --- a/plumbing/transport/http/upload_pack.go +++ b/plumbing/transport/http/upload_pack.go @@ -2,6 +2,7 @@ package http import ( "bytes" + "context" "fmt" "io" "net/http" @@ -28,7 +29,10 @@ func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) { return advertisedReferences(s.session, transport.UploadPackServiceName) } -func (s *upSession) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { +func (s *upSession) UploadPack( + ctx context.Context, req *packp.UploadPackRequest, +) (*packp.UploadPackResponse, error) { + if req.IsEmpty() { return nil, transport.ErrEmptyUploadPackRequest } @@ -47,7 +51,7 @@ func (s *upSession) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackR return nil, err } - res, err := s.doRequest(http.MethodPost, url, content) + res, err := s.doRequest(ctx, http.MethodPost, url, content) if err != nil { return nil, err } @@ -70,7 +74,10 @@ func (s *upSession) Close() error { return nil } -func (s *upSession) doRequest(method, url string, content *bytes.Buffer) (*http.Response, error) { +func (s *upSession) doRequest( + ctx context.Context, method, url string, content *bytes.Buffer, +) (*http.Response, error) { + var body io.Reader if content != nil { body = content @@ -84,7 +91,7 @@ func (s *upSession) doRequest(method, url string, content *bytes.Buffer) (*http. applyHeadersToRequest(req, content, s.endpoint.Host(), transport.UploadPackServiceName) s.applyAuthToRequest(req) - res, err := s.client.Do(req) + res, err := s.client.Do(req.WithContext(ctx)) if err != nil { return nil, plumbing.NewUnexpectedError(err) } diff --git a/plumbing/transport/internal/common/common.go b/plumbing/transport/internal/common/common.go index 04db770..2db8d54 100644 --- a/plumbing/transport/internal/common/common.go +++ b/plumbing/transport/internal/common/common.go @@ -7,6 +7,7 @@ package common import ( "bufio" + "context" "errors" "fmt" "io" @@ -64,6 +65,13 @@ type Command interface { Close() error } +// CommandKiller expands the Command interface, enableing it for being killed. +type CommandKiller interface { + // Kill and close the session whatever the state it is. It will block until + // the command is terminated. + Kill() error +} + type client struct { cmdr Commander } @@ -212,7 +220,7 @@ func (s *session) handleAdvRefDecodeError(err error) error { // UploadPack performs a request to the server to fetch a packfile. A reader is // returned with the packfile content. The reader must be closed after reading. -func (s *session) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { +func (s *session) UploadPack(ctx context.Context, req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { if req.IsEmpty() { return nil, transport.ErrEmptyUploadPackRequest } @@ -227,11 +235,14 @@ func (s *session) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackRes s.packRun = true - if err := uploadPack(s.Stdin, s.Stdout, req); err != nil { + in := s.StdinContext(ctx) + out := s.StdoutContext(ctx) + + if err := uploadPack(in, out, req); err != nil { return nil, err } - r, err := ioutil.NonEmptyReader(s.Stdout) + r, err := ioutil.NonEmptyReader(out) if err == ioutil.ErrEmptyReader { if c, ok := s.Stdout.(io.Closer); ok { _ = c.Close() @@ -244,22 +255,45 @@ func (s *session) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackRes return nil, err } - rc := ioutil.NewReadCloser(r, s.Command) + rc := ioutil.NewReadCloser(r, s) return DecodeUploadPackResponse(rc, req) } -func (s *session) ReceivePack(req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { +func (s *session) StdinContext(ctx context.Context) io.WriteCloser { + return ioutil.NewWriteCloserOnError( + ioutil.NewContextWriteCloser(ctx, s.Stdin), + s.onError, + ) +} + +func (s *session) StdoutContext(ctx context.Context) io.Reader { + return ioutil.NewReaderOnError( + ioutil.NewContextReader(ctx, s.Stdout), + s.onError, + ) +} + +func (s *session) onError(err error) { + if k, ok := s.Command.(CommandKiller); ok { + _ = k.Kill() + } + + _ = s.Close() +} + +func (s *session) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { if _, err := s.AdvertisedReferences(); err != nil { return nil, err } s.packRun = true - if err := req.Encode(s.Stdin); err != nil { + w := s.StdinContext(ctx) + if err := req.Encode(w); err != nil { return nil, err } - if err := s.Stdin.Close(); err != nil { + if err := w.Close(); err != nil { return nil, err } @@ -270,11 +304,12 @@ func (s *session) ReceivePack(req *packp.ReferenceUpdateRequest) (*packp.ReportS } report := packp.NewReportStatus() - if err := report.Decode(s.Stdout); err != nil { + if err := report.Decode(s.StdoutContext(ctx)); err != nil { return nil, err } if err := report.Error(); err != nil { + defer s.Close() return report, err } @@ -300,8 +335,9 @@ func (s *session) finish() error { } func (s *session) Close() (err error) { - defer ioutil.CheckClose(s.Command, &err) err = s.finish() + + defer ioutil.CheckClose(s.Command, &err) return } diff --git a/plumbing/transport/internal/common/server.go b/plumbing/transport/internal/common/server.go index dd6cfbe..f4ca692 100644 --- a/plumbing/transport/internal/common/server.go +++ b/plumbing/transport/internal/common/server.go @@ -1,6 +1,7 @@ package common import ( + "context" "fmt" "io" @@ -34,7 +35,7 @@ func ServeUploadPack(cmd ServerCommand, s transport.UploadPackSession) (err erro } var resp *packp.UploadPackResponse - resp, err = s.UploadPack(req) + resp, err = s.UploadPack(context.TODO(), req) if err != nil { return err } @@ -57,7 +58,7 @@ func ServeReceivePack(cmd ServerCommand, s transport.ReceivePackSession) error { return fmt.Errorf("error decoding: %s", err) } - rs, err := s.ReceivePack(req) + rs, err := s.ReceivePack(context.TODO(), req) if rs != nil { if err := rs.Encode(cmd.Stdout); err != nil { return fmt.Errorf("error in encoding report status %s", err) diff --git a/plumbing/transport/server/server.go b/plumbing/transport/server/server.go index 7c78afe..be36de5 100644 --- a/plumbing/transport/server/server.go +++ b/plumbing/transport/server/server.go @@ -3,6 +3,7 @@ package server import ( + "context" "errors" "fmt" "io" @@ -14,6 +15,7 @@ import ( "gopkg.in/src-d/go-git.v4/plumbing/revlist" "gopkg.in/src-d/go-git.v4/plumbing/storer" "gopkg.in/src-d/go-git.v4/plumbing/transport" + "gopkg.in/src-d/go-git.v4/utils/ioutil" ) var DefaultServer = NewServer(DefaultLoader) @@ -129,7 +131,7 @@ func (s *upSession) AdvertisedReferences() (*packp.AdvRefs, error) { return ar, nil } -func (s *upSession) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { +func (s *upSession) UploadPack(ctx context.Context, req *packp.UploadPackRequest) (*packp.UploadPackResponse, error) { if req.IsEmpty() { return nil, transport.ErrEmptyUploadPackRequest } @@ -167,7 +169,9 @@ func (s *upSession) UploadPack(req *packp.UploadPackRequest) (*packp.UploadPackR pw.CloseWithError(err) }() - return packp.NewUploadPackResponseWithPackfile(req, pr), nil + return packp.NewUploadPackResponseWithPackfile(req, + ioutil.NewContextReadCloser(ctx, pr), + ), nil } func (s *upSession) objectsToUpload(req *packp.UploadPackRequest) ([]plumbing.Hash, error) { @@ -222,7 +226,7 @@ var ( ErrUpdateReference = errors.New("failed to update ref") ) -func (s *rpSession) ReceivePack(req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { +func (s *rpSession) ReceivePack(ctx context.Context, req *packp.ReferenceUpdateRequest) (*packp.ReportStatus, error) { if s.caps == nil { s.caps = capability.NewList() if err := s.setSupportedCapabilities(s.caps); err != nil { @@ -238,7 +242,8 @@ func (s *rpSession) ReceivePack(req *packp.ReferenceUpdateRequest) (*packp.Repor //TODO: Implement 'atomic' update of references. - if err := s.writePackfile(req.Packfile); err != nil { + r := ioutil.NewContextReadCloser(ctx, req.Packfile) + if err := s.writePackfile(r); err != nil { s.unpackErr = err s.firstErr = err return s.reportStatus(), err diff --git a/plumbing/transport/server/upload_pack_test.go b/plumbing/transport/server/upload_pack_test.go index bd2b791..99473d3 100644 --- a/plumbing/transport/server/upload_pack_test.go +++ b/plumbing/transport/server/upload_pack_test.go @@ -39,6 +39,10 @@ func (s *UploadPackSuite) TestAdvertisedReferencesNotExists(c *C) { c.Assert(r, IsNil) } +func (s *UploadPackSuite) TestUploadPackWithContext(c *C) { + c.Skip("UploadPack cannot be canceled on server") +} + // Tests server with `asClient = true`. This is recommended when using a server // registered directly with `client.InstallProtocol`. type ClientLikeUploadPackSuite struct { diff --git a/plumbing/transport/test/receive_pack.go b/plumbing/transport/test/receive_pack.go index 15172c8..6309ef0 100644 --- a/plumbing/transport/test/receive_pack.go +++ b/plumbing/transport/test/receive_pack.go @@ -5,6 +5,7 @@ package test import ( "bytes" + "context" "io" "io/ioutil" @@ -31,6 +32,7 @@ func (s *ReceivePackSuite) TestAdvertisedReferencesEmpty(c *C) { r, err := s.Client.NewReceivePackSession(s.EmptyEndpoint, s.EmptyAuth) c.Assert(err, IsNil) defer func() { c.Assert(r.Close(), IsNil) }() + ar, err := r.AdvertisedReferences() c.Assert(err, IsNil) c.Assert(ar.Head, IsNil) @@ -51,7 +53,7 @@ func (s *ReceivePackSuite) TestAdvertisedReferencesNotExists(c *C) { {"master", plumbing.ZeroHash, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")}, } - writer, err := r.ReceivePack(req) + writer, err := r.ReceivePack(context.Background(), req) c.Assert(err, Equals, transport.ErrRepositoryNotFound) c.Assert(writer, IsNil) c.Assert(r.Close(), IsNil) @@ -102,6 +104,30 @@ func (s *ReceivePackSuite) TestFullSendPackOnEmpty(c *C) { s.checkRemoteHead(c, endpoint, fixture.Head) } +func (s *ReceivePackSuite) TestSendPackWithContext(c *C) { + fixture := fixtures.Basic().ByTag("packfile").One() + req := packp.NewReferenceUpdateRequest() + req.Packfile = fixture.Packfile() + req.Commands = []*packp.Command{ + {"refs/heads/master", plumbing.ZeroHash, fixture.Head}, + } + + r, err := s.Client.NewReceivePackSession(s.EmptyEndpoint, s.EmptyAuth) + c.Assert(err, IsNil) + defer func() { c.Assert(r.Close(), IsNil) }() + + info, err := r.AdvertisedReferences() + c.Assert(err, IsNil) + c.Assert(info, NotNil) + + ctx, close := context.WithCancel(context.TODO()) + close() + + report, err := r.ReceivePack(ctx, req) + c.Assert(err, NotNil) + c.Assert(report, IsNil) +} + func (s *ReceivePackSuite) TestSendPackOnEmpty(c *C) { endpoint := s.EmptyEndpoint full := false @@ -215,7 +241,7 @@ func (s *ReceivePackSuite) receivePackNoCheck(c *C, ep transport.Endpoint, req.Packfile = s.emptyPackfile() } - return r.ReceivePack(req) + return r.ReceivePack(context.Background(), req) } func (s *ReceivePackSuite) receivePack(c *C, ep transport.Endpoint, diff --git a/plumbing/transport/test/upload_pack.go b/plumbing/transport/test/upload_pack.go index 06ae893..ade6cdc 100644 --- a/plumbing/transport/test/upload_pack.go +++ b/plumbing/transport/test/upload_pack.go @@ -5,8 +5,10 @@ package test import ( "bytes" + "context" "io" "io/ioutil" + "time" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/format/packfile" @@ -45,7 +47,7 @@ func (s *UploadPackSuite) TestAdvertisedReferencesNotExists(c *C) { c.Assert(err, IsNil) req := packp.NewUploadPackRequest() req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, Equals, transport.ErrRepositoryNotFound) c.Assert(reader, IsNil) } @@ -93,7 +95,24 @@ func (s *UploadPackSuite) TestCapabilities(c *C) { c.Assert(info.Capabilities.Get(capability.Agent), HasLen, 1) } -func (s *UploadPackSuite) TestFullUploadPack(c *C) { +func (s *UploadPackSuite) TestUploadPack(c *C) { + r, err := s.Client.NewUploadPackSession(s.Endpoint, s.EmptyAuth) + c.Assert(err, IsNil) + defer func() { c.Assert(r.Close(), IsNil) }() + + req := packp.NewUploadPackRequest() + req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) + + reader, err := r.UploadPack(context.Background(), req) + c.Assert(err, IsNil) + + s.checkObjectNumber(c, reader, 28) +} + +func (s *UploadPackSuite) TestUploadPackWithContext(c *C) { + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond) + defer cancel() + r, err := s.Client.NewUploadPackSession(s.Endpoint, s.EmptyAuth) c.Assert(err, IsNil) defer func() { c.Assert(r.Close(), IsNil) }() @@ -105,21 +124,52 @@ func (s *UploadPackSuite) TestFullUploadPack(c *C) { req := packp.NewUploadPackRequest() req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(ctx, req) + c.Assert(err, NotNil) + c.Assert(reader, IsNil) +} + +func (s *UploadPackSuite) TestUploadPackWithContextOnRead(c *C) { + ctx, cancel := context.WithCancel(context.Background()) + + r, err := s.Client.NewUploadPackSession(s.Endpoint, s.EmptyAuth) + c.Assert(err, IsNil) + + info, err := r.AdvertisedReferences() + c.Assert(err, IsNil) + c.Assert(info, NotNil) + + req := packp.NewUploadPackRequest() + req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) + + reader, err := r.UploadPack(ctx, req) c.Assert(err, IsNil) + c.Assert(reader, NotNil) - s.checkObjectNumber(c, reader, 28) + cancel() + + _, err = io.Copy(ioutil.Discard, reader) + c.Assert(err, NotNil) + + err = reader.Close() + c.Assert(err, IsNil) + err = r.Close() + c.Assert(err, IsNil) } -func (s *UploadPackSuite) TestUploadPack(c *C) { +func (s *UploadPackSuite) TestUploadPackFull(c *C) { r, err := s.Client.NewUploadPackSession(s.Endpoint, s.EmptyAuth) c.Assert(err, IsNil) defer func() { c.Assert(r.Close(), IsNil) }() + info, err := r.AdvertisedReferences() + c.Assert(err, IsNil) + c.Assert(info, NotNil) + req := packp.NewUploadPackRequest() req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, IsNil) s.checkObjectNumber(c, reader, 28) @@ -135,7 +185,7 @@ func (s *UploadPackSuite) TestUploadPackInvalidReq(c *C) { req.Capabilities.Set(capability.Sideband) req.Capabilities.Set(capability.Sideband64k) - _, err = r.UploadPack(req) + _, err = r.UploadPack(context.Background(), req) c.Assert(err, NotNil) } @@ -148,7 +198,7 @@ func (s *UploadPackSuite) TestUploadPackNoChanges(c *C) { req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) req.Haves = append(req.Haves, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, Equals, transport.ErrEmptyUploadPackRequest) c.Assert(reader, IsNil) } @@ -162,7 +212,7 @@ func (s *UploadPackSuite) TestUploadPackMulti(c *C) { req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) req.Wants = append(req.Wants, plumbing.NewHash("e8d3ffab552895c19b9fcf7aa264d277cde33881")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, IsNil) s.checkObjectNumber(c, reader, 31) @@ -177,7 +227,7 @@ func (s *UploadPackSuite) TestUploadPackPartial(c *C) { req.Wants = append(req.Wants, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5")) req.Haves = append(req.Haves, plumbing.NewHash("918c48b83bd081e863dbe1b80f8998f058cd8294")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, IsNil) s.checkObjectNumber(c, reader, 4) @@ -190,7 +240,7 @@ func (s *UploadPackSuite) TestFetchError(c *C) { req := packp.NewUploadPackRequest() req.Wants = append(req.Wants, plumbing.NewHash("1111111111111111111111111111111111111111")) - reader, err := r.UploadPack(req) + reader, err := r.UploadPack(context.Background(), req) c.Assert(err, NotNil) c.Assert(reader, IsNil) -- cgit