From 23c016dd3d148c548b033557891627fd73d3f026 Mon Sep 17 00:00:00 2001 From: Jonathan Gramain Date: Fri, 20 Jul 2018 16:37:36 -0700 Subject: [PATCH] bf: ZENKO-745 unique location metrics redis keys Use new 'objectId' field set by Orbit to each location for the redis key, instead of the location name. This will avoid conflicts if locations are re-created with the same name. Take the opportunity to enforce an objectId to be set on each location, even if the config is from a static file, to make its use durable. --- lib/Config.js | 10 ++ lib/management/configuration.js | 1 + lib/utapi/utilities.js | 16 ++- locationConfig.json | 16 +++ .../locationConfig/locationConfigLegacy.json | 19 +++ tests/locationConfig/locationConfigTests.json | 22 ++++ tests/unit/management/configuration.js | 18 +++ tests/unit/testConfigs/locConstraintAssert.js | 118 ++++++++++++------ 8 files changed, 182 insertions(+), 38 deletions(-) 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'); + }); });