Skip to content

Commit c92fd34

Browse files
committed
fixup! bucket test async functions introduction
introducing the retry helper function
1 parent 87202c4 commit c92fd34

5 files changed

Lines changed: 88 additions & 97 deletions

File tree

tests/functional/raw-node/test/GCP/object/completeMpu.js

Lines changed: 22 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -49,29 +49,28 @@ function listObjectsPaginated(gcpClient, bucketName, cb) {
4949
params.Marker = marker;
5050
}
5151

52-
return gcpClient.listObjects(params, (err, res) => {
53-
if (err) {
54-
return cb(err);
55-
}
56-
57-
const contents = (res && res.Contents) || [];
58-
objects.push(...contents);
59-
60-
const isTruncated = Boolean(res && res.IsTruncated);
61-
if (!isTruncated) {
62-
return cb(null, objects);
63-
}
64-
65-
// AWS listObjects(V1) pagination: prefer NextMarker, fallback to last key.
66-
marker = (res && res.NextMarker) ||
67-
(contents.length ? contents[contents.length - 1].Key : undefined);
68-
69-
if (!marker) {
70-
return cb(null, objects);
71-
}
72-
73-
return _list();
74-
});
52+
const command = new ListObjectsCommand(params);
53+
return gcpClient.send(command)
54+
.then(res => {
55+
const contents = (res && res.Contents) || [];
56+
objects.push(...contents);
57+
58+
const isTruncated = Boolean(res && res.IsTruncated);
59+
if (!isTruncated) {
60+
return cb(null, objects);
61+
}
62+
63+
// AWS listObjects(V1) pagination: prefer NextMarker, fallback to last key.
64+
marker = (res && res.NextMarker) ||
65+
(contents.length ? contents[contents.length - 1].Key : undefined);
66+
67+
if (!marker) {
68+
return cb(null, objects);
69+
}
70+
71+
return _list();
72+
})
73+
.catch(err => cb(err));
7574
}
7675

7776
return _list();
@@ -100,19 +99,6 @@ describe('GCP: Complete MPU', function testSuite() {
10099
before(done => {
101100
config = getRealAwsConfig(credentialOne);
102101
gcpClient = new GCP(config);
103-
gcpClient.listObjects = (params, callback) => {
104-
const command = new ListObjectsCommand(params);
105-
return gcpClient.send(command)
106-
.then(data => callback(null, data))
107-
.catch(err => {
108-
if (err && err.$metadata && err.$metadata.httpStatusCode &&
109-
err.statusCode === undefined) {
110-
// eslint-disable-next-line no-param-reassign
111-
err.statusCode = err.$metadata.httpStatusCode;
112-
}
113-
return callback(err);
114-
});
115-
};
116102
async.eachSeries(Object.values(bucketNames),
117103
(bucket, next) => {
118104
const cmd = new CreateBucketCommand({ Bucket: bucket.Name });

tests/functional/raw-node/test/GCP/object/deleteMpu.js

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ const async = require('async');
33
const arsenal = require('arsenal');
44
const { ListObjectsCommand } = require('@aws-sdk/client-s3');
55
const { GCP } = arsenal.storage.data.external.GCP;
6-
const { gcpMpuSetup, genUniqID } =
6+
const { gcpMpuSetup, genUniqID, gcpRetry } =
77
require('../../../utils/gcpUtils');
88
const { getRealAwsConfig } =
99
require('../../../../aws-node-sdk/test/support/awsConfig');
@@ -57,32 +57,17 @@ describe('GCP: Abort MPU', function testSuite() {
5757
});
5858
};
5959

60-
const maxAttempts = 3;
6160
const buckets = Object.values(bucketNames);
62-
const createBuckets = attempt => {
63-
async.eachSeries(buckets,
64-
(bucket, next) => {
65-
const cmd = new CreateBucketCommand({ Bucket: bucket.Name });
66-
gcpClient.send(cmd)
67-
.then(() => next())
68-
.catch(err => {
69-
process.stdout.write(
70-
`err in creating bucket (attempt ${attempt + 1}) ${err}\n`);
71-
return next(err);
72-
});
73-
},
74-
err => {
75-
if (err && (err.name === 'SlowDown'
76-
|| err.$metadata?.httpStatusCode === 429)
77-
&& attempt < maxAttempts - 1) {
78-
const delay = Math.pow(2, attempt) * 1000;
79-
return setTimeout(() => createBuckets(attempt + 1), delay);
80-
}
81-
return done(err);
82-
});
83-
};
84-
85-
createBuckets(0);
61+
async.eachSeries(
62+
buckets,
63+
(bucket, next) => gcpRetry(
64+
gcpClient,
65+
() => new CreateBucketCommand({ Bucket: bucket.Name }),
66+
null,
67+
next,
68+
),
69+
done,
70+
);
8671
});
8772

8873
after(done => {

tests/functional/raw-node/test/GCP/object/getTagging.js

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
const assert = require('assert');
22
const arsenal = require('arsenal');
33
const { GCP } = arsenal.storage.data.external.GCP;
4-
const { genGetTagObj, genUniqID } =
4+
const { genGetTagObj, genUniqID, gcpRetry } =
55
require('../../../utils/gcpUtils');
66
const { getRealAwsConfig } =
77
require('../../../../aws-node-sdk/test/support/awsConfig');
@@ -21,33 +21,14 @@ describe('GCP: GET Object Tagging', () => {
2121
let gcpClient;
2222
let bucketCreated = false;
2323

24-
before(done => {
24+
before(async () => {
2525
config = getRealAwsConfig(credentialOne);
2626
gcpClient = new GCP(config);
27-
const maxAttempts = 3;
28-
29-
function createBucket(attempt) {
30-
const cmd = new CreateBucketCommand({ Bucket: bucketName });
31-
gcpClient.send(cmd)
32-
.then(() => {
33-
bucketCreated = true;
34-
return done();
35-
})
36-
.catch(err => {
37-
if ((err.name === 'SlowDown'
38-
|| err.$metadata?.httpStatusCode === 429)
39-
&& attempt < maxAttempts - 1) {
40-
const delay = Math.pow(2, attempt) * 1000;
41-
process.stdout.write(
42-
`SlowDown creating bucket, retrying in ${delay}ms (attempt ${attempt + 1})\n`);
43-
return setTimeout(() => createBucket(attempt + 1), delay);
44-
}
45-
process.stdout.write(`err in creating bucket ${err}`);
46-
return done(err);
47-
});
48-
}
49-
50-
createBucket(0);
27+
await gcpRetry(
28+
gcpClient,
29+
() => new CreateBucketCommand({ Bucket: bucketName }),
30+
);
31+
bucketCreated = true;
5132
});
5233

5334
beforeEach(function beforeFn(done) {

tests/functional/raw-node/test/GCP/object/putTagging.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ const assert = require('assert');
22
const async = require('async');
33
const arsenal = require('arsenal');
44
const { GCP } = arsenal.storage.data.external.GCP;
5-
const { genPutTagObj, genUniqID } =
5+
const { genPutTagObj, genUniqID, gcpRetry } =
66
require('../../../utils/gcpUtils');
77
const { getRealAwsConfig } =
88
require('../../../../aws-node-sdk/test/support/awsConfig');
@@ -20,16 +20,13 @@ describe('GCP: PUT Object Tagging', () => {
2020
let config;
2121
let gcpClient;
2222

23-
before(done => {
23+
before(async () => {
2424
config = getRealAwsConfig(credentialOne);
2525
gcpClient = new GCP(config);
26-
const cmd = new CreateBucketCommand({ Bucket: bucketName });
27-
gcpClient.send(cmd)
28-
.then(() => done())
29-
.catch(err => {
30-
process.stdout.write(`err in creating bucket ${err}`);
31-
return done(err);
32-
});
26+
await gcpRetry(
27+
gcpClient,
28+
() => new CreateBucketCommand({ Bucket: bucketName }),
29+
);
3330
});
3431

3532
beforeEach(function beforeFn(done) {

tests/functional/raw-node/utils/gcpUtils.js

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,50 @@
11
const async = require('async');
22
const assert = require('assert');
3+
const { callbackify } = require('util');
34
const { v4: uuidv4 } = require('uuid');
45

56
const genUniqID = () => uuidv4().replace(/-/g, '');
67

8+
const defaultShouldRetry = err =>
9+
err && (err.name === 'SlowDown'|| err.$metadata?.httpStatusCode === 429);
10+
11+
async function gcpRetry(gcpClient, makeCommand, retryOptions, cb) {
12+
if (cb) {
13+
return callbackify(() => gcpRetry(gcpClient, makeCommand,
14+
retryOptions))(cb);
15+
}
16+
17+
const {
18+
maxAttempts = 3,
19+
shouldRetry = defaultShouldRetry,
20+
getDelayMs = attempt => Math.pow(2, attempt) * 1000,
21+
} = retryOptions || {};
22+
23+
let lastError;
24+
25+
for (let attempt = 0; attempt < maxAttempts; attempt++) {
26+
try {
27+
const cmd = typeof makeCommand === 'function' ?
28+
makeCommand() : makeCommand;
29+
30+
return await gcpClient.send(cmd);
31+
} catch (err) {
32+
lastError = err;
33+
if (!shouldRetry(err, attempt) || attempt === maxAttempts - 1) {
34+
throw err;
35+
}
36+
const delay = getDelayMs(attempt);
37+
process.stdout.write(
38+
'Retryable error from GCP, retrying in ' +
39+
`${delay}ms (attempt ${attempt + 1}): ${err}\n`);
40+
41+
await new Promise(resolve => setTimeout(resolve, delay));
42+
}
43+
}
44+
45+
throw lastError;
46+
}
47+
748
// mpu test helpers
849
function gcpMpuSetup(params, callback) {
950
const { gcpClient, bucketNames, key, partCount, partSize } = params;
@@ -118,4 +159,5 @@ module.exports = {
118159
genGetTagObj,
119160
genDelTagObj,
120161
genUniqID,
162+
gcpRetry,
121163
};

0 commit comments

Comments
 (0)