From b8b70e25679abea52a5ee5fd7eeb298a13e55e66 Mon Sep 17 00:00:00 2001 From: Andrew Laski Date: Tue, 31 May 2016 16:29:24 -0400 Subject: [PATCH] Update functional tests for fixtures 3 In order to use the 3.0.0 release of the fixtures library some tests needed to be updated in order to be compatible with 1.4 and 3.0. Most failures with 3.0 were due to using bound methods of a class to patch another class. This requires a different signature on the method used for patching between the fixtures versions. Moving the methods to be functions addresses this for the cases where the test method does not need to access the class it was defined on. For test_networks a different tact was needed. Because the methods used for patching require accessing state on their defined class a proxy method is introduced. This proxy method captures and discards the 'self' parameter from the call point of the patched method. By doing so the patching methods can have the same signature for multiple fixtures versions. Change-Id: I9c5635d0930b091e1ae0a1439d687dd20a0ff939 --- .../api_sample_tests/test_instance_actions.py | 18 +-- .../api_sample_tests/test_migrations.py | 85 +++++++------- .../api_sample_tests/test_networks.py | 36 ++++-- .../api_sample_tests/test_volumes.py | 106 +++++++++--------- 4 files changed, 134 insertions(+), 111 deletions(-) diff --git a/nova/tests/functional/api_sample_tests/test_instance_actions.py b/nova/tests/functional/api_sample_tests/test_instance_actions.py index 175c6f0b5452..eda2dc5a98a6 100644 --- a/nova/tests/functional/api_sample_tests/test_instance_actions.py +++ b/nova/tests/functional/api_sample_tests/test_instance_actions.py @@ -38,11 +38,6 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21): 'contrib.instance_actions.Instance_actions') return f - def _fake_get(self, context, instance_uuid, expected_attrs=None, - want_objects=True): - return fake_instance.fake_instance_obj( - None, **{'uuid': instance_uuid}) - def setUp(self): super(ServerActionsSampleJsonTest, self).setUp() self.api.microversion = self.microversion @@ -50,6 +45,11 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21): self.events = fake_server_actions.FAKE_EVENTS self.instance = test_utils.get_test_instance(obj=True) + def _fake_get(stub_self, context, instance_uuid, expected_attrs=None, + want_objects=True): + return fake_instance.fake_instance_obj( + None, **{'uuid': instance_uuid}) + def fake_instance_action_get_by_request_id(context, uuid, request_id): return copy.deepcopy(self.actions[uuid][request_id]) @@ -70,7 +70,7 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21): fake_instance_action_events_get) self.stub_out('nova.db.instance_get_by_uuid', fake_instance_get_by_uuid) - self.stub_out('nova.compute.api.API.get', self._fake_get) + self.stub_out('nova.compute.api.API.get', _fake_get) def test_instance_action_get(self): fake_uuid = fake_server_actions.FAKE_UUID @@ -104,9 +104,3 @@ class ServerActionsSampleJsonTest(api_sample_base.ApiSampleTestBaseV21): class ServerActionsV221SampleJsonTest(ServerActionsSampleJsonTest): microversion = '2.21' scenarios = [('v2_21', {'api_major_version': 'v2.1'})] - - def _fake_get(self, context, instance_uuid, expected_attrs=None, - want_objects=True): - self.assertEqual('yes', context.read_deleted) - return fake_instance.fake_instance_obj( - None, **{'uuid': instance_uuid}) diff --git a/nova/tests/functional/api_sample_tests/test_migrations.py b/nova/tests/functional/api_sample_tests/test_migrations.py index 6665047d795f..edaf31775c9e 100644 --- a/nova/tests/functional/api_sample_tests/test_migrations.py +++ b/nova/tests/functional/api_sample_tests/test_migrations.py @@ -29,6 +29,48 @@ INSTANCE_UUID_1 = "8600d31b-d1a1-4632-b2ff-45c2be1a70ff" INSTANCE_UUID_2 = "9128d044-7b61-403e-b766-7547076ff6c1" +def _stub_migrations(stub_self, context, filters): + fake_migrations = [ + { + 'id': 1234, + 'source_node': 'node1', + 'dest_node': 'node2', + 'source_compute': 'compute1', + 'dest_compute': 'compute2', + 'dest_host': '1.2.3.4', + 'status': 'Done', + 'instance_uuid': 'instance_id_123', + 'old_instance_type_id': 1, + 'new_instance_type_id': 2, + 'migration_type': 'resize', + 'hidden': False, + 'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2), + 'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2), + 'deleted_at': None, + 'deleted': False + }, + { + 'id': 5678, + 'source_node': 'node10', + 'dest_node': 'node20', + 'source_compute': 'compute10', + 'dest_compute': 'compute20', + 'dest_host': '5.6.7.8', + 'status': 'Done', + 'instance_uuid': 'instance_id_456', + 'old_instance_type_id': 5, + 'new_instance_type_id': 6, + 'migration_type': 'resize', + 'hidden': False, + 'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2), + 'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2), + 'deleted_at': None, + 'deleted': False + } + ] + return fake_migrations + + class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV21): ADMIN_API = True extension_name = "os-migrations" @@ -40,51 +82,10 @@ class MigrationsSamplesJsonTest(api_sample_base.ApiSampleTestBaseV21): 'nova.api.openstack.compute.contrib.migrations.Migrations') return f - def _stub_migrations(self, context, filters): - fake_migrations = [ - { - 'id': 1234, - 'source_node': 'node1', - 'dest_node': 'node2', - 'source_compute': 'compute1', - 'dest_compute': 'compute2', - 'dest_host': '1.2.3.4', - 'status': 'Done', - 'instance_uuid': 'instance_id_123', - 'old_instance_type_id': 1, - 'new_instance_type_id': 2, - 'migration_type': 'resize', - 'hidden': False, - 'created_at': datetime.datetime(2012, 10, 29, 13, 42, 2), - 'updated_at': datetime.datetime(2012, 10, 29, 13, 42, 2), - 'deleted_at': None, - 'deleted': False - }, - { - 'id': 5678, - 'source_node': 'node10', - 'dest_node': 'node20', - 'source_compute': 'compute10', - 'dest_compute': 'compute20', - 'dest_host': '5.6.7.8', - 'status': 'Done', - 'instance_uuid': 'instance_id_456', - 'old_instance_type_id': 5, - 'new_instance_type_id': 6, - 'migration_type': 'resize', - 'hidden': False, - 'created_at': datetime.datetime(2013, 10, 22, 13, 42, 2), - 'updated_at': datetime.datetime(2013, 10, 22, 13, 42, 2), - 'deleted_at': None, - 'deleted': False - } - ] - return fake_migrations - def setUp(self): super(MigrationsSamplesJsonTest, self).setUp() self.stub_out('nova.compute.api.API.get_migrations', - self._stub_migrations) + _stub_migrations) def test_get_migrations(self): response = self._do_get('os-migrations') diff --git a/nova/tests/functional/api_sample_tests/test_networks.py b/nova/tests/functional/api_sample_tests/test_networks.py index 2d70b4dc7bc2..aa87ac56d847 100644 --- a/nova/tests/functional/api_sample_tests/test_networks.py +++ b/nova/tests/functional/api_sample_tests/test_networks.py @@ -20,6 +20,25 @@ from nova.tests.unit.api.openstack.compute import test_networks CONF = nova.conf.CONF +def _fixtures_passthrough(method_name): + # This compensates for how fixtures 3.x handles the signatures of + # MonkeyPatched functions vs fixtures < 3.x. In fixtures 3 if a bound + # method is patched in for a bound method then both objects will be passed + # in when called. This means the patch method should have the signature of + # (self, targetself, *args, **kwargs). However that will not work for + # fixtures < 3. This method captures self from the call point and discards + # it since it's not needed. + fake_network_api = test_networks.FakeNetworkAPI() + method = getattr(fake_network_api, method_name) + + def call(self, *args, **kwargs): + # self is the nova.network.api.API object that has been patched + # method is bound to FakeNetworkAPI so that will be passed in as self + return method(*args, **kwargs) + + return call + + class NetworksJsonTests(api_sample_base.ApiSampleTestBaseV21): ADMIN_API = True extension_name = "os-networks" @@ -35,15 +54,18 @@ class NetworksJsonTests(api_sample_base.ApiSampleTestBaseV21): def setUp(self): super(NetworksJsonTests, self).setUp() - fake_network_api = test_networks.FakeNetworkAPI() - self.stub_out("nova.network.api.API.get_all", fake_network_api.get_all) - self.stub_out("nova.network.api.API.get", fake_network_api.get) + self.stub_out("nova.network.api.API.get_all", + _fixtures_passthrough('get_all')) + self.stub_out("nova.network.api.API.get", + _fixtures_passthrough('get')) self.stub_out("nova.network.api.API.associate", - fake_network_api.associate) - self.stub_out("nova.network.api.API.delete", fake_network_api.delete) - self.stub_out("nova.network.api.API.create", fake_network_api.create) + _fixtures_passthrough('associate')) + self.stub_out("nova.network.api.API.delete", + _fixtures_passthrough('delete')) + self.stub_out("nova.network.api.API.create", + _fixtures_passthrough('create')) self.stub_out("nova.network.api.API.add_network_to_project", - fake_network_api.add_network_to_project) + _fixtures_passthrough('add_network_to_project')) def test_network_list(self): response = self._do_get('os-networks') diff --git a/nova/tests/functional/api_sample_tests/test_volumes.py b/nova/tests/functional/api_sample_tests/test_volumes.py index 9ae6a5d23f0f..ba1f8acec3a6 100644 --- a/nova/tests/functional/api_sample_tests/test_volumes.py +++ b/nova/tests/functional/api_sample_tests/test_volumes.py @@ -89,6 +89,56 @@ class SnapshotsSampleJsonTests(api_sample_base.ApiSampleTestBaseV21): self._verify_response('snapshots-show-resp', subs, response, 200) +def _get_volume_id(): + return 'a26887c6-c47b-4654-abb5-dfadf7d3f803' + + +def _stub_volume(id, displayname="Volume Name", + displaydesc="Volume Description", size=100): + volume = { + 'id': id, + 'size': size, + 'availability_zone': 'zone1:host1', + 'status': 'in-use', + 'attach_status': 'attached', + 'name': 'vol name', + 'display_name': displayname, + 'display_description': displaydesc, + 'created_at': datetime.datetime(2008, 12, 1, 11, 1, 55), + 'snapshot_id': None, + 'volume_type_id': 'fakevoltype', + 'volume_metadata': [], + 'volume_type': {'name': 'Backup'}, + 'multiattach': False, + 'attachments': {'3912f2b4-c5ba-4aec-9165-872876fe202e': + {'mountpoint': '/', + 'attachment_id': + 'a26887c6-c47b-4654-abb5-dfadf7d3f803' + } + } + } + return volume + + +def _stub_volume_get(stub_self, context, volume_id): + return _stub_volume(volume_id) + + +def _stub_volume_delete(stub_self, context, *args, **param): + pass + + +def _stub_volume_get_all(stub_self, context, search_opts=None): + id = _get_volume_id() + return [_stub_volume(id)] + + +def _stub_volume_create(stub_self, context, size, name, description, + snapshot, **param): + id = _get_volume_id() + return _stub_volume(id) + + class VolumesSampleJsonTest(test_servers.ServersSampleBase): extension_name = "os-volumes" @@ -99,60 +149,16 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): 'nova.api.openstack.compute.contrib.volumes.Volumes') return f - def _get_volume_id(self): - return 'a26887c6-c47b-4654-abb5-dfadf7d3f803' - - def _stub_volume(self, id, displayname="Volume Name", - displaydesc="Volume Description", size=100): - volume = { - 'id': id, - 'size': size, - 'availability_zone': 'zone1:host1', - 'status': 'in-use', - 'attach_status': 'attached', - 'name': 'vol name', - 'display_name': displayname, - 'display_description': displaydesc, - 'created_at': datetime.datetime(2008, 12, 1, 11, 1, 55), - 'snapshot_id': None, - 'volume_type_id': 'fakevoltype', - 'volume_metadata': [], - 'volume_type': {'name': 'Backup'}, - 'multiattach': False, - 'attachments': {'3912f2b4-c5ba-4aec-9165-872876fe202e': - {'mountpoint': '/', - 'attachment_id': - 'a26887c6-c47b-4654-abb5-dfadf7d3f803' - } - } - } - return volume - - def _stub_volume_get(self, context, volume_id): - return self._stub_volume(volume_id) - - def _stub_volume_delete(self, context, *args, **param): - pass - - def _stub_volume_get_all(self, context, search_opts=None): - id = self._get_volume_id() - return [self._stub_volume(id)] - - def _stub_volume_create(self, context, size, name, description, snapshot, - **param): - id = self._get_volume_id() - return self._stub_volume(id) - def setUp(self): super(VolumesSampleJsonTest, self).setUp() fakes.stub_out_networking(self) fakes.stub_out_rate_limiting(self.stubs) self.stub_out("nova.volume.cinder.API.delete", - self._stub_volume_delete) - self.stub_out("nova.volume.cinder.API.get", self._stub_volume_get) + _stub_volume_delete) + self.stub_out("nova.volume.cinder.API.get", _stub_volume_get) self.stub_out("nova.volume.cinder.API.get_all", - self._stub_volume_get_all) + _stub_volume_get_all) def _post_volume(self): subs_req = { @@ -161,7 +167,7 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): } self.stub_out("nova.volume.cinder.API.create", - self._stub_volume_create) + _stub_volume_create) response = self._do_post('os-volumes', 'os-volumes-post-req', subs_req) self._verify_response('os-volumes-post-resp', subs_req, response, 200) @@ -171,7 +177,7 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): 'volume_name': "Volume Name", 'volume_desc': "Volume Description", } - vol_id = self._get_volume_id() + vol_id = _get_volume_id() response = self._do_get('os-volumes/%s' % vol_id) self._verify_response('os-volumes-get-resp', subs, response, 200) @@ -198,7 +204,7 @@ class VolumesSampleJsonTest(test_servers.ServersSampleBase): def test_volumes_delete(self): self._post_volume() - vol_id = self._get_volume_id() + vol_id = _get_volume_id() response = self._do_delete('os-volumes/%s' % vol_id) self.assertEqual(202, response.status_code) self.assertEqual('', response.content)