tests: rearrage LVM thin tests to run at least some in devel env

This requires creating LVM volume group, so create on based on loop dev
in /tmp.
This is rather rough, but if any of this fails, run the tests anyway -
it will simply skip LVM tests.
This commit is contained in:
Marek Marczykowski-Górecki 2016-09-04 22:33:21 +02:00
parent b91b89a341
commit da3eed582b
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 73 additions and 7 deletions

27
ci/lvm-manage Executable file
View File

@ -0,0 +1,27 @@
# This is to include LVM-requiring tests in Travis-CI
if [ "$1" = "setup-lvm" -a -n "$2" ]; then
POOL_PATH=$2
VG_NAME=`echo $POOL_PATH | cut -f 1 -d /`
POOL_NAME=`echo $POOL_PATH | cut -f 2 -d /`
if lvs $VG_NAME >/dev/null 2>&1 || lvs $POOL_PATH >/dev/null 2>&1; then
echo "WARNING: either VG '$VG_NAME' or thin pool '$POOL_PATH' already exists, not reusing" >&2
exit 1
fi
set -e
loop_file=`mktemp`
truncate -s 1G $loop_file
loop_dev=`losetup -f --show $loop_file`
# auto cleanup
rm -f $loop_file
vgcreate "$VG_NAME" $loop_dev
lvcreate --thinpool "$POOL_NAME" --type thin-pool -L 960M "$VG_NAME"
exit 0
elif [ "$1" = "cleanup-lvm" -a -n "$2" ]; then
VG_NAME=`echo $2 | cut -f 1 -d /`
set -e
pvs=`vgs --noheadings -o pv_name $VG_NAME | tr -d ' '`
lvremove -f "$2"
vgremove "$VG_NAME"
losetup -d $pvs
exit 0
fi

View File

@ -58,40 +58,60 @@ POOL_CONF = {'name': 'test-lvm',
'thin_pool': DEFAULT_LVM_POOL.split('/')[1]} 'thin_pool': DEFAULT_LVM_POOL.split('/')[1]}
@skipUnlessLvmPoolExists class ThinPoolBase(qubes.tests.QubesTestCase):
class TC_00_ThinPool(qubes.tests.SystemTestsMixin,
qubes.tests.QubesTestCase):
''' Sanity tests for :py:class:`qubes.storage.lvm.ThinPool` ''' ''' Sanity tests for :py:class:`qubes.storage.lvm.ThinPool` '''
created_pool = False created_pool = False
def setUp(self): def setUp(self):
super(TC_00_ThinPool, self).setUp() super(ThinPoolBase, self).setUp()
volume_group, thin_pool = DEFAULT_LVM_POOL.split('/', 1) volume_group, thin_pool = DEFAULT_LVM_POOL.split('/', 1)
self.pool = self._find_pool(volume_group, thin_pool) self.pool = self._find_pool(volume_group, thin_pool)
if not self.pool: if not self.pool:
self.pool = self.app.add_pool(**POOL_CONF) self.pool = self.app.add_pool(**POOL_CONF)
self.created_pool = True self.created_pool = True
self.init_default_template()
def tearDown(self): def tearDown(self):
''' Remove the default lvm pool if it was created only for this test ''' ''' Remove the default lvm pool if it was created only for this test '''
if self.created_pool: if self.created_pool:
self.app.remove_pool(self.pool.name) self.app.remove_pool(self.pool.name)
super(TC_00_ThinPool, self).tearDown() super(ThinPoolBase, self).tearDown()
def _find_pool(self, volume_group, thin_pool): def _find_pool(self, volume_group, thin_pool):
''' Returns the pool matching the specified ``volume_group`` & ''' Returns the pool matching the specified ``volume_group`` &
``thin_pool``, or None. ``thin_pool``, or None.
''' '''
pools = [p for p in self.app.pools pools = [p for p in self.app.pools
if issubclass(p.__class__, ThinPool)] if issubclass(p.__class__, ThinPool)]
for pool in pools: for pool in pools:
if pool.volume_group == volume_group \ if pool.volume_group == volume_group \
and pool.thin_pool == thin_pool: and pool.thin_pool == thin_pool:
return pool return pool
return None return None
@skipUnlessLvmPoolExists
class TC_00_ThinPool(ThinPoolBase):
''' Sanity tests for :py:class:`qubes.storage.lvm.ThinPool` '''
def setUp(self):
xml_path = '/tmp/qubes-test.xml'
self.app = qubes.Qubes.create_empty_store(store=xml_path,
clockvm=None,
updatevm=None,
offline_mode=True,
)
os.environ['QUBES_XML_PATH'] = xml_path
super(TC_00_ThinPool, self).setUp()
def tearDown(self):
super(TC_00_ThinPool, self).tearDown()
os.unlink(self.app.store)
del self.app
for attr in dir(self):
if isinstance(getattr(self, attr), qubes.vm.BaseVM):
delattr(self, attr)
def test_000_default_thin_pool(self): def test_000_default_thin_pool(self):
''' Check whether :py:data`DEFAULT_LVM_POOL` exists. This pool is ''' Check whether :py:data`DEFAULT_LVM_POOL` exists. This pool is
created by default, if at installation time LVM + Thin was chosen. created by default, if at installation time LVM + Thin was chosen.
@ -139,6 +159,14 @@ class TC_00_ThinPool(qubes.tests.SystemTestsMixin,
self.assertTrue(os.path.exists(path)) self.assertTrue(os.path.exists(path))
self.pool.remove(volume) self.pool.remove(volume)
@skipUnlessLvmPoolExists
class TC_01_ThinPool(qubes.tests.SystemTestsMixin, ThinPoolBase):
''' Sanity tests for :py:class:`qubes.storage.lvm.ThinPool` '''
def setUp(self):
super(TC_01_ThinPool, self).setUp()
self.init_default_template()
def test_004_import(self): def test_004_import(self):
template_vm = self.app.default_template template_vm = self.app.default_template
name = self.make_vm_name('import') name = self.make_vm_name('import')

View File

@ -1,5 +1,11 @@
#!/bin/sh #!/bin/sh
CLEANUP_LVM=
if sudo --non-interactive $(dirname "$0")/ci/lvm-manage setup-lvm vg$$/pool; then
export DEFAULT_LVM_POOL=vg$$/pool
CLEANUP_LVM=yes
fi
: "${PYTHON:=python3}" : "${PYTHON:=python3}"
: "${TESTPYTHONPATH:=test-packages}" : "${TESTPYTHONPATH:=test-packages}"
@ -8,3 +14,8 @@ export PYTHONPATH
"${PYTHON}" setup.py egg_info --egg-base "${TESTPYTHONPATH}" "${PYTHON}" setup.py egg_info --egg-base "${TESTPYTHONPATH}"
"${PYTHON}" -m coverage run --rcfile=ci/coveragerc -m qubes.tests.run "$@" "${PYTHON}" -m coverage run --rcfile=ci/coveragerc -m qubes.tests.run "$@"
retcode=$?
if [ -n "$CLEANUP_LVM" ]; then
sudo --non-interactive $(dirname "$0")/ci/lvm-manage cleanup-lvm "$DEFAULT_LVM_POOL"
fi
exit $retcode