diff options
author | Julia Kreger <juliaashleykreger@gmail.com> | 2021-05-19 14:29:03 -0700 |
---|---|---|
committer | Julia Kreger <juliaashleykreger@gmail.com> | 2021-06-25 23:04:09 +0000 |
commit | 7b37e03b691cc45e319f61baa494dc0592c2a6f0 (patch) | |
tree | 9a9c6970543a42dbd0e4e83c0ba8f1e619e802c4 /ironic/tests/unit/objects | |
parent | 644ba5d4bc69a029f4b02cbd47e9c542ae316748 (diff) | |
download | ironic-7b37e03b691cc45e319f61baa494dc0592c2a6f0.tar.gz |
Set stage for objects to handle selected field lists.
Prior to this change, ironic would not pass the API consumer request
for a list of nodes down to the underlying layers with the list of
specific fields being requested.
This resulted in full objects being returned from the database where
in essence the entire database would be downloaded to construct the
objects, and in the case of joined views, whole roles would largely
be duplicated.
In order to be more efficent, we need to hand the user desired
fields down to the database, in order to return only that data,
and thus transform it.
In this case, we already have testing that handles the conversion
of objects at the lower layer, and in this case, the db object
conversion handler already understood fields, so we're just kind
of completing the awareness further downward for increased efficency.
This change only sets the stage, the final change to this is aligned
with API change to leverage this as the API is coded such that the
field does not include all of the required fields needed by the API
to render replies, which is fixed in the API patch to leverage this
with the API.
Story: 2008885
Task: 42495
Change-Id: I6283c4cc1b1ff608c4be24a6c41eb7b430a5ad68
Diffstat (limited to 'ironic/tests/unit/objects')
-rw-r--r-- | ironic/tests/unit/objects/test_node.py | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/ironic/tests/unit/objects/test_node.py b/ironic/tests/unit/objects/test_node.py index 8d8b2a8e5..6cbda0ba5 100644 --- a/ironic/tests/unit/objects/test_node.py +++ b/ironic/tests/unit/objects/test_node.py @@ -396,17 +396,68 @@ class TestNodeObject(db_base.DbTestCase, obj_utils.SchemasTestMixIn): self.assertThat(nodes, matchers.HasLength(1)) self.assertIsInstance(nodes[0], objects.Node) self.assertEqual(self.context, nodes[0]._context) + self.assertIsInstance(nodes[0].traits, objects.TraitList) def test_list_with_fields(self): with mock.patch.object(self.dbapi, 'get_node_list', autospec=True) as mock_get_list: mock_get_list.return_value = [self.fake_node] - objects.Node.list(self.context, fields=['name']) + nodes = objects.Node.list(self.context, + fields=['name', 'uuid', + 'provision_state']) mock_get_list.assert_called_with( filters=None, limit=None, marker=None, sort_key=None, sort_dir=None, - fields=['id', 'name', 'version', 'updated_at', 'created_at', - 'owner', 'lessee', 'driver', 'conductor_group']) + fields=['id', 'name', 'uuid', 'provision_state', 'version', + 'updated_at', 'created_at', 'owner', 'lessee', + 'driver', 'conductor_group']) + self.assertThat(nodes, matchers.HasLength(1)) + self.assertEqual(self.fake_node['uuid'], nodes[0].uuid) + self.assertEqual(self.fake_node['provision_state'], + nodes[0].provision_state) + self.assertIsInstance(nodes[0].traits, objects.TraitList) + # Random assortment of fields which should not be present. + for field in ['power_state', 'instance_info', 'resource_class', + 'automated_clean', 'properties', 'driver', 'traits']: + self.assertFalse(field not in dir(nodes[0])) + + def test_list_with_fields_traits(self): + with mock.patch.object(self.dbapi, 'get_node_list', + autospec=True) as mock_get_list: + # Trait objects and ultimately rows have an underlying + # version. Since we've never changed it, it should just + # be one, but this is required for the oslo versioned + # objects code path to handle objects properly and + # navigate mid-upgrade cases. + self.fake_node['traits'] = [{ + 'trait': 'traitx', 'version': "1"}] + mock_get_list.return_value = [self.fake_node] + nodes = objects.Node.list(self.context, + fields=['uuid', 'provision_state', + 'traits']) + self.assertThat(nodes, matchers.HasLength(1)) + self.assertEqual(self.fake_node['uuid'], nodes[0].uuid) + self.assertEqual(self.fake_node['provision_state'], + nodes[0].provision_state) + self.assertIsInstance(nodes[0].traits, objects.TraitList) + self.assertEqual('traitx', nodes[0].traits[0].trait) + for field in ['power_state', 'instance_info', 'resource_class', + 'automated_clean', 'properties', 'driver']: + self.assertFalse(field not in dir(nodes[0])) + + def test_list_with_fields_empty_trait_present(self): + with mock.patch.object(self.dbapi, 'get_node_list', + autospec=True) as mock_get_list: + mock_get_list.return_value = [self.fake_node] + nodes = objects.Node.list(self.context, + fields=['uuid', 'provision_state', + 'traits']) + self.assertThat(nodes, matchers.HasLength(1)) + self.assertEqual(self.fake_node['uuid'], nodes[0].uuid) + self.assertEqual(self.fake_node['provision_state'], + nodes[0].provision_state) + self.assertIsInstance(nodes[0].traits, objects.TraitList) + self.assertIn('traits', nodes[0]) def test_reserve(self): with mock.patch.object(self.dbapi, 'reserve_node', |