From bb4304eeeeb4156c77e6065e31fa95815e38018a Mon Sep 17 00:00:00 2001 From: Ian Cordasco Date: Wed, 1 Mar 2017 14:15:07 -0600 Subject: [PATCH] Update schema definition for network interfaces port Previously, listing or creating a network interface required the port be an integer. Updating the port, however, allowed it to be a string instead of similarly requiring it to be an integer. This updates the constraint and adds the basis of functional testing for those endpoints. Closes-bug: #1630276 Change-Id: Ic99d73dfd63fb3fe9a64d41ca2b8eafe4ff1c253 --- craton/api/v1/schemas.py | 2 +- craton/tests/functional/__init__.py | 3 + .../test_network_interface_calls.py | 57 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 craton/tests/functional/test_network_interface_calls.py diff --git a/craton/api/v1/schemas.py b/craton/api/v1/schemas.py index 29fa368..0a0be15 100644 --- a/craton/api/v1/schemas.py +++ b/craton/api/v1/schemas.py @@ -1325,7 +1325,7 @@ validators = { "type": "string", }, "port": { - "type": "string", + "type": "integer", }, "duplex": { "type": "string", diff --git a/craton/tests/functional/__init__.py b/craton/tests/functional/__init__.py index afaa2cc..08e5896 100644 --- a/craton/tests/functional/__init__.py +++ b/craton/tests/functional/__init__.py @@ -217,6 +217,9 @@ class TestCase(testtools.TestCase): def assertNoContent(self, response): self.assertEqual(requests.codes.NO_CONTENT, response.status_code) + def assertBadRequest(self, response): + self.assertEqual(requests.codes.BAD_REQUEST, response.status_code) + def get(self, url, headers=None, **params): resp = self.session.get( url, verify=False, headers=headers, params=params, diff --git a/craton/tests/functional/test_network_interface_calls.py b/craton/tests/functional/test_network_interface_calls.py new file mode 100644 index 0000000..65cac55 --- /dev/null +++ b/craton/tests/functional/test_network_interface_calls.py @@ -0,0 +1,57 @@ +from craton.tests import functional + + +class APIv1NetworkInterfacesTest(functional.DeviceTestBase): + def setUp(self): + super(APIv1NetworkInterfacesTest, self).setUp() + self.interfaces_url = self.url + '/v1/network-interfaces' + + def test_associate_network_device_with_a_host(self): + host = self.create_host('host-0', 'server', '127.0.0.1') + + payload = { + 'name': 'lo', + 'ip_address': '127.0.0.1', + 'device_id': host['id'], + 'interface_type': 'loopback', + } + response = self.post(self.interfaces_url, data=payload) + self.assertSuccessCreated(response) + self.assertIn('Location', response.headers) + interface = response.json() + self.assertEqual( + '{}/{}'.format(self.interfaces_url, interface['id']), + response.headers['Location'] + ) + + def test_port_must_be_an_integer_on_create(self): + host = self.create_host('host-0', 'server', '127.0.0.1') + + payload = { + 'name': 'lo', + 'ip_address': '127.0.0.1', + 'device_id': host['id'], + 'interface_type': 'loopback', + 'port': 'asdf', + } + response = self.post(self.interfaces_url, data=payload) + self.assertBadRequest(response) + + def test_port_must_be_an_integer_on_update(self): + host = self.create_host('host-0', 'server', '127.0.0.1') + + payload = { + 'name': 'lo', + 'ip_address': '127.0.0.1', + 'device_id': host['id'], + 'interface_type': 'loopback', + 'port': 80, + } + response = self.post(self.interfaces_url, data=payload) + self.assertSuccessCreated(response) + interface = response.json() + + url = self.interfaces_url + '/{}'.format(interface['id']) + payload = {'port': 'asdf'} + response = self.put(url, data=payload) + self.assertBadRequest(response)