From e86d5b063bbb741d411bf4b50b5cc8a9829960db Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Tue, 28 May 2013 15:55:58 -0700 Subject: Add lists of instance objects This adds a list-of-instances object, which can house the "get all" methods for instances. It's very simple, emulates a list, but provides us an object-oriented way to get multiple instances that mirrors the model. Related to blueprint unified-object-model Change-Id: Id6579030b88b92d4cb7db13ee6718ad01db7bf63 --- nova/objects/instance.py | 54 +++++++++++++++++ nova/tests/objects/test_instance.py | 114 ++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) diff --git a/nova/objects/instance.py b/nova/objects/instance.py index 0489f1374..58c581542 100644 --- a/nova/objects/instance.py +++ b/nova/objects/instance.py @@ -239,3 +239,57 @@ class Instance(base.NovaObject): uuid=self.uuid, expected_attrs=extra) self[attrname] = instance[attrname] + + +def _make_instance_list(context, inst_list, db_inst_list, expected_attrs): + inst_list.objects = [] + for db_inst in db_inst_list: + inst_obj = Instance._from_db_object(Instance(), db_inst, + expected_attrs=expected_attrs) + inst_obj._context = context + inst_list.objects.append(inst_obj) + inst_list.obj_reset_changes() + return inst_list + + +class InstanceList(base.ObjectListBase, base.NovaObject): + @base.remotable_classmethod + def get_by_filters(cls, context, filters, + sort_key=None, sort_dir=None, limit=None, marker=None, + expected_attrs=None): + db_inst_list = db.instance_get_all_by_filters( + context, filters, sort_key, sort_dir, limit, marker, + columns_to_join=expected_attrs) + + return _make_instance_list(context, cls(), db_inst_list, + expected_attrs) + + @base.remotable_classmethod + def get_by_host(cls, context, host, expected_attrs=None): + db_inst_list = db.instance_get_all_by_host( + context, host, columns_to_join=expected_attrs) + return _make_instance_list(context, cls(), db_inst_list, + expected_attrs) + + @base.remotable_classmethod + def get_by_host_and_node(cls, context, host, node, expected_attrs=None): + db_inst_list = db.instance_get_all_by_host_and_node( + context, host, node) + return _make_instance_list(context, cls(), db_inst_list, + expected_attrs) + + @base.remotable_classmethod + def get_by_host_and_not_type(cls, context, host, type_id=None, + expected_attrs=None): + db_inst_list = db.instance_get_all_by_host_and_not_type( + context, host, type_id=type_id) + return _make_instance_list(context, cls(), db_inst_list, + expected_attrs) + + @base.remotable_classmethod + def get_hung_in_rebooting(cls, context, reboot_window, + expected_attrs=None): + db_inst_list = db.instance_get_all_hung_in_rebooting(context, + reboot_window) + return _make_instance_list(context, cls(), db_inst_list, + expected_attrs) diff --git a/nova/tests/objects/test_instance.py b/nova/tests/objects/test_instance.py index 194f5f90c..54e010a8a 100644 --- a/nova/tests/objects/test_instance.py +++ b/nova/tests/objects/test_instance.py @@ -196,3 +196,117 @@ class TestInstanceObject(test_objects._LocalTest, class TestRemoteInstanceObject(test_objects._RemoteTest, _TestInstanceObject): pass + + +class _TestInstanceListObject(object): + def fake_instance(self, id, updates=None): + fake_instance = fakes.stub_instance(id=2, + access_ipv4='1.2.3.4', + access_ipv6='::1') + fake_instance['scheduled_at'] = None + fake_instance['terminated_at'] = None + fake_instance['deleted_at'] = None + fake_instance['created_at'] = None + fake_instance['updated_at'] = None + fake_instance['launched_at'] = ( + fake_instance['launched_at'].replace( + tzinfo=iso8601.iso8601.Utc(), microsecond=0)) + fake_instance['info_cache'] = {'network_info': 'foo', + 'instance_uuid': fake_instance['uuid']} + fake_instance['deleted'] = 0 + if updates: + fake_instance.update(updates) + return fake_instance + + def test_get_all_by_filters(self): + fakes = [self.fake_instance(1), self.fake_instance(2)] + ctxt = context.get_admin_context() + self.mox.StubOutWithMock(db, 'instance_get_all_by_filters') + db.instance_get_all_by_filters(ctxt, {'foo': 'bar'}, 'uuid', 'asc', + None, None, + columns_to_join=['metadata']).AndReturn( + fakes) + self.mox.ReplayAll() + inst_list = instance.InstanceList.get_by_filters( + ctxt, {'foo': 'bar'}, 'uuid', 'asc', expected_attrs=['metadata']) + + for i in range(0, len(fakes)): + self.assertTrue(isinstance(inst_list.objects[i], + instance.Instance)) + self.assertEqual(inst_list.objects[i].uuid, fakes[i]['uuid']) + self.assertRemotes() + + def test_get_by_host(self): + fakes = [self.fake_instance(1), + self.fake_instance(2)] + ctxt = context.get_admin_context() + self.mox.StubOutWithMock(db, 'instance_get_all_by_host') + db.instance_get_all_by_host(ctxt, 'foo', + columns_to_join=None).AndReturn(fakes) + self.mox.ReplayAll() + inst_list = instance.InstanceList.get_by_host(ctxt, 'foo') + for i in range(0, len(fakes)): + self.assertTrue(isinstance(inst_list.objects[i], + instance.Instance)) + self.assertEqual(inst_list.objects[i].uuid, fakes[i]['uuid']) + self.assertEqual(inst_list.obj_what_changed(), set()) + self.assertRemotes() + + def test_get_by_host_and_node(self): + fakes = [self.fake_instance(1), + self.fake_instance(2)] + ctxt = context.get_admin_context() + self.mox.StubOutWithMock(db, 'instance_get_all_by_host_and_node') + db.instance_get_all_by_host_and_node(ctxt, 'foo', 'bar').AndReturn( + fakes) + self.mox.ReplayAll() + inst_list = instance.InstanceList.get_by_host_and_node(ctxt, 'foo', + 'bar') + for i in range(0, len(fakes)): + self.assertTrue(isinstance(inst_list.objects[i], + instance.Instance)) + self.assertEqual(inst_list.objects[i].uuid, fakes[i]['uuid']) + self.assertRemotes() + + def test_get_by_host_and_not_type(self): + fakes = [self.fake_instance(1), + self.fake_instance(2)] + ctxt = context.get_admin_context() + self.mox.StubOutWithMock(db, 'instance_get_all_by_host_and_not_type') + db.instance_get_all_by_host_and_not_type(ctxt, 'foo', + type_id='bar').AndReturn( + fakes) + self.mox.ReplayAll() + inst_list = instance.InstanceList.get_by_host_and_not_type(ctxt, 'foo', + 'bar') + for i in range(0, len(fakes)): + self.assertTrue(isinstance(inst_list.objects[i], + instance.Instance)) + self.assertEqual(inst_list.objects[i].uuid, fakes[i]['uuid']) + self.assertRemotes() + + def test_get_hung_in_rebooting(self): + fakes = [self.fake_instance(1), + self.fake_instance(2)] + dt = timeutils.isotime() + ctxt = context.get_admin_context() + self.mox.StubOutWithMock(db, 'instance_get_all_hung_in_rebooting') + db.instance_get_all_hung_in_rebooting(ctxt, dt).AndReturn( + fakes) + self.mox.ReplayAll() + inst_list = instance.InstanceList.get_hung_in_rebooting(ctxt, dt) + for i in range(0, len(fakes)): + self.assertTrue(isinstance(inst_list.objects[i], + instance.Instance)) + self.assertEqual(inst_list.objects[i].uuid, fakes[i]['uuid']) + self.assertRemotes() + + +class TestInstanceListObject(test_objects._LocalTest, + _TestInstanceListObject): + pass + + +class TestRemoteInstanceListObject(test_objects._RemoteTest, + _TestInstanceListObject): + pass -- cgit