Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 56 additions & 32 deletions tests/functional/aws-node-sdk/test/mdSearch/basicSearch.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
const {
CreateBucketCommand,
DeleteBucketCommand,
PutObjectCommand,
DeleteObjectsCommand,
} = require('@aws-sdk/client-s3');
const s3Client = require('./utils/s3SDK');

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change

const { runAndCheckSearch, runIfMongo } = require('./utils/helpers');

const objectKey = 'findMe';
Expand All @@ -10,33 +17,35 @@ const updatedUserMetadata = { food: 'cake' };

runIfMongo('Basic search', () => {
const bucketName = `basicsearchmebucket${Date.now()}`;

before(done => {
s3Client.createBucket({ Bucket: bucketName }, err => {
if (err) {
return done(err);
}
return s3Client.putObject({ Bucket: bucketName, Key: objectKey,
Metadata: userMetadata, Tagging: objectTagData }, err => {
if (err) {
return done(err);
}
return s3Client.putObject({ Bucket: bucketName,
Key: hiddenKey, Tagging: hiddenTagData }, done);
});
});
});

after(done => {
s3Client.deleteObjects({ Bucket: bucketName, Delete: { Objects: [
{ Key: objectKey },
{ Key: hiddenKey }],
} },
err => {
if (err) {
return done(err);
}
return s3Client.deleteBucket({ Bucket: bucketName }, done);
});
s3Client.send(new CreateBucketCommand({ Bucket: bucketName }))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you can do convert to async/await

.then(() => s3Client.send(new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Metadata: userMetadata,
Tagging: objectTagData,
})))
.then(() => s3Client.send(new PutObjectCommand({
Bucket: bucketName,
Key: hiddenKey,
Tagging: hiddenTagData,
})))
.then(() => done())
.catch(done);
});

after(async () => {
await s3Client.send(new DeleteObjectsCommand({
Bucket: bucketName,
Delete: {
Objects: [
{ Key: objectKey },
{ Key: hiddenKey },
],
},
}));
await s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }));
});

it('should list object with searched for system metadata', done => {
Expand Down Expand Up @@ -87,8 +96,13 @@ runIfMongo('Basic search', () => {

describe('search when overwrite object', () => {
before(done => {
s3Client.putObject({ Bucket: bucketName, Key: objectKey,
Metadata: updatedUserMetadata }, done);
s3Client.send(new PutObjectCommand({
Bucket: bucketName,
Key: objectKey,
Metadata: updatedUserMetadata,
}))
.then(() => done())
.catch(done);
});

it('should list object with searched for updated user metadata',
Expand All @@ -104,12 +118,17 @@ runIfMongo('Basic search', () => {

runIfMongo('Search when no objects in bucket', () => {
const bucketName = `noobjectbucket${Date.now()}`;

before(done => {
s3Client.createBucket({ Bucket: bucketName }, done);
s3Client.send(new CreateBucketCommand({ Bucket: bucketName }))
.then(() => done())
.catch(done);
});

after(done => {
s3Client.deleteBucket({ Bucket: bucketName }, done);
s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }))
.then(() => done())
.catch(done);
});

it('should return empty listing when no objects in bucket', done => {
Expand All @@ -121,12 +140,17 @@ runIfMongo('Search when no objects in bucket', () => {

runIfMongo('Invalid regular expression searches', () => {
const bucketName = `badregex-${Date.now()}`;

before(done => {
s3Client.createBucket({ Bucket: bucketName }, done);
s3Client.send(new CreateBucketCommand({ Bucket: bucketName }))
.then(() => done())
.catch(done);
});

after(done => {
s3Client.deleteBucket({ Bucket: bucketName }, done);
s3Client.send(new DeleteBucketCommand({ Bucket: bucketName }))
.then(() => done())
.catch(done);
});

it('should return error if pattern is invalid', done => {
Expand Down
150 changes: 96 additions & 54 deletions tests/functional/aws-node-sdk/test/mdSearch/utils/helpers.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
const assert = require('assert');
const async = require('async');
const {
ListObjectsCommand,
ListObjectVersionsCommand,
DeleteObjectsCommand,
} = require('@aws-sdk/client-s3');

function _deleteVersionList(s3Client, versionList, bucket, callback) {
if (versionList === undefined || versionList.length === 0) {
return callback();
}
const params = { Bucket: bucket, Delete: { Objects: [] } };
versionList.forEach(version => {
params.Delete.Objects.push({
Key: version.Key, VersionId: version.VersionId });
});

return s3Client.deleteObjects(params, callback);
const params = {
Bucket: bucket,
Delete: {
Objects: versionList.map(version => ({
Key: version.Key,
VersionId: version.VersionId,
})),
},
};
return s3Client.send(new DeleteObjectsCommand(params))
.then(() => callback())
.catch(callback);
}

const testUtils = {};
Expand All @@ -21,62 +31,94 @@ testUtils.runIfMongo = process.env.S3METADATA === 'mongodb' ?

testUtils.runAndCheckSearch = (s3Client, bucketName, encodedSearch, listVersions,
testResult, done) => {
let searchRequest;
if (listVersions) {
searchRequest = s3Client.listObjectVersions({ Bucket: bucketName });
searchRequest.on('build', () => {
searchRequest.httpRequest.path =
`/${bucketName}?search=${encodedSearch}&&versions`;
});
searchRequest.on('success', res => {
if (testResult) {
assert.notStrictEqual(res.data.Versions[0].VersionId, undefined);
if (Array.isArray(testResult)) {
assert.strictEqual(res.data.Versions.length, testResult.length);
async.forEachOf(testResult, (expected, i, next) => {
assert.strictEqual(res.data.Versions[i].Key, expected);
next();
});
const makeRequest = async () => {
try {
const input = {
Bucket: bucketName,
};

let command;
if (listVersions) {
command = new ListObjectVersionsCommand(input);
} else {
command = new ListObjectsCommand(input);
}

// Add middleware to inject the search query parameter
// SDK v3 automatically encodes query parameters, so we decode first to avoid double-encoding
command.middlewareStack.add(
next => async args => {
if (!args.request.query) {
// eslint-disable-next-line no-param-reassign
args.request.query = {};
}
// Decode the already-encoded search string since SDK v3 will encode it again
// eslint-disable-next-line no-param-reassign
args.request.query.search = decodeURIComponent(encodedSearch);
if (listVersions) {
// eslint-disable-next-line no-param-reassign
args.request.query.versions = '';
}

return next(args);
},
{
step: 'build',
name: 'addSearchQuery',
}
);

const res = await s3Client.send(command);

if (listVersions) {
if (testResult) {
assert.notStrictEqual(res.Versions[0].VersionId, undefined);
if (Array.isArray(testResult)) {
assert.strictEqual(res.Versions.length, testResult.length);
async.forEachOf(testResult, (expected, i, next) => {
assert.strictEqual(res.Versions[i].Key, expected);
next();
}, done);
return;
} else {
assert(res.Versions[0], 'should be Contents listed');
assert.strictEqual(res.Versions[0].Key, testResult);
assert.strictEqual(res.Versions.length, 1);
}
} else {
assert(res.data.Versions[0], 'should be Contents listed');
assert.strictEqual(res.data.Versions[0].Key, testResult);
assert.strictEqual(res.data.Versions.length, 1);
assert.strictEqual(res.Versions.length, 0);
}
} else {
assert.strictEqual(res.data.Versions.length, 0);
if (testResult && typeof testResult === 'object' && testResult.code) {
// This was expected to be an error, but we got success
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// This was expected to be an error, but we got success

done(new Error('Expected error but got success'));
}
if (testResult) {
assert(res.Contents[0], 'should be Contents listed');
assert.strictEqual(res.Contents[0].Key, testResult);
assert.strictEqual(res.Contents.length, 1);
} else {
assert.strictEqual(res.Contents?.length, undefined);
}
}
return done();
});
} else {
searchRequest = s3Client.listObjects({ Bucket: bucketName });
searchRequest.on('build', () => {
searchRequest.httpRequest.path =
`/${bucketName}?search=${encodedSearch}`;
});
searchRequest.on('success', res => {
if (testResult) {
assert(res.data.Contents[0], 'should be Contents listed');
assert.strictEqual(res.data.Contents[0].Key, testResult);
assert.strictEqual(res.data.Contents.length, 1);
} else {
assert.strictEqual(res.data.Contents.length, 0);
done();
} catch (err) {
if (testResult && typeof testResult === 'object' && testResult.code) {
assert.strictEqual(err.name, testResult.code);
assert.strictEqual(err.message, testResult.message);
done();
}
return done();
});
}
searchRequest.on('error', err => {
if (testResult) {
assert.strictEqual(err.code, testResult.code);
assert.strictEqual(err.message, testResult.message);
done(err);
}
return done();
});
searchRequest.send();
};
makeRequest();
};

testUtils.removeAllVersions = (s3Client, bucket, callback) => {
async.waterfall([
cb => s3Client.listObjectVersions({ Bucket: bucket }, cb),
cb => s3Client.send(new ListObjectVersionsCommand({ Bucket: bucket }))
.then(data => cb(null, data))
.catch(cb),
(data, cb) => _deleteVersionList(s3Client, data.DeleteMarkers, bucket,
err => cb(err, data)),
(data, cb) => _deleteVersionList(s3Client, data.Versions, bucket,
Expand All @@ -88,7 +130,7 @@ testUtils.removeAllVersions = (s3Client, bucket, callback) => {
KeyMarker: data.NextKeyMarker,
VersionIdMarker: data.NextVersionIdMarker,
};
return this.removeAllVersions(params, cb);
return testUtils.removeAllVersions(s3Client, params, cb);
}
return cb();
},
Expand Down
19 changes: 3 additions & 16 deletions tests/functional/aws-node-sdk/test/mdSearch/utils/s3SDK.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
const S3 = require('aws-sdk').S3;
const { S3Client } = require('@aws-sdk/client-s3');
const getConfig = require('../../support/config');

const config = {
sslEnabled: false,
endpoint: 'http://127.0.0.1:8000',
apiVersions: { s3: '2006-03-01' },
signatureCache: false,
signatureVersion: 'v4',
region: 'us-east-1',
s3ForcePathStyle: true,
accessKeyId: 'accessKey1',
secretAccessKey: 'verySecretKey1',
};

const client = new S3(config);

module.exports = client;
module.exports = new S3Client(getConfig('default'));
Loading
Loading