11import asyncio
22import logging
3- from datetime import date , datetime , time
4- from functools import partial
5- from signal import Signals , raise_signal
6- from typing import Callable
3+ from datetime import datetime
74
85import pytest
96import pytest_asyncio
107from astral import LocationInfo
118from astral .location import Location
12- from pytz import BaseTzInfo , timezone
139
14- from appdaemon import AppDaemon , utils
10+ from appdaemon import AppDaemon
1511from appdaemon .logging import Logging
1612from appdaemon .models .config .appdaemon import AppDaemonConfig
1713
@@ -62,7 +58,7 @@ def ad_cfg() -> AppDaemonConfig:
6258 module_debug = {
6359 "_app_management" : "DEBUG" ,
6460 # "_events": "DEBUG",
65- # "_utility": "DEBUG",
61+ "_utility" : "DEBUG" ,
6662 },
6763 )
6864 )
@@ -88,18 +84,20 @@ async def ad_obj(logging_obj: Logging, running_loop, ad_cfg: AppDaemonConfig):
8884 # This can't be done here because the test might set the app directory to a different location
8985 # await ad.app_management.check_app_updates(mode=UpdateMode.TESTING)
9086
91- # ad.start()
87+ ad .start ()
9288 yield ad
9389 logger .info ('Back to fixture scope, stopping AppDaemon' )
94- pass
90+ if stopping_tasks := ad .stop ():
91+ logger .debug ("Waiting for stopping tasks to complete" )
92+ await stopping_tasks
9593
9694
97- @pytest .fixture (scope = "module" )
98- def ad_obj_fast (logging_obj : Logging , running_loop , ad_cfg : AppDaemonConfig ):
95+ @pytest_asyncio .fixture (scope = "module" )
96+ async def ad_obj_fast (logging_obj : Logging , running_loop , ad_cfg : AppDaemonConfig ):
9997 logger = logging .getLogger ("AppDaemon._test" )
10098 logger .info (f"Passed loop: { hex (id (running_loop ))} " )
10199
102- ad_cfg .timewarp = 5000
100+ ad_cfg .timewarp = 2000
103101 ad_cfg .starttime = ad_cfg .time_zone .localize (datetime (2025 , 6 , 25 , 0 , 0 , 0 ))
104102
105103 ad = AppDaemon (
@@ -113,10 +111,11 @@ def ad_obj_fast(logging_obj: Logging, running_loop, ad_cfg: AppDaemonConfig):
113111 logger .propagate = True
114112 logger .setLevel ("DEBUG" )
115113
116- ad .start ()
114+ # ad.start()
117115 yield ad
118- raise_signal (Signals .SIGTERM )
116+ # raise_signal(Signals.SIGTERM)
119117 # ad.stop()
118+ pass
120119
121120
122121@pytest .fixture
@@ -130,63 +129,3 @@ def location() -> Location:
130129 longitude = - 74.0060 ,
131130 )
132131 )
133-
134-
135- @pytest .fixture
136- def tz (location : Location ) -> BaseTzInfo :
137- return timezone (location .timezone )
138-
139-
140- @pytest .fixture
141- def default_date () -> date :
142- return date (2025 , 6 , 20 )
143-
144-
145- @pytest .fixture
146- def tomorrow_date (default_date : date ) -> date :
147- return default_date .replace (day = default_date .day + 1 )
148-
149-
150- @pytest .fixture
151- def now_creator (default_date : date , tz : BaseTzInfo ):
152- def create_time (hour : int ):
153- naive = datetime .combine (default_date , time (hour , 0 , 0 ))
154- return tz .localize (naive )
155-
156- return create_time
157-
158-
159- @pytest .fixture
160- def early_now (now_creator : Callable [..., datetime ]) -> datetime :
161- now = now_creator (4 )
162- assert now .isoformat () == "2025-06-20T04:00:00-04:00"
163- return now
164-
165-
166- @pytest .fixture
167- def default_now (now_creator : Callable [..., datetime ]) -> datetime :
168- now = now_creator (12 )
169- assert now .isoformat () == "2025-06-20T12:00:00-04:00"
170- return now
171-
172-
173- @pytest .fixture
174- def late_now (now_creator : Callable [..., datetime ]) -> datetime :
175- now = now_creator (23 )
176- assert now .isoformat () == "2025-06-20T23:00:00-04:00"
177- return now
178-
179-
180- @pytest .fixture
181- def parser (tz : BaseTzInfo , default_now : datetime ) -> partial [datetime ]:
182- return partial (utils .parse_datetime , now = default_now , timezone = tz )
183-
184-
185- @pytest .fixture
186- def parser_location (tz : BaseTzInfo , location : Location ) -> partial [datetime ]:
187- return partial (utils .parse_datetime , location = location , timezone = tz )
188-
189-
190- @pytest .fixture
191- def time_at_elevation (location : Location , default_now : datetime ) -> Callable [..., datetime ]:
192- return partial (location .time_at_elevation , date = default_now .date (), local = True )
0 commit comments