-
Couldn't load subscription status.
- Fork 252
Improvement/cldsrv 724 md search related functional tests #5981
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: improvement/CLDSRV-724-versionning-related-functional-tests
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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'); | ||
|
|
||
| const { runAndCheckSearch, runIfMongo } = require('./utils/helpers'); | ||
|
|
||
| const objectKey = 'findMe'; | ||
|
|
@@ -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 })) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 => { | ||
|
|
@@ -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', | ||
|
|
@@ -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 => { | ||
|
|
@@ -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 => { | ||
|
|
||
| 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 = {}; | ||||
|
|
@@ -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 | ||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||
| 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, | ||||
|
|
@@ -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(); | ||||
| }, | ||||
|
|
||||
| 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')); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.