Skip to content

Commit 128dd72

Browse files
authored
fix: Readd get_many for old engines (#375)
1 parent 045acc3 commit 128dd72

File tree

5 files changed

+128
-3
lines changed

5 files changed

+128
-3
lines changed

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ ciso8601 =
4949
dev =
5050
allure-pytest==2.*
5151
devtools==0.7.0
52-
mypy==1.*
52+
mypy==1.*,<1.10.0
5353
pre-commit==2.15.0
5454
pyfakefs>=4.5.3
5555
pytest==7.2.0

src/firebolt/service/V1/engine.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
from logging import getLogger
2-
from typing import List
2+
from typing import List, Optional, Union
33

44
from firebolt.model.V1.engine import Engine
55
from firebolt.service.V1.base import BaseService
6+
from firebolt.service.V1.types import EngineOrder
67
from firebolt.utils.urls import (
78
ACCOUNT_ENGINE_ID_BY_NAME_URL,
89
ACCOUNT_ENGINE_URL,
10+
ACCOUNT_LIST_ENGINES_URL,
911
ENGINES_BY_IDS_URL,
1012
)
13+
from firebolt.utils.util import prune_dict
1114

1215
logger = getLogger(__name__)
1316

@@ -47,3 +50,51 @@ def get_by_name(self, name: str) -> Engine:
4750
)
4851
engine_id = response.json()["engine_id"]["engine_id"]
4952
return self.get(id_=engine_id)
53+
54+
def get_many(
55+
self,
56+
name_contains: Optional[str] = None,
57+
current_status_eq: Optional[str] = None,
58+
current_status_not_eq: Optional[str] = None,
59+
region_eq: Optional[str] = None,
60+
order_by: Optional[Union[str, EngineOrder]] = None,
61+
) -> List[Engine]:
62+
"""
63+
Get a list of engines on Firebolt.
64+
65+
Args:
66+
name_contains: Filter for engines with a name containing this substring
67+
current_status_eq: Filter for engines with this status
68+
current_status_not_eq: Filter for engines that do not have this status
69+
region_eq: Filter for engines by region
70+
order_by: Method by which to order the results. See [EngineOrder]
71+
72+
Returns:
73+
A list of engines matching the filters
74+
"""
75+
76+
if isinstance(order_by, str):
77+
order_by = EngineOrder[order_by].name
78+
79+
if region_eq is not None:
80+
region_eq = self.resource_manager.regions.get_by_name(
81+
name=region_eq
82+
).key.region_id
83+
84+
response = self.client.get(
85+
url=ACCOUNT_LIST_ENGINES_URL.format(account_id=self.account_id),
86+
params=prune_dict(
87+
{
88+
"page.first": 5000,
89+
"filter.name_contains": name_contains,
90+
"filter.current_status_eq": current_status_eq,
91+
"filter.current_status_not_eq": current_status_not_eq,
92+
"filter.compute_region_id_region_id_eq": region_eq,
93+
"order_by": order_by,
94+
}
95+
),
96+
)
97+
return [
98+
Engine.parse_obj_with_service(obj=e["node"], engine_service=self)
99+
for e in response.json()["edges"]
100+
]

tests/integration/resource_manager/V1/test_engine.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ def test_get_engine(resource_manager: ResourceManager, engine_name: str):
1616
)
1717

1818

19+
def test_get_many(resource_manager: ResourceManager, engine_name: str):
20+
engines = resource_manager.engines.get_many(name_contains=engine_name)
21+
# >= 1 because we may have a stopped engine with the same name + _stopped
22+
assert len(engines) >= 1
23+
24+
1925
@mark.skip(reason="Interferes with other tests")
2026
def test_engine_stop_start(resource_manager: ResourceManager, engine_name: str):
2127
engine = resource_manager.engines.get_by_name(engine_name)

tests/unit/service/V1/conftest.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,20 @@ def do_mock(
260260
return do_mock
261261

262262

263+
@fixture
264+
def many_engines_callback(mock_engine: Engine) -> Callable:
265+
def do_mock(
266+
request: httpx.Request = None,
267+
**kwargs,
268+
) -> Response:
269+
return Response(
270+
status_code=httpx.codes.OK,
271+
json={"edges": [{"node": mock_engine.model_dict()}]},
272+
)
273+
274+
return do_mock
275+
276+
263277
@fixture
264278
def account_engine_url(server: str, account_id, mock_engine) -> str:
265279
return f"https://{server}" + ACCOUNT_ENGINE_URL.format(

tests/unit/service/V1/test_engine.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ def test_engine_start_stop(
2424
httpx_mock.add_callback(auth_callback, url=auth_url)
2525
httpx_mock.add_callback(provider_callback, url=provider_url)
2626
httpx_mock.add_callback(account_id_callback, url=account_id_url)
27-
httpx_mock.add_callback(auth_callback, url=auth_url)
2827

2928
httpx_mock.add_callback(engine_callback, url=f"{account_engine_url}", method="GET")
3029
httpx_mock.add_callback(
@@ -44,3 +43,58 @@ def test_engine_start_stop(
4443
engine = mock_engine.stop(wait_for_stop=False)
4544

4645
assert engine.name == mock_engine.name
46+
47+
48+
def test_engine_get_many(
49+
httpx_mock: HTTPXMock,
50+
settings: Settings,
51+
mock_engine: Engine,
52+
auth_callback: Callable,
53+
auth_url: str,
54+
engine_url: str,
55+
many_engines_callback: Callable,
56+
provider_callback: Callable,
57+
provider_url: str,
58+
account_id_callback: Callable,
59+
account_id_url: Pattern,
60+
):
61+
62+
httpx_mock.add_callback(auth_callback, url=auth_url)
63+
httpx_mock.add_callback(provider_callback, url=provider_url)
64+
httpx_mock.add_callback(account_id_callback, url=account_id_url)
65+
filters = "?page.first=5000&filter.name_contains=test"
66+
httpx_mock.add_callback(many_engines_callback, url=engine_url + filters)
67+
68+
manager = ResourceManager(settings=settings)
69+
engines = manager.engines.get_many(name_contains="test")
70+
assert len(engines) == 1
71+
assert engines[0].name == mock_engine.name
72+
73+
74+
def test_engine_get_many_with_region(
75+
httpx_mock: HTTPXMock,
76+
settings: Settings,
77+
mock_engine: Engine,
78+
auth_callback: Callable,
79+
auth_url: str,
80+
engine_url: str,
81+
many_engines_callback: Callable,
82+
provider_callback: Callable,
83+
provider_url: str,
84+
account_id_callback: Callable,
85+
account_id_url: Pattern,
86+
region_callback: Callable,
87+
region_url: str,
88+
):
89+
90+
httpx_mock.add_callback(auth_callback, url=auth_url)
91+
httpx_mock.add_callback(provider_callback, url=provider_url)
92+
httpx_mock.add_callback(account_id_callback, url=account_id_url)
93+
httpx_mock.add_callback(region_callback, url=region_url)
94+
filters = "?page.first=5000&filter.name_contains=test&filter.compute_region_id_region_id_eq=mock_region_id_1"
95+
httpx_mock.add_callback(many_engines_callback, url=engine_url + filters)
96+
97+
manager = ResourceManager(settings=settings)
98+
engines = manager.engines.get_many(name_contains="test", region_eq="mock_region_1")
99+
assert len(engines) == 1
100+
assert engines[0].name == mock_engine.name

0 commit comments

Comments
 (0)