Add unit tests to increase coverage

This patch proposes adding several new unit tests in effort to increase
the total unit test coverage.

Additionally, the ./tempest/serial_tests/ directory is not included in
coverage calculation. The reason being we don't want to test tests with
unit tests, which becomes a bit of an overkill.

Finally, there is an addition of a new option for the coverage program
called --fail-under. It will result the program in failure if the
coverage is under set percentage. Reason for this implementation is to
encourage writing unit tests for new code.

Change-Id: I804116413cd7d73cd7e5ae71409a8855ef937b88
This commit is contained in:
Katarina Strenkova 2023-08-29 15:17:57 +00:00
parent 702f0befce
commit 433dbdc4b9
5 changed files with 293 additions and 5 deletions

View File

@ -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/*

View File

@ -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.

View File

@ -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):

View File

@ -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'},

View File

@ -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}