Skip to content

Commit 4292393

Browse files
committed
utapi tests sdk migration
1 parent 403c41c commit 4292393

File tree

1 file changed

+140
-111
lines changed

1 file changed

+140
-111
lines changed

tests/utapi/awsNodeSdk.js

Lines changed: 140 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -1,159 +1,194 @@
11
const async = require('async');
22
const assert = require('assert');
3-
const { S3 } = require('aws-sdk');
3+
const { createHash } = require('crypto');
4+
const {
5+
S3Client,
6+
CreateBucketCommand,
7+
DeleteBucketCommand,
8+
PutObjectCommand,
9+
DeleteObjectCommand,
10+
DeleteObjectsCommand,
11+
CopyObjectCommand,
12+
PutBucketVersioningCommand,
13+
CreateMultipartUploadCommand,
14+
UploadPartCommand,
15+
CompleteMultipartUploadCommand,
16+
ListObjectVersionsCommand,
17+
GetObjectCommand,
18+
} = require('@aws-sdk/client-s3');
419

520
const MockUtapi = require('../utilities/mock/Utapi');
621
const getConfig = require('../functional/aws-node-sdk/test/support/config');
722
const WAIT_MS = 100;
823
let s3Client = null;
924

25+
/**
26+
* Creates an S3 client that uses MD5 checksums for DeleteObjects operations
27+
* Based on https://github.com/aws/aws-sdk-js-v3/blob/main/supplemental-docs/MD5_FALLBACK.md
28+
*/
29+
function createS3ClientWithMD5(configuration = {}) {
30+
const client = new S3Client(configuration);
31+
32+
client.middlewareStack.add(
33+
(next, context) => async args => {
34+
const needsMD5 = context.commandName === 'DeleteObjectsCommand' ||
35+
context.commandName === 'UploadPartCommand' ||
36+
context.commandName === 'CompleteMultipartUploadCommand';
37+
38+
if (!needsMD5) {
39+
return next(args);
40+
}
41+
42+
const headers = args.request.headers;
43+
44+
// Remove any checksum headers
45+
Object.keys(headers).forEach(header => {
46+
if (
47+
header.toLowerCase().startsWith('x-amz-checksum-') ||
48+
header.toLowerCase().startsWith('x-amz-sdk-checksum-')
49+
) {
50+
delete headers[header];
51+
}
52+
});
53+
54+
// Add MD5
55+
if (args.request.body) {
56+
const bodyContent = Buffer.from(args.request.body);
57+
// Create a new hash instance for each request
58+
headers['Content-MD5'] = createHash('md5').update(bodyContent).digest('base64');
59+
}
60+
61+
return await next(args);
62+
},
63+
{
64+
step: 'build',
65+
}
66+
);
67+
return client;
68+
}
69+
1070
function wait(timeoutMs, cb) {
1171
setTimeout(cb, timeoutMs);
1272
}
73+
1374
function createBucket(bucket, cb) {
14-
return s3Client.createBucket({
15-
Bucket: bucket,
16-
}, (err, data) => {
17-
assert.ifError(err);
18-
return cb(err, data);
19-
});
75+
return s3Client.send(new CreateBucketCommand({ Bucket: bucket }))
76+
.then(data => cb(null, data))
77+
.catch(cb);
2078
}
79+
2180
function deleteBucket(bucket, cb) {
22-
return s3Client.deleteBucket({
23-
Bucket: bucket,
24-
}, err => {
25-
assert.ifError(err);
26-
return cb(err);
27-
});
81+
return s3Client.send(new DeleteBucketCommand({ Bucket: bucket }))
82+
.then(() => cb())
83+
.catch(cb);
2884
}
85+
2986
function putObject(bucket, key, size, cb) {
30-
return s3Client.putObject({
87+
const body = Buffer.alloc(size);
88+
const params = {
3189
Bucket: bucket,
3290
Key: key,
33-
Body: Buffer.alloc(size),
34-
}, (err, data) => {
35-
assert.ifError(err);
36-
return cb(err, data);
37-
});
91+
Body: body,
92+
};
93+
return s3Client.send(new PutObjectCommand(params))
94+
.then(data => cb(null, data))
95+
.catch(cb);
3896
}
97+
3998
function deleteObject(bucket, key, cb) {
40-
return s3Client.deleteObject({
41-
Bucket: bucket,
42-
Key: key,
43-
}, err => {
44-
assert.ifError(err);
45-
return cb(err);
46-
});
99+
return s3Client.send(new DeleteObjectCommand({ Bucket: bucket, Key: key }))
100+
.then(() => cb())
101+
.catch(cb);
47102
}
103+
48104
function deleteObjects(bucket, keys, cb) {
49-
const objects = keys.map(key => {
50-
const keyObj = {
51-
Key: key,
52-
};
53-
return keyObj;
54-
});
105+
const objects = keys.map(key => ({ Key: key }));
106+
const deleteRequest = { Objects: objects, Quiet: true };
55107
const params = {
56108
Bucket: bucket,
57-
Delete: {
58-
Objects: objects,
59-
Quiet: true,
60-
},
109+
Delete: deleteRequest,
61110
};
62-
return s3Client.deleteObjects(params, err => {
63-
assert.ifError(err);
64-
return cb(err);
65-
});
111+
return s3Client.send(new DeleteObjectsCommand(params))
112+
.then(() => cb())
113+
.catch(cb);
66114
}
115+
67116
function copyObject(bucket, key, cb) {
68-
return s3Client.copyObject({
69-
Bucket: bucket,
70-
CopySource: `/${bucket}/${key}`,
71-
Key: `${key}-copy`,
72-
}, err => {
73-
assert.ifError(err);
74-
return cb(err);
75-
});
117+
const params = { Bucket: bucket, CopySource: `${bucket}/${key}`, Key: `${key}-copy` };
118+
return s3Client.send(new CopyObjectCommand(params))
119+
.then(() => cb())
120+
.catch(cb);
76121
}
122+
77123
function enableVersioning(bucket, enable, cb) {
78-
const versioningStatus = {
79-
Status: enable ? 'Enabled' : 'Disabled',
80-
};
81-
return s3Client.putBucketVersioning({
82-
Bucket: bucket,
83-
VersioningConfiguration: versioningStatus,
84-
}, err => {
85-
assert.ifError(err);
86-
return cb(err);
87-
});
124+
const versioningStatus = { Status: enable ? 'Enabled' : 'Disabled' };
125+
const params = { Bucket: bucket, VersioningConfiguration: versioningStatus };
126+
return s3Client.send(new PutBucketVersioningCommand(params))
127+
.then(() => cb())
128+
.catch(cb);
88129
}
130+
89131
function deleteVersionList(versionList, bucket, callback) {
90132
if (versionList === undefined || versionList.length === 0) {
91133
return callback();
92134
}
93-
const params = { Bucket: bucket, Delete: { Objects: [] } };
135+
const deleteRequest = { Objects: [] };
94136
versionList.forEach(version => {
95-
params.Delete.Objects.push({
96-
Key: version.Key, VersionId: version.VersionId,
97-
});
137+
deleteRequest.Objects.push({ Key: version.Key, VersionId: version.VersionId });
98138
});
99-
100-
return s3Client.deleteObjects(params, callback);
139+
const params = {
140+
Bucket: bucket,
141+
Delete: deleteRequest,
142+
};
143+
return s3Client.send(new DeleteObjectsCommand(params))
144+
.then(() => callback())
145+
.catch(callback);
101146
}
147+
102148
function removeAllVersions(params, callback) {
103149
const bucket = params.Bucket;
104150
async.waterfall([
105-
cb => s3Client.listObjectVersions(params, cb),
106-
(data, cb) => deleteVersionList(data.DeleteMarkers, bucket,
107-
err => cb(err, data)),
108-
(data, cb) => deleteVersionList(data.Versions, bucket,
109-
err => cb(err, data)),
151+
cb => s3Client.send(new ListObjectVersionsCommand(params))
152+
.then(data => cb(null, data))
153+
.catch(cb),
154+
(data, cb) => deleteVersionList(data.DeleteMarkers, bucket, err => cb(err, data)),
155+
(data, cb) => deleteVersionList(data.Versions, bucket, err => cb(err, data)),
110156
(data, cb) => {
111157
if (data.IsTruncated) {
112-
const params = {
113-
Bucket: bucket,
114-
KeyMarker: data.NextKeyMarker,
115-
VersionIdMarker: data.NextVersionIdMarker,
116-
};
158+
const params = { Bucket: bucket, KeyMarker: data.NextKeyMarker,
159+
VersionIdMarker: data.NextVersionIdMarker };
117160
return removeAllVersions(params, cb);
118161
}
119162
return cb();
120163
},
121164
], callback);
122165
}
166+
123167
function objectMPU(bucket, key, parts, partSize, callback) {
124168
let ETags = [];
125169
let uploadId = null;
126170
const partNumbers = Array.from(Array(parts).keys());
127-
const initiateMPUParams = {
128-
Bucket: bucket,
129-
Key: key,
130-
};
171+
const initiateMPUParams = { Bucket: bucket, Key: key };
131172
return async.waterfall([
132-
next => s3Client.createMultipartUpload(initiateMPUParams,
133-
(err, data) => {
134-
if (err) {
135-
return next(err);
136-
}
173+
next => s3Client.send(new CreateMultipartUploadCommand(initiateMPUParams))
174+
.then(data => {
137175
uploadId = data.UploadId;
138176
return next();
139-
}),
177+
})
178+
.catch(next),
140179
next =>
141180
async.mapLimit(partNumbers, 1, (partNumber, callback) => {
181+
const body = Buffer.alloc(partSize);
142182
const uploadPartParams = {
143183
Bucket: bucket,
144184
Key: key,
145185
PartNumber: partNumber + 1,
146186
UploadId: uploadId,
147-
Body: Buffer.alloc(partSize),
187+
Body: body,
148188
};
149-
150-
return s3Client.uploadPart(uploadPartParams,
151-
(err, data) => {
152-
if (err) {
153-
return callback(err);
154-
}
155-
return callback(null, data.ETag);
156-
});
189+
return s3Client.send(new UploadPartCommand(uploadPartParams))
190+
.then(data => callback(null, data.ETag))
191+
.catch(callback);
157192
}, (err, results) => {
158193
if (err) {
159194
return next(err);
@@ -162,33 +197,28 @@ function objectMPU(bucket, key, parts, partSize, callback) {
162197
return next();
163198
}),
164199
next => {
200+
const completeRequest = { Parts: partNumbers.map(n => ({ ETag: ETags[n], PartNumber: n + 1 })) };
165201
const params = {
166202
Bucket: bucket,
167203
Key: key,
168-
MultipartUpload: {
169-
Parts: partNumbers.map(n => ({
170-
ETag: ETags[n],
171-
PartNumber: n + 1,
172-
})),
173-
},
204+
MultipartUpload: completeRequest,
174205
UploadId: uploadId,
175206
};
176-
return s3Client.completeMultipartUpload(params, next);
207+
return s3Client.send(new CompleteMultipartUploadCommand(params))
208+
.then(data => next(null, data))
209+
.catch(next);
177210
},
178211
], callback);
179212
}
213+
180214
function removeVersions(buckets, cb) {
181-
return async.each(buckets,
182-
(bucket, done) => removeAllVersions({ Bucket: bucket }, done), cb);
215+
return async.each(buckets, (bucket, done) => removeAllVersions({ Bucket: bucket }, done), cb);
183216
}
217+
184218
function getObject(bucket, key, cb) {
185-
return s3Client.getObject({
186-
Bucket: bucket,
187-
Key: key,
188-
}, (err, data) => {
189-
assert.ifError(err);
190-
return cb(err, data);
191-
});
219+
return s3Client.send(new GetObjectCommand({ Bucket: bucket, Key: key }))
220+
.then(data => cb(null, data))
221+
.catch(cb);
192222
}
193223

194224
describe('utapi v2 metrics incoming and outgoing bytes', function t() {
@@ -204,8 +234,7 @@ describe('utapi v2 metrics incoming and outgoing bytes', function t() {
204234
}
205235

206236
before(() => {
207-
const config = getConfig('default', { signatureVersion: 'v4' });
208-
s3Client = new S3(config);
237+
s3Client = createS3ClientWithMD5(getConfig('default'));
209238
utapi.start();
210239
});
211240
afterEach(() => {

0 commit comments

Comments
 (0)