From 7653e9af53a5a6eca217b739c89d44ac7711fe02 Mon Sep 17 00:00:00 2001 From: ZelinWang Date: Fri, 24 Feb 2023 14:46:11 +0800 Subject: [PATCH 1/3] refine extension test --- .azure-pipelines/templates/azdev_setup.yml | 25 ++++++ azure-pipelines.yml | 46 +++-------- scripts/ci/test_source.py | 88 ++++++++++++++-------- scripts/ci/test_source.sh | 17 ----- 4 files changed, 92 insertions(+), 84 deletions(-) create mode 100644 .azure-pipelines/templates/azdev_setup.yml delete mode 100755 scripts/ci/test_source.sh diff --git a/.azure-pipelines/templates/azdev_setup.yml b/.azure-pipelines/templates/azdev_setup.yml new file mode 100644 index 00000000000..71084999a01 --- /dev/null +++ b/.azure-pipelines/templates/azdev_setup.yml @@ -0,0 +1,25 @@ +parameters: + - name: CLIRepoPath + type: string + default: '../azure-cli' + - name: CLIExtensionRepoPath + type: string + default: './' +steps: + - bash: | + set -ev + python -m venv env + chmod +x env/bin/activate + source ./env/bin/activate + # clone azure-cli + git clone -q --single-branch -b dev https://github.com/Azure/azure-cli.git ../azure-cli + python -m pip install -U pip + pip install azdev + azdev --version + azdev setup -c $CLI_REPO_PATH -r $CLI_EXT_REPO_PATH --debug + pip list -v + az --version + displayName: 'azdev setup' + env: + CLI_REPO_PATH: ${{ parameters.CLIRepoPath }} + CLI_EXT_REPO_PATH: ${{ parameters.CLIExtensionRepoPath }} \ No newline at end of file diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7da939505d8..7f93385244a 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -60,26 +60,11 @@ jobs: displayName: 'Use Python 3.10' inputs: versionSpec: 3.10 + - template: .azure-pipelines/templates/azdev_setup.yml - bash: | + #!/usr/bin/env bash set -ev - - # prepare and activate virtualenv - python -m venv env/ - - chmod +x ./env/bin/activate source ./env/bin/activate - - # clone azure-cli - git clone -q --single-branch -b dev https://github.com/Azure/azure-cli.git ../azure-cli - - python -m pip install -U pip - pip install -q azdev - - azdev setup -c ../azure-cli -r ./ - - azdev --version - az --version - azdev verify license - job: StaticAnalysis @@ -130,9 +115,15 @@ jobs: displayName: 'Use Python $(python.version)' inputs: versionSpec: '$(python.version)' + - template: .azure-pipelines/templates/azdev_setup.yml - bash: pip install wheel==0.30.0 displayName: 'Install wheel==0.30.0' - - bash: ./scripts/ci/test_source.sh + - bash: | + #!/usr/bin/env bash + set -ev + source ./env/bin/activate + az --version + python scripts/ci/test_source.py -v displayName: 'Run integration test and build test' env: ADO_PULL_REQUEST_LATEST_COMMIT: HEAD @@ -148,24 +139,11 @@ jobs: displayName: 'Use Python 3.10' inputs: versionSpec: 3.10 + - template: .azure-pipelines/templates/azdev_setup.yml - bash: | + #!/usr/bin/env bash set -ev - - # prepare and activate virtualenv - pip install virtualenv - python -m virtualenv venv/ - source ./venv/bin/activate - - # clone azure-cli - git clone --single-branch -b dev https://github.com/Azure/azure-cli.git ../azure-cli - - python -m pip install -U pip - pip install azdev - - azdev --version - - azdev setup -c ../azure-cli -r ./ - + source ./env/bin/activate # overwrite the default AZURE_EXTENSION_DIR set by ADO AZURE_EXTENSION_DIR=~/.azure/cliextensions az --version diff --git a/scripts/ci/test_source.py b/scripts/ci/test_source.py index feaa3fbc745..3a87f706c07 100755 --- a/scripts/ci/test_source.py +++ b/scripts/ci/test_source.py @@ -14,10 +14,9 @@ import unittest import shutil import shlex -from subprocess import check_output, check_call, CalledProcessError +from subprocess import check_output, check_call, CalledProcessError, run from unittest import mock -from wheel.install import WHEEL_INFO_RE from six import with_metaclass from util import SRC_PATH @@ -62,38 +61,61 @@ f'ALL_TESTS: {ALL_TESTS}.') -class TestExtensionSourceMeta(type): - def __new__(mcs, name, bases, _dict): - - def gen_test(ext_path): - def test(self): - ext_install_dir = os.path.join(self.ext_dir, 'ext') - pip_args = [sys.executable, '-m', 'pip', 'install', '--upgrade', '--target', - ext_install_dir, ext_path] - check_call(pip_args) - unittest_args = [sys.executable, '-m', 'unittest', 'discover', '-v', ext_path] - env = os.environ.copy() - env['PYTHONPATH'] = ext_install_dir - env['AZURE_CORE_USE_COMMAND_INDEX'] = 'false' - check_call(unittest_args, env=env) - return test - +# class TestExtensionSourceMeta(type): +# def __new__(mcs, name, bases, _dict): +# +# def gen_test(ext_path): +# def test(self): +# ext_install_dir = os.path.join(self.ext_dir, 'ext') +# pip_args = [sys.executable, '-m', 'pip', 'install', '--upgrade', '--target', +# ext_install_dir, ext_path] +# check_call(pip_args) +# unittest_args = [sys.executable, '-m', 'unittest', 'discover', '-v', ext_path] +# logger.warning(f'unittest_args: {unittest_args}') +# env = os.environ.copy() +# env['PYTHONPATH'] = ext_install_dir +# env['AZURE_CORE_USE_COMMAND_INDEX'] = 'false' +# check_call(unittest_args, env=env) +# return test +# +# for tname, ext_path in ALL_TESTS: +# test_name = "test_%s" % tname +# _dict[test_name] = gen_test(ext_path) +# return type.__new__(mcs, name, bases, _dict) +# +# +# class TestExtensionSource(with_metaclass(TestExtensionSourceMeta, unittest.TestCase)): +# +# def setUp(self): +# self.ext_dir = tempfile.mkdtemp() +# self.mock_env = mock.patch.dict(os.environ, {'AZURE_EXTENSION_DIR': self.ext_dir}) +# self.mock_env.start() +# +# def tearDown(self): +# self.mock_env.stop() +# shutil.rmtree(self.ext_dir) + + +class TestExtensionRecordingMode(unittest.TestCase): + + def run_command(self, cmd, check_return_code=False, cwd=None): + logger.info(f'cmd: {cmd}') + out = run(cmd, check=True, cwd=cwd) + if check_return_code and out.returncode: + raise RuntimeError(f"{cmd} failed") + + def test_extension(self): for tname, ext_path in ALL_TESTS: - test_name = "test_%s" % tname - _dict[test_name] = gen_test(ext_path) - return type.__new__(mcs, name, bases, _dict) - - -class TestExtensionSource(with_metaclass(TestExtensionSourceMeta, unittest.TestCase)): - - def setUp(self): - self.ext_dir = tempfile.mkdtemp() - self.mock_env = mock.patch.dict(os.environ, {'AZURE_EXTENSION_DIR': self.ext_dir}) - self.mock_env.start() - - def tearDown(self): - self.mock_env.stop() - shutil.rmtree(self.ext_dir) + ext_name = ext_path.split('/')[-1] + logger.info(f'installing extension: {ext_name}') + cmd = ['azdev', 'extension', 'add', ext_name] + self.run_command(cmd, check_return_code=True) + test_args = [sys.executable, '-m', 'azdev', 'test', '--no-exitfirst', '--discover', '--verbose', ext_name] + logger.warning(f'test_args: {test_args}') + self.run_command(test_args, check_return_code=True) + logger.info(f'uninstalling extension: {ext_name}') + cmd = ['azdev', 'extension', 'remove', ext_name] + self.run_command(cmd, check_return_code=True) class TestSourceWheels(unittest.TestCase): diff --git a/scripts/ci/test_source.sh b/scripts/ci/test_source.sh deleted file mode 100755 index 3aef6e1533e..00000000000 --- a/scripts/ci/test_source.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash -set -ex - -# Install CLI & CLI testsdk -echo "Installing azure-cli-testsdk, azure-cli-core, azure-cli from source code" -git clone https://github.com/Azure/azure-cli --depth 1 -find azure-cli/src/ -name setup.py -type f | xargs -I {} dirname {} | grep -v azure-cli-testsdk | xargs -I {} pip install --editable {} --no-deps -pip install --editable azure-cli/src/azure-cli-testsdk -pip install -r azure-cli/src/azure-cli/requirements.py3.$(uname).txt -echo "Installed." - -pip list -v -az --version - -python ./scripts/ci/test_source.py -v - -echo "OK. Completed tests." From f1e45c2167760a8c51c9b638eb6f226b34af39f2 Mon Sep 17 00:00:00 2001 From: ZelinWang Date: Fri, 24 Feb 2023 14:48:21 +0800 Subject: [PATCH 2/3] Update test_source.py --- scripts/ci/test_source.py | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/scripts/ci/test_source.py b/scripts/ci/test_source.py index 3a87f706c07..2cec7f87f96 100755 --- a/scripts/ci/test_source.py +++ b/scripts/ci/test_source.py @@ -61,41 +61,6 @@ f'ALL_TESTS: {ALL_TESTS}.') -# class TestExtensionSourceMeta(type): -# def __new__(mcs, name, bases, _dict): -# -# def gen_test(ext_path): -# def test(self): -# ext_install_dir = os.path.join(self.ext_dir, 'ext') -# pip_args = [sys.executable, '-m', 'pip', 'install', '--upgrade', '--target', -# ext_install_dir, ext_path] -# check_call(pip_args) -# unittest_args = [sys.executable, '-m', 'unittest', 'discover', '-v', ext_path] -# logger.warning(f'unittest_args: {unittest_args}') -# env = os.environ.copy() -# env['PYTHONPATH'] = ext_install_dir -# env['AZURE_CORE_USE_COMMAND_INDEX'] = 'false' -# check_call(unittest_args, env=env) -# return test -# -# for tname, ext_path in ALL_TESTS: -# test_name = "test_%s" % tname -# _dict[test_name] = gen_test(ext_path) -# return type.__new__(mcs, name, bases, _dict) -# -# -# class TestExtensionSource(with_metaclass(TestExtensionSourceMeta, unittest.TestCase)): -# -# def setUp(self): -# self.ext_dir = tempfile.mkdtemp() -# self.mock_env = mock.patch.dict(os.environ, {'AZURE_EXTENSION_DIR': self.ext_dir}) -# self.mock_env.start() -# -# def tearDown(self): -# self.mock_env.stop() -# shutil.rmtree(self.ext_dir) - - class TestExtensionRecordingMode(unittest.TestCase): def run_command(self, cmd, check_return_code=False, cwd=None): From 4f201831eadc26434253a2b5be62c0fbfe369f62 Mon Sep 17 00:00:00 2001 From: ZelinWang Date: Fri, 24 Feb 2023 17:54:00 +0800 Subject: [PATCH 3/3] update --- scripts/ci/test_source.py | 80 ++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/scripts/ci/test_source.py b/scripts/ci/test_source.py index 2cec7f87f96..df5f799e194 100755 --- a/scripts/ci/test_source.py +++ b/scripts/ci/test_source.py @@ -11,14 +11,10 @@ import os import sys import tempfile -import unittest import shutil import shlex -from subprocess import check_output, check_call, CalledProcessError, run - -from unittest import mock -from six import with_metaclass +from subprocess import check_output, CalledProcessError, run from util import SRC_PATH logger = logging.getLogger(__name__) @@ -61,44 +57,42 @@ f'ALL_TESTS: {ALL_TESTS}.') -class TestExtensionRecordingMode(unittest.TestCase): - - def run_command(self, cmd, check_return_code=False, cwd=None): - logger.info(f'cmd: {cmd}') - out = run(cmd, check=True, cwd=cwd) - if check_return_code and out.returncode: - raise RuntimeError(f"{cmd} failed") - - def test_extension(self): - for tname, ext_path in ALL_TESTS: - ext_name = ext_path.split('/')[-1] - logger.info(f'installing extension: {ext_name}') - cmd = ['azdev', 'extension', 'add', ext_name] - self.run_command(cmd, check_return_code=True) - test_args = [sys.executable, '-m', 'azdev', 'test', '--no-exitfirst', '--discover', '--verbose', ext_name] - logger.warning(f'test_args: {test_args}') - self.run_command(test_args, check_return_code=True) - logger.info(f'uninstalling extension: {ext_name}') - cmd = ['azdev', 'extension', 'remove', ext_name] - self.run_command(cmd, check_return_code=True) - - -class TestSourceWheels(unittest.TestCase): - - def test_source_wheels(self): - # Test we can build all sources into wheels and that metadata from the wheel is valid - built_whl_dir = tempfile.mkdtemp() - source_extensions = [os.path.join(SRC_PATH, n) for n in os.listdir(SRC_PATH) - if os.path.isdir(os.path.join(SRC_PATH, n))] - for s in source_extensions: - if not os.path.isfile(os.path.join(s, 'setup.py')): - continue - try: - check_output(['python', 'setup.py', 'bdist_wheel', '-q', '-d', built_whl_dir], cwd=s) - except CalledProcessError as err: - self.fail("Unable to build extension {} : {}".format(s, err)) - shutil.rmtree(built_whl_dir) +def run_command(cmd, check_return_code=False, cwd=None): + logger.info(f'cmd: {cmd}') + out = run(cmd, check=True, cwd=cwd) + if check_return_code and out.returncode: + raise RuntimeError(f"{cmd} failed") + + +def test_extension(): + for tname, ext_path in ALL_TESTS: + ext_name = ext_path.split('/')[-1] + logger.info(f'installing extension: {ext_name}') + cmd = ['azdev', 'extension', 'add', ext_name] + run_command(cmd, check_return_code=True) + test_args = [sys.executable, '-m', 'azdev', 'test', '--no-exitfirst', '--discover', '--verbose', ext_name] + logger.warning(f'test_args: {test_args}') + run_command(test_args, check_return_code=True) + logger.info(f'uninstalling extension: {ext_name}') + cmd = ['azdev', 'extension', 'remove', ext_name] + run_command(cmd, check_return_code=True) + + +def test_source_wheels(): + # Test we can build all sources into wheels and that metadata from the wheel is valid + built_whl_dir = tempfile.mkdtemp() + source_extensions = [os.path.join(SRC_PATH, n) for n in os.listdir(SRC_PATH) + if os.path.isdir(os.path.join(SRC_PATH, n))] + for s in source_extensions: + if not os.path.isfile(os.path.join(s, 'setup.py')): + continue + try: + check_output(['python', 'setup.py', 'bdist_wheel', '-q', '-d', built_whl_dir], cwd=s) + except CalledProcessError as err: + raise("Unable to build extension {} : {}".format(s, err)) + shutil.rmtree(built_whl_dir) if __name__ == '__main__': - unittest.main() + test_extension() + test_source_wheels()