diff --git a/api/handler/put_test.go b/api/handler/put_test.go index 3b88c13..7ea41ae 100644 --- a/api/handler/put_test.go +++ b/api/handler/put_test.go @@ -4,16 +4,13 @@ import ( "bytes" "context" "crypto/md5" - "crypto/rand" "encoding/base64" "encoding/hex" "encoding/json" - "errors" "io" "mime/multipart" "net/http" "net/http/httptest" - "runtime" "strconv" "strings" "testing" @@ -179,24 +176,6 @@ func TestPutObjectWithStreamBodyError(t *testing.T) { checkNotFound(t, tc, bktName, objName, emptyVersion) } -func TestPutObjectWithWrapReaderDiscardOnError(t *testing.T) { - tc := prepareHandlerContext(t) - - bktName, objName := "bucket-for-put", "object-for-put" - createTestBucket(tc, bktName) - - content := make([]byte, 128*1024) - _, err := rand.Read(content) - require.NoError(t, err) - - w, r := prepareTestPayloadRequest(tc, bktName, objName, bytes.NewReader(content)) - tc.tp.SetObjectPutError(objName, errors.New("some error")) - numGoroutineBefore := runtime.NumGoroutine() - tc.Handler().PutObjectHandler(w, r) - numGoroutineAfter := runtime.NumGoroutine() - require.Equal(t, numGoroutineBefore, numGoroutineAfter, "goroutines shouldn't leak during put object") -} - func TestPutObjectWithInvalidContentMD5(t *testing.T) { tc := prepareHandlerContext(t) tc.config.md5Enabled = true diff --git a/api/layer/object_test.go b/api/layer/object_test.go index dab69a4..2666577 100644 --- a/api/layer/object_test.go +++ b/api/layer/object_test.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/rand" "crypto/sha256" + "errors" "io" "testing" @@ -27,3 +28,25 @@ func TestWrapReader(t *testing.T) { require.Equal(t, src, dst) require.Equal(t, h[:], streamHash.Sum(nil)) } + +func TestGoroutinesDontLeakInPutAndHash(t *testing.T) { + tc := prepareContext(t) + l, ok := tc.layer.(*layer) + require.True(t, ok) + + content := make([]byte, 128*1024) + _, err := rand.Read(content) + require.NoError(t, err) + payload := bytes.NewReader(content) + + prm := PrmObjectCreate{ + Filepath: tc.obj, + Payload: payload, + } + + expErr := errors.New("some error") + tc.testFrostFS.SetObjectPutError(tc.obj, expErr) + _, _, _, _, err = l.objectPutAndHash(tc.ctx, prm, tc.bktInfo) + require.ErrorIs(t, err, expErr) + require.Empty(t, payload.Len(), "body must be read out otherwise goroutines can leak in wrapReader") +}