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:
@@ -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.
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user