Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions eng/scripts/dispatch_checks.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
from ci_tools.scenario.generation import build_whl_for_req, replace_dev_reqs
from ci_tools.logging import configure_logging, logger
from ci_tools.environment_exclusions import is_check_enabled, CHECK_DEFAULTS
from ci_tools.parsing import get_config_setting
from ci_tools.parsing import ParsedSetup, get_config_setting
from devtools_testutils.proxy_startup import prepare_local_tool
from packaging.requirements import Requirement

Expand Down Expand Up @@ -77,6 +77,15 @@ def _normalize_newlines(text: str) -> str:
return text.replace("\r\n", "\n").replace("\r", "\n")


def get_check_dest_dir(
package: str, check: str, dest_dir: Optional[str]
) -> Optional[str]:
if dest_dir and check == "apistub":
package_name = ParsedSetup.from_path(package).name
return os.path.join(dest_dir, package_name)
return dest_dir


async def _tee_stream(
proc: "asyncio.subprocess.Process", package: str, check: str
) -> tuple:
Expand Down Expand Up @@ -222,8 +231,10 @@ async def run_check(
cmd += ["--service", service]
if mark_arg:
cmd += ["--mark_arg", mark_arg]
if dest_dir and check == "apistub":
cmd += ["--dest-dir", dest_dir]
if check == "apistub":
check_dest_dir = get_check_dest_dir(package, check, dest_dir)
if check_dest_dir:
cmd += ["--dest-dir", check_dest_dir]
logger.info(f"[START {idx}/{total}] {check} :: {package}\nCMD: {' '.join(cmd)}")
env = os.environ.copy()
env["PROXY_URL"] = f"http://localhost:{proxy_port}"
Expand Down Expand Up @@ -500,14 +511,12 @@ def handler(signum, frame):


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="""
parser = argparse.ArgumentParser(description="""
This script is the single point for all checks invoked by CI within this repo. It works in two phases.
1. Identify which packages in the repo are in scope for this script invocation, based on a glob string and a service directory.
2. Invoke one or multiple `checks` environments for each package identified as in scope.
In the case of an environment invoking `pytest`, results can be collected in a junit xml file, and test markers can be selected via --mark_arg.
"""
)
""")

parser.add_argument(
"glob_string",
Expand Down
47 changes: 47 additions & 0 deletions eng/tools/azure-sdk-tools/tests/test_dispatch_checks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import os
import sys
from types import SimpleNamespace
from unittest.mock import patch

REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", "..", "..", ".."))
TOOLS_ROOT = os.path.join(REPO_ROOT, "eng", "tools", "azure-sdk-tools")
if TOOLS_ROOT not in sys.path:
sys.path.insert(0, TOOLS_ROOT)
if REPO_ROOT not in sys.path:
sys.path.insert(0, REPO_ROOT)

from eng.scripts.dispatch_checks import get_check_dest_dir


def test_apistub_dest_dir_uses_package_subdirectory():
package_dir = os.path.join(REPO_ROOT, "sdk", "core", "azure-core")
artifact_dir = os.path.join(REPO_ROOT, "artifacts")

with patch(
"eng.scripts.dispatch_checks.ParsedSetup.from_path",
return_value=SimpleNamespace(name="azure-core"),
):
result = get_check_dest_dir(package_dir, "apistub", artifact_dir)

assert result == os.path.join(artifact_dir, "azure-core")


def test_non_apistub_dest_dir_is_unchanged():
package_dir = os.path.join(REPO_ROOT, "sdk", "core", "azure-core")
artifact_dir = os.path.join(REPO_ROOT, "artifacts")

with patch("eng.scripts.dispatch_checks.ParsedSetup.from_path") as parsed_setup:
result = get_check_dest_dir(package_dir, "pylint", artifact_dir)

assert result == artifact_dir
parsed_setup.assert_not_called()


def test_empty_dest_dir_is_unchanged():
package_dir = os.path.join(REPO_ROOT, "sdk", "core", "azure-core")

with patch("eng.scripts.dispatch_checks.ParsedSetup.from_path") as parsed_setup:
result = get_check_dest_dir(package_dir, "apistub", None)

assert result is None
parsed_setup.assert_not_called()
39 changes: 39 additions & 0 deletions scripts/api_md_workflow/create_api_review_pr_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -605,6 +605,45 @@ def test_main_preflights_azsdk_first(self):

find_package_dir.assert_not_called()

def test_generate_api_for_package_uses_package_dir_destination(self):
package_dir = Path("sdk/example/azure-example")
with (
patch.object(workflow, "find_package_dir", return_value=package_dir),
patch.object(workflow, "run", return_value=command_result()) as run,
):
workflow.generate_api_for_package("azure-example", runtime_executable=None)

run.assert_called_once_with(
["azpysdk", "apistub", "--dest-dir", str(package_dir), "azure-example"],
check=True,
shell=workflow.sys.platform == "win32",
)

def test_generate_api_for_package_runtime_executable_uses_package_dir_destination(
self,
):
package_dir = Path("sdk/example/azure-example")
with (
patch.object(workflow, "find_package_dir", return_value=package_dir),
patch.object(workflow, "run", return_value=command_result()) as run,
):
workflow.generate_api_for_package(
"azure-example", runtime_executable="python"
)

run.assert_called_once_with(
[
"python",
"-m",
"azpysdk.main",
"apistub",
"--dest-dir",
str(package_dir),
"azure-example",
],
check=True,
)

def test_resolve_azsdk_uses_path_first(self):
with patch.object(workflow.shutil, "which", return_value="C:/tools/azsdk.exe"):
self.assertEqual(workflow.resolve_azsdk_executable(), "C:/tools/azsdk.exe")
Expand Down
Loading