diff --git a/tests/functional/aws-node-sdk/test/legacy/authV2QueryTests.js b/tests/functional/aws-node-sdk/test/legacy/authV2QueryTests.js index 4a2b7b0567..90eb2f9343 100644 --- a/tests/functional/aws-node-sdk/test/legacy/authV2QueryTests.js +++ b/tests/functional/aws-node-sdk/test/legacy/authV2QueryTests.js @@ -1,7 +1,15 @@ const assert = require('assert'); const process = require('node:process'); const cp = require('child_process'); -const { S3 } = require('aws-sdk'); +const { + S3Client, + CreateBucketCommand, + PutObjectCommand, + GetObjectCommand, + DeleteObjectCommand, + DeleteBucketCommand, +} = require('@aws-sdk/client-s3'); +const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); const getConfig = require('../support/config'); const provideRawOutput = require('../../lib/utility/provideRawOutput'); @@ -34,81 +42,100 @@ describe('aws-node-sdk v2auth query tests', function testSuite() { before(() => { const config = getConfig('default', { signatureVersion: 'v2' }); - - s3 = new S3(config); + s3 = new S3Client(config); }); // AWS allows an expiry further in the future // 604810 seconds is higher that the Expires time limit: 604800 seconds // ( seven days) itSkipAWS('should return an error code if expires header is too far ' + - 'in the future', done => { - const params = { Bucket: bucket, Expires: 604810 }; - const url = s3.getSignedUrl('createBucket', params); - provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { - assert.strictEqual(httpCode, '403 FORBIDDEN'); - done(); + 'in the future', async () => { + + // First, get a valid signed URL with maximum allowed expiry + const command = new CreateBucketCommand({ Bucket: bucket }); + const validUrl = await getSignedUrl(s3, command, { expiresIn: 604800 }); // Exactly 7 days + + // Manually modify the URL to have a longer expiry + const urlObj = new URL(validUrl); + const futureExpiry = Math.floor(Date.now() / 1000) + 604810; // 10 seconds more than limit + urlObj.searchParams.set('Expires', futureExpiry.toString()); + const invalidUrl = urlObj.toString(); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'PUT', invalidUrl], httpCode => { + assert.strictEqual(httpCode, '403 FORBIDDEN'); + resolve(); + }); }); }); - it('should return an error code if request occurs after expiry', - done => { - const params = { Bucket: bucket, Expires: 1 }; - const url = s3.getSignedUrl('createBucket', params); + it('should return an error code if request occurs after expiry', async () => { + const command = new CreateBucketCommand({ Bucket: bucket }); + const url = await getSignedUrl(s3, command, { expiresIn: 1 }); + await new Promise(resolve => { setTimeout(() => { provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { assert.strictEqual(httpCode, '403 FORBIDDEN'); - done(); + resolve(); }); }, 1500); }); + }); - it('should create a bucket', done => { - const params = { Bucket: bucket, Expires: almostOutsideTime }; - const url = s3.getSignedUrl('createBucket', params); - provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { - assert.strictEqual(httpCode, '200 OK'); - done(); + it('should create a bucket', async () => { + const command = new CreateBucketCommand({ Bucket: bucket }); + const url = await getSignedUrl(s3, command, { expiresIn: almostOutsideTime }); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { + assert.strictEqual(httpCode, '200 OK'); + resolve(); + }); }); }); - it('should put an object', done => { - const params = { Bucket: bucket, Key: 'key', Expires: - almostOutsideTime }; - const url = s3.getSignedUrl('putObject', params); - provideRawOutput(['-verbose', '-X', 'PUT', url, - '--upload-file', 'uploadFile'], httpCode => { - assert.strictEqual(httpCode, '200 OK'); - done(); + it('should put an object', async () => { + const command = new PutObjectCommand({ Bucket: bucket, Key: 'key' }); + const url = await getSignedUrl(s3, command, { expiresIn: almostOutsideTime }); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'PUT', url, + '--upload-file', 'uploadFile'], httpCode => { + assert.strictEqual(httpCode, '200 OK'); + resolve(); + }); + }); + }); + + it('should put an object with an acl setting and a storage class setting', async () => { + // This will test that upper case query parameters and lowercase + // query parameters (i.e., 'x-amz-acl') are being sorted properly. + // This will also test that query params that contain "x-amz-" + // are being added to the canonical headers list in our string + // to sign. + const command = new PutObjectCommand({ + Bucket: bucket, + Key: 'key', + ACL: 'public-read', + StorageClass: 'STANDARD' + }); + const url = await getSignedUrl(s3, command); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'PUT', url, + '--upload-file', 'uploadFile'], httpCode => { + assert.strictEqual(httpCode, '200 OK'); + resolve(); + }); }); }); - it('should put an object with an acl setting and a storage class setting', - done => { - // This will test that upper case query parameters and lowercase - // query parameters (i.e., 'x-amz-acl') are being sorted properly. - // This will also test that query params that contain "x-amz-" - // are being added to the canonical headers list in our string - // to sign. - const params = { Bucket: bucket, Key: 'key', - ACL: 'public-read', StorageClass: 'STANDARD' }; - const url = s3.getSignedUrl('putObject', params); - provideRawOutput(['-verbose', '-X', 'PUT', url, - '--upload-file', 'uploadFile'], httpCode => { - assert.strictEqual(httpCode, '200 OK'); - done(); - }); - }); - - - it('should get an object', done => { - const params = { Bucket: bucket, Key: 'key', Expires: - almostOutsideTime }; - const url = s3.getSignedUrl('getObject', params); - provideRawOutput(['-verbose', '-o', 'download', url], httpCode => { - assert.strictEqual(httpCode, '200 OK'); - done(); + + it('should get an object', async () => { + const command = new GetObjectCommand({ Bucket: bucket, Key: 'key' }); + const url = await getSignedUrl(s3, command, { expiresIn: almostOutsideTime }); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-o', 'download', url], httpCode => { + assert.strictEqual(httpCode, '200 OK'); + resolve(); + }); }); }); @@ -118,25 +145,26 @@ describe('aws-node-sdk v2auth query tests', function testSuite() { }); }); - it('should delete an object', done => { - const params = { Bucket: bucket, Key: 'key', Expires: - almostOutsideTime }; - const url = s3.getSignedUrl('deleteObject', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { + it('should delete an object', async () => { + const command = new DeleteObjectCommand({ Bucket: bucket, Key: 'key' }); + const url = await getSignedUrl(s3, command, { expiresIn: almostOutsideTime }); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); + resolve(); }); + }); }); - it('should delete a bucket', done => { - const params = { Bucket: bucket, Expires: almostOutsideTime }; - const url = s3.getSignedUrl('deleteBucket', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { + it('should delete a bucket', async () => { + const command = new DeleteBucketCommand({ Bucket: bucket }); + const url = await getSignedUrl(s3, command, { expiresIn: almostOutsideTime }); + await new Promise(resolve => { + provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); + resolve(); }); + }); }); }); diff --git a/tests/functional/aws-node-sdk/test/legacy/authV4QueryTests.js b/tests/functional/aws-node-sdk/test/legacy/authV4QueryTests.js index 5e23e8284f..271c3a8de1 100644 --- a/tests/functional/aws-node-sdk/test/legacy/authV4QueryTests.js +++ b/tests/functional/aws-node-sdk/test/legacy/authV4QueryTests.js @@ -3,14 +3,23 @@ const process = require('node:process'); const cp = require('child_process'); const { parseString } = require('xml2js'); -const { S3 } = require('aws-sdk'); +const { + S3Client, + ListBucketsCommand, + CreateBucketCommand, + PutObjectCommand, + ListObjectsCommand, + GetObjectCommand, + DeleteObjectCommand, + DeleteBucketCommand, +} = require('@aws-sdk/client-s3'); +const { getSignedUrl } = require('@aws-sdk/s3-request-presigner'); const getConfig = require('../support/config'); const provideRawOutput = require('../../lib/utility/provideRawOutput'); const random = Math.round(Math.random() * 100).toString(); const bucket = `mybucket-${random}`; - function diff(putFile, receivedFile, done) { process.stdout.write(`diff ${putFile} ${receivedFile}\n`); cp.spawn('diff', [putFile, receivedFile]).on('exit', code => { @@ -30,36 +39,35 @@ describe('aws-node-sdk v4auth query tests', function testSuite() { this.timeout(60000); let s3; - // setup test before(() => { - const config = getConfig('default', { signatureVersion: 'v4' }); - - s3 = new S3(config); + const config = getConfig('default', {}); + s3 = new S3Client(config); }); - // emptyListing test - it('should do an empty bucket listing', done => { - const url = s3.getSignedUrl('listBuckets'); - provideRawOutput(['-verbose', url], httpCode => { + it('should do an empty bucket listing', async () => { + const url = await getSignedUrl(s3, new ListBucketsCommand({}), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', url], httpCode => { assert.strictEqual(httpCode, '200 OK'); - done(); - }); + resolve(); + })); }); - // createBucket test - it('should create a bucket', done => { + it('should create a bucket', async () => { const params = { Bucket: bucket }; - const url = s3.getSignedUrl('createBucket', params); - provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { + const url = await getSignedUrl( + s3, + new CreateBucketCommand(params), + { expiresIn: 900 } + ); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'PUT', url], httpCode => { assert.strictEqual(httpCode, '200 OK'); - done(); - }); + resolve(); + })); }); - // fullListing test - it('should do a bucket listing with result', done => { - const url = s3.getSignedUrl('listBuckets'); - provideRawOutput(['-verbose', url], (httpCode, rawOutput) => { + it('should do a bucket listing with result', async () => { + const url = await getSignedUrl(s3, new ListBucketsCommand({}), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', url], (httpCode, rawOutput) => { assert.strictEqual(httpCode, '200 OK'); parseString(rawOutput.stdout, (err, xml) => { if (err) { @@ -69,57 +77,54 @@ describe('aws-node-sdk v4auth query tests', function testSuite() { .Buckets[0].Bucket.map(item => item.Name[0]); const whereIsMyBucket = bucketNames.indexOf(bucket); assert(whereIsMyBucket > -1); - done(); + resolve(); }); - }); + })); }); - // putObject test - it('should put an object', done => { + it('should put an object', async () => { const params = { Bucket: bucket, Key: 'key' }; - const url = s3.getSignedUrl('putObject', params); - provideRawOutput(['-verbose', '-X', 'PUT', url, + const url = await getSignedUrl(s3, new PutObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'PUT', url, '--upload-file', 'uploadFile'], httpCode => { assert.strictEqual(httpCode, '200 OK'); - done(); - }); + resolve(); + })); + }); + + it('should put an object with an acl setting and a storage class setting', async () => { + const params = { + Bucket: bucket, + Key: 'key', + ACL: 'public-read', + StorageClass: 'STANDARD', + ContentType: 'text/plain', + }; + const url = await getSignedUrl(s3, new PutObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'PUT', url, + '--upload-file', 'uploadFile'], httpCode => { + assert.strictEqual(httpCode, '200 OK'); + resolve(); + })); }); - it('should put an object with an acl setting and a storage class setting', - done => { - // This will test that upper case query parameters and lowercase - // query parameters (i.e., 'x-amz-acl') are being sorted properly. - // This will also test that query params that contain "x-amz-" - // are being added to the canonical headers list in our string - // to sign. - const params = { Bucket: bucket, Key: 'key', - ACL: 'public-read', StorageClass: 'STANDARD', - ContentType: 'text/plain' }; - const url = s3.getSignedUrl('putObject', params); - provideRawOutput(['-verbose', '-X', 'PUT', url, - '--upload-file', 'uploadFile'], httpCode => { - assert.strictEqual(httpCode, '200 OK'); - done(); - }); - }); - - it('should put an object with native characters', done => { + it('should put an object with native characters', async () => { const Key = 'key-pâtisserie-中文-español-English-हिन्दी-العربية-' + 'português-বাংলা-русский-日本語-ਪੰਜਾਬੀ-한국어-தமிழ்'; const params = { Bucket: bucket, Key }; - const url = s3.getSignedUrl('putObject', params); - provideRawOutput(['-verbose', '-X', 'PUT', url, + const url = await getSignedUrl(s3, new PutObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'PUT', url, '--upload-file', 'uploadFile'], httpCode => { assert.strictEqual(httpCode, '200 OK'); - done(); - }); + resolve(); + })); }); // listObjects test - it('should list objects in bucket', done => { + it('should list objects in bucket', async () => { const params = { Bucket: bucket }; - const url = s3.getSignedUrl('listObjects', params); - provideRawOutput(['-verbose', url], (httpCode, rawOutput) => { + const url = await getSignedUrl(s3, new ListObjectsCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', url], (httpCode, rawOutput) => { assert.strictEqual(httpCode, '200 OK'); parseString(rawOutput.stdout, (err, result) => { if (err) { @@ -127,19 +132,19 @@ describe('aws-node-sdk v4auth query tests', function testSuite() { } assert.strictEqual(result.ListBucketResult .Contents[0].Key[0], 'key'); - done(); + resolve(); }); - }); + })); }); // getObject test - it('should get an object', done => { + it('should get an object', async () => { const params = { Bucket: bucket, Key: 'key' }; - const url = s3.getSignedUrl('getObject', params); - provideRawOutput(['-verbose', '-o', 'download', url], httpCode => { + const url = await getSignedUrl(s3, new GetObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-o', 'download', url], httpCode => { assert.strictEqual(httpCode, '200 OK'); - done(); - }); + resolve(); + })); }); it('downloaded file should equal file that was put', done => { @@ -149,55 +154,50 @@ describe('aws-node-sdk v4auth query tests', function testSuite() { }); // deleteObject test - it('should delete an object', done => { + it('should delete an object', async () => { const params = { Bucket: bucket, Key: 'key' }; - const url = s3.getSignedUrl('deleteObject', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { - assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); - }); + const url = await getSignedUrl(s3, new DeleteObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { + assert.strictEqual(httpCode, '204 NO CONTENT'); + resolve(); + })); }); - it('should return a 204 on delete of an already deleted object', done => { + it('should return a 204 on delete of an already deleted object', async () => { const params = { Bucket: bucket, Key: 'key' }; - const url = s3.getSignedUrl('deleteObject', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { - assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); - }); + const url = await getSignedUrl(s3, new DeleteObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { + assert.strictEqual(httpCode, '204 NO CONTENT'); + resolve(); + })); }); - it('should return 204 on delete of non-existing object', done => { + it('should return 204 on delete of non-existing object', async () => { const params = { Bucket: bucket, Key: 'randomObject' }; - const url = s3.getSignedUrl('deleteObject', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { - assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); - }); + const url = await getSignedUrl(s3, new DeleteObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { + assert.strictEqual(httpCode, '204 NO CONTENT'); + resolve(); + })); }); - it('should delete an object with native characters', done => { + it('should delete an object with native characters', async () => { const Key = 'key-pâtisserie-中文-español-English-हिन्दी-العربية-' + 'português-বাংলা-русский-日本語-ਪੰਜਾਬੀ-한국어-தமிழ்'; const params = { Bucket: bucket, Key }; - const url = s3.getSignedUrl('deleteObject', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { + const url = await getSignedUrl(s3, new DeleteObjectCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); - }); + resolve(); + })); }); - // deleteBucket test - it('should delete a bucket', done => { + it('should delete a bucket', async () => { const params = { Bucket: bucket }; - const url = s3.getSignedUrl('deleteBucket', params); - provideRawOutput(['-verbose', '-X', 'DELETE', url], - httpCode => { - assert.strictEqual(httpCode, '204 NO CONTENT'); - done(); - }); + const url = await getSignedUrl(s3, new DeleteBucketCommand(params), { expiresIn: 900 }); + await new Promise(resolve => provideRawOutput(['-verbose', '-X', 'DELETE', url], httpCode => { + assert.strictEqual(httpCode, '204 NO CONTENT'); + resolve(); + })); }); }); diff --git a/tests/functional/aws-node-sdk/test/legacy/tests.js b/tests/functional/aws-node-sdk/test/legacy/tests.js index eb8322b745..fd704f9014 100644 --- a/tests/functional/aws-node-sdk/test/legacy/tests.js +++ b/tests/functional/aws-node-sdk/test/legacy/tests.js @@ -1,6 +1,19 @@ const assert = require('assert'); const crypto = require('crypto'); -const { S3 } = require('aws-sdk'); +const { + S3Client, + ListBucketsCommand, + CreateBucketCommand, + DeleteBucketCommand, + CreateMultipartUploadCommand, + UploadPartCommand, + AbortMultipartUploadCommand, + ListPartsCommand, + CompleteMultipartUploadCommand, + PutObjectCommand, + GetObjectCommand, + DeleteObjectCommand, +} = require('@aws-sdk/client-s3'); const getConfig = require('../support/config'); const { testsRangeOnEmptyFile } = require('../../../../unit/helpers'); @@ -33,192 +46,134 @@ describe('aws-node-sdk test suite as registered user', function testSuite() { // setup test before(() => { const config = getConfig('default', { signatureVersion: 'v4' }); - - s3 = new S3(config); + s3 = new S3Client(config); }); // bucketListing test - it('should do bucket listing', done => { - s3.listBuckets((err, data) => { - if (err) { - return done(new Error(`error listing buckets: ${err}`)); - } - - assert(data.Buckets, 'No buckets Info sent back'); - assert(data.Owner, 'No owner Info sent back'); - assert(data.Owner.ID, 'Owner ID not sent back'); - assert(data.Owner.DisplayName, 'DisplayName not sent back'); - const owner = Object.keys(data.Owner); - assert.strictEqual(owner.length, 2, 'Too much fields in owner'); - return done(); - }); + it('should do bucket listing', async () => { + const data = await s3.send(new ListBucketsCommand({})); + assert(data.Buckets, 'No buckets Info sent back'); + assert(data.Owner, 'No owner Info sent back'); + assert(data.Owner.ID, 'Owner ID not sent back'); + assert(data.Owner.DisplayName, 'DisplayName not sent back'); + const owner = Object.keys(data.Owner); + assert.strictEqual(owner.length, 2, 'Too much fields in owner'); }); // createbucket test - it('should create a bucket', done => { - s3.createBucket({ Bucket: bucket }, err => { - if (err) { - return done(new Error(`error creating bucket: ${err}`)); - } - return done(); - }); + it('should create a bucket', async () => { + await s3.send(new CreateBucketCommand({ Bucket: bucket })); }); // createMPU test - it('should create a multipart upload', done => { - s3.createMultipartUpload({ Bucket: bucket, Key: objectKey }, - (err, data) => { - if (err) { - return done(new Error( - `error initiating multipart upload: ${err}`)); - } - assert.strictEqual(data.Bucket, bucket); - assert.strictEqual(data.Key, objectKey); - assert.ok(data.UploadId); - multipartUploadData.firstUploadId = data.UploadId; - return done(); - }); + it('should create a multipart upload', async () => { + const data = await s3.send(new CreateMultipartUploadCommand({ Bucket: bucket, Key: objectKey })); + assert.strictEqual(data.Bucket, bucket); + assert.strictEqual(data.Key, objectKey); + assert.ok(data.UploadId); + multipartUploadData.firstUploadId = data.UploadId; }); - it('should upload a part of a multipart upload to be aborted', + it('should upload a part of a multipart upload to be aborted', async () => { // uploadpart test - done => { - const params = { - Bucket: bucket, - Key: objectKey, - PartNumber: 1, - UploadId: multipartUploadData.firstUploadId, - Body: firstBufferBody, - }; - s3.uploadPart(params, (err, data) => { - if (err) { - return done(new Error(`error uploading a part: ${err}`)); - } - assert.strictEqual(data.ETag, `"${calculatedFirstPartHash}"`); - return done(); - }); - }); + const params = { + Bucket: bucket, + Key: objectKey, + PartNumber: 1, + UploadId: multipartUploadData.firstUploadId, + Body: firstBufferBody, + }; + const data = await s3.send(new UploadPartCommand(params)); + assert.strictEqual(data.ETag, `"${calculatedFirstPartHash}"`); + }); // abortMPU test - it('should abort a multipart upload', done => { + it('should abort a multipart upload', async () => { const params = { Bucket: bucket, Key: objectKey, UploadId: multipartUploadData.firstUploadId, }; - s3.abortMultipartUpload(params, (err, data) => { - if (err) { - return done(new Error( - `error aborting multipart upload: ${err}`)); - } - assert.ok(data); - return done(); - }); + const data = await s3.send(new AbortMultipartUploadCommand(params)); + assert.ok(data); }); // createMPU test - it('should upload a part of a multipart upload', done => { - s3.createMultipartUpload({ Bucket: bucket, Key: 'toComplete' }, - (err, data) => { - if (err) { - return done(new Error( - `error initiating multipart upload: ${err}`)); - } - const uploadId = data.UploadId; - multipartUploadData.secondUploadId = data.UploadId; - const params = { - Bucket: bucket, - Key: 'toComplete', - PartNumber: 1, - UploadId: uploadId, - Body: firstBufferBody, - }; - s3.uploadPart(params, (err, data) => { - if (err) { - return done( - new Error(`error uploading a part: ${err}`)); - } - assert.strictEqual(data.ETag, - `"${calculatedFirstPartHash}"`); - return done(); - }); - return undefined; - }); + it('should upload a part of a multipart upload', async () => { + const data = await s3.send(new CreateMultipartUploadCommand({ Bucket: bucket, Key: 'toComplete' })); + const uploadId = data.UploadId; + multipartUploadData.secondUploadId = data.UploadId; + const params = { + Bucket: bucket, + Key: 'toComplete', + PartNumber: 1, + UploadId: uploadId, + Body: firstBufferBody, + }; + const uploadData = await s3.send(new UploadPartCommand(params)); + assert.strictEqual(uploadData.ETag, `"${calculatedFirstPartHash}"`); }); - it('should upload a second part of a multipart upload', + it('should upload a second part of a multipart upload', async () => { // createMPU test - done => { - const params = { - Bucket: bucket, - Key: 'toComplete', - PartNumber: 2, - UploadId: multipartUploadData.secondUploadId, - Body: secondBufferBody, - }; - s3.uploadPart(params, (err, data) => { - if (err) { - return done(new Error(`error uploading a part: ${err}`)); - } - assert.strictEqual(data.ETag, `"${calculatedSecondPartHash}"`); - return done(); - }); - }); + const params = { + Bucket: bucket, + Key: 'toComplete', + PartNumber: 2, + UploadId: multipartUploadData.secondUploadId, + Body: secondBufferBody, + }; + const data = await s3.send(new UploadPartCommand(params)); + assert.strictEqual(data.ETag, `"${calculatedSecondPartHash}"`); + }); // listparts test - it('should list the parts of a multipart upload', done => { + it('should list the parts of a multipart upload', async () => { const params = { Bucket: bucket, Key: 'toComplete', UploadId: multipartUploadData.secondUploadId, }; - s3.listParts(params, (err, data) => { - if (err) { - return done(new Error(`error listing parts: ${err}`)); - } - assert.strictEqual(data.Bucket, bucket); - assert.strictEqual(data.Key, 'toComplete'); - assert.strictEqual(data.UploadId, multipartUploadData - .secondUploadId); - assert.strictEqual(data.IsTruncated, false); - assert.strictEqual(data.Parts[0].PartNumber, 1); - assert.strictEqual(data.Parts[0].ETag, - `"${calculatedFirstPartHash}"`); - assert.strictEqual(data.Parts[0].Size, 5242880); - assert.strictEqual(data.Parts[1].PartNumber, 2); - assert.strictEqual(data.Parts[1].ETag, - `"${calculatedSecondPartHash}"`); - assert.strictEqual(data.Parts[1].Size, 5242880); - // Must disable for now when running with Vault - // since will need to pull actual ARN and canonicalId - // assert.strictEqual(data.Initiator.ID, accessKey1ARN); - // Note that for in memory implementation, "accessKey1" - // is both the access key and the canonicalId so this - // call works. For real implementation with vault, - // will need the canonicalId. - // assert.strictEqual(data.Owner.ID, config.accessKeyId); - assert.strictEqual(data.StorageClass, 'STANDARD'); - return {}; - }); - return done(); + const data = await s3.send(new ListPartsCommand(params)); + assert.strictEqual(data.Bucket, bucket); + assert.strictEqual(data.Key, 'toComplete'); + assert.strictEqual(data.UploadId, multipartUploadData.secondUploadId); + assert.strictEqual(data.IsTruncated, false); + assert.strictEqual(data.Parts[0].PartNumber, 1); + assert.strictEqual(data.Parts[0].ETag, `"${calculatedFirstPartHash}"`); + assert.strictEqual(data.Parts[0].Size, 5242880); + assert.strictEqual(data.Parts[1].PartNumber, 2); + assert.strictEqual(data.Parts[1].ETag, `"${calculatedSecondPartHash}"`); + assert.strictEqual(data.Parts[1].Size, 5242880); + // Must disable for now when running with Vault + // since will need to pull actual ARN and canonicalId + // assert.strictEqual(data.Initiator.ID, accessKey1ARN); + // Note that for in memory implementation, "accessKey1" + // is both the access key and the canonicalId so this + // call works. For real implementation with vault, + // will need the canonicalId. + // assert.strictEqual(data.Owner.ID, config.accessKeyId); + assert.strictEqual(data.StorageClass, 'STANDARD'); }); it('should return an error if do not provide correct ' + // completempu test - 'xml when completing a multipart upload', done => { + 'xml when completing a multipart upload', async () => { const params = { Bucket: bucket, Key: 'toComplete', UploadId: multipartUploadData.secondUploadId, }; - s3.completeMultipartUpload(params, err => { - assert.strictEqual(err.code, 'MalformedXML'); - return done(); - }); + try { + await s3.send(new CompleteMultipartUploadCommand(params)); + throw new Error('Expected MalformedXML error'); + } catch (err) { + assert.strictEqual(err.Code, 'MalformedXML'); + } }); // completempu test - it('should complete a multipart upload', done => { + it('should complete a multipart upload', async () => { const params = { Bucket: bucket, Key: 'toComplete', @@ -236,34 +191,26 @@ describe('aws-node-sdk test suite as registered user', function testSuite() { ], }, }; - s3.completeMultipartUpload(params, (err, data) => { - if (err) { - return done(new Error(`error completing mpu: ${err}`)); - } - assert.strictEqual(data.Bucket, bucket); - assert.strictEqual(data.Key, 'toComplete'); - assert.strictEqual(data.ETag, combinedETag); - return done(); - }); + const data = await s3.send(new CompleteMultipartUploadCommand(params)); + assert.strictEqual(data.Bucket, bucket); + assert.strictEqual(data.Key, 'toComplete'); + assert.strictEqual(data.ETag, combinedETag); }); - it('should get an object put by multipart upload', done => { + it('should get an object put by multipart upload', async () => { const params = { Bucket: bucket, Key: 'toComplete', }; - s3.getObject(params, (err, data) => { - if (err) { - return done(new Error( - `error getting object put by mpu: ${err}`)); - } - assert.strictEqual(data.ETag, - combinedETag); - const uploadedObj = Buffer.concat([firstBufferBody, - secondBufferBody]); - assert.deepStrictEqual(data.Body, uploadedObj); - return done(); - }); + const data = await s3.send(new GetObjectCommand(params)); + assert.strictEqual(data.ETag, combinedETag); + const uploadedObj = Buffer.concat([firstBufferBody, secondBufferBody]); + const chunks = []; + for await (const chunk of data.Body) { + chunks.push(chunk); + } + const body = Buffer.concat(chunks); + assert.deepStrictEqual(body, uploadedObj); }); const mpuRangeGetTests = [ @@ -316,73 +263,59 @@ describe('aws-node-sdk test suite as registered user', function testSuite() { ]; mpuRangeGetTests.forEach(test => { - it(test.it, done => { + it(test.it, async () => { const params = { Bucket: bucket, Key: 'toComplete', Range: test.range, }; - s3.getObject(params, (err, data) => { - if (err) { - return done(new Error( - `error getting object range put by mpu: ${err}`)); - } - assert.strictEqual(data.ContentLength, test.contentLength); - assert.strictEqual(data.AcceptRanges, 'bytes'); - assert.strictEqual(data.ContentRange, test.contentRange); - assert.strictEqual(data.ETag, - combinedETag); - assert.deepStrictEqual(data.Body, test.expectedBuff); - return done(); - }); + const data = await s3.send(new GetObjectCommand(params)); + assert.strictEqual(data.ContentLength, test.contentLength); + assert.strictEqual(data.AcceptRanges, 'bytes'); + assert.strictEqual(data.ContentRange, test.contentRange); + assert.strictEqual(data.ETag, combinedETag); + const chunks = []; + for await (const chunk of data.Body) { + chunks.push(chunk); + } + const body = Buffer.concat(chunks); + assert.deepStrictEqual(body, test.expectedBuff); }); }); - it('should delete object created by multipart upload', + it('should delete object created by multipart upload', async () => { // deleteObject test - done => { - const params = { - Bucket: bucket, - Key: 'toComplete', - }; - s3.deleteObject(params, (err, data) => { - if (err) { - return done(new Error(`error deleting object: ${err}`)); - } - assert.ok(data); - return done(); - }); - }); + const params = { + Bucket: bucket, + Key: 'toComplete', + }; + const data = await s3.send(new DeleteObjectCommand(params)); + assert.ok(data); + }); - it('should put an object regularly (non-MPU)', done => { + it('should put an object regularly (non-MPU)', async () => { const params = { Bucket: bucket, Key: 'normalput', Body: Buffer.allocUnsafe(200).fill(0, 0, 50).fill(1, 50), }; - s3.putObject(params, (err, data) => { - if (err) { - return done(new Error( - `error putting object regularly: ${err}`)); - } - assert.ok(data); - return done(); - }); + const data = await s3.send(new PutObjectCommand(params)); + assert.ok(data); }); it('should return InvalidRange if the range of the resource does ' + - 'not cover the byte range', - done => { + 'not cover the byte range', async () => { const params = { Bucket: bucket, Key: 'normalput', Range: 'bytes=200-200', }; - s3.getObject(params, err => { - assert.notEqual(err, null, 'Expected failure but got success'); - assert.strictEqual(err.code, 'InvalidRange'); - return done(); - }); + try { + await s3.send(new GetObjectCommand(params)); + throw new Error('Expected InvalidRange error'); + } catch (err) { + assert.strictEqual(err.Code, 'InvalidRange'); + } }); describe('Get range on empty object', () => { @@ -390,56 +323,41 @@ describe('aws-node-sdk test suite as registered user', function testSuite() { Bucket: bucketEmptyObj, Key: 'emptyobj', }; - beforeEach(done => { - s3.createBucket({ Bucket: bucketEmptyObj }, err => { - if (err) { - return done(new Error(`error creating bucket: ${err}`)); - } - return s3.putObject(params, err => { - if (err) { - return done(new Error( - `error putting object regularly: ${err}`)); - } - return done(); - }); - }); + beforeEach(async () => { + await s3.send(new CreateBucketCommand({ Bucket: bucketEmptyObj })); + await s3.send(new PutObjectCommand(params)); }); - afterEach(done => { - s3.deleteObject(params, err => { - if (err) { - return done(new Error( - `error deletting object regularly: ${err}`)); - } - return s3.deleteBucket({ Bucket: bucketEmptyObj }, err => { - if (err) { - return done(new Error(`error deleting bucket: ${err}`)); - } - return done(); - }); - }); + afterEach(async () => { + await s3.send(new DeleteObjectCommand(params)); + await s3.send(new DeleteBucketCommand({ Bucket: bucketEmptyObj })); }); testsRangeOnEmptyFile.forEach(test => { const validText = test.valid ? 'InvalidRange error' : 'empty file'; it(`should return ${validText} if get range ${test.range} on ` + - 'empty object', - done => { - const params = { + 'empty object', async () => { + const getParams = { Bucket: bucketEmptyObj, Key: 'emptyobj', Range: test.range, }; - s3.getObject(params, (err, data) => { + try { + const data = await s3.send(new GetObjectCommand(getParams)); + if (test.valid) { + throw new Error('Expected failure but got success'); + } + const chunks = []; + for await (const chunk of data.Body) { + chunks.push(chunk); + } + const body = Buffer.concat(chunks); + assert.strictEqual(body.toString(), ''); + } catch (err) { if (test.valid) { - assert.notEqual(err, null, 'Expected failure but ' + - 'got success'); - assert.strictEqual(err.code, 'InvalidRange'); + assert.strictEqual(err.Code, 'InvalidRange'); } else { - assert.equal(err, null, 'Expected success but ' + - `got failure: ${err}`); - assert.strictEqual(data.Body.toString(), ''); + throw err; } - return done(); - }); + } }); }); }); @@ -477,49 +395,37 @@ describe('aws-node-sdk test suite as registered user', function testSuite() { ]; regularObjectRangeGetTests.forEach(test => { - it(test.it, done => { + it(test.it, async () => { const params = { Bucket: bucket, Key: 'normalput', Range: test.range, }; - s3.getObject(params, (err, data) => { - if (err) { - return done(new Error( - `error getting object range: ${err}`)); - } - assert.strictEqual(data.AcceptRanges, 'bytes'); - assert.strictEqual(data.ContentLength, test.contentLength); - assert.strictEqual(data.ContentRange, test.contentRange); - assert.deepStrictEqual(data.Body, test.expectedBuff); - return done(); - }); + const data = await s3.send(new GetObjectCommand(params)); + assert.strictEqual(data.AcceptRanges, 'bytes'); + assert.strictEqual(data.ContentLength, test.contentLength); + assert.strictEqual(data.ContentRange, test.contentRange); + const chunks = []; + for await (const chunk of data.Body) { + chunks.push(chunk); + } + const body = Buffer.concat(chunks); + assert.deepStrictEqual(body, test.expectedBuff); }); }); - it('should delete an object put without MPU', + it('should delete an object put without MPU', async () => { // deleteObject test - done => { - const params = { - Bucket: bucket, - Key: 'normalput', - }; - s3.deleteObject(params, (err, data) => { - if (err) { - return done(new Error(`error deleting object: ${err}`)); - } - assert.ok(data); - return done(); - }); - }); + const params = { + Bucket: bucket, + Key: 'normalput', + }; + const data = await s3.send(new DeleteObjectCommand(params)); + assert.ok(data); + }); // deletebucket test - it('should delete a bucket', done => { - s3.deleteBucket({ Bucket: bucket }, err => { - if (err) { - return done(new Error(`error deleting bucket: ${err}`)); - } - return done(); - }); + it('should delete a bucket', async () => { + await s3.send(new DeleteBucketCommand({ Bucket: bucket })); }); });