From 9d7619f1e37d8427c4f9b68f2544ec4cf66a51e9 Mon Sep 17 00:00:00 2001 From: Mickael Bourgois Date: Thu, 19 Mar 2026 00:41:41 +0100 Subject: [PATCH] CLDSRV-835: Retry flaky upload socket hang up ``` 1) DELETE object With default signature with multipart upload "before all" hook for "should delete a object uploaded in parts successfully": TimeoutError: socket hang up ``` --- .../aws-node-sdk/test/object/deleteObject.js | 28 +++++++++++++------ 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/tests/functional/aws-node-sdk/test/object/deleteObject.js b/tests/functional/aws-node-sdk/test/object/deleteObject.js index 17dcf0dfd6..c6ca70acab 100644 --- a/tests/functional/aws-node-sdk/test/object/deleteObject.js +++ b/tests/functional/aws-node-sdk/test/object/deleteObject.js @@ -43,17 +43,27 @@ describe('DELETE object', () => { process.stdout.write('uploading parts\n'); uploadId = createRes.UploadId; + // Concurrent uploads help trigger flakiness with "TimeoutError: + // socket hang up" due to a keep-alive race: the server closes + // an idle connection just as the client picks it from the pool. + const uploadWithRetry = (params, attempt = 0) => + s3.send(new UploadPartCommand(params)).catch(err => { + if (attempt < 3) { + process.stdout.write(`Retrying UploadPart ${params.PartNumber} ` + + `(attempt ${attempt + 1}/3): ${err}\n`); + return uploadWithRetry(params, attempt + 1); + } + throw err; + }); const uploads = []; for (let i = 1; i <= 3; i++) { - uploads.push( - s3.send(new UploadPartCommand({ - Bucket: bucketName, - Key: objectName, - PartNumber: i, - Body: testfile, - UploadId: uploadId, - })) - ); + uploads.push(uploadWithRetry({ + Bucket: bucketName, + Key: objectName, + PartNumber: i, + Body: testfile, + UploadId: uploadId, + })); } const uploadResults = await Promise.all(uploads);