diff --git a/src/mesh/HISTORY.rst b/src/mesh/HISTORY.rst index c6218a300c9..a837f6f415e 100644 --- a/src/mesh/HISTORY.rst +++ b/src/mesh/HISTORY.rst @@ -3,6 +3,12 @@ Release History =============== +0.9.2 (2018-08-03) +++++++++++++++++++ + +* Fix output in get logs command. + + 0.9.1 (2018-07-26) ++++++++++++++++++ diff --git a/src/mesh/README.rst b/src/mesh/README.rst index 33148484cdb..dbf1fa67f34 100644 --- a/src/mesh/README.rst +++ b/src/mesh/README.rst @@ -1,6 +1,12 @@ Microsoft Azure CLI 'mesh' Command Module ============================================================== Official doc https://docs.microsoft.com/en-us/azure/service-fabric-mesh/ + +Run tests live using +python tests/latest/test_mesh_commands.py +For more info on testing see +https://github.com/Azure/azure-cli/blob/dev/doc/authoring_tests.md + Commands to manage Azure Service Fabric Mesh resources ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ :: diff --git a/src/mesh/azext_mesh/commands.py b/src/mesh/azext_mesh/commands.py index c444ca737a7..ef087dad9f6 100644 --- a/src/mesh/azext_mesh/commands.py +++ b/src/mesh/azext_mesh/commands.py @@ -21,7 +21,7 @@ def transform_log_output(result): """Print log. """ - print(result) + return result def transform_application(result): diff --git a/src/mesh/azext_mesh/tests/latest/data/template1.json b/src/mesh/azext_mesh/tests/latest/data/template1.json new file mode 100644 index 00000000000..35e930ad07d --- /dev/null +++ b/src/mesh/azext_mesh/tests/latest/data/template1.json @@ -0,0 +1,93 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string", + "metadata": { + "description": "Location of the resources." + }, + "defaultValue": "eastus" + } + }, + "resources": [ + { + "apiVersion": "2018-07-01-preview", + "name": "helloWorldNetwork", + "type": "Microsoft.ServiceFabricMesh/networks", + "location": "[parameters('location')]", + "dependsOn": [], + "properties": { + "addressPrefix": "10.0.0.4/22", + "ingressConfig": { + "layer4": [ + { + "name": "helloWorldIngress", + "publicPort": "80", + "applicationName": "helloWorldApp", + "serviceName": "helloWorldService", + "endpointName": "helloWorldListener" + } + ] + } + } + }, + { + "apiVersion": "2018-07-01-preview", + "name": "helloWorldApp", + "type": "Microsoft.ServiceFabricMesh/applications", + "location": "[parameters('location')]", + "dependsOn": [ + "Microsoft.ServiceFabricMesh/networks/helloWorldNetwork" + ], + "properties": { + "description": "Service Fabric Mesh HelloWorld Application!", + "services": [ + { + "type": "Microsoft.ServiceFabricMesh/services", + "location": "[parameters('location')]", + "name": "helloWorldService", + "properties": { + "description": "Service Fabric Mesh Hello World Service.", + "osType": "linux", + "codePackages": [ + { + "name": "helloWorldCode", + "image": "seabreeze/azure-mesh-helloworld:1.1-alpine", + "endpoints": [ + { + "name": "helloWorldListener", + "port": "80" + } + ], + "resources": { + "requests": { + "cpu": "1", + "memoryInGB": "1" + } + } + }, + { + "name": "helloWorldSideCar", + "image": "seabreeze/azure-mesh-helloworld-sidecar:1.0-alpine", + "resources": { + "requests": { + "cpu": "1", + "memoryInGB": "1" + } + } + } + ], + "replicaCount": "1", + "networkRefs": [ + { + "name": "[resourceId('Microsoft.ServiceFabricMesh/networks', 'helloWorldNetwork')]" + } + ] + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/src/mesh/azext_mesh/tests/latest/test_mesh_commands.py b/src/mesh/azext_mesh/tests/latest/test_mesh_commands.py new file mode 100644 index 00000000000..2b7b4922dfe --- /dev/null +++ b/src/mesh/azext_mesh/tests/latest/test_mesh_commands.py @@ -0,0 +1,162 @@ +# -------------------------------------------------------------------------------------------- +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. See License.txt in the project root for license information. +# -------------------------------------------------------------------------------------------- + +# pylint: disable=line-too-long,unused-argument + +import unittest +from azure.cli.testsdk import ScenarioTest, ResourceGroupPreparer +import os +import urllib.request + + +def _get_test_data_file(filename): + curr_dir = os.path.dirname(os.path.realpath(__file__)) + return os.path.join(curr_dir, 'data', filename).replace('\\', '\\\\') + + +class AzureMeshServiceScenarioTest(ScenarioTest): + @ResourceGroupPreparer(random_name_length=20) + def test_app_commands(self, resource_group): + app_name = 'helloWorldApp' + self.kwargs.update({ + 'resource_id': '', + 'resource_group': resource_group, + 'deployment_name': self.create_random_name(prefix='cli', length=24), + 'app_name': app_name, + 'template_location': _get_test_data_file('template1.json') + }) + + # Test create + self.cmd('az mesh deployment create -g {rg} --template-file {template_location} --name {deployment_name}') + + # Test list + app_list = self.cmd('az mesh app list --resource-group {rg}', checks=[ + self.check('[0].name', app_name) + ]).get_output_in_json() + assert len(app_list) == 1 + + # Test show resource group/name + data = self.cmd('az mesh app show --resource-group {rg} --name {app_name}', checks=[ + self.exists('description'), + self.check('healthState', 'Ok'), + self.exists('id'), + self.exists('location'), + self.check('name', app_name), + self.check('provisioningState', 'Succeeded'), + self.exists('serviceNames'), + self.check('resourceGroup', resource_group), + self.check('status', 'Ready'), + self.exists('type') + ]).get_output_in_json() + resource_id = data['id'] + + # Test show resource id + show_data = self.cmd('az mesh app show --id {0}'.format(resource_id)).get_output_in_json() + + assert data == show_data + + # Test delete + self.cmd('az mesh app delete -g {rg} --name {app_name} --yes') + + app_list = self.cmd('az mesh app list --resource-group {rg}').get_output_in_json() + assert len(app_list) == 0 + + @ResourceGroupPreparer(random_name_length=20) + def test_service_commands(self, resource_group): + app_name = 'helloWorldApp' + + self.kwargs.update({ + 'resource_id': '', + 'resource_group': resource_group, + 'deployment_name': self.create_random_name(prefix='cli', length=24), + 'app_name': app_name, + 'service_name': 'helloWorldService', + 'template_location': _get_test_data_file('template1.json') + + }) + + self.cmd('az mesh deployment create -g {rg} --template-file {template_location} --name {deployment_name}') + + app_list = self.cmd('az mesh app list --resource-group {rg}', checks=[ + self.check('[0].name', app_name) + ]).get_output_in_json() + assert len(app_list) == 1 + + # Test list + service_list = self.cmd('az mesh service list --resource-group {rg} --app-name {app_name}', checks=[ + + ]).get_output_in_json() + assert len(service_list) == 1 + + # Test show + self.cmd('az mesh service show --resource-group {rg} --app-name {app_name} --name {service_name}', checks=[]) + + self.cmd('az mesh app delete -g {rg} --name {app_name} --yes') + + @ResourceGroupPreparer(random_name_length=20) + def test_service_replica_commands(self, resource_group): + app_name = 'helloWorldApp' + + self.kwargs.update({ + 'resource_group': resource_group, + 'deployment_name': self.create_random_name(prefix='cli', length=24), + 'app_name': app_name, + 'service_name': 'helloWorldService', + 'replica_name': 0, + 'template_location': _get_test_data_file('template1.json') + }) + + self.cmd('az mesh deployment create -g {rg} --template-file {template_location} --name {deployment_name}') + + app_list = self.cmd('az mesh app list --resource-group {rg}', checks=[ + self.check('[0].name', app_name) + ]).get_output_in_json() + assert len(app_list) == 1 + + # Test list + service_list = self.cmd('az mesh service-replica list --resource-group {rg} --app-name {app_name} --service-name {service_name}',).get_output_in_json() + assert len(service_list) == 1 + + # Test show + self.cmd('az mesh service-replica show --resource-group {rg} --app-name {app_name} --service-name {service_name} --replica-name {replica_name}', checks=[ + self.exists('codePackages'), + self.exists('networkRefs'), + self.exists('osType'), + self.exists('replicaName'), + ]) + + self.cmd('az mesh app delete -g {rg} --name {app_name} --yes') + + @ResourceGroupPreparer(random_name_length=20) + def test_code_package_log_commands(self, resource_group): + app_name = 'helloWorldApp' + + self.kwargs.update({ + 'resource_group': resource_group, + 'deployment_name': self.create_random_name(prefix='cli', length=24), + 'app_name': app_name, + 'service_name': 'helloWorldService', + 'replica_name': 0, + 'template_location': _get_test_data_file('template1.json'), + 'code_package_name': 'helloWorldCode', + 'network_name': 'helloWorldNetwork' + }) + + self.cmd('az mesh deployment create -g {rg} --template-file {template_location} --name {deployment_name}') + + network_info = self.cmd('az mesh network show -g {rg} -n {network_name}').get_output_in_json() + ip = network_info["ingressConfig"]["publicIpAddress"] + urllib.request.urlopen('http://' + ip) + + # Test log + self.cmd('az mesh code-package-log get --app-name {app_name} --code-package-name helloWorldCode --replica-name {replica_name} --resource-group {rg} --service-name {service_name} ', checks=[ + self.exists('content') + ]) + + self.cmd('az mesh app delete -g {rg} --name {app_name} --yes') + + +if __name__ == '__main__': + unittest.main() diff --git a/src/mesh/setup.py b/src/mesh/setup.py index d93e05848e1..f8b0a9e2237 100644 --- a/src/mesh/setup.py +++ b/src/mesh/setup.py @@ -8,7 +8,7 @@ from codecs import open from setuptools import setup, find_packages -VERSION = "0.9.1" +VERSION = "0.9.2" CLASSIFIERS = [ 'Development Status :: 4 - Beta',