class Base(unittest.TestCase): """ Common setUp/tearDown for partition tests """ @unittest.skipIf(not os.path.isfile('/proc/mounts'), 'system does not have /proc/mounts') @unittest.skipIf(not process.can_sudo('mount'), 'current user must be allowed to run "mount" under sudo') @unittest.skipIf(not process.can_sudo('mkfs.ext2 -V'), 'current user must be allowed to run "mkfs.ext2" under ' 'sudo') @unittest.skipUnless(utils_path.find_command('mkfs.ext2', False), 'mkfs.ext2 utility must be available') @unittest.skipUnless(process.has_capability("cap_sys_admin"), "Capability to mount is required (cap_sys_admin)") @unittest.skipIf( os.getenv('TRAVIS') and os.getenv('TRAVIS_CPU_ARCH') in ['arm64', 'ppc64le', 's390x'], 'TRAVIS Environment is unsuitable for these tests') def setUp(self): prefix = temp_dir_prefix(self) self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) self.mountpoint = os.path.join(self.tmpdir.name, "disk") os.mkdir(self.mountpoint) self.disk = partition.Partition( os.path.join(self.tmpdir.name, "block"), 1, self.mountpoint) def tearDown(self): self.disk.unmount() self.tmpdir.cleanup()
class Base(unittest.TestCase): """ Common setUp/tearDown for partition tests """ @unittest.skipIf(not os.path.isfile("/proc/mounts"), "system does not have /proc/mounts") @unittest.skipIf( not process.can_sudo("mount"), 'current user must be allowed to run "mount" under sudo', ) @unittest.skipIf( not process.can_sudo("mkfs.ext2 -V"), 'current user must be allowed to run "mkfs.ext2" under ' "sudo", ) @unittest.skipUnless( utils_path.find_command("mkfs.ext2", False), "mkfs.ext2 utility must be available", ) @unittest.skipUnless( process.has_capability("cap_sys_admin"), "Capability to mount is required (cap_sys_admin)", ) def setUp(self): prefix = temp_dir_prefix(self) self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) self.mountpoint = os.path.join(self.tmpdir.name, "disk") os.mkdir(self.mountpoint) self.disk = partition.Partition( os.path.join(self.tmpdir.name, "block"), 1, self.mountpoint) def tearDown(self): self.disk.unmount() self.tmpdir.cleanup()
class Base(unittest.TestCase): """ Common setUp/tearDown for partition tests """ @unittest.skipIf(not os.path.isfile('/proc/mounts'), 'system does not have /proc/mounts') @unittest.skipIf(not process.can_sudo('mount'), 'current user must be allowed to run "mount" under sudo') @unittest.skipIf(not process.can_sudo('mkfs.ext2 -V'), 'current user must be allowed to run "mkfs.ext2" under ' 'sudo') @unittest.skipIf( os.getenv('TRAVIS') and os.getenv('TRAVIS_CPU_ARCH') in ['arm64', 'ppc64le', 's390x'], 'TRAVIS Environment is unsuitable for these tests') def setUp(self): prefix = temp_dir_prefix(__name__, self, 'setUp') self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) self.mountpoint = os.path.join(self.tmpdir.name, "disk") os.mkdir(self.mountpoint) self.disk = partition.Partition( os.path.join(self.tmpdir.name, "block"), 1, self.mountpoint) def tearDown(self): self.disk.unmount() self.tmpdir.cleanup()
class DiskSpace(unittest.TestCase): @unittest.skipIf( process.system("modinfo scsi_debug", shell=True, ignore_status=True), "Kernel mod 'scsi_debug' not available.") @unittest.skipIf(linux_modules.module_is_loaded("scsi_debug"), "Kernel mod 'scsi_debug' is already loaded.") @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support scsi_debug module') @unittest.skipIf(not process.can_sudo(), "This test requires root or " "passwordless sudo configured.") def test_get_diskspace(self): """ Use scsi_debug device to check disk size """ pre = glob.glob("/dev/sd*") process.system("modprobe scsi_debug", sudo=True) disks = set(glob.glob("/dev/sd*")).difference(pre) self.assertEqual(len(disks), 1, "pre: %s\npost: %s" % (disks, glob.glob("/dev/sd*"))) disk = disks.pop() self.assertEqual(lv_utils.get_diskspace(disk), "8388608") def tearDown(self): for _ in range(10): if process.run("modprobe -r scsi_debug", ignore_status=True, sudo=True).exit_status == 0: return time.sleep(0.05) raise RuntimeError("Failed to remove scsi_debug after testing")
def can_mount(): """ Test whether the current user can perform a loop mount AFAIK, this means being root, having mount and iso9660 kernel support :rtype: bool """ if not process.can_sudo(): LOG.debug('Can not use mount: current user is not "root" and ' 'sudo is not configured.') return False if not has_userland_tool('mount'): LOG.debug('Can not use mount: missing "mount" tool') return False with open('/proc/filesystems') as proc_filesystems: # pylint: disable=W1514 if 'iso9660' not in proc_filesystems.read(): process.system("modprobe iso9660", ignore_status=True, sudo=True) with open('/proc/filesystems') as proc_filesystems: # pylint: disable=W1514 if 'iso9660' not in proc_filesystems.read(): LOG.debug('Can not use mount: lack of iso9660 kernel support') return False return True
class BaseIso9660: """ Base class defining setup and tests for shared Iso9660 functionality """ def setUp(self): self.iso_path = os.path.abspath( os.path.join( os.path.dirname(os.path.dirname(__file__)), os.path.pardir, ".data", "sample.iso", )) self.iso = None prefix = temp_dir_prefix(self) self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) def test_basic_workflow(self): """ Check the basic Iso9660 workflow """ self.assertEqual(self.iso.read("file"), b"file content\n") dst = os.path.join(self.tmpdir.name, "file") self.iso.copy(os.path.join("Dir", "in_dir_file"), dst) self.assertEqual( open(dst, encoding="utf-8").read(), "content of in-dir-file\n") self.iso.close() self.iso.close() # check that double-close won't fail @unittest.skipIf( not process.can_sudo("mount"), "This test requires mount to run under sudo or root", ) @unittest.skipUnless( process.has_capability("cap_sys_admin"), "Capability to mount is required (cap_sys_admin)", ) def test_mnt_dir_workflow(self): """ Check the mnt_dir functionality """ base = self.iso.mnt_dir dir_path = os.path.join(base, "Dir") self.assertTrue(os.path.isdir(dir_path)) self.assertEqual(bytes(open(os.path.join(base, "file"), "rb").read()), b"file content\n") in_dir_file_path = os.path.join(base, "Dir", "in_dir_file") self.assertEqual(bytes(open(in_dir_file_path, "rb").read()), b"content of in-dir-file\n") self.iso.close() self.assertFalse( os.path.exists(base), "the mnt_dir is suppose to be " "destroyed after iso.close()", ) def tearDown(self): if self.iso is not None: self.iso.close() self.tmpdir.cleanup()
class IsoMount(BaseIso9660, unittest.TestCase): """ Mount-based check """ @unittest.skipIf(not process.can_sudo("mount"), "This test requires sudo or root") def setUp(self): super(IsoMount, self).setUp() self.iso = iso9660.Iso9660Mount(self.iso_path)
class BaseIso9660: """ Base class defining setup and tests for shared Iso9660 functionality """ def setUp(self): self.iso_path = os.path.abspath( os.path.join(os.path.dirname(os.path.dirname(__file__)), os.path.pardir, ".data", "sample.iso")) self.iso = None prefix = temp_dir_prefix(self) self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) @unittest.skipIf(os.uname()[4] == 's390x', ('Endianess issues on pycdlib, see ' 'https://github.com/clalancette/pycdlib/issues/39')) def test_basic_workflow(self): """ Check the basic Iso9660 workflow """ self.assertEqual(self.iso.read("file"), b"file content\n") dst = os.path.join(self.tmpdir.name, "file") self.iso.copy(os.path.join("Dir", "in_dir_file"), dst) self.assertEqual( open(dst, encoding='utf-8').read(), "content of in-dir-file\n") self.iso.close() self.iso.close() # check that double-close won't fail @unittest.skipIf(not process.can_sudo("mount"), "This test requires mount to run under sudo or root") @unittest.skipUnless(process.has_capability("cap_sys_admin"), "Capability to mount is required (cap_sys_admin)") @unittest.skipIf( os.getenv('TRAVIS') and os.getenv('TRAVIS_CPU_ARCH') in ['arm64', 'ppc64le', 's390x'], 'TRAVIS Environment is unsuitable for these tests') def test_mnt_dir_workflow(self): """ Check the mnt_dir functionality """ base = self.iso.mnt_dir dir_path = os.path.join(base, "Dir") self.assertTrue(os.path.isdir(dir_path)) self.assertEqual(bytes(open(os.path.join(base, "file"), 'rb').read()), b"file content\n") in_dir_file_path = os.path.join(base, "Dir", "in_dir_file") self.assertEqual(bytes(open(in_dir_file_path, 'rb').read()), b"content of in-dir-file\n") self.iso.close() self.assertFalse( os.path.exists(base), "the mnt_dir is suppose to be " "destroyed after iso.close()") def tearDown(self): if self.iso is not None: self.iso.close() self.tmpdir.cleanup()
class BaseIso9660(unittest.TestCase): """ Base class defining setup and tests for shared Iso9660 functionality """ def setUp(self): self.iso_path = os.path.abspath(os.path.join(os.path.dirname(__file__), os.path.pardir, ".data", "sample.iso")) self.iso = None self.tmpdir = tempfile.mkdtemp(prefix="avocado_" + __name__) def basic_workflow(self): """ Check the basic Iso9660 workflow :warning: Make sure to include this in per-implementation tests due to ast loader we can't just define a base-class. """ self.assertEqual(self.iso.read("file"), b"file content\n") dst = os.path.join(self.tmpdir, "file") self.iso.copy(os.path.join("Dir", "in_dir_file"), dst) self.assertEqual(open(dst).read(), "content of in-dir-file\n") self.iso.close() self.iso.close() # check that double-close won't fail @unittest.skipIf(not process.can_sudo("mount"), "This test requires mount to run under sudo or root") def mnt_dir_workflow(self): """ Check the mnt_dir functionality :warning: Make sure to include this in per-implementation tests due to ast loader we can't just define a base-class. """ base = self.iso.mnt_dir dir_path = os.path.join(base, "Dir") self.assertTrue(os.path.isdir(dir_path)) self.assertEqual(bytes(open(os.path.join(base, "file"), 'rb').read()), b"file content\n") in_dir_file_path = os.path.join(base, "Dir", "in_dir_file") self.assertEqual(bytes(open(in_dir_file_path, 'rb').read()), b"content of in-dir-file\n") self.iso.close() self.assertFalse(os.path.exists(base), "the mnt_dir is suppose to be " "destroyed after iso.close()") def tearDown(self): if self.iso is not None: self.iso.close() shutil.rmtree(self.tmpdir)
class Base(unittest.TestCase): """ Common setUp/tearDown for partition tests """ @unittest.skipIf(not os.path.isfile('/proc/mounts'), 'system does not have /proc/mounts') @unittest.skipIf(not process.can_sudo('mount'), 'current user must be allowed to run "mount" under sudo') @unittest.skipIf(not process.can_sudo('mkfs.ext2 -V'), 'current user must be allowed to run "mkfs.ext2" under ' 'sudo') def setUp(self): self.tmpdir = tempfile.mkdtemp(prefix="avocado_" + __name__) self.mountpoint = os.path.join(self.tmpdir, "disk") os.mkdir(self.mountpoint) self.disk = partition.Partition(os.path.join(self.tmpdir, "block"), 1, self.mountpoint) def tearDown(self): self.disk.unmount() shutil.rmtree(self.tmpdir)
class IsoMount(BaseIso9660, unittest.TestCase): """ Mount-based check """ @unittest.skipIf(not process.can_sudo("mount"), "This test requires sudo or root") @unittest.skipIf( os.getenv('TRAVIS') and os.getenv('TRAVIS_CPU_ARCH') in ['arm64', 'ppc64le', 's390x'], 'TRAVIS Environment is unsuitable for these tests') def setUp(self): super(IsoMount, self).setUp() self.iso = iso9660.Iso9660Mount(self.iso_path)
class IsoMount(BaseIso9660, unittest.TestCase): """ Mount-based check """ @unittest.skipIf(not process.can_sudo("mount"), "This test requires sudo or root") @unittest.skipUnless( process.has_capability("cap_sys_admin"), "Capability to mount is required (cap_sys_admin)", ) def setUp(self): super().setUp() self.iso = iso9660.Iso9660Mount(self.iso_path)
class IsoMount(BaseIso9660): """ Mount-based check """ @unittest.skipIf(not process.can_sudo(), "This test requires sudo or root") def setUp(self): super(IsoMount, self).setUp() self.iso = iso9660.Iso9660Mount(self.iso_path) def test_basic_workflow(self): """Call the basic workflow""" self.basic_workflow() def test_mnt_dir(self): """Use the mnt_dir property""" self.mnt_dir_workflow()
class TestPartitionMkfsMount(Base): """ Tests that assume a filesystem and mounted partition """ def setUp(self): super(TestPartitionMkfsMount, self).setUp() self.disk.mkfs() self.disk.mount() self.use_mnt_file = os.path.join(self.mountpoint, 'file') self.use_mnt_cmd = ("%s -c 'import time; f = open(\"%s\", \"w\"); " "time.sleep(60)'" % (sys.executable, self.use_mnt_file)) def run_process_to_use_mnt(self): proc = process.SubProcess(self.use_mnt_cmd, sudo=True) proc.start() self.assertTrue( wait.wait_for(lambda: os.path.exists(self.use_mnt_file), timeout=1, first=0.1, step=0.1), "File was not created within mountpoint") return proc @unittest.skipIf(missing_binary('lsof'), "requires running lsof") @unittest.skipIf(not process.can_sudo(sys.executable + " -c ''"), "requires running Python as a privileged user") @unittest.skipIf(not process.can_sudo('kill -l'), "requires running kill as a privileged user") def test_force_unmount(self): """ Test force-unmount feature """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = self.run_process_to_use_mnt() self.assertTrue(self.disk.unmount()) # Process should return -9, or when sudo is used # return code is 137 self.assertIn( proc.poll(), [-9, 137], "Unexpected return code when trying to kill process " "using the mountpoint") with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) @unittest.skipIf(not process.can_sudo(sys.executable + " -c ''"), "requires running Python as a privileged user") @unittest.skipUnless(missing_binary('lsof'), "requires not having lsof") def test_force_unmount_no_lsof(self): """ Checks that a force-unmount will fail on systems without lsof """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = self.run_process_to_use_mnt() self.assertRaises(partition.PartitionError, self.disk.unmount) proc.wait(timeout=1) @unittest.skipIf(not process.can_sudo(sys.executable + " -c ''"), "requires running Python as a privileged user") def test_force_unmount_get_pids_fail(self): """ Checks PartitionError is raised if there's no lsof to get pids """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = self.run_process_to_use_mnt() with unittest.mock.patch('avocado.utils.partition.process.run', side_effect=process.CmdError): with unittest.mock.patch( 'avocado.utils.partition.process.system_output', side_effect=OSError) as mocked_system_output: self.assertRaises(partition.PartitionError, self.disk.unmount) mocked_system_output.assert_called_with('lsof ' + self.mountpoint, sudo=True) self.disk.unmount() proc.wait(timeout=1) def test_double_mount(self): """ Check the attempt for second mount fails """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mount) self.assertIn(self.mountpoint, proc_mounts) def test_double_umount(self): """ Check double unmount works well """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) def test_format_mounted(self): """ Check format on mounted device fails """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mkfs)
class LVUtilsTest(unittest.TestCase): """ Check the LVM related utilities """ @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support LVM') @unittest.skipIf(process.system("which vgs", ignore_status=True), "LVM utils not installed (command vgs is missing)") @unittest.skipIf(not process.can_sudo(), "This test requires root or " "passwordless sudo configured.") def setUp(self): prefix = temp_dir_prefix(__name__, self, 'setUp') self.tmpdir = tempfile.TemporaryDirectory(prefix=prefix) self.vgs = [] def tearDown(self): self.tmpdir.cleanup() for vg_name in self.vgs: lv_utils.vg_remove(vg_name) @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support LVM') @unittest.skipIf( process.system( "vgs --all | grep -q avocado_testing_vg_" "e5kj3erv11a; [ $? -ne 0 ]", sudo=True, shell=True, ignore_status=True), "Unittest volume group already exists.") def test_basic_workflow(self): """ Check the basic workflow works using ramdisk """ ramdisk_filename = vg_ramdisk_dir = loop_device = None vg_name = "avocado_testing_vg_e5kj3erv11a" lv_name = "avocado_testing_lv_lk0ff33al5h" ramdisk_basedir = os.path.join(self.tmpdir.name, "foo", "bar") mount_loc = os.path.join(self.tmpdir.name, "lv_mount_location") os.mkdir(mount_loc) try: # Create ramdisk vg self.assertFalse(os.path.exists(ramdisk_basedir)) self.assertFalse(lv_utils.vg_check(vg_name)) spec = lv_utils.vg_ramdisk(False, vg_name, 10, ramdisk_basedir, "sparse_file") ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device = spec # Check it was created properly self.assertTrue(ramdisk_filename) self.assertTrue(vg_ramdisk_dir) self.assertTrue(vg_name) self.assertTrue(loop_device) self.assertTrue(os.path.exists(ramdisk_basedir)) self.assertTrue(glob.glob(os.path.join(ramdisk_basedir, "*"))) self.assertTrue(lv_utils.vg_check(vg_name)) vgs = lv_utils.vg_list() self.assertIn(vg_name, vgs) # Can't create existing vg self.assertRaises(lv_utils.LVException, lv_utils.vg_create, vg_name, loop_device) # Create and check LV lv_utils.lv_create(vg_name, lv_name, 1) lv_utils.lv_check(vg_name, lv_name) self.assertIn(vg_name, process.run("lvs --all", sudo=True).stdout_text) self.assertIn(lv_name, lv_utils.lv_list()) lv_utils.lv_mount(vg_name, lv_name, mount_loc, "ext2") lv_utils.lv_umount(vg_name, lv_name) lv_utils.lv_remove(vg_name, lv_name) self.assertNotIn(lv_name, lv_utils.lv_list()) # Cleanup ramdisk vgs lv_utils.vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device) self.assertTrue(os.path.exists(ramdisk_basedir)) self.assertFalse(glob.glob(os.path.join(ramdisk_basedir, "*"))) except BaseException as details: try: process.run("mountpoint %s && umount %s" % (mount_loc, mount_loc), shell=True, sudo=True) except BaseException as details: print("Fail to unmount LV: %s" % details) try: lv_utils.lv_remove(vg_name, lv_name) except BaseException as details: print("Fail to cleanup LV: %s" % details) try: lv_utils.vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device) except BaseException as details: print("Fail to cleanup vg_ramdisk: %s" % details)
class TestPartition(unittest.TestCase): """ Unit tests for avocado.utils.partition """ @unittest.skipIf(not os.path.isdir('/proc/mounts'), 'system does not have /proc/mounts') @unittest.skipIf(not process.can_sudo('mount'), 'current user must be allowed to run "mount" under sudo') @unittest.skipIf(not process.can_sudo('mkfs.ext2 -V'), 'current user must be allowed to run "mkfs.ext2" under ' 'sudo') def setUp(self): self.tmpdir = tempfile.mkdtemp(prefix="avocado_" + __name__) self.mountpoint = os.path.join(self.tmpdir, "disk") os.mkdir(self.mountpoint) self.disk = partition.Partition(os.path.join(self.tmpdir, "block"), 1, self.mountpoint) def test_basic(self): """ Test the basic workflow """ self.assertEqual(None, self.disk.get_mountpoint()) self.disk.mkfs() self.disk.mount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertEqual(self.mountpoint, self.disk.get_mountpoint()) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) @unittest.skipIf(not process.can_sudo('kill -l'), "requires running kill as a privileged user") def test_force_unmount(self): """ Test force-unmount feature """ self.disk.mkfs() self.disk.mount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = process.SubProcess("cd %s; while :; do echo a > a; rm a; done" % self.mountpoint, shell=True) proc.start() self.assertTrue(self.disk.unmount()) self.assertEqual(proc.poll(), -9) # Process should be killed -9 with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) def test_double_mount(self): """ Check the attempt for second mount fails """ self.disk.mkfs() self.disk.mount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mount) self.assertIn(self.mountpoint, proc_mounts) def test_double_umount(self): """ Check double unmount works well """ self.disk.mkfs() self.disk.mount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) def test_format_mounted(self): """ Check format on mounted device fails """ self.disk.mkfs() self.disk.mount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mkfs) def tearDown(self): self.disk.unmount() shutil.rmtree(self.tmpdir)
class TestPartitionMkfsMount(Base): """ Tests that assume a filesystem and mounted partition """ def setUp(self): super(TestPartitionMkfsMount, self).setUp() self.disk.mkfs() self.disk.mount() @unittest.skipIf(missing_binary('lsof'), "requires running lsof") @unittest.skipIf(not process.can_sudo('kill -l'), "requires running kill as a privileged user") def test_force_unmount(self): """ Test force-unmount feature """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = process.SubProcess( "cd %s; while :; do echo a > a; rm a; done" % self.mountpoint, shell=True) proc.start() self.assertTrue(self.disk.unmount()) self.assertEqual(proc.poll(), -9) # Process should be killed -9 with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) @unittest.skipUnless(missing_binary('lsof'), "requires not having lsof") def test_force_unmount_no_lsof(self): """ Checks that a force-unmount will fail on systems without lsof """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = process.SubProcess( "cd %s; while :; do echo a > a; rm a; done" % self.mountpoint, shell=True) proc.start() self.assertRaises(partition.PartitionError, self.disk.unmount) proc.terminate() proc.wait() def test_force_unmount_get_pids_fail(self): """ Checks PartitionError is raised if there's no lsof to get pids """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) proc = process.SubProcess( "cd %s; while :; do echo a > a; rm a; done" % self.mountpoint, shell=True) proc.start() with mock.patch('avocado.utils.partition.process.run', side_effect=process.CmdError): with mock.patch( 'avocado.utils.partition.process.system_output', side_effect=OSError) as mocked_system_output: self.assertRaises(partition.PartitionError, self.disk.unmount) mocked_system_output.assert_called_with('lsof ' + self.mountpoint) proc.terminate() proc.wait() def test_double_mount(self): """ Check the attempt for second mount fails """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mount) self.assertIn(self.mountpoint, proc_mounts) def test_double_umount(self): """ Check double unmount works well """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) self.disk.unmount() with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertNotIn(self.mountpoint, proc_mounts) def test_format_mounted(self): """ Check format on mounted device fails """ with open("/proc/mounts") as proc_mounts_file: proc_mounts = proc_mounts_file.read() self.assertIn(self.mountpoint, proc_mounts) self.assertRaises(partition.PartitionError, self.disk.mkfs)
class LVUtilsTest(unittest.TestCase): """ Check the LVM related utilities """ @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support LVM') @unittest.skipIf(process.system("which vgs", ignore_status=True), "LVM utils not installed (command vgs is missing)") @unittest.skipIf(not process.can_sudo(), "This test requires root or " "passwordless sudo configured.") def setUp(self): self.tmpdir = tempfile.mkdtemp(prefix='avocado_' + __name__) self.vgs = [] def tearDown(self): shutil.rmtree(self.tmpdir) for vg_name in self.vgs: lv_utils.vg_remove(vg_name) @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support LVM') @unittest.skipIf(process.system("modinfo scsi_debug", shell=True, ignore_status=True), "Kernel mod 'scsi_debug' not available.") @unittest.skipIf(process.system("lsmod | grep -q scsi_debug; [ $? -ne 0 ]", shell=True, ignore_status=True), "Kernel mod 'scsi_debug' is already loaded.") def test_get_diskspace(self): """ Use scsi_debug device to check disk size """ pre = glob.glob("/dev/sd*") try: process.system("modprobe scsi_debug", sudo=True) disks = set(glob.glob("/dev/sd*")).difference(pre) self.assertEqual(len(disks), 1, "pre: %s\npost: %s" % (disks, glob.glob("/dev/sd*"))) disk = disks.pop() self.assertEqual(lv_utils.get_diskspace(disk), "8388608") except BaseException: for _ in xrange(10): res = process.run("rmmod scsi_debug", ignore_status=True, sudo=True) if not res.exit_status: print("scsi_debug removed") break else: print("Fail to remove scsi_debug: %s" % res) for _ in xrange(10): res = process.run("rmmod scsi_debug", ignore_status=True, sudo=True) if not res.exit_status: break else: self.fail("Fail to remove scsi_debug after testing: %s" % res) @unittest.skipIf(sys.platform.startswith('darwin'), 'macOS does not support LVM') @unittest.skipIf(process.system("vgs --all | grep -q avocado_testing_vg_" "e5kj3erv11a; [ $? -ne 0 ]", sudo=True, shell=True, ignore_status=True), "Unittest volume group already exists.") def test_basic_workflow(self): """ Check the basic workflow works using ramdisk """ ramdisk_filename = vg_ramdisk_dir = loop_device = None vg_name = "avocado_testing_vg_e5kj3erv11a" lv_name = "avocado_testing_lv_lk0ff33al5h" ramdisk_basedir = os.path.join(self.tmpdir, "foo", "bar") mount_loc = os.path.join(self.tmpdir, "lv_mount_location") os.mkdir(mount_loc) try: # Create ramdisk vg self.assertFalse(os.path.exists(ramdisk_basedir)) self.assertFalse(lv_utils.vg_check(vg_name)) spec = lv_utils.vg_ramdisk(False, vg_name, 10, ramdisk_basedir, "sparse_file") ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device = spec # Check it was created properly self.assertTrue(ramdisk_filename) self.assertTrue(vg_ramdisk_dir) self.assertTrue(vg_name) self.assertTrue(loop_device) self.assertTrue(os.path.exists(ramdisk_basedir)) self.assertTrue(glob.glob(os.path.join(ramdisk_basedir, "*"))) self.assertTrue(lv_utils.vg_check(vg_name)) vgs = lv_utils.vg_list() self.assertIn(vg_name, vgs) # Can't create existing vg self.assertRaises(lv_utils.LVException, lv_utils.vg_create, vg_name, loop_device) # Create and check LV lv_utils.lv_create(vg_name, lv_name, 1) lv_utils.lv_check(vg_name, lv_name) self.assertIn(vg_name, process.system_output("lvs --all", sudo=True)) self.assertIn(lv_name, lv_utils.lv_list()) lv_utils.lv_mount(vg_name, lv_name, mount_loc, "ext2") lv_utils.lv_umount(vg_name, lv_name) lv_utils.lv_remove(vg_name, lv_name) self.assertNotIn(lv_name, lv_utils.lv_list()) # Cleanup ramdisk vgs lv_utils.vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device) self.assertTrue(os.path.exists(ramdisk_basedir)) self.assertFalse(glob.glob(os.path.join(ramdisk_basedir, "*"))) except BaseException as details: try: process.run("mountpoint %s && umount %s" % (mount_loc, mount_loc), shell=True, sudo=True) except BaseException as details: print("Fail to unmount LV: %s" % details) try: lv_utils.lv_remove(vg_name, lv_name) except BaseException as details: print("Fail to cleanup LV: %s" % details) try: lv_utils.vg_ramdisk_cleanup(ramdisk_filename, vg_ramdisk_dir, vg_name, loop_device) except BaseException as details: print("Fail to cleanup vg_ramdisk: %s" % details) raise