Discussion:
[Libstoragemgmt-devel] [PATCH 03/18] nstor.py: bugfix - Advertise EXPORT_CUSTOM_PATH
Tony Asleson
2014-12-01 22:56:51 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
plugin/nstor/nstor.py | 1 +
1 file changed, 1 insertion(+)

diff --git a/plugin/nstor/nstor.py b/plugin/nstor/nstor.py
index 9e854fc..da25e48 100644
--- a/plugin/nstor/nstor.py
+++ b/plugin/nstor/nstor.py
@@ -270,6 +270,7 @@ class NexentaStor(INfs, IStorageAreaNetwork):
c.set(Capabilities.EXPORTS)
c.set(Capabilities.EXPORT_FS)
c.set(Capabilities.EXPORT_REMOVE)
+ c.set(Capabilities.EXPORT_CUSTOM_PATH)
#
# #Block operations
c.set(Capabilities.VOLUMES)
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:49 UTC
Permalink
This code does not work and it can't work with the new directory layout
which we have been using for quite a while.

Signed-off-by: Tony Asleson <***@redhat.com>
---
python_binding/lsm/_client.py | 105 +-----------------------------------------
1 file changed, 1 insertion(+), 104 deletions(-)

diff --git a/python_binding/lsm/_client.py b/python_binding/lsm/_client.py
index 74c1e1a..e637962 100644
--- a/python_binding/lsm/_client.py
+++ b/python_binding/lsm/_client.py
@@ -15,12 +15,10 @@
#
# Author: tasleson

-import time
import os
-import unittest
from lsm import (Volume, NfsExport, Capabilities, Pool, System,
Disk, AccessGroup, FileSystem, FsSnapshot,
- uri_parse, LsmError, JobStatus, ErrorNumber,
+ uri_parse, LsmError, ErrorNumber,
INetworkAttachedStorage, TargetPort)

from _common import return_requires as _return_requires
@@ -973,104 +971,3 @@ class Client(INetworkAttachedStorage):
"""
_check_search_key(search_key, TargetPort.SUPPORTED_SEARCH_KEYS)
return self._tp.rpc('target_ports', _del_self(locals()))
-
-
-class _TestClient(unittest.TestCase):
- def wait_to_finish(self, job, vol):
-
- if vol is not None:
- return vol
- else:
- (status, percent, volume) = self.c.job_status(job)
- print 'Job status:', status, ' percent complete=', percent
-
- while status == JobStatus.INPROGRESS:
- time.sleep(1)
- (status, percent, volume) = self.c.job_status(job)
- print 'Job status:', status, ' percent complete=', percent
-
- self.c.job_free(job)
-
- if status == JobStatus.COMPLETE:
- self.assertTrue(volume is not None)
-
- return volume
-
- def setUp(self):
- #Most of the uri is not needed for the simulator
- #Remember that the setup and teardown methods are run for each test
- #case!
- self.c = Client('sim://***@host:5988/?namespace=root/foo')
-
- def test_tmo(self):
- expected = 40000
-
- self.c.time_out_set(expected)
- tmo = self.c.time_out_get()
- self.assertTrue(tmo == expected)
-
- def test_job_errors(self):
- self.assertRaises(LsmError, self.c.job_free, 0)
- self.assertRaises(LsmError, self.c.job_status, 0)
-
- def test_pools(self):
- self.pools = self.c.pools()
-
- self.assertTrue(len(self.pools) == 4)
-
- for p in self.pools:
- print p
-
- def test_volumes(self):
- volumes = self.c.volumes()
- self.assertTrue(len(volumes) == 0)
-
- pools = self.c.pools()
-
- #create a volume
- p = pools[0]
-
- #Create volumes
- num_volumes = 10
- for i in range(num_volumes):
- vol = self.wait_to_finish(
- *(self.c.volume_create(p, "TestVol" + str(i), 1024 * 1024 * 10,
- Volume.PROVISION_DEFAULT)))
- print str(vol)
-
- volumes = self.c.volumes()
- self.assertTrue(len(volumes) == num_volumes)
-
- #delete volumes
- for i in volumes:
- self.c.volume_delete(i)
-
- volumes = self.c.volumes()
- self.assertTrue(len(volumes) == 0)
-
- #Create a volume and replicate it
- vol = self.wait_to_finish(
- *(self.c.volume_create(p, "To be replicated", 1024 * 1024 * 10,
- Volume.PROVISION_DEFAULT)))
- rep = self.wait_to_finish(
- *(self.c.volume_replicate(p, Volume.REPLICATE_CLONE, vol,
- 'Replicated')))
-
- volumes = self.c.volumes()
- self.assertTrue(len(volumes) == 2)
-
- self.c.volume_delete(rep)
-
- re_sized = self.wait_to_finish(
- *(self.c.volume_resize(vol, vol.size_bytes * 2)))
-
- self.assertTrue(vol.size_bytes == re_sized.size_bytes / 2)
-
- self.c.volume_disable(re_sized)
- self.c.volume_enable(re_sized)
-
- def tearDown(self):
- self.c.close()
-
-if __name__ == "__main__":
- unittest.main()
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:58 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 147eeee..129a542 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -925,6 +925,19 @@ class TestPlugin(unittest.TestCase):
cap, rs('ag'), s,
lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
ag_list = self.c.access_groups('system_id', s.id)
+
+ if supported(cap,
+ [Cap.
+ ACCESS_GROUP_INITIATOR_ADD_ISCSI_IQN]):
+
+ init_id = self._ag_init_add(ag_to_delete)
+
+ if supported(
+ cap, [Cap.ACCESS_GROUP_INITIATOR_DELETE]):
+ self._ag_init_delete(
+ ag_to_delete, init_id,
+ lsm.AccessGroup.INIT_TYPE_ISCSI_IQN)
+
if supported(
cap, [Cap.ACCESS_GROUP_CREATE_WWPN,
Cap.ACCESS_GROUP_DELETE]):
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:56 UTC
Permalink
We were silently passing even though we were unable to find a pool to test
fs operations.

Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 3 +++
1 file changed, 3 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 45342a6..594ae0e 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -379,6 +379,9 @@ class TestPlugin(unittest.TestCase):
pool = self._get_pool_by_usage(system_id,
lsm.Pool.ELEMENT_TYPE_FS)

+ self.assertTrue(pool is not None, "Unable to find a suitable pool "
+ "for fs creation")
+
if pool is not None:
fs_size = self._object_size(pool)
fs = self.c.fs_create(pool, rs('fs'), fs_size)[1]
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:01 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 8755ccd..57b3f04 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -29,6 +29,7 @@ import sys
import yaml
import re
import os
+import tempfile
from lsm import LsmError, ErrorNumber
from lsm import Capabilities as Cap

@@ -1132,6 +1133,33 @@ class TestPlugin(unittest.TestCase):

self._volume_delete(vol)

+ def test_daemon_not_running(self):
+ current = None
+ got_exception = False
+ # Force a ErrorNumber.DAEMON_NOT_RUNNING
+ if 'LSM_UDS_PATH' in os.environ:
+ current = os.environ['LSM_UDS_PATH']
+
+ tmp_dir = tempfile.mkdtemp()
+ os.environ['LSM_UDS_PATH'] = tmp_dir
+
+ try:
+ tmp_c = lsm.Client(TestPlugin.URI, TestPlugin.PASSWORD)
+ except LsmError as expected_error:
+ got_exception = True
+ self.assertTrue(expected_error.code ==
+ ErrorNumber.DAEMON_NOT_RUNNING,
+ 'Actual error %d' % (expected_error.code))
+
+ self.assertTrue(got_exception)
+
+ os.rmdir(tmp_dir)
+
+ if current:
+ os.environ['LSM_UDS_PATH'] = current
+ else:
+ del os.environ['LSM_UDS_PATH']
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:03 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 98ac411..e53d839 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1174,6 +1174,10 @@ class TestPlugin(unittest.TestCase):

self.assertTrue(got_exception)

+ def test_close(self):
+ tmp_c = lsm.Client(TestPlugin.URI, TestPlugin.PASSWORD)
+ tmp_c.close()
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:06 UTC
Permalink
Added calls to:
export_auth
exports
export_fs
export_remove

Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 35 +++++++++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 8bd5b25..a0feab2 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1234,6 +1234,41 @@ class TestPlugin(unittest.TestCase):
if fs_child:
self._fs_delete(fs_child)

+ def test_nfs_auth_types(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.EXPORT_AUTH]):
+ auth_types = self.c.export_auth()
+ self.assertTrue(auth_types is not None)
+
+ def test_export_list(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.EXPORTS]):
+ exports = self.c.exports()
+ # TODO verify export values
+
+ def test_create_delete_exports(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.FS_CREATE, Cap.EXPORTS, Cap.EXPORT_FS,
+ Cap.EXPORT_REMOVE]):
+ fs, pool = self._fs_create(s.id)
+
+ if supported(cap, [Cap.EXPORT_CUSTOM_PATH]):
+ path = "/mnt/%s" % rs(None, 6)
+ exp = self.c.export_fs(fs.id, path, [], [],
+ ['192.168.2.1'])
+ else:
+ exp = self.c.export_fs(fs.id, None, [], [],
+ ['192.168.2.1'])
+ self.c.export_remove(exp)
+ self._fs_delete(fs)
+
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:54 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
plugin/ontap/ontap.py | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index 1672d31..c2a2c58 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -1186,6 +1186,11 @@ class Ontap(IStorageAreaNetwork, INfs):
"""
Creates or modifies the specified export
"""
+ # NetApp does not support anon_gid setting.
+ if not (anon_gid == -1 or anon_gid == 0xFFFFFFFFFFFFFFFF):
+ raise LsmError(ErrorNumber.INVALID_ARGUMENT,
+ "ontap plugin does not support "
+ "anon_gid setting")

#Get the volume info from the fs_id
vol = self._get_volume_from_id(fs_id)
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:55 UTC
Permalink
The metadata for this method was incorrect.

Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 13febf2..45342a6 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -126,7 +126,7 @@ class TestProxy(object):
'volume_replicate': (unicode, lsm.Volume),
'volume_replicate_range': (unicode,),
'volume_delete': (unicode,),
- 'volume_child_dependency_rm': (unicode),
+ 'volume_child_dependency_rm': (unicode,),
'fs_delete': (unicode,),
'fs_resize': (unicode, lsm.FileSystem),
'fs_create': (unicode, lsm.FileSystem),
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:59 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 129a542..2b8f34c 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1113,6 +1113,11 @@ class TestPlugin(unittest.TestCase):
self.assertTrue(
lsm.Volume.vpd83_verify("01234567890123456789012345abcdef"))

+ def test_available_plugins(self):
+ plugins = self.c.available_plugins(':')
+ self.assertTrue(plugins is not None)
+ self.assertTrue(len(plugins) > 0)
+ self.assertTrue(':' in plugins[0])

def dump_results():
"""
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:53 UTC
Permalink
The nfs export anonymous uid & gid are suppose to be integers. The command
line was passing None which overrode the python default of -1. This didn't
cause any issues as the plugins were only checking for existence, not value.
However, this did cause a problem if a user called the
API without specifying the uid & gid as the default integer value of -1 caused
the ontap plugin to fail with an exception.

Unfortunately the C API declares the uid & gid as uint64_t so the default value
of -1 gets interpreted as (2**64-1). Thus python plugins should check against
-1 and 18446744073709551615L to see if the argument is == default. They will
get -1 from python clients and 18446744073709551615L from C clients.

Signed-off-by: Tony Asleson <***@redhat.com>
---
c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h | 4 ++++
plugin/ontap/na.py | 4 +++-
plugin/ontap/ontap.py | 3 ++-
tools/lsmcli/cmdline.py | 8 ++++++--
4 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h b/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
index fedba24..5e3076d 100644
--- a/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
+++ b/c_binding/include/libstoragemgmt/libstoragemgmt_nfsexport.h
@@ -27,6 +27,10 @@
extern "C" {
#endif

+/**
+ * Because the nfs export functions use an unsigned data type these values
+ * will be represented as (2**64-1 and 2**64-2 respectively)
+ */
#define ANON_UID_GID_NA -1
#define ANON_UID_GID_ERROR (ANON_UID_GID_NA - 1)

diff --git a/plugin/ontap/na.py b/plugin/ontap/na.py
index 8532e87..a0f1d49 100644
--- a/plugin/ontap/na.py
+++ b/plugin/ontap/na.py
@@ -672,7 +672,9 @@ class Filer(object):
r['root'] = Filer._build_export_fs_list(root_list)

if anonuid:
- r['anon'] = anonuid
+ uid = long(anonuid)
+ if uid != -1 or uid != 0xFFFFFFFFFFFFFFFF:
+ r['anon'] = str(uid)

if sec_flavor:
r['sec-flavor'] = Filer._build_list(
diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index 26a249a..1672d31 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -1150,7 +1150,8 @@ class Ontap(IStorageAreaNetwork, INfs):
Ontap._get_group('root', e),
Ontap._get_group('read-write', e),
Ontap._get_group('read-only', e),
- Ontap._get_value('anon', e), None, None)
+ NfsExport.ANON_UID_GID_NA, NfsExport.ANON_UID_GID_NA,
+ None)

@handle_ontap_errors
def exports(self, search_key=None, search_value=None, flags=0):
diff --git a/tools/lsmcli/cmdline.py b/tools/lsmcli/cmdline.py
index 29f75d1..1bb6135 100644
--- a/tools/lsmcli/cmdline.py
+++ b/tools/lsmcli/cmdline.py
@@ -457,9 +457,13 @@ cmds = (
dict(name="--exportpath", metavar='<EXPORT_PATH>',
help="NFS server export path. e.g. '/foo/bar'."),
dict(name="--anonuid", metavar='<ANON_UID>',
- help='UID(User ID) to map to anonymous user'),
+ help='UID(User ID) to map to anonymous user',
+ default=NfsExport.ANON_UID_GID_NA,
+ type=long),
dict(name="--anongid", metavar='<ANON_GID>',
- help='GID(Group ID) to map to anonymous user'),
+ help='GID(Group ID) to map to anonymous user',
+ default=NfsExport.ANON_UID_GID_NA,
+ type=long),
dict(name="--auth-type", metavar='<AUTH_TYPE>',
help='NFS client authentication type'),
dict(name="--root-host", metavar='<ROOT_HOST>',
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:04 UTC
Permalink
Test volume_child_dependency & volume_child_dependency_rm

Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index e53d839..28cb207 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1178,6 +1178,43 @@ class TestPlugin(unittest.TestCase):
tmp_c = lsm.Client(TestPlugin.URI, TestPlugin.PASSWORD)
tmp_c.close()

+ def test_volume_depends(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.VOLUME_CREATE, Cap.VOLUME_DELETE,
+ Cap.VOLUME_CHILD_DEPENDENCY,
+ Cap.VOLUME_CHILD_DEPENDENCY_RM]) and \
+ (supported(cap, [Cap.VOLUME_REPLICATE_COPY]) or
+ supported(cap, [Cap.VOLUME_REPLICATE_CLONE])):
+ vol, pol = self._volume_create(s.id)
+
+ if supported(cap, [Cap.VOLUME_REPLICATE_CLONE]):
+ vol_child = self.c.volume_replicate(
+ None,
+ lsm.Volume.REPLICATE_CLONE,
+ vol,
+ rs('v_tc_'))[1]
+ else:
+ vol_child = self.c.volume_replicate(
+ None,
+ lsm.Volume.REPLICATE_COPY,
+ vol,
+ rs('v_fc_'))[1]
+
+ self.assertTrue(vol_child is not None)
+
+ if self.c.volume_child_dependency(vol):
+ self.c.volume_child_dependency_rm(vol)
+ else:
+ self.assertTrue(self.c.volume_child_dependency_rm(vol)
+ is None)
+
+ self._volume_delete(vol)
+
+ if vol_child:
+ self._volume_delete(vol_child)
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:52 UTC
Permalink
The source documentation lists that if the export_path is None that the
plugin shall create the export path automatically.

Signed-off-by: Tony Asleson <***@redhat.com>
---
plugin/ontap/ontap.py | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index f8ada86..26a249a 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -1189,6 +1189,11 @@ class Ontap(IStorageAreaNetwork, INfs):
#Get the volume info from the fs_id
vol = self._get_volume_from_id(fs_id)

+ # API states that if export path is None the plug-in will select
+ # export path
+ if export_path is None:
+ export_path = '/vol/' + vol.name
+
#If the export already exists we need to update the existing export
#not create a new one.
if self._current_export(export_path):
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:50 UTC
Permalink
This has been supported for some time, add it.

Signed-off-by: Tony Asleson <***@redhat.com>
---
plugin/ontap/ontap.py | 1 +
1 file changed, 1 insertion(+)

diff --git a/plugin/ontap/ontap.py b/plugin/ontap/ontap.py
index f51c373..f8ada86 100644
--- a/plugin/ontap/ontap.py
+++ b/plugin/ontap/ontap.py
@@ -542,6 +542,7 @@ class Ontap(IStorageAreaNetwork, INfs):
cap.set(Capabilities.EXPORT_REMOVE)
cap.set(Capabilities.EXPORT_CUSTOM_PATH)
cap.set(Capabilities.TARGET_PORTS)
+ cap.set(Capabilities.DISKS)
return cap

@handle_ontap_errors
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:02 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 14 ++++++++++++++
1 file changed, 14 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 57b3f04..98ac411 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1160,6 +1160,20 @@ class TestPlugin(unittest.TestCase):
else:
del os.environ['LSM_UDS_PATH']

+ def test_non_existent_plugin(self):
+ got_exception = False
+ try:
+ uri = "%s://***@host" % rs(None, 6)
+
+ tmp_c = lsm.Client(uri, TestPlugin.PASSWORD)
+ except LsmError as expected_error:
+ got_exception = True
+ self.assertTrue(expected_error.code ==
+ ErrorNumber.PLUGIN_NOT_EXIST,
+ 'Actual error %d' % (expected_error.code))
+
+ self.assertTrue(got_exception)
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:00 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 13 +++++++++++++
1 file changed, 13 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 2b8f34c..8755ccd 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1119,6 +1119,19 @@ class TestPlugin(unittest.TestCase):
self.assertTrue(len(plugins) > 0)
self.assertTrue(':' in plugins[0])

+ def test_volume_enable_disable(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.VOLUME_CREATE, Cap.VOLUME_DELETE,
+ Cap.VOLUME_ENABLE, Cap.VOLUME_DISABLE]):
+ vol, pool = self._volume_create(s.id)
+
+ self.c.volume_disable(vol)
+ self.c.volume_enable(vol)
+
+ self._volume_delete(vol)
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Tony Asleson
2014-12-01 22:56:57 UTC
Permalink
Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 3 +++
1 file changed, 3 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 594ae0e..147eeee 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -635,6 +635,9 @@ class TestPlugin(unittest.TestCase):
ss = self.c.fs_snapshot_create(fs, rs('ss'))[1]
self.assertTrue(self._fs_snapshot_exists(fs, ss.id))

+ if supported(cap, [Cap.FS_SNAPSHOT_RESTORE]):
+ self.c.fs_snapshot_restore(fs, ss, None, None, True)
+
# Delete snapshot
if supported(cap, [Cap.FS_SNAPSHOT_DELETE]):
self._fs_snapshot_delete(fs, ss)
--
1.8.2.1
Tony Asleson
2014-12-01 22:57:05 UTC
Permalink
Test fs_child_dependency & fs_child_dependency_rm

Signed-off-by: Tony Asleson <***@redhat.com>
---
test/plugin_test.py | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/test/plugin_test.py b/test/plugin_test.py
index 28cb207..8bd5b25 100755
--- a/test/plugin_test.py
+++ b/test/plugin_test.py
@@ -1215,6 +1215,25 @@ class TestPlugin(unittest.TestCase):
if vol_child:
self._volume_delete(vol_child)

+ def test_fs_depends(self):
+ for s in self.systems:
+ cap = self.c.capabilities(s)
+
+ if supported(cap, [Cap.FS_CREATE, Cap.FS_DELETE,
+ Cap.FS_CHILD_DEPENDENCY,
+ Cap.FS_CHILD_DEPENDENCY_RM,
+ Cap.FS_CLONE]):
+ fs, pol = self._fs_create(s.id)
+ fs_child = self.c.fs_clone(fs, rs('fs_c_'))[1]
+ self.assertTrue(fs_child is not None)
+
+ if self.c.fs_child_dependency(fs, None):
+ self.c.fs_child_dependency_rm(fs, None)
+
+ self._fs_delete(fs)
+ if fs_child:
+ self._fs_delete(fs_child)
+
def dump_results():
"""
unittest.main exits when done so we need to register this handler to
--
1.8.2.1
Loading...