20
20
import asyncio
21
21
import unittest
22
22
from unittest import mock
23
- from unittest .mock import Mock
23
+ from unittest .mock import Mock , AsyncMock
24
24
25
25
import jinja2
26
26
@@ -675,11 +675,12 @@ def test_061_on_qdb_change_required(self):
675
675
back .devices ['block' ]._exposed .append (
676
676
qubes .ext .block .BlockDevice (back , 'sda' ))
677
677
678
- self .ext .attach_and_notify = Mock ()
679
- with mock .patch ('asyncio.ensure_future' ):
680
- self .ext .on_qdb_change (back , None , None )
681
- self .ext .attach_and_notify .assert_called_once_with (
682
- front , assignment )
678
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
679
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
680
+ with mock .patch ('asyncio.ensure_future' ):
681
+ self .ext .on_qdb_change (back , None , None )
682
+ resolver .assert_called_once_with (
683
+ self .ext , {'sda' : {front : assignment }})
683
684
684
685
def test_062_on_qdb_change_auto_attached (self ):
685
686
back , front = self .added_assign_setup ()
@@ -690,11 +691,12 @@ def test_062_on_qdb_change_auto_attached(self):
690
691
back .devices ['block' ]._exposed .append (
691
692
qubes .ext .block .BlockDevice (back , 'sda' ))
692
693
693
- self .ext .attach_and_notify = Mock ()
694
- with mock .patch ('asyncio.ensure_future' ):
695
- self .ext .on_qdb_change (back , None , None )
696
- self .ext .attach_and_notify .assert_called_once_with (
697
- front , assignment )
694
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
695
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
696
+ with mock .patch ('asyncio.ensure_future' ):
697
+ self .ext .on_qdb_change (back , None , None )
698
+ resolver .assert_called_once_with (
699
+ self .ext , {'sda' : {front : assignment }})
698
700
699
701
def test_063_on_qdb_change_ask_to_attached (self ):
700
702
back , front = self .added_assign_setup ()
@@ -705,11 +707,12 @@ def test_063_on_qdb_change_ask_to_attached(self):
705
707
back .devices ['block' ]._exposed .append (
706
708
qubes .ext .block .BlockDevice (back , 'sda' ))
707
709
708
- self .ext .attach_and_notify = Mock ()
709
- with mock .patch ('asyncio.ensure_future' ):
710
- self .ext .on_qdb_change (back , None , None )
711
- self .ext .attach_and_notify .assert_called_once_with (
712
- front , assignment )
710
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
711
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
712
+ with mock .patch ('asyncio.ensure_future' ):
713
+ self .ext .on_qdb_change (back , None , None )
714
+ resolver .assert_called_once_with (
715
+ self .ext , {'sda' : {front : assignment }})
713
716
714
717
def test_064_on_qdb_change_multiple_assignments_including_full (self ):
715
718
back , front = self .added_assign_setup ()
@@ -732,11 +735,12 @@ def test_064_on_qdb_change_multiple_assignments_including_full(self):
732
735
back .devices ['block' ]._exposed .append (
733
736
qubes .ext .block .BlockDevice (back , 'sda' ))
734
737
735
- self .ext .attach_and_notify = Mock ()
736
- with mock .patch ('asyncio.ensure_future' ):
737
- self .ext .on_qdb_change (back , None , None )
738
- self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
739
- {'pid' : 'did' })
738
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
739
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
740
+ with mock .patch ('asyncio.ensure_future' ):
741
+ self .ext .on_qdb_change (back , None , None )
742
+ self .assertEqual (
743
+ resolver .call_args [0 ][1 ]['sda' ][front ].options ,{'pid' : 'did' })
740
744
741
745
def test_065_on_qdb_change_multiple_assignments_port_vs_dev (self ):
742
746
back , front = self .added_assign_setup ()
@@ -755,11 +759,12 @@ def test_065_on_qdb_change_multiple_assignments_port_vs_dev(self):
755
759
back .devices ['block' ]._exposed .append (
756
760
qubes .ext .block .BlockDevice (back , 'sda' ))
757
761
758
- self .ext .attach_and_notify = Mock ()
759
- with mock .patch ('asyncio.ensure_future' ):
760
- self .ext .on_qdb_change (back , None , None )
761
- self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
762
- {'pid' : 'any' })
762
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
763
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
764
+ with mock .patch ('asyncio.ensure_future' ):
765
+ self .ext .on_qdb_change (back , None , None )
766
+ self .assertEqual (
767
+ resolver .call_args [0 ][1 ]['sda' ][front ].options , {'pid' : 'any' })
763
768
764
769
def test_066_on_qdb_change_multiple_assignments_dev (self ):
765
770
back , front = self .added_assign_setup ()
@@ -780,13 +785,16 @@ def test_066_on_qdb_change_multiple_assignments_dev(self):
780
785
back .devices ['block' ]._exposed .append (
781
786
qubes .ext .block .BlockDevice (back , 'other' ))
782
787
783
- self .ext .attach_and_notify = Mock ()
784
- with mock .patch ('asyncio.ensure_future' ):
785
- self .ext .on_qdb_change (back , None , None )
786
- self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
787
- {'any' : 'did' })
788
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
789
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
790
+ with mock .patch ('asyncio.ensure_future' ):
791
+ self .ext .on_qdb_change (back , None , None )
792
+ self .assertEqual (
793
+ resolver .call_args [0 ][1 ]['sda' ][front ].options , {'any' : 'did' })
788
794
789
- def test_067_on_qdb_change_attached (self ):
795
+ @unittest .mock .patch (
796
+ 'qubes.ext.utils.resolve_conflicts_and_attach' , new_callable = Mock )
797
+ def test_067_on_qdb_change_attached (self , _confirm ):
790
798
# added
791
799
back_vm = TestVM (name = 'sys-usb' , qdb = get_qdb (mode = 'r' ), domain_xml = domain_xml_template .format ("" ))
792
800
exp_dev = qubes .ext .block .BlockDevice (back_vm , 'sda' )
@@ -830,7 +838,9 @@ def test_067_on_qdb_change_attached(self):
830
838
fire_event_async .assert_called_once_with (
831
839
'device-attach:block' , device = exp_dev , options = {})
832
840
833
- def test_068_on_qdb_change_changed (self ):
841
+ @unittest .mock .patch (
842
+ 'qubes.ext.utils.resolve_conflicts_and_attach' , new_callable = Mock )
843
+ def test_068_on_qdb_change_changed (self , _confirm ):
834
844
# attached to front-vm
835
845
back_vm = TestVM (name = 'sys-usb' , qdb = get_qdb (mode = 'r' ), domain_xml = domain_xml_template .format ("" ))
836
846
exp_dev = qubes .ext .block .BlockDevice (back_vm , 'sda' )
@@ -890,7 +900,9 @@ def test_068_on_qdb_change_changed(self):
890
900
fire_event_async_2 .assert_called_once_with (
891
901
'device-attach:block' , device = exp_dev , options = {})
892
902
893
- def test_069_on_qdb_change_removed_attached (self ):
903
+ @unittest .mock .patch (
904
+ 'qubes.ext.utils.resolve_conflicts_and_attach' , new_callable = Mock )
905
+ def test_069_on_qdb_change_removed_attached (self , _confirm ):
894
906
# attached to front-vm
895
907
back_vm = TestVM (name = 'sys-usb' , qdb = get_qdb (mode = 'r' ), domain_xml = domain_xml_template .format ("" ))
896
908
dom0 = TestVM ({}, name = 'dom0' ,
@@ -943,10 +955,7 @@ def test_069_on_qdb_change_removed_attached(self):
943
955
('device-removed:block' , frozenset ({('port' , exp_dev .port )}))],
944
956
1 )
945
957
946
- # with `new_callable=Mock` we override async function with synchronous Mock
947
- @unittest .mock .patch (
948
- 'qubes.ext.utils.confirm_device_attachment' , new_callable = Mock )
949
- def test_070_on_qdb_change_two_fronts_failed (self , _mock_confirm ):
958
+ def test_070_on_qdb_change_two_fronts (self ):
950
959
back , front = self .added_assign_setup ()
951
960
952
961
exp_dev = qubes .ext .block .BlockDevice (back , 'sda' )
@@ -956,43 +965,58 @@ def test_070_on_qdb_change_two_fronts_failed(self, _mock_confirm):
956
965
back .devices ['block' ]._assigned .append (assign )
957
966
back .devices ['block' ]._exposed .append (exp_dev )
958
967
959
- self .ext .attach_and_notify = Mock ()
968
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
969
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
970
+ with mock .patch ('asyncio.ensure_future' ):
971
+ self .ext .on_qdb_change (back , None , None )
972
+ resolver .assert_called_once_with (
973
+ self .ext , {'sda' : {front : assign , back : assign }})
960
974
961
- with mock .patch ('qubes.ext.utils.asyncio.ensure_future' ) as future :
962
- future .return_value = Mock ()
963
- future .return_value .result = Mock ()
964
- future .return_value .result .return_value = "nonsense"
965
- self .ext .on_qdb_change (back , None , None )
975
+ @unittest .mock .patch ('asyncio.create_subprocess_shell' )
976
+ def test_071_failed_confirmation (self , shell ):
977
+ back , front = self .added_assign_setup ()
966
978
979
+ exp_dev = qubes .ext .block .BlockDevice (back , 'sda' )
980
+ assign = DeviceAssignment (exp_dev , mode = 'auto-attach' )
981
+
982
+ front .devices ['block' ]._assigned .append (assign )
983
+ back .devices ['block' ]._assigned .append (assign )
984
+ back .devices ['block' ]._exposed .append (exp_dev )
985
+
986
+ proc = AsyncMock ()
987
+ shell .return_value = proc
988
+ proc .communicate = AsyncMock ()
989
+ proc .communicate .return_value = (b'nonsense' , b'' )
990
+
991
+ loop = asyncio .get_event_loop ()
992
+ self .ext .attach_and_notify = AsyncMock ()
993
+ loop .run_until_complete (qubes .ext .utils .resolve_conflicts_and_attach (
994
+ self .ext , {'sda' : {front : assign , back : assign }}))
967
995
self .ext .attach_and_notify .assert_not_called ()
968
996
969
- # with `new_callable=Mock` we override async function with synchronous Mock
970
- @unittest .mock .patch (
971
- 'qubes.ext.utils.confirm_device_attachment' , new_callable = Mock )
972
- def test_071_on_qdb_change_two_fronts (self , _mock_confirm ):
997
+ @unittest .mock .patch ('asyncio.create_subprocess_shell' )
998
+ def test_072_successful_confirmation (self , shell ):
973
999
back , front = self .added_assign_setup ()
974
1000
975
1001
exp_dev = qubes .ext .block .BlockDevice (back , 'sda' )
976
- assign = DeviceAssignment (exp_dev , mode = 'ask-to -attach' )
1002
+ assign = DeviceAssignment (exp_dev , mode = 'auto -attach' )
977
1003
978
1004
front .devices ['block' ]._assigned .append (assign )
979
1005
back .devices ['block' ]._assigned .append (assign )
980
1006
back .devices ['block' ]._exposed .append (exp_dev )
981
1007
982
- self .ext .attach_and_notify = Mock ()
983
-
984
- with mock .patch ('asyncio.ensure_future' ) as future :
985
- future .return_value = Mock ()
986
- future .return_value .result = Mock ()
987
- future .return_value .result .return_value = "front-vm"
988
- self .ext .on_qdb_change (back , None , None )
1008
+ proc = AsyncMock ()
1009
+ shell .return_value = proc
1010
+ proc .communicate = AsyncMock ()
1011
+ proc .communicate .return_value = (b'front-vm' , b'' )
989
1012
1013
+ loop = asyncio .get_event_loop ()
1014
+ self .ext .attach_and_notify = AsyncMock ()
1015
+ loop .run_until_complete (qubes .ext .utils .resolve_conflicts_and_attach (
1016
+ self .ext , {'sda' : {front : assign , back : assign }}))
990
1017
self .ext .attach_and_notify .assert_called_once_with (front , assign )
991
- # don't ask again
992
- self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].mode .value ,
993
- 'auto-attach' )
994
1018
995
- def test_072_on_qdb_change_ask (self ):
1019
+ def test_073_on_qdb_change_ask (self ):
996
1020
back , front = self .added_assign_setup ()
997
1021
998
1022
exp_dev = qubes .ext .block .BlockDevice (back , 'sda' )
@@ -1001,11 +1025,12 @@ def test_072_on_qdb_change_ask(self):
1001
1025
front .devices ['block' ]._assigned .append (assign )
1002
1026
back .devices ['block' ]._exposed .append (exp_dev )
1003
1027
1004
- self .ext .attach_and_notify = Mock ()
1005
- with mock .patch ('asyncio.ensure_future' ):
1006
- self .ext .on_qdb_change (back , None , None )
1007
- self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].mode .value ,
1008
- 'ask-to-attach' )
1028
+ resolver_path = 'qubes.ext.utils.resolve_conflicts_and_attach'
1029
+ with mock .patch (resolver_path , new_callable = Mock ) as resolver :
1030
+ with mock .patch ('asyncio.ensure_future' ):
1031
+ self .ext .on_qdb_change (back , None , None )
1032
+ resolver .assert_called_once_with (
1033
+ self .ext , {'sda' : {front : assign }})
1009
1034
1010
1035
def test_080_on_startup_multiple_assignments_including_full (self ):
1011
1036
back , front = self .added_assign_setup ()
@@ -1030,8 +1055,9 @@ def test_080_on_startup_multiple_assignments_including_full(self):
1030
1055
1031
1056
self .ext .attach_and_notify = Mock ()
1032
1057
loop = asyncio .get_event_loop ()
1033
- with mock .patch ('asyncio.ensure_future' ):
1034
- loop .run_until_complete (self .ext .on_domain_start (front , None ))
1058
+ with mock .patch ('asyncio.wait' ):
1059
+ with mock .patch ('asyncio.ensure_future' ):
1060
+ loop .run_until_complete (self .ext .on_domain_start (front , None ))
1035
1061
self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
1036
1062
{'pid' : 'did' })
1037
1063
@@ -1054,8 +1080,9 @@ def test_081_on_startup_multiple_assignments_port_vs_dev(self):
1054
1080
1055
1081
self .ext .attach_and_notify = Mock ()
1056
1082
loop = asyncio .get_event_loop ()
1057
- with mock .patch ('asyncio.ensure_future' ):
1058
- loop .run_until_complete (self .ext .on_domain_start (front , None ))
1083
+ with mock .patch ('asyncio.wait' ):
1084
+ with mock .patch ('asyncio.ensure_future' ):
1085
+ loop .run_until_complete (self .ext .on_domain_start (front , None ))
1059
1086
self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
1060
1087
{'pid' : 'any' })
1061
1088
@@ -1080,8 +1107,9 @@ def test_082_on_startup_multiple_assignments_dev(self):
1080
1107
1081
1108
self .ext .attach_and_notify = Mock ()
1082
1109
loop = asyncio .get_event_loop ()
1083
- with mock .patch ('asyncio.ensure_future' ):
1084
- loop .run_until_complete (self .ext .on_domain_start (front , None ))
1110
+ with mock .patch ('asyncio.wait' ):
1111
+ with mock .patch ('asyncio.ensure_future' ):
1112
+ loop .run_until_complete (self .ext .on_domain_start (front , None ))
1085
1113
self .assertEqual (self .ext .attach_and_notify .call_args [0 ][1 ].options ,
1086
1114
{'any' : 'did' })
1087
1115
0 commit comments