Browse Source

Merge "ut: Add create/delete tests using Neutron API"

Zuul 7 months ago
parent
commit
bf57aca6d4

+ 11
- 4
networking_ansible/tests/unit/base.py View File

@@ -29,6 +29,16 @@ QUOTA_REGISTRIES = (
29 29
 )
30 30
 
31 31
 
32
+def patch_neutron_quotas():
33
+    """Patch neutron quotas.
34
+
35
+    This is to avoid "No resource found" messages printed to stderr from
36
+    quotas Neutron code.
37
+    """
38
+    for func in QUOTA_REGISTRIES:
39
+        mock.patch(func).start()
40
+
41
+
32 42
 class BaseTestCase(base.BaseTestCase):
33 43
     test_config_files = []
34 44
     parse_config = True
@@ -57,10 +67,7 @@ class BaseTestCase(base.BaseTestCase):
57 67
 
58 68
 class NetworkingAnsibleTestCase(BaseTestCase):
59 69
     def setUp(self):
60
-        # This is to avoid "No resource found" messages printed to stderr from
61
-        # quotas Neutron code.
62
-        for func in QUOTA_REGISTRIES:
63
-            mock.patch(func).start()
70
+        patch_neutron_quotas()
64 71
         super(NetworkingAnsibleTestCase, self).setUp()
65 72
         self.mech = mech_driver.AnsibleMechanismDriver()
66 73
         self.mech.initialize()

+ 135
- 10
networking_ansible/tests/unit/ml2/test_mech_driver.py View File

@@ -14,14 +14,40 @@
14 14
 #    under the License.
15 15
 
16 16
 import mock
17
+import tempfile
17 18
 
19
+import fixtures
20
+from neutron.common import test_lib
18 21
 from neutron.plugins.ml2.common import exceptions as ml2_exc
22
+from neutron.tests.unit.plugins.ml2 import test_plugin
23
+from neutron_lib.api.definitions import portbindings
24
+from neutron_lib.api.definitions import provider_net
25
+import webob.exc
19 26
 
27
+from networking_ansible import ansible_networking as anet
20 28
 from networking_ansible.tests.unit import base
21 29
 
22 30
 
23
-@mock.patch('networking_ansible.ansible_networking.'
24
-            'AnsibleNetworking.vlan_access_port')
31
+class TestLibTestConfigFixture(fixtures.Fixture):
32
+    def __init__(self):
33
+        self._original_test_config = None
34
+
35
+    def _setUp(self):
36
+        self.addCleanup(self._restore)
37
+        self._original_test_config = test_lib.test_config.copy()
38
+
39
+    def _restore(self):
40
+        if self._original_test_config is not None:
41
+            test_lib.test_config = self._original_test_config
42
+
43
+
44
+class NetAnsibleML2Base(test_plugin.Ml2PluginV2TestCase):
45
+    def setUp(self):
46
+        base.patch_neutron_quotas()
47
+        super(NetAnsibleML2Base, self).setUp()
48
+
49
+
50
+@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
25 51
 @mock.patch('networking_ansible.ml2.mech_driver.provisioning_blocks',
26 52
             autospec=True)
27 53
 class TestBindPort(base.NetworkingAnsibleTestCase):
@@ -78,8 +104,7 @@ class TestIsPortBound(base.NetworkingAnsibleTestCase):
78 104
             self.mech._is_port_bound(self.mock_port_context.current))
79 105
 
80 106
 
81
-@mock.patch('networking_ansible.ansible_networking.'
82
-            'AnsibleNetworking.create_network')
107
+@mock.patch.object(anet.AnsibleNetworking, 'create_network')
83 108
 class TestCreateNetworkPostCommit(base.NetworkingAnsibleTestCase):
84 109
     def test_create_network_postcommit(self, mock_create_network):
85 110
         self.mech.create_network_postcommit(self.mock_net_context)
@@ -110,8 +135,7 @@ class TestCreateNetworkPostCommit(base.NetworkingAnsibleTestCase):
110 135
         mock_create_netwrk.assert_not_called()
111 136
 
112 137
 
113
-@mock.patch('networking_ansible.ansible_networking.'
114
-            'AnsibleNetworking.delete_network')
138
+@mock.patch.object(anet.AnsibleNetworking, 'delete_network')
115 139
 class TestDeleteNetworkPostCommit(base.NetworkingAnsibleTestCase):
116 140
     def test_delete_network_postcommit(self, mock_delete_network):
117 141
         self.mech.delete_network_postcommit(self.mock_net_context)
@@ -142,8 +166,7 @@ class TestDeleteNetworkPostCommit(base.NetworkingAnsibleTestCase):
142 166
 
143 167
 @mock.patch('networking_ansible.ml2.mech_driver.'
144 168
             'AnsibleMechanismDriver._is_port_bound')
145
-@mock.patch('networking_ansible.ansible_networking.'
146
-            'AnsibleNetworking.vlan_access_port')
169
+@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
147 170
 class TestDeletePortPostCommit(base.NetworkingAnsibleTestCase):
148 171
     def test_delete_port_postcommit_current(self,
149 172
                                             mock_vlan_access,
@@ -171,8 +194,7 @@ class TestInit(base.NetworkingAnsibleTestCase):
171 194
 
172 195
 @mock.patch('networking_ansible.ml2.mech_driver.'
173 196
             'AnsibleMechanismDriver._is_port_bound')
174
-@mock.patch('networking_ansible.ansible_networking.'
175
-            'AnsibleNetworking.vlan_access_port')
197
+@mock.patch.object(anet.AnsibleNetworking, 'vlan_access_port')
176 198
 @mock.patch('networking_ansible.ml2.mech_driver.provisioning_blocks',
177 199
             autospec=True)
178 200
 class TestUpdatePortPostCommit(base.NetworkingAnsibleTestCase):
@@ -198,3 +220,106 @@ class TestUpdatePortPostCommit(base.NetworkingAnsibleTestCase):
198 220
         mock_port_bound.side_effect = [False, False]
199 221
         self.mech.update_port_postcommit(self.mock_port_context)
200 222
         mock_vlan_access.assert_not_called()
223
+
224
+
225
+@mock.patch.object(anet.AnsibleNetworking, '_run_task')
226
+class TestML2PluginIntegration(NetAnsibleML2Base):
227
+    _mechanism_drivers = ['ansible']
228
+    HOSTS = ['testinghost', 'otherhost']
229
+    CIDR = '10.0.0.0/24'
230
+
231
+    CONFIG_CONTENT = {
232
+        'ansible:{:s}'.format(host): [
233
+            'ansible_network_os=provider\n',
234
+            'ansible_host=host_ip\n',
235
+            'ansible_user=user\n',
236
+            'ansible_pass=password\n',
237
+        ] for host in HOSTS
238
+    }
239
+
240
+    LOCAL_LINK_INFORMATION = [{
241
+        'switch_info': HOSTS[0],
242
+        'switch_id': 'foo',
243
+        'port_id': 'bar',
244
+    }]
245
+
246
+    UNBOUND_PORT_SPEC = {
247
+        'device_owner': 'baremetal:none',
248
+        'device_id': 'some-id',
249
+    }
250
+
251
+    BIND_PORT_UPDATE = {
252
+        'port': {
253
+            'binding:host_id': 'foo',
254
+            'binding:vnic_type': portbindings.VNIC_BAREMETAL,
255
+            'binding:profile': {
256
+                'local_link_information': LOCAL_LINK_INFORMATION,
257
+            },
258
+        },
259
+    }
260
+
261
+    def setUp(self):
262
+        self.useFixture(TestLibTestConfigFixture())
263
+        self.filename = tempfile.mktemp(prefix='test_anet')
264
+        self._configure()
265
+        super(TestML2PluginIntegration, self).setUp()
266
+        seg_id = self.vlan_range.split(':')[0]
267
+        self.network_spec = {
268
+            provider_net.PHYSICAL_NETWORK: self.physnet,
269
+            provider_net.NETWORK_TYPE: 'vlan',
270
+            provider_net.SEGMENTATION_ID: seg_id,
271
+            'arg_list': (
272
+                provider_net.PHYSICAL_NETWORK,
273
+                provider_net.NETWORK_TYPE,
274
+                provider_net.SEGMENTATION_ID,
275
+            ),
276
+            'admin_state_up': True
277
+        }
278
+
279
+    def _write_config_content(self):
280
+        with open(self.filename, 'w') as f:
281
+            for section, content in self.CONFIG_CONTENT.items():
282
+                f.write("[{:s}]\n".format(section))
283
+                f.writelines(content)
284
+                f.write("\n")
285
+
286
+    def _configure(self):
287
+        """Create config for the mech driver."""
288
+        test_lib.test_config.setdefault('config_files', []).append(
289
+            self.filename)
290
+        self._write_config_content()
291
+
292
+    def _create_network_with_spec(self, name, spec):
293
+        res = self._create_network(self.fmt, name, **spec)
294
+        network = self.deserialize(self.fmt, res)
295
+        return res, network
296
+
297
+    def test_create_network_vlan(self, m_run_task):
298
+        res, _ = self._create_network_with_spec('tenant', self.network_spec)
299
+        self.assertEqual(webob.exc.HTTPCreated.code, res.status_int)
300
+        expected_calls = [
301
+            mock.call(
302
+                'create_network',
303
+                host,
304
+                int(self.network_spec[provider_net.SEGMENTATION_ID]))
305
+            for host in self.HOSTS]
306
+        self.assertItemsEqual(
307
+            expected_calls,
308
+            m_run_task.call_args_list)
309
+
310
+    def test_delete_network(self, m_run_task):
311
+        res, network = self._create_network_with_spec('tenant',
312
+                                                      self.network_spec)
313
+        m_run_task.reset_mock()
314
+        req = self.new_delete_request('networks', network['network']['id'])
315
+        res = req.get_response(self.api)
316
+        self.assertEqual(webob.exc.HTTPNoContent.code, res.status_int)
317
+        expected_calls = [
318
+            mock.call(
319
+                'delete_network',
320
+                host,
321
+                int(self.network_spec[provider_net.SEGMENTATION_ID]))
322
+            for host in self.HOSTS]
323
+        self.assertItemsEqual(
324
+            expected_calls,
325
+            m_run_task.call_args_list)

Loading…
Cancel
Save