33
44
55import asyncio
6+ from collections .abc import AsyncIterable , Awaitable , Callable
7+ from contextlib import AsyncExitStack
68from copy import deepcopy
9+ from secrets import choice
710from typing import Final
811
912import pytest
13+ from asgi_lifespan import LifespanManager
1014from fastapi import FastAPI
15+ from pydantic import NonNegativeInt
1116from pytest_mock import MockerFixture
1217from pytest_simcore .helpers .typing_env import EnvVarsDict
18+ from servicelib .utils import limited_gather
1319from settings_library .rabbit import RabbitSettings
1420from settings_library .redis import RedisSettings
21+ from simcore_service_dynamic_scheduler .core .application import create_app
1522from simcore_service_dynamic_scheduler .services .generic_scheduler ._core import (
16- Core ,
1723 Operation ,
1824 get_core ,
1925)
4147 "redis-commander" ,
4248]
4349
50+ _PARALLEL_APP_CREATION : Final [NonNegativeInt ] = 5
51+
4452
4553@pytest .fixture
4654def disable_other_generic_scheduler_modules (mocker : MockerFixture ) -> None :
@@ -61,13 +69,41 @@ def app_environment(
6169 app_environment : EnvVarsDict ,
6270 rabbit_service : RabbitSettings ,
6371 redis_service : RedisSettings ,
72+ remove_redis_data : None ,
6473) -> EnvVarsDict :
6574 return app_environment
6675
6776
6877@pytest .fixture
69- def core (app : FastAPI ) -> Core :
70- return get_core (app )
78+ async def get_app (
79+ app_environment : EnvVarsDict ,
80+ ) -> AsyncIterable [Callable [[], Awaitable [FastAPI ]]]:
81+ exit_stack = AsyncExitStack ()
82+
83+ started_apps : list [FastAPI ] = []
84+
85+ async def _ () -> FastAPI :
86+ app = create_app ()
87+ started_apps .append (app )
88+
89+ await exit_stack .enter_async_context (LifespanManager (app ))
90+ return app
91+
92+ yield _
93+
94+ await exit_stack .aclose ()
95+
96+
97+ @pytest .fixture
98+ async def selected_app (
99+ get_app : Callable [[], Awaitable [FastAPI ]], app_count : NonNegativeInt
100+ ) -> FastAPI :
101+ # initialize a bunch of apps and randomly select one
102+ # this will make sure that there is competition events catching possible issues
103+ apps : list [FastAPI ] = await limited_gather (
104+ * [get_app () for _ in range (app_count )], limit = _PARALLEL_APP_CREATION
105+ )
106+ return choice (apps )
71107
72108
73109_STEPS_CALL_ORDER : list [tuple [str , str ]] = []
@@ -169,22 +205,42 @@ class _AddSalt(_BS): ...
169205class _AddPepper (_BS ): ...
170206
171207
208+ class _AddPaprika (_BS ): ...
209+
210+
211+ class _AddMint (_BS ): ...
212+
213+
214+ class _AddMilk (_BS ): ...
215+
216+
172217class _StirTillDone (_BS ): ...
173218
174219
175220_MASHED_POTATOES : Final [Operation ] = [
176221 SingleStepGroup (_PeelPotates ),
177222 SingleStepGroup (_BoilPotates ),
178223 SingleStepGroup (_MashPotates ),
179- ParallelStepGroup (_AddButter , _AddSalt , _AddPepper ),
224+ ParallelStepGroup (
225+ _AddButter , _AddSalt , _AddPepper , _AddPaprika , _AddMint , _AddMilk
226+ ),
180227 SingleStepGroup (_StirTillDone ),
181228]
182229
183230OperationRegistry .register ("mash_potatoes" , _MASHED_POTATOES ) # type: ignore[call-arg
184231
185232
186- async def test_core_workflow (core : Core ):
187- schedule_id : ScheduleId = await core .create ("mash_potatoes" , {})
233+ @pytest .mark .parametrize (
234+ "app_count" ,
235+ [
236+ 1 ,
237+ # 10, # TODO: figure out why it's not working with more than one app in parall
238+ ],
239+ )
240+ async def test_core_workflow (
241+ preserve_caplog_for_async_logging : None , selected_app : FastAPI
242+ ):
243+ schedule_id : ScheduleId = await get_core (selected_app ).create ("mash_potatoes" , {})
188244 print (f"started { schedule_id = } " )
189245
190246 async for attempt in AsyncRetrying (
@@ -194,14 +250,18 @@ async def test_core_workflow(core: Core):
194250 ):
195251 with attempt :
196252 await asyncio .sleep (0 ) # wait for envet to trigger
197- assert len (_STEPS_CALL_ORDER ) == 8
253+ assert len (_STEPS_CALL_ORDER ) == 10
198254 _asseert_order (
199255 _CreateSequence (
200256 _PeelPotates ,
201257 _BoilPotates ,
202258 _MashPotates ,
203259 ),
204- _CreateRandom (_AddButter , _AddSalt , _AddPepper ),
260+ _CreateRandom (
261+ _AddButter , _AddSalt , _AddPepper , _AddPaprika , _AddMint , _AddMilk
262+ ),
205263 _CreateSequence (_StirTillDone ),
206- _CreateSequence (_StirTillDone ), # TODO: this is wrong fix
207264 )
265+
266+
267+ # TODO: also add a test with 2 of the cores in parallel to see it still works as expected
0 commit comments