# -*- coding: utf-8 -*- ''' Unit tests for the docker state ''' # Import Python Libs from __future__ import absolute_import, print_function, unicode_literals # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import skipIf, TestCase from tests.support.mock import ( Mock, NO_MOCK, NO_MOCK_REASON, patch ) # Import Salt Libs import salt.modules.dockermod as docker_mod import salt.states.docker_volume as docker_state @skipIf(NO_MOCK, NO_MOCK_REASON) class DockerVolumeTestCase(TestCase, LoaderModuleMockMixin): ''' Test docker_volume states ''' def setup_loader_modules(self): return { docker_mod: { '__context__': {'docker.docker_version': ''} }, docker_state: { '__opts__': {'test': False} } } def test_present(self): ''' Test docker_volume.present ''' volumes = [] default_driver = 'dummy_default' def create_volume(name, driver=None, driver_opts=None): for v in volumes: # present should never try to add a conflicting # volume self.assertNotEqual(v['Name'], name) if driver is None: driver = default_driver new = {'Name': name, 'Driver': driver} volumes.append(new) return new def remove_volume(name): old_len = len(volumes) removed = [v for v in volumes if v['Name'] == name] # present should not have tried to remove a volume # that didn't exist self.assertEqual(1, len(removed)) volumes.remove(removed[0]) return removed[0] docker_create_volume = Mock(side_effect=create_volume) __salt__ = { 'docker.create_volume': docker_create_volume, 'docker.volumes': Mock(return_value={'Volumes': volumes}), 'docker.remove_volume': Mock(side_effect=remove_volume) } with patch.dict(docker_state.__dict__, {'__salt__': __salt__}): ret = docker_state.present('volume_foo') docker_create_volume.assert_called_with('volume_foo', driver=None, driver_opts=None) self.assertEqual( { 'name': 'volume_foo', 'comment': '', 'changes': { 'created': { 'Driver': default_driver, 'Name': 'volume_foo', }, }, 'result': True, }, ret) self.assertEqual(len(volumes), 1) self.assertEqual(volumes[0]['Name'], 'volume_foo') self.assertIs(volumes[0]['Driver'], default_driver) # run it again with the same arguments orig_volumes = [volumes[0].copy()] ret = docker_state.present('volume_foo') self.assertEqual( { 'name': 'volume_foo', 'comment': "Volume 'volume_foo' already exists.", 'changes': {}, 'result': True, }, ret) self.assertEqual(orig_volumes, volumes) # run it again with a different driver but don't force ret = docker_state.present('volume_foo', driver='local') self.assertEqual( { 'name': 'volume_foo', 'comment': ("Driver for existing volume 'volume_foo'" " ('dummy_default') does not match specified" " driver ('local') and force is False"), 'changes': {}, 'result': False, }, ret) self.assertEqual(orig_volumes, volumes) # run it again with a different driver and force ret = docker_state.present( 'volume_foo', driver='local', force=True) self.assertEqual( { 'name': 'volume_foo', 'comment': "", 'changes': { 'removed': { 'Driver': default_driver, 'Name': 'volume_foo', }, 'created': { 'Driver': 'local', 'Name': 'volume_foo', }, }, 'result': True, }, ret) mod_orig_volumes = [orig_volumes[0].copy()] mod_orig_volumes[0]['Driver'] = 'local' self.assertEqual(mod_orig_volumes, volumes) def test_present_with_another_driver(self): ''' Test docker_volume.present ''' docker_create_volume = Mock(return_value='created') docker_remove_volume = Mock(return_value='removed') __salt__ = {'docker.create_volume': docker_create_volume, 'docker.remove_volume': docker_remove_volume, 'docker.volumes': Mock(return_value={ 'Volumes': [{'Name': 'volume_foo', 'Driver': 'foo'}]}), } with patch.dict(docker_state.__dict__, {'__salt__': __salt__}): ret = docker_state.present( 'volume_foo', driver='bar', force=True, ) docker_remove_volume.assert_called_with('volume_foo') docker_create_volume.assert_called_with('volume_foo', driver='bar', driver_opts=None) self.assertEqual(ret, {'name': 'volume_foo', 'comment': '', 'changes': {'created': 'created', 'removed': 'removed'}, 'result': True}) def test_present_wo_existing_volumes(self): ''' Test docker_volume.present without existing volumes. ''' docker_create_volume = Mock(return_value='created') docker_remove_volume = Mock(return_value='removed') __salt__ = {'docker.create_volume': docker_create_volume, 'docker.remove_volume': docker_remove_volume, 'docker.volumes': Mock(return_value={'Volumes': None}), } with patch.dict(docker_state.__dict__, {'__salt__': __salt__}): ret = docker_state.present( 'volume_foo', driver='bar', force=True, ) docker_create_volume.assert_called_with('volume_foo', driver='bar', driver_opts=None) self.assertEqual(ret, {'name': 'volume_foo', 'comment': '', 'changes': {'created': 'created'}, 'result': True}) def test_absent(self): ''' Test docker_volume.absent ''' docker_remove_volume = Mock(return_value='removed') __salt__ = {'docker.remove_volume': docker_remove_volume, 'docker.volumes': Mock(return_value={ 'Volumes': [{'Name': 'volume_foo'}]}), } with patch.dict(docker_state.__dict__, {'__salt__': __salt__}): ret = docker_state.absent( 'volume_foo', ) docker_remove_volume.assert_called_with('volume_foo') self.assertEqual(ret, {'name': 'volume_foo', 'comment': '', 'changes': {'removed': 'removed'}, 'result': True})