17
17
import datetime
18
18
import os
19
19
import re
20
- import time
21
20
22
21
import mock
23
22
import netifaces
@@ -793,7 +792,8 @@ def test_dnsmasq_execute_use_network_dns_servers(self):
793
792
]
794
793
self ._test_dnsmasq_execute (extra_expected = expected )
795
794
796
- def test_isolated_host (self ):
795
+ @mock .patch ('nova.privsep.linux_net.modify_ebtables' )
796
+ def test_isolated_host (self , mock_modify_ebtables ):
797
797
self .flags (fake_network = False ,
798
798
share_dhcp_address = True )
799
799
executes = []
@@ -824,34 +824,47 @@ def fake_ensure(bridge, interface, network, gateway):
824
824
driver .plug (network , 'fakemac' )
825
825
826
826
expected = [
827
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'INPUT' , '-p' ,
828
- 'ARP' , '-i' , iface , '--arp-ip-dst' , dhcp , '-j' , 'DROP' ),
829
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-I' , 'INPUT' , '-p' ,
830
- 'ARP' , '-i' , iface , '--arp-ip-dst' , dhcp , '-j' , 'DROP' ),
831
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'OUTPUT' , '-p' ,
832
- 'ARP' , '-o' , iface , '--arp-ip-src' , dhcp , '-j' , 'DROP' ),
833
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-I' , 'OUTPUT' , '-p' ,
834
- 'ARP' , '-o' , iface , '--arp-ip-src' , dhcp , '-j' , 'DROP' ),
835
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'FORWARD' ,
836
- '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' , 'udp' ,
837
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
838
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-I' , 'FORWARD' ,
839
- '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' , 'udp' ,
840
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
841
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'FORWARD' ,
842
- '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' , 'udp' ,
843
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
844
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-I' , 'FORWARD' ,
845
- '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' , 'udp' ,
846
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
847
827
('iptables-save' , '-c' ),
848
828
('iptables-restore' , '-c' ),
849
829
('ip6tables-save' , '-c' ),
850
830
('ip6tables-restore' , '-c' ),
851
831
]
852
832
self .assertEqual (expected , executes )
853
-
854
- executes = []
833
+ mock_modify_ebtables .assert_has_calls ([
834
+ mock .call ('filter' ,
835
+ ['INPUT' , '-p' , 'ARP' , '-i' , iface , '--arp-ip-dst' ,
836
+ dhcp , '-j' , 'DROP' ],
837
+ insert_rule = False ),
838
+ mock .call ('filter' ,
839
+ ['INPUT' , '-p' , 'ARP' , '-i' , iface , '--arp-ip-dst' ,
840
+ dhcp , '-j' , 'DROP' ],
841
+ insert_rule = True ),
842
+ mock .call ('filter' ,
843
+ ['OUTPUT' , '-p' , 'ARP' , '-o' , iface , '--arp-ip-src' ,
844
+ dhcp , '-j' , 'DROP' ],
845
+ insert_rule = False ),
846
+ mock .call ('filter' ,
847
+ ['OUTPUT' , '-p' , 'ARP' , '-o' , iface , '--arp-ip-src' ,
848
+ dhcp , '-j' , 'DROP' ],
849
+ insert_rule = True ),
850
+ mock .call ('filter' ,
851
+ ['FORWARD' , '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' ,
852
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
853
+ insert_rule = False ),
854
+ mock .call ('filter' ,
855
+ ['FORWARD' , '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' ,
856
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
857
+ insert_rule = True ),
858
+ mock .call ('filter' ,
859
+ ['FORWARD' , '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' ,
860
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
861
+ insert_rule = False ),
862
+ mock .call ('filter' ,
863
+ ['FORWARD' , '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' ,
864
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
865
+ insert_rule = True )])
866
+
867
+ mock_modify_ebtables .reset_mock ()
855
868
856
869
def fake_remove (bridge , gateway ):
857
870
return
@@ -861,19 +874,23 @@ def fake_remove(bridge, gateway):
861
874
fake_remove )
862
875
863
876
driver .unplug (network )
864
- expected = [
865
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'INPUT' , '-p' ,
866
- 'ARP' , '-i' , iface , '--arp-ip-dst' , dhcp , '-j' , 'DROP' ),
867
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'OUTPUT' , '-p' ,
868
- 'ARP' , '-o' , iface , '--arp-ip-src' , dhcp , '-j' , 'DROP' ),
869
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'FORWARD' ,
870
- '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' , 'udp' ,
871
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
872
- ('ebtables' , '--concurrent' , '-t' , 'filter' , '-D' , 'FORWARD' ,
873
- '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' , 'udp' ,
874
- '--ip-destination-port' , '67:68' , '-j' , 'DROP' ),
875
- ]
876
- self .assertEqual (expected , executes )
877
+ mock_modify_ebtables .assert_has_calls ([
878
+ mock .call ('filter' ,
879
+ ['INPUT' , '-p' , 'ARP' , '-i' , iface , '--arp-ip-dst' ,
880
+ dhcp , '-j' , 'DROP' ],
881
+ insert_rule = False ),
882
+ mock .call ('filter' ,
883
+ ['OUTPUT' , '-p' , 'ARP' , '-o' , iface , '--arp-ip-src' ,
884
+ dhcp , '-j' , 'DROP' ],
885
+ insert_rule = False ),
886
+ mock .call ('filter' ,
887
+ ['FORWARD' , '-p' , 'IPv4' , '-i' , iface , '--ip-protocol' ,
888
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
889
+ insert_rule = False ),
890
+ mock .call ('filter' ,
891
+ ['FORWARD' , '-p' , 'IPv4' , '-o' , iface , '--ip-protocol' ,
892
+ 'udp' , '--ip-destination-port' , '67:68' , '-j' , 'DROP' ],
893
+ insert_rule = False )])
877
894
878
895
@mock .patch ('nova.privsep.linux_net.routes_show' )
879
896
@mock .patch ('nova.privsep.linux_net.route_delete' )
@@ -1211,85 +1228,66 @@ def fake_execute(*cmd, **kwargs):
1211
1228
driver .ensure_bridge ('brq1234567-89' , '' )
1212
1229
device_exists .assert_called_once_with ('brq1234567-89' )
1213
1230
1214
- def test_exec_ebtables_success (self ):
1215
- executes = []
1216
-
1217
- def fake_execute (* args , ** kwargs ):
1218
- executes .append (args )
1219
- return "" , ""
1220
-
1221
- with mock .patch .object (self .driver , '_execute' ,
1222
- side_effect = fake_execute ):
1223
- self .driver ._exec_ebtables ('fake' , ['fake' ])
1224
- self .assertEqual (1 , len (executes ))
1225
-
1226
- def _ebtables_race_stderr (self ):
1227
- return (u"Unable to update the kernel. Two possible causes:\n "
1228
- "1. Multiple ebtables programs were executing simultaneously."
1229
- " The ebtables\n userspace tool doesn't by default support "
1230
- "multiple ebtables programs running\n concurrently. The "
1231
- "ebtables option --concurrent or a tool like flock can be\n "
1232
- "used to support concurrent scripts that update the ebtables "
1233
- "kernel tables.\n 2. The kernel doesn't support a certain "
1234
- "ebtables extension, consider\n recompiling your kernel or "
1235
- "insmod the extension.\n .\n " )
1236
-
1237
- def test_exec_ebtables_fail_all (self ):
1238
- executes = []
1239
-
1240
- def fake_sleep (interval ):
1241
- pass
1242
-
1243
- def fake_execute (* args , ** kwargs ):
1244
- executes .append (args )
1245
- raise processutils .ProcessExecutionError ('error' ,
1246
- stderr = self ._ebtables_race_stderr ())
1247
-
1248
- with mock .patch .object (time , 'sleep' , side_effect = fake_sleep ), \
1249
- mock .patch .object (self .driver , '_execute' ,
1250
- side_effect = fake_execute ):
1251
- self .assertRaises (processutils .ProcessExecutionError ,
1252
- self .driver ._exec_ebtables , 'fake' , ['fake' ])
1253
- max_calls = CONF .ebtables_exec_attempts
1254
- self .assertEqual (max_calls , len (executes ))
1255
-
1256
- def test_exec_ebtables_fail_no_retry (self ):
1257
- executes = []
1258
-
1259
- def fake_sleep (interval ):
1260
- pass
1261
-
1262
- def fake_execute (* args , ** kwargs ):
1263
- executes .append (args )
1264
- raise processutils .ProcessExecutionError ('error' ,
1265
- stderr = "Sorry, rule does not exist" )
1266
-
1267
- with mock .patch .object (time , 'sleep' , side_effect = fake_sleep ), \
1268
- mock .patch .object (self .driver , '_execute' ,
1269
- side_effect = fake_execute ):
1270
- self .assertRaises (processutils .ProcessExecutionError ,
1271
- self .driver ._exec_ebtables , 'fake' , 'fake' )
1272
- self .assertEqual (1 , len (executes ))
1273
-
1274
- def test_exec_ebtables_fail_once (self ):
1275
- executes = []
1276
-
1277
- def fake_sleep (interval ):
1278
- pass
1279
-
1280
- def fake_execute (* args , ** kwargs ):
1281
- executes .append (args )
1282
- if len (executes ) == 1 :
1283
- raise processutils .ProcessExecutionError ('error' ,
1284
- stderr = self ._ebtables_race_stderr ())
1285
- else :
1286
- return "" , ""
1287
-
1288
- with mock .patch .object (time , 'sleep' , side_effect = fake_sleep ), \
1289
- mock .patch .object (self .driver , '_execute' ,
1290
- side_effect = fake_execute ):
1291
- self .driver ._exec_ebtables ('fake' , 'fake' )
1292
- self .assertEqual (2 , len (executes ))
1231
+ @mock .patch ('nova.privsep.linux_net.modify_ebtables' ,
1232
+ return_value = ('' , '' ))
1233
+ def test_exec_ebtables_success (self , mock_modify_ebtables ):
1234
+ self .driver ._exec_ebtables ('fake' , 'fake' )
1235
+ mock_modify_ebtables .assert_called ()
1236
+
1237
+ @mock .patch ('nova.privsep.linux_net.modify_ebtables' ,
1238
+ side_effect = processutils .ProcessExecutionError (
1239
+ 'error' ,
1240
+ stderr = (u'Unable to update the kernel. Two possible '
1241
+ 'causes:\n 1. Multiple ebtables programs were '
1242
+ 'executing simultaneously. The ebtables\n '
1243
+ 'userspace tool doesn\' t by default support '
1244
+ 'multiple ebtables programs running\n '
1245
+ 'concurrently. The ebtables option --concurrent '
1246
+ 'or a tool like flock can be\n used to support '
1247
+ 'concurrent scripts that update the ebtables '
1248
+ 'kernel tables.\n 2. The kernel doesn\' t support '
1249
+ 'a certain ebtables extension, consider\n '
1250
+ 'recompiling your kernel or insmod the '
1251
+ 'extension.\n .\n ' )))
1252
+ @mock .patch ('time.sleep' )
1253
+ def test_exec_ebtables_fail_all (self , mock_sleep , mock_modify_ebtables ):
1254
+ self .flags (ebtables_exec_attempts = 5 )
1255
+ self .assertRaises (processutils .ProcessExecutionError ,
1256
+ self .driver ._exec_ebtables , 'fake' , 'fake' )
1257
+ self .assertEqual (5 , mock_modify_ebtables .call_count )
1258
+
1259
+ @mock .patch ('nova.privsep.linux_net.modify_ebtables' ,
1260
+ side_effect = processutils .ProcessExecutionError (
1261
+ 'error' ,
1262
+ stderr = (u'Sorry, rule does not exist' )))
1263
+ @mock .patch ('time.sleep' )
1264
+ def test_exec_ebtables_fail_no_retry (self , mock_sleep ,
1265
+ mock_modify_ebtables ):
1266
+ self .assertRaises (processutils .ProcessExecutionError ,
1267
+ self .driver ._exec_ebtables , 'fake' , 'fake' )
1268
+ mock_modify_ebtables .assert_called ()
1269
+
1270
+ @mock .patch ('nova.privsep.linux_net.modify_ebtables' ,
1271
+ side_effect = [
1272
+ processutils .ProcessExecutionError (
1273
+ 'error' ,
1274
+ stderr = (u'Unable to update the kernel. Two possible '
1275
+ 'causes:\n 1. Multiple ebtables programs were '
1276
+ 'executing simultaneously. The ebtables\n '
1277
+ 'userspace tool doesn\' t by default support '
1278
+ 'multiple ebtables programs running\n '
1279
+ 'concurrently. The ebtables option '
1280
+ '--concurrent or a tool like flock can be\n '
1281
+ 'used to support concurrent scripts that '
1282
+ 'update the ebtables kernel tables.\n 2. The '
1283
+ 'kernel doesn\' t support a certain ebtables '
1284
+ 'extension, consider\n recompiling your '
1285
+ 'kernel or insmod the extension.\n .\n ' )),
1286
+ ('' , '' )])
1287
+ @mock .patch ('time.sleep' )
1288
+ def test_exec_ebtables_fail_once (self , mock_sleep , mock_modify_ebtables ):
1289
+ self .driver ._exec_ebtables ('fake' , 'fake' )
1290
+ self .assertEqual (2 , mock_modify_ebtables .call_count )
1293
1291
1294
1292
@mock .patch ('os.path.exists' , return_value = True )
1295
1293
@mock .patch ('nova.privsep.linux_net.set_device_disabled' )
0 commit comments