@@ -594,4 +594,69 @@ def read_with_interrupt(key):
594594 self .obj , 4 )
595595
596596 self .assertEqual (result , ['10.137.0.1' , '10.137.0.2' ])
597- self .assertEqual (call_count [0 ], 2 )
597+ self .assertEqual (call_count [0 ], 2 )
598+
599+ def test_read_rules_retries_on_interrupted_error (self ):
600+ """read_rules() must retry qdb.multiread() on InterruptedError."""
601+ self .obj .qdb .entries ['/qubes-firewall/10.137.0.2/policy' ] = b'drop'
602+ self .obj .qdb .entries ['/qubes-firewall/10.137.0.2/0000' ] = b'action=accept'
603+
604+ original_multiread = self .obj .qdb .multiread
605+ call_count = [0 ]
606+
607+ def multiread_with_interrupt (path ):
608+ call_count [0 ] += 1
609+ if call_count [0 ] == 1 :
610+ raise InterruptedError
611+ return original_multiread (path )
612+
613+ self .obj .qdb .multiread = multiread_with_interrupt
614+
615+ result = qubesagent .firewall .FirewallWorker .read_rules (
616+ self .obj , '10.137.0.2' )
617+
618+ self .assertEqual (call_count [0 ], 2 )
619+ self .assertIsNotNone (result )
620+
621+ def test_update_handled_retries_on_interrupted_error (self ):
622+ """update_handled() must retry qdb.read() on InterruptedError."""
623+ self .obj .qdb .entries ['/qubes-firewall-handled/10.137.0.2' ] = b'5'
624+
625+ original_read = self .obj .qdb .read
626+ call_count = [0 ]
627+
628+ def read_with_interrupt (key ):
629+ call_count [0 ] += 1
630+ if call_count [0 ] == 1 :
631+ raise InterruptedError
632+ return original_read (key )
633+
634+ self .obj .qdb .read = read_with_interrupt
635+
636+ qubesagent .firewall .FirewallWorker .update_handled (
637+ self .obj , '10.137.0.2' )
638+
639+ self .assertEqual (call_count [0 ], 2 )
640+ self .assertEqual (
641+ self .obj .qdb .entries ['/qubes-firewall-handled/10.137.0.2' ], '6' )
642+
643+ def test_log_error_retries_on_interrupted_error (self ):
644+ """log_error() must retry qdb.read('/default-user') on InterruptedError."""
645+ self .obj .qdb .entries ['/default-user' ] = b'user'
646+
647+ original_read = self .obj .qdb .read
648+ call_count = [0 ]
649+
650+ def read_with_interrupt (key ):
651+ call_count [0 ] += 1
652+ if key == '/default-user' and call_count [0 ] == 1 :
653+ raise InterruptedError
654+ return original_read (key )
655+
656+ self .obj .qdb .read = read_with_interrupt
657+
658+ with patch ('subprocess.check_output' ):
659+ qubesagent .firewall .FirewallWorker .log_error (
660+ self .obj , 'test error' )
661+
662+ self .assertGreaterEqual (call_count [0 ], 2 )
0 commit comments