diff --git a/lib/Config.js b/lib/Config.js index 90281da39b..6f738c480d 100644 --- a/lib/Config.js +++ b/lib/Config.js @@ -160,6 +160,16 @@ function locationConstraintAssert(locationConstraints) { assert(supportedBackends.indexOf(locationConstraints[l].type) > -1, 'bad config: locationConstraints[region].type must ' + `be one of ${supportedBackends}`); + assert(typeof locationConstraints[l].objectId === 'string', + 'bad config: locationConstraints[region].objectId is ' + + 'mandatory and must be a unique string across locations'); + assert(Object.keys(locationConstraints) + .filter(loc => (locationConstraints[loc].objectId === + locationConstraints[l].objectId)) + .length === 1, + 'bad config: location constraint objectId ' + + `"${locationConstraints[l].objectId}" is not unique across ` + + 'configured locations'); assert(typeof locationConstraints[l].legacyAwsBehavior === 'boolean', 'bad config: locationConstraints[region]' + diff --git a/lib/management/configuration.js b/lib/management/configuration.js index 6957301f6d..f4676a3386 100644 --- a/lib/management/configuration.js +++ b/lib/management/configuration.js @@ -85,6 +85,7 @@ function patchConfiguration(newConf, log, cb) { Object.keys(newConf.locations || {}).forEach(k => { const l = newConf.locations[k]; const location = { + objectId: l.objectId, details: {}, }; let supportsVersioning = false; diff --git a/lib/utapi/utilities.js b/lib/utapi/utilities.js index 72f35a45e6..0defa6e090 100644 --- a/lib/utapi/utilities.js +++ b/lib/utapi/utilities.js @@ -216,6 +216,16 @@ function pushMetric(action, log, metricObj) { return utapi.pushMetric(action, log.getSerializedUids(), utapiObj); } +/** + * internal: get the unique location ID from the location name + * + * @param {string} location - location name + * @return {string} - location unique ID + */ +function _getLocationId(location) { + return _config.locationConstraints[location].objectId; +} + /** * Call the Utapi Client 'getLocationMetric' method with the * associated parameters @@ -225,7 +235,8 @@ function pushMetric(action, log, metricObj) { * @return {function} - `utapi.getLocationMetric` */ function getLocationMetric(location, log, cb) { - return utapi.getLocationMetric(location, log.getSerializedUids(), cb); + const locationId = _getLocationId(location); + return utapi.getLocationMetric(locationId, log.getSerializedUids(), cb); } /** @@ -238,7 +249,8 @@ function getLocationMetric(location, log, cb) { * @return {function} - `utapi.pushLocationMetric` */ function pushLocationMetric(location, byteLength, log, cb) { - return utapi.pushLocationMetric(location, byteLength, + const locationId = _getLocationId(location); + return utapi.pushLocationMetric(locationId, byteLength, log.getSerializedUids(), cb); } diff --git a/locationConfig.json b/locationConfig.json index 9ac6b69898..16267b3a7f 100644 --- a/locationConfig.json +++ b/locationConfig.json @@ -1,81 +1,97 @@ { "us-east-1": { "type": "file", + "objectId": "us-east-1", "legacyAwsBehavior": true, "details": {} }, "us-east-2": { "type": "file", + "objectId": "us-east-2", "legacyAwsBehavior": false, "details": {} }, "us-west-1": { "type": "file", + "objectId": "us-west-1", "legacyAwsBehavior": false, "details": {} }, "us-west-2": { "type": "file", + "objectId": "us-west-2", "legacyAwsBehavior": false, "details": {} }, "ca-central-1": { "type": "file", + "objectId": "ca-central-1", "legacyAwsBehavior": false, "details": {} }, "cn-north-1": { "type": "file", + "objectId": "cn-north-1", "legacyAwsBehavior": false, "details": {} }, "ap-south-1": { "type": "file", + "objectId": "ap-south-1", "legacyAwsBehavior": false, "details": {} }, "ap-northeast-1": { "type": "file", + "objectId": "ap-northeast-1", "legacyAwsBehavior": false, "details": {} }, "ap-northeast-2": { "type": "file", + "objectId": "ap-northeast-2", "legacyAwsBehavior": false, "details": {} }, "ap-southeast-1": { "type": "file", + "objectId": "ap-southeast-1", "legacyAwsBehavior": false, "details": {} }, "ap-southeast-2": { "type": "file", + "objectId": "ap-southeast-2", "legacyAwsBehavior": false, "details": {} }, "eu-central-1": { "type": "file", + "objectId": "eu-central-1", "legacyAwsBehavior": false, "details": {} }, "eu-west-1": { "type": "file", + "objectId": "eu-west-1", "legacyAwsBehavior": false, "details": {} }, "eu-west-2": { "type": "file", + "objectId": "eu-west-2", "legacyAwsBehavior": false, "details": {} }, "EU": { "type": "file", + "objectId": "EU", "legacyAwsBehavior": false, "details": {} }, "sa-east-1": { "type": "file", + "objectId": "sa-east-1", "legacyAwsBehavior": false, "details": {} } diff --git a/tests/locationConfig/locationConfigLegacy.json b/tests/locationConfig/locationConfigLegacy.json index 5f3e2cde1f..6fd7dabd71 100644 --- a/tests/locationConfig/locationConfigLegacy.json +++ b/tests/locationConfig/locationConfigLegacy.json @@ -2,42 +2,50 @@ { "legacy": { "type": "mem", + "objectId": "legacy", "legacyAwsBehavior": false, "details": {} }, "us-east-1": { "type": "file", + "objectId": "us-east-1", "legacyAwsBehavior": true, "details": {} }, "us-east-2": { "type": "file", + "objectId": "us-east-2", "legacyAwsBehavior": true, "details": {} }, "scality-internal-file": { "type": "file", + "objectId": "scality-internal-file", "legacyAwsBehavior": false, "details": {} }, "dataFile": { "type": "file", + "objectId": "dataFile", "legacyAwsBehavior": false, "details": {} }, "scality-internal-mem": { "type": "mem", + "objectId": "scality-internal-mem", "legacyAwsBehavior": false, "details": {} }, "scality-us-west-1": { "type": "mem", + "objectId": "scality-us-west-1", "legacyAwsBehavior": false, "details": {} }, "awsbackendencryption": { "type": "aws_s3", + "objectId": "awsbackendencryption", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -49,6 +57,7 @@ }, "awsbackend": { "type": "aws_s3", + "objectId": "awsbackend", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -59,6 +68,7 @@ }, "awsbackendmismatch": { "type": "aws_s3", + "objectId": "awsbackendmismatch", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -69,6 +79,7 @@ }, "awsbackendhttp": { "type": "aws_s3", + "objectId": "awsbackendhttp", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -80,6 +91,7 @@ }, "awsbackend2": { "type": "aws_s3", + "objectId": "awsbackend2", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -90,6 +102,7 @@ }, "azurebackend": { "type": "azure", + "objectId": "azurebackend", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname.blob.core.fake.net/", @@ -101,6 +114,7 @@ }, "azurebackend2": { "type": "azure", + "objectId": "azurebackend2", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname2.blob.core.fake.net/", @@ -112,6 +126,7 @@ }, "azurebackendmismatch": { "type": "azure", + "objectId": "azurebackendmismatch", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname.blob.core.fake.net/", @@ -123,6 +138,7 @@ }, "gcpbackend": { "type": "gcp", + "objectId": "gcpbackend", "legacyAwsBehavior": true, "details": { "gcpEndpoint": "storage.googleapis.com", @@ -134,6 +150,7 @@ }, "withversioning": { "type": "aws_s3", + "objectId": "withversioning", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -145,6 +162,7 @@ }, "withoutversioning": { "type": "aws_s3", + "objectId": "withoutversioning", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -156,6 +174,7 @@ }, "transientfile": { "type": "file", + "objectId": "transientfile", "legacyAwsBehavior": false, "details": {}, "isTransient": true diff --git a/tests/locationConfig/locationConfigTests.json b/tests/locationConfig/locationConfigTests.json index 4a3d58c9b7..ad5b5c1f47 100644 --- a/tests/locationConfig/locationConfigTests.json +++ b/tests/locationConfig/locationConfigTests.json @@ -1,36 +1,43 @@ { "us-east-1": { "type": "file", + "objectId": "us-east-1", "legacyAwsBehavior": true, "details": {} }, "us-east-2": { "type": "file", + "objectId": "us-east-2", "legacyAwsBehavior": true, "details": {} }, "scality-internal-file": { "type": "file", + "objectId": "scality-internal-file", "legacyAwsBehavior": false, "details": {} }, "dataFile": { "type": "file", + "objectId": "dataFile", "legacyAwsBehavior": false, "details": {} }, "scality-internal-mem": { "type": "mem", + "objectId": "scality-internal-mem", "legacyAwsBehavior": false, "details": {} }, "scality-us-west-1": { "type": "mem", + "objectId": "scality-us-west-1", "legacyAwsBehavior": false, "details": {} }, "awsbackendencryption": { "type": "aws_s3", + "objectId": "awsbackendencryption", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -42,6 +49,7 @@ }, "awsbackend": { "type": "aws_s3", + "objectId": "awsbackend", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -52,6 +60,7 @@ }, "awsbackendhttp": { "type": "aws_s3", + "objectId": "awsbackendhttp", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -63,6 +72,7 @@ }, "awsbackendmismatch": { "type": "aws_s3", + "objectId": "awsbackendmismatch", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -73,6 +83,7 @@ }, "awsbackend2": { "type": "aws_s3", + "objectId": "awsbackend2", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -83,6 +94,7 @@ }, "awsbackendPathStyle": { "type": "aws_s3", + "objectId": "awsbackendPathStyle", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -94,6 +106,7 @@ }, "azurebackend": { "type": "azure", + "objectId": "azurebackend", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname.blob.core.fake.net/", @@ -105,6 +118,7 @@ }, "azurebackend2": { "type": "azure", + "objectId": "azurebackend2", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname2.blob.core.fake.net/", @@ -116,6 +130,7 @@ }, "azurebackendmismatch": { "type": "azure", + "objectId": "azurebackendmismatch", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname.blob.core.fake.net/", @@ -127,6 +142,7 @@ }, "azurenonexistcontainer": { "type": "azure", + "objectId": "azurenonexistcontainer", "legacyAwsBehavior": true, "details": { "azureStorageEndpoint": "https://fakeaccountname.blob.core.fake.net/", @@ -138,6 +154,7 @@ }, "gcpbackend": { "type": "gcp", + "objectId": "gcpbackend", "legacyAwsBehavior": true, "details": { "gcpEndpoint": "storage.googleapis.com", @@ -149,6 +166,7 @@ }, "gcpbackend2": { "type": "gcp", + "objectId": "gcpbackend2", "legacyAwsBehavior": true, "details": { "gcpEndpoint": "storage.googleapis.com", @@ -160,6 +178,7 @@ }, "gcpbackendmismatch": { "type": "gcp", + "objectId": "gcpbackendmismatch", "legacyAwsBehavior": true, "details": { "gcpEndpoint": "storage.googleapis.com", @@ -171,6 +190,7 @@ }, "withversioning": { "type": "aws_s3", + "objectId": "withversioning", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -182,6 +202,7 @@ }, "withoutversioning": { "type": "aws_s3", + "objectId": "withoutversioning", "legacyAwsBehavior": true, "details": { "awsEndpoint": "s3.amazonaws.com", @@ -193,6 +214,7 @@ }, "transientfile": { "type": "file", + "objectId": "transientfile", "legacyAwsBehavior": false, "details": {}, "isTransient": true diff --git a/tests/unit/management/configuration.js b/tests/unit/management/configuration.js index a9faca6091..34ea74e8a2 100644 --- a/tests/unit/management/configuration.js +++ b/tests/unit/management/configuration.js @@ -89,17 +89,20 @@ describe('patchConfiguration', () => { locations: { 'legacy': { name: 'legacy', + objectId: 'legacy', locationType: 'location-mem-v1', details: {}, }, 'us-east-1': { name: 'us-east-1', + objectId: 'us-east-1', locationType: 'location-file-v1', legacyAwsBehavior: true, details: {}, }, 'azurebackendtest': { name: 'azurebackendtest', + objectId: 'azurebackendtest', locationType: 'location-azure-v1', details: { bucketMatch: 'azurebucketmatch', @@ -111,6 +114,7 @@ describe('patchConfiguration', () => { }, 'awsbackendtest': { name: 'awsbackendtest', + objectId: 'awsbackendtest', locationType: 'location-aws-s3-v1', details: { bucketMatch: 'awsbucketmatch', @@ -122,6 +126,7 @@ describe('patchConfiguration', () => { }, 'gcpbackendtest': { name: 'gcpbackendtest', + objectId: 'gcpbackendtest', locationType: 'location-gcp-v1', details: { bucketMatch: 'gcpbucketmatch', @@ -133,6 +138,7 @@ describe('patchConfiguration', () => { }, 'sproxydbackendtest': { name: 'sproxydbackendtest', + objectId: 'sproxydbackendtest', locationType: 'location-scality-sproxyd-v1', details: { chordCos: 3, @@ -142,18 +148,21 @@ describe('patchConfiguration', () => { }, 'transienttest': { name: 'transienttest', + objectId: 'transienttest', locationType: 'location-file-v1', isTransient: true, details: {}, }, 'sizelimitedtest': { name: 'sizelimitedtest', + objectId: 'sizelimitedtest', locationType: 'location-file-v1', sizeLimitGB: 1024, details: {}, }, 'sizezerotest': { name: 'sizezerotest', + objectId: 'sizezerotest', locationType: 'location-file-v1', sizeLimitGB: 0, details: {}, @@ -185,6 +194,7 @@ describe('patchConfiguration', () => { locationConstraints: { 'legacy': { type: 'mem', + objectId: 'legacy', legacyAwsBehavior: false, isTransient: false, sizeLimitGB: null, @@ -192,6 +202,7 @@ describe('patchConfiguration', () => { }, 'us-east-1': { type: 'file', + objectId: 'us-east-1', legacyAwsBehavior: true, isTransient: false, sizeLimitGB: null, @@ -209,6 +220,7 @@ describe('patchConfiguration', () => { isTransient: false, sizeLimitGB: null, type: 'azure', + objectId: 'azurebackendtest', }, 'awsbackendtest': { details: { @@ -228,6 +240,7 @@ describe('patchConfiguration', () => { isTransient: false, sizeLimitGB: null, type: 'aws_s3', + objectId: 'awsbackendtest', }, 'gcpbackendtest': { details: { @@ -245,6 +258,7 @@ describe('patchConfiguration', () => { isTransient: false, sizeLimitGB: null, type: 'gcp', + objectId: 'gcpbackendtest', }, 'sproxydbackendtest': { details: { @@ -264,9 +278,11 @@ describe('patchConfiguration', () => { isTransient: false, sizeLimitGB: null, type: 'scality', + objectId: 'sproxydbackendtest', }, 'transienttest': { type: 'file', + objectId: 'transienttest', legacyAwsBehavior: false, isTransient: true, sizeLimitGB: null, @@ -274,6 +290,7 @@ describe('patchConfiguration', () => { }, 'sizelimitedtest': { type: 'file', + objectId: 'sizelimitedtest', legacyAwsBehavior: false, isTransient: false, sizeLimitGB: 1024, @@ -281,6 +298,7 @@ describe('patchConfiguration', () => { }, 'sizezerotest': { type: 'file', + objectId: 'sizezerotest', legacyAwsBehavior: false, isTransient: false, sizeLimitGB: null, diff --git a/tests/unit/testConfigs/locConstraintAssert.js b/tests/unit/testConfigs/locConstraintAssert.js index 83eed0916b..50e62abdd5 100644 --- a/tests/unit/testConfigs/locConstraintAssert.js +++ b/tests/unit/testConfigs/locConstraintAssert.js @@ -2,8 +2,9 @@ const assert = require('assert'); const { locationConstraintAssert } = require('../../../lib/Config'); class LocationConstraint { - constructor(type, legacyAwsBehavior, details, sizeLimit) { + constructor(type, objectId, legacyAwsBehavior, details, sizeLimit) { this.type = type || 'scality'; + this.objectId = objectId; this.legacyAwsBehavior = legacyAwsBehavior || false; this.sizeLimitGB = sizeLimit || undefined; this.details = Object.assign({}, { @@ -47,7 +48,7 @@ describe('locationConstraintAssert', () => { }); }); it('should throw error if type is not a string', () => { - const locationConstraint = new LocationConstraint(42); + const locationConstraint = new LocationConstraint(42, 'locId'); assert.throws(() => { locationConstraintAssert({ 'scality-east': locationConstraint }); }, @@ -55,7 +56,8 @@ describe('locationConstraintAssert', () => { /and must be a string/); }); it('should throw error if type is not mem/file/scality', () => { - const locationConstraint = new LocationConstraint('notSupportedType'); + const locationConstraint = new LocationConstraint( + 'notSupportedType', 'locId'); assert.throws(() => { locationConstraintAssert({ 'scality-east': locationConstraint }); }, @@ -63,7 +65,8 @@ describe('locationConstraintAssert', () => { /one of mem,file,scality/); }); it('should throw error if legacyAwsBehavior is not a boolean', () => { - const locationConstraint = new LocationConstraint('scality', 42); + const locationConstraint = new LocationConstraint( + 'scality', 'locId', 42); assert.throws(() => { locationConstraintAssert({ 'scality-east': locationConstraint }); }, @@ -71,7 +74,8 @@ describe('locationConstraintAssert', () => { /is mandatory and must be a boolean/); }); it('should throw error if details is not an object', () => { - const locationConstraint = new LocationConstraint('scality', false, 42); + const locationConstraint = + new LocationConstraint('scality', 'locId', false, 42); assert.throws(() => { locationConstraintAssert({ 'scality-east': locationConstraint }); }, @@ -79,7 +83,8 @@ describe('locationConstraintAssert', () => { /mandatory and must be an object/); }); it('should throw error if awsEndpoint is not a string', () => { - const locationConstraint = new LocationConstraint('scality', false, + const locationConstraint = new LocationConstraint( + 'scality', 'locId', false, { awsEndpoint: 42, }); @@ -89,7 +94,8 @@ describe('locationConstraintAssert', () => { /bad config: awsEndpoint must be a string/); }); it('should throw error if bucketName is not a string', () => { - const locationConstraint = new LocationConstraint('scality', false, + const locationConstraint = new LocationConstraint( + 'scality', 'locId', false, { awsEndpoint: 's3.amazonaws.com', bucketName: 42, @@ -100,7 +106,8 @@ describe('locationConstraintAssert', () => { /bad config: bucketName must be a string/); }); it('should throw error if credentialsProfile is not a string', () => { - const locationConstraint = new LocationConstraint('scality', false, + const locationConstraint = new LocationConstraint( + 'scality', 'locId', false, { awsEndpoint: 's3.amazonaws.com', bucketName: 'premadebucket', @@ -120,8 +127,9 @@ describe('locationConstraintAssert', () => { 'include us-east-1 as a locationConstraint/'); }); it('should not throw error for a valid azure location constraint', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails()); assert.doesNotThrow(() => { locationConstraintAssert({ 'azurefaketest': locationConstraint, @@ -131,8 +139,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureContainerName is ' + 'not specified', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureContainerName: undefined })); assert.throws(() => { locationConstraintAssert({ @@ -145,8 +154,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureContainerName is ' + 'invalid value', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureContainerName: '.' })); assert.throws(() => { locationConstraintAssert({ @@ -159,8 +169,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureStorageEndpoint ' + 'is not specified', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureStorageEndpoint: undefined })); assert.throws(() => { locationConstraintAssert({ @@ -174,8 +185,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureStorageAccountName ' + 'is not specified', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureStorageAccountName: undefined })); assert.throws(() => { locationConstraintAssert({ @@ -189,8 +201,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureStorageAccountName ' + 'is invalid value', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureStorageAccountName: 'invalid!!!' })); assert.throws(() => { locationConstraintAssert({ @@ -203,8 +216,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureStorageAccessKey ' + 'is not specified', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureStorageAccessKey: undefined })); assert.throws(() => { locationConstraintAssert({ @@ -218,8 +232,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if type is azure and azureStorageAccessKey ' + 'is not a valid base64 string', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('azure', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId2', true, getAzureDetails({ azureStorageAccessKey: 'invalid!!!' })); assert.throws(() => { locationConstraintAssert({ @@ -232,8 +247,9 @@ describe('locationConstraintAssert', () => { }); it('should set https to true by default', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('aws_s3', true); + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'aws_s3', 'locId2', true); assert.doesNotThrow(() => { locationConstraintAssert({ 'us-east-1': usEast1, @@ -246,10 +262,11 @@ describe('locationConstraintAssert', () => { }); it('should override default if https is set to false', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('aws_s3', true, { - https: false, - }); + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'aws_s3', 'locId2', true, { + https: false, + }); assert.doesNotThrow(() => { locationConstraintAssert({ 'us-east-1': usEast1, @@ -262,8 +279,9 @@ describe('locationConstraintAssert', () => { }); it('should set pathStyle config option to false by default', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('aws_s3', true); + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'aws_s3', 'locId2', true); assert.doesNotThrow(() => { locationConstraintAssert({ 'us-east-1': usEast1, @@ -275,8 +293,9 @@ describe('locationConstraintAssert', () => { }); it('should override default if pathStyle is set to true', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('aws_s3', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'aws_s3', 'locId2', true, { pathStyle: true }); assert.doesNotThrow(() => { locationConstraintAssert({ @@ -289,8 +308,9 @@ describe('locationConstraintAssert', () => { }); it('should throw error if sizeLimitGB is not a number', () => { - const usEast1 = new LocationConstraint(); - const locationConstraint = new LocationConstraint('aws_s3', true, + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'aws_s3', 'locId2', true, null, true); assert.throws(() => { locationConstraintAssert({ @@ -301,4 +321,30 @@ describe('locationConstraintAssert', () => { '/bad config: locationConstraints[region].sizeLimitGB ' + 'must be a number (in gigabytes)'); }); + + it('should throw error if objectId is not set', () => { + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', undefined, true, + getAzureDetails()); + assert.throws(() => { + locationConstraintAssert({ 'azurefaketest': locationConstraint, + 'us-east-1': usEast1 }); + }, + '/bad config: locationConstraints[region].objectId is mandatory ' + + 'and must be a unique string across locations'); + }); + + it('should throw error if objectId is duplicated', () => { + const usEast1 = new LocationConstraint(undefined, 'locId1'); + const locationConstraint = new LocationConstraint( + 'azure', 'locId1', true, + getAzureDetails()); + assert.throws(() => { + locationConstraintAssert({ 'azurefaketest': locationConstraint, + 'us-east-1': usEast1 }); + }, + '/bad config: location constraint objectId "locId1" is not unique ' + + 'across configured locations'); + }); });