Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'internal/git/gitpipe/catfile_object_test.go')
-rw-r--r--internal/git/gitpipe/catfile_object_test.go47
1 files changed, 47 insertions, 0 deletions
diff --git a/internal/git/gitpipe/catfile_object_test.go b/internal/git/gitpipe/catfile_object_test.go
index 5e40cf444..17ccfe017 100644
--- a/internal/git/gitpipe/catfile_object_test.go
+++ b/internal/git/gitpipe/catfile_object_test.go
@@ -13,6 +13,7 @@ import (
"gitlab.com/gitlab-org/gitaly/v15/internal/git/localrepo"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper"
"gitlab.com/gitlab-org/gitaly/v15/internal/testhelper/testcfg"
+ "google.golang.org/grpc/metadata"
)
func TestCatfileObject(t *testing.T) {
@@ -149,4 +150,50 @@ func TestCatfileObject(t *testing.T) {
err: context.Canceled,
}, it.Result())
})
+
+ t.Run("context cancellation with cached process", func(t *testing.T) {
+ ctx, cancel := context.WithCancel(testhelper.Context(t))
+ ctx = testhelper.MergeIncomingMetadata(ctx, metadata.Pairs(
+ catfile.SessionIDField, "1",
+ ))
+
+ catfileCache := catfile.NewCache(cfg)
+ defer catfileCache.Stop()
+
+ objectReader, objectReaderCancel, err := catfileCache.ObjectReader(ctx, repo)
+ require.NoError(t, err)
+ defer objectReaderCancel()
+
+ inputIter, inputCh, nextCh := newChanObjectIterator()
+
+ it, err := CatfileObject(ctx, objectReader, inputIter)
+ require.NoError(t, err)
+
+ // We request a single object from the catfile process. Because the request queue is
+ // not flushed after every object this means that the request is currently
+ // outstanding.
+ <-nextCh
+ inputCh <- git.ObjectID(lfsPointer1)
+
+ // Wait for the pipeline to request the next object.
+ <-nextCh
+
+ // We now cancel the context with the outstanding request. In the past, this used to
+ // block the downstream consumer of the object data. This is because of two reasons:
+ //
+ // - When the process is being cached then cancellation of the context doesn't cause
+ // the process to get killed. So consequentially, the process would sit around
+ // waiting for input.
+ // - We didn't flush the queue when the context was cancelled, so the buffered input
+ // never arrived at the process.
+ cancel()
+
+ // Now we queue another request that should cause the pipeline to fail.
+ inputCh <- git.ObjectID(lfsPointer1)
+
+ // Reading the object should now fail because the context got cancelled, but it
+ // definitely shouldn't block like it did earlier.
+ require.False(t, it.Next())
+ require.Equal(t, context.Canceled, it.Err())
+ })
}