Set lock_path correctly.
[openstack-build/neutron-build.git] / neutron / tests / unit / plugins / ml2 / drivers / openvswitch / agent / openflow / ovs_ofctl / test_br_tun.py
1 # Copyright (C) 2014,2015 VA Linux Systems Japan K.K.
2 # Copyright (C) 2014,2015 YAMAMOTO Takashi <yamamoto at valinux co jp>
3 # All Rights Reserved.
4 #
5 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
6 #    not use this file except in compliance with the License. You may obtain
7 #    a copy of the License at
8 #
9 #         http://www.apache.org/licenses/LICENSE-2.0
10 #
11 #    Unless required by applicable law or agreed to in writing, software
12 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 #    License for the specific language governing permissions and limitations
15 #    under the License.
16
17 import mock
18 import netaddr
19
20 import neutron.plugins.ml2.drivers.openvswitch.agent.common.constants \
21     as ovs_const
22 from neutron.tests.unit.plugins.ml2.drivers.openvswitch.agent.\
23     openflow.ovs_ofctl import ovs_bridge_test_base
24
25
26 call = mock.call  # short hand
27
28
29 class OVSTunnelBridgeTest(ovs_bridge_test_base.OVSBridgeTestBase,
30                           ovs_bridge_test_base.OVSDVRProcessTestMixin):
31     dvr_process_table_id = ovs_const.DVR_PROCESS
32     dvr_process_next_table_id = ovs_const.PATCH_LV_TO_TUN
33
34     def setUp(self):
35         super(OVSTunnelBridgeTest, self).setUp()
36         self.setup_bridge_mock('br-tun', self.br_tun_cls)
37
38     def test_setup_default_table(self):
39         patch_int_ofport = 5555
40         mock_do_action_flows = mock.patch.object(self.br,
41                                                  'do_action_flows').start()
42         self.mock.attach_mock(mock_do_action_flows, 'do_action_flows')
43         self.br.setup_default_table(patch_int_ofport=patch_int_ofport,
44                                     arp_responder_enabled=False)
45         flow_args = [{'priority': 1, 'in_port': patch_int_ofport,
46                       'actions': 'resubmit(,2)'},
47                      {'priority': 0, 'actions': 'drop'},
48                      {'priority': 0, 'table': 2,
49                       'dl_dst': '00:00:00:00:00:00/01:00:00:00:00:00',
50                       'actions': 'resubmit(,20)'},
51                      {'priority': 0, 'table': 2,
52                       'dl_dst': '01:00:00:00:00:00/01:00:00:00:00:00',
53                       'actions': 'resubmit(,22)'},
54                      {'priority': 0, 'table': 3, 'actions': 'drop'},
55                      {'priority': 0, 'table': 4, 'actions': 'drop'},
56                      {'priority': 0, 'table': 6, 'actions': 'drop'},
57                      {'priority': 1, 'table': 10,
58                       'actions': 'learn(cookie=0,table=20,priority=1,'
59                       'hard_timeout=300,NXM_OF_VLAN_TCI[0..11],'
60                       'NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],'
61                       'load:0->NXM_OF_VLAN_TCI[],'
62                       'load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],'
63                       'output:NXM_OF_IN_PORT[]),'
64                       'output:%s' % patch_int_ofport},
65                      {'priority': 0, 'table': 20, 'actions': 'resubmit(,22)'}
66                      ]
67         expected = [call.do_action_flows('add', flow_args),
68                     call.add_flow(priority=0, table=22, actions='drop')]
69         self.assertEqual(expected, self.mock.mock_calls)
70
71     def test_setup_default_table_arp_responder_enabled(self):
72         patch_int_ofport = 5555
73         mock_do_action_flows = mock.patch.object(self.br,
74                                                  'do_action_flows').start()
75         self.mock.attach_mock(mock_do_action_flows, 'do_action_flows')
76         self.br.setup_default_table(patch_int_ofport=patch_int_ofport,
77             arp_responder_enabled=True)
78         flow_args = [{'priority': 1, 'in_port': patch_int_ofport,
79                       'actions': 'resubmit(,2)'},
80                      {'priority': 0, 'actions': 'drop'},
81                      {'priority': 1, 'table': 2, 'dl_dst': 'ff:ff:ff:ff:ff:ff',
82                       'actions': 'resubmit(,21)', 'proto': 'arp'},
83                      {'priority': 0, 'table': 2,
84                       'dl_dst': '00:00:00:00:00:00/01:00:00:00:00:00',
85                       'actions': 'resubmit(,20)'},
86                      {'priority': 0, 'table': 2,
87                       'dl_dst': '01:00:00:00:00:00/01:00:00:00:00:00',
88                       'actions': 'resubmit(,22)'},
89                      {'priority': 0, 'table': 3, 'actions': 'drop'},
90                      {'priority': 0, 'table': 4, 'actions': 'drop'},
91                      {'priority': 0, 'table': 6, 'actions': 'drop'},
92                      {'priority': 1, 'table': 10,
93                       'actions': 'learn(cookie=0,table=20,priority=1,'
94                       'hard_timeout=300,NXM_OF_VLAN_TCI[0..11],'
95                       'NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],'
96                       'load:0->NXM_OF_VLAN_TCI[],'
97                       'load:NXM_NX_TUN_ID[]->NXM_NX_TUN_ID[],'
98                       'output:NXM_OF_IN_PORT[]),'
99                       'output:%s' % patch_int_ofport},
100                      {'priority': 0, 'table': 20, 'actions': 'resubmit(,22)'},
101                      {'priority': 0, 'table': 21, 'actions': 'resubmit(,22)'}
102                      ]
103         expected = [call.do_action_flows('add', flow_args),
104                     call.add_flow(priority=0, table=22, actions='drop')]
105         self.assertEqual(expected, self.mock.mock_calls)
106
107     def test_provision_local_vlan(self):
108         network_type = 'vxlan'
109         lvid = 888
110         segmentation_id = 777
111         distributed = False
112         self.br.provision_local_vlan(network_type=network_type, lvid=lvid,
113                                      segmentation_id=segmentation_id,
114                                      distributed=distributed)
115         expected = [
116             call.add_flow(priority=1, tun_id=segmentation_id,
117                           actions='mod_vlan_vid:%s,resubmit(,10)' % lvid,
118                           table=4),
119         ]
120         self.assertEqual(expected, self.mock.mock_calls)
121
122     def test_reclaim_local_vlan(self):
123         network_type = 'vxlan'
124         segmentation_id = 777
125         self.br.reclaim_local_vlan(network_type=network_type,
126                                    segmentation_id=segmentation_id)
127         expected = [
128             call.delete_flows(tun_id=segmentation_id, table=4),
129         ]
130         self.assertEqual(expected, self.mock.mock_calls)
131
132     def test_install_flood_to_tun(self):
133         vlan = 3333
134         tun_id = 2222
135         ports = [11, 44, 22, 33]
136         self.br.install_flood_to_tun(vlan=vlan,
137                                      tun_id=tun_id,
138                                      ports=ports)
139         expected = [
140             call.mod_flow(table=22, dl_vlan=vlan,
141                           actions='strip_vlan,set_tunnel:%(tun)s,'
142                           'output:%(ports)s' % {
143                               'tun': tun_id,
144                               'ports': ','.join(map(str, ports)),
145                           }),
146         ]
147         self.assertEqual(expected, self.mock.mock_calls)
148
149     def test_delete_flood_to_tun(self):
150         vlan = 3333
151         self.br.delete_flood_to_tun(vlan=vlan)
152         expected = [
153             call.delete_flows(table=22, dl_vlan=vlan),
154         ]
155         self.assertEqual(expected, self.mock.mock_calls)
156
157     def test_install_unicast_to_tun(self):
158         vlan = 3333
159         port = 55
160         mac = '08:60:6e:7f:74:e7'
161         tun_id = 2222
162         self.br.install_unicast_to_tun(vlan=vlan,
163                                        tun_id=tun_id,
164                                        port=port,
165                                        mac=mac)
166         expected = [
167             call.add_flow(priority=2, table=20, dl_dst=mac, dl_vlan=vlan,
168                           actions='strip_vlan,set_tunnel:%(tun)s,'
169                           'output:%(port)s' % {
170                               'tun': tun_id,
171                               'port': port,
172                           }),
173         ]
174         self.assertEqual(expected, self.mock.mock_calls)
175
176     def test_delete_unicast_to_tun(self):
177         vlan = 3333
178         mac = '08:60:6e:7f:74:e7'
179         self.br.delete_unicast_to_tun(vlan=vlan, mac=mac)
180         expected = [
181             call.delete_flows(table=20, dl_dst=mac, dl_vlan=vlan),
182         ]
183         self.assertEqual(expected, self.mock.mock_calls)
184
185     def test_delete_unicast_to_tun_without_mac(self):
186         vlan = 3333
187         mac = None
188         self.br.delete_unicast_to_tun(vlan=vlan, mac=mac)
189         expected = [
190             call.delete_flows(table=20, dl_vlan=vlan),
191         ]
192         self.assertEqual(expected, self.mock.mock_calls)
193
194     def test_install_arp_responder(self):
195         vlan = 3333
196         ip = '192.0.2.1'
197         mac = '08:60:6e:7f:74:e7'
198         self.br.install_arp_responder(vlan=vlan, ip=ip, mac=mac)
199         expected = [
200             call.add_flow(proto='arp', nw_dst=ip,
201                           actions='move:NXM_OF_ETH_SRC[]->NXM_OF_ETH_DST[],'
202                           'mod_dl_src:%(mac)s,load:0x2->NXM_OF_ARP_OP[],'
203                           'move:NXM_NX_ARP_SHA[]->NXM_NX_ARP_THA[],'
204                           'move:NXM_OF_ARP_SPA[]->NXM_OF_ARP_TPA[],'
205                           'load:%(mac)#x->NXM_NX_ARP_SHA[],'
206                           'load:%(ip)#x->NXM_OF_ARP_SPA[],in_port' % {
207                               'mac': netaddr.EUI(mac,
208                                                  dialect=netaddr.mac_unix),
209                               'ip': netaddr.IPAddress(ip),
210                           },
211                           priority=1, table=21, dl_vlan=vlan),
212         ]
213         self.assertEqual(expected, self.mock.mock_calls)
214
215     def test_delete_arp_responder(self):
216         vlan = 3333
217         ip = '192.0.2.1'
218         self.br.delete_arp_responder(vlan=vlan, ip=ip)
219         expected = [
220             call.delete_flows(table=21, dl_vlan=vlan, proto='arp', nw_dst=ip),
221         ]
222         self.assertEqual(expected, self.mock.mock_calls)
223
224     def test_delete_arp_responder_without_ip(self):
225         vlan = 3333
226         ip = None
227         self.br.delete_arp_responder(vlan=vlan, ip=ip)
228         expected = [
229             call.delete_flows(table=21, dl_vlan=vlan, proto='arp'),
230         ]
231         self.assertEqual(expected, self.mock.mock_calls)
232
233     def test_setup_tunnel_port(self):
234         network_type = 'vxlan'
235         port = 11111
236         self.br.setup_tunnel_port(network_type=network_type, port=port)
237         expected = [
238             call.add_flow(priority=1, in_port=port, actions='resubmit(,4)'),
239         ]
240         self.assertEqual(expected, self.mock.mock_calls)
241
242     def test_cleanup_tunnel_port(self):
243         port = 11111
244         self.br.cleanup_tunnel_port(port=port)
245         expected = [
246             call.delete_flows(in_port=port),
247         ]
248         self.assertEqual(expected, self.mock.mock_calls)
249
250     def test_add_dvr_mac_tun(self):
251         mac = '00:02:b3:13:fe:3d'
252         port = 8888
253         self.br.add_dvr_mac_tun(mac=mac, port=port)
254         expected = [
255             call.add_flow(priority=1, table=9, dl_src=mac,
256                           actions='output:%s' % port),
257         ]
258         self.assertEqual(expected, self.mock.mock_calls)
259
260     def test_remove_dvr_mac_tun(self):
261         mac = '00:02:b3:13:fe:3d'
262         self.br.remove_dvr_mac_tun(mac=mac)
263         expected = [
264             call.delete_flows(eth_src=mac, table_id=9),
265         ]
266         self.assertEqual(expected, self.mock.mock_calls)
267
268     def _mock_add_tunnel_port(self, deferred_br=False):
269         port_name = 'fake_port'
270         remote_ip = '192.168.1.3'
271         local_ip = '192.168.1.2'
272         tunnel_type = 'vxlan'
273         vxlan_udp_port = '4789'
274         dont_fragment = True
275         if deferred_br:
276             with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.add_port',
277                             return_value=9999) as add_port, \
278                     self.br.deferred() as deferred_br:
279                 ofport = deferred_br.add_tunnel_port(port_name, remote_ip,
280                                                      local_ip, tunnel_type,
281                                                      vxlan_udp_port,
282                                                      dont_fragment)
283         else:
284             with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.add_port',
285                             return_value=9999) as add_port:
286                 ofport = self.br.add_tunnel_port(port_name, remote_ip,
287                                                  local_ip, tunnel_type,
288                                                  vxlan_udp_port,
289                                                  dont_fragment)
290         self.assertEqual(9999, ofport)
291         self.assertEqual(1, add_port.call_count)
292         self.assertEqual(port_name, add_port.call_args[0][0])
293
294     def _mock_delete_port(self, deferred_br=False):
295         port_name = 'fake_port'
296         if deferred_br:
297             with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
298                             'delete_port') as delete_port, \
299                     self.br.deferred() as deferred_br:
300                 deferred_br.delete_port(port_name)
301         else:
302             with mock.patch('neutron.agent.common.ovs_lib.OVSBridge.'
303                             'delete_port') as delete_port:
304                 self.br.delete_port(port_name)
305         self.assertEqual([call(port_name)], delete_port.mock_calls)
306
307     def test_add_tunnel_port(self):
308         self._mock_add_tunnel_port()
309
310     def test_delete_port(self):
311         self._mock_delete_port()
312
313     def test_deferred_br_add_tunnel_port(self):
314         self._mock_add_tunnel_port(True)
315
316     def test_deferred_br_delete_port(self):
317         self._mock_delete_port(True)