diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/dotnetcore-hello-up.zip b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/dotnetcore-hello-up.zip new file mode 100644 index 00000000000..0a6c3e4c8df Binary files /dev/null and b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/dotnetcore-hello-up.zip differ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/html-static-hello-world-up.zip b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/html-static-hello-world-up.zip new file mode 100644 index 00000000000..9416df3c169 Binary files /dev/null and b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/html-static-hello-world-up.zip differ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/node-Express-up.zip b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/node-Express-up.zip new file mode 100644 index 00000000000..618dd796056 Binary files /dev/null and b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/node-Express-up.zip differ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/python-hello-world-up.zip b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/python-hello-world-up.zip new file mode 100644 index 00000000000..39c01a78744 Binary files /dev/null and b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/python-hello-world-up.zip differ diff --git a/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_up_commands.py b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_up_commands.py new file mode 100644 index 00000000000..7272d5f3692 --- /dev/null +++ b/src/azure-cli/azure/cli/command_modules/appservice/tests/latest/test_webapp_up_commands.py @@ -0,0 +1,296 @@ +# -------------------------------------------------------------------------------------------- +# 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 +# pylint: disable=too-few-public-methods + +import json +import unittest +import jmespath +import tempfile +import os + +from azure.cli.testsdk import ( + ScenarioTest, ResourceGroupPreparer, JMESPathCheck, live_only) + +TEST_DIR = os.path.abspath(os.path.join(os.path.abspath(__file__), '..')) + + +class WebAppUpE2ETests(ScenarioTest): + @live_only() + @ResourceGroupPreparer() + def test_webapp_up_node_e2e(self, resource_group): + plan = self.create_random_name('up-nodeplan', 24) + webapp_name = self.create_random_name('up-nodeapp', 24) + zip_file_name = os.path.join(TEST_DIR, 'node-Express-up.zip') + + # create a temp directory and unzip the code to this folder + import zipfile + import tempfile + temp_dir = tempfile.mkdtemp() + zip_ref = zipfile.ZipFile(zip_file_name, 'r') + zip_ref.extractall(temp_dir) + current_working_dir = os.getcwd() + + # change the working dir to the dir where the code has been extracted to + up_working_dir = os.path.join(temp_dir, 'myExpressApp') + os.chdir(up_working_dir) + + # test dryrun operation + result = self.cmd( + 'webapp up -n {} --dryrun'.format(webapp_name)).get_output_in_json() + self.assertTrue(result['sku'].lower() == 'premiumv2') + self.assertTrue(result['name'].startswith(webapp_name)) + self.assertTrue(result['src_path'].replace( + os.sep + os.sep, os.sep), up_working_dir) + self.assertTrue(result['runtime_version'] == 'node|10.14') + self.assertTrue(result['os'].lower() == 'linux') + + # test the full E2E operation works + full_result = self.cmd( + 'webapp up -n {} -g {} --plan {}'.format(webapp_name, resource_group, plan)).get_output_in_json() + self.assertTrue(result['name'] == full_result['name']) + + # Verify app is created + # since we set local context, -n and -g are no longer required + self.cmd('webapp show', checks=[ + JMESPathCheck('name', webapp_name), + JMESPathCheck('httpsOnly', True), + JMESPathCheck('kind', 'app,linux'), + JMESPathCheck('resourceGroup', resource_group) + ]) + + self.cmd('webapp config show', checks=[ + JMESPathCheck('linuxFxVersion', result['runtime_version']), + JMESPathCheck('tags.cli', 'webapp_up'), + ]) + + self.cmd('webapp config appsettings list', checks=[ + JMESPathCheck('[0].name', 'SCM_DO_BUILD_DURING_DEPLOYMENT'), + JMESPathCheck('[0].value', 'True') + ]) + + self.cmd('appservice plan show', checks=[ + JMESPathCheck('reserved', True), + JMESPathCheck('name', plan), + JMESPathCheck('sku.tier', 'PremiumV2'), + JMESPathCheck('sku.name', 'P1v2') + ]) + + # cleanup + # switch back the working dir + os.chdir(current_working_dir) + # delete temp_dir + import shutil + shutil.rmtree(temp_dir) + + @live_only() + @ResourceGroupPreparer() + def test_webapp_up_python_e2e(self, resource_group): + plan = self.create_random_name('up-pythonplan', 24) + webapp_name = self.create_random_name('up-pythonapp', 24) + zip_file_name = os.path.join(TEST_DIR, 'python-hello-world-up.zip') + + # create a temp directory and unzip the code to this folder + import zipfile + import tempfile + temp_dir = tempfile.mkdtemp() + zip_ref = zipfile.ZipFile(zip_file_name, 'r') + zip_ref.extractall(temp_dir) + current_working_dir = os.getcwd() + + # change the working dir to the dir where the code has been extracted to + up_working_dir = os.path.join(temp_dir, 'python-docs-hello-world') + os.chdir(up_working_dir) + + # test dryrun operation + result = self.cmd('webapp up -n {} --sku S1 --dryrun' + .format(webapp_name)).get_output_in_json() + self.assertTrue(result['sku'].lower() == 'standard') + self.assertTrue(result['name'].startswith(webapp_name)) + self.assertTrue(result['src_path'].replace( + os.sep + os.sep, os.sep), up_working_dir) + self.assertTrue(result['runtime_version'] == 'python|3.7') + self.assertTrue(result['os'].lower() == 'linux') + + # test the full E2E operation works + full_result = self.cmd( + 'webapp up -n {} --sku S1 -g {} --plan {}'.format(webapp_name, resource_group, plan)).get_output_in_json() + self.assertTrue(result['name'] == full_result['name']) + + # Verify app is created + # since we set local context, -n and -g are no longer required + self.cmd('webapp show', checks=[ + JMESPathCheck('name', webapp_name), + JMESPathCheck('httpsOnly', True), + JMESPathCheck('kind', 'app,linux'), + JMESPathCheck('resourceGroup', resource_group) + ]) + + self.cmd('webapp config show', checks=[ + JMESPathCheck('linuxFxVersion', result['runtime_version']), + JMESPathCheck('tags.cli', 'webapp_up'), + ]) + + self.cmd('webapp config appsettings list', checks=[ + JMESPathCheck('[0].name', 'SCM_DO_BUILD_DURING_DEPLOYMENT'), + JMESPathCheck('[0].value', 'True') + ]) + + # verify SKU and kind of ASP created + self.cmd('appservice plan show', checks=[ + JMESPathCheck('reserved', True), + JMESPathCheck('name', plan), + JMESPathCheck('sku.tier', 'Standard'), + JMESPathCheck('sku.name', 'S1') + ]) + + # cleanup + # switch back the working dir + os.chdir(current_working_dir) + # delete temp_dir + import shutil + shutil.rmtree(temp_dir) + + @live_only() + @ResourceGroupPreparer() + def test_webapp_up_dotnetcore_e2e(self, resource_group): + plan = self.create_random_name('up-dotnetcoreplan', 24) + webapp_name = self.create_random_name('up-dotnetcoreapp', 24) + zip_file_name = os.path.join(TEST_DIR, 'dotnetcore-hello-up.zip') + + # create a temp directory and unzip the code to this folder + import zipfile + import tempfile + temp_dir = tempfile.mkdtemp() + zip_ref = zipfile.ZipFile(zip_file_name, 'r') + zip_ref.extractall(temp_dir) + current_working_dir = os.getcwd() + + # change the working dir to the dir where the code has been extracted to + up_working_dir = os.path.join(temp_dir, 'hellodotnetcore') + os.chdir(up_working_dir) + + # test dryrun operation + result = self.cmd('webapp up -n {} --dryrun' + .format(webapp_name)).get_output_in_json() + self.assertTrue(result['sku'].lower() == 'free') + self.assertTrue(result['name'].startswith(webapp_name)) + self.assertTrue(result['src_path'].replace( + os.sep + os.sep, os.sep), up_working_dir) + self.assertTrue(result['runtime_version'] == 'dotnetcore|2.2') + self.assertTrue(result['os'].lower() == 'windows') + + # test the full E2E operation works + full_result = self.cmd( + 'webapp up -n {} -g {} --plan {}'.format(webapp_name, resource_group, plan)).get_output_in_json() + self.assertTrue(result['name'] == full_result['name']) + + # Verify app is created + # since we set local context, -n and -g are no longer required + self.cmd('webapp show', checks=[ + JMESPathCheck('name', webapp_name), + JMESPathCheck('httpsOnly', True), + JMESPathCheck('kind', 'app'), + JMESPathCheck('resourceGroup', resource_group) + ]) + + self.cmd('webapp config show', checks=[ + JMESPathCheck('tags.cli', 'webapp_up'), + JMESPathCheck('windowsFxVersion', None) + ]) + + self.cmd('webapp config appsettings list', checks=[ + JMESPathCheck('[1].name', 'SCM_DO_BUILD_DURING_DEPLOYMENT'), + JMESPathCheck('[1].value', 'True') + ]) + + # verify SKU and kind of ASP created + self.cmd('appservice plan show', checks=[ + JMESPathCheck('reserved', False), + JMESPathCheck('name', plan), + JMESPathCheck('sku.tier', 'Free'), + JMESPathCheck('sku.name', 'F1') + ]) + + # cleanup + # switch back the working dir + os.chdir(current_working_dir) + # delete temp_dir + import shutil + shutil.rmtree(temp_dir) + + @live_only() + @ResourceGroupPreparer() + def test_webapp_up_statichtml_e2e(self, resource_group): + plan = self.create_random_name('up-statichtmlplan', 24) + webapp_name = self.create_random_name('up-statichtmlapp', 24) + zip_file_name = os.path.join( + TEST_DIR, 'html-static-hello-world-up.zip') + + # create a temp directory and unzip the code to this folder + import zipfile + import tempfile + temp_dir = tempfile.mkdtemp() + zip_ref = zipfile.ZipFile(zip_file_name, 'r') + zip_ref.extractall(temp_dir) + current_working_dir = os.getcwd() + + # change the working dir to the dir where the code has been extracted to + up_working_dir = os.path.join(temp_dir, 'html-docs-hello-world-master') + os.chdir(up_working_dir) + + # test dryrun operation + result = self.cmd('webapp up -n {} --dryrun --html' + .format(webapp_name)).get_output_in_json() + self.assertTrue(result['sku'].lower() == 'free') + self.assertTrue(result['name'].startswith(webapp_name)) + self.assertTrue(result['src_path'].replace( + os.sep + os.sep, os.sep), up_working_dir) + self.assertTrue(result['runtime_version'] == '-') + self.assertTrue(result['os'].lower() == 'windows') + + # test the full E2E operation works + full_result = self.cmd( + 'webapp up -n {} -g {} --plan {} --html'.format(webapp_name, resource_group, plan)).get_output_in_json() + self.assertTrue(result['name'] == full_result['name']) + + # Verify app is created + # since we set local context, -n and -g are no longer required + self.cmd('webapp show', checks=[ + JMESPathCheck('name', webapp_name), + JMESPathCheck('httpsOnly', True), + JMESPathCheck('kind', 'app'), + JMESPathCheck('resourceGroup', resource_group) + ]) + + self.cmd('webapp config show', checks=[ + JMESPathCheck('tags.cli', 'webapp_up'), + JMESPathCheck('windowsFxVersion', None) + ]) + + self.cmd('webapp config appsettings list', checks=[ + JMESPathCheck('[1].name', 'SCM_DO_BUILD_DURING_DEPLOYMENT'), + JMESPathCheck('[1].value', 'True') + ]) + + # verify SKU and kind of ASP created + self.cmd('appservice plan show', checks=[ + JMESPathCheck('reserved', False), + JMESPathCheck('name', plan), + JMESPathCheck('sku.tier', 'Free'), + JMESPathCheck('sku.name', 'F1') + ]) + + # cleanup + # switch back the working dir + os.chdir(current_working_dir) + # delete temp_dir + import shutil + shutil.rmtree(temp_dir) + + +if __name__ == '__main__': + unittest.main()