@@ -262,6 +262,20 @@ def tearDown(self): # pylint: disable=invalid-name
262262 super (TC_20_DispVMMixin , self ).tearDown ()
263263 logger .info ("end" )
264264
265+ def _run_cmd_and_log_output (self , qube , cmd , user = "root" , timeout = 30 ):
266+ try :
267+ stdout , _ = self .loop .run_until_complete (
268+ asyncio .wait_for (
269+ qube .run_for_stdio (
270+ cmd , user = user , stderr = subprocess .STDOUT
271+ ),
272+ timeout = timeout ,
273+ )
274+ )
275+ except subprocess .CalledProcessError as e :
276+ stdout = getattr (e , "stdout" , str (e ))
277+ logger .critical ("{}: {}: {}" .format (qube .name , cmd , stdout ))
278+
265279 def _test_event_handler (
266280 self , vm , event , * args , ** kwargs
267281 ): # pylint: disable=unused-argument
@@ -285,7 +299,6 @@ def _test_event_was_handled(self, vm, event):
285299 def _register_handlers (self , vm ): # pylint: disable=unused-argument
286300 events = [
287301 # appvm
288- "domain-preload-dispvm-autostart" ,
289302 "domain-preload-dispvm-start" ,
290303 "domain-preload-dispvm-used" ,
291304 # dispvm
@@ -304,11 +317,12 @@ def _register_handlers(self, vm): # pylint: disable=unused-argument
304317 def _on_domain_add (self , app , event , vm ): # pylint: disable=unused-argument
305318 self ._register_handlers (vm )
306319
307- async def cleanup_preload_run (self , qube ):
320+ async def cleanup_preload_run (self , qube , down_to = 0 ):
308321 old_preload = qube .features .get ("preload-dispvm" , "" )
309322 old_preload = old_preload .split (" " ) if old_preload else []
310323 if not old_preload :
311324 return
325+ old_preload = old_preload [:down_to ]
312326 logger .info (
313327 "cleaning up preloaded disposables: %s:%s" , qube .name , old_preload
314328 )
@@ -333,7 +347,9 @@ def cleanup_preload(self):
333347 self .disp_base_alt ,
334348 ]:
335349 continue
336- logger .info ("removing preloaded disposables: '%s'" , qube .name )
350+ logger .info (
351+ "removing preloaded disposables configured in: '%s'" , qube .name
352+ )
337353 target = qube
338354 if qube .klass == "AdminVM" and default_dispvm :
339355 target = default_dispvm
@@ -453,7 +469,6 @@ async def run_preload(self):
453469 stdout = await self .run_preload_proc ()
454470 self .assertEqual (stdout , dispvm_name )
455471 test_cases = [
456- (False , appvm .name , "domain-preload-dispvm-autostart" , True ),
457472 (False , appvm .name , "domain-preload-dispvm-start" , True ),
458473 (True , appvm .name , "domain-preload-dispvm-used" , True ),
459474 (
@@ -637,15 +652,12 @@ async def _test_016_preload_race_less(self):
637652 logger .info ("end" )
638653
639654 def test_017_preload_autostart (self ):
640- """The script triggers the API call
641- 'admin.vm.CreateDisposable+preload-autostart' which fires the event
642- 'domain-preload-dispvm-autostart', clearing the current preload list
643- and filling with new ones."""
655+ """The script triggers the API call 'admin.vm.CreateDisposable+preload'
656+ which is responsible for bootstrapping."""
644657 logger .info ("start" )
645658 self .app .default_dispvm = self .disp_base
646659
647- preload_max = 1
648- logger .info ("no refresh to be made" )
660+ logger .info ("must not change as max is 0" )
649661 proc = self .loop .run_until_complete (
650662 asyncio .create_subprocess_exec ("/usr/lib/qubes/preload-dispvm" )
651663 )
@@ -654,39 +666,70 @@ def test_017_preload_autostart(self):
654666 )
655667 self .assertEqual (self .disp_base .get_feat_preload (), [])
656668
657- logger .info ("refresh to be made" )
669+ preload_max = 1
670+ logger .info ("must not change existing preloaded disposables" )
658671 self .disp_base .features ["preload-dispvm-max" ] = str (preload_max )
659672 self .loop .run_until_complete (self .wait_preload (preload_max ))
660673 old_preload = self .disp_base .get_feat_preload ()
661674 proc = self .loop .run_until_complete (
662675 asyncio .create_subprocess_exec ("/usr/lib/qubes/preload-dispvm" )
663676 )
664- self .loop .run_until_complete (asyncio .wait_for (proc .wait (), timeout = 40 ))
677+ self .loop .run_until_complete (asyncio .wait_for (proc .wait (), timeout = 10 ))
665678 preload_dispvm = self .disp_base .get_feat_preload ()
666- self .assertEqual (len (old_preload ), preload_max )
667- self .assertEqual (len (preload_dispvm ), preload_max )
668- self .assertTrue (
669- set (old_preload ).isdisjoint (preload_dispvm ),
670- f"old_preload={ old_preload } preload_dispvm={ preload_dispvm } " ,
679+ self .assertEqual (
680+ old_preload ,
681+ preload_dispvm ,
682+ msg = f"old_preload={ old_preload } preload_dispvm={ preload_dispvm } " ,
671683 )
672684
673- logger .info ("global refresh to be made" )
674685 preload_max += 1
686+ logger .info ("global refill must work" )
675687 self .adminvm .features ["preload-dispvm-max" ] = str (preload_max )
676688 self .loop .run_until_complete (self .wait_preload (preload_max ))
677- del self .disp_base .features ["preload-dispvm-max" ]
689+ old_old_preload = self .disp_base .get_feat_preload ()
690+ self .loop .run_until_complete (
691+ self .cleanup_preload_run (self .disp_base , down_to = preload_max - 1 )
692+ )
678693 old_preload = self .disp_base .get_feat_preload ()
694+ self .assertEqual (len (old_preload ), preload_max - 1 )
695+ self .assertIn (old_preload [0 ], old_old_preload )
679696 proc = self .loop .run_until_complete (
680697 asyncio .create_subprocess_exec ("/usr/lib/qubes/preload-dispvm" )
681698 )
682- self .loop .run_until_complete (asyncio .wait_for (proc .wait (), timeout = 40 ))
699+ try :
700+ self .loop .run_until_complete (
701+ asyncio .wait_for (proc .wait (), timeout = 40 )
702+ )
703+ except asyncio .TimeoutError :
704+ debug_preload = self .disp_base .get_feat_preload ()
705+ for qube in debug_preload :
706+ qube = self .app .domains [qube ]
707+ if qube .is_paused ():
708+ self .loop .run_until_complete (
709+ asyncio .wait_for (qube .unpause (), timeout = 5 )
710+ )
711+ self ._run_cmd_and_log_output (
712+ qube , "systemtl --user is-system-running" , user = "user"
713+ )
714+ self ._run_cmd_and_log_output (
715+ qube , "systemtl is-system-running" , user = "root"
716+ )
717+ self ._run_cmd_and_log_output (
718+ qube , "systemd-analyze --no-pager --user blame" , user = "user"
719+ )
720+ self ._run_cmd_and_log_output (
721+ qube , "systemd-analyze --no-pager blame" , user = "root"
722+ )
723+ self ._run_cmd_and_log_output (
724+ qube , "journalctl --no-pager --user" , user = "user"
725+ )
726+ self ._run_cmd_and_log_output (
727+ qube , "journalctl --no-pager" , user = "root"
728+ )
729+ raise
683730 preload_dispvm = self .disp_base .get_feat_preload ()
684- self .assertEqual ( len ( old_preload ), preload_max )
731+ self .assertIn ( old_preload [ 0 ], preload_dispvm )
685732 self .assertEqual (len (preload_dispvm ), preload_max )
686- self .assertTrue (
687- set (old_preload ).isdisjoint (preload_dispvm ),
688- f"old_preload={ old_preload } preload_dispvm={ preload_dispvm } " ,
689- )
690733
691734 self .app .default_dispvm = None
692735 logger .info ("end" )
0 commit comments