diff --git a/azure-cli.pyproj b/azure-cli.pyproj index 4d2ec899cae..049533c288b 100644 --- a/azure-cli.pyproj +++ b/azure-cli.pyproj @@ -115,7 +115,9 @@ + + diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/_command_type.py b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/_command_type.py index eb479b220f0..cec1bf4fee1 100644 --- a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/_command_type.py +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/_command_type.py @@ -12,17 +12,25 @@ FilesCompleter, DirectoriesCompleter) +from msrest.exceptions import DeserializationError + from . import _validators as validators from azure.cli.core.commands import ( + FORCE_PARAM_NAME, command_table, command_module_map, CliCommand, CliCommandArgument, - get_op_handler) + get_op_handler, + _user_confirmed) from azure.cli.core._util import CLIError +from azure.cli.core._config import az_config from azure.cli.core.commands._introspection import ( extract_full_summary_from_signature, extract_args_from_signature) +from azure.cli.core.commands.parameters import file_type + +# TODO: Enum choice lists _CLASS_NAME = re.compile(r"<(.*?)>") # Strip model name from class docstring @@ -101,9 +109,9 @@ def find_param_type(model, param): :returns: str """ # Search for the :type param_name: in the docstring - pattern = r":type {}:(.*?)\n(\s*:param |\s*:rtype:|\s*:raises:|\"\"\")".format(param) + pattern = r":type {}:(.*?)\n(\s*:param |\s*:rtype:|\s*:raises:|\s*\"{{3}})".format(param) param_type = re.search(pattern, model.__doc__, re.DOTALL) - return re.sub(r"\n\s*", " ", param_type.group(1).strip()) + return re.sub(r"\n\s*", "", param_type.group(1).strip()) def find_param_help(model, param): @@ -115,7 +123,7 @@ def find_param_help(model, param): # Search for :param param_name: in the docstring pattern = r":param {}:(.*?)\n\s*:type ".format(param) param_doc = re.search(pattern, model.__doc__, re.DOTALL) - return re.sub(r"\n\s*", "", param_doc.group(1).strip()) + return re.sub(r"\n\s*", " ", param_doc.group(1).strip()) def find_return_type(model): @@ -261,12 +269,16 @@ def deserialize_json(self, client, kwargs, json_obj): :param dict kwargs: The request kwargs :param dict json_obj: The loaded JSON content """ - #TODO: catch exception - kwargs[self._request_param['name']] = client._deserialize( #pylint:disable=W0212 - self._request_param['model'], json_obj) - if kwargs[self._request_param['name']] is None: - message = "Failed to deserialized JSON file into object {}" + message = "Failed to deserialized JSON file into object {}" + try: + kwargs[self._request_param['name']] = client._deserialize( #pylint:disable=W0212 + self._request_param['model'], json_obj) + except DeserializationError as error: + message += ": {}".format(error) raise ValueError(message.format(self._request_param['model'])) + else: + if kwargs[self._request_param['name']] is None: + raise ValueError(message.format(self._request_param['model'])) def queue_argument(self, name=None, path=None, root=None, #pylint:disable=too-many-arguments options=None, type=None, dependencies=None): #pylint:disable=W0622 @@ -399,6 +411,7 @@ def __init__(self, module_name, name, operation, factory, transform_result, #pyl self.ignore.extend(ignore) self.parser = None self.validator = validator + self.confirmation = 'delete' in operation # The name of the request options parameter self._options_param = format_options_name(operation) @@ -413,6 +426,9 @@ def _execute_command(kwargs): from msrest.paging import Paged from msrest.exceptions import ValidationError, ClientRequestError from azure.batch.models import BatchErrorException + if self._cancel_operation(kwargs): + raise CLIError('Operation cancelled.') + try: client = factory(kwargs) self._build_options(kwargs) @@ -483,6 +499,17 @@ def _execute_command(kwargs): get_op_handler(operation)) ) + def _cancel_operation(self, kwargs): + """Whether to cancel the current operation because user + declined the confirmation prompt. + :param dict kwargs: The request arguments. + :returns: bool + """ + return self.confirmation \ + and not kwargs.get(FORCE_PARAM_NAME) \ + and not az_config.getboolean('core', 'disable_confirm_prompt', fallback=False) \ + and not _user_confirmed(self.confirmation, kwargs) + def _build_parameters(self, path, kwargs, param, value): """Recursively build request parameter dictionary from command line args. :param str arg_path: Current parameter namespace. @@ -670,6 +697,7 @@ def _load_transformed_arguments(self, handler): options_list=[arg_name(param)], required=False, default=None, + type=file_type, completer=FilesCompleter(), help=docstring)) elif arg[0] not in self.ignore: @@ -682,8 +710,17 @@ def _load_transformed_arguments(self, handler): required=True, default=None, completer=DirectoriesCompleter(), + type=file_type, validator=validators.validate_file_destination, help=docstring)) + if self.confirmation: + param = FORCE_PARAM_NAME + docstring = 'Do not prompt for confirmation.' + yield (param, CliCommandArgument(param, + options_list=[arg_name(param)], + required=False, + action='store_true', + help=docstring)) def cli_data_plane_command(name, operation, client_factory, transform=None, #pylint:disable=too-many-arguments diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create-invalid.json b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create-invalid.json new file mode 100644 index 00000000000..83bec8562c3 --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create-invalid.json @@ -0,0 +1,16 @@ +{ + "id": "azure-cli-test-json", + "vmSize": "small", + "cloudServiceConfiguration": { + "osFamily": "4", + "targetOSVersion": "*" + } + "targetDedicated": 2, + "resizeTimeout": "PT15M", + "environmentSettings": [ + { + "name": "TEST_ENV", + "value": "TEST_VALUE" + }, + ] +} \ No newline at end of file diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create.json b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create.json new file mode 100644 index 00000000000..58625e7b17a --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-create.json @@ -0,0 +1,20 @@ +{ + "id": "azure-cli-test-json", + "vmSize": "small", + "cloudServiceConfiguration": { + "osFamily": "4", + "targetOSVersion": "*" + }, + "targetDedicated": 2, + "resizeTimeout": "PT15M", + "environmentSettings": [ + { + "name": "TEST_ENV", + "value": "TEST_VALUE" + } + ], + "startTask": { + "commandLine": "cmd /c echo test", + "waitForSuccess": true + } +} \ No newline at end of file diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-update.json b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-update.json new file mode 100644 index 00000000000..29a37bafb88 --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/data/batch-pool-update.json @@ -0,0 +1,9 @@ +{ + "startTask": { + "commandLine": "cmd /c echo updated", + "waitForSuccess": true + }, + "certificateReferences": {}, + "metadata": {}, + "applicationPackageReferences": {} +} \ No newline at end of file diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/recordings/test_batch_pools.yaml b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/recordings/test_batch_pools.yaml new file mode 100644 index 00000000000..00c61ff11af --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/recordings/test_batch_pools.yaml @@ -0,0 +1,745 @@ +interactions: +- request: + body: '{"vmSize": "small", "cloudServiceConfiguration": {"osFamily": "4"}, "id": + "azure-cli-test-paas"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['96'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [f550b2e4-e1c6-11e6-a00f-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:11 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-paas'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:13 GMT'] + ETag: ['0x8D443EADAC12B54'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:13 GMT'] + Location: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-paas'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [2d7f8961-8904-4ce1-bce0-3577774be6ca] + status: {code: 201, message: Created} +- request: + body: '{"vmSize": "Standard_A1", "virtualMachineConfiguration": {"nodeAgentSKUId": + "batch.node.ubuntu 16.04", "imageReference": {"offer": "UbuntuServer", "publisher": + "Canonical", "sku": "16.04.0-LTS"}}, "id": "azure-cli-test-iaas"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['225'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [f73284e4-e1c6-11e6-a068-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:14 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:13 GMT'] + ETag: ['0x8D443EADB55F1D1'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:14 GMT'] + Location: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [78b810fb-3d59-4faf-981c-fa2e9f296af7] + status: {code: 201, message: Created} +- request: + body: '{"cloudServiceConfiguration": {"osFamily": "4", "targetOSVersion": "*"}, + "id": "azure-cli-test-json", "resizeTimeout": "PT15M", "startTask": {"commandLine": + "cmd /c echo test", "waitForSuccess": true}, "vmSize": "small", "targetDedicated": + 2}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['242'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [f90073ae-e1c6-11e6-be4a-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:17 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-json'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:18 GMT'] + ETag: ['0x8D443EADD4E4364'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:18 GMT'] + Location: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-json'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [9f27bd16-acf6-44ed-85b1-a60265719d1f] + status: {code: 201, message: Created} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fa980f24-e1c6-11e6-873b-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:20 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools\"\ + ,\"value\":[\r\n {\r\n \"id\":\"azure-cli-test-iaas\",\"url\":\"https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas\"\ + ,\"eTag\":\"0x8D443EADB55F1D1\",\"lastModified\":\"2017-01-23T23:52:14.7333585Z\"\ + ,\"creationTime\":\"2017-01-23T23:52:14.7333585Z\",\"state\":\"active\",\"\ + stateTransitionTime\":\"2017-01-23T23:52:14.7333585Z\",\"allocationState\"\ + :\"steady\",\"allocationStateTransitionTime\":\"2017-01-23T23:52:15.2893726Z\"\ + ,\"vmSize\":\"standard_a1\",\"resizeTimeout\":\"PT15M\",\"currentDedicated\"\ + :0,\"targetDedicated\":0,\"enableAutoScale\":false,\"enableInterNodeCommunication\"\ + :false,\"maxTasksPerNode\":1,\"taskSchedulingPolicy\":{\r\n \"nodeFillType\"\ + :\"Spread\"\r\n },\"virtualMachineConfiguration\":{\r\n \"imageReference\"\ + :{\r\n \"publisher\":\"Canonical\",\"offer\":\"UbuntuServer\",\"\ + sku\":\"16.04.0-LTS\",\"version\":\"latest\"\r\n },\"nodeAgentSKUId\"\ + :\"batch.node.ubuntu 16.04\"\r\n }\r\n },{\r\n \"id\":\"azure-cli-test-json\"\ + ,\"url\":\"https://test1.westus.batch.azure.com/pools/azure-cli-test-json\"\ + ,\"eTag\":\"0x8D443EADD4E4364\",\"lastModified\":\"2017-01-23T23:52:18.0384612Z\"\ + ,\"creationTime\":\"2017-01-23T23:52:18.0384612Z\",\"state\":\"active\",\"\ + stateTransitionTime\":\"2017-01-23T23:52:18.0384612Z\",\"allocationState\"\ + :\"resizing\",\"allocationStateTransitionTime\":\"2017-01-23T23:52:18.0384612Z\"\ + ,\"vmSize\":\"small\",\"resizeTimeout\":\"PT15M\",\"currentDedicated\":0,\"\ + targetDedicated\":2,\"enableAutoScale\":false,\"enableInterNodeCommunication\"\ + :false,\"startTask\":{\r\n \"commandLine\":\"cmd /c echo test\",\"\ + runElevated\":false,\"maxTaskRetryCount\":0,\"waitForSuccess\":true\r\n \ + \ },\"maxTasksPerNode\":1,\"taskSchedulingPolicy\":{\r\n \"nodeFillType\"\ + :\"Spread\"\r\n },\"cloudServiceConfiguration\":{\r\n \"osFamily\"\ + :\"4\",\"targetOSVersion\":\"*\",\"currentOSVersion\":\"*\"\r\n }\r\n\ + \ },{\r\n \"id\":\"azure-cli-test-paas\",\"url\":\"https://test1.westus.batch.azure.com/pools/azure-cli-test-paas\"\ + ,\"eTag\":\"0x8D443EADAC12B54\",\"lastModified\":\"2017-01-23T23:52:13.7583444Z\"\ + ,\"creationTime\":\"2017-01-23T23:52:13.7583444Z\",\"state\":\"active\",\"\ + stateTransitionTime\":\"2017-01-23T23:52:13.7583444Z\",\"allocationState\"\ + :\"steady\",\"allocationStateTransitionTime\":\"2017-01-23T23:52:13.9853568Z\"\ + ,\"vmSize\":\"small\",\"resizeTimeout\":\"PT15M\",\"currentDedicated\":0,\"\ + targetDedicated\":0,\"enableAutoScale\":false,\"enableInterNodeCommunication\"\ + :false,\"maxTasksPerNode\":1,\"taskSchedulingPolicy\":{\r\n \"nodeFillType\"\ + :\"Spread\"\r\n },\"cloudServiceConfiguration\":{\r\n \"osFamily\"\ + :\"4\",\"targetOSVersion\":\"*\",\"currentOSVersion\":\"*\"\r\n }\r\n\ + \ }\r\n ]\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:20 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [847425c3-c53b-4340-b5d8-4c574711bc25] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fb19bd74-e1c6-11e6-aeb6-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:21 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools?timeout=30&$filter=id%20eq%20%27azure-cli-test-paas%27&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools\"\ + ,\"value\":[\r\n {\r\n \"id\":\"azure-cli-test-paas\",\"url\":\"https://test1.westus.batch.azure.com/pools/azure-cli-test-paas\"\ + ,\"eTag\":\"0x8D443EADAC12B54\",\"lastModified\":\"2017-01-23T23:52:13.7583444Z\"\ + ,\"creationTime\":\"2017-01-23T23:52:13.7583444Z\",\"state\":\"active\",\"\ + stateTransitionTime\":\"2017-01-23T23:52:13.7583444Z\",\"allocationState\"\ + :\"steady\",\"allocationStateTransitionTime\":\"2017-01-23T23:52:13.9853568Z\"\ + ,\"vmSize\":\"small\",\"resizeTimeout\":\"PT15M\",\"currentDedicated\":0,\"\ + targetDedicated\":0,\"enableAutoScale\":false,\"enableInterNodeCommunication\"\ + :false,\"maxTasksPerNode\":1,\"taskSchedulingPolicy\":{\r\n \"nodeFillType\"\ + :\"Spread\"\r\n },\"cloudServiceConfiguration\":{\r\n \"osFamily\"\ + :\"4\",\"targetOSVersion\":\"*\",\"currentOSVersion\":\"*\"\r\n }\r\n\ + \ }\r\n ]\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:20 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [155fb20a-6a06-4bda-896a-eebd56d5d1c8] + status: {code: 200, message: OK} +- request: + body: '{"targetDedicated": 5}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['22'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fbc198ae-e1c6-11e6-8c19-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:22 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-paas/resize?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-paas/resize'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:22 GMT'] + ETag: ['0x8D443EADFDFC929'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:22 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [0d410380-0e7c-4533-b657-ba32cf8ec358] + status: {code: 202, message: Accepted} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fc416250-e1c6-11e6-bb2f-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:23 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-paas?timeout=30&$select=allocationState%2C%20targetDedicated&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"allocationState\":\"resizing\",\"targetDedicated\":5\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:22 GMT'] + ETag: ['0x8D443EADFDFC929'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:22 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [78439dbb-f1da-47fb-a496-e3b23fb1921b] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fcccd66c-e1c6-11e6-92dd-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:24 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-paas/stopresize?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-paas/stopresize'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:24 GMT'] + ETag: ['0x8D443EAE0F18A3D'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:24 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [23f7ab27-8fc0-4a42-80a9-ccc4cce299ea] + status: {code: 202, message: Accepted} +- request: + body: '{"autoScaleFormula": "$TargetDedicated=3"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['42'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fd6abde6-e1c6-11e6-9e21-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:25 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/enableautoscale?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/enableautoscale'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:25 GMT'] + ETag: ['0x8D443EAE189D3F9'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:25 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [7f7732e8-d7fa-4f67-b1fa-cd7535b34a9d] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [fdff38be-e1c6-11e6-8fd3-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:26 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas?timeout=30&$select=enableAutoScale&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"enableAutoScale\":true\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:26 GMT'] + ETag: ['0x8D443EAE189D3F9'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:25 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [a9adaa39-430c-4a13-98ec-57e622eb9513] + status: {code: 200, message: OK} +- request: + body: '{"autoScaleFormula": "$TargetDedicated=3"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['42'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [feaf1b1e-e1c6-11e6-9845-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:27 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/evaluateautoscale?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#Microsoft.Azure.Batch.Protocol.Entities.AutoScaleRun\"\ + ,\"timestamp\":\"2017-01-23T23:52:27.3571622Z\",\"results\":\"$TargetDedicated=3;$NodeDeallocationOption=requeue\"\ + \r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/evaluateautoscale'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:27 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [592d4d3f-851f-4d3d-a38c-a3db54124922] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [ff3c63b4-e1c6-11e6-b988-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:28 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/disableautoscale?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas/disableautoscale'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:28 GMT'] + ETag: ['0x8D443EAE35EA5D7'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:28 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [372e10ea-c4d9-4c25-b14e-14e54854c6da] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [ffb9ffec-e1c6-11e6-9e66-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:29 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas?timeout=30&$select=enableAutoScale&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"enableAutoScale\":false\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:28 GMT'] + ETag: ['0x8D443EAE35EA5D7'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:28 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [c71a3996-5269-47ff-b09a-f9670f828ea9] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [003c1d42-e1c7-11e6-8724-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:30 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/poolusagemetrics?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#poolusagemetrics\"\ + ,\"value\":[\r\n {\r\n \"poolId\":\"luxblend_pool_2016-12-11-20-17-19-535237\"\ + ,\"startTime\":\"2017-01-23T17:00:00Z\",\"endTime\":\"2017-01-23T17:30:00Z\"\ + ,\"vmSize\":\"standard_nc24\",\"totalCoreHours\":6.9306946060000012,\"dataIngressGiB\"\ + :0.0,\"dataEgressGiB\":0.0\r\n }\r\n ]\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:29 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [3d991166-4591-4745-95fe-0db8bd03ba2c] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [00e818fe-e1c7-11e6-b6e7-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:31 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-json?timeout=30&$select=startTask&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"startTask\":{\r\n \"commandLine\":\"cmd /c echo test\",\"runElevated\"\ + :false,\"maxTaskRetryCount\":0,\"waitForSuccess\":true\r\n }\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:30 GMT'] + ETag: ['0x8D443EADD4E4364'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:18 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [c0b69132-5a22-4498-8f5b-9250d95e0469] + status: {code: 200, message: OK} +- request: + body: '{"startTask": {"commandLine": "new_value"}}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['43'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [014de2d0-e1c7-11e6-a10d-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:31 GMT'] + method: PATCH + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-json?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceId: ['https://test1.westus.batch.azure.com/pools/azure-cli-test-json'] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:31 GMT'] + ETag: ['0x8D443EAE56FF009'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:31 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [a2619bb4-d5aa-4919-a0b1-7fa722aedea6] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [01dbc5a2-e1c7-11e6-8dde-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:32 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-json?timeout=30&$select=startTask&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"startTask\":{\r\n \"commandLine\":\"new_value\",\"runElevated\":false,\"\ + maxTaskRetryCount\":0,\"waitForSuccess\":false\r\n }\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:32 GMT'] + ETag: ['0x8D443EAE56FF009'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:31 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [c51f4e38-b5bb-406d-9e0a-6a6b714cab0b] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [02793410-e1c7-11e6-8485-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:33 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/nodeagentskus?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#nodeagentskus\"\ + ,\"value\":[\r\n {\r\n \"id\":\"batch.node.centos 7\",\"verifiedImageReferences\"\ + :[\r\n {\r\n \"publisher\":\"OpenLogic\",\"offer\":\"CentOS\"\ + ,\"sku\":\"7.2\",\"version\":\"latest\"\r\n },{\r\n \"publisher\"\ + :\"OpenLogic\",\"offer\":\"CentOS\",\"sku\":\"7.1\",\"version\":\"latest\"\ + \r\n },{\r\n \"publisher\":\"OpenLogic\",\"offer\":\"CentOS\"\ + ,\"sku\":\"7.0\",\"version\":\"latest\"\r\n },{\r\n \"publisher\"\ + :\"OpenLogic\",\"offer\":\"CentOS-HPC\",\"sku\":\"7.1\",\"version\":\"latest\"\ + \r\n },{\r\n \"publisher\":\"Oracle\",\"offer\":\"Oracle-Linux\"\ + ,\"sku\":\"7.2\",\"version\":\"latest\"\r\n },{\r\n \"publisher\"\ + :\"Oracle\",\"offer\":\"Oracle-Linux\",\"sku\":\"7.0\",\"version\":\"latest\"\ + \r\n },{\r\n \"publisher\":\"microsoft-ads\",\"offer\":\"\ + linux-data-science-vm\",\"sku\":\"linuxdsvm\",\"version\":\"latest\"\r\n \ + \ }\r\n ],\"osType\":\"linux\"\r\n },{\r\n \"id\":\"batch.node.debian\ + \ 8\",\"verifiedImageReferences\":[\r\n {\r\n \"publisher\"\ + :\"Credativ\",\"offer\":\"Debian\",\"sku\":\"8\",\"version\":\"latest\"\r\n\ + \ }\r\n ],\"osType\":\"linux\"\r\n },{\r\n \"id\":\"batch.node.opensuse\ + \ 13.2\",\"verifiedImageReferences\":[\r\n {\r\n \"publisher\"\ + :\"SUSE\",\"offer\":\"openSUSE\",\"sku\":\"13.2\",\"version\":\"latest\"\r\ + \n }\r\n ],\"osType\":\"linux\"\r\n },{\r\n \"id\":\"\ + batch.node.opensuse 42.1\",\"verifiedImageReferences\":[\r\n {\r\n\ + \ \"publisher\":\"SUSE\",\"offer\":\"openSUSE-Leap\",\"sku\":\"42.1\"\ + ,\"version\":\"latest\"\r\n },{\r\n \"publisher\":\"SUSE\"\ + ,\"offer\":\"SLES\",\"sku\":\"12-SP1\",\"version\":\"latest\"\r\n },{\r\ + \n \"publisher\":\"SUSE\",\"offer\":\"SLES-HPC\",\"sku\":\"12-SP1\"\ + ,\"version\":\"latest\"\r\n }\r\n ],\"osType\":\"linux\"\r\n \ + \ },{\r\n \"id\":\"batch.node.ubuntu 14.04\",\"verifiedImageReferences\"\ + :[\r\n {\r\n \"publisher\":\"Canonical\",\"offer\":\"UbuntuServer\"\ + ,\"sku\":\"14.04.5-LTS\",\"version\":\"latest\"\r\n }\r\n ],\"\ + osType\":\"linux\"\r\n },{\r\n \"id\":\"batch.node.ubuntu 16.04\"\ + ,\"verifiedImageReferences\":[\r\n {\r\n \"publisher\":\"\ + Canonical\",\"offer\":\"UbuntuServer\",\"sku\":\"16.04.0-LTS\",\"version\"\ + :\"latest\"\r\n }\r\n ],\"osType\":\"linux\"\r\n },{\r\n \ + \ \"id\":\"batch.node.windows amd64\",\"verifiedImageReferences\":[\r\n\ + \ {\r\n \"publisher\":\"MicrosoftWindowsServer\",\"offer\"\ + :\"WindowsServer\",\"sku\":\"2012-R2-Datacenter\",\"version\":\"latest\"\r\ + \n },{\r\n \"publisher\":\"MicrosoftWindowsServer\",\"offer\"\ + :\"WindowsServer\",\"sku\":\"2012-Datacenter\",\"version\":\"latest\"\r\n\ + \ },{\r\n \"publisher\":\"MicrosoftWindowsServer\",\"offer\"\ + :\"WindowsServer\",\"sku\":\"2008-R2-SP1\",\"version\":\"latest\"\r\n \ + \ },{\r\n \"publisher\":\"MicrosoftWindowsServer\",\"offer\":\"\ + WindowsServer\",\"sku\":\"2016-Datacenter\",\"version\":\"latest\"\r\n \ + \ },{\r\n \"publisher\":\"MicrosoftWindowsServer\",\"offer\"\ + :\"WindowsServer\",\"sku\":\"2016-Datacenter-with-Containers\",\"version\"\ + :\"latest\"\r\n },{\r\n \"publisher\":\"microsoft-ads\",\"\ + offer\":\"standard-data-science-vm\",\"sku\":\"standard-data-science-vm\"\ + ,\"version\":\"latest\"\r\n }\r\n ],\"osType\":\"windows\"\r\n\ + \ }\r\n ]\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:33 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [47181dfd-d09c-45b0-924a-4e375e419a1e] + status: {code: 200, message: OK} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['0'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [02e5bde6-e1c7-11e6-85a4-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:34 GMT'] + method: DELETE + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: ''} + headers: + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:34 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [c72cd167-87b9-437b-8002-81f13b09c4cc] + status: {code: 202, message: Accepted} +- request: + body: null + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [037344ac-e1c7-11e6-b19e-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:35 GMT'] + method: GET + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-iaas?timeout=30&$select=state&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#pools/@Element\"\ + ,\"state\":\"deleting\"\r\n}"} + headers: + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:34 GMT'] + ETag: ['0x8D443EAE70326F6'] + Last-Modified: ['Mon, 23 Jan 2017 23:52:34 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + Transfer-Encoding: [chunked] + X-Content-Type-Options: [nosniff] + request-id: [0f0a563f-eaf7-4987-b2bf-eb0cb55292a9] + status: {code: 200, message: OK} +- request: + body: '{"vmSize": "small", "applicationPackageReferences": [{"applicationId": + "does-not-exist"}], "cloudServiceConfiguration": {"osFamily": "4"}, "id": "app_package_test"}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['164'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [03e8709a-e1c7-11e6-a409-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:36 GMT'] + method: POST + uri: https://test1.westus.batch.azure.com/pools?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#Microsoft.Azure.Batch.Protocol.Entities.Container.errors/@Element\"\ + ,\"code\":\"InvalidApplicationPackageReferences\",\"message\":{\r\n \"\ + lang\":\"en-US\",\"value\":\"One or more of the specified application package\ + \ references are invalid.\\nRequestId:9232316a-a0cf-4f04-b30a-3acf5789b2f1\\\ + nTime:2017-01-23T23:52:36.1309218Z\"\r\n },\"values\":[\r\n {\r\n \ + \ \"key\":\"does-not-exist\",\"value\":\"The specified application package\ + \ does not exist.\"\r\n }\r\n ]\r\n}"} + headers: + Content-Length: ['521'] + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:35 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + X-Content-Type-Options: [nosniff] + request-id: [9232316a-a0cf-4f04-b30a-3acf5789b2f1] + status: {code: 409, message: One or more of the specified application package + references are invalid.} +- request: + body: '{"applicationPackageReferences": [{"applicationId": "does-not-exist"}]}' + headers: + Accept: [application/json] + Accept-Encoding: ['gzip, deflate'] + Connection: [keep-alive] + Content-Length: ['71'] + Content-Type: [application/json; odata=minimalmetadata; charset=utf-8] + User-Agent: [python/3.5.1 (Windows-8.1-6.3.9600-SP0) requests/2.9.1 msrest/0.4.4 + msrest_azure/0.4.6 batchserviceclient/1.1.0 Azure-SDK-For-Python] + accept-language: [en-US] + client-request-id: [046ae30a-e1c7-11e6-99a4-54ee750f2fc7] + ocp-date: ['Mon, 23 Jan 2017 23:52:37 GMT'] + method: PATCH + uri: https://test1.westus.batch.azure.com/pools/azure-cli-test-paas?timeout=30&api-version=2016-07-01.3.1 + response: + body: {string: "{\r\n \"odata.metadata\":\"https://test1.westus.batch.azure.com/$metadata#Microsoft.Azure.Batch.Protocol.Entities.Container.errors/@Element\"\ + ,\"code\":\"InvalidApplicationPackageReferences\",\"message\":{\r\n \"\ + lang\":\"en-US\",\"value\":\"One or more of the specified application package\ + \ references are invalid.\\nRequestId:e3baa04b-f7f7-453b-9439-8002316f39f0\\\ + nTime:2017-01-23T23:52:37.0798071Z\"\r\n },\"values\":[\r\n {\r\n \ + \ \"key\":\"does-not-exist\",\"value\":\"The specified application package\ + \ does not exist.\"\r\n }\r\n ]\r\n}"} + headers: + Content-Length: ['521'] + Content-Type: [application/json;odata=minimalmetadata] + DataServiceVersion: ['3.0'] + Date: ['Mon, 23 Jan 2017 23:52:36 GMT'] + Server: [Microsoft-HTTPAPI/2.0] + Strict-Transport-Security: [max-age=31536000; includeSubDomains] + X-Content-Type-Options: [nosniff] + request-id: [e3baa04b-f7f7-453b-9439-8002316f39f0] + status: {code: 409, message: One or more of the specified application package + references are invalid.} +version: 1 diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_commands.py b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_commands.py new file mode 100644 index 00000000000..bae0aecec51 --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_commands.py @@ -0,0 +1,385 @@ +import datetime +import isodate +import os +import unittest +from .. import _validators +from .. import _command_type + +class TestObj(object): + pass + +class TestBatchValidators(unittest.TestCase): + + def test_batch_datetime_format(self): + obj = _validators.datetime_format("2017-01-24T15:47:24Z") + self.assertIsInstance(obj, datetime.datetime) + + with self.assertRaises(ValueError): + _validators.datetime_format("test") + + def test_batch_duration_format(self): + obj = _validators.duration_format("P3Y6M4DT12H30M5S") + self.assertIsInstance(obj, isodate.Duration) + + with self.assertRaises(ValueError): + _validators.duration_format("test") + + def test_batch_metadata_item_format(self): + meta = _validators.metadata_item_format("name=value") + self.assertEqual(meta, {'name': 'name', 'value': 'value'}) + + with self.assertRaises(ValueError): + _validators.metadata_item_format("test") + + with self.assertRaises(ValueError): + _validators.metadata_item_format("name=value=other") + + def test_batch_environment_setting_format(self): + env = _validators.environment_setting_format("name=value") + self.assertEqual(env, {'name': 'name', 'value': 'value'}) + + with self.assertRaises(ValueError): + _validators.environment_setting_format("test") + + with self.assertRaises(ValueError): + _validators.environment_setting_format("name=value=other") + + def test_batch_application_package_reference_format(self): + ref = _validators.application_package_reference_format("app_1") + self.assertEqual(ref, {'application_id': 'app_1'}) + + ref = _validators.application_package_reference_format("app#1") + self.assertEqual(ref, {'application_id': 'app', 'version': '1'}) + + ref = _validators.application_package_reference_format("app#1#RC") + self.assertEqual(ref, {'application_id': 'app', 'version': '1#RC'}) + + #def test_batch_certificate_reference_format(self): + + # cert = _validators.certificate_reference_format("thumbprint_lkjsahakjg") + # self.assertEqual(ref, {'thumbprint': 'thumbprint_lkjsahakjg', + # 'thumbprint_algorithm': 'sha1'}) + + def test_batch_validate_options(self): + ns = TestObj() + _validators.validate_options(ns) + self.assertFalse(hasattr(ns, 'ocp_range')) + + ns.start_range = "100" + ns.end_range = None + _validators.validate_options(ns) + self.assertFalse(hasattr(ns, 'start_range')) + self.assertFalse(hasattr(ns, 'end_range')) + self.assertEqual(ns.ocp_range, "bytes=100-") + + del ns.ocp_range + ns.start_range = None + ns.end_range = 150 + _validators.validate_options(ns) + self.assertFalse(hasattr(ns, 'start_range')) + self.assertFalse(hasattr(ns, 'end_range')) + self.assertEqual(ns.ocp_range, "bytes=0-150") + + del ns.ocp_range + ns.start_range = 11 + ns.end_range = 22 + _validators.validate_options(ns) + self.assertFalse(hasattr(ns, 'start_range')) + self.assertFalse(hasattr(ns, 'end_range')) + self.assertEqual(ns.ocp_range, "bytes=11-22") + + def test_batch_validate_file_destination(self): + ns = TestObj() + _validators.validate_file_destination(ns) + self.assertFalse(hasattr(ns, 'destination')) + + ns.destination = os.path.dirname(__file__) + ns.file_name = "/wd/stdout.txt" + _validators.validate_file_destination(ns) + self.assertEqual(ns.destination, os.path.join(os.path.dirname(__file__), 'stdout.txt')) + + ns.destination = __file__ + with self.assertRaises(ValueError): + _validators.validate_file_destination(ns) + + ns.destination = os.path.join(os.path.dirname(__file__), 'test.txt') + _validators.validate_file_destination(ns) + self.assertEqual(ns.destination, os.path.join(os.path.dirname(__file__), 'test.txt')) + + ns.destination = "X:\\test.txt" + with self.assertRaises(ValueError): + _validators.validate_file_destination(ns) + + +class TestBatchParser(unittest.TestCase): + + def test_batch_build_prefix(self): + resolved = _command_type._build_prefix('id', 'id', 'pool') + self.assertEqual(resolved, 'id') + + resolved = _command_type._build_prefix('id', 'id', 'pool.start_task') + self.assertEqual(resolved, 'start_task_id') + + resolved = _command_type._build_prefix('properties_id', 'id', 'pool.start_task.properties') + self.assertEqual(resolved, 'start_task_id') + + resolved = _command_type._build_prefix('start_task_id', 'id', 'pool.start_task.properties') + self.assertEqual(resolved, 'pool_id') + + resolved = _command_type._build_prefix('pool_id', 'id', 'pool.start_task.properties') + self.assertEqual(resolved, 'pool_id') + + def test_batch_find_param_type(self): + model = TestObj() + model.__doc__ = """ + :param name: The name of the environment variable. + :type name: str + :param value: The value of the environment variable. +""" + self.assertEqual(_command_type.find_param_type(model, 'name'), 'str') + + model.__doc__ = """ + :param pool_get_options: Additional parameters for the operation + :type pool_get_options: :class:`PoolGetOptions + ` + :param dict custom_headers: headers that will be added to the request +""" + self.assertEqual(_command_type.find_param_type(model, 'pool_get_options'), + ':class:`PoolGetOptions`') + + model.__doc__ = ''' + :param node_fill_type: How tasks should be distributed across compute + nodes. Possible values include: 'spread', 'pack', 'unmapped' + :type node_fill_type: str or :class:`ComputeNodeFillType + ` + """ +''' + self.assertEqual(_command_type.find_param_type(model, 'node_fill_type'), + 'str or :class:`ComputeNodeFillType' + + '`') + + model.__doc__ = """ + :param name: The name of the environment variable. + :type name:str + :raises: BatchException +""" + self.assertEqual(_command_type.find_param_type(model, 'name'), 'str') + + def test_batch_find_param_help(self): + model = TestObj() + model.__doc__ = """ + :param pool_id: The id of the pool to get. + :type pool_id: str + :param pool_get_options: Additional parameters for the operation + :type pool_get_options: :class:`PoolGetOptions + ` +""" + self.assertEqual(_command_type.find_param_help(model, 'pool_id'), + 'The id of the pool to get.') + self.assertEqual(_command_type.find_param_help(model, 'pool_get_options'), + 'Additional parameters for the operation') + + model.__doc__ = """ + :param node_fill_type: How tasks should be distributed across compute + nodes. Possible values include: 'spread', 'pack', 'unmapped' + :type node_fill_type: str or :class:`ComputeNodeFillType + ` +""" + self.assertEqual(_command_type.find_param_help(model, 'node_fill_type'), + "How tasks should be distributed across compute nodes. " + + "Possible values include: 'spread', 'pack', 'unmapped'") + + def test_batch_find_return_type(self): + model = TestObj() + model.__doc__ = """ + :param node_fill_type: How tasks should be distributed across compute + nodes. Possible values include: 'spread', 'pack', 'unmapped' + :type node_fill_type: str or :class:`ComputeNodeFillType + ` +""" + self.assertIsNone(_command_type.find_return_type(model)) + + model.__doc__ = """ + :type callback: Callable[Bytes, response=None] + :param operation_config: :ref:`Operation configuration + overrides`. + :rtype: Generator + :rtype: :class:`ClientRawResponse` + if raw=true +""" + self.assertEqual(_command_type.find_return_type(model), 'Generator') + + def test_batch_class_name(self): + type_str = ":class:`ComputeNodeFillType`" + self.assertEqual(_command_type.class_name(type_str), + "azure.batch.models.ComputeNodeFillType") + + type_str = "str or :class:`ComputeNodeFillType`" + self.assertEqual(_command_type.class_name(type_str), + "azure.batch.models.ComputeNodeFillType") + + def test_batch_operations_name(self): + op_str = "PythonTestCase" + self.assertEqual(_command_type.operations_name(op_str), "python_test_case") + + op_str = "PythonTestCaseOperations" + self.assertEqual(_command_type.operations_name(op_str), "python_test_case") + + op_str = "Python" + self.assertEqual(_command_type.operations_name(op_str), "python") + + op_str = "python" + self.assertEqual(_command_type.operations_name(op_str), "python") + + def test_batch_full_name(self): + arg_details = {'path': 'pool.start_task', 'root': 'id'} + self.assertEqual(_command_type.full_name(arg_details), 'pool.start_task.id') + + def test_batch_group_title(self): + path = "pool" + self.assertEqual(_command_type.group_title(path), "Pool") + + path = "pool.start_task" + self.assertEqual(_command_type.group_title(path), "Pool : Start Task") + + path = "pool.start_task.constraints" + self.assertEqual(_command_type.group_title(path), "Pool : Start Task : Constraints") + + def test_batch_arg_name(self): + self.assertEqual(_command_type.arg_name("pool_id"), "--pool-id") + self.assertEqual(_command_type.arg_name("id"), "--id") + self.assertEqual(_command_type.arg_name("start_task_id"), "--start-task-id") + + def test_batch_format_options_name(self): + op = "azure.batch.operations.pool_opterations#PoolOperations.get" + self.assertEqual(_command_type.format_options_name(op), "pool_get_options") + + op = "azure.batch.operations.pool_opterations#PoolOperations.upgrade_os" + self.assertEqual(_command_type.format_options_name(op), "pool_upgrade_os_options") + + op = "azure.batch.operations.pool_opterations#JobScheduleOperations.get" + self.assertEqual(_command_type.format_options_name(op), "job_schedule_get_options") + + def test_batch_argument_tree(self): + tree = _command_type.BatchArgumentTree(None) + self.assertEqual(list(tree), []) + + tree.set_request_param("pool", "azure.batch.models.PoolAddParameter") + self.assertEqual(tree._request_param, {'name': 'pool', 'model': 'PoolAddParameter'}) + + self.assertEqual(tree.dequeue_argument("id"), {}) + self.assertFalse(tree.existing("id")) + + tree.queue_argument('id', 'pool', 'id', {}, 'str', ['vm_size', 'id']) + tree.queue_argument('vm_size', 'pool', 'vm_size', {}, 'str', ['vm_size', 'id']) + tree.queue_argument('target_dedicated', 'pool', 'target_dedicated', {}, 'int', + ['vm_size', 'id']) + tree.queue_argument('command_line', 'pool.start_task', 'command_line', {}, 'str', + ['command_line']) + tree.queue_argument('run_elevated', 'pool.start_task', 'run_elevated', {}, 'bool', + ['command_line']) + tree.queue_argument('node_agent_sku_id', 'pool.virtual_machine_configuration', + 'node_agent_sku_id', {}, 'str', + ['node_agent_sku_id', 'image_reference.offer', + 'image_reference.publisher']) + tree.queue_argument('offer', 'pool.virtual_machine_configuration.image_reference', + 'offer', {}, 'str', ['offer', 'publisher']) + tree.queue_argument('publisher', 'pool.virtual_machine_configuration.image_reference', + 'publisher', {}, 'str', ['offer', 'publisher']) + tree.queue_argument('version', 'pool.virtual_machine_configuration.image_reference', + 'version', {}, 'str', ['offer', 'publisher']) + tree.queue_argument('subnet_id', 'pool.network_configuration', 'id', {}, 'str', ['id']) + tree.queue_argument('os_family', 'pool.cloud_service_configuration', 'os_family', {}, + 'str', ['os_family']) + tree.queue_argument('target_os_version', 'pool.cloud_service_configuration', + 'target_os_version', {}, 'str', ['os_family']) + + self.assertEqual(len(list(tree)), 12) + self.assertTrue(tree.existing('vm_size')) + + ns = TestObj() + ns.id = None + ns.vm_size = None + ns.target_dedicated = 3 + ns.command_line = None + ns.run_elevated = None + ns.node_agent_sku_id = None + ns.offer = None + ns.publisher = None + ns.version = None + ns.subnet_id = None + ns.os_family = None + ns.target_os_version = None + with self.assertRaises(ValueError): + tree.parse(ns) + ns.id = "test_pool" + with self.assertRaises(ValueError): + tree.parse(ns) + ns.vm_size = "small" + tree.parse(ns) + ns.run_elevated = True + with self.assertRaises(ValueError): + tree.parse(ns) + ns.command_line = "cmd" + tree.parse(ns) + ns.run_elevated = None + tree.parse(ns) + ns.offer = "offer" + with self.assertRaises(ValueError): + tree.parse(ns) + ns.publisher = "publisher" + with self.assertRaises(ValueError): + tree.parse(ns) + ns.node_agent_sku_id = "sku id" + tree.parse(ns) + + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive(ns, False, ['pool.id', 'pool.vm_size']) + ns.id = None + tree.parse_mutually_exclusive(ns, False, ['pool.id', 'pool.vm_size']) + ns.vm_size = None + tree.parse_mutually_exclusive(ns, False, ['pool.id', 'pool.vm_size']) + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive(ns, True, ['pool.id', 'pool.vm_size']) + + ns.id = None + tree.parse_mutually_exclusive(ns, False, ['pool.id', 'pool.cloud_service_configuration']) + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive( + ns, True, ['pool.id', 'pool.cloud_service_configuration']) + ns.id = "id" + tree.parse_mutually_exclusive( + ns, True, ['pool.id', 'pool.cloud_service_configuration']) + ns.target_os_version = "4" + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive( + ns, True, ['pool.id', 'pool.cloud_service_configuration']) + + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive( + ns, True, ['pool.virtual_machine_configuration', + 'pool.cloud_service_configuration']) + ns.target_os_version = None + tree.parse_mutually_exclusive( + ns, True, ['pool.virtual_machine_configuration', + 'pool.cloud_service_configuration']) + ns.publisher = None + ns.offer = None + ns.node_agent_sku_id = None + tree.parse_mutually_exclusive( + ns, False, ['pool.virtual_machine_configuration', + 'pool.cloud_service_configuration']) + with self.assertRaises(ValueError): + tree.parse_mutually_exclusive(ns, True, ['pool.virtual_machine_configuration', + 'pool.cloud_service_configuration']) + + siblings = tree._get_siblings("pool") + self.assertEqual(sorted(siblings), ["id", "target_dedicated", "vm_size"]) + siblings = tree._get_siblings("pool.virtual_machine_configuration") + self.assertEqual(sorted(siblings), ["node_agent_sku_id"]) + children = tree._get_children("pool.virtual_machine_configuration") + self.assertEqual(sorted(children), ["node_agent_sku_id", "offer", "publisher", "version"]) + + tree.dequeue_argument('node_agent_sku_id') + self.assertEqual(len(list(tree)), 11) + diff --git a/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_pool_commands.py b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_pool_commands.py new file mode 100644 index 00000000000..cdad6c456f6 --- /dev/null +++ b/src/command_modules/azure-cli-batch/azure/cli/command_modules/batch/tests/test_batch_pool_commands.py @@ -0,0 +1,190 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +import os + +from azure.cli.core._util import CLIError +from azure.cli.core.test_utils.vcr_test_base import VCRTestBase + + +class BatchPoolScenarioTest(VCRTestBase): + + def __init__(self, test_method): + super(BatchPoolScenarioTest, self).__init__(__file__, test_method) + self.pool_paas = "azure-cli-test-paas" + self.pool_iaas = "azure-cli-test-iaas" + self.pool_json = "azure-cli-test-json" + self.data_dir = os.path.join( + os.path.dirname(__file__), 'data', 'batch-pool-{}.json').replace('\\', '\\\\') + self.account_name = os.environ.get('AZURE_BATCH_ACCOUNT_NAME', 'test1') + self.account_key = os.environ.get('AZURE_BATCH_ACCESS_KEY', 'ZmFrZV9hY29jdW50X2tleQ==') + self.account_endpoint = os.environ.get('AZURE_BATCH_ENDPOINT', + 'http://test1.westus.batch.azure.com') + + def set_up(self): + os.environ['AZURE_BATCH_ACCOUNT'] = self.account_name + os.environ['AZURE_BATCH_ACCESS_KEY'] = self.account_key + os.environ['AZURE_BATCH_ENDPOINT'] = self.account_endpoint + + def tear_down(self): + # Clean up any running pools in case the test exited early + for pool in [self.pool_iaas, self.pool_paas, self.pool_json]: + try: + self.cmd('batch pool delete --pool-id {} --force'.format(pool)) + except Exception: + pass + + def test_batch_pools(self): + self.execute() + + def body(self): + + # test create paas pool using parameters + self.cmd('batch pool create --id {} --vm-size small --os-family 4'.format( + self.pool_paas)) + + # test create iaas pool using parameters + self.cmd('batch pool create --id {} --vm-size Standard_A1 --publisher Canonical --offer' + + 'UbuntuServer --sku 16.04.0-LTS --node-agent-sku-id "batch.node.ubuntu 16.04"'. + format(self.pool_iaas)) + + # test create pool with missing parameters + try: + self.cmd('batch pool create --id missing-params-test --os-family 4') + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool with missing required mutually exclusive parameters + try: + self.cmd('batch pool create --id missing-required-group-test --vm-size small') + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool with parameters from mutually exclusive groups + try: + self.cmd('batch pool create --id mutually-exclusive-test --vm-size small --os-family' + + '4 --publisher Canonical --offer UbuntuServer') + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool with invalid vm size for IaaS + try: + self.cmd('batch pool create --id invalid-size-test --vm-size small --publisher ' + + 'Canonical --offer UbuntuServer --sku 16.04.0-LTS --node-agent-sku-id ' + + '"batch.node.ubuntu 16.04"') + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool with missing optional parameters + try: + self.cmd('batch pool create --id missing-optional-test --vm-size small --os-family' + + ' 4 --run-elevated') + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool from JSON file + self.cmd('batch pool create --json-file {}'.format(self.data_dir.format('create'))) + + # test create pool from non-existant JSON file + try: + self.cmd('batch pool create --json-file batch-pool-create-missing.json') + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool from invalid JSON file + try: + self.cmd('batch pool create --json-file {}'.format( + self.data_dir.format('create-invalid'))) + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test create pool from JSON file with additional parameters + try: + self.cmd('batch pool create --json-file {} --vm-size small'.format( + self.data_dir.format('create'))) + raise AssertionError("Excepted exception to be raised.") + except SystemExit as exp: + self.assertEqual(exp.code, 2) + + # test list pools + pool_list = self.cmd('batch pool list') + self.assertEqual(len(pool_list), 3) + pool_ids = sorted([p['id'] for p in pool_list]) + self.assertEqual(pool_ids, [self.pool_iaas, self.pool_json, self.pool_paas]) + + # test list pools with select + pool_list = self.cmd('batch pool list --filter "id eq \'{}\'"'.format(self.pool_paas)) + self.assertEqual(len(pool_list), 1) + + # test resize pool + self.cmd('batch pool resize --pool-id {} --target-dedicated 5'.format(self.pool_paas)) + pool_result = self.cmd('batch pool show --pool-id {} --select "allocationState,' + + ' targetDedicated"'.format(self.pool_paas)) + self.assertEqual(pool_result['allocationState'], 'resizing') + self.assertEqual(pool_result['targetDedicated'], 5) + + # test cancel pool resize + self.cmd('batch pool resize --pool-id {} --abort'.format(self.pool_paas)) + + # test enable autoscale + self.cmd('batch pool autoscale enable --pool-id {} --auto-scale-formula ' + + '"$TargetDedicated=3"'.format(self.pool_iaas)) + pool_result = self.cmd('batch pool show --pool-id {} --select "enableAutoScale"'.format( + self.pool_iaas)) + self.assertEqual(pool_result['enableAutoScale'], True) + + # test evaluate autoscale + self.cmd('batch pool autoscale evaluate --pool-id {} --auto-scale-formula ' + + '"$TargetDedicated=3"'.format(self.pool_iaas)) + + # test disable autoscale + self.cmd('batch pool autoscale disable --pool-id {}'.format(self.pool_iaas)) + pool_result = self.cmd('batch pool show --pool-id {} --select "enableAutoScale"'.format( + self.pool_iaas)) + self.assertEqual(pool_result['enableAutoScale'], False) + + # test list usage metrics + metrics = self.cmd('batch pool usage-metrics list') + + # TODO: Test update pool from JSON file + + # test patch pool using parameters + current = self.cmd('batch pool show --pool-id {} --select "startTask"'.format( + self.pool_json)) + self.cmd('batch pool set --pool-id {} --command-line new_value'.format( + self.pool_json)) + updated = self.cmd('batch pool show --pool-id {} --select "startTask"'.format( + self.pool_json)) + self.assertNotEqual(current['startTask']['commandLine'], + updated['startTask']['commandLine']) + + # test list node agent skus + skus = self.cmd('batch pool node-agent-skus list') + + ## test delete iaas pool + self.cmd('batch pool delete --pool-id {} --force'.format(self.pool_iaas)) + pool_result = self.cmd('batch pool show --pool-id {} --select "state"'.format( + self.pool_iaas)) + self.assertEqual(pool_result['state'], 'deleting') + + ## test app package reference + try: + self.cmd('batch pool create --id app_package_test --vm-size small --os-family 4 ' + + '--application-package-references does-not-exist') + raise AssertionError("Excepted exception to be raised.") + except CLIError as err: + pass + try: + self.cmd('batch pool set --pool-id {} --application-package-references ' + + 'does-not-exist'.format(self.pool_paas)) + raise AssertionError("Excepted exception to be raised.") + except CLIError as err: + pass