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
|
$ 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_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_detach_volume_on_lvm (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_attach_detach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_stats_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_attach_detach_volume_via_attachment_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_stats_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_attach_detach_volume_via_attachment_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_stats_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_attach_detach_volume_via_attachment_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_attach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_attach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_volume_on_xtremio (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_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_delete_volume_on_lvm (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_delete_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_snapshot_on_kaminario (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_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_snapshot_on_xtremio (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_volume_from_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_delete_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_create_volume_from_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_create_delete_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_create_volume_from_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_create_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_create_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_volume_on_xtremio (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_disk_io_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_detach_volume_via_attachment_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_disk_io_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_attach_detach_volume_via_attachment_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_disk_io_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_disk_io_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_extend_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_disk_io_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_extend_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_disk_io_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_extend_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_stats_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_stats_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_stats_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_multiple_volumes_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
test_stats_with_creation_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_multiple_volumes_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
test_stats_with_creation_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||||
test_connect_disconnect_multiple_volumes_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
test_stats_with_creation_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
|
Ran 48 tests in x.ys
|
||||||
test_stats_with_cretion_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
|
||||||
test_stats_with_cretion_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
OK
|
||||||
test_stats_with_cretion_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
|
||||||
|
|
||||||
As can be seen each test will have a meaningful name ending in the name of the
|
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.
|
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
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import json
|
||||||
import functools
|
import functools
|
||||||
import os
|
import os
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import tempfile
|
||||||
|
|
||||||
import unittest2
|
import unittest2
|
||||||
import yaml
|
import yaml
|
||||||
@@ -156,3 +158,61 @@ class BaseFunctTestCase(unittest2.TestCase):
|
|||||||
|
|
||||||
self.assertIn(snap, vol.snapshots)
|
self.assertIn(snap, vol.snapshots)
|
||||||
return snap
|
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.
|
# under the License.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import tempfile
|
|
||||||
|
|
||||||
import base_tests
|
import base_tests
|
||||||
|
|
||||||
@@ -26,13 +25,40 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
|
|||||||
stats = self.backend.stats()
|
stats = self.backend.stats()
|
||||||
self.assertIn('vendor_name', stats)
|
self.assertIn('vendor_name', stats)
|
||||||
self.assertIn('volume_backend_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:
|
for pool_info in pools_info:
|
||||||
self.assertIn('free_capacity_gb', pool_info)
|
self.assertIn('free_capacity_gb', pool_info)
|
||||||
self.assertIn('total_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):
|
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
|
# We are not testing delete, so leave the deletion to the tearDown
|
||||||
|
|
||||||
def test_create_delete_volume(self):
|
def test_create_delete_volume(self):
|
||||||
@@ -114,29 +140,61 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
|
|||||||
self.assertNotIn(attach, vol.connections)
|
self.assertNotIn(attach, vol.connections)
|
||||||
|
|
||||||
def test_disk_io(self):
|
def test_disk_io(self):
|
||||||
data = '0123456789' * 100
|
|
||||||
|
|
||||||
vol = self._create_vol(self.backend)
|
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
|
self.assertEqual(data, read_data)
|
||||||
# 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)
|
|
||||||
|
|
||||||
# Detach without removing the mapping of the volume since it's faster
|
def test_extend(self):
|
||||||
attach.detach()
|
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
|
new_size = vol.size + 1
|
||||||
attach.attach()
|
vol.extend(new_size)
|
||||||
stdout = self._root_execute('dd', 'if=' + attach.path, count=1,
|
|
||||||
ibs=len(data))
|
|
||||||
|
|
||||||
self.assertEqual(data, stdout)
|
self.assertEqual(new_size, vol.size)
|
||||||
vol.detach()
|
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):
|
def test_connect_disconnect_volume(self):
|
||||||
# TODO(geguileo): Implement the test
|
# TODO(geguileo): Implement the test
|
||||||
@@ -149,7 +207,3 @@ class BackendFunctBasic(base_tests.BaseFunctTestCase):
|
|||||||
def test_connect_disconnect_multiple_times(self):
|
def test_connect_disconnect_multiple_times(self):
|
||||||
# TODO(geguileo): Implement the test
|
# TODO(geguileo): Implement the test
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_stats_with_creation(self):
|
|
||||||
# TODO(geguileo): Implement the test
|
|
||||||
pass
|
|
||||||
|
|||||||
Reference in New Issue
Block a user