From c8c715db72180d4f7cefc45be0bdd935dc21188b Mon Sep 17 00:00:00 2001 From: tistocks Date: Fri, 3 May 2013 15:29:58 -0700 Subject: [PATCH 01/11] First round adding HDInsight service --- lib/azure.js | 25 +++++ .../serviceManagement/hdinsightservice.js | 89 ++++++++++++++++++ test/services/HDInsight/hdinsight-tests.js | 83 +++++++++++++++++ test/services/HDInsight/hdinsight-util.js | 21 +++++ test/testlist.txt | 91 ++++++++++--------- 5 files changed, 264 insertions(+), 45 deletions(-) create mode 100644 lib/services/serviceManagement/hdinsightservice.js create mode 100644 test/services/HDInsight/hdinsight-tests.js create mode 100644 test/services/HDInsight/hdinsight-util.js diff --git a/lib/azure.js b/lib/azure.js index 425f7e3a1d..c64441b182 100644 --- a/lib/azure.js +++ b/lib/azure.js @@ -201,6 +201,31 @@ exports.createSqlManagementService = function (subscriptionId, authentication, h return new SqlManagementService(subscriptionId, authentication, hostOptions); }; +var HDInsightService = require('./services/serviceManagement/hdinsightservice'); +exports.HDInsightService = HDInsightService; + +/** +* Creates a new HDInsightService object. +* +* @param {string} subscriptionId The subscription ID for the account. +* @param {string} authentication The authentication object for the client. +* { +* keyfile: 'path to .pem', +* certfile: 'path to .pem', +* keyvalue: privatekey value, +* certvalue: public cert value +* } +* @param {string} hostOptions The host options to override defaults. +* { +* host: 'management.core.windows.net', +* apiversion: '2012-03-01', +* serializetype: 'XML' +* } +*/ +exports.createHDInsightService = function (subscriptionId, authentication, hostOptions) { + return new HDInsightService(subscriptionId, authentication, hostOptions); +}; + /** * ServiceBusManagementService client exports. */ diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js new file mode 100644 index 0000000000..fd3c033b8f --- /dev/null +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -0,0 +1,89 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Module dependencies. +var util = require('util'); +var _ = require('underscore'); + +var ServiceManagementClient = require('../core/servicemanagementclient'); +var WebResource = require('../../http/webresource'); + +// var js2xml = require('../../util/js2xml'); +// var Constants = require('../../util/constants'); + +/** +* +* Creates a new HDInsightService object +* +* @constructor +* @param {string} subscriptionId Subscription ID for the account or the connection string +* @param {object} authentication The authentication object for the client. +* { +* keyfile: 'path to .pem', +* certfile: 'path to .pem', +* keyvalue: privatekey value, +* certvalue: public cert value +* } +* @param {object} hostOptions The host options to override defaults. +* { +* host: 'management.core.windows.net', +* apiversion: '2012-03-01', +* serializetype: 'XML' +* } +*/ +function HDInsightService(subscriptionId, authentication, hostOptions) { + if (typeof subscriptionId != 'string' || subscriptionId.length === 0) { + throw new Error('A subscriptionId or a connection string is required'); + } + + if (!hostOptions) { + hostOptions = { }; + } + + hostOptions.serializetype = 'XML'; + HDInsightService['super_'].call(this, authentication, hostOptions); + + this.subscriptionId = subscriptionId; +} + +util.inherits(HDInsightService, ServiceManagementClient); + +HDInsightService.prototype.listClusters = function (callback) { + var path = this._makePath('servers'); + var webResource = WebResource.get(path); + + this.performRequest(webResource, null, null, function (responseObject, next) { + if (!responseObject.error) { + responseObject.sqlServers = []; + if (responseObject.response.body.Servers && responseObject.response.body.Servers.Server) { + responseObject.sqlServers = responseObject.response.body.Servers.Server; + if (!_.isArray(responseObject.sqlServers)) { + responseObject.sqlServers = [ responseObject.sqlServers ]; + } + } + } + + var finalCallback = function (returnObject) { + callback(returnObject.error, returnObject.sqlServers, returnObject.response); + }; + + next(responseObject, finalCallback); + }); +}; + +HDInsightService.prototype._makePath = function (operationName) { + return '/' + this.subscriptionId + '/services/sqlservers/' + operationName; +}; +module.exports = HDInsightService; diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js new file mode 100644 index 0000000000..8b24e8db50 --- /dev/null +++ b/test/services/HDInsight/hdinsight-tests.js @@ -0,0 +1,83 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var assert = require('assert'); +var mocha = require('mocha'); +var should = require('should'); + +// Test includes +var testutil = require('../../util/util'); + +var hdinsightutil = require('./hdinsight-util.js'); + +var azure = testutil.libRequire('azure'); + + +describe('HDInsight Test', function() { + var storageAccounts; + var sqlServers; + + var storage1Name = "azurehdxstrtst00"; + var storage2Name = "azurehdxstrtst01"; + + var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; + var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; + var serviceMan = azure.createServiceManagementService(subscriptionId, auth); + var sqlMan = azure.createSqlManagementService(subscriptionId, auth); + var hdInsight = azure.createHDInsightService(subscriptionId, auth); + + // NOTE: To Do, we should actually create new acounts for our tests + // So that we can work on any existing subscription. + before (function (done) { + serviceMan.listStorageAccounts(function (err, response) { + should.not.exist(err); + should.exist(response.body); + response.body.length.should.eql(2); + ''.should.eql(response.body); + for(var i in response.body) + { + // if (response.body[i].) + } + storageAccounts = response.body; + + sqlMan.listServers(function (err, response) { + should.not.exist(err); + should.exists(response); + response.length.should.eql(2); + sqlServers = response; + done(err); + }); + }); + }); + + + it('should run tests', function (done) { + var result; + storageAccounts.length.should.eql(2); + done(); + }); + + it('should list storage accounts', function (done) { + var result; + + hdInsight.listClusters(function (err, response) { + should.not.exist(err); + + response.length.should.eql(2); + done(err); + }); + }); + +}); diff --git a/test/services/HDInsight/hdinsight-util.js b/test/services/HDInsight/hdinsight-util.js new file mode 100644 index 0000000000..8412bffe90 --- /dev/null +++ b/test/services/HDInsight/hdinsight-util.js @@ -0,0 +1,21 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var exports = module.exports; + +exports.AzureHDInsightSubscriptionId = function () +{ + return process.env['AZURE_SUBSCRIPTION_ID']; +} \ No newline at end of file diff --git a/test/testlist.txt b/test/testlist.txt index fa5d96d5ac..7c1e90f2b7 100644 --- a/test/testlist.txt +++ b/test/testlist.txt @@ -1,45 +1,46 @@ -serviceruntime/roleenvironment-tests.js -serviceruntime/runtimeversionmanager-tests.js -serviceruntime/runtimeversionprotocolclient-tests.js -services/blob/internal/sharedaccesssignature-tests.js -services/blob/internal/sharedkey-tests.js -services/blob/internal/sharedkeylite-tests.js -services/blob/blobservice-tests.js -services/blob/filters-tests.js -services/core/connectionstringparser-tests.js -services/core/serviceclient-tests.js -services/core/exponentialretrypolicyfilter-tests.js -services/core/linearretrypolicyfilter-tests.js -services/core/servicesettings-tests.js -services/core/servicebussettings-tests.js -services/core/servicemanagementsettings-tests.js -services/core/storageservicesettings-tests.js -services/queue/queueservice-tests.js -services/serviceBus/internal/wraptokenmanager-tests.js -services/serviceBus/apnsservice-tests.js -services/serviceBus/apnsservice-registrations-tests.js -services/serviceBus/servicebusservice-tests.js -services/serviceBus/notificationhubs-tests.js -services/serviceBus/wnsservice-tests.js -services/serviceBus/wnsservice-registrations-tests.js -services/serviceBus/wrapservice-tests.js -services/serviceManagement/affinitygroup-tests.js -services/serviceManagement/servicebusmanagementservice-tests.js -services/serviceManagement/servicemanagementservice-tests.js -services/serviceManagement/sqlmanagementservice-tests.js -services/table/internal/sharedkeytable-tests.js -services/table/internal/sharedkeylitetable-tests.js -services/table/batchserviceclient-tests.js -services/table/tabledatatype-tests.js -services/table/tablequery-tests.js -services/table/tableservice-batch-tests.js -services/table/tableservice-tablequery-tests.js -services/table/tableservice-tests.js -services/sqlAzure/sqlservice-tests.js -util/date-tests.js -util/edmtype-tests.js -util/iso8061date-tests.js -util/odatahandler-tests.js -util/util-tests.js -util/validate-tests.js -azure-tests.js \ No newline at end of file +# serviceruntime/roleenvironment-tests.js +# serviceruntime/runtimeversionmanager-tests.js +# serviceruntime/runtimeversionprotocolclient-tests.js +# services/blob/internal/sharedaccesssignature-tests.js +# services/blob/internal/sharedkey-tests.js +# services/blob/internal/sharedkeylite-tests.js +# services/blob/blobservice-tests.js +# services/blob/filters-tests.js +# services/core/connectionstringparser-tests.js +# services/core/serviceclient-tests.js +# services/core/exponentialretrypolicyfilter-tests.js +# services/core/linearretrypolicyfilter-tests.js +# services/core/servicesettings-tests.js +# services/core/servicebussettings-tests.js +# services/core/servicemanagementsettings-tests.js +# services/core/storageservicesettings-tests.js +# services/queue/queueservice-tests.js +# services/serviceBus/internal/wraptokenmanager-tests.js +# services/serviceBus/apnsservice-tests.js +# services/serviceBus/apnsservice-registrations-tests.js +# services/serviceBus/servicebusservice-tests.js +# services/serviceBus/notificationhubs-tests.js +# services/serviceBus/wnsservice-tests.js +# services/serviceBus/wnsservice-registrations-tests.js +# services/serviceBus/wrapservice-tests.js +# services/serviceManagement/affinitygroup-tests.js +# services/serviceManagement/servicebusmanagementservice-tests.js +# services/serviceManagement/servicemanagementservice-tests.js +# services/serviceManagement/sqlmanagementservice-tests.js +# services/table/internal/sharedkeytable-tests.js +# services/table/internal/sharedkeylitetable-tests.js +# services/table/batchserviceclient-tests.js +# services/table/tabledatatype-tests.js +# services/table/tablequery-tests.js +# services/table/tableservice-batch-tests.js +# services/table/tableservice-tablequery-tests.js +# services/table/tableservice-tests.js +# services/sqlAzure/sqlservice-tests.js +# util/date-tests.js +# util/edmtype-tests.js +# util/iso8061date-tests.js +# util/odatahandler-tests.js +# util/util-tests.js +# util/validate-tests.js +# azure-tests.js +services/HDInsight/hdinsight-tests.js \ No newline at end of file From e865ad96c47c3d49dc30eff3e7b0a173c26a6ba8 Mon Sep 17 00:00:00 2001 From: Pedro Urbina Date: Mon, 6 May 2013 16:31:13 -0700 Subject: [PATCH 02/11] Adding a library to create namespaces. This mirrors the C# functionality --- test/services/HDInsight/namespace-tests.js | 53 ++++++++++++++++++++++ test/services/HDInsight/namespace-util.js | 53 ++++++++++++++++++++++ test/testlist.txt | 3 +- 3 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 test/services/HDInsight/namespace-tests.js create mode 100644 test/services/HDInsight/namespace-util.js diff --git a/test/services/HDInsight/namespace-tests.js b/test/services/HDInsight/namespace-tests.js new file mode 100644 index 0000000000..d3ef485ed1 --- /dev/null +++ b/test/services/HDInsight/namespace-tests.js @@ -0,0 +1,53 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Test functions +var namespace = require('./namespace-util.js'); + +// Test includes +var assert = require('assert'); + +describe('HDInsight Namespace Test', function() { + + it('GetNameSpace', function (done) { + + var subscriptionId = "0bf0b5da-dc38-4795-8595-3170ffefec48"; + var expected = "hdinsightC2D4FSA77HSYSQLRU4V73NKI3YH2OYHQXACMRGPECIHSH7FXTUAQ-East-US"; + var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + assert.equal(expected, result); + + var subscriptionId = "c72f7fde-36ec-4cdf-93bf-43f90fe5373a"; + var expected = "hdinsightGTUVH76U5MNNGTJEFMKSGQMQO7AFBW52LMZPQ22R6UUXVWBDRBVA-East-US"; + var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + assert.equal(expected, result); + + var subscriptionId = "04066490-336b-4732-adfa-90ba5422cc84"; + var expected = "hdinsightXVS5S5SBDTTR7OJ4IOKGRTFM2M3P33KWPGP5SPYDJZYUMY73KOIQ-East-US"; + var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + assert.equal(expected, result); + + var subscriptionId = "3cfbb7fc-1347-4eff-bf07-2e1f43084b00"; + var expected = "hdinsightVXFY2XGLQTT5PCJCDRKJXWE2W2PQZOJK3NLO4QSNHEKS32E6RM5A-East-US"; + var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + assert.equal(expected, result); + + var subscriptionId = "ee3733c1-5ebd-4a20-95ce-17dba36a071a"; + var expected = "hdinsightLDBRGOYTMVIJZ2ZAJZZTFFJD7N3MNFCJGONZO53VLK2V5GIEU2SQ-East-US"; + var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + assert.equal(expected, result); + + done(); + }); +}); diff --git a/test/services/HDInsight/namespace-util.js b/test/services/HDInsight/namespace-util.js new file mode 100644 index 0000000000..5c86c8dd3f --- /dev/null +++ b/test/services/HDInsight/namespace-util.js @@ -0,0 +1,53 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// External dependencies +var crypto = require('crypto'); + +function GetNameSpace(subscriptionId, prefix, location) { + location = location.replace(" ", "-"); + var hash = crypto.createHash('sha256').update(new Buffer(subscriptionId, 'utf-8')).digest("hex"); + return prefix + Base32NoPaddingEncode(new Buffer(hash, "hex")) + "-" + location; +} + +var base32StandardAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; +function _Base32NoPaddingEncode (data) { + + var result = ""; + for (var i = 0; i < data.length; i+=5) { + + // Process input 5 bytes at a time + var multiplier = 256; + var loopValue = 0; + for (var j = Math.min(data.length-1, i+4); j >= i ; j--) { + loopValue += data[j] * multiplier; + multiplier = multiplier * 256; + } + + // Converts them into base32 + var bytes = Math.min(data.length - i, 5); + for (var bitOffset = (bytes+1)*8 - 5; bitOffset > 3; bitOffset -= 5) { + result += base32StandardAlphabet[LongUnsignedRor(loopValue,bitOffset) & 0x1f]; + } + + } + + return result; +} + +function _LongUnsignedRor(value, count) { + for(var i = 0; i Date: Tue, 7 May 2013 17:37:45 -0700 Subject: [PATCH 03/11] Added unit tests for listClusters --- .../serviceManagement/hdinsightservice.js | 56 ++++-- lib/util/util.js | 53 ++++++ .../hdinsight-listClusters-unit-tests.js | 170 +++++++++++++++++ test/services/HDInsight/hdinsight-tests.js | 119 +++++++++--- .../HDInsight/hdinsight-unit-tests.js | 179 ++++++++++++++++++ test/services/HDInsight/hdinsight-util.js | 74 +++++++- test/testlist.txt | 2 +- 7 files changed, 609 insertions(+), 44 deletions(-) create mode 100644 test/services/HDInsight/hdinsight-listClusters-unit-tests.js create mode 100644 test/services/HDInsight/hdinsight-unit-tests.js diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js index fd3c033b8f..a5280b859d 100644 --- a/lib/services/serviceManagement/hdinsightservice.js +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -18,7 +18,6 @@ var util = require('util'); var _ = require('underscore'); var ServiceManagementClient = require('../core/servicemanagementclient'); -var WebResource = require('../../http/webresource'); // var js2xml = require('../../util/js2xml'); // var Constants = require('../../util/constants'); @@ -60,30 +59,61 @@ function HDInsightService(subscriptionId, authentication, hostOptions) { util.inherits(HDInsightService, ServiceManagementClient); +var WebResource = require('../../http/webresource'); + HDInsightService.prototype.listClusters = function (callback) { - var path = this._makePath('servers'); + var path = '/' + this.subscriptionId + '/cloudservices'; var webResource = WebResource.get(path); + webResource.withHeader('x-ms-version', '2011-08-18'); + webResource.withHeader('accept', 'application/xml'); - this.performRequest(webResource, null, null, function (responseObject, next) { + this.performRequest(webResource, null, null, function (responseObject , next) { + var cloudServices = []; if (!responseObject.error) { - responseObject.sqlServers = []; - if (responseObject.response.body.Servers && responseObject.response.body.Servers.Server) { - responseObject.sqlServers = responseObject.response.body.Servers.Server; - if (!_.isArray(responseObject.sqlServers)) { - responseObject.sqlServers = [ responseObject.sqlServers ]; + if (responseObject.response && responseObject.response.body && + responseObject.response.body.CloudServices && responseObject.response.body.CloudServices.CloudService) { + + if (!_.isArray(responseObject.response.body.CloudServices.CloudService)) { + responseObject.response.body.CloudServices.CloudService = [ responseObject.response.body.CloudServices.CloudService ]; + } + + var cloudService = responseObject.response.body.CloudServices.CloudService; + + for (var i = 0; i < cloudService.length; i++) { + if (cloudService[i].Name && + cloudService[i].Name.indexOf('hdinsight') === 0) { + var resources = []; + + if (cloudService[i].Resources && cloudService[i].Resources.Resource) { + if (!_.isArray(cloudService[i].Resources.Resource)) { + cloudService[i].Resources.Resource = [ cloudService[i].Resources.Resource ]; + } + + var resource = cloudService[i].Resources.Resource; + for (var j = 0; j < resource.length; j++) { + if (resource[j].ResourceProviderNamespace == 'hdinsight') { + resources.push(resource[j]); + } + } + cloudService[i].Resources.Resource = resources; + } + + cloudServices.push (cloudService[i]); + } + + responseObject.response.body.CloudServices.CloudService = cloudServices; } + } } var finalCallback = function (returnObject) { - callback(returnObject.error, returnObject.sqlServers, returnObject.response); + callback(returnObject.error, returnObject.response); }; next(responseObject, finalCallback); + }); }; -HDInsightService.prototype._makePath = function (operationName) { - return '/' + this.subscriptionId + '/services/sqlservers/' + operationName; -}; -module.exports = HDInsightService; +module.exports = HDInsightService; \ No newline at end of file diff --git a/lib/util/util.js b/lib/util/util.js index 52502d9fa6..c7ede729bc 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -15,6 +15,7 @@ var fs = require('fs'); var path = require('path'); +var assert = require('assert'); var _ = require('underscore'); /** @@ -319,4 +320,56 @@ exports.getNodeVersion = function () { }; }; +function pollRequest(channel, reqid, callback) { +  channel.getOperationStatus(reqid, function(error, response) { +    if (error) { +      callback(error, { isSuccessful: false }); +    } else { +      assert.ok(response.isSuccessful); +      var body = response.body; +      if (body.Status === 'InProgress') { +        setTimeout(function() { +          pollRequest(channel, reqid, callback); +        }, exports.POLL_REQUEST_INTERVAL); +      } else if (body.Status === 'Failed') { +        callback(body.Error, { isSuccessful: false,  statusCode: body.HttpStatusCode}); +      } else { +        callback(null, { isSuccessful: true,  statusCode: body.HttpStatusCode}); +      } +    } +  }); +} + +exports.doServiceManagementOperation = function(channel, operation) { +  var callback = arguments[arguments.length - 1]; + +  /*jshint camelcase:false*/ +  function callback_(error, response) { +    if (error) { +      callback(error, response); +    } else { +      if (response.statusCode === 200) { +        callback(null, response); +      } else { +        // poll +        pollRequest(channel, response.headers['x-ms-request-id'], function(error, response) { +          if (error) { +            callback(error, response); +          } else { +            callback(null, response); +          } +        }); +      } +    } +  } + +  var args = Array.prototype.slice.call(arguments).slice(2, arguments.length - 1); +  args.push(callback_); +  if (!channel[operation]) { +    throw new Error('Incorrect service management operarion requested : ' + operation); +  } + +  channel[operation].apply(channel, args); +}; + exports.pathExistsSync = fs.existsSync ? fs.existsSync : path.existsSync; \ No newline at end of file diff --git a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js new file mode 100644 index 0000000000..3243f4dd20 --- /dev/null +++ b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js @@ -0,0 +1,170 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var assert = require('assert'); +var mocha = require('mocha'); +var should = require('should'); +var sinon = require('sinon'); + +// Test includes +var testutil = require('../../util/util'); + +var HDInsightUtil = require('./hdinsight-util.js'); + +var azure = testutil.libRequire('azure'); +var hdInsightUtil; + +describe('HDInsight listClusters', function() { + var storageAccounts; + var sqlServers; + + var storage1Name = "azurehdxstrtst00"; + var storage2Name = "azurehdxstrtst01"; + var foundStorage1 = false; + var foundStorage2 = false; + + var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; + var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; + var serviceMan = azure.createServiceManagementService(subscriptionId, auth); + var sqlMan = azure.createSqlManagementService(subscriptionId, auth); + var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); + var hdInsight = azure.createHDInsightService(subscriptionId, auth); + var WebResource = require('../../../lib/http/webresource'); + var _performRequestSpy; + var _performRequestOriginal; + + // var createStorageAccountAndWait = function (name, next) { + // serviceMan.listStorageAccounts(function (err, response)) { + // } + // }; + + beforeEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + afterEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + after(function (done) { + hdInsightUtil.Revert(); + done(); + }); + + // NOTE: To Do, we should actually create new acounts for our tests + // So that we can work on any existing subscription. + before (function (done) { + hdInsightUtil = new HDInsightUtil(HDInsight); + // this._performRequestOriginal = hdInsight._performRequest; + // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); + // hdInsight._performRequest = this._performRequestSpy; + // this._performRequestOriginal.should.eql(''); + // false.should.be.eql(true); + // console.log(typeof(hdInsight._performRequest)); + // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { + // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // finalCallback(responseObject); + // }); + // }); + + // serviceMan.listStorageAccounts(function (err, response) { + // should.not.exist(err); + // should.exist(response.body); + // // // response.body.length.should.eql(2); + // // for(var i in response.body) + // // { + // // if (response.body[i].ServiceName === storage1Name) + // // { + // // foundStorage1 = true; + // // } + // // else if (response.body[i].ServiceName === storage2Name) + // // { + // // foundStorage2 = true; + // // } + // // } + // // if (!foundStorage1) + // // { + // // var options = {}; + // // options.Location = 'East US'; + // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { + // // "asdf".should.eql(response); + // // done(err); + // // }); + // // } + // storageAccounts = response.body; + + // sqlMan.listServers(function (err, response) { + // should.not.exist(err); + // should.exists(response); + // // response.length.should.eql(2); + // sqlServers = response; + // done(err); + // }); + // }); + done(); + }); + + var result = { + CloudServices: { + CloudService: [ + { Name: 'not-hdinsight' } , + { + Name: 'hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2', + GeoRegion: 'East US 2', + Resources: { + Resource: [ + { + ResourceProviderNamespace: 'hdinsight', + Type: 'containers', + Name: 'tsthdx00hdxcibld02', + State: 'Started', + SubState: 'Running' + }, + { + ResourceProviderNamespace: 'not-hdinsight' + } + ] + } + } + ] + } + }; + + it('should remove CloudServices not related to HDInsight', function (done) { + hdInsightUtil.StubProcessRequestWithSuccess(result); + hdInsight.listClusters(function (err, response) { + should.not.exist(err); + should.exist(response.body.CloudServices.CloudService); + response.body.CloudServices.CloudService.length.should.eql(1); + response.body.CloudServices.CloudService[0].Name.should.eql('hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2'); + done(err); + }); + }); + + it('should remove resources not representing a cluster', function (done) { + hdInsightUtil.StubProcessRequestWithSuccess(result); + hdInsight.listClusters(function (err, response) { + should.not.exist(err); + should.exist(response.body.CloudServices.CloudService); + response.body.CloudServices.CloudService[0].Resources.Resource.length.should.eql(1); + response.body.CloudServices.CloudService[0].Resources.Resource[0].Name.should.eql('tsthdx00hdxcibld02'); + done(err); + }); + }); + +}); diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 8b24e8db50..2cafd2fc8c 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -16,14 +16,15 @@ var assert = require('assert'); var mocha = require('mocha'); var should = require('should'); +var sinon = require('sinon'); // Test includes var testutil = require('../../util/util'); -var hdinsightutil = require('./hdinsight-util.js'); +var HDInsightUtil = require('./hdinsight-util.js'); var azure = testutil.libRequire('azure'); - +var hdInsightUtil; describe('HDInsight Test', function() { var storageAccounts; @@ -31,51 +32,119 @@ describe('HDInsight Test', function() { var storage1Name = "azurehdxstrtst00"; var storage2Name = "azurehdxstrtst01"; + var foundStorage1 = false; + var foundStorage2 = false; var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var serviceMan = azure.createServiceManagementService(subscriptionId, auth); var sqlMan = azure.createSqlManagementService(subscriptionId, auth); + var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); + var WebResource = require('../../../lib/http/webresource'); + var _performRequestSpy; + var _performRequestOriginal; + + // var createStorageAccountAndWait = function (name, next) { + // serviceMan.listStorageAccounts(function (err, response)) { + // } + // }; + + beforeEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + afterEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + after(function (done) { + hdInsightUtil.Revert(); + done(); + }); // NOTE: To Do, we should actually create new acounts for our tests // So that we can work on any existing subscription. before (function (done) { - serviceMan.listStorageAccounts(function (err, response) { - should.not.exist(err); - should.exist(response.body); - response.body.length.should.eql(2); - ''.should.eql(response.body); - for(var i in response.body) - { - // if (response.body[i].) - } - storageAccounts = response.body; - - sqlMan.listServers(function (err, response) { - should.not.exist(err); - should.exists(response); - response.length.should.eql(2); - sqlServers = response; - done(err); - }); - }); + hdInsightUtil = new HDInsightUtil(HDInsight); + // this._performRequestOriginal = hdInsight._performRequest; + // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); + // hdInsight._performRequest = this._performRequestSpy; + // this._performRequestOriginal.should.eql(''); + // false.should.be.eql(true); + // console.log(typeof(hdInsight._performRequest)); + // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { + // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // finalCallback(responseObject); + // }); + // }); + + // serviceMan.listStorageAccounts(function (err, response) { + // should.not.exist(err); + // should.exist(response.body); + // // // response.body.length.should.eql(2); + // // for(var i in response.body) + // // { + // // if (response.body[i].ServiceName === storage1Name) + // // { + // // foundStorage1 = true; + // // } + // // else if (response.body[i].ServiceName === storage2Name) + // // { + // // foundStorage2 = true; + // // } + // // } + // // if (!foundStorage1) + // // { + // // var options = {}; + // // options.Location = 'East US'; + // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { + // // "asdf".should.eql(response); + // // done(err); + // // }); + // // } + // storageAccounts = response.body; + + // sqlMan.listServers(function (err, response) { + // should.not.exist(err); + // should.exists(response); + // // response.length.should.eql(2); + // sqlServers = response; + // done(err); + // }); + // }); + done(); }); it('should run tests', function (done) { var result; - storageAccounts.length.should.eql(2); - done(); + // hdInsightUtil.StubProcessRequestWithError(403, 'Unauthorized', 'You are not authorized'); + hdInsightUtil.StubProcessRequestWithSuccess("foo"); + hdInsight.listClusters(function (err, response) { + console.log(err); + console.log(response); + should.not.exist(err); + // response.bar.should.eql('foo'); + response.should.eql(''); + // response.length.should.eql(2); + done(err); + }); }); it('should list storage accounts', function (done) { var result; hdInsight.listClusters(function (err, response) { + console.log(err); + console.log(response); should.not.exist(err); - - response.length.should.eql(2); + // response.bar.should.eql('foo'); + response.should.eql(''); + // response.length.should.eql(2); done(err); }); }); diff --git a/test/services/HDInsight/hdinsight-unit-tests.js b/test/services/HDInsight/hdinsight-unit-tests.js new file mode 100644 index 0000000000..c93602710d --- /dev/null +++ b/test/services/HDInsight/hdinsight-unit-tests.js @@ -0,0 +1,179 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var assert = require('assert'); +var mocha = require('mocha'); +var should = require('should'); +var sinon = require('sinon'); + +// Test includes +var testutil = require('../../util/util'); + +var HDInsightUtil = require('./hdinsight-util.js'); + +var azure = testutil.libRequire('azure'); +var hdInsightUtil; + +describe('HDInsight listClusters', function() { + var storageAccounts; + var sqlServers; + + var storage1Name = "azurehdxstrtst00"; + var storage2Name = "azurehdxstrtst01"; + var foundStorage1 = false; + var foundStorage2 = false; + + var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; + var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; + var serviceMan = azure.createServiceManagementService(subscriptionId, auth); + var sqlMan = azure.createSqlManagementService(subscriptionId, auth); + var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); + var hdInsight = azure.createHDInsightService(subscriptionId, auth); + var WebResource = require('../../../lib/http/webresource'); + var _performRequestSpy; + var _performRequestOriginal; + + // var createStorageAccountAndWait = function (name, next) { + // serviceMan.listStorageAccounts(function (err, response)) { + // } + // }; + + beforeEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + afterEach(function (done) { + hdInsightUtil.NoStubProcessRequest(); + done(); + }); + + after(function (done) { + hdInsightUtil.Revert(); + done(); + }); + + // NOTE: To Do, we should actually create new acounts for our tests + // So that we can work on any existing subscription. + before (function (done) { + hdInsightUtil = new HDInsightUtil(HDInsight); + // this._performRequestOriginal = hdInsight._performRequest; + // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); + // hdInsight._performRequest = this._performRequestSpy; + // this._performRequestOriginal.should.eql(''); + // false.should.be.eql(true); + // console.log(typeof(hdInsight._performRequest)); + // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { + // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // // callback({ error: null, response: response }, function(responseObject, finalCallback) { + // finalCallback(responseObject); + // }); + // }); + + // serviceMan.listStorageAccounts(function (err, response) { + // should.not.exist(err); + // should.exist(response.body); + // // // response.body.length.should.eql(2); + // // for(var i in response.body) + // // { + // // if (response.body[i].ServiceName === storage1Name) + // // { + // // foundStorage1 = true; + // // } + // // else if (response.body[i].ServiceName === storage2Name) + // // { + // // foundStorage2 = true; + // // } + // // } + // // if (!foundStorage1) + // // { + // // var options = {}; + // // options.Location = 'East US'; + // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { + // // "asdf".should.eql(response); + // // done(err); + // // }); + // // } + // storageAccounts = response.body; + + // sqlMan.listServers(function (err, response) { + // should.not.exist(err); + // should.exists(response); + // // response.length.should.eql(2); + // sqlServers = response; + // done(err); + // }); + // }); + done(); + }); + + + it('should run tests', function (done) { + var result; + // hdInsightUtil.StubProcessRequestWithError(403, 'Unauthorized', 'You are not authorized'); + result = { + CloudServices: { + CloudService: [ + { Name: 'not-hdinsight' } , + { + Name: 'hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2', + GeoRegion: 'East US 2', + Resources: { + Resource: [ + { + ResourceProviderNamespace: 'hdinsight', + Type: 'containers', + Name: 'tsthdx00hdxcibld02', + State: 'Started', + SubState: 'Running' + }, + { + ResourceProviderNamespace: 'not-hdinsight' + } + ] + } + } + ] + } + }; + + hdInsightUtil.StubProcessRequestWithSuccess(result); + hdInsight.listClusters(function (err, response) { + console.log(err); + console.log(response); + should.not.exist(err); + should.exist(response.body.CloudServices.CloudService); + response.body.CloudServices.CloudService.length.should.eql(1); + response.body.CloudServices.CloudService[0].Resources.Resource.length.should.eql(1); + response.body.CloudServices.CloudService[0].Resources.Resource[0].Name.should.eql('tsthdx00hdxcibld02'); + done(err); + }); + }); + + it('should list storage accounts', function (done) { + var result; + + hdInsight.listClusters(function (err, response) { + console.log(err); + console.log(response); + should.not.exist(err); + // response.bar.should.eql('foo'); + response.should.eql(''); + // response.length.should.eql(2); + done(err); + }); + }); + +}); diff --git a/test/services/HDInsight/hdinsight-util.js b/test/services/HDInsight/hdinsight-util.js index 8412bffe90..c25ef79fa9 100644 --- a/test/services/HDInsight/hdinsight-util.js +++ b/test/services/HDInsight/hdinsight-util.js @@ -13,9 +13,73 @@ * limitations under the License. */ -var exports = module.exports; +var testutil = require('../../util/util'); +var mockData = null; -exports.AzureHDInsightSubscriptionId = function () -{ - return process.env['AZURE_SUBSCRIPTION_ID']; -} \ No newline at end of file +var sinon = require('sinon'); +var _performRequestOriginal; +var _performRequestStub; +var _originalClass; + +function HDInsightUtil(originalClass) { + _originalClass = originalClass; + _performRequestOriginal = originalClass.prototype._performRequest; + console.log(_performRequestOriginal); + originalClass.prototype._performRequestOriginal = originalClass.prototype._performRequest; + _performRequestStub = sinon.stub(originalClass.prototype, '_performRequest', function(webResource, body, options, callback) { + var response; + var result; + if (!mockData) { + this._performRequestOriginal(webResource, body, options, callback); + } + else if (mockData.errorCode) { + response = { + isSuccessful: false, + statusCode: mockData.statusCode, + body: { Error: { '$': {}, Code: mockData.errorCode, Message: mockData.message } } + }; + + var err = []; + err['Error'] = mockData.message; + err.code = mockData.errorCode; + result = { error: err, response: response }; + callback(result, function(responseObject, finalCallback) { + finalCallback(responseObject); + }); + } + else if (mockData.body) { + response = { + isSuccessful: true, + statusCode: 200, + body: mockData.body + }; + result = { error: null, response: response }; + callback(result, function(responseObject, finalCallback) { + finalCallback(responseObject); + }); + } + }); + originalClass.prototype._performRequest = _performRequestStub; + // hdInsight._performRequest = function(webResource, body, options, callback) { + // if (!isMocked) { + // _performRequestOriginal(webResource, body, options, callback); + // } +} + +module.exports = HDInsightUtil; + +HDInsightUtil.prototype.StubProcessRequestWithError = function(statusCode, errorCode, message) { + mockData = { statusCode: statusCode, errorCode: errorCode, message: message }; +}; + +HDInsightUtil.prototype.NoStubProcessRequest = function() { + mockData = null; +}; + +HDInsightUtil.prototype.StubProcessRequestWithSuccess = function(body) { + mockData = { body: body }; +}; + +HDInsightUtil.prototype.Revert = function() { + _originalClass.prototype._performRequest = _performRequestOriginal; +}; \ No newline at end of file diff --git a/test/testlist.txt b/test/testlist.txt index 7c1e90f2b7..39c5ae4582 100644 --- a/test/testlist.txt +++ b/test/testlist.txt @@ -43,4 +43,4 @@ # util/util-tests.js # util/validate-tests.js # azure-tests.js -services/HDInsight/hdinsight-tests.js \ No newline at end of file +services/HDInsight/hdinsight-listClusters-unit-tests.js \ No newline at end of file From 93004ebef1803d31487ceb3983c7165e34745e60 Mon Sep 17 00:00:00 2001 From: tistocks Date: Tue, 7 May 2013 19:08:21 -0700 Subject: [PATCH 04/11] more unit tests for listClusters --- .../HDInsight/PerformRequestStubUtil.js | 94 ++++++++++++ .../hdinsight-listClusters-unit-tests.js | 138 +++++++++--------- test/services/HDInsight/hdinsight-tests.js | 90 +----------- test/services/HDInsight/namespace-tests.js | 3 +- test/services/HDInsight/namespace-util.js | 66 +++++---- test/testlist.txt | 4 +- 6 files changed, 207 insertions(+), 188 deletions(-) create mode 100644 test/services/HDInsight/PerformRequestStubUtil.js diff --git a/test/services/HDInsight/PerformRequestStubUtil.js b/test/services/HDInsight/PerformRequestStubUtil.js new file mode 100644 index 0000000000..1162250fad --- /dev/null +++ b/test/services/HDInsight/PerformRequestStubUtil.js @@ -0,0 +1,94 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var mockData = null; + +var sinon = require('sinon'); +var _performRequestOriginal; +var _performRequestStub; +var _originalClass; +var _lastWebResource; + +function PerformRequestStubUtil(originalClass) { + _originalClass = originalClass; + _performRequestOriginal = originalClass.prototype._performRequest; + originalClass.prototype._performRequestOriginal = originalClass.prototype._performRequest; + _performRequestStub = sinon.stub(originalClass.prototype, '_performRequest', function(webResource, body, options, callback) { + _lastWebResource = webResource; + var response; + var result; + if (!mockData) { + this._performRequestOriginal(webResource, body, options, callback); + } + else if (mockData.errorCode) { + response = { + isSuccessful: false, + statusCode: mockData.statusCode, + body: { Error: { '$': {}, Code: mockData.errorCode, Message: mockData.message } } + }; + + var err = []; + err['Error'] = mockData.message; + err.code = mockData.errorCode; + result = { error: err, response: response }; + callback(result, function(responseObject, finalCallback) { + finalCallback(responseObject); + }); + } + else if (mockData.body) { + response = { + isSuccessful: true, + statusCode: 200, + body: mockData.body + }; + result = { error: null, response: response }; + callback(result, function(responseObject, finalCallback) { + finalCallback(responseObject); + }); + } + }); + originalClass.prototype._performRequest = _performRequestStub; + // hdInsight._performRequest = function(webResource, body, options, callback) { + // if (!isMocked) { + // _performRequestOriginal(webResource, body, options, callback); + // } +} + +module.exports = PerformRequestStubUtil; + +PerformRequestStubUtil.prototype.GetLastWebResource = function() { + return _lastWebResource; +}; + +PerformRequestStubUtil.prototype.StubAuthenticationFailed = function() { + var msg = 'The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.'; + this.StubProcessRequestWithError(403, 'AuthenticationFailed', msg); +} + +PerformRequestStubUtil.prototype.StubProcessRequestWithError = function(statusCode, errorCode, message) { + mockData = { statusCode: statusCode, errorCode: errorCode, message: message }; +}; + +PerformRequestStubUtil.prototype.NoStubProcessRequest = function() { + mockData = null; +}; + +PerformRequestStubUtil.prototype.StubProcessRequestWithSuccess = function(body) { + mockData = { body: body }; +}; + +PerformRequestStubUtil.prototype.Revert = function() { + _originalClass.prototype._performRequest = _performRequestOriginal; +}; \ No newline at end of file diff --git a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js index 3243f4dd20..affe33869c 100644 --- a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js +++ b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js @@ -13,37 +13,23 @@ * limitations under the License. */ -var assert = require('assert'); var mocha = require('mocha'); var should = require('should'); -var sinon = require('sinon'); +var _ = require('underscore'); // Test includes var testutil = require('../../util/util'); -var HDInsightUtil = require('./hdinsight-util.js'); +var PerformRequestStubUtil = require('./PerformRequestStubUtil.js'); var azure = testutil.libRequire('azure'); -var hdInsightUtil; - -describe('HDInsight listClusters', function() { - var storageAccounts; - var sqlServers; - - var storage1Name = "azurehdxstrtst00"; - var storage2Name = "azurehdxstrtst01"; - var foundStorage1 = false; - var foundStorage2 = false; +var performRequestStubUtil; +describe('HDInsight listClusters (under unit test)', function() { var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; - var serviceMan = azure.createServiceManagementService(subscriptionId, auth); - var sqlMan = azure.createSqlManagementService(subscriptionId, auth); var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); - var WebResource = require('../../../lib/http/webresource'); - var _performRequestSpy; - var _performRequestOriginal; // var createStorageAccountAndWait = function (name, next) { // serviceMan.listStorageAccounts(function (err, response)) { @@ -51,75 +37,28 @@ describe('HDInsight listClusters', function() { // }; beforeEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); + performRequestStubUtil.NoStubProcessRequest(); done(); }); afterEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); + performRequestStubUtil.NoStubProcessRequest(); done(); }); after(function (done) { - hdInsightUtil.Revert(); + performRequestStubUtil.Revert(); done(); }); // NOTE: To Do, we should actually create new acounts for our tests // So that we can work on any existing subscription. before (function (done) { - hdInsightUtil = new HDInsightUtil(HDInsight); - // this._performRequestOriginal = hdInsight._performRequest; - // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); - // hdInsight._performRequest = this._performRequestSpy; - // this._performRequestOriginal.should.eql(''); - // false.should.be.eql(true); - // console.log(typeof(hdInsight._performRequest)); - // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { - // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // finalCallback(responseObject); - // }); - // }); - - // serviceMan.listStorageAccounts(function (err, response) { - // should.not.exist(err); - // should.exist(response.body); - // // // response.body.length.should.eql(2); - // // for(var i in response.body) - // // { - // // if (response.body[i].ServiceName === storage1Name) - // // { - // // foundStorage1 = true; - // // } - // // else if (response.body[i].ServiceName === storage2Name) - // // { - // // foundStorage2 = true; - // // } - // // } - // // if (!foundStorage1) - // // { - // // var options = {}; - // // options.Location = 'East US'; - // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { - // // "asdf".should.eql(response); - // // done(err); - // // }); - // // } - // storageAccounts = response.body; - - // sqlMan.listServers(function (err, response) { - // should.not.exist(err); - // should.exists(response); - // // response.length.should.eql(2); - // sqlServers = response; - // done(err); - // }); - // }); + performRequestStubUtil = new PerformRequestStubUtil(HDInsight); done(); }); - var result = { + var goodResult = { CloudServices: { CloudService: [ { Name: 'not-hdinsight' } , @@ -145,8 +84,63 @@ describe('HDInsight listClusters', function() { } }; + var singleResult = { + CloudServices: { + CloudService: { + Name: 'hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2', + GeoRegion: 'East US 2', + Resources: { + Resource: { + ResourceProviderNamespace: 'hdinsight', + Type: 'containers', + Name: 'tsthdx00hdxcibld02', + State: 'Started', + SubState: 'Running' + } + } + } + } + }; + + it('should pass the error to the callback function', function(done) { + performRequestStubUtil.StubAuthenticationFailed(); + hdInsight.listClusters(function (err, response) { + should.exist(err); + response.statusCode.should.be.eql(403); + done(); + }); + }); + + it('should turn single cloudservice items and resource items into arrays', function(done) { + performRequestStubUtil.StubProcessRequestWithSuccess(singleResult); + hdInsight.listClusters(function (err, response) { + should.not.exist(err); + should.exist(response.body.CloudServices.CloudService); + _.isArray(response.body.CloudServices.CloudService).should.be.eql(true); + response.body.CloudServices.CloudService.length.should.be.eql(1); + should.exist(response.body.CloudServices.CloudService[0].Resources.Resource); + _.isArray(response.body.CloudServices.CloudService).should.be.eql(true); + response.body.CloudServices.CloudService.length.should.be.eql(1); + done(err); + }); + }); + + it('should provide the right headers for the request', function(done) { + performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); + hdInsight.listClusters(function (err) { + var webResource = performRequestStubUtil.GetLastWebResource(); + should.exist(webResource); + webResource.path.should.be.eql('/' + subscriptionId + '/cloudservices'); + webResource.httpVerb.should.be.eql('GET'); + _.size(webResource.headers).should.be.eql(2); + webResource.headers['x-ms-version'].should.be.eql('2011-08-18'); + webResource.headers['accept'].should.be.eql('application/xml'); + done(err); + }); + }); + it('should remove CloudServices not related to HDInsight', function (done) { - hdInsightUtil.StubProcessRequestWithSuccess(result); + performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); hdInsight.listClusters(function (err, response) { should.not.exist(err); should.exist(response.body.CloudServices.CloudService); @@ -157,7 +151,7 @@ describe('HDInsight listClusters', function() { }); it('should remove resources not representing a cluster', function (done) { - hdInsightUtil.StubProcessRequestWithSuccess(result); + performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); hdInsight.listClusters(function (err, response) { should.not.exist(err); should.exist(response.body.CloudServices.CloudService); diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 2cafd2fc8c..138896d994 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -21,7 +21,7 @@ var sinon = require('sinon'); // Test includes var testutil = require('../../util/util'); -var HDInsightUtil = require('./hdinsight-util.js'); +var HDInsightUtil = require('./PerformRequestStubUtil.js'); var azure = testutil.libRequire('azure'); var hdInsightUtil; @@ -39,112 +39,34 @@ describe('HDInsight Test', function() { var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var serviceMan = azure.createServiceManagementService(subscriptionId, auth); var sqlMan = azure.createSqlManagementService(subscriptionId, auth); - var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); - var WebResource = require('../../../lib/http/webresource'); + var _performRequestSpy; var _performRequestOriginal; - // var createStorageAccountAndWait = function (name, next) { - // serviceMan.listStorageAccounts(function (err, response)) { - // } - // }; - beforeEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); done(); }); afterEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); done(); }); after(function (done) { - hdInsightUtil.Revert(); done(); }); - // NOTE: To Do, we should actually create new acounts for our tests - // So that we can work on any existing subscription. before (function (done) { - hdInsightUtil = new HDInsightUtil(HDInsight); - // this._performRequestOriginal = hdInsight._performRequest; - // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); - // hdInsight._performRequest = this._performRequestSpy; - // this._performRequestOriginal.should.eql(''); - // false.should.be.eql(true); - // console.log(typeof(hdInsight._performRequest)); - // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { - // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // finalCallback(responseObject); - // }); - // }); - - // serviceMan.listStorageAccounts(function (err, response) { - // should.not.exist(err); - // should.exist(response.body); - // // // response.body.length.should.eql(2); - // // for(var i in response.body) - // // { - // // if (response.body[i].ServiceName === storage1Name) - // // { - // // foundStorage1 = true; - // // } - // // else if (response.body[i].ServiceName === storage2Name) - // // { - // // foundStorage2 = true; - // // } - // // } - // // if (!foundStorage1) - // // { - // // var options = {}; - // // options.Location = 'East US'; - // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { - // // "asdf".should.eql(response); - // // done(err); - // // }); - // // } - // storageAccounts = response.body; - - // sqlMan.listServers(function (err, response) { - // should.not.exist(err); - // should.exists(response); - // // response.length.should.eql(2); - // sqlServers = response; - // done(err); - // }); - // }); done(); }); - it('should run tests', function (done) { - var result; - // hdInsightUtil.StubProcessRequestWithError(403, 'Unauthorized', 'You are not authorized'); - hdInsightUtil.StubProcessRequestWithSuccess("foo"); - hdInsight.listClusters(function (err, response) { - console.log(err); - console.log(response); - should.not.exist(err); - // response.bar.should.eql('foo'); - response.should.eql(''); - // response.length.should.eql(2); - done(err); - }); - }); - - it('should list storage accounts', function (done) { - var result; - + it('should be able to list clusters', function (done) { hdInsight.listClusters(function (err, response) { - console.log(err); - console.log(response); should.not.exist(err); - // response.bar.should.eql('foo'); - response.should.eql(''); - // response.length.should.eql(2); + should.exist(response.body.CloudServices); + should.exist(response.body.CloudServices.CloudService); + response.body.CloudServices.CloudService.length.should.be.above(0); done(err); }); }); diff --git a/test/services/HDInsight/namespace-tests.js b/test/services/HDInsight/namespace-tests.js index d3ef485ed1..6686931a7f 100644 --- a/test/services/HDInsight/namespace-tests.js +++ b/test/services/HDInsight/namespace-tests.js @@ -14,7 +14,7 @@ */ // Test functions -var namespace = require('./namespace-util.js'); +var HDInsightNamespace = require('./namespace-util.js'); // Test includes var assert = require('assert'); @@ -22,6 +22,7 @@ var assert = require('assert'); describe('HDInsight Namespace Test', function() { it('GetNameSpace', function (done) { + var namespace = new HDInsightNamespace(); var subscriptionId = "0bf0b5da-dc38-4795-8595-3170ffefec48"; var expected = "hdinsightC2D4FSA77HSYSQLRU4V73NKI3YH2OYHQXACMRGPECIHSH7FXTUAQ-East-US"; diff --git a/test/services/HDInsight/namespace-util.js b/test/services/HDInsight/namespace-util.js index 5c86c8dd3f..e0b63b4a13 100644 --- a/test/services/HDInsight/namespace-util.js +++ b/test/services/HDInsight/namespace-util.js @@ -16,38 +16,44 @@ // External dependencies var crypto = require('crypto'); -function GetNameSpace(subscriptionId, prefix, location) { - location = location.replace(" ", "-"); - var hash = crypto.createHash('sha256').update(new Buffer(subscriptionId, 'utf-8')).digest("hex"); - return prefix + Base32NoPaddingEncode(new Buffer(hash, "hex")) + "-" + location; -} - -var base32StandardAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"; -function _Base32NoPaddingEncode (data) { - - var result = ""; - for (var i = 0; i < data.length; i+=5) { - - // Process input 5 bytes at a time - var multiplier = 256; - var loopValue = 0; - for (var j = Math.min(data.length-1, i+4); j >= i ; j--) { - loopValue += data[j] * multiplier; - multiplier = multiplier * 256; - } +function HDInsightNamespace() { - // Converts them into base32 - var bytes = Math.min(data.length - i, 5); - for (var bitOffset = (bytes+1)*8 - 5; bitOffset > 3; bitOffset -= 5) { - result += base32StandardAlphabet[LongUnsignedRor(loopValue,bitOffset) & 0x1f]; - } +} - } +function _LongUnsignedRor(value, count) { + for(var i = 0; i= i ; j--) { + loopValue += data[j] * multiplier; + multiplier = multiplier * 256; + } + + // Converts them into base32 + var bytes = Math.min(data.length - i, 5); + for (var bitOffset = (bytes+1)*8 - 5; bitOffset > 3; bitOffset -= 5) { + var index = _LongUnsignedRor(loopValue,bitOffset) % 32; + result += base32StandardAlphabet[index]; + } + } + return result; } -function _LongUnsignedRor(value, count) { - for(var i = 0; i Date: Tue, 7 May 2013 19:08:47 -0700 Subject: [PATCH 05/11] removed unused files --- .../HDInsight/hdinsight-unit-tests.js | 179 ------------------ test/services/HDInsight/hdinsight-util.js | 85 --------- 2 files changed, 264 deletions(-) delete mode 100644 test/services/HDInsight/hdinsight-unit-tests.js delete mode 100644 test/services/HDInsight/hdinsight-util.js diff --git a/test/services/HDInsight/hdinsight-unit-tests.js b/test/services/HDInsight/hdinsight-unit-tests.js deleted file mode 100644 index c93602710d..0000000000 --- a/test/services/HDInsight/hdinsight-unit-tests.js +++ /dev/null @@ -1,179 +0,0 @@ -/** -* Copyright (c) Microsoft. All rights reserved. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -var assert = require('assert'); -var mocha = require('mocha'); -var should = require('should'); -var sinon = require('sinon'); - -// Test includes -var testutil = require('../../util/util'); - -var HDInsightUtil = require('./hdinsight-util.js'); - -var azure = testutil.libRequire('azure'); -var hdInsightUtil; - -describe('HDInsight listClusters', function() { - var storageAccounts; - var sqlServers; - - var storage1Name = "azurehdxstrtst00"; - var storage2Name = "azurehdxstrtst01"; - var foundStorage1 = false; - var foundStorage2 = false; - - var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; - var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; - var serviceMan = azure.createServiceManagementService(subscriptionId, auth); - var sqlMan = azure.createSqlManagementService(subscriptionId, auth); - var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); - var hdInsight = azure.createHDInsightService(subscriptionId, auth); - var WebResource = require('../../../lib/http/webresource'); - var _performRequestSpy; - var _performRequestOriginal; - - // var createStorageAccountAndWait = function (name, next) { - // serviceMan.listStorageAccounts(function (err, response)) { - // } - // }; - - beforeEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); - done(); - }); - - afterEach(function (done) { - hdInsightUtil.NoStubProcessRequest(); - done(); - }); - - after(function (done) { - hdInsightUtil.Revert(); - done(); - }); - - // NOTE: To Do, we should actually create new acounts for our tests - // So that we can work on any existing subscription. - before (function (done) { - hdInsightUtil = new HDInsightUtil(HDInsight); - // this._performRequestOriginal = hdInsight._performRequest; - // this._performRequestSpy = sinon.spy(hdInsight, '_performRequest'); - // hdInsight._performRequest = this._performRequestSpy; - // this._performRequestOriginal.should.eql(''); - // false.should.be.eql(true); - // console.log(typeof(hdInsight._performRequest)); - // hdInsight._performRequest = sinon.stub(hdInsight, '_performRequest', function(a, b , c, callback) { - // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // // callback({ error: null, response: response }, function(responseObject, finalCallback) { - // finalCallback(responseObject); - // }); - // }); - - // serviceMan.listStorageAccounts(function (err, response) { - // should.not.exist(err); - // should.exist(response.body); - // // // response.body.length.should.eql(2); - // // for(var i in response.body) - // // { - // // if (response.body[i].ServiceName === storage1Name) - // // { - // // foundStorage1 = true; - // // } - // // else if (response.body[i].ServiceName === storage2Name) - // // { - // // foundStorage2 = true; - // // } - // // } - // // if (!foundStorage1) - // // { - // // var options = {}; - // // options.Location = 'East US'; - // // serviceMan.createStorageAccount(storage1Name, options, function(err, response) { - // // "asdf".should.eql(response); - // // done(err); - // // }); - // // } - // storageAccounts = response.body; - - // sqlMan.listServers(function (err, response) { - // should.not.exist(err); - // should.exists(response); - // // response.length.should.eql(2); - // sqlServers = response; - // done(err); - // }); - // }); - done(); - }); - - - it('should run tests', function (done) { - var result; - // hdInsightUtil.StubProcessRequestWithError(403, 'Unauthorized', 'You are not authorized'); - result = { - CloudServices: { - CloudService: [ - { Name: 'not-hdinsight' } , - { - Name: 'hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2', - GeoRegion: 'East US 2', - Resources: { - Resource: [ - { - ResourceProviderNamespace: 'hdinsight', - Type: 'containers', - Name: 'tsthdx00hdxcibld02', - State: 'Started', - SubState: 'Running' - }, - { - ResourceProviderNamespace: 'not-hdinsight' - } - ] - } - } - ] - } - }; - - hdInsightUtil.StubProcessRequestWithSuccess(result); - hdInsight.listClusters(function (err, response) { - console.log(err); - console.log(response); - should.not.exist(err); - should.exist(response.body.CloudServices.CloudService); - response.body.CloudServices.CloudService.length.should.eql(1); - response.body.CloudServices.CloudService[0].Resources.Resource.length.should.eql(1); - response.body.CloudServices.CloudService[0].Resources.Resource[0].Name.should.eql('tsthdx00hdxcibld02'); - done(err); - }); - }); - - it('should list storage accounts', function (done) { - var result; - - hdInsight.listClusters(function (err, response) { - console.log(err); - console.log(response); - should.not.exist(err); - // response.bar.should.eql('foo'); - response.should.eql(''); - // response.length.should.eql(2); - done(err); - }); - }); - -}); diff --git a/test/services/HDInsight/hdinsight-util.js b/test/services/HDInsight/hdinsight-util.js deleted file mode 100644 index c25ef79fa9..0000000000 --- a/test/services/HDInsight/hdinsight-util.js +++ /dev/null @@ -1,85 +0,0 @@ -/** -* Copyright (c) Microsoft. All rights reserved. -* -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -var testutil = require('../../util/util'); -var mockData = null; - -var sinon = require('sinon'); -var _performRequestOriginal; -var _performRequestStub; -var _originalClass; - -function HDInsightUtil(originalClass) { - _originalClass = originalClass; - _performRequestOriginal = originalClass.prototype._performRequest; - console.log(_performRequestOriginal); - originalClass.prototype._performRequestOriginal = originalClass.prototype._performRequest; - _performRequestStub = sinon.stub(originalClass.prototype, '_performRequest', function(webResource, body, options, callback) { - var response; - var result; - if (!mockData) { - this._performRequestOriginal(webResource, body, options, callback); - } - else if (mockData.errorCode) { - response = { - isSuccessful: false, - statusCode: mockData.statusCode, - body: { Error: { '$': {}, Code: mockData.errorCode, Message: mockData.message } } - }; - - var err = []; - err['Error'] = mockData.message; - err.code = mockData.errorCode; - result = { error: err, response: response }; - callback(result, function(responseObject, finalCallback) { - finalCallback(responseObject); - }); - } - else if (mockData.body) { - response = { - isSuccessful: true, - statusCode: 200, - body: mockData.body - }; - result = { error: null, response: response }; - callback(result, function(responseObject, finalCallback) { - finalCallback(responseObject); - }); - } - }); - originalClass.prototype._performRequest = _performRequestStub; - // hdInsight._performRequest = function(webResource, body, options, callback) { - // if (!isMocked) { - // _performRequestOriginal(webResource, body, options, callback); - // } -} - -module.exports = HDInsightUtil; - -HDInsightUtil.prototype.StubProcessRequestWithError = function(statusCode, errorCode, message) { - mockData = { statusCode: statusCode, errorCode: errorCode, message: message }; -}; - -HDInsightUtil.prototype.NoStubProcessRequest = function() { - mockData = null; -}; - -HDInsightUtil.prototype.StubProcessRequestWithSuccess = function(body) { - mockData = { body: body }; -}; - -HDInsightUtil.prototype.Revert = function() { - _originalClass.prototype._performRequest = _performRequestOriginal; -}; \ No newline at end of file From f38283ca68c374d86f217b3e6f704afc4c59c412 Mon Sep 17 00:00:00 2001 From: tistocks Date: Tue, 21 May 2013 15:05:24 -0700 Subject: [PATCH 06/11] Added Create and cleaned up test data --- .../hdinsightnamespaceutils.js | 0 .../serviceManagement/hdinsightservice.js | 226 ++++ .../HDInsight/PerformRequestStubUtil.js | 8 +- .../hdinsight-createCluster-unit-tests.js | 1152 +++++++++++++++++ .../hdinsight-listClusters-unit-tests.js | 24 +- .../HDInsight/hdinsight-test-utils.js | 110 ++ test/services/HDInsight/hdinsight-tests.js | 58 +- .../HDInsight/hdinsight-unit-tests.js | 115 ++ test/services/HDInsight/namespace-tests.js | 2 +- test/testlist.txt | 6 +- 10 files changed, 1667 insertions(+), 34 deletions(-) rename test/services/HDInsight/namespace-util.js => lib/services/serviceManagement/hdinsightnamespaceutils.js (100%) create mode 100644 test/services/HDInsight/hdinsight-createCluster-unit-tests.js create mode 100644 test/services/HDInsight/hdinsight-test-utils.js create mode 100644 test/services/HDInsight/hdinsight-unit-tests.js diff --git a/test/services/HDInsight/namespace-util.js b/lib/services/serviceManagement/hdinsightnamespaceutils.js similarity index 100% rename from test/services/HDInsight/namespace-util.js rename to lib/services/serviceManagement/hdinsightnamespaceutils.js diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js index a5280b859d..34151bc3c5 100644 --- a/lib/services/serviceManagement/hdinsightservice.js +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -15,9 +15,12 @@ // Module dependencies. var util = require('util'); +var js2xml = require('../../util/js2xml'); var _ = require('underscore'); +var uuid = require('node-uuid'); var ServiceManagementClient = require('../core/servicemanagementclient'); +var HDInsightNamespace = require('./hdinsightnamespaceutils.js'); // var js2xml = require('../../util/js2xml'); // var Constants = require('../../util/constants'); @@ -61,6 +64,229 @@ util.inherits(HDInsightService, ServiceManagementClient); var WebResource = require('../../http/webresource'); +function isInt(value){ + if((parseFloat(value) == parseInt(value, 10)) && !isNaN(value)) { + return true; + } + else { + return false; + } +} + +HDInsightService.prototype.validateCreationObject = function (clusterCreationObject) { + if (!clusterCreationObject.name || typeof(clusterCreationObject.name) != 'string') { + throw new Error('The [name] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.location || typeof(clusterCreationObject.location) != 'string') { + throw new Error('The [location] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.defaultStorageAccountName || typeof(clusterCreationObject.defaultStorageAccountName) != 'string') { + throw new Error('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.defaultStorageAccountKey || typeof(clusterCreationObject.defaultStorageAccountKey) != 'string') { + throw new Error('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.defaultStorageContainer || typeof(clusterCreationObject.defaultStorageContainer) != 'string') { + throw new Error('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.user || typeof(clusterCreationObject.user) != 'string') { + throw new Error('The [user] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.password || typeof(clusterCreationObject.password) != 'string') { + throw new Error('The [password] field is required when creating a cluster and must be a string'); + } + if (!clusterCreationObject.nodes || typeof(clusterCreationObject.nodes) != 'number' || !isInt(clusterCreationObject.nodes)) { + throw new Error('The [nodes] field is required when creating a cluster and must be an integer'); + } + if (clusterCreationObject.additionalStorageAccounts) { + if (!_.isArray(clusterCreationObject.additionalStorageAccounts)) { + throw new Error('The [additionalStorageAccounts] field is optional when creating a cluster but must be an array when specified'); + } + for (var i = 0; i < clusterCreationObject.additionalStorageAccounts.length; i++) { + var account = clusterCreationObject.additionalStorageAccounts[i]; + if (!account.name || typeof(account.name) != 'string') { + throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element ' + i + ' does not have a [name] field or it is not a string'); + } + if (!account.key || typeof(account.key) != 'string') { + throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element ' + i + ' does not have a [key] field or it is not a string'); + } + } + } + if (clusterCreationObject.oozieMetastore) { + if (!clusterCreationObject.hiveMetastore) { + throw new Error('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); + } + if (!clusterCreationObject.oozieMetastore.server || typeof(clusterCreationObject.oozieMetastore.server) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); + } + if (!clusterCreationObject.oozieMetastore.database || typeof(clusterCreationObject.oozieMetastore.database) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); + } + if (!clusterCreationObject.oozieMetastore.user || typeof(clusterCreationObject.oozieMetastore.user) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); + } + if (!clusterCreationObject.oozieMetastore.password || typeof(clusterCreationObject.oozieMetastore.password) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); + } + } + if (clusterCreationObject.hiveMetastore) { + if (!clusterCreationObject.oozieMetastore) { + throw new Error('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); + } + if (!clusterCreationObject.hiveMetastore.server || typeof(clusterCreationObject.hiveMetastore.server) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); + } + if (!clusterCreationObject.hiveMetastore.database || typeof(clusterCreationObject.hiveMetastore.database) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); + } + if (!clusterCreationObject.hiveMetastore.user || typeof(clusterCreationObject.hiveMetastore.user) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); + } + if (!clusterCreationObject.hiveMetastore.password || typeof(clusterCreationObject.hiveMetastore.password) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); + } + } +}; + +HDInsightService.prototype.convertCreationObject = function (clusterCreationObject) { + var payload = { + Resource : { + '$' : { 'xmlns' : 'http://schemas.microsoft.com/windowsazure' }, + IntrinsicSettings : { + ClusterContainer : { + '$' : { xmlns : 'http://schemas.datacontract.org/2004/07/Microsoft.ClusterServices.DataAccess.Context' }, + AzureStorageLocation : clusterCreationObject.location, + Deployment : { + ASVAccounts : { + ASVAccount : [{ + AccountName : clusterCreationObject.defaultStorageAccountName, + BlobContainerName : clusterCreationObject.defaultStorageContainer, + SecretKey : clusterCreationObject.defaultStorageAccountKey + }] + }, + ClusterPassword : clusterCreationObject.password, + ClusterUsername : clusterCreationObject.user, + NodeSizes : { + ClusterNodeSize : [ + { + Count : 1, + RoleType : 'HeadNode', + VMSize : 'ExtraLarge' + }, + { + Count : clusterCreationObject.nodes, + RoleType : 'DataNode', + VMSize : 'Large' + } + ] + }, + SqlMetaStores : { }, + Version : 'default' + }, + DeploymentAction : 'Create', + DnsName : clusterCreationObject.name, + IncarnationID : uuid.v4(), + SubscriptionId : this.subscriptionId + } + } + } + }; + if (clusterCreationObject.additionalStorageAccounts) { + for (var i = 0; i < clusterCreationObject.additionalStorageAccounts.length; i++) { + var account = { + AccountName : clusterCreationObject.additionalStorageAccounts[i].name, + BlobContainerName : 'deployment1', + SecretKey : clusterCreationObject.additionalStorageAccounts[i].key + }; + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount.push(account); + } + } + if (clusterCreationObject.oozieMetastore) { + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.SqlMetaStores.SqlAzureMetaStore = []; + var oozieMetastore = { + '$' : { xmlns: 'http://schemas.datacontract.org/2004/07/Microsoft.ClusterServices.DataAccess' }, + AzureServerName : clusterCreationObject.oozieMetastore.server, + DatabaseName : clusterCreationObject.oozieMetastore.database, + Password : clusterCreationObject.oozieMetastore.password, + Type : 'OozieMetastore', + Username : clusterCreationObject.oozieMetastore.user + }; + var hiveMetastore = { + '$' : { xmlns: 'http://schemas.datacontract.org/2004/07/Microsoft.ClusterServices.DataAccess' }, + AzureServerName : clusterCreationObject.hiveMetastore.server, + DatabaseName : clusterCreationObject.hiveMetastore.database, + Password : clusterCreationObject.hiveMetastore.password, + Type : 'OozieMetastore', + Username : clusterCreationObject.hiveMetastore.user + }; + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.SqlMetaStores.SqlAzureMetaStore.push(oozieMetastore); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.SqlMetaStores.SqlAzureMetaStore.push(hiveMetastore); + } + return payload; +}; + +HDInsightService.prototype.deleteCluster = function (callback) { + callback('ERROR', null); +}; + +/** +* +* Creates a new HDInsight Cluster +* +* @param {object} clusterCreationObject // The details of the cluster to create +* { +* // the following are required fields +* name: 'the name of the cluster (dns name) all lower case', +* location: 'the Azure data center where the cluster is to be created', +* defaultStorageAccountName: 'The name of the default Azure storage account', +* defaultStorageAccountKey: 'The secret key for the default Azure storage account', +* defaultStorageContainer: 'The container for the default Azure storage account', +* user: 'The username to use for the cluster', +* password: 'The password to use for the cluster', +* nodes: number // The number of nodes to use +* // the following are optional fields +* additionalStorageAccounts : [ { +* name: 'the name of the storage acount' +* key: 'the secret key for the storage acount' +* }, { // additional accounts following the same pattern } +* ] +* // the following are optional but if one is specified the other is required +* oozieMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* hiveMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* } +* @param {function} callback +* +* +* +*/ +HDInsightService.prototype.createCluster = function (clusterCreationObject, callback) { + this.validateCreationObject(clusterCreationObject); + var payload = this.convertCreationObject(clusterCreationObject); + var namespaceUtil = new HDInsightNamespace(); + var regionCloudServiceName = namespaceUtil.GetNameSpace(this.subscriptionId, 'hdinsight' , 'East US'); + var path = '/' + this.subscriptionId + '/cloudservices/' + regionCloudServiceName + '/resources/hdinsight/containers/' + payload.Resource.IntrinsicSettings.ClusterContainer.DnsName; + var webResource = WebResource.put(path); + webResource.withHeader('x-ms-version', '2011-08-18'); + webResource.withHeader('accept', 'application/xml'); + this.performRequest(webResource, js2xml.serialize(payload), null, function (responseObject, next) { + var finalCallback = function (returnObject) { + callback(returnObject.error, returnObject.response); + }; + + next(responseObject, finalCallback); + }); +}; + HDInsightService.prototype.listClusters = function (callback) { var path = '/' + this.subscriptionId + '/cloudservices'; var webResource = WebResource.get(path); diff --git a/test/services/HDInsight/PerformRequestStubUtil.js b/test/services/HDInsight/PerformRequestStubUtil.js index 1162250fad..e09b95f9df 100644 --- a/test/services/HDInsight/PerformRequestStubUtil.js +++ b/test/services/HDInsight/PerformRequestStubUtil.js @@ -72,12 +72,12 @@ PerformRequestStubUtil.prototype.GetLastWebResource = function() { return _lastWebResource; }; -PerformRequestStubUtil.prototype.StubAuthenticationFailed = function() { +PerformRequestStubUtil.prototype.StubAuthenticationFailed = function(url) { var msg = 'The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.'; - this.StubProcessRequestWithError(403, 'AuthenticationFailed', msg); + this.StubProcessRequestWithError(url, 403, 'AuthenticationFailed', msg); } -PerformRequestStubUtil.prototype.StubProcessRequestWithError = function(statusCode, errorCode, message) { +PerformRequestStubUtil.prototype.StubProcessRequestWithError = function(url, statusCode, errorCode, message) { mockData = { statusCode: statusCode, errorCode: errorCode, message: message }; }; @@ -85,7 +85,7 @@ PerformRequestStubUtil.prototype.NoStubProcessRequest = function() { mockData = null; }; -PerformRequestStubUtil.prototype.StubProcessRequestWithSuccess = function(body) { +PerformRequestStubUtil.prototype.StubProcessRequestWithSuccess = function(url, body) { mockData = { body: body }; }; diff --git a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js new file mode 100644 index 0000000000..9a122d61d9 --- /dev/null +++ b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js @@ -0,0 +1,1152 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var mocha = require('mocha'); +var should = require('should'); +var assert = require('assert'); +var _ = require('underscore'); +var HDInsightTestUtils = require('./hdinsight-test-utils.js') + +// Test includes +var testutil = require('../../util/util'); + +var PerformRequestStubUtil = require('./PerformRequestStubUtil.js'); + +var azure = testutil.libRequire('azure'); +var performRequestStubUtil; + +describe('HDInsight createCluster (under unit test)', function() { + var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; + var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; + var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); + var hdInsight = azure.createHDInsightService(subscriptionId, auth); + var hdinsightTestUtils = new HDInsightTestUtils(); + var creds; + + beforeEach(function (done) { + performRequestStubUtil.NoStubProcessRequest(); + done(); + }); + + afterEach(function (done) { + performRequestStubUtil.NoStubProcessRequest(); + done(); + }); + + after(function (done) { + performRequestStubUtil.Revert(); + done(); + }); + + // NOTE: To Do, we should actually create new acounts for our tests + // So that we can work on any existing subscription. + before (function (done) { + performRequestStubUtil = new PerformRequestStubUtil(HDInsight); + hdinsightTestUtils.getTestCredentialData(function (result) { + should.exist(result); + creds = result; + done(); + }); + }); + + it('should validate the name field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = {}; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [name] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the name field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [name] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the location field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [location] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the location field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [location] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageAccountName field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageAccountName field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageAccountKey field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageAccountKey field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageContainer field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the defaultStorageContainer field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the user field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [user] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the user field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [user] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the password field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [password] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the password field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 4 + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [password] field is required when creating a cluster and must be a string'); + } + }) + + it('should validate the nodes field of the clusterCreationObject is not undefined', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [nodes] field is required when creating a cluster and must be an integer'); + } + }) + + it('should validate the nodes field of the clusterCreationObject is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 'not a number' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [nodes] field is required when creating a cluster and must be an integer'); + } + }) + + it('should validate the additionalStorageAccounts field of the clusterCreationObject is an array', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [additionalStorageAccounts] field is optional when creating a cluster but must be an array when specified'); + } + }) + + it('should validate the additionalStorageAccounts elements contain a name field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ }] + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element 0 does not have a [name] field or it is not a string'); + } + }) + + it('should validate the additionalStorageAccounts elements contain a name field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 4 + }] + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element 0 does not have a [name] field or it is not a string'); + } + }) + + it('should validate the additionalStorageAccounts elements contain a key field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name' + }] + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element 0 does not have a [key] field or it is not a string'); + } + }) + + it('should validate the additionalStorageAccounts elements contain a key field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 4 + }] + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element 0 does not have a [key] field or it is not a string'); + } + }) + + it('should validate that if an oozie metastore is provided then a hive metastore is also provided', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); + } + }) + + it('should validate that if a hive metastore is provided then an oozie metastore is also provided', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a server field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : {}, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a server field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 4 + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a database field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : "server" + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a database field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 4 + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a user field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : "server", + database : 'database' + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a user field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 4 + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a password field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user' + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); + } + }) + + it('should validate that if an oozie metastore is provided then it contains a password field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 4 + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); + } + }) + + + it('should validate that if an hive metastore is provided then it contains a server field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : {} + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a server field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 4 + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a database field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a database field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + database : 4 + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a user field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + database : 'database' + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a user field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + database : 'database', + user : 4 + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a password field', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + database : 'database', + user : 'user', + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); + } + }) + + it('should validate that if an hive metastore is provided then it contains a password field and it is a string', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'deploy1', + user : 'user', + password : 'password', + nodes : 4, + additionalStorageAccounts : [{ + name : 'name', + key : 'KEY' + }], + oozieMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 'password' + }, + hiveMetastore : { + server : 'server', + database : 'database', + user : 'user', + password : 4 + } + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); + } + }) + + it('should convert the the clusterCreationObject with no additionalStorageAccounts and no metastores to the proper payload object', function() { + performRequestStubUtil.StubAuthenticationFailed("http://test"); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'defaultAccount', + defaultStorageAccountKey : 'defaultKEY', + defaultStorageContainer : 'defaultContainer', + user : 'user', + password : 'password', + nodes : 4, + }; + var payload = hdInsight.convertCreationObject(clusterCreationObject); + should.exist(payload.Resource); + should.exist(payload.Resource.$); + should.exist(payload.Resource.$.xmlns); + payload.Resource.$.xmlns.should.be.eql('http://schemas.microsoft.com/windowsazure'); + should.exist(payload.Resource.IntrinsicSettings); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.$); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.$.xmlns); + payload.Resource.IntrinsicSettings.ClusterContainer.$.xmlns.should.be.eql('http://schemas.datacontract.org/2004/07/Microsoft.ClusterServices.DataAccess.Context'); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount.should.be.an.instanceOf(Array); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount.length.should.be.eql(1); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount[0]); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount[0].AccountName.should.be.eql('defaultAccount'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount[0].BlobContainerName.should.be.eql('defaultContainer'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ASVAccounts.ASVAccount[0].SecretKey.should.be.eql('defaultKEY'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ClusterPassword.should.be.eql('password'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.ClusterUsername.should.be.eql('user'); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes); + should.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize.should.be.an.instanceOf(Array); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize.length.should.be.eql(2); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[0].Count.should.be.eql(1); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[0].RoleType.should.be.eql('HeadNode'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[0].VMSize.should.be.eql('ExtraLarge'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[1].Count.should.be.eql(4); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[1].RoleType.should.be.eql('DataNode'); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.NodeSizes.ClusterNodeSize[1].VMSize.should.be.eql('Large'); + should.not.exist(payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.SqlMetaStores.SqlAzureMetaStore); + payload.Resource.IntrinsicSettings.ClusterContainer.Deployment.Version.should.be.eql('default'); + payload.Resource.IntrinsicSettings.ClusterContainer.DeploymentAction.should.be.eql('Create'); + payload.Resource.IntrinsicSettings.ClusterContainer.DnsName.should.be.eql('test'); + // TODO: validate that the IncarnationID is a properly formated guid. + // payload.Resource.IntrinsicSettings.ClusterContainer.IncarnationID. should.be.a.guid(); + payload.Resource.IntrinsicSettings.ClusterContainer.SubscriptionId.should.be.eql(subscriptionId); + }) +}); diff --git a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js index affe33869c..3aefae421d 100644 --- a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js +++ b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js @@ -16,6 +16,7 @@ var mocha = require('mocha'); var should = require('should'); var _ = require('underscore'); +var HDInsightTestUtils = require('./hdinsight-test-utils.js') // Test includes var testutil = require('../../util/util'); @@ -30,11 +31,8 @@ describe('HDInsight listClusters (under unit test)', function() { var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); - - // var createStorageAccountAndWait = function (name, next) { - // serviceMan.listStorageAccounts(function (err, response)) { - // } - // }; + var hdinsightTestUtils = new HDInsightTestUtils(); + var creds; beforeEach(function (done) { performRequestStubUtil.NoStubProcessRequest(); @@ -55,7 +53,11 @@ describe('HDInsight listClusters (under unit test)', function() { // So that we can work on any existing subscription. before (function (done) { performRequestStubUtil = new PerformRequestStubUtil(HDInsight); - done(); + hdinsightTestUtils.getTestCredentialData(function (result) { + should.exist(result); + creds = result; + done(); + }); }); var goodResult = { @@ -103,7 +105,7 @@ describe('HDInsight listClusters (under unit test)', function() { }; it('should pass the error to the callback function', function(done) { - performRequestStubUtil.StubAuthenticationFailed(); + performRequestStubUtil.StubAuthenticationFailed('http://test.com'); hdInsight.listClusters(function (err, response) { should.exist(err); response.statusCode.should.be.eql(403); @@ -112,7 +114,7 @@ describe('HDInsight listClusters (under unit test)', function() { }); it('should turn single cloudservice items and resource items into arrays', function(done) { - performRequestStubUtil.StubProcessRequestWithSuccess(singleResult); + performRequestStubUtil.StubProcessRequestWithSuccess('http://test.com', singleResult); hdInsight.listClusters(function (err, response) { should.not.exist(err); should.exist(response.body.CloudServices.CloudService); @@ -126,7 +128,7 @@ describe('HDInsight listClusters (under unit test)', function() { }); it('should provide the right headers for the request', function(done) { - performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); + performRequestStubUtil.StubProcessRequestWithSuccess('http://test.com', goodResult); hdInsight.listClusters(function (err) { var webResource = performRequestStubUtil.GetLastWebResource(); should.exist(webResource); @@ -140,7 +142,7 @@ describe('HDInsight listClusters (under unit test)', function() { }); it('should remove CloudServices not related to HDInsight', function (done) { - performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); + performRequestStubUtil.StubProcessRequestWithSuccess('http://test.com', goodResult); hdInsight.listClusters(function (err, response) { should.not.exist(err); should.exist(response.body.CloudServices.CloudService); @@ -151,7 +153,7 @@ describe('HDInsight listClusters (under unit test)', function() { }); it('should remove resources not representing a cluster', function (done) { - performRequestStubUtil.StubProcessRequestWithSuccess(goodResult); + performRequestStubUtil.StubProcessRequestWithSuccess('http://test.com', goodResult); hdInsight.listClusters(function (err, response) { should.not.exist(err); should.exist(response.body.CloudServices.CloudService); diff --git a/test/services/HDInsight/hdinsight-test-utils.js b/test/services/HDInsight/hdinsight-test-utils.js new file mode 100644 index 0000000000..ac8b5a3de6 --- /dev/null +++ b/test/services/HDInsight/hdinsight-test-utils.js @@ -0,0 +1,110 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var fs = require('fs'); +var xml2js = require('xml2js'); +var _ = require('underscore'); + + +function HDInsightTestUtils() { +} + +module.exports = HDInsightTestUtils; + +HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { + var file = process.env['AZURE_HDINSIGHT_CREDENTIALFILE']; + var parser = new xml2js.Parser(); + fs.readFile(file, 'utf-8', function(err, data) { + parser.parseString(data, function(err, result) { + var creds = result.ArrayOfAzureTestCredentials.AzureTestCredentials; + if (!_.isArray(creds)) { + creds = [ + creds + ]; + } + var retval = { }; + for (var i = 0; i < creds.length; i++) { + var cred = { + credsName : creds[i].CredentialsName, + subscriptionId : creds[i].SubscriptionId, + dnsName : creds[i].DnsName, + cluster : creds[i].Cluster, + user : creds[i].AzureUserName, + password : creds[i].AzurePassword, + hadoopUserName : creds[i].HadoopUserName, + defaultStorageAccount : { + name : creds[i].DefaultStorageAccount.Name, + key : creds[i].DefaultStorageAccount.Key, + container : creds[i].DefaultStorageAccount.Container + } + }; + if (_.isArray(creds[i].AdditionalStorageAccounts)) { + creds[i].AdditionalStorageAccounts = creds[i].AdditionalStorageAccounts[0]; + } + var accounts = creds[i].AdditionalStorageAccounts.StorageAccountCredentials; + if (!_.isArray(accounts)) { + accounts = [ accounts ]; + } + cred.additionalStorageAccounts = []; + for (var j = 0; j < accounts.length; j++) { + var account = { + name : accounts[j].Name, + key : accounts[j].Key, + container : accounts[j].Container + }; + cred.additionalStorageAccounts.push(account); + } + if (_.isArray(creds[i].OozieStores)) { + creds[i].OozieStores = creds[i].OozieStores[0]; + } + var oozies = creds[i].OozieStores.MetastoreCredentials; + if (!_.isArray(oozies)) { + oozies = [ oozies ]; + } + cred.oozieStores = []; + for (j = 0; j < oozies.length; j++) { + var oozie = { + description : oozies[j].Description, + server : oozies[j].SqlServer, + database : oozies[j].Database, + user : oozies[j].UserName, + password : oozies[j].Password + }; + cred.oozieStores.push(oozie); + } + if (_.isArray(creds[i].HiveStores)) { + creds[i].HiveStores = creds[i].HiveStores[0]; + } + var hives = creds[i].HiveStores.MetastoreCredentials; + if (!_.isArray(hives)) { + hives = [ hives ]; + } + cred.hiveStores = []; + for (j = 0; j < hives.length; j++) { + var hive = { + description : hives[j].Description, + server : hives[j].SqlServer, + database : hives[j].Database, + user : hives[j].UserName, + password : hives[j].Password + }; + cred.hiveStores.push(hive); + } + retval[cred.credsName] = cred; + } + callback(retval); + }); + }); +}; diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 138896d994..1bb46f421f 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -17,6 +17,7 @@ var assert = require('assert'); var mocha = require('mocha'); var should = require('should'); var sinon = require('sinon'); +var HDInsightTestUtils = require('./hdinsight-test-utils.js') // Test includes var testutil = require('../../util/util'); @@ -27,22 +28,11 @@ var azure = testutil.libRequire('azure'); var hdInsightUtil; describe('HDInsight Test', function() { - var storageAccounts; - var sqlServers; - - var storage1Name = "azurehdxstrtst00"; - var storage2Name = "azurehdxstrtst01"; - var foundStorage1 = false; - var foundStorage2 = false; - var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; - var serviceMan = azure.createServiceManagementService(subscriptionId, auth); - var sqlMan = azure.createSqlManagementService(subscriptionId, auth); - var hdInsight = azure.createHDInsightService(subscriptionId, auth); - - var _performRequestSpy; - var _performRequestOriginal; + var hdInsight; + var hdinsightTestUtils = new HDInsightTestUtils(); + var creds; beforeEach(function (done) { done(); @@ -57,9 +47,46 @@ describe('HDInsight Test', function() { }); before (function (done) { - done(); + hdinsightTestUtils.getTestCredentialData(function (result) { + should.exist(result); + creds = result; + hdInsight = azure.createHDInsightService(creds["default"].subscriptionId, auth); + done(); + }); }); + it('should be able to create a cluster', function (done) { + var cred = creds["default"]; + var clusterCreationObject = { + name : 'tistocks-jstest2', + location : 'East US', + defaultStorageAccountName : cred.defaultStorageAccount.name, + defaultStorageAccountKey : cred.defaultStorageAccount.key, + defaultStorageContainer : cred.defaultStorageAccount.container, + user : cred.user, + password : creds.password, + nodes : 4, + additionalStorageAccounts : [{ + name : cred.additionalStorageAccounts[0].name, + key : cred.additionalStorageAccounts[0].key + }], + oozieMetastore : { + server : cred.oozieStores[0].server, + database : cred.oozieStores[0].database, + user : cred.oozieStores[0].user, + password : cred.oozieStores[0].password + }, + hiveMetastore : { + server : cred.hiveStores[0].server, + database : cred.hiveStores[0].database, + user : cred.hiveStores[0].user, + password : cred.hiveStores[0].password + } + }; + hdInsight.createCluster(clusterCreationObject, function (err, response) { + done(err); + }); + }); it('should be able to list clusters', function (done) { hdInsight.listClusters(function (err, response) { @@ -70,5 +97,4 @@ describe('HDInsight Test', function() { done(err); }); }); - }); diff --git a/test/services/HDInsight/hdinsight-unit-tests.js b/test/services/HDInsight/hdinsight-unit-tests.js new file mode 100644 index 0000000000..cac85f739e --- /dev/null +++ b/test/services/HDInsight/hdinsight-unit-tests.js @@ -0,0 +1,115 @@ +/** +* Copyright (c) Microsoft. All rights reserved. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +var assert = require('assert'); +var mocha = require('mocha'); +var should = require('should'); +var sinon = require('sinon'); +var HDInsightTestUtils = require('./hdinsight-test-utils.js') + +// Test includes +var testutil = require('../../util/util'); + +var azure = testutil.libRequire('azure'); +var hdInsightUtil; + +describe('HDInsight listClusters', function() { + + var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; + var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; + var hdInsight = azure.createHDInsightService(subscriptionId, auth); + var hdinsightTestUtils = new HDInsightTestUtils(); + + beforeEach(function (done) { + done(); + }); + + afterEach(function (done) { + done(); + }); + + after(function (done) { + done(); + }); + + // NOTE: To Do, we should actually create new acounts for our tests + // So that we can work on any existing subscription. + before (function (done) { + done(); + }); + + it('should be able to access the credentail information', function() { + hdinsightTestUtils.getTestCredentialData(function (result) { + should.exist(result); + }); + }); + + // it('should run tests', function (done) { + // var result; + // // hdInsightUtil.StubProcessRequestWithError(403, 'Unauthorized', 'You are not authorized'); + // result = { + // CloudServices: { + // CloudService: [ + // { Name: 'not-hdinsight' } , + // { + // Name: 'hdinsightHRIEVKWCABCRT3AK64SGDGFJDR7EM64QV4T5UXU23MU6ZPCWG5NQ-East-US-2', + // GeoRegion: 'East US 2', + // Resources: { + // Resource: [ + // { + // ResourceProviderNamespace: 'hdinsight', + // Type: 'containers', + // Name: 'tsthdx00hdxcibld02', + // State: 'Started', + // SubState: 'Running' + // }, + // { + // ResourceProviderNamespace: 'not-hdinsight' + // } + // ] + // } + // } + // ] + // } + // }; + + // hdInsightUtil.StubProcessRequestWithSuccess(result); + // hdInsight.listClusters(function (err, response) { + // console.log(err); + // console.log(response); + // should.not.exist(err); + // should.exist(response.body.CloudServices.CloudService); + // response.body.CloudServices.CloudService.length.should.eql(1); + // response.body.CloudServices.CloudService[0].Resources.Resource.length.should.eql(1); + // response.body.CloudServices.CloudService[0].Resources.Resource[0].Name.should.eql('tsthdx00hdxcibld02'); + // done(err); + // }); + // }); + + // it('should list storage accounts', function (done) { + // var result; + + // hdInsight.listClusters(function (err, response) { + // console.log(err); + // console.log(response); + // should.not.exist(err); + // // response.bar.should.eql('foo'); + // response.should.eql(''); + // // response.length.should.eql(2); + // done(err); + // }); + // }); + +}); diff --git a/test/services/HDInsight/namespace-tests.js b/test/services/HDInsight/namespace-tests.js index 6686931a7f..29fd695e85 100644 --- a/test/services/HDInsight/namespace-tests.js +++ b/test/services/HDInsight/namespace-tests.js @@ -14,7 +14,7 @@ */ // Test functions -var HDInsightNamespace = require('./namespace-util.js'); +var HDInsightNamespace = require('../../../lib/services/serviceManagement/hdinsightnamespaceutils.js'); // Test includes var assert = require('assert'); diff --git a/test/testlist.txt b/test/testlist.txt index 9a6b10a5ea..59387f9084 100644 --- a/test/testlist.txt +++ b/test/testlist.txt @@ -43,6 +43,8 @@ # util/util-tests.js # util/validate-tests.js # azure-tests.js -services/HDInsight/hdinsight-tests.js +# services/HDInsight/hdinsight-tests.js +services/HDInsight/hdinsight-unit-tests.js services/HDInsight/hdinsight-listClusters-unit-tests.js -services/HDInsight/namespace-tests.js \ No newline at end of file +services/HDInsight/hdinsight-createCluster-unit-tests.js +# services/HDInsight/namespace-tests.js \ No newline at end of file From 6a2422cc477a5850a58df963d5dd7f13f863b9eb Mon Sep 17 00:00:00 2001 From: tistocks Date: Tue, 21 May 2013 15:24:30 -0700 Subject: [PATCH 07/11] fixed merge bug in /ib/util/util.js --- lib/util/util.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/util/util.js b/lib/util/util.js index 891f75776a..8ed69d06f1 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -344,7 +344,8 @@ exports.analyzeStream = function (stream, calculateMD5, callback) { callback(length, md5); }); - +}; + function pollRequest(channel, reqid, callback) {   channel.getOperationStatus(reqid, function(error, response) {     if (error) { From 4311268f23a1131377e860cb34edd05fa45dfcbb Mon Sep 17 00:00:00 2001 From: tistocks Date: Tue, 21 May 2013 16:15:47 -0700 Subject: [PATCH 08/11] added header and error test for create --- .../hdinsight-createCluster-unit-tests.js | 35 ++++-- .../HDInsight/hdinsight-test-utils.js | 102 ++++++++++++------ test/services/HDInsight/hdinsight-tests.js | 38 +------ .../HDInsight/hdinsight-unit-tests.js | 6 +- 4 files changed, 106 insertions(+), 75 deletions(-) diff --git a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js index 9a122d61d9..3c1e164983 100644 --- a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js +++ b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js @@ -17,7 +17,8 @@ var mocha = require('mocha'); var should = require('should'); var assert = require('assert'); var _ = require('underscore'); -var HDInsightTestUtils = require('./hdinsight-test-utils.js') +var HDInsightTestUtils = require('./hdinsight-test-utils.js'); +var HDInsightNamespace = require('../../../lib/services/serviceManagement/hdinsightnamespaceutils.js'); // Test includes var testutil = require('../../util/util'); @@ -33,7 +34,6 @@ describe('HDInsight createCluster (under unit test)', function() { var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); var hdinsightTestUtils = new HDInsightTestUtils(); - var creds; beforeEach(function (done) { performRequestStubUtil.NoStubProcessRequest(); @@ -54,13 +54,36 @@ describe('HDInsight createCluster (under unit test)', function() { // So that we can work on any existing subscription. before (function (done) { performRequestStubUtil = new PerformRequestStubUtil(HDInsight); - hdinsightTestUtils.getTestCredentialData(function (result) { - should.exist(result); - creds = result; + done(); + }); + + it('should pass the error to the callback function', function(done) { + performRequestStubUtil.StubAuthenticationFailed('http://test.com'); + var clusterCreationObject = hdinsightTestUtils.getDefaultWithAsvAndMetastores(); + hdInsight.createCluster(clusterCreationObject, function (err, response) { + should.exist(err); + response.statusCode.should.be.eql(403); done(); }); }); + it('should provide the right headers for the request', function(done) { + performRequestStubUtil.StubProcessRequestWithSuccess('http://test.com', {}); + var clusterCreationObject = hdinsightTestUtils.getDefaultWithAsvAndMetastores(); + hdInsight.createCluster(clusterCreationObject, function (err) { + var webResource = performRequestStubUtil.GetLastWebResource(); + should.exist(webResource); + var namespaceUtil = new HDInsightNamespace(); + var regionCloudServiceName = namespaceUtil.GetNameSpace(subscriptionId, 'hdinsight' , 'East US'); + webResource.path.should.be.eql('/' + subscriptionId + '/cloudservices/' + regionCloudServiceName + '/resources/hdinsight/containers/' + clusterCreationObject.name); + webResource.httpVerb.should.be.eql('PUT'); + _.size(webResource.headers).should.be.eql(2); + webResource.headers['x-ms-version'].should.be.eql('2011-08-18'); + webResource.headers['accept'].should.be.eql('application/xml'); + done(err); + }); + }); + it('should validate the name field of the clusterCreationObject is not undefined', function() { performRequestStubUtil.StubAuthenticationFailed("http://test"); var clusterCreationObject = {}; @@ -423,7 +446,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 4 }] }; diff --git a/test/services/HDInsight/hdinsight-test-utils.js b/test/services/HDInsight/hdinsight-test-utils.js index ac8b5a3de6..7b992a60ab 100644 --- a/test/services/HDInsight/hdinsight-test-utils.js +++ b/test/services/HDInsight/hdinsight-test-utils.js @@ -16,13 +16,57 @@ var fs = require('fs'); var xml2js = require('xml2js'); var _ = require('underscore'); - +var should = require('should'); +var creds; function HDInsightTestUtils() { + this.getTestCredentialData(function (result) { + creds = result; + should.exist(result); + }); } module.exports = HDInsightTestUtils; +HDInsightTestUtils.prototype.getDefaultCreds = function() { + return creds['default']; +}; + +HDInsightTestUtils.prototype.getDefaultWithAsvAndMetastores = function() { + return this.getCreationWithAsvAndMetastore('default'); +}; + +HDInsightTestUtils.prototype.getCreationWithAsvAndMetastore = function (name) { + var cred = creds[name]; + var clusterCreationObject = { + name : 'tistocks-jstest2', + location : 'East US', + defaultStorageAccountName : cred.defaultStorageAccount.name, + defaultStorageAccountKey : cred.defaultStorageAccount.key, + defaultStorageContainer : cred.defaultStorageAccount.container, + user : cred.user, + password : cred.password, + nodes : 4, + additionalStorageAccounts : [{ + name : cred.additionalStorageAccounts[0].name, + key : cred.additionalStorageAccounts[0].key + }], + oozieMetastore : { + server : cred.oozieStores[0].server, + database : cred.oozieStores[0].database, + user : cred.oozieStores[0].user, + password : cred.oozieStores[0].password + }, + hiveMetastore : { + server : cred.hiveStores[0].server, + database : cred.hiveStores[0].database, + user : cred.hiveStores[0].user, + password : cred.hiveStores[0].password + } + }; + return clusterCreationObject; +} + HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { var file = process.env['AZURE_HDINSIGHT_CREDENTIALFILE']; var parser = new xml2js.Parser(); @@ -37,17 +81,17 @@ HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { var retval = { }; for (var i = 0; i < creds.length; i++) { var cred = { - credsName : creds[i].CredentialsName, - subscriptionId : creds[i].SubscriptionId, - dnsName : creds[i].DnsName, - cluster : creds[i].Cluster, - user : creds[i].AzureUserName, - password : creds[i].AzurePassword, - hadoopUserName : creds[i].HadoopUserName, + credsName : creds[i].CredentialsName[0], + subscriptionId : creds[i].SubscriptionId[0], + dnsName : creds[i].DnsName[0], + cluster : creds[i].Cluster[0], + user : creds[i].AzureUserName[0], + password : creds[i].AzurePassword[0], + hadoopUserName : creds[i].HadoopUserName[0], defaultStorageAccount : { - name : creds[i].DefaultStorageAccount.Name, - key : creds[i].DefaultStorageAccount.Key, - container : creds[i].DefaultStorageAccount.Container + name : creds[i].DefaultStorageAccount[0].Name[0], + key : creds[i].DefaultStorageAccount[0].Key[0], + container : creds[i].DefaultStorageAccount[0].Container[0] } }; if (_.isArray(creds[i].AdditionalStorageAccounts)) { @@ -60,45 +104,39 @@ HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { cred.additionalStorageAccounts = []; for (var j = 0; j < accounts.length; j++) { var account = { - name : accounts[j].Name, - key : accounts[j].Key, - container : accounts[j].Container + name : accounts[j].Name[0], + key : accounts[j].Key[0], + container : accounts[j].Container[0] }; cred.additionalStorageAccounts.push(account); } - if (_.isArray(creds[i].OozieStores)) { - creds[i].OozieStores = creds[i].OozieStores[0]; - } - var oozies = creds[i].OozieStores.MetastoreCredentials; + var oozies = creds[i].OozieStores[0].MetastoreCredentials; if (!_.isArray(oozies)) { oozies = [ oozies ]; } cred.oozieStores = []; for (j = 0; j < oozies.length; j++) { var oozie = { - description : oozies[j].Description, - server : oozies[j].SqlServer, - database : oozies[j].Database, - user : oozies[j].UserName, - password : oozies[j].Password + description : oozies[j].Description[0], + server : oozies[j].SqlServer[0], + database : oozies[j].Database[0], + user : oozies[j].UserName[0], + password : oozies[j].Password[0] }; cred.oozieStores.push(oozie); } - if (_.isArray(creds[i].HiveStores)) { - creds[i].HiveStores = creds[i].HiveStores[0]; - } - var hives = creds[i].HiveStores.MetastoreCredentials; + var hives = creds[i].HiveStores[0].MetastoreCredentials; if (!_.isArray(hives)) { hives = [ hives ]; } cred.hiveStores = []; for (j = 0; j < hives.length; j++) { var hive = { - description : hives[j].Description, - server : hives[j].SqlServer, - database : hives[j].Database, - user : hives[j].UserName, - password : hives[j].Password + description : hives[j].Description[0], + server : hives[j].SqlServer[0], + database : hives[j].Database[0], + user : hives[j].UserName[0], + password : hives[j].Password[0] }; cred.hiveStores.push(hive); } diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 1bb46f421f..9415c5ec47 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -31,7 +31,7 @@ describe('HDInsight Test', function() { var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var hdInsight; - var hdinsightTestUtils = new HDInsightTestUtils(); + var hdInsightTestUtils = new HDInsightTestUtils(); var creds; beforeEach(function (done) { @@ -47,42 +47,12 @@ describe('HDInsight Test', function() { }); before (function (done) { - hdinsightTestUtils.getTestCredentialData(function (result) { - should.exist(result); - creds = result; - hdInsight = azure.createHDInsightService(creds["default"].subscriptionId, auth); - done(); - }); + hdInsight = azure.createHDInsightService(hdInsightTestUtils.getDefaultCreds().subscriptionId, auth); + done(); }); it('should be able to create a cluster', function (done) { - var cred = creds["default"]; - var clusterCreationObject = { - name : 'tistocks-jstest2', - location : 'East US', - defaultStorageAccountName : cred.defaultStorageAccount.name, - defaultStorageAccountKey : cred.defaultStorageAccount.key, - defaultStorageContainer : cred.defaultStorageAccount.container, - user : cred.user, - password : creds.password, - nodes : 4, - additionalStorageAccounts : [{ - name : cred.additionalStorageAccounts[0].name, - key : cred.additionalStorageAccounts[0].key - }], - oozieMetastore : { - server : cred.oozieStores[0].server, - database : cred.oozieStores[0].database, - user : cred.oozieStores[0].user, - password : cred.oozieStores[0].password - }, - hiveMetastore : { - server : cred.hiveStores[0].server, - database : cred.hiveStores[0].database, - user : cred.hiveStores[0].user, - password : cred.hiveStores[0].password - } - }; + var cred = hdInsightTestUtils.getDefaultWithAsvAndMetastores(); hdInsight.createCluster(clusterCreationObject, function (err, response) { done(err); }); diff --git a/test/services/HDInsight/hdinsight-unit-tests.js b/test/services/HDInsight/hdinsight-unit-tests.js index cac85f739e..7519e221c6 100644 --- a/test/services/HDInsight/hdinsight-unit-tests.js +++ b/test/services/HDInsight/hdinsight-unit-tests.js @@ -51,9 +51,9 @@ describe('HDInsight listClusters', function() { }); it('should be able to access the credentail information', function() { - hdinsightTestUtils.getTestCredentialData(function (result) { - should.exist(result); - }); + // hdinsightTestUtils.getTestCredentialData(function (result) { + // should.exist(result); + // }); }); // it('should run tests', function (done) { From 07779a954fb2eb79f14ecc36491a4b136205cea2 Mon Sep 17 00:00:00 2001 From: tistocks Date: Wed, 22 May 2013 12:22:32 -0700 Subject: [PATCH 09/11] cleaned up the test cases and removed some unnecissary code --- .../serviceManagement/hdinsightservice.js | 36 +-- .../HDInsight/PerformRequestStubUtil.js | 2 +- .../hdinsight-createCluster-unit-tests.js | 213 +++++++++--------- .../HDInsight/hdinsight-test-utils.js | 4 +- test/services/HDInsight/hdinsight-tests.js | 10 +- test/services/HDInsight/namespace-tests.js | 30 +-- 6 files changed, 144 insertions(+), 151 deletions(-) diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js index 34151bc3c5..d5b45bb863 100644 --- a/lib/services/serviceManagement/hdinsightservice.js +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -74,28 +74,28 @@ function isInt(value){ } HDInsightService.prototype.validateCreationObject = function (clusterCreationObject) { - if (!clusterCreationObject.name || typeof(clusterCreationObject.name) != 'string') { + if (typeof(clusterCreationObject.name) != 'string') { throw new Error('The [name] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.location || typeof(clusterCreationObject.location) != 'string') { + if (typeof(clusterCreationObject.location) != 'string') { throw new Error('The [location] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.defaultStorageAccountName || typeof(clusterCreationObject.defaultStorageAccountName) != 'string') { + if (typeof(clusterCreationObject.defaultStorageAccountName) != 'string') { throw new Error('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.defaultStorageAccountKey || typeof(clusterCreationObject.defaultStorageAccountKey) != 'string') { + if (typeof(clusterCreationObject.defaultStorageAccountKey) != 'string') { throw new Error('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.defaultStorageContainer || typeof(clusterCreationObject.defaultStorageContainer) != 'string') { + if (typeof(clusterCreationObject.defaultStorageContainer) != 'string') { throw new Error('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.user || typeof(clusterCreationObject.user) != 'string') { + if (typeof(clusterCreationObject.user) != 'string') { throw new Error('The [user] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.password || typeof(clusterCreationObject.password) != 'string') { + if (typeof(clusterCreationObject.password) != 'string') { throw new Error('The [password] field is required when creating a cluster and must be a string'); } - if (!clusterCreationObject.nodes || typeof(clusterCreationObject.nodes) != 'number' || !isInt(clusterCreationObject.nodes)) { + if (typeof(clusterCreationObject.nodes) != 'number' || !isInt(clusterCreationObject.nodes)) { throw new Error('The [nodes] field is required when creating a cluster and must be an integer'); } if (clusterCreationObject.additionalStorageAccounts) { @@ -104,10 +104,10 @@ HDInsightService.prototype.validateCreationObject = function (clusterCreationObj } for (var i = 0; i < clusterCreationObject.additionalStorageAccounts.length; i++) { var account = clusterCreationObject.additionalStorageAccounts[i]; - if (!account.name || typeof(account.name) != 'string') { + if (typeof(account.name) != 'string') { throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element ' + i + ' does not have a [name] field or it is not a string'); } - if (!account.key || typeof(account.key) != 'string') { + if (typeof(account.key) != 'string') { throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element ' + i + ' does not have a [key] field or it is not a string'); } } @@ -116,16 +116,16 @@ HDInsightService.prototype.validateCreationObject = function (clusterCreationObj if (!clusterCreationObject.hiveMetastore) { throw new Error('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); } - if (!clusterCreationObject.oozieMetastore.server || typeof(clusterCreationObject.oozieMetastore.server) != 'string') { + if (typeof(clusterCreationObject.oozieMetastore.server) != 'string') { throw new Error('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); } - if (!clusterCreationObject.oozieMetastore.database || typeof(clusterCreationObject.oozieMetastore.database) != 'string') { + if (typeof(clusterCreationObject.oozieMetastore.database) != 'string') { throw new Error('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); } - if (!clusterCreationObject.oozieMetastore.user || typeof(clusterCreationObject.oozieMetastore.user) != 'string') { + if (typeof(clusterCreationObject.oozieMetastore.user) != 'string') { throw new Error('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); } - if (!clusterCreationObject.oozieMetastore.password || typeof(clusterCreationObject.oozieMetastore.password) != 'string') { + if (typeof(clusterCreationObject.oozieMetastore.password) != 'string') { throw new Error('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); } } @@ -133,16 +133,16 @@ HDInsightService.prototype.validateCreationObject = function (clusterCreationObj if (!clusterCreationObject.oozieMetastore) { throw new Error('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); } - if (!clusterCreationObject.hiveMetastore.server || typeof(clusterCreationObject.hiveMetastore.server) != 'string') { + if (typeof(clusterCreationObject.hiveMetastore.server) != 'string') { throw new Error('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); } - if (!clusterCreationObject.hiveMetastore.database || typeof(clusterCreationObject.hiveMetastore.database) != 'string') { + if (typeof(clusterCreationObject.hiveMetastore.database) != 'string') { throw new Error('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); } - if (!clusterCreationObject.hiveMetastore.user || typeof(clusterCreationObject.hiveMetastore.user) != 'string') { + if (typeof(clusterCreationObject.hiveMetastore.user) != 'string') { throw new Error('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); } - if (!clusterCreationObject.hiveMetastore.password || typeof(clusterCreationObject.hiveMetastore.password) != 'string') { + if (typeof(clusterCreationObject.hiveMetastore.password) != 'string') { throw new Error('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); } } diff --git a/test/services/HDInsight/PerformRequestStubUtil.js b/test/services/HDInsight/PerformRequestStubUtil.js index e09b95f9df..091b5da28b 100644 --- a/test/services/HDInsight/PerformRequestStubUtil.js +++ b/test/services/HDInsight/PerformRequestStubUtil.js @@ -75,7 +75,7 @@ PerformRequestStubUtil.prototype.GetLastWebResource = function() { PerformRequestStubUtil.prototype.StubAuthenticationFailed = function(url) { var msg = 'The server failed to authenticate the request. Verify that the certificate is valid and is associated with this subscription.'; this.StubProcessRequestWithError(url, 403, 'AuthenticationFailed', msg); -} +}; PerformRequestStubUtil.prototype.StubProcessRequestWithError = function(url, statusCode, errorCode, message) { mockData = { statusCode: statusCode, errorCode: errorCode, message: message }; diff --git a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js index 3c1e164983..2859fcd1ce 100644 --- a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js +++ b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js @@ -15,7 +15,6 @@ var mocha = require('mocha'); var should = require('should'); -var assert = require('assert'); var _ = require('underscore'); var HDInsightTestUtils = require('./hdinsight-test-utils.js'); var HDInsightNamespace = require('../../../lib/services/serviceManagement/hdinsightnamespaceutils.js'); @@ -85,7 +84,7 @@ describe('HDInsight createCluster (under unit test)', function() { }); it('should validate the name field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = {}; try { @@ -96,10 +95,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [name] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the name field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 4 }; @@ -112,10 +111,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [name] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the location field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test' }; @@ -131,7 +130,7 @@ describe('HDInsight createCluster (under unit test)', function() { }) it('should validate the location field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 4 @@ -145,10 +144,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [location] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageAccountName field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US' @@ -162,10 +161,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageAccountName field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -180,14 +179,14 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageAccountKey field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', - defaultStorageAccountName : 'test', + defaultStorageAccountName : 'test' }; try { @@ -198,10 +197,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageAccountKey field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -217,15 +216,15 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageContainer field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', defaultStorageAccountName : 'test', - defaultStorageAccountKey : 'KEY', + defaultStorageAccountKey : 'KEY' }; try { @@ -236,10 +235,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the defaultStorageContainer field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -256,10 +255,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the user field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -276,10 +275,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [user] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the user field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -297,10 +296,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [user] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the password field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -318,10 +317,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [password] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the password field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -340,10 +339,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [password] field is required when creating a cluster and must be a string'); } - }) + }); it('should validate the nodes field of the clusterCreationObject is not undefined', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -362,10 +361,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [nodes] field is required when creating a cluster and must be an integer'); } - }) + }); it('should validate the nodes field of the clusterCreationObject is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -385,10 +384,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [nodes] field is required when creating a cluster and must be an integer'); } - }) + }); it('should validate the additionalStorageAccounts field of the clusterCreationObject is an array', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -409,10 +408,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [additionalStorageAccounts] field is optional when creating a cluster but must be an array when specified'); } - }) + }); it('should validate the additionalStorageAccounts elements contain a name field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -433,10 +432,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element 0 does not have a [name] field or it is not a string'); } - }) + }); it('should validate the additionalStorageAccounts elements contain a name field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -459,10 +458,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element 0 does not have a [name] field or it is not a string'); } - }) + }); it('should validate the additionalStorageAccounts elements contain a key field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -472,7 +471,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name' }] }; @@ -485,10 +484,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element 0 does not have a [key] field or it is not a string'); } - }) + }); it('should validate the additionalStorageAccounts elements contain a key field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -498,7 +497,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 4 }] @@ -512,10 +511,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element 0 does not have a [key] field or it is not a string'); } - }) + }); it('should validate that if an oozie metastore is provided then a hive metastore is also provided', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -525,7 +524,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -540,10 +539,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); } - }) + }); it('should validate that if a hive metastore is provided then an oozie metastore is also provided', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -553,7 +552,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -568,10 +567,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a server field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -581,7 +580,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -597,10 +596,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a server field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -610,7 +609,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -628,10 +627,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a database field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -641,12 +640,12 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], oozieMetastore : { - server : "server" + server : 'server' }, hiveMetastore : {} }; @@ -659,10 +658,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a database field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -672,7 +671,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -691,10 +690,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a user field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -704,12 +703,12 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], oozieMetastore : { - server : "server", + server : 'server', database : 'database' }, hiveMetastore : {} @@ -723,10 +722,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a user field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -736,7 +735,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -756,10 +755,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a password field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -769,7 +768,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -789,10 +788,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); } - }) + }); it('should validate that if an oozie metastore is provided then it contains a password field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -802,7 +801,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -823,11 +822,11 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a server field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -837,7 +836,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -858,10 +857,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a server field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -871,7 +870,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -894,10 +893,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a database field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -907,7 +906,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -918,7 +917,7 @@ describe('HDInsight createCluster (under unit test)', function() { password : 'password' }, hiveMetastore : { - server : 'server', + server : 'server' } }; try @@ -930,10 +929,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a database field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -943,7 +942,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -967,10 +966,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a user field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -980,7 +979,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -1004,10 +1003,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a user field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -1017,7 +1016,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -1042,10 +1041,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a password field', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -1055,7 +1054,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -1068,7 +1067,7 @@ describe('HDInsight createCluster (under unit test)', function() { hiveMetastore : { server : 'server', database : 'database', - user : 'user', + user : 'user' } }; try @@ -1080,10 +1079,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); } - }) + }); it('should validate that if an hive metastore is provided then it contains a password field and it is a string', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -1093,7 +1092,7 @@ describe('HDInsight createCluster (under unit test)', function() { user : 'user', password : 'password', nodes : 4, - additionalStorageAccounts : [{ + additionalStorageAccounts : [{ name : 'name', key : 'KEY' }], @@ -1119,10 +1118,10 @@ describe('HDInsight createCluster (under unit test)', function() { { error.message.should.be.eql('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); } - }) + }); it('should convert the the clusterCreationObject with no additionalStorageAccounts and no metastores to the proper payload object', function() { - performRequestStubUtil.StubAuthenticationFailed("http://test"); + performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { name : 'test', location : 'East US', @@ -1131,7 +1130,7 @@ describe('HDInsight createCluster (under unit test)', function() { defaultStorageContainer : 'defaultContainer', user : 'user', password : 'password', - nodes : 4, + nodes : 4 }; var payload = hdInsight.convertCreationObject(clusterCreationObject); should.exist(payload.Resource); @@ -1171,5 +1170,5 @@ describe('HDInsight createCluster (under unit test)', function() { // TODO: validate that the IncarnationID is a properly formated guid. // payload.Resource.IntrinsicSettings.ClusterContainer.IncarnationID. should.be.a.guid(); payload.Resource.IntrinsicSettings.ClusterContainer.SubscriptionId.should.be.eql(subscriptionId); - }) + }); }); diff --git a/test/services/HDInsight/hdinsight-test-utils.js b/test/services/HDInsight/hdinsight-test-utils.js index 7b992a60ab..e7fb9d0e43 100644 --- a/test/services/HDInsight/hdinsight-test-utils.js +++ b/test/services/HDInsight/hdinsight-test-utils.js @@ -65,10 +65,10 @@ HDInsightTestUtils.prototype.getCreationWithAsvAndMetastore = function (name) { } }; return clusterCreationObject; -} +}; HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { - var file = process.env['AZURE_HDINSIGHT_CREDENTIALFILE']; + var file = process.env['AZURE_HDINSIGHT_CREDENTIALFILE']; var parser = new xml2js.Parser(); fs.readFile(file, 'utf-8', function(err, data) { parser.parseString(data, function(err, result) { diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 9415c5ec47..0b08631748 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -16,23 +16,17 @@ var assert = require('assert'); var mocha = require('mocha'); var should = require('should'); -var sinon = require('sinon'); -var HDInsightTestUtils = require('./hdinsight-test-utils.js') +var HDInsightTestUtils = require('./hdinsight-test-utils.js'); // Test includes var testutil = require('../../util/util'); -var HDInsightUtil = require('./PerformRequestStubUtil.js'); - var azure = testutil.libRequire('azure'); -var hdInsightUtil; describe('HDInsight Test', function() { - var subscriptionId = process.env['AZURE_SUBSCRIPTION_ID']; var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var hdInsight; var hdInsightTestUtils = new HDInsightTestUtils(); - var creds; beforeEach(function (done) { done(); @@ -52,7 +46,7 @@ describe('HDInsight Test', function() { }); it('should be able to create a cluster', function (done) { - var cred = hdInsightTestUtils.getDefaultWithAsvAndMetastores(); + var clusterCreationObject = hdInsightTestUtils.getDefaultWithAsvAndMetastores(); hdInsight.createCluster(clusterCreationObject, function (err, response) { done(err); }); diff --git a/test/services/HDInsight/namespace-tests.js b/test/services/HDInsight/namespace-tests.js index 29fd695e85..8675f9f656 100644 --- a/test/services/HDInsight/namespace-tests.js +++ b/test/services/HDInsight/namespace-tests.js @@ -24,29 +24,29 @@ describe('HDInsight Namespace Test', function() { it('GetNameSpace', function (done) { var namespace = new HDInsightNamespace(); - var subscriptionId = "0bf0b5da-dc38-4795-8595-3170ffefec48"; - var expected = "hdinsightC2D4FSA77HSYSQLRU4V73NKI3YH2OYHQXACMRGPECIHSH7FXTUAQ-East-US"; - var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + var subscriptionId = '0bf0b5da-dc38-4795-8595-3170ffefec48'; + var expected = 'hdinsightC2D4FSA77HSYSQLRU4V73NKI3YH2OYHQXACMRGPECIHSH7FXTUAQ-East-US'; + var result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); - var subscriptionId = "c72f7fde-36ec-4cdf-93bf-43f90fe5373a"; - var expected = "hdinsightGTUVH76U5MNNGTJEFMKSGQMQO7AFBW52LMZPQ22R6UUXVWBDRBVA-East-US"; - var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + subscriptionId = 'c72f7fde-36ec-4cdf-93bf-43f90fe5373a'; + expected = 'hdinsightGTUVH76U5MNNGTJEFMKSGQMQO7AFBW52LMZPQ22R6UUXVWBDRBVA-East-US'; + result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); - var subscriptionId = "04066490-336b-4732-adfa-90ba5422cc84"; - var expected = "hdinsightXVS5S5SBDTTR7OJ4IOKGRTFM2M3P33KWPGP5SPYDJZYUMY73KOIQ-East-US"; - var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + subscriptionId = '04066490-336b-4732-adfa-90ba5422cc84'; + expected = 'hdinsightXVS5S5SBDTTR7OJ4IOKGRTFM2M3P33KWPGP5SPYDJZYUMY73KOIQ-East-US'; + result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); - var subscriptionId = "3cfbb7fc-1347-4eff-bf07-2e1f43084b00"; - var expected = "hdinsightVXFY2XGLQTT5PCJCDRKJXWE2W2PQZOJK3NLO4QSNHEKS32E6RM5A-East-US"; - var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + subscriptionId = '3cfbb7fc-1347-4eff-bf07-2e1f43084b00'; + expected = 'hdinsightVXFY2XGLQTT5PCJCDRKJXWE2W2PQZOJK3NLO4QSNHEKS32E6RM5A-East-US'; + result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); - var subscriptionId = "ee3733c1-5ebd-4a20-95ce-17dba36a071a"; - var expected = "hdinsightLDBRGOYTMVIJZ2ZAJZZTFFJD7N3MNFCJGONZO53VLK2V5GIEU2SQ-East-US"; - var result = namespace.GetNameSpace(subscriptionId, "hdinsight", "East US"); + subscriptionId = 'ee3733c1-5ebd-4a20-95ce-17dba36a071a'; + expected = 'hdinsightLDBRGOYTMVIJZ2ZAJZZTFFJD7N3MNFCJGONZO53VLK2V5GIEU2SQ-East-US'; + result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); done(); From 5671b6def5f0ac2071805428ad4138f8340b6566 Mon Sep 17 00:00:00 2001 From: tistocks Date: Wed, 22 May 2013 12:31:15 -0700 Subject: [PATCH 10/11] increased function comments --- .../serviceManagement/hdinsightservice.js | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js index d5b45bb863..29dfaa513e 100644 --- a/lib/services/serviceManagement/hdinsightservice.js +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -73,6 +73,42 @@ function isInt(value){ } } +/** +* +* Validates that a clusterCreationObject is properly formed. +* +* @param {object} clusterCreationObject The object used to supply all parameters needed to create a cluster. +* { +* // the following are required fields +* name: 'the name of the cluster (dns name) all lower case', +* location: 'the Azure data center where the cluster is to be created', +* defaultStorageAccountName: 'The name of the default Azure storage account', +* defaultStorageAccountKey: 'The secret key for the default Azure storage account', +* defaultStorageContainer: 'The container for the default Azure storage account', +* user: 'The username to use for the cluster', +* password: 'The password to use for the cluster', +* nodes: number // The number of nodes to use +* // the following are optional fields +* additionalStorageAccounts : [ { +* name: 'the name of the storage acount' +* key: 'the secret key for the storage acount' +* }, { // additional accounts following the same pattern } +* ] +* // the following are optional but if one is specified the other is required +* oozieMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* hiveMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* } +*/ HDInsightService.prototype.validateCreationObject = function (clusterCreationObject) { if (typeof(clusterCreationObject.name) != 'string') { throw new Error('The [name] field is required when creating a cluster and must be a string'); @@ -148,6 +184,42 @@ HDInsightService.prototype.validateCreationObject = function (clusterCreationObj } }; +/** +* +* Converts a cluster creation object into a playload that is actually sent to the server to create the cluster. +* +* @param {object} clusterCreationObject The object used to supply all parameters needed to create a cluster. +* { +* // the following are required fields +* name: 'the name of the cluster (dns name) all lower case', +* location: 'the Azure data center where the cluster is to be created', +* defaultStorageAccountName: 'The name of the default Azure storage account', +* defaultStorageAccountKey: 'The secret key for the default Azure storage account', +* defaultStorageContainer: 'The container for the default Azure storage account', +* user: 'The username to use for the cluster', +* password: 'The password to use for the cluster', +* nodes: number // The number of nodes to use +* // the following are optional fields +* additionalStorageAccounts : [ { +* name: 'the name of the storage acount' +* key: 'the secret key for the storage acount' +* }, { // additional accounts following the same pattern } +* ] +* // the following are optional but if one is specified the other is required +* oozieMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* hiveMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* } +*/ HDInsightService.prototype.convertCreationObject = function (clusterCreationObject) { var payload = { Resource : { @@ -270,6 +342,7 @@ HDInsightService.prototype.deleteCluster = function (callback) { * */ HDInsightService.prototype.createCluster = function (clusterCreationObject, callback) { + // Convert the simply form "clusterCreationObject" into the complex form "payload" needed by the server REST call. this.validateCreationObject(clusterCreationObject); var payload = this.convertCreationObject(clusterCreationObject); var namespaceUtil = new HDInsightNamespace(); @@ -287,6 +360,12 @@ HDInsightService.prototype.createCluster = function (clusterCreationObject, call }); }; +/** +* +* Lists all HDInsight clusters current existing on the subscription. +* @param {function} callback +* +*/ HDInsightService.prototype.listClusters = function (callback) { var path = '/' + this.subscriptionId + '/cloudservices'; var webResource = WebResource.get(path); From 911c3bd862ef81817337dcda5a97fb51f9f68631 Mon Sep 17 00:00:00 2001 From: tistocks Date: Wed, 22 May 2013 14:30:11 -0700 Subject: [PATCH 11/11] moved code arround per team standard --- .../serviceManagement/hdinsightservice.js | 128 +----------------- lib/util/util.js | 59 ++++++++ lib/util/validate.js | 114 ++++++++++++++++ package.json | 3 +- test/services/HDInsight/creds.xml | 63 +++++++++ .../hdinsight-createCluster-unit-tests.js | 20 +++ .../hdinsight-listClusters-unit-tests.js | 8 +- .../HDInsight/hdinsight-test-utils.js | 8 +- test/services/HDInsight/hdinsight-tests.js | 8 +- test/services/HDInsight/namespace-tests.js | 16 +-- test/testlist.txt | 4 +- 11 files changed, 284 insertions(+), 147 deletions(-) create mode 100644 test/services/HDInsight/creds.xml diff --git a/lib/services/serviceManagement/hdinsightservice.js b/lib/services/serviceManagement/hdinsightservice.js index 29dfaa513e..20e4e328a6 100644 --- a/lib/services/serviceManagement/hdinsightservice.js +++ b/lib/services/serviceManagement/hdinsightservice.js @@ -15,12 +15,13 @@ // Module dependencies. var util = require('util'); +var azureUtil = require('../../util/util.js'); var js2xml = require('../../util/js2xml'); var _ = require('underscore'); var uuid = require('node-uuid'); +var Validate = require('../../util/validate.js'); var ServiceManagementClient = require('../core/servicemanagementclient'); -var HDInsightNamespace = require('./hdinsightnamespaceutils.js'); // var js2xml = require('../../util/js2xml'); // var Constants = require('../../util/constants'); @@ -64,126 +65,6 @@ util.inherits(HDInsightService, ServiceManagementClient); var WebResource = require('../../http/webresource'); -function isInt(value){ - if((parseFloat(value) == parseInt(value, 10)) && !isNaN(value)) { - return true; - } - else { - return false; - } -} - -/** -* -* Validates that a clusterCreationObject is properly formed. -* -* @param {object} clusterCreationObject The object used to supply all parameters needed to create a cluster. -* { -* // the following are required fields -* name: 'the name of the cluster (dns name) all lower case', -* location: 'the Azure data center where the cluster is to be created', -* defaultStorageAccountName: 'The name of the default Azure storage account', -* defaultStorageAccountKey: 'The secret key for the default Azure storage account', -* defaultStorageContainer: 'The container for the default Azure storage account', -* user: 'The username to use for the cluster', -* password: 'The password to use for the cluster', -* nodes: number // The number of nodes to use -* // the following are optional fields -* additionalStorageAccounts : [ { -* name: 'the name of the storage acount' -* key: 'the secret key for the storage acount' -* }, { // additional accounts following the same pattern } -* ] -* // the following are optional but if one is specified the other is required -* oozieMetastore : { -* server : 'the name of the sql server to use', -* database : 'the sql databse to use' -* user : 'the user name to use when logging into the database' -* password : 'the password to use when logging into the database' -* } -* hiveMetastore : { -* server : 'the name of the sql server to use', -* database : 'the sql databse to use' -* user : 'the user name to use when logging into the database' -* password : 'the password to use when logging into the database' -* } -* } -*/ -HDInsightService.prototype.validateCreationObject = function (clusterCreationObject) { - if (typeof(clusterCreationObject.name) != 'string') { - throw new Error('The [name] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.location) != 'string') { - throw new Error('The [location] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.defaultStorageAccountName) != 'string') { - throw new Error('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.defaultStorageAccountKey) != 'string') { - throw new Error('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.defaultStorageContainer) != 'string') { - throw new Error('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.user) != 'string') { - throw new Error('The [user] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.password) != 'string') { - throw new Error('The [password] field is required when creating a cluster and must be a string'); - } - if (typeof(clusterCreationObject.nodes) != 'number' || !isInt(clusterCreationObject.nodes)) { - throw new Error('The [nodes] field is required when creating a cluster and must be an integer'); - } - if (clusterCreationObject.additionalStorageAccounts) { - if (!_.isArray(clusterCreationObject.additionalStorageAccounts)) { - throw new Error('The [additionalStorageAccounts] field is optional when creating a cluster but must be an array when specified'); - } - for (var i = 0; i < clusterCreationObject.additionalStorageAccounts.length; i++) { - var account = clusterCreationObject.additionalStorageAccounts[i]; - if (typeof(account.name) != 'string') { - throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element ' + i + ' does not have a [name] field or it is not a string'); - } - if (typeof(account.key) != 'string') { - throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element ' + i + ' does not have a [key] field or it is not a string'); - } - } - } - if (clusterCreationObject.oozieMetastore) { - if (!clusterCreationObject.hiveMetastore) { - throw new Error('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); - } - if (typeof(clusterCreationObject.oozieMetastore.server) != 'string') { - throw new Error('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); - } - if (typeof(clusterCreationObject.oozieMetastore.database) != 'string') { - throw new Error('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); - } - if (typeof(clusterCreationObject.oozieMetastore.user) != 'string') { - throw new Error('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); - } - if (typeof(clusterCreationObject.oozieMetastore.password) != 'string') { - throw new Error('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); - } - } - if (clusterCreationObject.hiveMetastore) { - if (!clusterCreationObject.oozieMetastore) { - throw new Error('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); - } - if (typeof(clusterCreationObject.hiveMetastore.server) != 'string') { - throw new Error('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); - } - if (typeof(clusterCreationObject.hiveMetastore.database) != 'string') { - throw new Error('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); - } - if (typeof(clusterCreationObject.hiveMetastore.user) != 'string') { - throw new Error('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); - } - if (typeof(clusterCreationObject.hiveMetastore.password) != 'string') { - throw new Error('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); - } - } -}; - /** * * Converts a cluster creation object into a playload that is actually sent to the server to create the cluster. @@ -343,10 +224,9 @@ HDInsightService.prototype.deleteCluster = function (callback) { */ HDInsightService.prototype.createCluster = function (clusterCreationObject, callback) { // Convert the simply form "clusterCreationObject" into the complex form "payload" needed by the server REST call. - this.validateCreationObject(clusterCreationObject); + Validate.isValidHDInsightCreationObject(clusterCreationObject); var payload = this.convertCreationObject(clusterCreationObject); - var namespaceUtil = new HDInsightNamespace(); - var regionCloudServiceName = namespaceUtil.GetNameSpace(this.subscriptionId, 'hdinsight' , 'East US'); + var regionCloudServiceName = azureUtil.getNameSpace(this.subscriptionId, 'hdinsight' , 'East US'); var path = '/' + this.subscriptionId + '/cloudservices/' + regionCloudServiceName + '/resources/hdinsight/containers/' + payload.Resource.IntrinsicSettings.ClusterContainer.DnsName; var webResource = WebResource.put(path); webResource.withHeader('x-ms-version', '2011-08-18'); diff --git a/lib/util/util.js b/lib/util/util.js index 8ed69d06f1..4dfb92c847 100644 --- a/lib/util/util.js +++ b/lib/util/util.js @@ -266,6 +266,65 @@ exports.tryGetValueInsensitive = function (key, haystack, defaultValue) { return defaultValue; }; +function _LongUnsignedRor(value, count) { + for(var i = 0; i= i ; j--) { + loopValue += data[j] * multiplier; + multiplier = multiplier * 256; + } + + // Converts them into base32 + var bytes = Math.min(data.length - i, 5); + for (var bitOffset = (bytes+1)*8 - 5; bitOffset > 3; bitOffset -= 5) { + var index = _LongUnsignedRor(loopValue,bitOffset) % 32; + result += base32StandardAlphabet[index]; + } + } + return result; +} + +/** +* Returns the namespace for a subscriptoinId, prefix and location +* +* @subscriptionId {string} The Azure subscription id. +* @prefix {string} The prifix for the service. +* @location {string} The location of the service. +* @return {Bool} True if the value is an integer number; false otherwise. +*/ +exports.getNameSpace = function (subscriptionId, prefix, location) { + location = location.replace(' ', '-'); + var hash = crypto.createHash('sha256').update(new Buffer(subscriptionId, 'utf-8')).digest('hex'); + return prefix + _Base32NoPaddingEncode(new Buffer(hash, 'hex')) + '-' + location; +}; + +/** +* Determines if a value (string or number) is an integer number. +* +* @param {object} The value to assess. +* @return {Bool} True if the value is an integer number; false otherwise. +*/ +exports.isInt = function (value){ + if((parseFloat(value) == parseInt(value, 10)) && !isNaN(value)) { + return true; + } + else { + return false; + } +}; + /** * Returns the value in a chained object. * diff --git a/lib/util/validate.js b/lib/util/validate.js index 57037f666f..c7caabf33b 100644 --- a/lib/util/validate.js +++ b/lib/util/validate.js @@ -36,6 +36,120 @@ exports.isValidUri = function (uri) { } }; +/** +* +* Validates that a clusterCreationObject is properly formed. +* +* @param {object} clusterCreationObject The object used to supply all parameters needed to create a cluster. +* { +* // the following are required fields +* name: 'the name of the cluster (dns name) all lower case', +* location: 'the Azure data center where the cluster is to be created', +* defaultStorageAccountName: 'The name of the default Azure storage account', +* defaultStorageAccountKey: 'The secret key for the default Azure storage account', +* defaultStorageContainer: 'The container for the default Azure storage account', +* user: 'The username to use for the cluster', +* password: 'The password to use for the cluster', +* nodes: number // The number of nodes to use +* // the following are optional fields +* additionalStorageAccounts : [ { +* name: 'the name of the storage acount' +* key: 'the secret key for the storage acount' +* }, { // additional accounts following the same pattern } +* ] +* // the following are optional but if one is specified the other is required +* oozieMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* hiveMetastore : { +* server : 'the name of the sql server to use', +* database : 'the sql databse to use' +* user : 'the user name to use when logging into the database' +* password : 'the password to use when logging into the database' +* } +* } +*/ +exports.isValidHDInsightCreationObject = function (clusterCreationObject) { + if (typeof(clusterCreationObject.name) != 'string') { + throw new Error('The [name] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.location) != 'string') { + throw new Error('The [location] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.defaultStorageAccountName) != 'string') { + throw new Error('The [defaultStorageAccountName] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.defaultStorageAccountKey) != 'string') { + throw new Error('The [defaultStorageAccountKey] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.defaultStorageContainer) != 'string') { + throw new Error('The [defaultStorageContainer] field is required when creating a cluster and must be a string'); + } + if (!this.containerNameIsValid(clusterCreationObject.defaultStorageContainer, function() {})) { + throw new Error('The [defaultStorageContainer] field is required when creating a cluster and must be a valid storage container name'); + } + if (typeof(clusterCreationObject.user) != 'string') { + throw new Error('The [user] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.password) != 'string') { + throw new Error('The [password] field is required when creating a cluster and must be a string'); + } + if (typeof(clusterCreationObject.nodes) != 'number' || !azureutil.isInt(clusterCreationObject.nodes)) { + throw new Error('The [nodes] field is required when creating a cluster and must be an integer'); + } + if (clusterCreationObject.additionalStorageAccounts) { + if (!_.isArray(clusterCreationObject.additionalStorageAccounts)) { + throw new Error('The [additionalStorageAccounts] field is optional when creating a cluster but must be an array when specified'); + } + for (var i = 0; i < clusterCreationObject.additionalStorageAccounts.length; i++) { + var account = clusterCreationObject.additionalStorageAccounts[i]; + if (typeof(account.name) != 'string') { + throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [name] field and it must be a string. Element ' + i + ' does not have a [name] field or it is not a string'); + } + if (typeof(account.key) != 'string') { + throw new Error('The [additionalStorageAccounts] field is optional but if supplied each element must have a [key] field and it must be a string. Element ' + i + ' does not have a [key] field or it is not a string'); + } + } + } + if (clusterCreationObject.oozieMetastore) { + if (!clusterCreationObject.hiveMetastore) { + throw new Error('If the [oozieMetastore] field is supplied, than the [hiveMetastore] field must also be supplied'); + } + if (typeof(clusterCreationObject.oozieMetastore.server) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [server] field which must be a string'); + } + if (typeof(clusterCreationObject.oozieMetastore.database) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [database] field which must be a string'); + } + if (typeof(clusterCreationObject.oozieMetastore.user) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [user] field which must be a string'); + } + if (typeof(clusterCreationObject.oozieMetastore.password) != 'string') { + throw new Error('If the [oozieMetastore] field is supplied it must contain a [password] field which must be a string'); + } + } + if (clusterCreationObject.hiveMetastore) { + if (!clusterCreationObject.oozieMetastore) { + throw new Error('If the [hiveMetastore] field is supplied, than the [oozieMetastore] field must also be supplied'); + } + if (typeof(clusterCreationObject.hiveMetastore.server) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [server] field which must be a string'); + } + if (typeof(clusterCreationObject.hiveMetastore.database) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [database] field which must be a string'); + } + if (typeof(clusterCreationObject.hiveMetastore.user) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [user] field which must be a string'); + } + if (typeof(clusterCreationObject.hiveMetastore.password) != 'string') { + throw new Error('If the [hiveMetastore] field is supplied it must contain a [password] field which must be a string'); + } + } +}; + /** * Creates a anonymous function that check if a given key is base 64 encoded. * diff --git a/package.json b/package.json index b80154c3bb..0789ab3a34 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "tunnel": ">= 0.0.1", "request": ">= 2.9.203", "validator": ">= 0.4.12", - "wns": ">= 0.5.3" + "wns": ">= 0.5.3", + "encdec": ">= 0.1.3" }, "devDependencies": { "mocha": "*", diff --git a/test/services/HDInsight/creds.xml b/test/services/HDInsight/creds.xml new file mode 100644 index 0000000000..80e5e85271 --- /dev/null +++ b/test/services/HDInsight/creds.xml @@ -0,0 +1,63 @@ + + + + default + {subscription Id} + path to valid .cer file + path to invalid .cer file + known-cluster + https://known-cluster.azurehdinsight.net:563 + userName + PASSWORD + hadoop + + https://umapi.rdfetest.dnsdemo4.com:8443 + hadoopservicesnightly + {subscription Id} + + + default-storage-account.blob.core.windows.net + SECRET KEY + deployment1 + + + + additional-storage-account.blob.core.windows.net + SECREATE KEY + deployment1 + + + + + HiveDB1 + some-server.database.windows.net + somedbname-hive + dbusername + dbpassword + + + HiveDB2 + some-server.database.windows.net + somedbname-hive + dbusername + dbpassword + + + + + OozieDB1 + some-server2.database.windows.net + somedbname-oozie + dbusername + dbpassword + + + OozieDB2 + some-server2.database.windows.net + somedbname-oozie + dbusername + dbpassword + + + + \ No newline at end of file diff --git a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js index 2859fcd1ce..e1e36d9c5d 100644 --- a/test/services/HDInsight/hdinsight-createCluster-unit-tests.js +++ b/test/services/HDInsight/hdinsight-createCluster-unit-tests.js @@ -257,6 +257,26 @@ describe('HDInsight createCluster (under unit test)', function() { } }); + it('should validate the defaultStorageContainer field is not invalid', function() { + performRequestStubUtil.StubAuthenticationFailed('http://test'); + var clusterCreationObject = { + name : 'test', + location : 'East US', + defaultStorageAccountName : 'test', + defaultStorageAccountKey : 'KEY', + defaultStorageContainer : 'INVLAID' + }; + try + { + hdInsight.createCluster(clusterCreationObject, function(err, response) {}); + throw new Error('this line should never be reached'); + } + catch (error) + { + error.message.should.be.eql('The [defaultStorageContainer] field is required when creating a cluster and must be a valid storage container name'); + } + }); + it('should validate the user field of the clusterCreationObject is not undefined', function() { performRequestStubUtil.StubAuthenticationFailed('http://test'); var clusterCreationObject = { diff --git a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js index 3aefae421d..daf916c867 100644 --- a/test/services/HDInsight/hdinsight-listClusters-unit-tests.js +++ b/test/services/HDInsight/hdinsight-listClusters-unit-tests.js @@ -16,7 +16,6 @@ var mocha = require('mocha'); var should = require('should'); var _ = require('underscore'); -var HDInsightTestUtils = require('./hdinsight-test-utils.js') // Test includes var testutil = require('../../util/util'); @@ -31,7 +30,6 @@ describe('HDInsight listClusters (under unit test)', function() { var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var HDInsight = require('../../../lib/services/serviceManagement/hdinsightservice.js'); var hdInsight = azure.createHDInsightService(subscriptionId, auth); - var hdinsightTestUtils = new HDInsightTestUtils(); var creds; beforeEach(function (done) { @@ -53,11 +51,7 @@ describe('HDInsight listClusters (under unit test)', function() { // So that we can work on any existing subscription. before (function (done) { performRequestStubUtil = new PerformRequestStubUtil(HDInsight); - hdinsightTestUtils.getTestCredentialData(function (result) { - should.exist(result); - creds = result; - done(); - }); + done(); }); var goodResult = { diff --git a/test/services/HDInsight/hdinsight-test-utils.js b/test/services/HDInsight/hdinsight-test-utils.js index e7fb9d0e43..a0c7dec624 100644 --- a/test/services/HDInsight/hdinsight-test-utils.js +++ b/test/services/HDInsight/hdinsight-test-utils.js @@ -19,10 +19,13 @@ var _ = require('underscore'); var should = require('should'); var creds; -function HDInsightTestUtils() { +function HDInsightTestUtils(callback) { this.getTestCredentialData(function (result) { creds = result; should.exist(result); + if (callback) { + callback(); + } }); } @@ -69,6 +72,9 @@ HDInsightTestUtils.prototype.getCreationWithAsvAndMetastore = function (name) { HDInsightTestUtils.prototype.getTestCredentialData = function(callback) { var file = process.env['AZURE_HDINSIGHT_CREDENTIALFILE']; + if (!file) { + file = __dirname + '/creds.xml'; + } var parser = new xml2js.Parser(); fs.readFile(file, 'utf-8', function(err, data) { parser.parseString(data, function(err, result) { diff --git a/test/services/HDInsight/hdinsight-tests.js b/test/services/HDInsight/hdinsight-tests.js index 0b08631748..1983bd730d 100644 --- a/test/services/HDInsight/hdinsight-tests.js +++ b/test/services/HDInsight/hdinsight-tests.js @@ -26,7 +26,7 @@ var azure = testutil.libRequire('azure'); describe('HDInsight Test', function() { var auth = { keyvalue: testutil.getCertificateKey(), certvalue: testutil.getCertificate() }; var hdInsight; - var hdInsightTestUtils = new HDInsightTestUtils(); + var hdInsightTestUtils; beforeEach(function (done) { done(); @@ -41,8 +41,10 @@ describe('HDInsight Test', function() { }); before (function (done) { - hdInsight = azure.createHDInsightService(hdInsightTestUtils.getDefaultCreds().subscriptionId, auth); - done(); + hdInsightTestUtils = new HDInsightTestUtils(function () { + hdInsight = azure.createHDInsightService(hdInsightTestUtils.getDefaultCreds().subscriptionId, auth); + done(); + }); }); it('should be able to create a cluster', function (done) { diff --git a/test/services/HDInsight/namespace-tests.js b/test/services/HDInsight/namespace-tests.js index 8675f9f656..525156a13b 100644 --- a/test/services/HDInsight/namespace-tests.js +++ b/test/services/HDInsight/namespace-tests.js @@ -14,39 +14,37 @@ */ // Test functions -var HDInsightNamespace = require('../../../lib/services/serviceManagement/hdinsightnamespaceutils.js'); +var azureUtil = require('../../../lib/util/util.js'); // Test includes var assert = require('assert'); describe('HDInsight Namespace Test', function() { - it('GetNameSpace', function (done) { - var namespace = new HDInsightNamespace(); - + it('GetNameSpace should properly create namespaces', function (done) { var subscriptionId = '0bf0b5da-dc38-4795-8595-3170ffefec48'; var expected = 'hdinsightC2D4FSA77HSYSQLRU4V73NKI3YH2OYHQXACMRGPECIHSH7FXTUAQ-East-US'; - var result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); + var result = azureUtil.getNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); subscriptionId = 'c72f7fde-36ec-4cdf-93bf-43f90fe5373a'; expected = 'hdinsightGTUVH76U5MNNGTJEFMKSGQMQO7AFBW52LMZPQ22R6UUXVWBDRBVA-East-US'; - result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); + result = azureUtil.getNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); subscriptionId = '04066490-336b-4732-adfa-90ba5422cc84'; expected = 'hdinsightXVS5S5SBDTTR7OJ4IOKGRTFM2M3P33KWPGP5SPYDJZYUMY73KOIQ-East-US'; - result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); + result = azureUtil.getNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); subscriptionId = '3cfbb7fc-1347-4eff-bf07-2e1f43084b00'; expected = 'hdinsightVXFY2XGLQTT5PCJCDRKJXWE2W2PQZOJK3NLO4QSNHEKS32E6RM5A-East-US'; - result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); + result = azureUtil.getNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); subscriptionId = 'ee3733c1-5ebd-4a20-95ce-17dba36a071a'; expected = 'hdinsightLDBRGOYTMVIJZ2ZAJZZTFFJD7N3MNFCJGONZO53VLK2V5GIEU2SQ-East-US'; - result = namespace.GetNameSpace(subscriptionId, 'hdinsight', 'East US'); + result = azureUtil.getNameSpace(subscriptionId, 'hdinsight', 'East US'); assert.equal(expected, result); done(); diff --git a/test/testlist.txt b/test/testlist.txt index 16922c73a5..a5ae1c9584 100644 --- a/test/testlist.txt +++ b/test/testlist.txt @@ -46,7 +46,7 @@ # util/validate-tests.js # azure-tests.js # services/HDInsight/hdinsight-tests.js -services/HDInsight/hdinsight-unit-tests.js +# services/HDInsight/hdinsight-unit-tests.js services/HDInsight/hdinsight-listClusters-unit-tests.js services/HDInsight/hdinsight-createCluster-unit-tests.js -# services/HDInsight/namespace-tests.js +services/HDInsight/namespace-tests.js