Add more funtional tests

This patch adds 4 new functional tests:

- Stats proper update after volume creation
- Extend volume operation
- Volume cloning
- Creating a volume from snapshot

It also improves the create volume tests to check the size of the newly
created volume.
This commit is contained in:
Gorka Eguileor
2018-03-14 13:35:08 +01:00
parent 69e1b65c18
commit 0b608f85e9
3 changed files with 186 additions and 54 deletions

View File

@@ -132,45 +132,63 @@ the location of our configuration file via environmental variable
$ CL_FTEST_CFG=temp/tests.yaml tox -efunctional
functional develop-inst-nodeps: /home/geguileo/code/cinderlib
functional installed: You are using pip version 8.1.2, ...
functional runtests: PYTHONHASHSEED='2093635202'
functional runtests: commands[0] | unit2 discover -v -s tests/functional
test_attach_detach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_stats_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_stats_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_stats_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_clone_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_clone_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_clone_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_delete_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_delete_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_delete_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_delete_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_attach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_attach_detach_volume_via_attachment_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_disk_io_kaminario (tests_basic.BackendFunctBasic) ... ok
test_disk_io_lvm (tests_basic.BackendFunctBasic) ... ok
test_disk_io_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_volumes_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_connect_disconnect_multiple_times_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_stats_with_cretion_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_stats_with_cretion_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_stats_with_cretion_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_volume_from_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_volume_from_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_volume_from_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_create_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_disk_io_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_disk_io_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_disk_io_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_extend_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_extend_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_extend_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_stats_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_stats_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_stats_on_xtremio (tests_basic.BackendFunctBasic) ... ok
test_stats_with_creation_on_kaminario (tests_basic.BackendFunctBasic) ... ok
test_stats_with_creation_on_lvm (tests_basic.BackendFunctBasic) ... ok
test_stats_with_creation_on_xtremio (tests_basic.BackendFunctBasic) ... ok
----------------------------------------------------------------------
Ran 48 tests in x.ys
OK
As can be seen each test will have a meaningful name ending in the name of the
backend we have provided via the `volume_backend_name` key in the YAML file.

View File

@@ -13,9 +13,11 @@
# License for the specific language governing permissions and limitations
# under the License.
import json
import functools
import os
import subprocess
import tempfile
import unittest2
import yaml
@@ -156,3 +158,61 @@ class BaseFunctTestCase(unittest2.TestCase):
self.assertIn(snap, vol.snapshots)
return snap
def _get_vol_size(self, vol, do_detach=True):
if not vol.local_attach:
vol.attach()
try:
while True:
try:
result = self._root_execute('lsblk', '-o', 'SIZE', '-J',
'-b', vol.local_attach.path)
data = json.loads(result)
size_bytes = data['blockdevices'][0]['size']
return float(size_bytes) / 1024.0 / 1024.0 / 1024.0
# NOTE(geguileo): We can't catch subprocess.CalledProcessError
# because somehow we get an instance from a different
# subprocess.CalledProcessError class that isn't the same.
except Exception as exc:
# If the volume is not yet available
if getattr(exc, 'returncode', 0) != 32:
raise
finally:
if do_detach:
vol.detach()
def _write_data(self, vol, data=None, do_detach=True):
if not data:
data = '0123456789' * 100
if not vol.local_attach:
vol.attach()
# TODO(geguileo: This will not work on Windows, for that we need to
# pass delete=False and do the manual deletion ourselves.
try:
with tempfile.NamedTemporaryFile() as f:
f.write(data)
f.flush()
self._root_execute('dd', 'if=' + f.name,
of=vol.local_attach.path)
finally:
if do_detach:
vol.detach()
return data
def _read_data(self, vol, length, do_detach=True):
if not vol.local_attach:
vol.attach()
try:
stdout = self._root_execute('dd', 'if=' + vol.local_attach.path,
count=1, ibs=length)
finally:
if do_detach:
vol.detach()
return stdout
def _pools_info(self, stats):
return stats.get('pools', [stats])

View File

@@ -14,7 +14,6 @@
# under the License.
import os
import tempfile
import base_tests
@@ -26,13 +25,40 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
stats = self.backend.stats()
self.assertIn('vendor_name', stats)
self.assertIn('volume_backend_name', stats)
pools_info = stats.get('pools', [stats])
pools_info = self._pools_info(stats)
for pool_info in pools_info:
self.assertIn('free_capacity_gb', pool_info)
self.assertIn('total_capacity_gb', pool_info)
def test_stats_with_creation(self):
# This test can fail if we are don't have exclusive usage of the
# storage pool used in the tests or if the specific driver does not
# return the right values in allocated_capacity_gb or
# provisioned_capacity_gb.
initial_stats = self.backend.stats(refresh=True)
vol = self._create_vol(self.backend)
new_stats = self.backend.stats(refresh=True)
initial_pools_info = self._pools_info(initial_stats)
new_pools_info = self._pools_info(new_stats)
initial_volumes = sum(p.get('total_volumes', 0)
for p in initial_pools_info)
new_volumes = sum(p.get('total_volumes', 1) for p in new_pools_info)
self.assertEqual(initial_volumes + 1, new_volumes)
initial_size = sum(p.get('allocated_capacity_gb',
p.get('provisioned_capacity_gb', 0))
for p in initial_pools_info)
new_size = sum(p.get('allocated_capacity_gb',
p.get('provisioned_capacity_gb', vol.size))
for p in new_pools_info)
self.assertEqual(initial_size + vol.size, new_size)
def test_create_volume(self):
self._create_vol(self.backend)
vol = self._create_vol(self.backend)
vol_size = self._get_vol_size(vol)
self.assertEqual(vol.size, vol_size)
# We are not testing delete, so leave the deletion to the tearDown
def test_create_delete_volume(self):
@@ -114,29 +140,61 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
self.assertNotIn(attach, vol.connections)
def test_disk_io(self):
data = '0123456789' * 100
vol = self._create_vol(self.backend)
data = self._write_data(vol)
attach = vol.attach()
read_data = self._read_data(vol, len(data))
# TODO(geguileo: This will not work on Windows, for that we need to
# pass delete=False and do the manual deletion ourselves.
with tempfile.NamedTemporaryFile() as f:
f.write(data)
f.flush()
self._root_execute('dd', 'if=' + f.name, of=attach.path)
self.assertEqual(data, read_data)
# Detach without removing the mapping of the volume since it's faster
attach.detach()
def test_extend(self):
vol = self._create_vol(self.backend)
original_size = vol.size
result_original_size = self._get_vol_size(vol)
self.assertEqual(original_size, result_original_size)
# Reattach, using old mapping, to validate data is there
attach.attach()
stdout = self._root_execute('dd', 'if=' + attach.path, count=1,
ibs=len(data))
new_size = vol.size + 1
vol.extend(new_size)
self.assertEqual(data, stdout)
vol.detach()
self.assertEqual(new_size, vol.size)
result_new_size = self._get_vol_size(vol)
self.assertEqual(new_size, result_new_size)
def test_clone(self):
vol = self._create_vol(self.backend)
original_size = self._get_vol_size(vol, do_detach=False)
data = self._write_data(vol)
new_vol = vol.clone()
self.assertEqual(vol.size, new_vol.size)
cloned_size = self._get_vol_size(new_vol, do_detach=False)
read_data = self._read_data(new_vol, len(data))
self.assertEqual(original_size, cloned_size)
self.assertEqual(data, read_data)
def test_create_volume_from_snapshot(self):
# Create a volume and write some data
vol = self._create_vol(self.backend)
original_size = self._get_vol_size(vol, do_detach=False)
data = self._write_data(vol)
# Take a snapshot
snap = vol.create_snapshot()
self.assertEqual(vol.size, snap.volume_size)
# Change the data in the volume
reversed_data = data[::-1]
self._write_data(vol, data=reversed_data)
# Create a new volume from the snapshot with the original data
new_vol = snap.create_volume()
self.assertEqual(vol.size, new_vol.size)
created_size = self._get_vol_size(new_vol, do_detach=False)
read_data = self._read_data(new_vol, len(data))
self.assertEqual(original_size, created_size)
self.assertEqual(data, read_data)
def test_connect_disconnect_volume(self):
# TODO(geguileo): Implement the test
@@ -149,7 +207,3 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
def test_connect_disconnect_multiple_times(self):
# TODO(geguileo): Implement the test
pass
def test_stats_with_creation(self):
# TODO(geguileo): Implement the test
pass