99import asyncio
1010import logging
1111import os
12+ import signal
1213import sys
1314import time
1415from typing import (
@@ -147,7 +148,7 @@ def __init__(
147148 self ._timeout = 0.0 if timeout < 0.0 else timeout
148149 self ._max_workers = 1 if max_workers < 1 else max_workers
149150 self ._results = []
150- self ._stop = False
151+ self ._stop_cnt = 0
151152 self ._stopped = False
152153 self ._running_tests_sem = asyncio .Semaphore (1 )
153154 self ._schedule_lock = asyncio .Lock ()
@@ -203,7 +204,12 @@ def stopped(self) -> bool:
203204
204205 async def stop (self ) -> None :
205206 self ._logger .info ("Stopping tests execution" )
206- self ._stop = True
207+ self ._stop_cnt += 1
208+
209+ if self ._stop_cnt > 1 :
210+ # by stopping SUT first, we cause scheduler to complete
211+ # current test immediatelly without waiting
212+ await self ._sut .stop ()
207213
208214 try :
209215 # we enter in the semaphore queue in order to get highest
@@ -217,7 +223,7 @@ async def stop(self) -> None:
217223 async with self ._schedule_lock :
218224 pass
219225 finally :
220- self ._stop = False
226+ self ._stop_cnt = 0
221227 self ._stopped = True
222228
223229 self ._logger .info ("All tests have been completed" )
@@ -227,7 +233,7 @@ async def _run_test(self, test: Test) -> None:
227233 Run a single test and populate the results array.
228234 """
229235 async with self ._running_tests_sem :
230- if self ._stop :
236+ if self ._stop_cnt > 0 :
231237 self ._logger .info ("Test '%s' has been stopped" , test .name )
232238 return None
233239
@@ -294,6 +300,12 @@ async def _run_test(self, test: Test) -> None:
294300 "exec_time" : exec_time ,
295301 }
296302
303+ # we won't consider killed tests, unless they have been
304+ # killed by kirk by forcibly stop
305+ if test_data ["returncode" ] == - signal .SIGKILL :
306+ self ._logger .info ("Test killed: %s" , test .name )
307+ return
308+
297309 results = await self ._framework .read_result (
298310 test ,
299311 test_data ["stdout" ],
@@ -304,6 +316,12 @@ async def _run_test(self, test: Test) -> None:
304316 self ._logger .debug ("results=%s" , results )
305317 self ._results .append (results )
306318
319+ await libkirk .events .fire ("test_completed" , results )
320+ await self ._write_kmsg (test , results )
321+
322+ self ._logger .info ("Test completed: %s" , test .name )
323+ self ._logger .debug (results )
324+
307325 # raise kernel errors at the end so we can collect test results
308326 if status == self .KERNEL_TAINTED :
309327 await libkirk .events .fire ("kernel_tainted" , tainted_msg )
@@ -317,12 +335,6 @@ async def _run_test(self, test: Test) -> None:
317335 await libkirk .events .fire ("sut_not_responding" )
318336 raise KernelTimeoutError ()
319337
320- await libkirk .events .fire ("test_completed" , results )
321- await self ._write_kmsg (test , results )
322-
323- self ._logger .info ("Test completed: %s" , test .name )
324- self ._logger .debug (results )
325-
326338 async def _run_and_wait (self , tests : List [Test ]) -> None :
327339 """
328340 Run tests one after another.
@@ -380,11 +392,10 @@ async def schedule(self, jobs: List[Any]) -> None:
380392 exc_name = err .__class__ .__name__
381393 self ._logger .info ("%s caught during tests execution" , exc_name )
382394
383- raise_exc = not self ._stop
384395 async with self ._running_tests_sem :
385396 pass
386397
387- if raise_exc :
398+ if self . _stop_cnt == 0 :
388399 self ._logger .info ("Propagating %s exception" , exc_name )
389400 raise err
390401
0 commit comments