master - tests: better check for python libpath
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=99cd7108d3c589fb8eb...
Commit: 99cd7108d3c589fb8ebbd636c98881cfee30e868
Parent: f8745dc23e8c3e0b2850a0982d251f112d653179
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:57:29 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
tests: better check for python libpath
Find also python3 lvm.so name.
And ATM just run a single test, otherwise we get too many cores.
---
test/api/pytest.sh | 4 +++-
1 files changed, 3 insertions(+), 1 deletions(-)
diff --git a/test/api/pytest.sh b/test/api/pytest.sh
index 2581768..bf31b39 100644
--- a/test/api/pytest.sh
+++ b/test/api/pytest.sh
@@ -31,7 +31,7 @@ aux prepare_dmeventd
#Locate the python binding library to use.
if [[ -n "${abs_top_builddir+varset}" ]]; then
- python_lib=($(find "$abs_top_builddir" -name lvm.so))
+ python_lib=($(find "$abs_top_builddir" -name lvm*.so))
if [[ ${#python_lib[*]} -ne 1 ]]; then
if [[ ${#python_lib[*]} -gt 1 ]]; then
# Unable to test python bindings if multiple libraries found:
@@ -58,6 +58,8 @@ aux prepare_pvs 6
PY_UNIT_PVS=$(cat DEVICES)
export PY_UNIT_PVS
+python_lvm_unit.py -v -f TestLvm.test_lv_persistence
+exit
#python_lvm_unit.py -v -f
# Run individual tests for shorter error trace
5 years, 11 months
master - python: specify libdm path for linking
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f8745dc23e8c3e0b285...
Commit: f8745dc23e8c3e0b2850a0982d251f112d653179
Parent: 550380c1a48697d6c5bc63b4d63c4b1d772dd14a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:54:58 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
python: specify libdm path for linking
---
python/setup.py.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/python/setup.py.in b/python/setup.py.in
index dac999a..d09b791 100644
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -21,7 +21,7 @@ from distutils.core import setup, Extension
liblvm = Extension('lvm',
sources = ['liblvm_python.c'],
libraries= ['lvm2app', 'devmapper'],
- library_dirs= ['@top_builddir@/liblvm'],
+ library_dirs= ['@top_builddir@/liblvm', '@top_builddir@/libdm'],
include_dirs= ['@top_builddir@/include'])
setup (name='lvm',
5 years, 11 months
master - tests: aux fixes
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=550380c1a48697d6c5b...
Commit: 550380c1a48697d6c5bc63b4d63c4b1d772dd14a
Parent: 3b3ee66b1f86518ef39a1b88a868083f9d2fc4e7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:53:05 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
tests: aux fixes
Properly check for kernel version.
Also detect sysfs throttling support.
---
test/lib/aux.sh | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/test/lib/aux.sh b/test/lib/aux.sh
index de3f218..5b2aebf 100644
--- a/test/lib/aux.sh
+++ b/test/lib/aux.sh
@@ -843,7 +843,7 @@ prepare_backing_dev() {
return 0
elif test "${LVM_TEST_PREFER_BRD-1}" = "1" && \
test ! -d /sys/block/ram0 && \
- test kernel_at_least 4 16 && \
+ kernel_at_least 4 16 && \
test "$size" -lt 16384; then
# try to use ramdisk if possible, but for
# big allocs (>16G) do not try to use ramdisk
@@ -1067,6 +1067,7 @@ enable_dev() {
# Throttle down performance of kcopyd when mirroring i.e. disk image
throttle_sys="/sys/module/dm_mirror/parameters/raid1_resync_throttle"
throttle_dm_mirror() {
+ test -e "$throttle_sys" || return
test -f THROTTLE || cat "$throttle_sys" > THROTTLE
echo ${1-1} > "$throttle_sys"
}
5 years, 11 months
master - tests: time limit waiting on lvmetad kill
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3b3ee66b1f86518ef39...
Commit: 3b3ee66b1f86518ef39a1b88a868083f9d2fc4e7
Parent: b5da4fdfcebb5a9c2c32b64b27a12f6480829a97
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:52:05 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
tests: time limit waiting on lvmetad kill
---
test/shell/lvmetad-disabled.sh | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvmetad-disabled.sh b/test/shell/lvmetad-disabled.sh
index 0f180c7..84d7b54 100644
--- a/test/shell/lvmetad-disabled.sh
+++ b/test/shell/lvmetad-disabled.sh
@@ -19,7 +19,11 @@ SKIP_WITH_LVMPOLLD=1
aux prepare_devs 2
kill "$(< LOCAL_LVMETAD)"
-while test -e "$TESTDIR/lvmetad.socket"; do echo -n .; sleep .1; done # wait for the socket close
+for i in {200..0} ; do
+ test -e "$TESTDIR/lvmetad.socket" || break
+ test "$i" -eq 0 && die "Too slow closing of lvmetad.socket. Aborting test."
+ echo -n .; sleep .1;
+done # wait for the socket close
test ! -e "$LVM_LVMETAD_PIDFILE"
aux lvmconf "global/use_lvmetad = 0"
5 years, 11 months
master - tests: move into generated file
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=be154e30e895bf08e00...
Commit: be154e30e895bf08e00a8cf32ceb79b7c0f4b5a6
Parent: ad756bb7083743b612d3fc66b268b605576f448a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:40:32 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
tests: move into generated file
Since python path is evaluated and we cannot use anymore /usr/bin/env
switch to generated file.
---
configure | 3 +-
configure.ac | 1 +
test/api/python_lvm_unit.py | 1048 ----------------------------------------
test/api/python_lvm_unit.py.in | 1048 ++++++++++++++++++++++++++++++++++++++++
4 files changed, 1051 insertions(+), 1049 deletions(-)
diff --git a/configure b/configure
index ce70d92..7d945df 100755
--- a/configure
+++ b/configure
@@ -15559,7 +15559,7 @@ _ACEOF
################################################################################
-ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile device_mapper/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/
libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_
init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile"
+ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/dmfilemapd/Makefile daemons/lvmdbusd/Makefile daemons/lvmdbusd/lvmdbusd daemons/lvmdbusd/lvmdb.py daemons/lvmdbusd/lvm_shell_proxy.py daemons/lvmdbusd/path.py daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile device_mapper/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/locking/Makefile include/lvm-version.h libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/
libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/com.redhat.lvmdbus1.service scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmdbusd_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_
init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/lvmdump.sh scripts/Makefile test/Makefile test/api/Makefile test/api/python_lvm_unit.py test/unit/Makefile tools/Makefile udev/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -16327,6 +16327,7 @@ do
"scripts/Makefile") CONFIG_FILES="$CONFIG_FILES scripts/Makefile" ;;
"test/Makefile") CONFIG_FILES="$CONFIG_FILES test/Makefile" ;;
"test/api/Makefile") CONFIG_FILES="$CONFIG_FILES test/api/Makefile" ;;
+ "test/api/python_lvm_unit.py") CONFIG_FILES="$CONFIG_FILES test/api/python_lvm_unit.py" ;;
"test/unit/Makefile") CONFIG_FILES="$CONFIG_FILES test/unit/Makefile" ;;
"tools/Makefile") CONFIG_FILES="$CONFIG_FILES tools/Makefile" ;;
"udev/Makefile") CONFIG_FILES="$CONFIG_FILES udev/Makefile" ;;
diff --git a/configure.ac b/configure.ac
index 7b517ef..e427708 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2159,6 +2159,7 @@ scripts/lvmdump.sh
scripts/Makefile
test/Makefile
test/api/Makefile
+test/api/python_lvm_unit.py
test/unit/Makefile
tools/Makefile
udev/Makefile
diff --git a/test/api/python_lvm_unit.py b/test/api/python_lvm_unit.py
deleted file mode 100755
index 296ca14..0000000
--- a/test/api/python_lvm_unit.py
+++ /dev/null
@@ -1,1048 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
-#
-# This file is part of LVM2.
-#
-# This copyrighted material is made available to anyone wishing to use,
-# modify, copy, or redistribute it subject to the terms and conditions
-# of the GNU General Public License v.2.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-
-import unittest
-import random
-import string
-import lvm
-import os
-import itertools
-import sys
-
-if sys.version_info[0] > 2:
- long = int
-
-# Set of basic unit tests for the python bindings.
-#
-# *** WARNING ***
-#
-# This test tries to only modify configuration for the list of allowed
-# PVs, but an error in it could potentially cause data loss if run on a
-# production system. Therefore it is strongly advised that this unit test
-# not be run on a system that contains data of value.
-
-fh = None
-
-
-def l(txt):
- if os.environ.get('PY_UNIT_LOG') is not None:
- global fh
- if fh is None:
- fh = open('/tmp/lvm_py_unit_test_' + rs(10), "a")
- fh.write(txt + "\n")
- fh.flush()
-
-
-def rs(rand_len=10):
- """
- Generate a random string
- """
- return ''.join(
- random.choice(string.ascii_uppercase)for x in range(rand_len))
-
-
-def _get_allowed_devices():
- rc = os.environ.get('PY_UNIT_PVS')
- if rc is not None:
- rc = rc.splitlines()
- rc.sort()
- return rc
-
-
-class AllowedPVS(object):
- """
- We are only allowed to muck with certain PV, filter to only
- the ones we can use.
- """
-
- def __init__(self):
- self.handle = None
- self.pvs_all = None
-
- def __enter__(self):
- rc = []
-
- allowed_dev = _get_allowed_devices()
-
- if allowed_dev:
- self.handle = lvm.listPvs()
- self.pvs_all = self.handle.open()
-
- for p in self.pvs_all:
- if p.getName() in allowed_dev:
- rc.append(p)
-
- #Sort them consistently
- rc.sort(key=lambda x: x.getName())
- return rc
-
- def __exit__(self, t_type, value, traceback):
- if self.handle:
- self.pvs_all = None
- self.handle.close()
-
-
-class TestLvm(unittest.TestCase):
-
- VG_P = os.environ.get('PREFIX')
-
- @staticmethod
- def _get_pv_device_names():
- rc = []
- with AllowedPVS() as pvs:
- for p in pvs:
- rc.append(p.getName())
- return rc
-
- @staticmethod
- def _create_thick_lv(device_list, name):
- vg = lvm.vgCreate(TestLvm.VG_P + "_" + name)
-
- for d in device_list:
- vg.extend(d)
-
- vg.createLvLinear(name, vg.getSize() / 2)
- vg.close()
- vg = None
-
- @staticmethod
- def _create_thin_pool(device_list, pool_name):
- vg = lvm.vgCreate(TestLvm.VG_P + "_" + pool_name)
-
- for d in device_list:
- vg.extend(d)
-
- vg.createLvThinpool(
- pool_name, vg.getSize() / 2, 0, 0, lvm.THIN_DISCARDS_PASSDOWN, 1)
- return vg
-
- @staticmethod
- def _create_thin_lv(pv_devices, name):
- thin_pool_name = 'thin_vg_pool_' + rs(4)
- vg = TestLvm._create_thin_pool(pv_devices, thin_pool_name)
- vg.createLvThin(thin_pool_name, name, vg.getSize() / 8)
- vg.close()
- vg = None
-
- @staticmethod
- def _vg_names():
- rc = []
- vg_names = lvm.listVgNames()
-
- for i in vg_names:
- if i[0:len(TestLvm.VG_P)] == TestLvm.VG_P:
- rc.append(i)
-
- return rc
-
- @staticmethod
- def _get_lv(lv_vol_type=None, lv_name=None):
- vg_name_list = TestLvm._vg_names()
- for vg_name in vg_name_list:
- vg = lvm.vgOpen(vg_name, "w")
- lvs = vg.listLVs()
-
- for lv in lvs:
- attr = lv.getAttr()
- if lv_vol_type or lv_name:
- if lv_vol_type is not None and attr[0] == lv_vol_type:
- return lv, vg
- elif lv_name is not None and lv_name == lv.getName():
- return lv, vg
- else:
- return lv, vg
- vg.close()
- return None, None
-
- @staticmethod
- def _remove_vg(vg_name):
- vg = lvm.vgOpen(vg_name, 'w')
-
- pvs = vg.listPVs()
-
- pe_devices = []
-
- #Remove old snapshots first, then lv
- for lv in vg.listLVs():
- attr = lv.getAttr()
- if attr[0] == 's':
- lv.remove()
-
- lvs = vg.listLVs()
-
- #Now remove any thin lVs
- for lv in vg.listLVs():
- attr = lv.getAttr()
- if attr[0] == 'V':
- lv.remove()
-
- #now remove the rest
- for lv in vg.listLVs():
- name = lv.getName()
-
- #Don't remove the hidden ones
- if '_tmeta' not in name and '_tdata' not in name:
- lv.remove()
-
- for p in pvs:
- pe_devices.append(p.getName())
-
- for pv in pe_devices[:-1]:
- vg.reduce(pv)
-
- vg.remove()
- vg.close()
-
- @staticmethod
- def _clean_up():
- #Clear out the testing PVs, but only if they contain stuff
- #this unit test created
- for vg_n in TestLvm._vg_names():
- TestLvm._remove_vg(vg_n)
-
- for d in TestLvm._get_pv_device_names():
- lvm.pvRemove(d)
- lvm.pvCreate(d)
-
- def setUp(self):
- device_list = TestLvm._get_pv_device_names()
-
- #Make sure we have an adequate number of PVs to use
- self.assertTrue(len(device_list) >= 4)
- TestLvm._clean_up()
-
- def tearDown(self):
- TestLvm._clean_up()
-
- def test_pv_resize(self):
- with AllowedPVS() as pvs:
- pv = pvs[0]
- curr_size = pv.getSize()
- dev_size = pv.getDevSize()
- self.assertTrue(curr_size == dev_size)
- pv.resize(curr_size / 2)
- with AllowedPVS() as pvs:
- pv = pvs[0]
- resized_size = pv.getSize()
- self.assertTrue(resized_size != curr_size)
- pv.resize(dev_size)
-
- def test_pv_life_cycle(self):
- """
- Test removing and re-creating a PV
- """
- target_name = None
-
- with AllowedPVS() as pvs:
- pv = pvs[0]
- target_name = pv.getName()
- lvm.pvRemove(target_name)
-
- with AllowedPVS() as pvs:
- for p in pvs:
- self.assertTrue(p.getName() != target_name)
-
- lvm.pvCreate(target_name, 0)
-
- with AllowedPVS() as pvs:
- found = False
- for p in pvs:
- if p.getName() == target_name:
- found = True
-
- self.assertTrue(found)
-
- @staticmethod
- def _test_pv_methods():
- with AllowedPVS() as pvs:
- for p in pvs:
- p.getName()
- p.getUuid()
- p.getMdaCount()
- p.getSize()
- p.getDevSize()
- p.getFree()
- p = None
-
- def test_version(self):
- version = lvm.getVersion()
- self.assertNotEquals(version, None)
- self.assertEquals(type(version), str)
- self.assertTrue(len(version) > 0)
-
- def test_pv_getters(self):
- with AllowedPVS() as pvs:
- pv = pvs[0]
- self.assertEqual(type(pv.getName()), str)
- self.assertTrue(len(pv.getName()) > 0)
-
- self.assertEqual(type(pv.getUuid()), str)
- self.assertTrue(len(pv.getUuid()) > 0)
-
- self.assertTrue(
- type(pv.getMdaCount()) == int or
- type(pv.getMdaCount()) == long)
-
- self.assertTrue(
- type(pv.getSize()) == int or
- type(pv.getSize()) == long)
-
- self.assertTrue(
- type(pv.getDevSize()) == int or
- type(pv.getSize()) == long)
-
- self.assertTrue(
- type(pv.getFree()) == int or
- type(pv.getFree()) == long)
-
- def _test_prop(self, prop_obj, prop, var_type, settable):
- result = prop_obj.getProperty(prop)
-
- #If we have no string value we can get a None type back
- if result[0] is not None:
- self.assertEqual(type(result[0]), var_type)
- else:
- self.assertTrue(str == var_type)
- self.assertEqual(type(result[1]), bool)
- self.assertTrue(result[1] == settable)
-
- def test_pv_segs(self):
- with AllowedPVS() as pvs:
- pv = pvs[0]
- pv_segs = pv.listPVsegs()
-
- #LVsegs returns a tuple, (value, bool settable)
- #TODO: Test other properties of pv_seg
- for i in pv_segs:
- self._test_prop(i, 'pvseg_start', long, False)
-
- def test_pv_property(self):
- with AllowedPVS() as pvs:
- pv = pvs[0]
- self._test_prop(pv, 'pv_mda_count', long, False)
-
- def test_lv_property(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- lv_seg_properties = [
- ('chunk_size', long, False), ('devices', str, False),
- ('discards', str, False), ('region_size', long, False),
- ('segtype', str, False), ('seg_pe_ranges', str, False),
- ('seg_size', long, False), ('seg_size_pe', long, False),
- ('seg_start', long, False), ('seg_start_pe', long, False),
- ('seg_tags', str, False), ('stripes', long, False),
- ('stripe_size', long, False), ('thin_count', long, False),
- ('transaction_id', long, False), ('zero', long, False)]
-
- lv_properties = [
- ('convert_lv', str, False), ('copy_percent', long, False),
- ('data_lv', str, False), ('lv_attr', str, False),
- ('lv_host', str, False), ('lv_kernel_major', long, False),
- ('lv_kernel_minor', long, False),
- ('lv_kernel_read_ahead', long, False),
- ('lv_major', long, False), ('lv_minor', long, False),
- ('lv_name', str, False), ('lv_path', str, False),
- ('lv_profile', str, False), ('lv_read_ahead', long, False),
- ('lv_size', long, False), ('lv_tags', str, False),
- ('lv_time', str, False), ('lv_uuid', str, False),
- ('metadata_lv', str, False), ('mirror_log', str, False),
- ('lv_modules', str, False), ('move_pv', str, False),
- ('origin', str, False), ('origin_size', long, False),
- ('pool_lv', str, False), ('raid_max_recovery_rate', long, False),
- ('raid_min_recovery_rate', long, False),
- ('raid_mismatch_count', long, False),
- ('raid_sync_action', str, False),
- ('raid_write_behind', long, False), ('seg_count', long, False),
- ('snap_percent', long, False), ('sync_percent', long, False)]
-
- # Generic test case, make sure we get what we expect
- for t in lv_properties:
- self._test_prop(lv, *t)
-
- segments = lv.listLVsegs()
- if segments and len(segments):
- for s in segments:
- for t in lv_seg_properties:
- self._test_prop(s, *t)
-
- # Test specific cases
- tag = 'hello_world'
- lv.addTag(tag)
- tags = lv.getProperty('lv_tags')
- self.assertTrue(tag in tags[0])
- vg.close()
-
- def test_lv_tags(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
- self._test_tags(lv)
- vg.close()
-
- def test_lv_active_inactive(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
- lv.deactivate()
- self.assertTrue(lv.isActive() is False)
- lv.activate()
- self.assertTrue(lv.isActive() is True)
- vg.close()
-
- def test_lv_rename(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- current_name = lv.getName()
- new_name = rs()
- lv.rename(new_name)
- self.assertEqual(lv.getName(), new_name)
- lv.rename(current_name)
- vg.close()
-
- def test_lv_persistence(self):
- # Make changes to the lv, close the vg and re-open to make sure that
- # the changes persist
- lv_name = 'lv_test_persist'
- TestLvm._create_thick_lv(TestLvm._get_pv_device_names(), lv_name)
-
- # Test rename
- lv, vg = TestLvm._get_lv(None, lv_name)
- current_name = lv.getName()
- new_name = rs()
- lv.rename(new_name)
-
- vg.close()
- vg = None
-
- lv, vg = TestLvm._get_lv(None, new_name)
-
- self.assertTrue(lv is not None)
-
- if lv and vg:
- lv.rename(lv_name)
- vg.close()
- vg = None
-
- # Test lv tag add
- tag = 'hello_world'
-
- lv, vg = TestLvm._get_lv(None, lv_name)
- lv.addTag(tag)
- vg.close()
- vg = None
-
- lv, vg = TestLvm._get_lv(None, lv_name)
- tags = lv.getTags()
-
- self.assertTrue(tag in tags)
- vg.close()
- vg = None
-
- # Test lv tag delete
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
-
- if lv and vg:
- tags = lv.getTags()
-
- for t in tags:
- lv.removeTag(t)
-
- vg.close()
- vg = None
-
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
-
- if lv and vg:
- tags = lv.getTags()
-
- if tags:
- self.assertEqual(len(tags), 0)
- vg.close()
- vg = None
-
- # Test lv deactivate
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
-
- if lv and vg:
- lv.deactivate()
- vg.close()
- vg = None
-
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
- if lv and vg:
- self.assertFalse(lv.isActive())
- vg.close()
- vg = None
-
- # Test lv activate
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
- if lv and vg:
- lv.activate()
- vg.close()
- vg = None
-
- lv, vg = TestLvm._get_lv(None, lv_name)
- self.assertTrue(lv is not None and vg is not None)
- if lv and vg:
- self.assertTrue(lv.isActive())
- vg.close()
- vg = None
-
- def test_lv_snapshot(self):
-
- thin_lv = 'thin_lv'
- thick_lv = 'thick_lv'
-
- device_names = TestLvm._get_pv_device_names()
-
- TestLvm._create_thin_lv(device_names[0:2], thin_lv)
- TestLvm._create_thick_lv(device_names[2:4], thick_lv)
-
- lv, vg = TestLvm._get_lv(None, thick_lv)
-# FIXME lv.snapshot('thick_snap_shot', 1024*1024)
- vg.close()
-
-# FIXME thick_ss, vg = TestLvm._get_lv(None, 'thick_snap_shot')
-# FIXME self.assertTrue(thick_ss is not None)
-# FIXME vg.close()
-
- thin_lv, vg = TestLvm._get_lv(None, thin_lv)
- thin_lv.snapshot('thin_snap_shot')
- vg.close()
-
- thin_ss, vg = TestLvm._get_lv(None, 'thin_snap_shot')
- self.assertTrue(thin_ss is not None)
-
- origin = thin_ss.getOrigin()
- self.assertTrue(thin_lv, origin)
-
- vg.close()
-
- def test_lv_suspend(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- result = lv.isSuspended()
- self.assertTrue(type(result) == bool)
- vg.close()
-
- def test_lv_size(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- result = lv.getSize()
- self.assertTrue(type(result) == int or type(result) == long)
- vg.close()
-
- def test_lv_resize(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- curr_size = lv.getSize()
- lv.resize(curr_size + (1024 * 1024))
- latest = lv.getSize()
- self.assertTrue(curr_size != latest)
-
- def test_lv_seg(self):
- lv_name = 'lv_test'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- lv_segs = lv.listLVsegs()
-
- #LVsegs returns a tuple, (value, bool settable)
- #TODO: Test other properties of lv_seg
- for i in lv_segs:
- self._test_prop(i, 'seg_start_pe', long, False)
-
- vg.close()
-
- def test_get_set_extend_size(self):
- thick_lv = 'get_set_prop'
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thick_lv(device_names[0:2], thick_lv)
- lv, vg = TestLvm._get_lv(None, thick_lv)
-
- new_extent = 1024 * 1024 * 4
-
- self.assertFalse(
- vg.getExtentSize() != new_extent,
- "Cannot determine if it works if they are the same")
-
- vg.setExtentSize(new_extent)
- self.assertEqual(vg.getExtentSize(), new_extent)
- vg.close()
-
- def test_vg_get_set_prop(self):
- thick_lv = 'get_set_prop'
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thick_lv(device_names[0:2], thick_lv)
- lv, vg = TestLvm._get_lv(None, thick_lv)
-
- self.assertTrue(vg is not None)
- if vg:
- vg_mda_copies = vg.getProperty('vg_mda_copies')
- vg.setProperty('vg_mda_copies', vg_mda_copies[0])
- vg.close()
-
- def test_vg_remove_restore(self):
- #Store off the list of physical devices
- pv_devices = []
-
- thick_lv = 'get_set_prop'
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thick_lv(device_names[0:2], thick_lv)
- lv, vg = TestLvm._get_lv(None, thick_lv)
-
- vg_name = vg.getName()
-
- pvs = vg.listPVs()
- for p in pvs:
- pv_devices.append(p.getName())
- vg.close()
-
- TestLvm._remove_vg(vg_name)
- self._create_thick_lv(pv_devices, thick_lv)
-
- def test_vg_names(self):
- vg = lvm.listVgNames()
- self.assertTrue(isinstance(vg, tuple))
-
- def test_dupe_lv_create(self):
- """
- Try to create a lv with the same name expecting a failure
- Note: This was causing a seg. fault previously
- """
- thick_lv = 'dupe_name'
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thick_lv(device_names[0:2], thick_lv)
- lv, vg = TestLvm._get_lv(None, thick_lv)
-
- self.assertTrue(vg is not None)
-
- if vg:
- lvs = vg.listLVs()
-
- if len(lvs):
- lv = lvs[0]
- lv_name = lv.getName()
- self.assertRaises(
- lvm.LibLVMError, vg.createLvLinear, lv_name, lv.getSize())
- vg.close()
-
- def test_vg_uuids(self):
-
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vgs_uuids = lvm.listVgUuids()
-
- self.assertTrue(len(vgs_uuids) > 0)
- self.assertTrue(isinstance(vgs_uuids, tuple))
-
- vgs_uuids = list(vgs_uuids)
- vgs_names = lvm.listVgNames()
-
- for vg_name in vgs_names:
- vg = lvm.vgOpen(vg_name, "r")
-
- #TODO Write/fix BUG, vg uuid don't match between
- #lvm.listVgUuids and vg.getUuid()
- vg_uuid_search = vg.getUuid().replace('-', '')
-
- self.assertTrue(vg_uuid_search in vgs_uuids)
- vgs_uuids.remove(vg_uuid_search)
- vg.close()
-
- self.assertTrue(len(vgs_uuids) == 0)
-
- def test_pv_lookup_from_vg(self):
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vg_names = TestLvm._vg_names()
-
- self.assertTrue(len(vg_names) > 0)
-
- for vg_name in vg_names:
- vg = lvm.vgOpen(vg_name, 'w')
- pvs = vg.listPVs()
-
- for p in pvs:
- name = p.getName()
- uuid = p.getUuid()
-
- pv_name_lookup = vg.pvFromName(name)
- pv_uuid_lookup = vg.pvFromUuid(uuid)
-
- self.assertTrue(
- pv_name_lookup.getName() == pv_uuid_lookup.getName())
- self.assertTrue(
- pv_name_lookup.getUuid() == pv_uuid_lookup.getUuid())
-
- self.assertTrue(name == pv_name_lookup.getName())
- self.assertTrue(uuid == pv_uuid_lookup.getUuid())
-
- pv_name_lookup = None
- pv_uuid_lookup = None
- p = None
-
- pvs = None
- vg.close()
-
- def test_percent_to_float(self):
- self.assertEqual(lvm.percentToFloat(0), 0.0)
- self.assertEqual(lvm.percentToFloat(1000000), 1.0)
- self.assertEqual(lvm.percentToFloat(1000000 / 2), 0.5)
-
- def test_scan(self):
- self.assertEqual(lvm.scan(), None)
-
- def test_config_reload(self):
- self.assertEqual(lvm.configReload(), None)
-
- def test_config_override(self):
- self.assertEquals(lvm.configOverride("global.test = 1"), None)
-
- def test_config_find_bool(self):
- either_or = lvm.configFindBool("global/fallback_to_local_locking")
- self.assertTrue(type(either_or) == bool)
- self.assertTrue(lvm.configFindBool("global/locking_type"))
-
- def test_vg_from_pv_lookups(self):
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vgname_list = TestLvm._vg_names()
-
- self.assertTrue(len(vgname_list) > 0)
-
- for vg_name in vgname_list:
- vg = lvm.vgOpen(vg_name, 'r')
-
- vg_name = vg.getName()
-
- pv_list = vg.listPVs()
- for pv in pv_list:
- vg_name_from_pv = lvm.vgNameFromPvid(pv.getUuid())
- self.assertEquals(vg_name, vg_name_from_pv)
- self.assertEqual(vg_name, lvm.vgNameFromDevice(pv.getName()))
- vg.close()
-
- def test_vg_get_name(self):
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vgname_list = TestLvm._vg_names()
-
- self.assertTrue(len(vgname_list) > 0)
-
- for vg_name in vgname_list:
- vg = lvm.vgOpen(vg_name, 'r')
- self.assertEqual(vg.getName(), vg_name)
- vg.close()
-
- def test_vg_get_uuid(self):
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vgname_list = TestLvm._vg_names()
-
- self.assertTrue(len(vgname_list) > 0)
-
- for vg_name in vgname_list:
- vg = lvm.vgOpen(vg_name, 'r')
- uuid = vg.getUuid()
- self.assertNotEqual(uuid, None)
- self.assertTrue(len(uuid) > 0)
- vg.close()
-
- RETURN_NUMERIC = [
- "getSeqno", "getSize", "getFreeSize", "getFreeSize",
- "getExtentSize", "getExtentCount", "getFreeExtentCount",
- "getPvCount", "getMaxPv", "getMaxLv"]
-
- def test_vg_getters(self):
- device_names = TestLvm._get_pv_device_names()
- TestLvm._create_thin_lv(device_names[0:2], 'thin')
- TestLvm._create_thick_lv(device_names[2:4], 'thick')
-
- vg_name_list = TestLvm._vg_names()
-
- self.assertTrue(len(vg_name_list) > 0)
-
- for vg_name in vg_name_list:
- vg = lvm.vgOpen(vg_name, 'r')
- self.assertTrue(type(vg.isClustered()) == bool)
- self.assertTrue(type(vg.isExported()) == bool)
- self.assertTrue(type(vg.isPartial()) == bool)
-
- #Loop through the list invoking the method
- for method_name in TestLvm.RETURN_NUMERIC:
- method = getattr(vg, method_name)
- result = method()
- self.assertTrue(type(result) == int or type(result) == long)
-
- vg.close()
-
- def _test_tags(self, tag_obj):
- existing_tags = tag_obj.getTags()
- self.assertTrue(type(existing_tags) == tuple)
-
- num_tags = random.randint(2, 40)
- created_tags = []
-
- for i in range(num_tags):
- tag_name = rs(random.randint(1, 128))
- tag_obj.addTag(tag_name)
- created_tags.append(tag_name)
-
- tags = tag_obj.getTags()
- self.assertTrue(len(existing_tags) + len(created_tags) == len(tags))
-
- num_remove = len(created_tags)
-
- for i in range(num_remove):
- tag_to_remove = created_tags[
- random.randint(0, len(created_tags) - 1)]
-
- created_tags.remove(tag_to_remove)
-
- tag_obj.removeTag(tag_to_remove)
-
- current_tags = tag_obj.getTags()
- self.assertFalse(tag_to_remove in current_tags)
-
- current_tags = tag_obj.getTags()
- self.assertTrue(len(current_tags) == len(existing_tags))
- for e in existing_tags:
- self.assertTrue(e in current_tags)
-
- def test_vg_tags(self):
- device_names = TestLvm._get_pv_device_names()
-
- i = 0
- for d in device_names:
- if i % 2 == 0:
- TestLvm._create_thin_lv([d], "thin_lv%d" % i)
- else:
- TestLvm._create_thick_lv([d], "thick_lv%d" % i)
- i += 1
-
- for vg_name in TestLvm._vg_names():
- vg = lvm.vgOpen(vg_name, 'w')
- self._test_tags(vg)
- vg.close()
-
- @staticmethod
- def _test_listing():
-
- env = os.environ
-
- for k, v in env.items():
- l("%s:%s" % (k, v))
-
- with lvm.listPvs() as pvs:
- for p in pvs:
- l('pv= %s' % p.getName())
-
- l('Checking for VG')
- for v in lvm.listVgNames():
- l('vg= %s' % v)
-
- def test_pv_empty_listing(self):
- #We had a bug where we would seg. fault if we had no PVs.
-
- l('testPVemptylisting entry')
-
- device_names = TestLvm._get_pv_device_names()
-
- for d in device_names:
- l("Removing %s" % d)
- lvm.pvRemove(d)
-
- count = 0
-
- with lvm.listPvs() as pvs:
- for p in pvs:
- count += 1
- l('pv= %s' % p.getName())
-
- self.assertTrue(count == 0)
-
- for d in device_names:
- lvm.pvCreate(d)
-
- def test_pv_create(self):
- size = [0, 1024 * 1024 * 8]
- pvmeta_copies = [0, 1, 2]
- pvmeta_size = [0, 255, 512, 1024]
- data_alignment = [0, 2048, 4096]
- zero = [0, 1]
-
- device_names = TestLvm._get_pv_device_names()
-
- for d in device_names:
- lvm.pvRemove(d)
-
- d = device_names[0]
-
- #Test some error cases
- self.assertRaises(TypeError, lvm.pvCreate, None)
- self.assertRaises(lvm.LibLVMError, lvm.pvCreate, '')
- self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 4)
- self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 4)
- self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 2 ** 34)
- self.assertRaises(
- lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 4096, 2 ** 34)
-
- #Try a number of combinations and permutations
- for s in size:
- for copies in pvmeta_copies:
- for pv_size in pvmeta_size:
- for align in data_alignment:
- for z in zero:
- lvm.pvCreate(d, s, copies, pv_size, align,
- align, z)
- lvm.pvRemove(d)
-
- #Restore
- for d in device_names:
- lvm.pvCreate(d)
-
- def test_vg_reduce(self):
- # Test the case where we try to reduce a vg where the last PV has
- # no metadata copies. In this case the reduce should fail.
- vg_name = TestLvm.VG_P + 'reduce_test'
-
- device_names = TestLvm._get_pv_device_names()
-
- for d in device_names:
- lvm.pvRemove(d)
-
- lvm.pvCreate(device_names[0], 0, 0) # Size all, pvmetadatacopies 0
- lvm.pvCreate(device_names[1])
- lvm.pvCreate(device_names[2])
- lvm.pvCreate(device_names[3])
-
- vg = lvm.vgCreate(vg_name)
-
- vg.extend(device_names[3])
- vg.extend(device_names[2])
- vg.extend(device_names[1])
- vg.extend(device_names[0])
- vg.close()
-
- vg = None
-
- vg = lvm.vgOpen(vg_name, 'w')
-
- vg.reduce(device_names[3])
- vg.reduce(device_names[2])
-
- self.assertRaises(lvm.LibLVMError, vg.reduce, device_names[1])
-
- vg.close()
- vg = None
-
- vg = lvm.vgOpen(vg_name, 'w')
- vg.remove()
- vg.close()
-
- @staticmethod
- def _test_valid_names(method):
- sample = 'azAZ09._-+'
-
- method('x' * 127)
- method('.X')
- method('..X')
-
- for i in range(1, 7):
- tests = (''.join(i) for i in itertools.product(sample, repeat=i))
- for t in tests:
- if t == '.' or t == '..':
- t += 'X'
- elif t.startswith('-'):
- t = 'H' + t
- method(t)
-
- def _test_bad_names(self, method, dupe_name):
- # Test for duplicate name
- self.assertRaises(lvm.LibLVMError, method, dupe_name)
-
- # Test for too long a name
- self.assertRaises(lvm.LibLVMError, method, ('x' * 128))
-
- # Test empty
- self.assertRaises(lvm.LibLVMError, method, '')
-
- # Invalid characters
- self.assertRaises(lvm.LibLVMError, method, '&invalid^char')
-
- # Cannot start with .. and no following characters
- self.assertRaises(lvm.LibLVMError, method, '..')
-
- # Cannot start with . and no following characters
- self.assertRaises(lvm.LibLVMError, method, '.')
-
- # Cannot start with a hyphen
- self.assertRaises(lvm.LibLVMError, method, '-not_good')
-
- def _lv_reserved_names(self, method):
- prefixes = ['snapshot', 'pvmove']
- reserved = [
- '_mlog', '_mimage', '_pmspare', '_rimage', '_rmeta',
- '_vorigin', '_tdata', '_tmeta']
-
- for p in prefixes:
- self.assertRaises(lvm.LibLVMError, method, p + rs(3))
-
- for r in reserved:
- self.assertRaises(lvm.LibLVMError, method, rs(3) + r + rs(1))
- self.assertRaises(lvm.LibLVMError, method, r + rs(1))
-
- def test_vg_lv_name_validate(self):
- lv_name = 'vg_lv_name_validate'
- TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
- lv, vg = TestLvm._get_lv(None, lv_name)
-
- self._test_bad_names(lvm.vgNameValidate, vg.getName())
- self._test_bad_names(vg.lvNameValidate, lv.getName())
-
- # Test good values
- TestLvm._test_valid_names(lvm.vgNameValidate)
- TestLvm._test_valid_names(vg.lvNameValidate)
- self._lv_reserved_names(vg.lvNameValidate)
-
- vg.close()
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/test/api/python_lvm_unit.py.in b/test/api/python_lvm_unit.py.in
new file mode 100755
index 0000000..2f9cbb5
--- /dev/null
+++ b/test/api/python_lvm_unit.py.in
@@ -0,0 +1,1048 @@
+#!@PYTHON@
+
+# Copyright (C) 2012-2013 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import unittest
+import random
+import string
+import lvm
+import os
+import itertools
+import sys
+
+if sys.version_info[0] > 2:
+ long = int
+
+# Set of basic unit tests for the python bindings.
+#
+# *** WARNING ***
+#
+# This test tries to only modify configuration for the list of allowed
+# PVs, but an error in it could potentially cause data loss if run on a
+# production system. Therefore it is strongly advised that this unit test
+# not be run on a system that contains data of value.
+
+fh = None
+
+
+def l(txt):
+ if os.environ.get('PY_UNIT_LOG') is not None:
+ global fh
+ if fh is None:
+ fh = open('/tmp/lvm_py_unit_test_' + rs(10), "a")
+ fh.write(txt + "\n")
+ fh.flush()
+
+
+def rs(rand_len=10):
+ """
+ Generate a random string
+ """
+ return ''.join(
+ random.choice(string.ascii_uppercase)for x in range(rand_len))
+
+
+def _get_allowed_devices():
+ rc = os.environ.get('PY_UNIT_PVS')
+ if rc is not None:
+ rc = rc.splitlines()
+ rc.sort()
+ return rc
+
+
+class AllowedPVS(object):
+ """
+ We are only allowed to muck with certain PV, filter to only
+ the ones we can use.
+ """
+
+ def __init__(self):
+ self.handle = None
+ self.pvs_all = None
+
+ def __enter__(self):
+ rc = []
+
+ allowed_dev = _get_allowed_devices()
+
+ if allowed_dev:
+ self.handle = lvm.listPvs()
+ self.pvs_all = self.handle.open()
+
+ for p in self.pvs_all:
+ if p.getName() in allowed_dev:
+ rc.append(p)
+
+ #Sort them consistently
+ rc.sort(key=lambda x: x.getName())
+ return rc
+
+ def __exit__(self, t_type, value, traceback):
+ if self.handle:
+ self.pvs_all = None
+ self.handle.close()
+
+
+class TestLvm(unittest.TestCase):
+
+ VG_P = os.environ.get('PREFIX')
+
+ @staticmethod
+ def _get_pv_device_names():
+ rc = []
+ with AllowedPVS() as pvs:
+ for p in pvs:
+ rc.append(p.getName())
+ return rc
+
+ @staticmethod
+ def _create_thick_lv(device_list, name):
+ vg = lvm.vgCreate(TestLvm.VG_P + "_" + name)
+
+ for d in device_list:
+ vg.extend(d)
+
+ vg.createLvLinear(name, vg.getSize() / 2)
+ vg.close()
+ vg = None
+
+ @staticmethod
+ def _create_thin_pool(device_list, pool_name):
+ vg = lvm.vgCreate(TestLvm.VG_P + "_" + pool_name)
+
+ for d in device_list:
+ vg.extend(d)
+
+ vg.createLvThinpool(
+ pool_name, vg.getSize() / 2, 0, 0, lvm.THIN_DISCARDS_PASSDOWN, 1)
+ return vg
+
+ @staticmethod
+ def _create_thin_lv(pv_devices, name):
+ thin_pool_name = 'thin_vg_pool_' + rs(4)
+ vg = TestLvm._create_thin_pool(pv_devices, thin_pool_name)
+ vg.createLvThin(thin_pool_name, name, vg.getSize() / 8)
+ vg.close()
+ vg = None
+
+ @staticmethod
+ def _vg_names():
+ rc = []
+ vg_names = lvm.listVgNames()
+
+ for i in vg_names:
+ if i[0:len(TestLvm.VG_P)] == TestLvm.VG_P:
+ rc.append(i)
+
+ return rc
+
+ @staticmethod
+ def _get_lv(lv_vol_type=None, lv_name=None):
+ vg_name_list = TestLvm._vg_names()
+ for vg_name in vg_name_list:
+ vg = lvm.vgOpen(vg_name, "w")
+ lvs = vg.listLVs()
+
+ for lv in lvs:
+ attr = lv.getAttr()
+ if lv_vol_type or lv_name:
+ if lv_vol_type is not None and attr[0] == lv_vol_type:
+ return lv, vg
+ elif lv_name is not None and lv_name == lv.getName():
+ return lv, vg
+ else:
+ return lv, vg
+ vg.close()
+ return None, None
+
+ @staticmethod
+ def _remove_vg(vg_name):
+ vg = lvm.vgOpen(vg_name, 'w')
+
+ pvs = vg.listPVs()
+
+ pe_devices = []
+
+ #Remove old snapshots first, then lv
+ for lv in vg.listLVs():
+ attr = lv.getAttr()
+ if attr[0] == 's':
+ lv.remove()
+
+ lvs = vg.listLVs()
+
+ #Now remove any thin lVs
+ for lv in vg.listLVs():
+ attr = lv.getAttr()
+ if attr[0] == 'V':
+ lv.remove()
+
+ #now remove the rest
+ for lv in vg.listLVs():
+ name = lv.getName()
+
+ #Don't remove the hidden ones
+ if '_tmeta' not in name and '_tdata' not in name:
+ lv.remove()
+
+ for p in pvs:
+ pe_devices.append(p.getName())
+
+ for pv in pe_devices[:-1]:
+ vg.reduce(pv)
+
+ vg.remove()
+ vg.close()
+
+ @staticmethod
+ def _clean_up():
+ #Clear out the testing PVs, but only if they contain stuff
+ #this unit test created
+ for vg_n in TestLvm._vg_names():
+ TestLvm._remove_vg(vg_n)
+
+ for d in TestLvm._get_pv_device_names():
+ lvm.pvRemove(d)
+ lvm.pvCreate(d)
+
+ def setUp(self):
+ device_list = TestLvm._get_pv_device_names()
+
+ #Make sure we have an adequate number of PVs to use
+ self.assertTrue(len(device_list) >= 4)
+ TestLvm._clean_up()
+
+ def tearDown(self):
+ TestLvm._clean_up()
+
+ def test_pv_resize(self):
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ curr_size = pv.getSize()
+ dev_size = pv.getDevSize()
+ self.assertTrue(curr_size == dev_size)
+ pv.resize(curr_size / 2)
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ resized_size = pv.getSize()
+ self.assertTrue(resized_size != curr_size)
+ pv.resize(dev_size)
+
+ def test_pv_life_cycle(self):
+ """
+ Test removing and re-creating a PV
+ """
+ target_name = None
+
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ target_name = pv.getName()
+ lvm.pvRemove(target_name)
+
+ with AllowedPVS() as pvs:
+ for p in pvs:
+ self.assertTrue(p.getName() != target_name)
+
+ lvm.pvCreate(target_name, 0)
+
+ with AllowedPVS() as pvs:
+ found = False
+ for p in pvs:
+ if p.getName() == target_name:
+ found = True
+
+ self.assertTrue(found)
+
+ @staticmethod
+ def _test_pv_methods():
+ with AllowedPVS() as pvs:
+ for p in pvs:
+ p.getName()
+ p.getUuid()
+ p.getMdaCount()
+ p.getSize()
+ p.getDevSize()
+ p.getFree()
+ p = None
+
+ def test_version(self):
+ version = lvm.getVersion()
+ self.assertNotEquals(version, None)
+ self.assertEquals(type(version), str)
+ self.assertTrue(len(version) > 0)
+
+ def test_pv_getters(self):
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ self.assertEqual(type(pv.getName()), str)
+ self.assertTrue(len(pv.getName()) > 0)
+
+ self.assertEqual(type(pv.getUuid()), str)
+ self.assertTrue(len(pv.getUuid()) > 0)
+
+ self.assertTrue(
+ type(pv.getMdaCount()) == int or
+ type(pv.getMdaCount()) == long)
+
+ self.assertTrue(
+ type(pv.getSize()) == int or
+ type(pv.getSize()) == long)
+
+ self.assertTrue(
+ type(pv.getDevSize()) == int or
+ type(pv.getSize()) == long)
+
+ self.assertTrue(
+ type(pv.getFree()) == int or
+ type(pv.getFree()) == long)
+
+ def _test_prop(self, prop_obj, prop, var_type, settable):
+ result = prop_obj.getProperty(prop)
+
+ #If we have no string value we can get a None type back
+ if result[0] is not None:
+ self.assertEqual(type(result[0]), var_type)
+ else:
+ self.assertTrue(str == var_type)
+ self.assertEqual(type(result[1]), bool)
+ self.assertTrue(result[1] == settable)
+
+ def test_pv_segs(self):
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ pv_segs = pv.listPVsegs()
+
+ #LVsegs returns a tuple, (value, bool settable)
+ #TODO: Test other properties of pv_seg
+ for i in pv_segs:
+ self._test_prop(i, 'pvseg_start', long, False)
+
+ def test_pv_property(self):
+ with AllowedPVS() as pvs:
+ pv = pvs[0]
+ self._test_prop(pv, 'pv_mda_count', long, False)
+
+ def test_lv_property(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ lv_seg_properties = [
+ ('chunk_size', long, False), ('devices', str, False),
+ ('discards', str, False), ('region_size', long, False),
+ ('segtype', str, False), ('seg_pe_ranges', str, False),
+ ('seg_size', long, False), ('seg_size_pe', long, False),
+ ('seg_start', long, False), ('seg_start_pe', long, False),
+ ('seg_tags', str, False), ('stripes', long, False),
+ ('stripe_size', long, False), ('thin_count', long, False),
+ ('transaction_id', long, False), ('zero', long, False)]
+
+ lv_properties = [
+ ('convert_lv', str, False), ('copy_percent', long, False),
+ ('data_lv', str, False), ('lv_attr', str, False),
+ ('lv_host', str, False), ('lv_kernel_major', long, False),
+ ('lv_kernel_minor', long, False),
+ ('lv_kernel_read_ahead', long, False),
+ ('lv_major', long, False), ('lv_minor', long, False),
+ ('lv_name', str, False), ('lv_path', str, False),
+ ('lv_profile', str, False), ('lv_read_ahead', long, False),
+ ('lv_size', long, False), ('lv_tags', str, False),
+ ('lv_time', str, False), ('lv_uuid', str, False),
+ ('metadata_lv', str, False), ('mirror_log', str, False),
+ ('lv_modules', str, False), ('move_pv', str, False),
+ ('origin', str, False), ('origin_size', long, False),
+ ('pool_lv', str, False), ('raid_max_recovery_rate', long, False),
+ ('raid_min_recovery_rate', long, False),
+ ('raid_mismatch_count', long, False),
+ ('raid_sync_action', str, False),
+ ('raid_write_behind', long, False), ('seg_count', long, False),
+ ('snap_percent', long, False), ('sync_percent', long, False)]
+
+ # Generic test case, make sure we get what we expect
+ for t in lv_properties:
+ self._test_prop(lv, *t)
+
+ segments = lv.listLVsegs()
+ if segments and len(segments):
+ for s in segments:
+ for t in lv_seg_properties:
+ self._test_prop(s, *t)
+
+ # Test specific cases
+ tag = 'hello_world'
+ lv.addTag(tag)
+ tags = lv.getProperty('lv_tags')
+ self.assertTrue(tag in tags[0])
+ vg.close()
+
+ def test_lv_tags(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self._test_tags(lv)
+ vg.close()
+
+ def test_lv_active_inactive(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ lv.deactivate()
+ self.assertTrue(lv.isActive() is False)
+ lv.activate()
+ self.assertTrue(lv.isActive() is True)
+ vg.close()
+
+ def test_lv_rename(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ current_name = lv.getName()
+ new_name = rs()
+ lv.rename(new_name)
+ self.assertEqual(lv.getName(), new_name)
+ lv.rename(current_name)
+ vg.close()
+
+ def test_lv_persistence(self):
+ # Make changes to the lv, close the vg and re-open to make sure that
+ # the changes persist
+ lv_name = 'lv_test_persist'
+ TestLvm._create_thick_lv(TestLvm._get_pv_device_names(), lv_name)
+
+ # Test rename
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ current_name = lv.getName()
+ new_name = rs()
+ lv.rename(new_name)
+
+ vg.close()
+ vg = None
+
+ lv, vg = TestLvm._get_lv(None, new_name)
+
+ self.assertTrue(lv is not None)
+
+ if lv and vg:
+ lv.rename(lv_name)
+ vg.close()
+ vg = None
+
+ # Test lv tag add
+ tag = 'hello_world'
+
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ lv.addTag(tag)
+ vg.close()
+ vg = None
+
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ tags = lv.getTags()
+
+ self.assertTrue(tag in tags)
+ vg.close()
+ vg = None
+
+ # Test lv tag delete
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+
+ if lv and vg:
+ tags = lv.getTags()
+
+ for t in tags:
+ lv.removeTag(t)
+
+ vg.close()
+ vg = None
+
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+
+ if lv and vg:
+ tags = lv.getTags()
+
+ if tags:
+ self.assertEqual(len(tags), 0)
+ vg.close()
+ vg = None
+
+ # Test lv deactivate
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+
+ if lv and vg:
+ lv.deactivate()
+ vg.close()
+ vg = None
+
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+ if lv and vg:
+ self.assertFalse(lv.isActive())
+ vg.close()
+ vg = None
+
+ # Test lv activate
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+ if lv and vg:
+ lv.activate()
+ vg.close()
+ vg = None
+
+ lv, vg = TestLvm._get_lv(None, lv_name)
+ self.assertTrue(lv is not None and vg is not None)
+ if lv and vg:
+ self.assertTrue(lv.isActive())
+ vg.close()
+ vg = None
+
+ def test_lv_snapshot(self):
+
+ thin_lv = 'thin_lv'
+ thick_lv = 'thick_lv'
+
+ device_names = TestLvm._get_pv_device_names()
+
+ TestLvm._create_thin_lv(device_names[0:2], thin_lv)
+ TestLvm._create_thick_lv(device_names[2:4], thick_lv)
+
+ lv, vg = TestLvm._get_lv(None, thick_lv)
+# FIXME lv.snapshot('thick_snap_shot', 1024*1024)
+ vg.close()
+
+# FIXME thick_ss, vg = TestLvm._get_lv(None, 'thick_snap_shot')
+# FIXME self.assertTrue(thick_ss is not None)
+# FIXME vg.close()
+
+ thin_lv, vg = TestLvm._get_lv(None, thin_lv)
+ thin_lv.snapshot('thin_snap_shot')
+ vg.close()
+
+ thin_ss, vg = TestLvm._get_lv(None, 'thin_snap_shot')
+ self.assertTrue(thin_ss is not None)
+
+ origin = thin_ss.getOrigin()
+ self.assertTrue(thin_lv, origin)
+
+ vg.close()
+
+ def test_lv_suspend(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ result = lv.isSuspended()
+ self.assertTrue(type(result) == bool)
+ vg.close()
+
+ def test_lv_size(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ result = lv.getSize()
+ self.assertTrue(type(result) == int or type(result) == long)
+ vg.close()
+
+ def test_lv_resize(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ curr_size = lv.getSize()
+ lv.resize(curr_size + (1024 * 1024))
+ latest = lv.getSize()
+ self.assertTrue(curr_size != latest)
+
+ def test_lv_seg(self):
+ lv_name = 'lv_test'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ lv_segs = lv.listLVsegs()
+
+ #LVsegs returns a tuple, (value, bool settable)
+ #TODO: Test other properties of lv_seg
+ for i in lv_segs:
+ self._test_prop(i, 'seg_start_pe', long, False)
+
+ vg.close()
+
+ def test_get_set_extend_size(self):
+ thick_lv = 'get_set_prop'
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
+
+ new_extent = 1024 * 1024 * 4
+
+ self.assertFalse(
+ vg.getExtentSize() != new_extent,
+ "Cannot determine if it works if they are the same")
+
+ vg.setExtentSize(new_extent)
+ self.assertEqual(vg.getExtentSize(), new_extent)
+ vg.close()
+
+ def test_vg_get_set_prop(self):
+ thick_lv = 'get_set_prop'
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
+
+ self.assertTrue(vg is not None)
+ if vg:
+ vg_mda_copies = vg.getProperty('vg_mda_copies')
+ vg.setProperty('vg_mda_copies', vg_mda_copies[0])
+ vg.close()
+
+ def test_vg_remove_restore(self):
+ #Store off the list of physical devices
+ pv_devices = []
+
+ thick_lv = 'get_set_prop'
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
+
+ vg_name = vg.getName()
+
+ pvs = vg.listPVs()
+ for p in pvs:
+ pv_devices.append(p.getName())
+ vg.close()
+
+ TestLvm._remove_vg(vg_name)
+ self._create_thick_lv(pv_devices, thick_lv)
+
+ def test_vg_names(self):
+ vg = lvm.listVgNames()
+ self.assertTrue(isinstance(vg, tuple))
+
+ def test_dupe_lv_create(self):
+ """
+ Try to create a lv with the same name expecting a failure
+ Note: This was causing a seg. fault previously
+ """
+ thick_lv = 'dupe_name'
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thick_lv(device_names[0:2], thick_lv)
+ lv, vg = TestLvm._get_lv(None, thick_lv)
+
+ self.assertTrue(vg is not None)
+
+ if vg:
+ lvs = vg.listLVs()
+
+ if len(lvs):
+ lv = lvs[0]
+ lv_name = lv.getName()
+ self.assertRaises(
+ lvm.LibLVMError, vg.createLvLinear, lv_name, lv.getSize())
+ vg.close()
+
+ def test_vg_uuids(self):
+
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vgs_uuids = lvm.listVgUuids()
+
+ self.assertTrue(len(vgs_uuids) > 0)
+ self.assertTrue(isinstance(vgs_uuids, tuple))
+
+ vgs_uuids = list(vgs_uuids)
+ vgs_names = lvm.listVgNames()
+
+ for vg_name in vgs_names:
+ vg = lvm.vgOpen(vg_name, "r")
+
+ #TODO Write/fix BUG, vg uuid don't match between
+ #lvm.listVgUuids and vg.getUuid()
+ vg_uuid_search = vg.getUuid().replace('-', '')
+
+ self.assertTrue(vg_uuid_search in vgs_uuids)
+ vgs_uuids.remove(vg_uuid_search)
+ vg.close()
+
+ self.assertTrue(len(vgs_uuids) == 0)
+
+ def test_pv_lookup_from_vg(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vg_names = TestLvm._vg_names()
+
+ self.assertTrue(len(vg_names) > 0)
+
+ for vg_name in vg_names:
+ vg = lvm.vgOpen(vg_name, 'w')
+ pvs = vg.listPVs()
+
+ for p in pvs:
+ name = p.getName()
+ uuid = p.getUuid()
+
+ pv_name_lookup = vg.pvFromName(name)
+ pv_uuid_lookup = vg.pvFromUuid(uuid)
+
+ self.assertTrue(
+ pv_name_lookup.getName() == pv_uuid_lookup.getName())
+ self.assertTrue(
+ pv_name_lookup.getUuid() == pv_uuid_lookup.getUuid())
+
+ self.assertTrue(name == pv_name_lookup.getName())
+ self.assertTrue(uuid == pv_uuid_lookup.getUuid())
+
+ pv_name_lookup = None
+ pv_uuid_lookup = None
+ p = None
+
+ pvs = None
+ vg.close()
+
+ def test_percent_to_float(self):
+ self.assertEqual(lvm.percentToFloat(0), 0.0)
+ self.assertEqual(lvm.percentToFloat(1000000), 1.0)
+ self.assertEqual(lvm.percentToFloat(1000000 / 2), 0.5)
+
+ def test_scan(self):
+ self.assertEqual(lvm.scan(), None)
+
+ def test_config_reload(self):
+ self.assertEqual(lvm.configReload(), None)
+
+ def test_config_override(self):
+ self.assertEquals(lvm.configOverride("global.test = 1"), None)
+
+ def test_config_find_bool(self):
+ either_or = lvm.configFindBool("global/fallback_to_local_locking")
+ self.assertTrue(type(either_or) == bool)
+ self.assertTrue(lvm.configFindBool("global/locking_type"))
+
+ def test_vg_from_pv_lookups(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vgname_list = TestLvm._vg_names()
+
+ self.assertTrue(len(vgname_list) > 0)
+
+ for vg_name in vgname_list:
+ vg = lvm.vgOpen(vg_name, 'r')
+
+ vg_name = vg.getName()
+
+ pv_list = vg.listPVs()
+ for pv in pv_list:
+ vg_name_from_pv = lvm.vgNameFromPvid(pv.getUuid())
+ self.assertEquals(vg_name, vg_name_from_pv)
+ self.assertEqual(vg_name, lvm.vgNameFromDevice(pv.getName()))
+ vg.close()
+
+ def test_vg_get_name(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vgname_list = TestLvm._vg_names()
+
+ self.assertTrue(len(vgname_list) > 0)
+
+ for vg_name in vgname_list:
+ vg = lvm.vgOpen(vg_name, 'r')
+ self.assertEqual(vg.getName(), vg_name)
+ vg.close()
+
+ def test_vg_get_uuid(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vgname_list = TestLvm._vg_names()
+
+ self.assertTrue(len(vgname_list) > 0)
+
+ for vg_name in vgname_list:
+ vg = lvm.vgOpen(vg_name, 'r')
+ uuid = vg.getUuid()
+ self.assertNotEqual(uuid, None)
+ self.assertTrue(len(uuid) > 0)
+ vg.close()
+
+ RETURN_NUMERIC = [
+ "getSeqno", "getSize", "getFreeSize", "getFreeSize",
+ "getExtentSize", "getExtentCount", "getFreeExtentCount",
+ "getPvCount", "getMaxPv", "getMaxLv"]
+
+ def test_vg_getters(self):
+ device_names = TestLvm._get_pv_device_names()
+ TestLvm._create_thin_lv(device_names[0:2], 'thin')
+ TestLvm._create_thick_lv(device_names[2:4], 'thick')
+
+ vg_name_list = TestLvm._vg_names()
+
+ self.assertTrue(len(vg_name_list) > 0)
+
+ for vg_name in vg_name_list:
+ vg = lvm.vgOpen(vg_name, 'r')
+ self.assertTrue(type(vg.isClustered()) == bool)
+ self.assertTrue(type(vg.isExported()) == bool)
+ self.assertTrue(type(vg.isPartial()) == bool)
+
+ #Loop through the list invoking the method
+ for method_name in TestLvm.RETURN_NUMERIC:
+ method = getattr(vg, method_name)
+ result = method()
+ self.assertTrue(type(result) == int or type(result) == long)
+
+ vg.close()
+
+ def _test_tags(self, tag_obj):
+ existing_tags = tag_obj.getTags()
+ self.assertTrue(type(existing_tags) == tuple)
+
+ num_tags = random.randint(2, 40)
+ created_tags = []
+
+ for i in range(num_tags):
+ tag_name = rs(random.randint(1, 128))
+ tag_obj.addTag(tag_name)
+ created_tags.append(tag_name)
+
+ tags = tag_obj.getTags()
+ self.assertTrue(len(existing_tags) + len(created_tags) == len(tags))
+
+ num_remove = len(created_tags)
+
+ for i in range(num_remove):
+ tag_to_remove = created_tags[
+ random.randint(0, len(created_tags) - 1)]
+
+ created_tags.remove(tag_to_remove)
+
+ tag_obj.removeTag(tag_to_remove)
+
+ current_tags = tag_obj.getTags()
+ self.assertFalse(tag_to_remove in current_tags)
+
+ current_tags = tag_obj.getTags()
+ self.assertTrue(len(current_tags) == len(existing_tags))
+ for e in existing_tags:
+ self.assertTrue(e in current_tags)
+
+ def test_vg_tags(self):
+ device_names = TestLvm._get_pv_device_names()
+
+ i = 0
+ for d in device_names:
+ if i % 2 == 0:
+ TestLvm._create_thin_lv([d], "thin_lv%d" % i)
+ else:
+ TestLvm._create_thick_lv([d], "thick_lv%d" % i)
+ i += 1
+
+ for vg_name in TestLvm._vg_names():
+ vg = lvm.vgOpen(vg_name, 'w')
+ self._test_tags(vg)
+ vg.close()
+
+ @staticmethod
+ def _test_listing():
+
+ env = os.environ
+
+ for k, v in env.items():
+ l("%s:%s" % (k, v))
+
+ with lvm.listPvs() as pvs:
+ for p in pvs:
+ l('pv= %s' % p.getName())
+
+ l('Checking for VG')
+ for v in lvm.listVgNames():
+ l('vg= %s' % v)
+
+ def test_pv_empty_listing(self):
+ #We had a bug where we would seg. fault if we had no PVs.
+
+ l('testPVemptylisting entry')
+
+ device_names = TestLvm._get_pv_device_names()
+
+ for d in device_names:
+ l("Removing %s" % d)
+ lvm.pvRemove(d)
+
+ count = 0
+
+ with lvm.listPvs() as pvs:
+ for p in pvs:
+ count += 1
+ l('pv= %s' % p.getName())
+
+ self.assertTrue(count == 0)
+
+ for d in device_names:
+ lvm.pvCreate(d)
+
+ def test_pv_create(self):
+ size = [0, 1024 * 1024 * 8]
+ pvmeta_copies = [0, 1, 2]
+ pvmeta_size = [0, 255, 512, 1024]
+ data_alignment = [0, 2048, 4096]
+ zero = [0, 1]
+
+ device_names = TestLvm._get_pv_device_names()
+
+ for d in device_names:
+ lvm.pvRemove(d)
+
+ d = device_names[0]
+
+ #Test some error cases
+ self.assertRaises(TypeError, lvm.pvCreate, None)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, '')
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 4)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 4)
+ self.assertRaises(lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 2 ** 34)
+ self.assertRaises(
+ lvm.LibLVMError, lvm.pvCreate, d, 0, 0, 0, 4096, 2 ** 34)
+
+ #Try a number of combinations and permutations
+ for s in size:
+ for copies in pvmeta_copies:
+ for pv_size in pvmeta_size:
+ for align in data_alignment:
+ for z in zero:
+ lvm.pvCreate(d, s, copies, pv_size, align,
+ align, z)
+ lvm.pvRemove(d)
+
+ #Restore
+ for d in device_names:
+ lvm.pvCreate(d)
+
+ def test_vg_reduce(self):
+ # Test the case where we try to reduce a vg where the last PV has
+ # no metadata copies. In this case the reduce should fail.
+ vg_name = TestLvm.VG_P + 'reduce_test'
+
+ device_names = TestLvm._get_pv_device_names()
+
+ for d in device_names:
+ lvm.pvRemove(d)
+
+ lvm.pvCreate(device_names[0], 0, 0) # Size all, pvmetadatacopies 0
+ lvm.pvCreate(device_names[1])
+ lvm.pvCreate(device_names[2])
+ lvm.pvCreate(device_names[3])
+
+ vg = lvm.vgCreate(vg_name)
+
+ vg.extend(device_names[3])
+ vg.extend(device_names[2])
+ vg.extend(device_names[1])
+ vg.extend(device_names[0])
+ vg.close()
+
+ vg = None
+
+ vg = lvm.vgOpen(vg_name, 'w')
+
+ vg.reduce(device_names[3])
+ vg.reduce(device_names[2])
+
+ self.assertRaises(lvm.LibLVMError, vg.reduce, device_names[1])
+
+ vg.close()
+ vg = None
+
+ vg = lvm.vgOpen(vg_name, 'w')
+ vg.remove()
+ vg.close()
+
+ @staticmethod
+ def _test_valid_names(method):
+ sample = 'azAZ09._-+'
+
+ method('x' * 127)
+ method('.X')
+ method('..X')
+
+ for i in range(1, 7):
+ tests = (''.join(i) for i in itertools.product(sample, repeat=i))
+ for t in tests:
+ if t == '.' or t == '..':
+ t += 'X'
+ elif t.startswith('-'):
+ t = 'H' + t
+ method(t)
+
+ def _test_bad_names(self, method, dupe_name):
+ # Test for duplicate name
+ self.assertRaises(lvm.LibLVMError, method, dupe_name)
+
+ # Test for too long a name
+ self.assertRaises(lvm.LibLVMError, method, ('x' * 128))
+
+ # Test empty
+ self.assertRaises(lvm.LibLVMError, method, '')
+
+ # Invalid characters
+ self.assertRaises(lvm.LibLVMError, method, '&invalid^char')
+
+ # Cannot start with .. and no following characters
+ self.assertRaises(lvm.LibLVMError, method, '..')
+
+ # Cannot start with . and no following characters
+ self.assertRaises(lvm.LibLVMError, method, '.')
+
+ # Cannot start with a hyphen
+ self.assertRaises(lvm.LibLVMError, method, '-not_good')
+
+ def _lv_reserved_names(self, method):
+ prefixes = ['snapshot', 'pvmove']
+ reserved = [
+ '_mlog', '_mimage', '_pmspare', '_rimage', '_rmeta',
+ '_vorigin', '_tdata', '_tmeta']
+
+ for p in prefixes:
+ self.assertRaises(lvm.LibLVMError, method, p + rs(3))
+
+ for r in reserved:
+ self.assertRaises(lvm.LibLVMError, method, rs(3) + r + rs(1))
+ self.assertRaises(lvm.LibLVMError, method, r + rs(1))
+
+ def test_vg_lv_name_validate(self):
+ lv_name = 'vg_lv_name_validate'
+ TestLvm._create_thin_lv(TestLvm._get_pv_device_names(), lv_name)
+ lv, vg = TestLvm._get_lv(None, lv_name)
+
+ self._test_bad_names(lvm.vgNameValidate, vg.getName())
+ self._test_bad_names(vg.lvNameValidate, lv.getName())
+
+ # Test good values
+ TestLvm._test_valid_names(lvm.vgNameValidate)
+ TestLvm._test_valid_names(vg.lvNameValidate)
+ self._lv_reserved_names(vg.lvNameValidate)
+
+ vg.close()
+
+if __name__ == "__main__":
+ unittest.main()
5 years, 11 months
master - tests: drop junk
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b5da4fdfcebb5a9c2c3...
Commit: b5da4fdfcebb5a9c2c32b64b27a12f6480829a97
Parent: be154e30e895bf08e00a8cf32ceb79b7c0f4b5a6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:51:35 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
tests: drop junk
---
test/shell/lvconvert-mirror.sh | 5 -----
1 files changed, 0 insertions(+), 5 deletions(-)
diff --git a/test/shell/lvconvert-mirror.sh b/test/shell/lvconvert-mirror.sh
index 91b8490..3fd4822 100644
--- a/test/shell/lvconvert-mirror.sh
+++ b/test/shell/lvconvert-mirror.sh
@@ -360,10 +360,6 @@ check mirror_no_temporaries $vg $lv1
check mirror_legs $vg $lv1 3
lvremove -ff $vg
-lvs -a $vg
-dmsetup table
-losetup -a
-ls -lRa $PWD
# "rhbz440405: lvconvert -m0 incorrectly fails if all PEs allocated"
lvcreate -aey -l "$(get pv_field "$dev1" pe_count)" --type mirror -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3:$DEVRANGE"
@@ -373,5 +369,4 @@ lvconvert -m0 $vg/$lv1 "$dev1"
check linear $vg $lv1
lvremove -ff $vg
-
vgremove -ff $vg
5 years, 11 months
master - build: configure detect libaio
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ad756bb7083743b612d...
Commit: ad756bb7083743b612d3fc66b268b605576f448a
Parent: c1abcee1424022b308fa265037af5826ae2af82d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 21:43:03 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 22:02:41 2018 +0200
build: configure detect libaio
No point to start building lvm without this header file.
Although there could be 'some point' in supporting standalone build
of 'just' libdm where the libaio might be avoided.
TODO: think about configure option for building libdm only.
---
configure | 2 +-
configure.ac | 2 +-
include/configure.h.in | 3 +++
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/configure b/configure
index ed00809..ce70d92 100755
--- a/configure
+++ b/configure
@@ -6141,7 +6141,7 @@ fi
for ac_header in assert.h ctype.h dirent.h errno.h fcntl.h float.h \
- getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
+ getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
diff --git a/configure.ac b/configure.ac
index 41e612f..7b517ef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -103,7 +103,7 @@ AC_HEADER_SYS_WAIT
AC_HEADER_TIME
AC_CHECK_HEADERS([assert.h ctype.h dirent.h errno.h fcntl.h float.h \
- getopt.h inttypes.h langinfo.h libgen.h limits.h locale.h paths.h \
+ getopt.h inttypes.h langinfo.h libaio.h libgen.h limits.h locale.h paths.h \
signal.h stdarg.h stddef.h stdio.h stdlib.h string.h sys/file.h \
sys/ioctl.h syslog.h sys/mman.h sys/param.h sys/resource.h sys/stat.h \
sys/time.h sys/types.h sys/utsname.h sys/wait.h time.h \
diff --git a/include/configure.h.in b/include/configure.h.in
index 66cc27c..15fd150 100644
--- a/include/configure.h.in
+++ b/include/configure.h.in
@@ -245,6 +245,9 @@
/* Define to 1 if you have the <langinfo.h> header file. */
#undef HAVE_LANGINFO_H
+/* Define to 1 if you have the <libaio.h> header file. */
+#undef HAVE_LIBAIO_H
+
/* Define to 1 if you have the <libcman.h> header file. */
#undef HAVE_LIBCMAN_H
5 years, 11 months
master - WHATS_NEW: updates
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c1abcee1424022b308f...
Commit: c1abcee1424022b308fa265037af5826ae2af82d
Parent: 889558fedb0f31d754ce146ac0858db1d5613543
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue May 15 10:49:06 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue May 15 10:49:06 2018 -0500
WHATS_NEW: updates
---
WHATS_NEW | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 5b1494b..84805a9 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,9 @@
Version 2.02.178 -
=====================================
+ Remove lvm1 and pool format handling and add filter to ignore them.
+ Move some filter checks to after disks are read.
+ Rework disk scanning and when it is used.
+ Add new io layer and shift code to using it.
lvconvert: don't return success on degraded -m raid1 conversion
--enable-testing switch for ./configure has been removed.
--with-snapshots switch for ./configure has been removed.
5 years, 11 months
master - conf: update conf
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=889558fedb0f31d754c...
Commit: 889558fedb0f31d754ce146ac0858db1d5613543
Parent: d25c135806593146e70a7c9f7c44535fbeec49f5
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 16:58:28 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 16:58:28 2018 +0200
conf: update conf
Matching patch 2eba7c77557655cfbd19f191ec5d1ad1025897b3
---
lib/config/config_settings.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index d8db7df..f49709c 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -768,7 +768,7 @@ cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, D
"the error messages.\n")
cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_BOOL, 0, vsn(1, 0, 18), NULL, 0, NULL,
- "This setting setting no longer used.\n")
+ "This setting is no longer used.\n")
cfg(global_format_CFG, "format", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL, 0, NULL,
"This setting is no longer used.\n")
5 years, 11 months
master - tests: fix size of COW
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=d25c135806593146e70...
Commit: d25c135806593146e70a7c9f7c44535fbeec49f5
Parent: 0217c53b24db3b0d50d1088ecd7bfc3ad1ba3955
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue May 15 16:49:53 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue May 15 16:49:53 2018 +0200
tests: fix size of COW
Needs to be changed to match 4K extent_size.
---
test/shell/snapshot-usage.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/snapshot-usage.sh b/test/shell/snapshot-usage.sh
index 307ab5f..bcfa16a 100644
--- a/test/shell/snapshot-usage.sh
+++ b/test/shell/snapshot-usage.sh
@@ -189,7 +189,7 @@ lvremove -f $vg1/snap
# Undeleted header would trigger attempt to access
# beyond end of COW device
# Fails to create when chunk size is different
-lvcreate -s -pr -l12 -n snap $vg1/$lv
+lvcreate -s -pr -l3 -n snap $vg1/$lv
# When header is undelete, fails to read snapshot without read errors
#dd if="$DM_DEV_DIR/$vg1/snap" of=/dev/null bs=1M count=2
5 years, 11 months