From 061dfb0d97032f49e89dc82224658d1a66ae0909 Mon Sep 17 00:00:00 2001 From: Kyrylo Romanenko Date: Fri, 24 Feb 2017 18:14:46 +0200 Subject: [PATCH] Add functional api tests for node resource class Add following tests: Create new node with specified longest name of resource class. Update existing node with specified resource class. Show resource class field of specified node. List nodes of specified resource class only. Get detailed nodes list of specified resource class only. Try to create a node with too long resource class name. Try to update a node with too long resource class name. Try to create a node with resource class using older api version. Try to update a node with resource class using older api version. Try to list nodes with resource class using older api version. Closes-Bug: #1668605 Change-Id: If412a2aeab2ab457f04067cf296cac80b4378482 --- .../baremetal/v1/json/baremetal_client.py | 26 +++- ironic_tempest_plugin/tests/api/admin/base.py | 6 +- .../tests/api/admin/test_nodes.py | 125 ++++++++++++++++++ 3 files changed, 148 insertions(+), 9 deletions(-) diff --git a/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py b/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py index 663ca9c200..40aa1d072a 100644 --- a/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py +++ b/ironic_tempest_plugin/services/baremetal/v1/json/baremetal_client.py @@ -25,6 +25,11 @@ class BaremetalClient(base.BaremetalClient): """List all existing nodes.""" return self._list_request('nodes', **kwargs) + @base.handle_errors + def list_nodes_detail(self, **kwargs): + """Detailed list of all existing nodes.""" + return self._list_request('/nodes/detail', **kwargs) + @base.handle_errors def list_chassis(self): """List all existing chassis.""" @@ -151,12 +156,18 @@ class BaremetalClient(base.BaremetalClient): :return: A tuple with the server response and the created node. """ - node = {'chassis_uuid': chassis_id, - 'properties': {'cpu_arch': kwargs.get('cpu_arch', 'x86_64'), - 'cpus': kwargs.get('cpus', 8), - 'local_gb': kwargs.get('local_gb', 1024), - 'memory_mb': kwargs.get('memory_mb', 4096)}, - 'driver': kwargs.get('driver', 'fake')} + node = {} + if kwargs.get('resource_class'): + node['resource_class'] = kwargs['resource_class'] + + node.update( + {'chassis_uuid': chassis_id, + 'properties': {'cpu_arch': kwargs.get('cpu_arch', 'x86_64'), + 'cpus': kwargs.get('cpus', 8), + 'local_gb': kwargs.get('local_gb', 1024), + 'memory_mb': kwargs.get('memory_mb', 4096)}, + 'driver': kwargs.get('driver', 'fake')} + ) return self._create_request('nodes', node) @@ -278,7 +289,8 @@ class BaremetalClient(base.BaremetalClient): 'properties/local_gb', 'properties/memory_mb', 'driver', - 'instance_uuid') + 'instance_uuid', + 'resource_class') if not patch: patch = self._make_patch(node_attributes, **kwargs) diff --git a/ironic_tempest_plugin/tests/api/admin/base.py b/ironic_tempest_plugin/tests/api/admin/base.py index 81b712c7e6..9577f83fa3 100644 --- a/ironic_tempest_plugin/tests/api/admin/base.py +++ b/ironic_tempest_plugin/tests/api/admin/base.py @@ -163,7 +163,7 @@ class BaseBaremetalTest(api_version_utils.BaseMicroversionTest, @classmethod @creates('node') def create_node(cls, chassis_id, cpu_arch='x86', cpus=8, local_gb=10, - memory_mb=4096): + memory_mb=4096, resource_class=None): """Wrapper utility for creating test baremetal nodes. :param chassis_id: The unique identifier of the chassis. @@ -171,13 +171,15 @@ class BaseBaremetalTest(api_version_utils.BaseMicroversionTest, :param cpus: Number of CPUs. Default: 8. :param local_gb: Disk size. Default: 10. :param memory_mb: Available RAM. Default: 4096. + :param resource_class: Node resource class. :return: A tuple with the server response and the created node. """ resp, body = cls.client.create_node(chassis_id, cpu_arch=cpu_arch, cpus=cpus, local_gb=local_gb, memory_mb=memory_mb, - driver=cls.driver) + driver=cls.driver, + resource_class=resource_class) return resp, body diff --git a/ironic_tempest_plugin/tests/api/admin/test_nodes.py b/ironic_tempest_plugin/tests/api/admin/test_nodes.py index dd7bf915e1..7f44823782 100644 --- a/ironic_tempest_plugin/tests/api/admin/test_nodes.py +++ b/ironic_tempest_plugin/tests/api/admin/test_nodes.py @@ -16,6 +16,7 @@ from tempest import config from tempest.lib.common.utils import data_utils from tempest.lib import decorators from tempest.lib import exceptions as lib_exc +from tempest import test from ironic_tempest_plugin.common import waiters from ironic_tempest_plugin.tests.api.admin import api_microversion_fixture @@ -166,6 +167,130 @@ class TestNodes(base.BaseBaremetalTest): self.assertIn(self.node['uuid'], [n['uuid'] for n in body['nodes']]) +class TestNodesResourceClass(base.BaseBaremetalTest): + + min_microversion = '1.21' + + def setUp(self): + super(TestNodesResourceClass, self).setUp() + self.useFixture( + api_microversion_fixture.APIMicroversionFixture( + TestNodesResourceClass.min_microversion) + ) + _, self.chassis = self.create_chassis() + self.resource_class = data_utils.rand_name(name='Resource_Class') + _, self.node = self.create_node( + self.chassis['uuid'], resource_class=self.resource_class) + + @decorators.idempotent_id('2a00340c-8152-4a61-9fc5-0b3cdefec258') + def test_create_node_resource_class_long(self): + """Create new node with specified longest name of resource class.""" + res_class_long_name = data_utils.arbitrary_string(80) + _, body = self.create_node( + self.chassis['uuid'], + resource_class=res_class_long_name) + self.assertEqual(res_class_long_name, body['resource_class']) + + @decorators.idempotent_id('142db00d-ac0f-415b-8da8-9095fbb561f7') + def test_update_node_resource_class(self): + """Update existing node with specified resource class.""" + new_res_class_name = data_utils.rand_name(name='Resource_Class') + _, body = self.client.update_node( + self.node['uuid'], resource_class=new_res_class_name) + _, body = self.client.show_node(self.node['uuid']) + self.assertEqual(new_res_class_name, body['resource_class']) + + @decorators.idempotent_id('73e6f7b5-3e51-49ea-af5b-146cd49f40ee') + def test_show_node_resource_class(self): + """Show resource class field of specified node.""" + _, body = self.client.show_node(self.node['uuid']) + self.assertEqual(self.resource_class, body['resource_class']) + + @decorators.idempotent_id('f2bf4465-280c-4fdc-bbf7-fcf5188befa4') + def test_list_nodes_resource_class(self): + """List nodes of specified resource class only.""" + res_class = 'ResClass-{0}'.format(data_utils.rand_uuid()) + for node in range(3): + _, body = self.create_node( + self.chassis['uuid'], resource_class=res_class) + + _, body = self.client.list_nodes(resource_class=res_class) + self.assertEqual(3, len([i['uuid'] for i in body['nodes']])) + + @decorators.idempotent_id('40733bad-bb79-445e-a094-530a44042995') + def test_list_nodes_detail_resource_class(self): + """Get detailed nodes list of specified resource class only.""" + res_class = 'ResClass-{0}'.format(data_utils.rand_uuid()) + for node in range(3): + _, body = self.create_node( + self.chassis['uuid'], resource_class=res_class) + + _, body = self.client.list_nodes_detail(resource_class=res_class) + self.assertEqual(3, len([i['uuid'] for i in body['nodes']])) + + for node in body['nodes']: + self.assertEqual(res_class, node['resource_class']) + + @test.attr(type='negative') + @decorators.idempotent_id('e75136d4-0690-48a5-aef3-75040aee73ad') + def test_create_node_resource_class_too_long(self): + """Try to create a node with too long resource class name.""" + resource_class = data_utils.arbitrary_string(81) + self.assertRaises(lib_exc.BadRequest, self.create_node, + self.chassis['uuid'], resource_class=resource_class) + + @test.attr(type='negative') + @decorators.idempotent_id('f0aeece4-8671-44ea-a482-b4047fc4cf74') + def test_update_node_resource_class_too_long(self): + """Try to update a node with too long resource class name.""" + resource_class = data_utils.arbitrary_string(81) + self.assertRaises(lib_exc.BadRequest, self.client.update_node, + self.node['uuid'], resource_class=resource_class) + + +class TestNodesResourceClassOldApi(base.BaseBaremetalTest): + + old_microversion = '1.20' + + def setUp(self): + super(TestNodesResourceClassOldApi, self).setUp() + self.useFixture( + api_microversion_fixture.APIMicroversionFixture( + TestNodesResourceClassOldApi.old_microversion) + ) + _, self.chassis = self.create_chassis() + _, self.node = self.create_node(self.chassis['uuid']) + + @test.attr(type='negative') + @decorators.idempotent_id('2c364408-4746-4b3c-9821-20d47b57bdec') + def test_create_node_resource_class_old_api(self): + """Try to create a node with resource class using older api version.""" + resource_class = data_utils.arbitrary_string() + self.assertRaises(lib_exc.UnexpectedResponseCode, self.create_node, + self.chassis['uuid'], resource_class=resource_class) + + @test.attr(type='negative') + @decorators.idempotent_id('666f3c1a-4922-4a3d-b6d9-dea7c74d30bc') + def test_update_node_resource_class_old_api(self): + """Try to update a node with resource class using older api version.""" + resource_class = data_utils.arbitrary_string() + self.assertRaises(lib_exc.UnexpectedResponseCode, + self.client.update_node, + self.node['uuid'], resource_class=resource_class) + + @test.attr(type='negative') + @decorators.idempotent_id('95903480-f16d-4774-8775-6c7f87b27c59') + def test_list_nodes_by_resource_class_old_api(self): + """Try to list nodes with resource class using older api version.""" + resource_class = data_utils.arbitrary_string() + self.assertRaises( + lib_exc.UnexpectedResponseCode, + self.client.list_nodes, resource_class=resource_class) + self.assertRaises( + lib_exc.UnexpectedResponseCode, + self.client.list_nodes_detail, resource_class=resource_class) + + class TestNodesVif(base.BaseBaremetalTest): min_microversion = '1.28'