Skip to content
Open
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
9 changes: 8 additions & 1 deletion lisa/search_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,12 +546,19 @@ def check_setspace(
has_met_check = True
break
if not has_met_check:
# check_setspace matches any requirement item regardless of
# is_allow_set, so don't render SetSpace's "not(...)" notation.
Comment thread
SRIKKANTH marked this conversation as resolved.
result.add_reason(
f"requires [{requirement}]" f" but VM supports [{capability}]"
f"requires [{_format_setspace_items(requirement)}]"
f" but VM supports [{_format_setspace_items(capability)}]"
)
return result


def _format_setspace_items(value: SetSpace[Any]) -> str:
return ", ".join(x.value if isinstance(x, Enum) else str(x) for x in value)


def choose_value_setspace_by_priority(
requirement: Optional[Union[SetSpace[T], T]],
capability: Optional[Union[SetSpace[T], T]],
Expand Down
3 changes: 2 additions & 1 deletion lisa/sut_orchestrator/azure/platform_.py
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,8 @@ def _prepare_environment(self, environment: Environment, log: Logger) -> bool:
)
else:
error_message = (
"; ".join(errors)
# Locations often report identical reasons.
"; ".join(dict.fromkeys(errors))
Comment thread
SRIKKANTH marked this conversation as resolved.
if errors
else (
"no eligible VM configuration found" f" in {allowed_locations}"
Expand Down
17 changes: 17 additions & 0 deletions selftests/azure/test_prepare.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from pathlib import Path
from typing import Any, Dict, List, Optional
from unittest.case import TestCase
from unittest.mock import patch

from azure.mgmt.compute.models import ResourceSku # type: ignore

Expand Down Expand Up @@ -156,6 +157,22 @@ def test_predefined_inconsistent_location_failed(self) -> None:
)
self.assertEqual(message, str(cm.exception)[0 : len(message)])

def test_duplicate_location_errors_are_deduplicated(self) -> None:
env = self.load_environment(node_req_count=1)
self.set_node_runbook(env, 0, location="westus3,eastus")
error = "the same requirement mismatch"

with patch.object(
self._platform,
"_get_azure_capabilities",
return_value=([], error),
) as get_capabilities:
with self.assertRaises(NotMeetRequirementException) as cm:
self._platform._prepare_environment(env, self._log)

self.assertEqual(2, get_capabilities.call_count)
self.assertEqual(error, str(cm.exception))

def test_no_predefined_location_use_default_locations(self) -> None:
# no predefined location found, use default location list
env = self.load_environment(node_req_count=1)
Expand Down
46 changes: 46 additions & 0 deletions selftests/test_search_space.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from functools import partial
from typing import Any, List, Optional, TypeVar

from lisa.schema import DiskControllerType, NetworkDataPath
from lisa.search_space import (
CountSpace,
IntRange,
Expand All @@ -15,8 +16,10 @@
SetSpace,
check,
check_countspace,
check_setspace,
choose_value,
choose_value_countspace,
intersect_setspace_by_priority,
)
from lisa.util import LisaException
from lisa.util.logger import get_logger
Expand Down Expand Up @@ -207,6 +210,49 @@ def test_choose_value_not_supported(self) -> None:
requirement.choose_value(capability)
self.assertIn("doesn't support", str(cm.exception))

def test_check_setspace_reason_lists_required_items(self) -> None:
# Default SetSpace has is_allow_set=False, but check_setspace treats it
# as "any of", so the reason must not render it as "not(...)".
cases = [
(
SetSpace[DiskControllerType](items=[DiskControllerType.NVME]),
SetSpace[DiskControllerType](
is_allow_set=True, items=[DiskControllerType.SCSI]
),
"requires [NVMe] but VM supports [SCSI]",
),
(
DiskControllerType.NVME,
DiskControllerType.SCSI,
"requires [NVMe] but VM supports [SCSI]",
),
(
SetSpace[str](is_allow_set=True, items=["aa"]),
SetSpace[str](items=["bb"]),
"requires [aa] but VM supports [bb]",
),
(
# A merged requirement, e.g. Sriov() intersected with the
# default {Synthetic, Sriov}, is returned with is_allow_set=False.
intersect_setspace_by_priority(
NetworkDataPath.Sriov,
SetSpace[NetworkDataPath](
items=[NetworkDataPath.Synthetic, NetworkDataPath.Sriov]
),
[NetworkDataPath.Sriov],
),
SetSpace[NetworkDataPath](
is_allow_set=True, items=[NetworkDataPath.Synthetic]
),
"requires [Sriov] but VM supports [Synthetic]",
),
]
for requirement, capability, expected_reason in cases:
with self.subTest(requirement=requirement, capability=capability):
result = check_setspace(requirement, capability)
self.assertFalse(result.result)
self.assertEqual([expected_reason], result.reasons)

def test_int_range_validation(self) -> None:
with self.assertRaises(expected_exception=LisaException) as cm:
IntRange(min=6, max=4)
Expand Down
Loading