Added more unit tests to OpenNebula driver

Also fixed some minor bugs found along the way.
This commit is contained in:
rallytime 2015-08-06 17:22:51 -06:00
parent bf536ce646
commit a639c28050
2 changed files with 477 additions and 57 deletions

View File

@ -498,7 +498,14 @@ def get_cluster_id(kwargs=None, call=None):
'The get_cluster_id function requires a name.'
)
return list_clusters()[name]['id']
try:
ret = list_clusters()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The cluster \'{0}\' could not be found'.format(name)
)
return ret
def get_datastore_id(kwargs=None, call=None):
@ -527,7 +534,14 @@ def get_datastore_id(kwargs=None, call=None):
'The get_datastore_id function requires a name.'
)
return list_datastores()[name]['id']
try:
ret = list_datastores()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The datastore \'{0}\' could not be found.'.format(name)
)
return ret
def get_host_id(kwargs=None, call=None):
@ -556,7 +570,14 @@ def get_host_id(kwargs=None, call=None):
'The get_host_id function requires a name.'
)
return avail_locations()[name]['id']
try:
ret = avail_locations()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The host \'{0}\' could not be found'.format(name)
)
return ret
def get_image(vm_):
@ -604,7 +625,14 @@ def get_image_id(kwargs=None, call=None):
'The get_image_id function requires a name.'
)
return avail_images()[name]['id']
try:
ret = avail_images()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The image \'{0}\' could not be found'.format(name)
)
return ret
def get_location(vm_):
@ -659,7 +687,14 @@ def get_secgroup_id(kwargs=None, call=None):
'The get_secgroup_id function requires a \'name\'.'
)
return list_security_groups()[name]['id']
try:
ret = list_security_groups()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The security group \'{0}\' could not be found.'.format(name)
)
return ret
def get_template_id(kwargs=None, call=None):
@ -688,7 +723,14 @@ def get_template_id(kwargs=None, call=None):
'The get_template_id function requires a \'name\'.'
)
return list_templates()[name]['id']
try:
ret = list_templates()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The template \'{0}\' could not be foound.'.format(name)
)
return ret
def get_vm_id(kwargs=None, call=None):
@ -717,7 +759,14 @@ def get_vm_id(kwargs=None, call=None):
'The get_vm_id function requires a name.'
)
return list_nodes()[name]['id']
try:
ret = list_nodes()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The VM \'{0}\' could not be found.'.format(name)
)
return ret
def get_vn_id(kwargs=None, call=None):
@ -746,7 +795,14 @@ def get_vn_id(kwargs=None, call=None):
'The get_vn_id function requires a name.'
)
return list_vns()[name]['id']
try:
ret = list_vns()[name]['id']
except KeyError:
raise SaltCloudSystemExit(
'The VN \'{0}\' could not be found.'.format(name)
)
return ret
def create(vm_):
@ -1271,7 +1327,7 @@ def image_persistent(call=None, kwargs=None):
.. code-block:: bash
salt-cloud -f image_persistent opennebula name=my-image persist=True
salt-cloud --function image_persistent opennebula image_id=5
salt-cloud --function image_persistent opennebula image_id=5 persist=False
'''
if call != 'function':
raise SaltCloudSystemExit(
@ -1577,6 +1633,18 @@ def image_update(call=None, kwargs=None):
'The image_update function requires an \'update_type\' to be provided.'
)
if update_type == update_args[0]:
update_number = 0
elif update_type == update_args[1]:
update_number = 1
else:
raise SaltCloudSystemExit(
'The update_type argument must be either {0} or {1}.'.format(
update_args[0],
update_args[1]
)
)
if image_id:
if image_name:
log.warning(
@ -1605,18 +1673,6 @@ def image_update(call=None, kwargs=None):
'to be provided.'
)
if update_type == update_args[0]:
update_number = 0
elif update_type == update_args[1]:
update_number = 1
else:
raise SaltCloudSystemExit(
'The update_type argument must be either {0} or {1}.'.format(
update_args[0],
update_args[1]
)
)
server, user, password = _get_xml_rpc()
auth = ':'.join([user, password])
response = server.one.image.update(auth, int(image_id), data, int(update_number))
@ -1763,9 +1819,9 @@ def secgroup_clone(call=None, kwargs=None):
.. code-block:: bash
salt-cloud -f secgroup_clone opennebula name=my-cloned-secgroup secgroup_id=0
salt-cloud -f secgroup_clone opennebula name=my-cloned-secgroup secgroup_name=my-secgroup
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The secgroup_clone function must be called with -f or --function.'
)
@ -1832,7 +1888,7 @@ def secgroup_delete(call=None, kwargs=None):
salt-cloud -f secgroup_delete opennebula name=my-secgroup
salt-cloud --function secgroup_delete opennebula secgroup_id=100
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The secgroup_delete function must be called with -f or --function.'
)
@ -1893,7 +1949,7 @@ def secgroup_info(call=None, kwargs=None):
salt-cloud -f secgroup_info opennebula name=my-secgroup
salt-cloud --function secgroup_info opennebula secgroup_id=5
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The secgroup_info function must be called with -f or --function.'
)
@ -1987,6 +2043,18 @@ def secgroup_update(call=None, kwargs=None):
'The secgroup_update function requires an \'update_type\' to be provided.'
)
if update_type == update_args[0]:
update_number = 0
elif update_type == update_args[1]:
update_number = 1
else:
raise SaltCloudSystemExit(
'The update_type argument must be either {0} or {1}.'.format(
update_args[0],
update_args[1]
)
)
if secgroup_id:
if secgroup_name:
log.warning(
@ -2015,18 +2083,6 @@ def secgroup_update(call=None, kwargs=None):
'to be provided.'
)
if update_type == update_args[0]:
update_number = 0
elif update_type == update_args[1]:
update_number = 1
else:
raise SaltCloudSystemExit(
'The update_type argument must be either {0} or {1}.'.format(
update_args[0],
update_args[1]
)
)
server, user, password = _get_xml_rpc()
auth = ':'.join([user, password])
response = server.one.secgroup.update(auth, int(secgroup_id), data, int(update_number))
@ -2129,7 +2185,7 @@ def template_clone(call=None, kwargs=None):
salt-cloud -f template_clone opennebula name=my-new-template template_id=0
salt-cloud -f template_clone opennebula name=my-new-template template_name=my-template
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The template_clone function must be called with -f or --function.'
)
@ -2196,7 +2252,7 @@ def template_delete(call=None, kwargs=None):
salt-cloud -f template_delete opennebula name=my-template
salt-cloud --function template_delete opennebula template_id=5
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The template_delete function must be called with -f or --function.'
)
@ -2207,12 +2263,6 @@ def template_delete(call=None, kwargs=None):
name = kwargs.get('name', None)
template_id = kwargs.get('template_id', None)
if not name and not template_id:
raise SaltCloudSystemExit(
'The template_delete function requires either a \'name\' or a \'template_id\' '
'to be provided.'
)
if template_id:
if name:
log.warning(
@ -2270,7 +2320,7 @@ def template_instantiate(call=None, kwargs=None):
salt-cloud -f template_instantiate opennebula vm_name=my-new-vm template_id=0
'''
if call == 'action':
if call != 'function':
raise SaltCloudSystemExit(
'The template_instantiate function must be called with -f or --function.'
)

View File

@ -17,24 +17,13 @@ ensure_in_syspath('../../../')
from salt.cloud.clouds import opennebula
from salt.exceptions import SaltCloudSystemExit
# Import Third Party Libs
try:
import salt.ext.six.moves.xmlrpc_client # pylint: disable=E0611,W0611
from lxml import etree # pylint: disable=W0611
HAS_XML_LIBS = True
except ImportError:
HAS_XML_LIBS = False
# Global Variables
opennebula.__active_provider_name__ = ''
opennebula.__opts__ = {}
@skipIf(NO_MOCK, NO_MOCK_REASON)
@skipIf(HAS_XML_LIBS is False, 'The \'lxml\' library is required to run these tests.')
@patch('salt.cloud.clouds.opennebula.__virtual__', MagicMock(return_value='opennebula'))
@patch('salt.cloud.clouds.opennebula._get_xml_rpc',
MagicMock(return_value=('server', 'user', 'password')))
class OpenNebulaTestCase(TestCase):
'''
Unit TestCase for salt.cloud.clouds.opennebula module.
@ -169,6 +158,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_clusters',
MagicMock(return_value={'foo': {'id': 'bar'}}))
def test_get_cluster_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_cluster_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_clusters',
MagicMock(return_value={'test-cluster': {'id': '100'}}))
def test_get_cluster_id_success(self):
@ -198,6 +198,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_datastores',
MagicMock(return_value={'test-datastore': {'id': '100'}}))
def test_get_datastore_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_datastore_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_datastores',
MagicMock(return_value={'test-datastore': {'id': '100'}}))
def test_get_datastore_id_success(self):
@ -227,6 +238,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.avail_locations',
MagicMock(return_value={'test-host': {'id': '100'}}))
def test_get_host_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_host_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.avail_locations',
MagicMock(return_value={'test-host': {'id': '100'}}))
def test_get_host_id_success(self):
@ -258,6 +280,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.avail_images',
MagicMock(return_value={'test-image': {'id': '100'}}))
def test_get_image_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_image_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.avail_images',
MagicMock(return_value={'test-image': {'id': '100'}}))
def test_get_image_id_success(self):
@ -289,6 +322,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_security_groups',
MagicMock(return_value={'test-security-group': {'id': '100'}}))
def test_get_secgroup_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_secgroup_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_security_groups',
MagicMock(return_value={'test-secgroup': {'id': '100'}}))
def test_get_secgroup_id_success(self):
@ -318,6 +362,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_templates',
MagicMock(return_value={'test-template': {'id': '100'}}))
def test_get_template_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_template_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_templates',
MagicMock(return_value={'test-template': {'id': '100'}}))
def test_get_template_id_success(self):
@ -347,6 +402,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_nodes',
MagicMock(return_value={'test-vm': {'id': '100'}}))
def test_get_vm_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_vm_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_nodes',
MagicMock(return_value={'test-vm': {'id': '100'}}))
def test_get_vm_id_success(self):
@ -376,6 +442,17 @@ class OpenNebulaTestCase(TestCase):
None,
call='foo')
@patch('salt.cloud.clouds.opennebula.list_vns',
MagicMock(return_value={'test-vn': {'id': '100'}}))
def test_get_vn_id_not_found(self):
'''
Tests that a SaltCloudSystemExit is raised when no name is provided.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.get_vn_id,
kwargs={'name': 'test'},
call='function')
@patch('salt.cloud.clouds.opennebula.list_vns',
MagicMock(return_value={'test-vn': {'id': '100'}}))
def test_get_vn_id_success(self):
@ -442,6 +519,23 @@ class OpenNebulaTestCase(TestCase):
'function',
kwargs={'name': 'test'})
@skipIf(True, 'Need to figure out how to mock calls to the O.N. API first.')
@patch('image.clone', MagicMock(return_value=[True, 11, 0]))
def test_image_clone_success(self):
'''
Tests that image_clone returns successfully
'''
name = 'test-image'
expected = {
'action': 'image.clone',
'cloned': 'True',
'cloned_image_id': '11',
'cloned_image_name': name,
'error_code': '0',
}
ret = opennebula.image_clone('function', kwargs={'name': name, 'image_id': 1})
self.assertEqual(expected, ret)
def test_image_delete_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
@ -456,6 +550,20 @@ class OpenNebulaTestCase(TestCase):
'''
self.assertRaises(SaltCloudSystemExit, opennebula.image_delete, 'function')
def test_image_info_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.image_info, 'foo')
def test_image_info_no_image_id_or_image_name(self):
'''
Tests that a SaltCloudSystemExit is raised when a neither an image_id
nor a name is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.image_info, 'function')
def test_image_persist_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
@ -479,6 +587,268 @@ class OpenNebulaTestCase(TestCase):
'function',
kwargs={'persist': False})
# TODO: Write tests for image_snapshot_delete, image_snapshot_revert, and image_snapshot_flatten
def test_image_update_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.image_update, 'foo')
def test_image_update_no_update_type(self):
'''
Tests that a SaltCloudSystemExit is raised when the update_type kwarg is
missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.image_update, 'function')
def test_image_update_bad_update_type_value(self):
'''
Tests that a SaltCloudSystemExit is raised when the update_type kwarg is
not a valid value.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.image_update,
'function',
kwargs={'update_type': 'foo'})
def test_image_update_no_image_id_or_image_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the image_id and image_name
kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.image_update,
'function',
kwargs={'update_type': 'merge'})
def test_image_update_no_data_or_path(self):
'''
Tests that a SaltCloudSystemExit is raised when the data and path
kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.image_update,
'function',
kwargs={'update_type': 'merge', 'image_id': '0'})
# TODO: Write tests for script and show_instance functions
def test_secgroup_allocate_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_allocate, 'foo')
def test_secgroup_allocate_no_data_or_path(self):
'''
Tests that a SaltCloudSystemExit is raised when the data and path
kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_allocate, 'function')
def test_secgroup_clone_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_clone, 'foo')
def test_secgroup_clone_no_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the name kwarg is
missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_clone, 'function')
def test_secgroup_clone_no_secgroup_id_or_secgroup_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the secgroup_id and
secgroup_name kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.secgroup_clone,
'function',
kwargs={'name': 'test'})
def test_secgroup_delete_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_delete, 'foo')
def test_secgroup_delete_no_secgroup_id_or_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the secgroup_id and
name kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_clone, 'function')
def test_secgroup_info_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_info, 'foo')
def test_secgroup_info_no_secgroup_id_or_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the secgroup_id and
name kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_info, 'function')
def test_secgroup_update_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_update, 'foo')
def test_secgroup_update_no_update_type(self):
'''
Tests that a SaltCloudSystemExit is raised when the update_type arg is
missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.secgroup_update, 'function')
def test_secgroup_update_bad_update_type_value(self):
'''
Tests that a SaltCloudSystemExit is raised when the secgroup_id and
secgroup_name kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.secgroup_update,
'function',
kwargs={'update_type': 'foo'})
def test_secgroup_update_no_secgroup_id_or_secgroup_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the secgroup_id and
secgroup_name kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.secgroup_update,
'function',
kwargs={'update_type': 'merge'})
def test_secgroup_update_no_data_or_path(self):
'''
Tests that a SaltCloudSystemExit is raised when the data and
path kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.secgroup_update,
'function',
kwargs={'update_type': 'merge', 'secgroup_id': '0'})
def test_template_allocate_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_allocate, 'foo')
def test_template_allocate_no_data_or_path(self):
'''
Tests that a SaltCloudSystemExit is raised when the data and
path kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_allocate, 'function')
def test_template_clone_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_clone, 'foo')
def test_template_clone_no_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the name arg is missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_clone, 'function')
def test_template_clone_no_template_name_or_template_id(self):
'''
Tests that a SaltCloudSystemExit is raised when the template_name and
template_id args are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.template_clone,
'function',
kwargs={'name': 'foo'})
def test_template_delete_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_delete, 'foo')
def test_template_delete_no_name_or_template_id(self):
'''
Tests that a SaltCloudSystemExit is raised when the name and
template_id args are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_delete, 'function')
def test_template_instantiate_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.template_instantiate, 'foo')
def test_template_instantiate_no_vm_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the vm_name arg is missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.template_instantiate,
'function',
None)
def test_template_instantiate_no_template_id_or_template_name(self):
'''
Tests that a SaltCloudSystemExit is raised when the template_name and
template_id args are missing.
'''
self.assertRaises(SaltCloudSystemExit,
opennebula.template_instantiate,
'function',
kwargs={'vm_name': 'test'})
def test_vm_action_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--action or -a is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.vm_action, 'foo')
def test_vm_action_no_action(self):
'''
Tests that a SaltCloudSystemExit is raised when the action arg is missing
'''
self.assertRaises(SaltCloudSystemExit, opennebula.vm_action, 'action')
def test_vm_allocate_function_error(self):
'''
Tests that a SaltCloudSystemExit is raised when something other than
--function or -f is provided.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.vm_allocate, 'foo')
def test_vm_allocate_no_data_or_path(self):
'''
Tests that a SaltCloudSystemExit is raised when the data and
path kwargs are missing.
'''
self.assertRaises(SaltCloudSystemExit, opennebula.vm_allocate, 'function')
if __name__ == '__main__':
from integration import run_tests