mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
9a268e05d6
In relation to #25293, it solves the improbable case where the OS returns the mount options as names instead of numeric ids. The module converts these names to numeric ids before returning the opts. This is done only for uid= and gid= opts, for now. It can be extended to others.
332 lines
14 KiB
Python
332 lines
14 KiB
Python
# -*- coding: utf-8 -*-
|
|
'''
|
|
:codeauthor: :email:`Rupesh Tare <rupesht@saltstack.com>`
|
|
'''
|
|
# Import Python libs
|
|
from __future__ import absolute_import
|
|
import os
|
|
|
|
# Import Salt Testing Libs
|
|
from salttesting import TestCase, skipIf
|
|
from salttesting.mock import (
|
|
mock_open,
|
|
MagicMock,
|
|
patch,
|
|
NO_MOCK,
|
|
NO_MOCK_REASON
|
|
)
|
|
|
|
# Import Salt Libs
|
|
import salt.utils
|
|
from salt.exceptions import CommandExecutionError
|
|
|
|
|
|
from salt.modules import mount
|
|
|
|
# Globals
|
|
mount.__grains__ = {}
|
|
mount.__salt__ = {}
|
|
mount.__context__ = {}
|
|
|
|
MOCK_SHELL_FILE = 'A B C D F G\n'
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
class MountTestCase(TestCase):
|
|
'''
|
|
Test cases for salt.modules.mount
|
|
'''
|
|
def test_active(self):
|
|
'''
|
|
List the active mounts.
|
|
'''
|
|
with patch.dict(mount.__grains__, {'os': 'FreeBSD'}):
|
|
# uid=user1 tests the improbable case where a OS returns a name
|
|
# instead of a numeric id, for #25293
|
|
mock = MagicMock(return_value='A B C D,E,F,uid=user1,gid=grp1')
|
|
mock_user = MagicMock(return_value={'uid': '100'})
|
|
mock_group = MagicMock(return_value={'gid': '100'})
|
|
with patch.dict(mount.__salt__, {'cmd.run_stdout': mock,
|
|
'user.info': mock_user,
|
|
'group.info': mock_group}):
|
|
self.assertEqual(mount.active(), {'B':
|
|
{'device': 'A',
|
|
'opts': ['D', 'E', 'F',
|
|
'uid=100',
|
|
'gid=100'],
|
|
'fstype': 'C'}})
|
|
|
|
with patch.dict(mount.__grains__, {'os': 'Solaris'}):
|
|
mock = MagicMock(return_value='A * B * C D/E/F')
|
|
with patch.dict(mount.__salt__, {'cmd.run_stdout': mock}):
|
|
self.assertEqual(mount.active(), {'B':
|
|
{'device': 'A',
|
|
'opts': ['D', 'E', 'F'],
|
|
'fstype': 'C'}})
|
|
|
|
with patch.dict(mount.__grains__, {'os': 'OpenBSD'}):
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, '_active_mounts_openbsd', mock):
|
|
self.assertEqual(mount.active(), {})
|
|
|
|
with patch.dict(mount.__grains__, {'os': 'MacOS'}):
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, '_active_mounts_darwin', mock):
|
|
self.assertEqual(mount.active(), {})
|
|
|
|
with patch.dict(mount.__grains__, {'os': 'MacOS'}):
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, '_active_mountinfo', mock):
|
|
with patch.object(mount, '_active_mounts_darwin', mock):
|
|
self.assertEqual(mount.active(extended=True), {})
|
|
|
|
def test_fstab(self):
|
|
'''
|
|
List the content of the fstab
|
|
'''
|
|
mock = MagicMock(return_value=False)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
self.assertEqual(mount.fstab(), {})
|
|
|
|
mock = MagicMock(return_value=True)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
file_data = '\n'.join(['#',
|
|
'A B C D,E,F G H'])
|
|
with patch('salt.utils.fopen',
|
|
mock_open(read_data=file_data),
|
|
create=True) as m:
|
|
m.return_value.__iter__.return_value = file_data.splitlines()
|
|
self.assertEqual(mount.fstab(), {'B': {'device': 'A',
|
|
'dump': 'G',
|
|
'fstype': 'C',
|
|
'opts': ['D', 'E', 'F'],
|
|
'pass': 'H'}})
|
|
|
|
def test_rm_fstab(self):
|
|
'''
|
|
Remove the mount point from the fstab
|
|
'''
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'fstab', mock):
|
|
self.assertTrue(mount.rm_fstab('name', 'device'))
|
|
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'fstab', mock):
|
|
with patch('salt.utils.fopen', mock_open()) as m_open:
|
|
helper_open = m_open()
|
|
helper_open.write.assertRaises(CommandExecutionError,
|
|
mount.rm_fstab,
|
|
config=None)
|
|
|
|
def test_set_fstab(self):
|
|
'''
|
|
Tests to verify that this mount is represented in the fstab,
|
|
change the mount to match the data passed, or add the mount
|
|
if it is not present.
|
|
'''
|
|
mock = MagicMock(return_value=False)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
self.assertRaises(CommandExecutionError,
|
|
mount.set_fstab, 'A', 'B', 'C')
|
|
|
|
mock = MagicMock(return_value=True)
|
|
mock_read = MagicMock(side_effect=OSError)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
with patch.object(salt.utils, 'fopen', mock_read):
|
|
self.assertRaises(CommandExecutionError,
|
|
mount.set_fstab, 'A', 'B', 'C')
|
|
|
|
mock = MagicMock(return_value=True)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
with patch('salt.utils.fopen',
|
|
mock_open(read_data=MOCK_SHELL_FILE)):
|
|
self.assertEqual(mount.set_fstab('A', 'B', 'C'), 'new')
|
|
|
|
def test_rm_automaster(self):
|
|
'''
|
|
Remove the mount point from the auto_master
|
|
'''
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'automaster', mock):
|
|
self.assertTrue(mount.rm_automaster('name', 'device'))
|
|
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'fstab', mock):
|
|
with patch('salt.utils.fopen', mock_open()) as m_open:
|
|
helper_open = m_open()
|
|
helper_open.write.assertRaises(CommandExecutionError,
|
|
mount.rm_automaster,
|
|
'name', 'device')
|
|
|
|
def test_set_automaster(self):
|
|
'''
|
|
Verify that this mount is represented in the auto_salt, change the mount
|
|
to match the data passed, or add the mount if it is not present.
|
|
'''
|
|
mock = MagicMock(return_value=True)
|
|
with patch.object(os.path, 'isfile', mock):
|
|
self.assertRaises(CommandExecutionError,
|
|
mount.set_automaster,
|
|
'A', 'B', 'C')
|
|
|
|
def test_automaster(self):
|
|
'''
|
|
Test the list the contents of the fstab
|
|
'''
|
|
self.assertDictEqual(mount.automaster(), {})
|
|
|
|
def test_mount(self):
|
|
'''
|
|
Mount a device
|
|
'''
|
|
with patch.dict(mount.__grains__, {'os': 'MacOS'}):
|
|
mock = MagicMock(return_value=True)
|
|
with patch.object(os.path, 'exists', mock):
|
|
mock = MagicMock(return_value=None)
|
|
with patch.dict(mount.__salt__, {'file.mkdir': None}):
|
|
mock = MagicMock(return_value={'retcode': True,
|
|
'stderr': True})
|
|
with patch.dict(mount.__salt__, {'cmd.run_all': mock}):
|
|
self.assertTrue(mount.mount('name', 'device'))
|
|
|
|
mock = MagicMock(return_value={'retcode': False,
|
|
'stderr': False})
|
|
with patch.dict(mount.__salt__, {'cmd.run_all': mock}):
|
|
self.assertTrue(mount.mount('name', 'device'))
|
|
|
|
def test_remount(self):
|
|
'''
|
|
Attempt to remount a device, if the device is not already mounted, mount
|
|
is called
|
|
'''
|
|
with patch.dict(mount.__grains__, {'os': 'MacOS'}):
|
|
mock = MagicMock(return_value=[])
|
|
with patch.object(mount, 'active', mock):
|
|
mock = MagicMock(return_value=True)
|
|
with patch.object(mount, 'mount', mock):
|
|
self.assertTrue(mount.remount('name', 'device'))
|
|
|
|
def test_umount(self):
|
|
'''
|
|
Attempt to unmount a device by specifying the directory it is
|
|
mounted on
|
|
'''
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'active', mock):
|
|
self.assertEqual(mount.umount('name'),
|
|
'name does not have anything mounted')
|
|
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'active', mock):
|
|
mock = MagicMock(return_value={'retcode': True, 'stderr': True})
|
|
with patch.dict(mount.__salt__, {'cmd.run_all': mock}):
|
|
self.assertTrue(mount.umount('name'))
|
|
|
|
mock = MagicMock(return_value={'retcode': False})
|
|
with patch.dict(mount.__salt__, {'cmd.run_all': mock}):
|
|
self.assertTrue(mount.umount('name'))
|
|
|
|
def test_is_fuse_exec(self):
|
|
'''
|
|
Returns true if the command passed is a fuse mountable application
|
|
'''
|
|
with patch.object(salt.utils, 'which', return_value=None):
|
|
self.assertFalse(mount.is_fuse_exec('cmd'))
|
|
|
|
with patch.object(salt.utils, 'which', return_value=True):
|
|
self.assertFalse(mount.is_fuse_exec('cmd'))
|
|
|
|
mock = MagicMock(side_effect=[1, 0])
|
|
with patch.object(salt.utils, 'which', mock):
|
|
self.assertFalse(mount.is_fuse_exec('cmd'))
|
|
|
|
def test_swaps(self):
|
|
'''
|
|
Return a dict containing information on active swap
|
|
'''
|
|
|
|
file_data = '\n'.join(['Filename Type Size Used Priority',
|
|
'/dev/sda1 partition 31249404 4100 -1'])
|
|
with patch.dict(mount.__grains__, {'os': ''}):
|
|
with patch('salt.utils.fopen',
|
|
mock_open(read_data=file_data),
|
|
create=True) as m:
|
|
m.return_value.__iter__.return_value = file_data.splitlines()
|
|
|
|
self.assertDictEqual(mount.swaps(), {'/dev/sda1':
|
|
{'priority': '-1',
|
|
'size': '31249404',
|
|
'type': 'partition',
|
|
'used': '4100'}})
|
|
|
|
file_data = '\n'.join(['Device Size Used Unknown Unknown Priority',
|
|
'/dev/sda1 31249404 4100 unknown unknown -1'])
|
|
mock = MagicMock(return_value=file_data)
|
|
with patch.dict(mount.__grains__, {'os': 'OpenBSD'}):
|
|
with patch.dict(mount.__salt__, {'cmd.run_stdout': mock}):
|
|
self.assertDictEqual(mount.swaps(), {'/dev/sda1':
|
|
{'priority': '-1',
|
|
'size': '31249404',
|
|
'type': 'partition',
|
|
'used': '4100'}})
|
|
|
|
def test_swapon(self):
|
|
'''
|
|
Activate a swap disk
|
|
'''
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'swaps', mock):
|
|
self.assertEqual(mount.swapon('name'),
|
|
{'stats': 'name', 'new': False})
|
|
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'swaps', mock):
|
|
mock = MagicMock(return_value=None)
|
|
with patch.dict(mount.__salt__, {'cmd.run': mock}):
|
|
self.assertEqual(mount.swapon('name', False), {})
|
|
|
|
mock = MagicMock(side_effect=[{}, {'name': 'name'}])
|
|
with patch.object(mount, 'swaps', mock):
|
|
mock = MagicMock(return_value=None)
|
|
with patch.dict(mount.__salt__, {'cmd.run': mock}):
|
|
self.assertEqual(mount.swapon('name'), {'stats': 'name',
|
|
'new': True})
|
|
|
|
def test_swapoff(self):
|
|
'''
|
|
Deactivate a named swap mount
|
|
'''
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'swaps', mock):
|
|
self.assertEqual(mount.swapoff('name'), None)
|
|
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'swaps', mock):
|
|
with patch.dict(mount.__grains__, {'os': 'test'}):
|
|
mock = MagicMock(return_value=None)
|
|
with patch.dict(mount.__salt__, {'cmd.run': mock}):
|
|
self.assertFalse(mount.swapoff('name'))
|
|
|
|
mock = MagicMock(side_effect=[{'name': 'name'}, {}])
|
|
with patch.object(mount, 'swaps', mock):
|
|
with patch.dict(mount.__grains__, {'os': 'test'}):
|
|
mock = MagicMock(return_value=None)
|
|
with patch.dict(mount.__salt__, {'cmd.run': mock}):
|
|
self.assertTrue(mount.swapoff('name'))
|
|
|
|
def test_is_mounted(self):
|
|
'''
|
|
Provide information if the path is mounted
|
|
'''
|
|
mock = MagicMock(return_value={})
|
|
with patch.object(mount, 'active', mock):
|
|
self.assertFalse(mount.is_mounted('name'))
|
|
|
|
mock = MagicMock(return_value={'name': 'name'})
|
|
with patch.object(mount, 'active', mock):
|
|
self.assertTrue(mount.is_mounted('name'))
|
|
|
|
if __name__ == '__main__':
|
|
from integration import run_tests
|
|
run_tests(MountTestCase, needs_daemon=False)
|