diff --git a/.coveragerc b/.coveragerc index 449e62c2d3..398755be4b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,4 +1,4 @@ [run] branch = True source = tempest -omit = tempest/tests/*,tempest/scenario/test_*.py,tempest/api/* +omit = tempest/tests/*,tempest/scenario/test_*.py,tempest/api/*,tempest/serial_tests/* diff --git a/tempest/tests/common/test_compute.py b/tempest/tests/common/test_compute.py index 142bb081e9..4d933cd322 100644 --- a/tempest/tests/common/test_compute.py +++ b/tempest/tests/common/test_compute.py @@ -17,8 +17,9 @@ from unittest import mock from urllib import parse as urlparse - from tempest.common import compute +from tempest import exceptions +from tempest.lib import exceptions as lib_exc from tempest.tests import base @@ -28,6 +29,58 @@ class TestCompute(base.TestCase): self.client_sock = mock.Mock() self.url = urlparse.urlparse("http://www.fake.com:80") + @mock.patch('tempest.common.compute.' 'config.CONF.validation') + def test_get_server_ip_connect_method_floating(self, mock_conf): + fake_server = {'id': 'fake-uuid'} + fake_vr = {'floating_ip': {'ip': '10.10.10.1'}} + mock_conf.connect_method = 'floating' + + fake_server_ip = compute.get_server_ip(fake_server, fake_vr) + self.assertEqual(fake_server_ip, '10.10.10.1') + + # assert that InvalidParam is raised when validadation + # resources are not set + self.assertRaises(lib_exc.InvalidParam, + compute.get_server_ip, + fake_server) + + @mock.patch('tempest.common.compute.' 'config.CONF.validation') + def test_get_server_ip_connect_method_fixed(self, mock_conf): + fake_server = {'id': 'fake-uuid', + 'addresses': { + 'private': [ + {'addr': '192.168.0.3', + 'version': 4}]}} + mock_conf.connect_method = 'fixed' + mock_conf.network_for_ssh = 'private' + mock_conf.ip_version_for_ssh = 4 + + fake_server_ip = compute.get_server_ip(fake_server) + self.assertEqual(fake_server_ip, '192.168.0.3') + + fake_server_v6 = {'id': 'fake-uuid', + 'addresses': { + 'private': [ + {'addr': '2345:0425:2CA1::0567:5673:23b5', + 'version': 6}]}} + # assert when server is unreachable + self.assertRaises(exceptions.ServerUnreachable, + compute.get_server_ip, + fake_server_v6) + + @mock.patch('tempest.common.compute.' 'config.CONF.validation') + def test_get_server_ip_invalid_config(self, mock_conf): + fake_server = {'id': 'fake-uuid', + 'addresses': { + 'private': [ + {'addr': '192.168.0.3', + 'version': 4}]}} + mock_conf.connect_method = 'fake-method' + # assert when the connection method is not correctly set + self.assertRaises(lib_exc.InvalidConfiguration, + compute.get_server_ip, + fake_server) + def test_rfp_frame_not_cached(self): # rfp negotiation frame arrived separately after upgrade # response, so it's not cached. diff --git a/tempest/tests/common/test_waiters.py b/tempest/tests/common/test_waiters.py index 93c949e64d..f194173961 100755 --- a/tempest/tests/common/test_waiters.py +++ b/tempest/tests/common/test_waiters.py @@ -27,6 +27,78 @@ from tempest.tests import base import tempest.tests.utils as utils +class TestServerWaiters(base.TestCase): + def setUp(self): + super(TestServerWaiters, self).setUp() + self.client = mock.MagicMock() + self.client.build_timeout = 1 + self.client.build_interval = 1 + + def test_wait_for_server_status(self): + fake_server = {'id': 'fake-uuid', + 'status': 'ACTIVE'} + self.client.show_server.return_value = ({'server': fake_server}) + start_time = int(time.time()) + waiters.wait_for_server_status( + self.client, fake_server['id'], 'ACTIVE') + end_time = int(time.time()) + # Ensure waiter returns before build_timeout + self.assertLess((end_time - start_time), 10) + + def test_wait_for_server_status_build(self): + fake_server = {'id': 'fake-uuid', + 'status': 'BUILD'} + self.client.show_server.return_value = ({'server': fake_server}) + start_time = int(time.time()) + waiters.wait_for_server_status(self.client, fake_server['id'], 'BUILD') + end_time = int(time.time()) + # Ensure waiter returns before build_timeout + self.assertLess((end_time - start_time), 10) + + def test_wait_for_server_status_timeout(self): + time_mock = self.patch('time.time') + time_mock.side_effect = utils.generate_timeout_series(1) + + fake_server = {'id': 'fake-uuid', + 'status': 'SAVING'} + self.client.show_server.return_value = ({'server': fake_server}) + self.assertRaises(lib_exc.TimeoutException, + waiters.wait_for_server_status, + self.client, fake_server['id'], 'ACTIVE') + + def test_wait_for_server_status_error_on_server_build(self): + fake_server = {'id': 'fake-uuid', + 'status': 'ERROR'} + self.client.show_server.return_value = ({'server': fake_server}) + self.assertRaises(exceptions.BuildErrorException, + waiters.wait_for_server_status, + self.client, fake_server['id'], 'ACTIVE') + + def test_wait_for_server_termination(self): + fake_server = {'id': 'fake-uuid', + 'status': 'ACTIVE'} + self.client.show_server.side_effect = lib_exc.NotFound + waiters.wait_for_server_termination(self.client, fake_server['id']) + + def test_wait_for_server_termination_timeout(self): + time_mock = self.patch('time.time') + time_mock.side_effect = utils.generate_timeout_series(1) + + fake_server = {'id': 'fake-uuid', + 'status': 'ACTIVE'} + self.assertRaises(lib_exc.TimeoutException, + waiters.wait_for_server_termination, + self.client, fake_server['id']) + + def test_wait_for_server_termination_error_status(self): + fake_server = {'id': 'fake-uuid', + 'status': 'ERROR'} + self.client.show_server.return_value = ({'server': fake_server}) + self.assertRaises(lib_exc.DeleteErrorException, + waiters.wait_for_server_termination, + self.client, fake_server['id']) + + class TestImageWaiters(base.TestCase): def setUp(self): super(TestImageWaiters, self).setUp() @@ -145,6 +217,15 @@ class TestImageWaiters(base.TestCase): waiters.wait_for_image_copied_to_stores, self.client, 'fake_image_id') + def test_wait_for_image_copied_to_stores_status_killed(self): + self.client.show_image.return_value = ({ + 'status': 'killed', + 'os_glance_importing_to_stores': None, + 'os_glance_failed_import': 'fake_os_glance_failed_import'}) + self.assertRaises(exceptions.ImageKilledException, + waiters.wait_for_image_copied_to_stores, + self.client, 'fake_image_id') + def test_wait_for_image_tasks_status(self): self.client.show_image_tasks.return_value = ({ 'tasks': [{'status': 'success'}]}) @@ -168,6 +249,28 @@ class TestImageWaiters(base.TestCase): waiters.wait_for_image_tasks_status, self.client, 'fake_image_id', 'success') + def test_wait_for_tasks_status(self): + self.client.show_tasks.return_value = ({ + 'status': 'success'}) + start_time = int(time.time()) + waiters.wait_for_tasks_status( + self.client, 'fake_task_id', 'success') + end_time = int(time.time()) + # Ensure waiter returns before build_timeout + self.assertLess((end_time - start_time), 10) + + def test_wait_for_tasks_status_timeout(self): + time_mock = self.patch('time.time') + self.patch('time.time', side_effect=[0., 1.]) + time_mock.side_effect = utils.generate_timeout_series(1) + + self.client.show_tasks.return_value = ( + {'status': 'success'}, + {'status': 'processing'}) + self.assertRaises(lib_exc.TimeoutException, + waiters.wait_for_tasks_status, + self.client, 'fake_task_id', 'success') + class TestInterfaceWaiters(base.TestCase): @@ -366,6 +469,31 @@ class TestVolumeWaiters(base.TestCase): mock.call(mock.sentinel.volume_id), mock.call(mock.sentinel.volume_id)]) + def test_wait_for_volume_retype(self): + fake_volume = {'volume_type': {'id': 'fake-uuid'}} + show_volume = mock.Mock(return_value={'volume': fake_volume}) + client = mock.Mock(resource_type="volume", + build_interval=1, + build_timeout=1, + show_volume=show_volume) + waiters.wait_for_volume_retype( + client, mock.sentinel.volume_id, fake_volume['volume_type']) + + def test_wait_for_volume_retype_timeout(self): + fake_volume = {'volume_type': {'id': 'fake-uuid'}} + show_volume = mock.Mock(return_value={'volume': fake_volume}) + client = mock.Mock(resource_type="volume", + build_interval=1, + build_timeout=1, + show_volume=show_volume) + + self.patch('time.time', side_effect=[0., client.build_timeout + 1.]) + self.patch('time.sleep') + self.assertRaises(lib_exc.TimeoutException, + waiters.wait_for_volume_retype, + client, mock.sentinel.volume_id, + 'fake_volume_type') + @mock.patch.object(time, 'sleep') def test_wait_for_volume_status_error_restoring(self, mock_sleep): # Tests that the wait method raises VolumeRestoreErrorException if @@ -450,7 +578,25 @@ class TestVolumeWaiters(base.TestCase): mock.call(uuids.volume_id), mock.call(uuids.volume_id)]) - def test_wait_for_volume_attachment(self): + def test_wait_for_volume_attachment_create_timeout(self): + show_volume = mock.MagicMock(return_value={ + 'volume': {'attachments': [ + {'attachment_id': uuids.attachment_id, + 'server_id': uuids.server_id, + 'volume_id': uuids.volume_id}]}}) + client = mock.Mock(spec=volumes_client.VolumesClient, + build_interval=1, + build_timeout=1, + show_volume=show_volume) + self.patch('time.time', side_effect=[0., client.build_timeout + 1.]) + self.patch('time.sleep') + # Assert that a timeout is raised if the attachment is not + # created within required time + self.assertRaises(lib_exc.TimeoutException, + waiters.wait_for_volume_attachment_create, + client, 'fake_volume_id', 'fake_server_id') + + def test_wait_for_volume_attachment_remove(self): vol_detached = {'volume': {'attachments': []}} vol_attached = {'volume': {'attachments': [ {'attachment_id': uuids.attachment_id}]}} @@ -469,7 +615,7 @@ class TestVolumeWaiters(base.TestCase): mock.call(uuids.volume_id), mock.call(uuids.volume_id)]) - def test_wait_for_volume_attachment_timeout(self): + def test_wait_for_volume_attachment_remove_timeout(self): show_volume = mock.MagicMock(return_value={ 'volume': {'attachments': [ {'attachment_id': uuids.attachment_id}]}}) @@ -635,6 +781,67 @@ class TestVolumeWaiters(base.TestCase): .1 ) + def test_wait_for_caching(self): + mock_client = mock.Mock( + build_interval=1, + build_timeout=1 + ) + mock_cache_client = mock.Mock() + mock_cache_client.list_cache.return_value = { + "cached_images": [{ + "image_id": 'fake_image_id'}]} + waiters.wait_for_caching( + mock_client, mock_cache_client, 'fake_image_id') + + def test_wait_for_caching_timeout(self): + time_mock = self.patch('time.time') + time_mock.side_effect = utils.generate_timeout_series(1) + + mock_client = mock.Mock( + build_interval=1, + build_timeout=1 + ) + mock_cache_client = mock.Mock() + mock_cache_client.list_cache.return_value = { + "cached_images": [{ + "image_id": 'fake_image_id'}]} + # Assert that TimeoutException is raised when the image + # failed to cache in time + self.assertRaises( + lib_exc.TimeoutException, + waiters.wait_for_caching, + mock_client, + mock_cache_client, + 'fake_image_id' + ) + + def test_wait_for_object_create(self): + mock_object_client = mock.Mock( + build_interval=1, + build_timeout=1 + ) + waiters.wait_for_object_create( + mock_object_client, 'fake_container', 'fake_object') + + def test_wait_for_object_create_timeout(self): + time_mock = self.patch('time.time') + time_mock.side_effect = utils.generate_timeout_series(1) + + mock_object_client = mock.Mock( + build_interval=1, + build_timeout=1 + ) + # Assert that TimeoutException is raised when the object is not + # created in time + self.assertRaises( + lib_exc.TimeoutException, + waiters.wait_for_object_create, + mock_object_client, + 'fake_container', + 'fake_object', + .1 + ) + class TestPortCreationWaiter(base.TestCase): def test_wait_for_port_status(self): diff --git a/tempest/tests/lib/common/test_cred_client.py b/tempest/tests/lib/common/test_cred_client.py index 7ea660b695..e44c5ede81 100644 --- a/tempest/tests/lib/common/test_cred_client.py +++ b/tempest/tests/lib/common/test_cred_client.py @@ -38,6 +38,13 @@ class TestCredClientV2(base.TestCase): self.projects_client.create_tenant.assert_called_once_with( name='fake_name', description='desc') + def test_show_project(self): + self.projects_client.show_tenant.return_value = { + 'tenant': 'a_tenant' + } + res = self.creds_client.show_project('fake_id') + self.assertEqual('a_tenant', res) + def test_delete_project(self): self.creds_client.delete_project('fake_id') self.projects_client.delete_tenant.assert_called_once_with( @@ -79,11 +86,32 @@ class TestCredClientV3(base.TestCase): self.projects_client.create_project.assert_called_once_with( name='fake_name', description='desc', domain_id='fake_domain_id') + def test_show_project(self): + self.projects_client.show_project.return_value = { + 'project': 'a_tenant' + } + res = self.creds_client.show_project('fake_id') + self.assertEqual('a_tenant', res) + def test_delete_project(self): self.creds_client.delete_project('fake_id') self.projects_client.delete_project.assert_called_once_with( 'fake_id') + def test_create_domain(self): + self.domains_client.create_domain.return_value = { + 'domain': 'a_tenant' + } + res = self.creds_client.create_domain('fake_name', 'desc') + self.assertEqual('a_tenant', res) + self.domains_client.create_domain.assert_called_once_with( + name='fake_name', description='desc') + + def test_delete_domain(self): + self.creds_client.delete_domain('fake_id') + self.domains_client.delete_domain.assert_called_once_with( + 'fake_id') + def test_get_credentials(self): ret = self.creds_client.get_credentials( {'name': 'some_user', 'id': 'fake_id'}, diff --git a/tox.ini b/tox.ini index 47ef5ebc29..fa32ba3669 100644 --- a/tox.ini +++ b/tox.ini @@ -64,7 +64,7 @@ commands = coverage combine coverage html -d cover coverage xml -o cover/coverage.xml - coverage report + coverage report -m --fail-under=76 [testenv:debug] commands = oslo_debug_helper -t tempest/tests {posargs}