From fc453c36297e03b038cb377419a1ec124e255bda Mon Sep 17 00:00:00 2001 From: Trevor McCasland Date: Mon, 27 Jun 2016 09:58:10 -0500 Subject: [PATCH] Improve coverage in guestagent and backup models Coverage improvement overview: trove/backup/models.py 88% -> 99% trove/guestagent/models.py 93% -> 100% trove/backup/models.py cases covered: Backup.validate_can_perform_action: * raise exception.DatastoreOperationNotSupported Backup.create: * raise exception.ClusterInstanceOperationNotSupported * raise exception.BackupCreationError Backup.verify_swift_auth_token: * raise exception.SwiftAuthError * raise exception.SwiftNotFound DBBackup.filename: * raise ValueError DBBackup.check_swift_object_exist: * raise exception.RestoreBackupIntegrityError * except ClientException as e: return False raise exception.SwiftAuthError trove/guestagent/models.py cases covered: AgentHeartBeat.create: * raise exception.InvalidModelError AgentHeartBeat.save: * raise exception.InvalidModelError Change-Id: I9ca867b66f96ae1d4aa257342d96e043b9058e5d --- .../unittests/backup/test_backup_models.py | 89 ++++++++++++++++++- .../test_agent_heartbeats_models.py | 22 +++++ 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/trove/tests/unittests/backup/test_backup_models.py b/trove/tests/unittests/backup/test_backup_models.py index 1851f793a6..da03407922 100644 --- a/trove/tests/unittests/backup/test_backup_models.py +++ b/trove/tests/unittests/backup/test_backup_models.py @@ -16,12 +16,15 @@ import datetime from mock import DEFAULT from mock import MagicMock from mock import patch +from swiftclient.client import ClientException from trove.backup import models from trove.backup import state from trove.common import context from trove.common import exception +from trove.common import remote from trove.common import utils +from trove.db.models import DatabaseModelBase from trove.instance import models as instance_models from trove.taskmanager import api from trove.tests.unittests import trove_testtools @@ -190,8 +193,6 @@ class BackupCreateTest(trove_testtools.TestCase): instance = MagicMock() with patch.object(instance_models.BuiltInstance, 'load', return_value=instance): - instance.validate_can_perform_action = MagicMock( - return_value=None) with patch.object( models.Backup, 'validate_can_perform_action', side_effect=exception.DatastoreOperationNotSupported @@ -201,6 +202,39 @@ class BackupCreateTest(trove_testtools.TestCase): self.context, self.instance_id, BACKUP_NAME, BACKUP_DESC) + def test_create_backup_cluster_instance_operation_not_supported(self): + instance = MagicMock() + instance.cluster_id = 'bad_id' + with patch.object(instance_models.BuiltInstance, 'load', + return_value=instance),\ + patch.object(models.Backup, 'validate_can_perform_action', + return_value=None),\ + patch.object(models.Backup, 'verify_swift_auth_token', + return_value=None): + self.assertRaises(exception.ClusterInstanceOperationNotSupported, + models.Backup.create, + self.context, self.instance_id, + BACKUP_NAME, BACKUP_DESC) + + def test_create_backup_creation_error(self): + instance = MagicMock() + instance.cluster_id = None + with patch.object(instance_models.BuiltInstance, 'load', + return_value=instance),\ + patch.object(models.Backup, 'validate_can_perform_action', + return_value=None),\ + patch.object(models.Backup, 'verify_swift_auth_token', + return_value=None),\ + patch.object(DatabaseModelBase, 'is_valid', + return_value=False),\ + patch('trove.quota.quota.QuotaEngine.reserve', + return_value=[]): + DatabaseModelBase.errors = {} + self.assertRaises(exception.BackupCreationError, + models.Backup.create, + self.context, self.instance_id, + BACKUP_NAME, BACKUP_DESC) + class BackupDeleteTest(trove_testtools.TestCase): def setUp(self): @@ -357,6 +391,57 @@ class BackupORMTest(trove_testtools.TestCase): def test_filename(self): self.assertEqual(BACKUP_FILENAME, self.backup.filename) + def test_filename_bad(self): + + def _set_bad_filename(): + self.backup.location = 'bad' + self.backup.filename + + self.assertRaises(ValueError, _set_bad_filename) + + def test_check_swift_object_exist_integrity_error(self): + mock_client = MagicMock() + mock_client.head_object.return_value = {'etag': ''} + with patch.object(remote, 'get_endpoint', return_value=None),\ + patch.object(remote, 'Connection', + return_value=mock_client): + self.assertRaises(exception.RestoreBackupIntegrityError, + self.backup.check_swift_object_exist, + self.context, True) + + def test_check_swift_object_exist_client_exception(self): + with patch.object(remote, 'get_endpoint', return_value=None),\ + patch.object(remote, 'Connection', + side_effect=ClientException(self.context.tenant)): + self.assertRaises(exception.SwiftAuthError, + self.backup.check_swift_object_exist, + self.context) + + def test_check_swift_object_exist_client_exception_404(self): + e = ClientException(self.context.tenant) + e.http_status = 404 + with patch.object(remote, 'get_endpoint', return_value=None),\ + patch.object(remote, 'Connection', + side_effect=e): + self.assertFalse( + self.backup.check_swift_object_exist(self.context)) + + def test_swift_auth_token_client_exception(self): + with patch.object(remote, 'get_endpoint', return_value=None),\ + patch.object(remote, 'Connection', + side_effect=ClientException(self.context.tenant)): + self.assertRaises(exception.SwiftAuthError, + models.Backup.verify_swift_auth_token, + self.context) + + def test_swift_auth_token_no_service_endpoint(self): + with patch.object(remote, 'get_endpoint', return_value=None),\ + patch.object(remote, 'Connection', + side_effect=exception.NoServiceEndpoint): + self.assertRaises(exception.SwiftNotFound, + models.Backup.verify_swift_auth_token, + self.context) + class PaginationTests(trove_testtools.TestCase): diff --git a/trove/tests/unittests/guestagent/test_agent_heartbeats_models.py b/trove/tests/unittests/guestagent/test_agent_heartbeats_models.py index 92664726b3..2b68ba1dde 100644 --- a/trove/tests/unittests/guestagent/test_agent_heartbeats_models.py +++ b/trove/tests/unittests/guestagent/test_agent_heartbeats_models.py @@ -11,6 +11,7 @@ # See the License for the specific language governing permissions and # limitations under the License. +from mock import Mock from mock import patch import uuid @@ -63,6 +64,27 @@ class AgentHeartBeatTest(trove_testtools.TestCase): self.assertIsNotNone(heartbeat.guest_agent_version) self.assertEqual("1.2.3", heartbeat.guest_agent_version) + def test_create_invalid_model_error(self): + """ + Test the creation failure of a new agent heartbeat record + """ + instance = Mock() + instance.errors = {} + instance.is_valid = Mock(return_value=False) + with patch.object(AgentHeartBeat, 'save', return_value=instance): + self.assertRaises(exception.InvalidModelError, + AgentHeartBeat.create) + + def test_save_invalid_model_error(self): + """ + Test the save failure of an agent heartbeat record + """ + instance_id = str(uuid.uuid4()) + heartbeat = AgentHeartBeat.create( + instance_id=instance_id) + with patch.object(AgentHeartBeat, 'is_valid', return_value=False): + self.assertRaises(exception.InvalidModelError, heartbeat.save) + def test_find_by_instance_id(self): """ Test to retrieve a guest agents by its id