|
| 1 | +# -------------------------------------------------------------------------------------------- |
| 2 | +# Copyright (c) Microsoft Corporation. All rights reserved. |
| 3 | +# Licensed under the MIT License. See License.txt in the project root for license information. |
| 4 | +# -------------------------------------------------------------------------------------------- |
| 5 | + |
| 6 | +import importlib |
| 7 | +from pathlib import Path |
| 8 | +import subprocess |
| 9 | +import tempfile |
| 10 | +import pytest |
| 11 | +import sys |
| 12 | +import shutil |
| 13 | + |
| 14 | + |
| 15 | +# This fixture ensures tests are run against final built wheels of the extension |
| 16 | +# instead of the unbuilt local code, which may have breaking differences with |
| 17 | +# the thing we actually ship to users. All but the test modules themselves are |
| 18 | +# replaced with the wheel in case the tests themselves rely on unshipped code. |
| 19 | + |
| 20 | + |
| 21 | +@pytest.fixture(autouse=True, scope="session") |
| 22 | +def run_on_wheel(request): |
| 23 | + |
| 24 | + modules_to_test = {i.module for i in request.session.items} |
| 25 | + extensions_to_build = {module.__name__.split(".")[0] for module in modules_to_test} |
| 26 | + extension_dirs = {Path(a.split("/azext_")[0]) for a in request.config.args} |
| 27 | + |
| 28 | + with tempfile.TemporaryDirectory(delete=True) as build_dir: |
| 29 | + |
| 30 | + # Delete the extensions build dir, as azdev extension build doesn't |
| 31 | + # reliably handle changes |
| 32 | + for extension_dir in extension_dirs: |
| 33 | + if (extension_dir / "build").exists(): |
| 34 | + shutil.rmtree((extension_dir / "build").as_posix(), ignore_errors=True) |
| 35 | + |
| 36 | + # Build all extensions being tested into wheels |
| 37 | + for extension in extensions_to_build: |
| 38 | + subprocess.run( |
| 39 | + ["azdev", "extension", "build", extension.replace("azext_", ""), "--dist-dir", build_dir], |
| 40 | + check=True, |
| 41 | + ) |
| 42 | + |
| 43 | + # Add the wheel to the path and reload extension modules so the |
| 44 | + # tests pick up the wheel code over the unbuilt code |
| 45 | + sys.path.insert(0, Path(build_dir).glob("*.whl").__next__().as_posix()) |
| 46 | + for module in list(sys.modules.values()): |
| 47 | + if extension in module.__name__ and module not in modules_to_test: |
| 48 | + del sys.modules[module.__name__] |
| 49 | + importlib.import_module(module.__name__) |
| 50 | + |
| 51 | + yield |
| 52 | + |
0 commit comments