Repository: IBM/pyds8k (language: python)

Issue:
release 1.4.0



Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 8190428..7790340 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,10 @@
 
 This repository contains the IBM RESTful API Python client, which establishes terminal connection with IBM DS8000 storage systems. The Python client protocol enables full management and monitoring of these storage arrays by issuing dedicated RESTful APIs.
 
+## Python Compatibility
+
+The content in this collection supports Python 3.6 and newer.
+
 ## Getting started
 
 Clone the repository, and then add it to your PYTHONPATH directory. The Python client is then ready for import and use.
diff --git a/docs/api/pyds8k.auth.ds8k.rst b/docs/api/pyds8k.auth.ds8k.rst
deleted file mode 100644
index 0ffb8e8..0000000
--- a/docs/api/pyds8k.auth.ds8k.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-pyds8k.auth.ds8k package
-=============================
-
-Subpackages
------------
-
-.. toctree::
-
-   pyds8k.auth.ds8k.v1
-
-Submodules
-----------
-
-pyds8k.auth.ds8k.base module
---------------------------------------
-
-.. automodule:: pyds8k.auth.ds8k.base
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: pyds8k.auth.ds8k
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/api/pyds8k.auth.ds8k.v1.rst b/docs/api/pyds8k.auth.ds8k.v1.rst
deleted file mode 100644
index 6d60688..0000000
--- a/docs/api/pyds8k.auth.ds8k.v1.rst
+++ /dev/null
@@ -1,22 +0,0 @@
-pyds8k.auth.ds8k.v1 package
-=============================
-
-Submodules
-----------
-
-pyds8k.auth.ds8k.v1.auth module
---------------------------------------
-
-.. automodule:: pyds8k.auth.ds8k.v1.auth
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: pyds8k.auth.ds8k.v1
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/api/pyds8k.auth.rst b/docs/api/pyds8k.auth.rst
deleted file mode 100644
index 3f376cd..0000000
--- a/docs/api/pyds8k.auth.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-pyds8k.auth package
-=====================
-
-Subpackages
------------
-
-.. toctree::
-
-   pyds8k.auth.ds8k
-
-Submodules
-----------
-
-pyds8k.auth.authenticate module
----------------------------
-
-.. automodule:: pyds8k.auth.authenticate
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: pyds8k.auth
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/api/pyds8k.client.ds8k.rst b/docs/api/pyds8k.client.ds8k.rst
index bb25105..4b4cffd 100644
--- a/docs/api/pyds8k.client.ds8k.rst
+++ b/docs/api/pyds8k.client.ds8k.rst
@@ -1,14 +1,14 @@
 pyds8k.client.ds8k package
-=============================
+==========================
 
 Subpackages
 -----------
 
 .. toctree::
+   :maxdepth: 4
 
    pyds8k.client.ds8k.v1
 
-
 Module contents
 ---------------
 
diff --git a/docs/api/pyds8k.client.ds8k.v1.rst b/docs/api/pyds8k.client.ds8k.v1.rst
index 5aed1bb..be19f73 100644
--- a/docs/api/pyds8k.client.ds8k.v1.rst
+++ b/docs/api/pyds8k.client.ds8k.v1.rst
@@ -5,21 +5,13 @@ Submodules
 ----------
 
 pyds8k.client.ds8k.v1.client module
---------------------------------------
+-----------------------------------
 
 .. automodule:: pyds8k.client.ds8k.v1.client
    :members:
    :undoc-members:
    :show-inheritance:
 
-pyds8k.client.ds8k.v1.sc\_client module
---------------------------------------
-
-.. automodule:: pyds8k.client.ds8k.v1.sc_client
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
 
 Module contents
 ---------------
diff --git a/docs/api/pyds8k.client.rst b/docs/api/pyds8k.client.rst
index 5d3a455..d83e6bc 100644
--- a/docs/api/pyds8k.client.rst
+++ b/docs/api/pyds8k.client.rst
@@ -5,6 +5,7 @@ Subpackages
 -----------
 
 .. toctree::
+   :maxdepth: 4
 
    pyds8k.client.ds8k
 
@@ -12,14 +13,13 @@ Submodules
 ----------
 
 pyds8k.client.exceptions module
----------------------------
+-------------------------------
 
 .. automodule:: pyds8k.client.exceptions
    :members:
    :undoc-members:
    :show-inheritance:
 
-
 Module contents
 ---------------
 
diff --git a/docs/api/pyds8k.dataParser.rst b/docs/api/pyds8k.dataParser.rst
deleted file mode 100644
index ffefde9..0000000
--- a/docs/api/pyds8k.dataParser.rst
+++ /dev/null
@@ -1,30 +0,0 @@
-pyds8k.dataParser package
-========================
-
-Submodules
-----------
-
-pyds8k.dataParser.base module
---------------------------------------
-
-.. automodule:: pyds8k.dataParser.base
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.dataParser.ds8k module
----------------------------------
-
-.. automodule:: pyds8k.dataParser.ds8k
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: pyds8k.dataParser
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/api/pyds8k.resources.ds8k.rst b/docs/api/pyds8k.resources.ds8k.rst
index 90dde13..5a53162 100644
--- a/docs/api/pyds8k.resources.ds8k.rst
+++ b/docs/api/pyds8k.resources.ds8k.rst
@@ -5,11 +5,10 @@ Subpackages
 -----------
 
 .. toctree::
+   :maxdepth: 4
 
    pyds8k.resources.ds8k.v1
 
-
-
 Module contents
 ---------------
 
diff --git a/docs/api/pyds8k.resources.ds8k.v1.common.rst b/docs/api/pyds8k.resources.ds8k.v1.common.rst
index 646baf7..eb2fab7 100644
--- a/docs/api/pyds8k.resources.ds8k.v1.common.rst
+++ b/docs/api/pyds8k.resources.ds8k.v1.common.rst
@@ -1,42 +1,16 @@
 pyds8k.resources.ds8k.v1.common package
-=============================
+=======================================
 
 Submodules
 ----------
-
-pyds8k.resources.ds8k.v1.common.attr\_names module
---------------------------------------
-
-.. automodule:: pyds8k.resources.ds8k.v1.attr_names
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.resources.ds8k.v1.common.base module
---------------------------------------
-
-.. automodule:: pyds8k.resources.ds8k.v1.base
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
 pyds8k.resources.ds8k.v1.common.mixins module
---------------------------------------
-
-.. automodule:: pyds8k.resources.ds8k.v1.mixins
-   :members:
-   :undoc-members:
-   :show-inheritance:
+---------------------------------------------
 
-pyds8k.resources.ds8k.v1.common.types module
---------------------------------------
-
-.. automodule:: pyds8k.resources.ds8k.v1.types
+.. automodule:: pyds8k.resources.ds8k.v1.common.mixins
    :members:
    :undoc-members:
    :show-inheritance:
 
-
 Module contents
 ---------------
 
diff --git a/docs/api/pyds8k.resources.ds8k.v1.cs.rst b/docs/api/pyds8k.resources.ds8k.v1.cs.rst
index 57155b5..87b1155 100644
--- a/docs/api/pyds8k.resources.ds8k.v1.cs.rst
+++ b/docs/api/pyds8k.resources.ds8k.v1.cs.rst
@@ -1,17 +1,24 @@
 pyds8k.resources.ds8k.v1.cs package
-=============================
+===================================
 
 Submodules
 ----------
 
-pyds8k.resources.ds8k.v1.cs.pprcs module
---------------------------------------
+pyds8k.resources.ds8k.v1.cs.flashcopies module
+----------------------------------------------
 
-.. automodule:: pyds8k.resources.ds8k.v1.pprcs
+.. automodule:: pyds8k.resources.ds8k.v1.cs.flashcopies
    :members:
    :undoc-members:
    :show-inheritance:
 
+pyds8k.resources.ds8k.v1.cs.pprcs module
+----------------------------------------
+
+.. automodule:: pyds8k.resources.ds8k.v1.cs.pprcs
+   :members:
+   :undoc-members:
+   :show-inheritance:
 
 Module contents
 ---------------
diff --git a/docs/api/pyds8k.resources.ds8k.v1.rst b/docs/api/pyds8k.resources.ds8k.v1.rst
index 7194a55..4f3a71b 100644
--- a/docs/api/pyds8k.resources.ds8k.v1.rst
+++ b/docs/api/pyds8k.resources.ds8k.v1.rst
@@ -1,10 +1,11 @@
 pyds8k.resources.ds8k.v1 package
-=============================
+================================
 
 Subpackages
 -----------
 
 .. toctree::
+   :maxdepth: 4
 
    pyds8k.resources.ds8k.v1.common
    pyds8k.resources.ds8k.v1.cs
@@ -13,11 +14,10 @@ Submodules
 ----------
 
 pyds8k.resources.ds8k.v1.encryption\_groups module
---------------------------------------
+--------------------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.encryption_groups
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.eserep module
@@ -25,7 +25,6 @@ pyds8k.resources.ds8k.v1.eserep module
 
 .. automodule:: pyds8k.resources.ds8k.v1.eserep
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.events module
@@ -33,103 +32,90 @@ pyds8k.resources.ds8k.v1.events module
 
 .. automodule:: pyds8k.resources.ds8k.v1.events
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.flashcopy module
---------------------------------------
+-----------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.flashcopy
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.host\_ports module
---------------------------------------
+-------------------------------------------
 
-.. automodule:: pyds8k.resources.ds8k.v1.hosts_ports
+.. automodule:: pyds8k.resources.ds8k.v1.host_ports
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.hosts module
---------------------------------------
+-------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.hosts
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.io\_enclosures module
---------------------------------------
+----------------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.io_enclosures
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.ioports module
---------------------------------------
+---------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.ioports
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.lss module
---------------------------------------
+-----------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.lss
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.mappings module
---------------------------------------
+----------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.mappings
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.marrays module
---------------------------------------
+---------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.marrays
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.nodes module
---------------------------------------
+-------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.nodes
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.pools module
---------------------------------------
+-------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.pools
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.pprc module
---------------------------------------
+------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.pprc
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.systems module
---------------------------------------
+---------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.systems
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.tserep module
@@ -137,26 +123,22 @@ pyds8k.resources.ds8k.v1.tserep module
 
 .. automodule:: pyds8k.resources.ds8k.v1.tserep
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.users module
---------------------------------------
+-------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.users
    :members:
-   :undoc-members:
    :show-inheritance:
 
 pyds8k.resources.ds8k.v1.volumes module
---------------------------------------
+---------------------------------------
 
 .. automodule:: pyds8k.resources.ds8k.v1.volumes
    :members:
-   :undoc-members:
    :show-inheritance:
 
-
 Module contents
 ---------------
 
diff --git a/docs/api/pyds8k.resources.rst b/docs/api/pyds8k.resources.rst
deleted file mode 100644
index 5c8261e..0000000
--- a/docs/api/pyds8k.resources.rst
+++ /dev/null
@@ -1,29 +0,0 @@
-pyds8k.resources package
-=====================
-
-Subpackages
------------
-
-.. toctree::
-
-   pyds8k.resources.ds8k
-
-Submodules
-----------
-
-pyds8k.resources.utils module
----------------------------
-
-.. automodule:: pyds8k.resources.utils
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-
-Module contents
----------------
-
-.. automodule:: pyds8k.resources
-   :members:
-   :undoc-members:
-   :show-inheritance:
diff --git a/docs/api/pyds8k.rst b/docs/api/pyds8k.rst
index 2ea66fd..acfdf94 100644
--- a/docs/api/pyds8k.rst
+++ b/docs/api/pyds8k.rst
@@ -1,84 +1,26 @@
-:orphan:
-
 pyds8k package
-=============
+==============
 
 Subpackages
 -----------
 
 .. toctree::
-   pyds8k.auth
+   :maxdepth: 4
+
    pyds8k.client
-   pyds8k.dataParser
-   pyds8k.resources
+   pyds8k.resources.ds8k
 
 Submodules
 ----------
 
-pyds8k.base module
--------------------
-
-.. automodule:: pyds8k.base
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.dateutil module
----------------------
-
-.. automodule:: pyds8k.dateutil
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
 pyds8k.exceptions module
--------------------
+------------------------
 
 .. automodule:: pyds8k.exceptions
    :members:
    :undoc-members:
    :show-inheritance:
 
-pyds8k.httpclient module
----------------------
-
-.. automodule:: pyds8k.httpclient
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.messages module
----------------------
-
-.. automodule:: pyds8k.messages
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.settings module
--------------------
-
-.. automodule:: pyds8k.settings
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.size\_converter module
----------------------
-
-.. automodule:: pyds8k.size_converter
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
-pyds8k.utils module
--------------------
-
-.. automodule:: pyds8k.utils
-   :members:
-   :undoc-members:
-   :show-inheritance:
-
 
 Module contents
 ---------------
diff --git a/docs/conf.py b/docs/conf.py
index 592e0b7..5b24962 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -4,9 +4,11 @@
 # list see the documentation:
 # http://www.sphinx-doc.org/en/master/config
 
-import sys, os
+import os
+import sys
 
-sys.path.insert(0,os.path.realpath(os.path.abspath('../')))
+sys.path.insert(0, os.path.realpath(os.path.abspath('../')))
+sys.path.append(os.path.abspath('../..'))
 
 import pyds8k
 
@@ -22,7 +24,13 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode', 'sphinx.ext.coverage', 'sphinx.ext.todo']
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.viewcode',
+    'sphinx.ext.coverage',
+    'sphinx.ext.todo',
+    'sphinx.ext.napoleon'
+]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -37,8 +45,8 @@
 master_doc = 'index'
 
 # General information about the project.
-project = 'IBM Storage'
-copyright = '2012-2019 IBM'
+project = 'IBM DS8000 pyds8k'
+copyright = '2012-2022 IBM'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -88,12 +96,20 @@
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+html_theme = 'alabaster'
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {}
+#
+html_theme_options = {
+    'body_max_width': '75%',
+    'page_width': '95%',
+    'fixed_sidebar': True,
+    'sidebar_width': '20%',
+    'body_text_align': 'justify'
+
+}
 
 # Add any paths that contain custom themes here, relative to this directory.
 #html_theme_path = []
@@ -238,9 +254,9 @@
 
 # Bibliographic Dublin Core info.
 epub_title = 'pyds8k'
-epub_author = 'Author'
-epub_publisher = 'Author'
-epub_copyright = '2019, Author'
+epub_author = 'IBM'
+epub_publisher = 'IBM'
+epub_copyright = '2022, IBM'
 
 # The language of the text. It defaults to the language option
 # or en if the language is not set.
diff --git a/docs/index.rst b/docs/index.rst
index 40804d1..3e49947 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -1,4 +1,4 @@
-IBMStorage |release| Documentation
+pyds8k |release| Documentation
 ========================================
 
 Overview
diff --git a/pyds8k/__init__.py b/pyds8k/__init__.py
index 6cbc41c..9dd7718 100644
--- a/pyds8k/__init__.py
+++ b/pyds8k/__init__.py
@@ -22,7 +22,7 @@
 """
 PYDS8K_DEFAULT_LOGGER = "pyds8k"
 
-version_tuple = (1, 1, 0)
+version_tuple = (1, 4, 0)
 
 
 def get_version_string():
diff --git a/pyds8k/auth/__init__.py b/pyds8k/auth/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/auth/ds8k/__init__.py b/pyds8k/auth/ds8k/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/auth/ds8k/base.py b/pyds8k/auth/ds8k/base.py
index f844a2e..3e404a7 100644
--- a/pyds8k/auth/ds8k/base.py
+++ b/pyds8k/auth/ds8k/base.py
@@ -17,7 +17,7 @@
 from pyds8k.dataParser.ds8k import RequestParser, ResponseParser
 
 AUTH_URL = '/tokens'
-DEFAULT_BASE_URL = '/api/v1'
+DEFAULT_BASE_URL = ''
 
 
 class Auth(object):
diff --git a/pyds8k/auth/ds8k/v1/__init__.py b/pyds8k/auth/ds8k/v1/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/client/__init__.py b/pyds8k/client/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/client/ds8k/__init__.py b/pyds8k/client/ds8k/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/client/ds8k/v1/__init__.py b/pyds8k/client/ds8k/v1/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/client/ds8k/v1/client.py b/pyds8k/client/ds8k/v1/client.py
index 5c390d3..b92ca4d 100755
--- a/pyds8k/client/ds8k/v1/client.py
+++ b/pyds8k/client/ds8k/v1/client.py
@@ -13,12 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ##############################################################################
-
 from logging import getLogger
 from pyds8k import PYDS8K_DEFAULT_LOGGER
 from pyds8k.httpclient import HTTPClient
 from pyds8k.base import Resource, DefaultManager
-from pyds8k.resources.ds8k.v1.common import types
 from pyds8k.resources.ds8k.v1.systems import System, \
     SystemManager
 
@@ -30,23 +28,35 @@ class Client(object):
     """
     Top-level object to access all the DS8K resources.
 
-    :param service_address: Hostname/IP address of the REST server if it is
-                           standalone or the hostname/IP address of the DS8K
-                           system. Required.
-    :type service_address: string
-    :param user: Username for logining to the DS8K system. Required.
-    :type user: string
-    :param password: Password for logining to the DS8K system. Required.
-    :type password: string
-    :param port: Port number of the server.
-    :type port: int
-    :param hostname: Hostname/IP address of the DS8K system. It is required if
-                     the server is standalone.
-    :type hostname: string
-    :param timeout: How long to wait for the server to send data before giving
-                    up. In seconds.
-                    Default is 25, and 0 means no limitation.
-    :type timeout: float
+    See available member functions from the docstring of
+    :py:mod:`pyds8k.resources.ds8k.v1.common.mixins`
+
+    Args:
+        service_address (string): Required. Hostname/IP address
+                    of the REST server if it is standalone or the
+                    hostname/IP address of the DS8K system.
+        user (string): Required. Username for logining to the
+                     DS8K system.
+        password (string): Required. Password for logining to
+                     the DS8K system.
+        port (int):  Port number of the server.
+        hostname (string): Hostname/IP address of the DS8K HMC.
+                     Required if the REST-API server is standalone.
+        timeout (float): How long to wait for the server to send
+                     data before giving up. In seconds.
+                     Default is 25, and 0 means no limitation.
+        verify (bool): Either 1)a boolean, indicating whether we verify
+                       the server's TLS certificate,
+                       or 2) a string of the path to a CA bundle to use.
+                       Defaults to ``True``, meaning that the default CA of
+                       python ``requests`` module is used.
+                       The default CA bundle of requests module
+                       can be found by:
+
+                        | ``import requests``
+                        | ``print(requests.certs.where())``
+    Returns:
+        object: DS8000 REST-API Client
     """
 
     def __init__(self, service_address, user, password,
@@ -55,6 +65,7 @@ def __init__(self, service_address, user, password,
                  service_type='ds8k',
                  service_version='v1',
                  timeout=None,
+                 verify=True
                  ):
         logger.info('================== logger is enabled ==================')
 
@@ -64,6 +75,7 @@ def __init__(self, service_address, user, password,
                             service_type=service_type,
                             service_version=service_version,
                             timeout=timeout,
+                            verify=verify
                             )
 
         self.client = client
@@ -81,64 +93,3 @@ def __getattr__(self, k):
                 return method
         except Exception:
             raise AttributeError(k)
-
-    def create_volume(self, name, cap, pool, tp='', lss=''):
-        """
-        Create a fb volume.
-
-        name, cap(in GiB) and pool id is mandatory.
-        tp have three optional values: 'none', 'ese' and 'tse'.
-        default is 'none', will create a standard volume.
-        """
-
-        return self.system.create_volume_fb(
-            name=name, cap=cap,
-            pool=pool, tp=tp,
-            captype=types.DS8K_CAPTYPE_GIB,
-            lss=lss,
-        )
-
-    def create_volumes(self, name_col, cap, pool, tp='', lss=''):
-        """
-        Create fb volumes.
-
-        name_col, cap(in GiB) and pool id is mandatory.
-        name_col is a volume name list.
-        tp have three optional values: 'none', 'ese' and 'tse'.
-        default is 'none', will create standard volumes.
-        """
-
-        return self.create_volumes_without_same_prefix(name_col, cap,
-                                                       pool, tp, lss
-                                                       )
-
-    def create_volumes_with_same_prefix(self, name, cap, pool,
-                                        quantity='', tp='', lss=''
-                                        ):
-        """
-        Create fb volumes with same name prefix.
-
-        name, cap(in GiB) pool id and quantity is mandatory.
-        name is the volume name prefix, the final volume names will
-        be something like 'prefix_1', 'prefix_2', ...
-        tp have three optional values: 'none', 'ese' and 'tse'.
-        default is 'none', will create standard volumes.
-        """
-
-        return self.system.create_volumes_with_same_prefix(
-            cap=cap, pool=pool,
-            stgtype=types.DS8K_VOLUME_TYPE_FB,
-            name=name, quantity=quantity,
-            captype=types.DS8K_CAPTYPE_GIB, tp=tp,
-            lss=lss,
-        )
-
-    def create_volumes_without_same_prefix(self, name_col, cap, pool,
-                                           tp='', lss=''):
-        return self.system.create_volumes_without_same_prefix(
-            cap=cap, pool=pool,
-            stgtype=types.DS8K_VOLUME_TYPE_FB,
-            name_col=name_col,
-            captype=types.DS8K_CAPTYPE_GIB, tp=tp,
-            lss=lss,
-        )
diff --git a/pyds8k/client/ds8k/v1/sc_client.py b/pyds8k/client/ds8k/v1/sc_client.py
index 44ea2a0..980a741 100755
--- a/pyds8k/client/ds8k/v1/sc_client.py
+++ b/pyds8k/client/ds8k/v1/sc_client.py
@@ -27,7 +27,7 @@ class SCClient(object):
     """
     SC side client. Used to interaction with current side client.
 
-    !--important: the id field of all resources are case insensitive--!
+    !--important: the id field of all resources are case-insensitive--!
     """
 
     def __init__(self, service_address, user, password,
@@ -90,6 +90,10 @@ def list_extentpool_virtualpool(self, pool_id):
     def list_flashcopies(self):
         return self.client.get_flashcopies()
 
+    @dictionarize
+    def list_cs_flashcopies(self):
+        return self.client.get_cs_flashcopies()
+
     @dictionarize
     def list_volume_flashcopies(self, volume_id):
         # two requests
diff --git a/pyds8k/dataParser/__init__.py b/pyds8k/dataParser/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/dataParser/base.py b/pyds8k/dataParser/base.py
index 00d9f44..f593023 100755
--- a/pyds8k/dataParser/base.py
+++ b/pyds8k/dataParser/base.py
@@ -16,12 +16,13 @@
 
 from abc import ABCMeta, abstractmethod
 
+import six
 
-class BaseRequestParser(object, metaclass=ABCMeta):
-    """
-    Parse the data user wants to send to server,
-    in the right format that server defined.
-    """
+
+@six.add_metaclass(ABCMeta)
+class BaseRequestParser(object):
+    # Parse the data user wants to send to server,
+    # in the right format that server defined.
 
     @abstractmethod
     def get_raw_data(self):
@@ -32,10 +33,9 @@ def get_request_data(self):
         pass
 
 
-class BaseResponseParser(object, metaclass=ABCMeta):
-    """
-    Parser response data, to get resource link, representation, etc.
-    """
+@six.add_metaclass(ABCMeta)
+class BaseResponseParser(object):
+    # Parser response data, to get resource link, representation, etc.
 
     response_key = ''
     success_status = ('ok', 'successful', )
@@ -56,20 +56,19 @@ def get_representations(self):
 
     @abstractmethod
     def get_posta_response_data(self):
-        """
-        Return a list of ({resource_data_key:resource_data}, resource_uri)
-        or ({error_status_key:status_data}, None) if the rest server returns
-        a partial failure response.
-
-        For example:
-        If you create two resources(res1, res2) at a time, you should return
-        [({resource_data_key:res1_data}, res1_uri),
-         ({error_status_key:res2_status_data}, None)
-         ]
-        or
-        [({resource_data_key:res1_data}, res1_uri), ] if you only care about
-        success ones.
-        """
+        # Return a list of ({resource_data_key:resource_data}, resource_uri)
+        # or ({error_status_key:status_data}, None) if the rest server returns
+        # a partial failure response.
+
+        # For example:
+        # If you create two resources(res1, res2) at a time, you should return
+        # [({resource_data_key:res1_data}, res1_uri),
+        # ({error_status_key:res2_status_data}, None)
+        #  ]
+        # or
+        # [({resource_data_key:res1_data}, res1_uri), ] if you only care about
+        # success ones.
+
         pass
 
     @abstractmethod
diff --git a/pyds8k/dataParser/ds8k.py b/pyds8k/dataParser/ds8k.py
index eb98f22..5e7aa72 100755
--- a/pyds8k/dataParser/ds8k.py
+++ b/pyds8k/dataParser/ds8k.py
@@ -29,10 +29,9 @@
 
 
 class RequestParser(BaseRequestParser):
-    """
-    Parse the data user wants to send to server,
-    in the right format that server defined.
-    """
+    # Parse the data user wants to send to server,
+    # in the right format that server defined.
+
     request_key = 'request'
     request_key_multi = 'request'
     param_key = 'params'
@@ -60,9 +59,8 @@ def get_request_data(self):
 
 
 class ResponseParser(BaseResponseParser):
-    """
-    Parse response data, to get resource link, representation, etc.
-    """
+    # Parse response data, to get resource link, representation, etc.
+
     response_key = 'data'
     status_key = 'server'
     url_field = 'link'
diff --git a/pyds8k/httpclient.py b/pyds8k/httpclient.py
index 7f7bb9a..d7d8a49 100755
--- a/pyds8k/httpclient.py
+++ b/pyds8k/httpclient.py
@@ -42,41 +42,39 @@
 
 class HTTPClient(object):
     """
-    A HTTP client interacting with a RESTful web service.
-
-    :param service_address: Hostname/IP address of the web service. Required.
-    :type service_address: string
-    :param user: Username for connecting to the web service. Required.
-    :type user: string
-    :param password: Password for connecting to the web service. Required.
-    :type password: string
-    :param hostname: It is required when the service has a
+    An HTTP client interacting with RESTAPI web service.
+
+    Args:
+     service_address (str): Hostname/IP address of the web service. Required.
+     user (str): Username for connecting to the web service. Required.
+     password (str): Password for connecting to the web service. Required.
+     hostname (str): It is required when the service has a
                      remote backend (eg: a storage system)
-    :param port: Port number of the server.
-    :type port: int
-    :type hostname: string
-    :param service_type: It is used to decide which series of resources, which
+     port (int): Port number of the server.
+     service_type (str): It is used to decide which series of resources, which
                          auth functions, and which data parsers will take
                          effect when a HTTPClient instance is instantiated.
                          Required. Currently, only 'ds8k' is supported.
-    :type service_type: string
-    :param service_version: It is used to decide which version of resources,
+     service_version (str): It is used to decide which version of resources,
                             which auth functions, and which data parsers will
                             take effect when a HTTPClient instance is
                             instantiated. Default is "v1"
                             Currently, only "v1" is supported.
-    :type service_version: string
-    :param timeout: How long to wait for the server to send data before giving
-                    up, as a float. In seconds.
+     timeout (float): How long to wait for the server to send data
+                    before giving up, as a float. In seconds.
                     Default is 25, and 0 means no limitation.
-    :type timeout: float
-    :param secure: Use HTTPS if it is True, Default is True.
-    :type secure: boolean
-    :param cert: If string, path to ssl client cert file(.pem).
-                 If tuple, ('cert', 'key') pair.
-    :type cert: string or tuple
-    :param defaultHeaders: The extra http headers in every request.
-    :type defaultHeaders: dict
+     secure (bool): Use HTTPS if it is True, Default is True.
+     cert (str/tuple): If str, path to ssl client cert file(.pem).
+                 If tuple, ('cert', 'key') pair. Defaults to None.
+     verify (bool/str): (optional) Either a bool, in which case it controls
+                 whether we verify the server's TLS certificate, or a string,
+                 in which case it must be a path to a CA bundle to use.
+                 Defaults to ``True``.
+     default_headers (dict): The extra http headers in every request.
+
+    Returns:
+        object: An HTTP client interacting with RESTAPI web service.
+
     """
 
     USER_AGENT = 'python-restclient'
@@ -91,35 +89,63 @@ def __init__(self, service_address, user, password,
                  hostname=None,
                  secure=True,
                  timeout=DEFAULT_TIMEOUT_SEC,
-                 defaultHeaders={},
+                 default_headers=None,
                  cert=None,
+                 verify=True
                  ):
         self.user = user
         self.password = password
-        self.schema = secure and 'https' or 'http'
-        self.service_address = service_address
+        self.service_type = service_type
+        self.service_version = service_version
+        self.service_address = service_address.rstrip('/')
         self.hostname = hostname
         self.port = port
+        url_service_point = self.service_address
+        list_uri = [self.service_address]
+        self.schema = None
+        if ":" in self.service_address:
+            list_uri = self.service_address.split(':')
+            if list_uri[0].strip().lower() in ["http", "https"]:
+                # found schema string
+                self.schema = list_uri[0].strip().lower()
+                list_uri = list_uri[1:]
+
+        # if no schema provide, default secure as True set schema to https
+        self.schema = self.schema or secure and "https" or "http"
+        prefix_http = f"{self.schema}://"
+
+        list_uri[0] = list_uri[0].lstrip("//")
+        if len(list_uri) > 1 and "/" != list_uri[1][0]:
+            # found embedded port
+            self.port = int(list_uri[1].split('/')[0])
+            url_service_point = ":".join(list_uri)
+        elif len(list_uri) == 1:
+            # no port in service address, add port if defined port is not 80
+            if "80" != self.port:
+                list_seg_sp = list_uri[0].split('/')
+                list_seg_sp[0] = f"{list_seg_sp[0]}:{self.port}"
+                url_service_point = "/".join(list_seg_sp)
+        list_uri = url_service_point.split('/')
+        # if context root is provided, default to /api
+        if len(list_uri) == 1:
+            list_uri.append('api')
+        list_uri.append(self.service_version)
+        self.service_address = f"{prefix_http}{'/'.join(list_uri)}"
+        self.domain = f"{prefix_http}{list_uri[0]}"
+        self.base_url = f"/{'/'.join(list_uri[1:])}"
+        self.verify = verify if "https" == self.schema else False
         self.cert = cert
-        self.domain = self.schema + '://' + self.service_address \
-            + (':' + str(self.port) if self.port else '')
         self.timeout = timeout
         self.defaultHeaders = self.DefaultHeaders.copy()
-        self.defaultHeaders.update(defaultHeaders)
+        self.defaultHeaders = dict()
+        if default_headers is not None and isinstance(default_headers, dict):
+            self.defaultHeaders.update(default_headers)
         self.defaultQuerystrings = {}
-        self.service_type = service_type
-        self.service_version = service_version
         self.authenticate = get_authenticate(
             service_type=self.service_type,
             service_version=self.service_version
         )
-
-        if not secure:
-            self.verify_cert = False
-        elif self.cert is not None:
-            self.verify_cert = True
-        else:
-            self.verify_cert = False
+        self.session = requests.session()
 
     @classmethod
     def log_req(cls, args, kwargs):
@@ -177,17 +203,18 @@ def request(self, url, method, **kwargs):
             if self.authenticate.get_auth_url() in url:
                 attempts += 1
                 log_required = False
-            absolute_url = url if is_absolute_url(url) else self.domain + url
+            absolute_url = url if is_absolute_url(url) \
+                else self.service_address + url
             if log_required:
                 self.log_req(
                     (absolute_url, method,),
                     kwargs
                  )
             try:
-                resp = requests.request(
+                resp = self.session.request(
                     method,
                     absolute_url,
-                    verify=self.verify_cert,
+                    verify=self.verify,
                     cert=self.cert,
                     **kwargs)
                 self.log_resp(resp)
@@ -206,7 +233,8 @@ def request(self, url, method, **kwargs):
                     url = self._parse_url(link)
                     logger.info(REDIRECTING.format(old_url, url))
                     continue
-                elif resp.status_code >= 400:
+
+                if resp.status_code >= 400:
                     raise exceptions.raise_error(resp, body, self.service_type)
                 return resp, body
 
@@ -220,6 +248,7 @@ def request(self, url, method, **kwargs):
             except exceptions.BadRequest as e:
                 raise e
             except requests.exceptions.ConnectionError as e:
+                logger.error(f"Error When Requesting Url: {absolute_url}")
                 raise exceptions.ConnectionError(CONNECTION_ERROR.format(e))
             except Timeout as e:
                 logger.debug(e)
diff --git a/pyds8k/resources/__init__.py b/pyds8k/resources/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/resources/ds8k/__init__.py b/pyds8k/resources/ds8k/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/resources/ds8k/v1/__init__.py b/pyds8k/resources/ds8k/v1/__init__.py
index c125f61..6ef8f0b 100755
--- a/pyds8k/resources/ds8k/v1/__init__.py
+++ b/pyds8k/resources/ds8k/v1/__init__.py
@@ -17,11 +17,12 @@
 from . import ioports, flashcopy, events, mappings, pprc, eserep, \
     users, systems, nodes, marrays, encryption_groups, io_enclosures, \
     pools, tserep, lss, volumes, host_ports, hosts
-from .cs import pprcs
+from .cs import pprcs, flashcopies
 
 __all__ = (
     'ioports',
     'flashcopy',
+    'flashcopies',
     'events',
     'mappings',
     'pprc',
diff --git a/pyds8k/resources/ds8k/v1/common/__init__.py b/pyds8k/resources/ds8k/v1/common/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/resources/ds8k/v1/common/base.py b/pyds8k/resources/ds8k/v1/common/base.py
index 52df2cc..e04c414 100755
--- a/pyds8k/resources/ds8k/v1/common/base.py
+++ b/pyds8k/resources/ds8k/v1/common/base.py
@@ -35,7 +35,7 @@ class Base(RootResourceMixin, Resource):
     # the id_field can't be set to value other than "id"
     id_field = 'id'
     url_field = 'link'
-    base_url = '/api/v1'
+    base_url = ''
     create_method = 'posta'
     # Required only in writable resources, fileds are from _template
     # Resource id is exclude.
diff --git a/pyds8k/resources/ds8k/v1/common/mixins.py b/pyds8k/resources/ds8k/v1/common/mixins.py
index 9223a55..5bf1e56 100755
--- a/pyds8k/resources/ds8k/v1/common/mixins.py
+++ b/pyds8k/resources/ds8k/v1/common/mixins.py
@@ -27,6 +27,7 @@
 class RootBaseMixin(object):
     pass
 
+
 # Note: the format of all the get list methods should be:
 #           get_{right type in types}
 #       the format of all the get single methods should be:
@@ -37,46 +38,137 @@ class RootBaseMixin(object):
 
 class RootSystemMixin(object):
     def get_systems(self):
+        """
+        Get DS8000 System Object
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.systems.System`.
+
+        """
         return self.all(types.DS8K_SYSTEM, rebuild_url=True).list()
 
 
 class RootNodeMixin(object):
     def get_nodes(self, node_id=None):
+        """
+        Get nodes
+
+        Args:
+            node_id (str): get the node by id or all nodes if no id specified.
+
+        Returns:
+            list:A list of :py:class:`pyds8k.resources.ds8k.v1.nodes.Node`.
+
+        """
         if node_id:
             return self.get_node(node_id)
         return self.all(types.DS8K_NODE, rebuild_url=True).list()
 
     def get_node(self, node_id):
+        """
+        Get a node by id
+
+        Args:
+            node_id (str): id of the node to get.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.nodes.Node`.
+
+        """
         return self.one(types.DS8K_NODE, node_id, rebuild_url=True).get()
 
 
 class RootMarrayMixin(object):
     def get_marrays(self, marray_id=None):
+        """
+        Get managed arrays
+
+        Args:
+            marray_id (str): id of the target managed array, get all if none
+
+        Returns:
+            list: the list of
+            :py:class:`pyds8k.resources.ds8k.v1.marrays.Marray`.
+
+        """
         if marray_id:
             return self.get_marray(marray_id)
         return self.all(types.DS8K_MARRAY, rebuild_url=True).list()
 
     def get_marray(self, marray_id):
+        """
+        Get a managed array.
+
+        Args:
+            marray_id (str): Required. id of the target managed array.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.marrays.Marray`.
+
+        """
         return self.one(types.DS8K_MARRAY, marray_id, rebuild_url=True).get()
 
 
 class RootUserMixin(object):
     def get_users(self, user_name=None):
+        """
+        Get users.
+
+        Args:
+            user_name (str): name of the target user. get all if none.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.users.User`.
+
+        """
         if user_name:
             return self.get_user(user_name)
         return self.all(types.DS8K_USER, rebuild_url=True).list()
 
     def get_user(self, user_name):
+        """
+        Get a user.
+
+        Args:
+            user_name (str): Required. the name of the target user.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.users.User`.
+
+        """
         return self.one(types.DS8K_USER, user_name, rebuild_url=True).get()
 
 
 class RootIOEnclosureMixin(object):
     def get_io_enclosures(self, enclosure_id=None):
+        """
+        Get IO Enclosures.
+
+        Args:
+            enclosure_id (str): id of the target IO Enclosure. Get all if none.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.io_enclosures.IOEnclosure`.
+
+        """
         if enclosure_id:
             return self.get_io_enclosure(enclosure_id)
         return self.all(types.DS8K_IOENCLOSURE, rebuild_url=True).list()
 
     def get_io_enclosure(self, enclosure_id):
+        """
+        Get an IO Enclosure.
+
+        Args:
+            enclosure_id (str): Required. id of the target IO Enclosure.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.io_enclosures.IOEnclosure`.
+
+        """
         return self.one(types.DS8K_IOENCLOSURE,
                         enclosure_id,
                         rebuild_url=True).get()
@@ -84,11 +176,33 @@ def get_io_enclosure(self, enclosure_id):
 
 class RootEncryptionGroupMixin(object):
     def get_encryption_groups(self, group_id=None):
+        """
+        Get Encryption Groups.
+
+        Args:
+            group_id (str): id of the target Encryption Group. Get all if none.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.encryption_groups.EncryptionGroup`.
+
+        """
         if group_id:
             return self.get_encryption_group(group_id)
         return self.all(types.DS8K_ENCRYPTION_GROUP, rebuild_url=True).list()
 
     def get_encryption_group(self, group_id):
+        """
+        Get An Encryption Groups.
+
+        Args:
+            group_id (str): Required. id of the target Encryption Group.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.encryption_groups.EncryptionGroup`.
+
+        """
         return self.one(types.DS8K_ENCRYPTION_GROUP,
                         group_id,
                         rebuild_url=True).get()
@@ -96,11 +210,31 @@ def get_encryption_group(self, group_id):
 
 class RootPoolMixin(object):
     def get_pools(self, pool_id=None):
+        """
+        Get Extent Pools
+
+        Args:
+            pool_id (str): id of the target extent pool. Get all if none.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.pools.Pool`.
+
+        """
         if pool_id:
             return self.get_pool(pool_id)
         return self.all(types.DS8K_POOL, rebuild_url=True).list()
 
     def get_pool(self, pool_id):
+        """
+        Get Extent Pool
+
+        Args:
+            pool_id (str): Required. id of the target extent pool.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.pools.Pool`.
+
+        """
         return self.one(types.DS8K_POOL, pool_id, rebuild_url=True).get()
 
     def get_tserep_by_pool(self, pool_id):
@@ -134,8 +268,8 @@ def update_tserep_cap_by_pool(self, pool_id, cap, captype=''):
                           pool_id,
                           rebuild_url=True
                           ).all(
-                              types.DS8K_TSEREP
-                              ).update({'cap': cap, 'captype': captype})
+            types.DS8K_TSEREP
+        ).update({'cap': cap, 'captype': captype})
         return res
 
     def update_eserep_cap_by_pool(self, pool_id, cap, captype=''):
@@ -143,8 +277,8 @@ def update_eserep_cap_by_pool(self, pool_id, cap, captype=''):
                           pool_id,
                           rebuild_url=True
                           ).all(
-                              types.DS8K_ESEREP
-                              ).update({'cap': cap, 'captype': captype})
+            types.DS8K_ESEREP
+        ).update({'cap': cap, 'captype': captype})
         return res
 
     def update_tserep_threshold_by_pool(self, pool_id, threshold):
@@ -152,8 +286,8 @@ def update_tserep_threshold_by_pool(self, pool_id, threshold):
                           pool_id,
                           rebuild_url=True
                           ).all(
-                              types.DS8K_TSEREP
-                              ).update({'threshold': threshold})
+            types.DS8K_TSEREP
+        ).update({'threshold': threshold})
         return res
 
     def update_eserep_threshold_by_pool(self, pool_id, threshold):
@@ -161,11 +295,22 @@ def update_eserep_threshold_by_pool(self, pool_id, threshold):
                           pool_id,
                           rebuild_url=True
                           ).all(
-                              types.DS8K_ESEREP
-                              ).update({'threshold': threshold})
+            types.DS8K_ESEREP
+        ).update({'threshold': threshold})
         return res
 
     def get_volumes_by_pool(self, pool_id):
+        """
+        Get volumes of a pool by the pool id.
+
+        Args:
+            pool_id (str): id of the target extent pool.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         return self.one(types.DS8K_POOL,
                         pool_id,
                         rebuild_url=True
@@ -174,25 +319,81 @@ def get_volumes_by_pool(self, pool_id):
 
 class RootVolumeMixin(object):
     def get_volumes(self, volume_id=None):
+        """
+        Get Volumes
+
+        Args:
+            volume_id (str): id of the target volume. Get all if none.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         if volume_id:
             return self.get_volume(volume_id)
         return self.all(types.DS8K_VOLUME, rebuild_url=True).list()
 
     def get_volume(self, volume_id):
+        """
+        Get A volume.
+
+        Args:
+            volume_id (str): Required. id of the target volume.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         return self.one(types.DS8K_VOLUME, volume_id, rebuild_url=True).get()
 
     def delete_volume(self, volume_id):
+        """
+        Delete A volume.
+
+        Args:
+            volume_id (str): Required. id of the target volume.
+
+        Returns:
+            tuple: tuple of DS8000 Server Response.
+
+        """
         _, res = self.one(types.DS8K_VOLUME,
                           volume_id,
                           rebuild_url=True).delete()
         return res
 
-    def create_volume(self, name, cap, pool, stgtype,
-                      captype='', lss='', tp='',
-                      ):
+    def create_volume(
+            self,
+            name,
+            cap,
+            pool,
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=types.DS8K_CAPTYPE_GIB,
+            lss='',
+            tp=''):
+        """
+        Create One Volume
+
+        Args:
+            name (str): Required. The name for the volume to be created
+            cap (str): Required. The capacity, number in str
+            pool (str): Required. The pool for the volume
+            stgtype (str): select from types.DS8K_VOLUME_TYPES,
+                          Default to ``'fb'``
+            captype (str): select from types.DS8K_CAPTYPES,
+                          Default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method,
+                     valid options include `none`, `ese`, `tse`
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         self._verify_type(captype, types.DS8K_CAPTYPES)
         self._verify_type(stgtype, types.DS8K_VOLUME_TYPES)
-        self._verify_type(tp, types.DE8K_TPS)
+        self._verify_type(tp, types.DS8K_TPS)
         _, res = self.all(types.DS8K_VOLUME,
                           rebuild_url=True
                           ).posta({'name': name,
@@ -206,18 +407,47 @@ def create_volume(self, name, cap, pool, stgtype,
                                   )
         return res
 
-    def create_volumes(self, cap, pool, stgtype,
-                       name='', quantity='',
-                       name_col='',
-                       captype='', lss='', tp='',
-                       ):
+    def create_volumes(
+            self,
+            name_col,
+            cap,
+            pool,
+            name='',
+            quantity='',
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=types.DS8K_CAPTYPE_GIB,
+            lss='',
+            tp=''):
+        """
+        Create a group of volumes with different names
+
+        Args:
+            name_col (list): ["name-1", "name-2",..., "name-N"]
+            cap (str): the capacity, number in str
+            pool (str): the pool for the volume
+            name (str): Either 1) Name of the volume to be created,
+                       or 2) Prefix of the <quantity> volumes to be created
+            quantity (str): number of volumes to create, number in str
+            stgtype (str): select from types.DS8K_VOLUME_TYPES,
+                          default to ``'fb'``
+            captype (str): select from types.DS8K_CAPTYPES,
+                          default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method,
+                     in ``none``, ``ese``, ``tse``
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         self._verify_type(captype, types.DS8K_CAPTYPES)
         self._verify_type(stgtype, types.DS8K_VOLUME_TYPES)
-        self._verify_type(tp, types.DE8K_TPS)
+        self._verify_type(tp, types.DS8K_TPS)
         _, res = self.all(types.DS8K_VOLUME,
                           rebuild_url=True
                           ).posta({'name': name,
-                                   'namecol': name_col,
+                                   'namecol': name_col if name_col else None,
                                    'quantity': quantity,
                                    'cap': cap,
                                    'captype': captype,
@@ -232,51 +462,230 @@ def create_volumes(self, cap, pool, stgtype,
     def create_volume_ckd(self, name, cap, pool,
                           captype='', lss='', tp='',
                           ):
-        return self.create_volume(name=name, cap=cap,
-                                  pool=pool,
-                                  stgtype=types.DS8K_VOLUME_TYPE_CKD,
-                                  captype=captype, lss=lss, tp=tp)
+        """
+        Create One CKD Volume
+
+        Args:
+            name (str): Required. The name for the volume to be created
+            cap (str): Required. The capacity, number in str
+            pool (str): Required. The pool for the volume
+            captype (str): select from types.DS8K_CAPTYPES,
+                          Default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method,
+                     valid options include `none`, `ese`, `tse`
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
+        return self.create_volume(
+            name, cap, pool,
+            stgtype=types.DS8K_VOLUME_TYPE_CKD,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
 
     def create_volume_fb(self, name, cap, pool,
                          captype='', lss='', tp='',
                          ):
-        return self.create_volume(name=name, cap=cap,
-                                  pool=pool, stgtype=types.DS8K_VOLUME_TYPE_FB,
-                                  captype=captype, lss=lss, tp=tp)
-
-    def create_volumes_with_same_prefix(self, cap, pool, stgtype,
-                                        name='', quantity='',
-                                        captype='', lss='', tp='',
-                                        ):
-        return self.create_volumes(cap=cap, pool=pool, stgtype=stgtype,
-                                   name=name, quantity=quantity,
-                                   captype=captype, lss=lss, tp=tp,
-                                   )
-
-    def create_volumes_without_same_prefix(self, cap, pool, stgtype,
-                                           name_col='',
-                                           captype='', lss='', tp='',
-                                           ):
-        return self.create_volumes(cap=cap, pool=pool, stgtype=stgtype,
-                                   name_col=name_col,
-                                   captype=captype, lss=lss, tp=tp,
-                                   )
+        """
+        Create One FB Volume
+
+        Args:
+            name (str): Required. The name for the volume
+                       to be created
+            cap (str): Required. The capacity, number in str
+            pool (str): Required. The pool for the volume
+            captype (str): select from types.DS8K_CAPTYPES,
+                          Default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method,
+                     valid options include `none`, `ese`, `tse`
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
+        return self.create_volume(
+            name, cap, pool,
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
+
+    def create_volumes_with_same_prefix(
+            self,
+            name,
+            cap,
+            pool,
+            quantity='',
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=types.DS8K_CAPTYPE_GIB,
+            lss='',
+            tp=''):
+        """
+        Create a volume with a name or a group of
+        volumes with the same prefix
+
+        Args:
+            name (str): 1, Name of the volume to be created,
+                       or 2. Prefix of the <quantity> volumes
+                       to be created
+            cap (str): the capacity, number in str
+            pool (str): the pool for the volume
+            quantity (str): number of volumes to create, number in str
+            stgtype (str): select from types.DS8K_VOLUME_TYPES,
+                          default to ``'fb'``
+            captype (str): select from types.DS8K_CAPTYPES,
+                          default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method, in none, ese, tse
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
+        return self.create_volumes(
+            None, cap, pool,
+            name=name,
+            quantity=quantity,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
+
+    def create_volumes_without_same_prefix(
+            self,
+            name_col,
+            cap,
+            pool,
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=types.DS8K_CAPTYPE_GIB,
+            lss='',
+            tp=''):
+        """
+        Create a group of volumes with specified names
+
+        Args:
+            name_col (str): ["name-1", "name-2",..., "name-N"]
+            cap (str): the capacity, number in str
+            pool (str): the pool for the volume
+            stgtype (str): select from types.DS8K_VOLUME_TYPES,
+                          default to ``'fb'``
+            captype (str): select from types.DS8K_CAPTYPES,
+                         default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method, in none, ese, tse
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+        """
+        if not isinstance(name_col, list):
+            raise ValueError(
+                INVALID_TYPE.format('list')
+            )
+        return self.create_volumes(
+            name_col, cap, pool,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
+
+    def create_volumes_with_names(
+            self,
+            names,
+            cap,
+            pool,
+            stgtype=types.DS8K_VOLUME_TYPE_FB,
+            captype=types.DS8K_CAPTYPE_GIB,
+            lss='',
+            tp=''):
+        """
+        Create a group of volumes with specified names
+
+        Args:
+            names (str): ["name-1", "name-2",..., "name-N"]
+            cap (str): the capacity, number in str
+            pool (str): the pool for the volume
+            stgtype (str): select from types.DS8K_VOLUME_TYPES,
+                         default to ``'fb'``
+            captype (str): select from types.DS8K_CAPTYPES,
+                         default to ``'gib'``
+            lss (str): logical subsystem id
+            tp (str): storage allocation method, in none, ese, tse
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+        """
+        if not isinstance(names, list):
+            raise ValueError(
+                INVALID_TYPE.format('list')
+            )
+        return self.create_volumes(
+            names, cap, pool,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
 
     def update_volume_rename(self, volume_id, new_name):
+        """
+        Rename a volume by its id
+
+        Args:
+            volume_id (str): id of the volume
+            new_name (str): the new name of the volume
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         _, res = self.one(types.DS8K_VOLUME,
                           volume_id,
                           rebuild_url=True).update({'name': new_name})
         return res
 
     def update_volume_extend(self, volume_id, new_size, captype=''):
+        """
+
+        Args:
+            volume_id (str): Required. id of the target volume.
+            new_size (str): Required. new size of the target volume.
+            captype (str): Required. select from types.DS8K_CAPTYPES.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         _, res = self.one(types.DS8K_VOLUME,
                           volume_id,
                           rebuild_url=True).update(
-                              {'cap': new_size, 'captype': captype}
-                              )
+            {'cap': new_size, 'captype': captype}
+        )
         return res
 
     def update_volume_move(self, volume_id, new_pool):
+        """
+        Move one volume to a new extent pool.
+        Args:
+            volume_id (str): Required. id of the target volume.
+            new_pool (str): Required. id of the new extent pool.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         _, res = self.one(types.DS8K_VOLUME,
                           volume_id,
                           rebuild_url=True).update({'pool': new_pool})
@@ -291,24 +700,75 @@ def update_volume_move(self, volume_id, new_pool):
 
 class RootIOPortMixin(object):
     def get_ioports(self, port_id=None):
+        """
+        Get IO Ports
+
+        Args:
+            port_id (str): id of the target IO port. Get all if none.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.ioports.IOPort`.
+
+        """
         if port_id:
             return self.get_ioport(port_id)
         return self.all(types.DS8K_IOPORT, rebuild_url=True).list()
 
     def get_ioport(self, port_id):
+        """
+        Get an IO Port.
+
+        Args:
+            port_id (str): Required. id of the target IO port.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.ioports.IOPort`.
+
+        """
         return self.one(types.DS8K_IOPORT, port_id, rebuild_url=True).get()
 
 
 class RootHostPortMixin(object):
     def get_host_ports(self, port_id=None):
+        """
+        Get Host Ports.
+
+        Args:
+            port_id (str): id of the target host port. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         if port_id:
             return self.get_host_port(port_id)
         return self.all(types.DS8K_HOST_PORT, rebuild_url=True).list()
 
     def get_host_port(self, port_id):
+        """
+        Get A Host Port.
+        Args:
+            port_id (str): Required. id of the target host port.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         return self.one(types.DS8K_HOST_PORT, port_id, rebuild_url=True).get()
 
     def delete_host_port(self, port_id):
+        """
+        Delete A Host Port.
+
+        Args:
+            port_id (str): Required. id of the target host port.
+
+        Returns:
+            tuple: A tuple of HTTP Response and DS8000 server message.
+
+        """
         _, res = self.one(types.DS8K_HOST_PORT,
                           port_id,
                           rebuild_url=True
@@ -316,6 +776,17 @@ def delete_host_port(self, port_id):
         return res
 
     def create_host_port(self, port_id, host_name):
+        """
+        Create A Host Port.
+
+        Args:
+            port_id (str): Required. wwpn of the port.
+            host_name (str): Required. name of the host.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         # .create().save() is not a good way for DS8K.
         _, res = self.all(types.DS8K_HOST_PORT,
                           rebuild_url=True
@@ -323,6 +794,17 @@ def create_host_port(self, port_id, host_name):
         return res
 
     def update_host_port_change_host(self, port_id, host_name):
+        """
+        Change Port to another Host.
+
+        Args:
+            port_id (str): Required. id of the host port.
+            host_name (): Required. name of the new host.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         _, res = self.one(types.DS8K_HOST_PORT,
                           port_id,
                           rebuild_url=True
@@ -332,32 +814,113 @@ def update_host_port_change_host(self, port_id, host_name):
 
 class RootHostMixin(object):
     def get_hosts(self, host_name=None):
+        """
+        Get Hosts.
+
+        Args:
+            host_name (str): name of the target host. Get all if None.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.hosts.Host`.
+
+        """
         if host_name:
             return self.get_host(host_name)
         return self.all(types.DS8K_HOST, rebuild_url=True).list()
 
     def get_host(self, host_name):
+        """
+        Get A Host.
+
+        Args:
+            host_name (str): Required. name of the target host.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.hosts.Host`.
+
+        """
         return self.one(types.DS8K_HOST, host_name, rebuild_url=True).get()
 
     def get_ioports_by_host(self, host_name):
+        """
+        Get IO Ports by the name of the Host.
+        Args:
+            host_name (str): Required. name of the host.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.ioports.IOPort`.
+
+        """
         return self.one(types.DS8K_HOST,
                         host_name,
                         rebuild_url=True
                         ).all(types.DS8K_IOPORT).list()
 
     def get_mappings_by_host(self, host_name):
+        """
+        Get Volume Mappings by the name fo the Host.
+
+        Args:
+            host_name (str): Required. name of the host.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.mappings.Volmap`.
+
+        """
         return self.one(types.DS8K_HOST,
                         host_name,
                         rebuild_url=True
                         ).all(types.DS8K_VOLMAP).list()
 
     def get_mapping_by_host(self, host_name, lunid):
+        """
+        Get the Volume Mapping by the name of the host
+        and the id of the volume.
+
+        Args:
+            host_name (str): Required. name of the host.
+            lunid (str): Required. id of the volume.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.mappings.Volmap`.
+
+        """
         return self.one(types.DS8K_HOST,
                         host_name,
                         rebuild_url=True
                         ).one(types.DS8K_VOLMAP, lunid).get()
 
+    def get_volumes_by_host(self, host_name):
+        """
+        Get Volumes by the name of the Host.
+
+        Args:
+            host_name (str): Required. name of the host.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
+        return (
+            self.one(types.DS8K_HOST, host_name, rebuild_url=True)
+            .all(types.DS8K_VOLUME)
+            .list()
+        )
+
     def delete_host(self, host_name):
+        """
+        Delete a host by name.
+
+        Args:
+            host_name (str): Required. name of the host.
+
+        Returns:
+            tuple: tuple of DS8000 Server Response.
+
+        """
         _, res = self.one(types.DS8K_HOST,
                           host_name,
                           rebuild_url=True
@@ -365,6 +928,17 @@ def delete_host(self, host_name):
         return res
 
     def create_host(self, host_name, hosttype):
+        """
+        Create A Host.
+
+        Args:
+            host_name (str): Required. name of the host.
+            hosttype (str): Required. type of the host.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.hosts.Host`.
+
+        """
         # .create().save() is not a good way for DS8K.
         _, res = self.all(types.DS8K_HOST,
                           rebuild_url=True
@@ -392,8 +966,8 @@ def map_volume_to_host(self, host_name, volume_id, lunid=''):
                           host_name,
                           rebuild_url=True
                           ).all(types.DS8K_VOLMAP).posta(
-                              post_data
-                              )
+            post_data
+        )
         return res
 
     def unmap_volume_from_host(self, host_name, lunid):
@@ -406,6 +980,17 @@ def unmap_volume_from_host(self, host_name, lunid):
 
 class RootLSSMixin(object):
     def get_lss(self, lss_id=None, lss_type=''):
+        """
+        Get LSS
+
+        Args:
+            lss_id (str): id of the target LSS. Get all if None.
+            lss_type (str): type of the target LSS.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.lss.LSS`.
+
+        """
         if lss_id:
             return self.get_lss_by_id(lss_id)
         if not lss_type:
@@ -414,49 +999,254 @@ def get_lss(self, lss_id=None, lss_type=''):
             raise ValueError(
                 INVALID_TYPE.format(
                     ', '.join(types.DS8K_VOLUME_TYPES)
-                    )
                 )
+            )
         return self.all(types.DS8K_LSS, rebuild_url=True).list(
             params={'type': lss_type}
         )
 
     def get_lss_by_id(self, lss_id):
+        """
+        Get LSS by id
+
+        Args:
+            lss_id (str): Required. id of the target LSS.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.lss.LSS`.
+
+        """
         return self.one(types.DS8K_LSS, lss_id, rebuild_url=True).get()
 
     def get_volumes_by_lss(self, lss_id):
+        """
+        Get Volumes by id of the LSS
+
+        Args:
+            lss_id (str): Required. id of the LSS.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         return self.one(types.DS8K_LSS,
                         lss_id,
                         rebuild_url=True
                         ).all(types.DS8K_VOLUME).list()
 
+    def create_lss_ckd(
+            self,
+            lss_id=None,
+            lss_type=types.DS8K_VOLUME_TYPE_CKD,
+            lcu_type=types.DS8K_LCU_TYPE_3990_6,
+            ss_id=None):
+        """
+        Create CKD LSS
+
+        Args:
+            lss_id (str): Required. id of the lss to be created.
+            lss_type (str): 'ckd', optional
+            lcu_type (str): valid types are 3990-3, 3990-6, 3990-tpf, bs2000
+            ss_id (str): associated subsystem id
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.lss.LSS`.
+
+        """
+        self._verify_type(lss_type, types.DS8K_LSS_TYPES)
+        self._verify_type(lcu_type, types.DS8K_LCU_TYPES)
+        _, res = self.all(
+            types.DS8K_LSS,
+            rebuild_url=True
+        ).posta(
+            {
+                'id': lss_id,
+                'type': lss_type,
+                'sub_system_identifier': ss_id,
+                'ckd_base_cu_type': lcu_type
+            }
+        )
+        return res
+
+    def delete_lss_by_id(self, lss_id):
+        """
+        Delete an LSS.
+
+        Args:
+            lss_id (str): Require. id of lss to be deleted.
+
+        Returns:
+            tuple: tuple of HTTP Response and DS8000 server message.
+
+        """
+        return self.one(types.DS8K_LSS, lss_id, rebuild_url=True).delete()
+
 
 class RootFlashCopyMixin(object):
     def get_flashcopies(self, fcid=None):
-        return self.get_flashcopy(fcid)
+        """
+        Get Flash Copies.
 
-    def get_flashcopy(self, fcid=None):
+        Args:
+            fcid (str):  id of the flash copy. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.flashcopy.FlashCopy`.
+
+        """
         if fcid:
             return self.one(types.DS8K_FLASHCOPY, fcid, rebuild_url=True).get()
         return self.all(types.DS8K_FLASHCOPY, rebuild_url=True).list()
 
+    def get_flashcopy(self, fcid=None):
+        """
+        Get A Flash Copy.
+
+        Args:
+            fcid (str): Required. id of the flash copy.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.flashcopy.FlashCopy`.
+
+        """
+        return self.get_flashcopies(fcid)
+
     def get_flashcopies_by_volume(self, volume_id):
+        """
+        Get Flash Copies by volume id.
+
+        Args:
+            volume_id (str):  Required. id of the target volume.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.flashcopy.FlashCopy`.
+
+        """
         return self.one(types.DS8K_VOLUME,
                         volume_id,
                         rebuild_url=True).all(types.DS8K_FLASHCOPY).list()
 
+    def get_cs_flashcopies(self, fcid=None):
+        """
+        Get Copy Service Flash Copies(R8).
+        Args:
+            fcid (str): id of the flash copy. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.cs.flashcopies.FlashCopy`.
+
+        """
+        if fcid:
+            return self.one('{}.{}'.format(
+                types.DS8K_COPY_SERVICE_PREFIX,
+                types.DS8K_CS_FLASHCOPY), fcid, rebuild_url=True).get()
+        return self.all('{}.{}'.format(
+            types.DS8K_COPY_SERVICE_PREFIX,
+            types.DS8K_CS_FLASHCOPY), rebuild_url=True).list()
+
+    def get_cs_flashcopy(self, fcid=None):
+        """
+        Get A Copy Service Flash Copy(R8).
+        Args:
+            fcid (str): Required. id of the flash copy.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.cs.flashcopies.FlashCopy`.
+
+        """
+        return self.get_cs_flashcopies(fcid)
+
+    def create_cs_flashcopy(self, volume_pairs, options=[]):
+        """
+        Create Copy Service FlashCopy
+
+        Args:
+            volume_pairs (list):
+            [{"source_volume": 0000,"target_volume": 1100},..]
+            options (list): Options.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.cs.flashcopies.FlashCopy`.
+
+        """
+        for option in options:
+            self._verify_type(option, types.DS8K_FC_OPTIONS)
+        _, res = self.all('{}.{}'.format(
+            types.DS8K_COPY_SERVICE_PREFIX,
+            types.DS8K_CS_FLASHCOPY),
+            rebuild_url=True).posta({"volume_pairs": volume_pairs,
+                                     "options": options
+                                     })
+        return res
+
+    def delete_cs_flashcopy(self, flashcopy_id):
+        """
+        Delete A Copy Service Flash Copy(R8).
+
+        Args:
+            flashcopy_id (str): Required. id of the target flash copy.
+
+        Returns:
+            tuple: A tuple of DS8000 RESTAPI server response.
+
+        """
+        _, res = self.one('{}.{}'.format(
+            types.DS8K_COPY_SERVICE_PREFIX,
+            types.DS8K_CS_FLASHCOPY),
+            flashcopy_id,
+            rebuild_url=True).delete()
+        return res
+
 
 class RootPPRCMixin(object):
     def get_pprc(self, pprc_id=None):
+        """
+        Get PPRC.
+
+        Args:
+            pprc_id (str): id of the PPRC. Get all if None.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.pprc.PPRC`.
+
+        """
         if pprc_id:
             return self.one(types.DS8K_PPRC, pprc_id, rebuild_url=True).get()
         return self.all(types.DS8K_PPRC, rebuild_url=True).list()
 
     def get_pprc_by_volume(self, volume_id):
+        """
+        Get PPRC for a Volume by volume id.
+
+        Args:
+            volume_id (str): Required. id of the target volume.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.pprc.PPRC`.
+
+        """
         return self.one(types.DS8K_VOLUME,
                         volume_id,
                         rebuild_url=True).all(types.DS8K_PPRC).list()
 
     def get_cs_pprcs(self, pprc_id=None):
+        """
+        Get Copy Service PPRCs(R8).
+
+        Args:
+            pprc_id (str): id of the PPRC. Get all if None.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.cs.pprcs.PPRC`.
+
+        """
         if pprc_id:
             return self.get_cs_pprc(pprc_id)
         return self.all('{}.{}'.format(
@@ -464,6 +1254,16 @@ def get_cs_pprcs(self, pprc_id=None):
             types.DS8K_CS_PPRC), rebuild_url=True).list()
 
     def get_cs_pprc(self, pprc_id):
+        """
+        Get A Copy Service PPRCs(R8).
+
+        Args:
+            pprc_id (str): Required. id of the PPRC.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.cs.pprcs.PPRC`.
+
+        """
         return self.one('{}.{}'.format(
             types.DS8K_COPY_SERVICE_PREFIX,
             types.DS8K_CS_PPRC), pprc_id, rebuild_url=True).get()
@@ -471,6 +1271,17 @@ def get_cs_pprc(self, pprc_id):
 
 class RootEventMixin(object):
     def get_events(self, evt_id=None, evt_filter={}):
+        """
+        Get Events.
+
+        Args:
+            evt_id (str): id of the event. Get all if None.
+            evt_filter (dict): predefined filters.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.events.Event`.
+
+        """
         if evt_id:
             return self.get_event(evt_id)
         return self.all(types.DS8K_EVENT,
@@ -478,6 +1289,16 @@ def get_events(self, evt_id=None, evt_filter={}):
                         ).list(params=evt_filter)
 
     def get_event(self, evt_id):
+        """
+        Get An Event.
+
+        Args:
+            evt_id (str): Required. id of the event.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.events.Event`.
+
+        """
         return self.one(types.DS8K_EVENT, evt_id, rebuild_url=True).get()
 
     def get_events_by_filter(self,
@@ -487,6 +1308,20 @@ def get_events_by_filter(self,
                              before=None,
                              after=None,
                              ):
+        """
+        Get Events by filters.
+
+        Args:
+            warning (bool): True or False
+            error (bool): True or False
+            info (bool): True or False
+            before (datetime): timestamp of the end of the time window.
+            after (datetime): timestamp of the start of the time window.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.events.Event`.
+
+        """
         severity = []
         for k, v in {'warning': warning,
                      'error': error,
@@ -505,7 +1340,7 @@ def get_events_by_filter(self,
                 if not isinstance(v, datetime):
                     raise InvalidArgumentError(
                         'before/after must be an datetime instance.'
-                        )
+                    )
                 dttz = datetime(year=v.year,
                                 month=v.month,
                                 day=v.day,
@@ -540,6 +1375,17 @@ class RootResourceMixin(RootSystemMixin,
 
 class VolumeMixin(object):
     def get_volumes(self, volume_id=None):
+        """
+        Get Volumes for the Caller Object.
+
+        Args:
+            volume_id (str): id of the volume. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         if volume_id:
             return self.get_volume(volume_id)
         if not self.id:
@@ -551,6 +1397,17 @@ def get_volumes(self, volume_id=None):
         return volumes
 
     def get_volume(self, volume_id):
+        """
+        Get A Volume for the Caller Object.
+
+        Args:
+            volume_id (str): Required. id of the volume.
+
+        Returns:
+            object: list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.volumes.Volume`.
+
+        """
         if not self.id:
             raise IDMissingError()
         return self.one(types.DS8K_VOLUME, volume_id).get()
@@ -558,6 +1415,17 @@ def get_volume(self, volume_id):
 
 class FCPortMixin(object):
     def get_ioports(self, port_id=None):
+        """
+        Get IO Ports for the Caller Object.
+
+        Args:
+            port_id (str): id of the IO Port. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.ioports.IOPort`.
+
+        """
         if port_id:
             return self.get_ioport(port_id)
         if not self.id:
@@ -569,6 +1437,16 @@ def get_ioports(self, port_id=None):
         return ioports
 
     def get_ioport(self, port_id):
+        """
+        Get An IO Port for the Caller Object.
+
+        Args:
+            port_id (str): Required. id of the IO Port.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.ioports.IOPort`.
+
+        """
         if not self.id:
             raise IDMissingError()
         return self.one(types.DS8K_IOPORT, port_id).get()
@@ -576,6 +1454,17 @@ def get_ioport(self, port_id):
 
 class HostPortMixin(object):
     def get_host_ports(self, port_id=None):
+        """
+        Get Host Ports for the Caller Object.
+
+        Args:
+            port_id (str): id of the Host Port. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         if port_id:
             return self.get_host_port(port_id)
         if not self.id:
@@ -587,6 +1476,16 @@ def get_host_ports(self, port_id=None):
         return host_ports
 
     def get_host_port(self, port_id):
+        """
+        Get An Host Ports for the Caller Object.
+
+        Args:
+            port_id (str): id of the Host Port. Get all if None.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.host_ports.HostPort`.
+
+        """
         if not self.id:
             raise IDMissingError()
         return self.one(types.DS8K_HOST_PORT, port_id).get()
@@ -594,9 +1493,17 @@ def get_host_port(self, port_id):
 
 class FlashCopyMixin(object):
     def get_flashcopies(self, fcid=None):
-        return self.get_flashcopy(fcid)
+        """
+        Get Flash Copies for the Caller Object.
 
-    def get_flashcopy(self, fcid=None):
+        Args:
+            fcid (str): id of the flash copy. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.flashcopy.FlashCopy`.
+
+        """
         if not self.id:
             raise IDMissingError()
         if fcid:
@@ -607,9 +1514,72 @@ def get_flashcopy(self, fcid=None):
         self._stop_updating()
         return flashcopies
 
+    def get_flashcopy(self, fcid):
+        """
+        Get A Flash Copies for the Caller Object.
+
+        Args:
+            fcid (str): Required. id of the flash copy.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.flashcopy.FlashCopy`.
+
+        """
+        return self.get_flashcopies(fcid)
+
+    def get_cs_flashcopies(self, fcid=None):
+        """
+        Get Copy Service Flash Copies for the Caller Object.
+
+        Args:
+            fcid (str): id of the flash copy. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.cs.flashcopies.FlashCopy`.
+
+        """
+        if not self.id:
+            raise IDMissingError()
+        if fcid:
+            return self.one('{}.{}'.format(
+                types.DS8K_COPY_SERVICE_PREFIX,
+                types.DS8K_CS_FLASHCOPY), fcid).get()
+        flashcopies = self.all('{}.{}'.format(
+            types.DS8K_COPY_SERVICE_PREFIX,
+            types.DS8K_CS_FLASHCOPY)).list()
+        self._start_updating()
+        setattr(self, types.DS8K_CS_FLASHCOPY, flashcopies)
+        self._stop_updating()
+        return flashcopies
+
+    def get_cs_flashcopy(self, fcid):
+        """
+        Get A Copy Service Flash Copies for the Caller Object.
+
+        Args:
+            fcid (str): Required. id of the flash copy.
+
+        Returns:
+            object:
+            :py:class:`pyds8k.resources.ds8k.v1.cs.flashcopies.FlashCopy`.
+
+        """
+        return self.get_cs_flashcopies(fcid)
+
 
 class PPRCMixin(object):
     def get_pprc(self, pprc_id=None):
+        """
+        Get PPRC for the Caller Object.
+
+        Args:
+            pprc_id (str): id of the PPRC. Get all if None.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.pprc.PPRC`.
+
+        """
         if not self.id:
             raise IDMissingError()
         if pprc_id:
@@ -621,6 +1591,16 @@ def get_pprc(self, pprc_id=None):
         return pprc
 
     def get_cs_pprcs(self, pprc_id=None):
+        """
+        Get Copy Service PPRC for the Caller Object.
+
+        Args:
+            pprc_id (str): id of the PPRC. Get all if None.
+
+        Returns:
+            list: A list of :py:class:`pyds8k.resources.ds8k.v1.cs.pprcs.PPRC`.
+
+        """
         if not self.id:
             raise IDMissingError
         if pprc_id:
@@ -636,6 +1616,16 @@ def get_cs_pprcs(self, pprc_id=None):
         return pprcs
 
     def get_cs_pprc(self, pprc_id):
+        """
+        Get A Copy Service PPRC for the Caller Object.
+
+        Args:
+            pprc_id (str): Required. id of the PPRC.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.cs.pprcs.PPRC`.
+
+        """
         if not self.id:
             raise IDMissingError
         return self.one('{}.{}'.format(
@@ -645,6 +1635,17 @@ def get_cs_pprc(self, pprc_id):
 
 class VolmapMixin(object):
     def get_mappings(self, lunid=None):
+        """
+        Get Mappings of the Volume by Volume id for the Caller Object.
+
+        Args:
+            lunid (str): id of the volume. Get all if None.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.mappings.Volmap`.
+
+        """
         if lunid:
             return self.get_mapping(lunid)
         if not self.id:
@@ -656,17 +1657,49 @@ def get_mappings(self, lunid=None):
         return mappings
 
     def get_mapping(self, lunid):
+        """
+        Get the Mapping of the Volume by Volume id for the Caller Object.
+
+        Args:
+            lunid (str): Require. id of the volume.
+
+        Returns:
+            object: :py:class:`pyds8k.resources.ds8k.v1.mappings.Volmap`.
+
+        """
         if not self.id:
             raise IDMissingError()
         return self.one(types.DS8K_VOLMAP, lunid).get()
 
     def delete_mapping(self, lunid):
+        """
+        Delete the Mapping of the Volume by Volume id for the Caller Object.
+
+        Args:
+            lunid (str): Require. id of the volume.
+
+        Returns:
+            tuple: tuple of DS8000 RESTAPI Server Response.
+
+        """
         if not self.id:
             raise IDMissingError()
         _, res = self.one(types.DS8K_VOLMAP, lunid).delete()
         return res
 
     def create_mappings(self, volumes=[], mappings=[]):
+        """
+        Create the Mapping of the Volume by Volume id for the Caller Object.
+
+        Args:
+            volumes (list): Require. volume ids.
+            mappings (list): Required. mappings.
+
+        Returns:
+            list: A list of
+            :py:class:`pyds8k.resources.ds8k.v1.mappings.Volmap`.
+
+        """
         if not self.id:
             raise IDMissingError()
         if volumes:
diff --git a/pyds8k/resources/ds8k/v1/common/types.py b/pyds8k/resources/ds8k/v1/common/types.py
index 387a54f..52befe4 100755
--- a/pyds8k/resources/ds8k/v1/common/types.py
+++ b/pyds8k/resources/ds8k/v1/common/types.py
@@ -25,6 +25,16 @@
 DS8K_TSEREP = 'tserep'
 DS8K_ESEREP = 'eserep'
 DS8K_LSS = 'lss'
+DS8K_LCU_TYPE_3990_3 = '3990-3'
+DS8K_LCU_TYPE_3990_TPF = '3990-tpf'
+DS8K_LCU_TYPE_3990_6 = '3990-6'
+DS8K_LCU_TYPE_bs2000 = 'bs2000'
+DS8K_LCU_TYPES = (
+    DS8K_LCU_TYPE_3990_3,
+    DS8K_LCU_TYPE_3990_TPF,
+    DS8K_LCU_TYPE_3990_6,
+    DS8K_LCU_TYPE_bs2000
+)
 DS8K_VOLUME = 'volumes'
 DS8K_SE = 'SE'
 DS8K_VOLUME_GROUP = 'volgrps'
@@ -36,6 +46,7 @@
 DS8K_VOLUME_TYPE_FB = 'fb'
 DS8K_VOLUME_TYPE_CKD = 'ckd'
 DS8K_VOLUME_TYPES = (DS8K_VOLUME_TYPE_FB, DS8K_VOLUME_TYPE_CKD)
+DS8K_LSS_TYPES = (DS8K_VOLUME_TYPE_CKD, )
 DS8K_FLASHCOPY = 'flashcopy'
 DS8K_PPRC = 'pprc'
 DS8K_CAPTYPE_GIB = 'gib'
@@ -50,7 +61,30 @@
 DS8K_TP_NONE = 'none'
 DS8K_TP_ESE = 'ese'
 DS8K_TP_TSE = 'tse'
-DE8K_TPS = (DS8K_TP_NONE, DS8K_TP_ESE, DS8K_TP_TSE)
+DS8K_TPS = (DS8K_TP_NONE, DS8K_TP_ESE, DS8K_TP_TSE)
 
 DS8K_COPY_SERVICE_PREFIX = 'cs'
 DS8K_CS_PPRC = 'pprcs'
+DS8K_CS_FLASHCOPY = 'flashcopies'
+
+DS8K_OPTION_FRCO = "freeze_consistency"
+DS8K_OPTION_ITW = "inhibit_target_writes"
+DS8K_OPTION_RECH = "record_changes"
+DS8K_OPTION_NBC = "no_background_copy"
+DS8K_OPTION_PER = "persistent"
+DS8K_OPTION_APTP = "allow_pprc_target_primary"
+DS8K_OPTION_RERE = "reverse_restore"
+DS8K_OPTION_FRR = "fast_reverse_restore"
+DS8K_OPTION_PSET = "permit_space_efficient_target"
+DS8K_OPTION_FSETOOS = "fail_space_efficient_target_out_of_space"
+
+DS8K_FC_OPTIONS = (DS8K_OPTION_FRCO,
+                   DS8K_OPTION_ITW,
+                   DS8K_OPTION_RECH,
+                   DS8K_OPTION_NBC,
+                   DS8K_OPTION_PER,
+                   DS8K_OPTION_APTP,
+                   DS8K_OPTION_RERE,
+                   DS8K_OPTION_FRR,
+                   DS8K_OPTION_PSET,
+                   DS8K_OPTION_FSETOOS)
diff --git a/pyds8k/resources/ds8k/v1/cs/__init__.py b/pyds8k/resources/ds8k/v1/cs/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/resources/ds8k/v1/cs/flashcopies.py b/pyds8k/resources/ds8k/v1/cs/flashcopies.py
new file mode 100644
index 0000000..51c1424
--- /dev/null
+++ b/pyds8k/resources/ds8k/v1/cs/flashcopies.py
@@ -0,0 +1,73 @@
+##############################################################################
+# Copyright 2019 IBM Corp.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+
+"""
+advanced FlashCopies interface.
+"""
+import six
+from pyds8k.base import ManagerMeta, ResourceMeta
+from ..common.base import Base, BaseManager
+from ..common.types import DS8K_CS_FLASHCOPY, DS8K_FLASHCOPY
+from ..volumes import Volume, VolumeManager
+
+
+@six.add_metaclass(ResourceMeta)
+class FlashCopy(Base):
+    resource_type = DS8K_CS_FLASHCOPY
+    _template = {'id': None,
+                 'persistent': None,
+                 'recording': None,
+                 'backgroundcopy': None,
+                 'state': None,
+                 'options': [],
+                 'volume_pairs': []
+                 }
+
+    related_resource = {'_volume_pairs': [{
+        'source_volume': (Volume, VolumeManager),
+        'target_volume': (Volume, VolumeManager)
+    }]
+    }
+
+    def __repr__(self):
+        return "<FlashCopy: {0}>".format(self._get_id())
+
+    def _add_details(self, info, force=False):
+        super(FlashCopy, self)._add_details(info, force=force)
+        if DS8K_FLASHCOPY in info:
+            self._id = info[DS8K_FLASHCOPY][0]['id']
+
+
+@six.add_metaclass(ManagerMeta)
+class FlashCopyManager(BaseManager):
+    """
+    Manage advanced FlashCopies resources.
+    """
+    resource_class = FlashCopy
+    resource_type = DS8K_CS_FLASHCOPY
+
+    def get(self, resource_id='', url='', obj_class=None, **kwargs):
+        return self._get(resource_id=resource_id, url=url,
+                         obj_class=obj_class, **kwargs)
+
+    def list(self, url='', obj_class=None, body=None, **kwargs):
+        return self._list(url=url, obj_class=obj_class, body=body, **kwargs)
+
+    def posta(self, url='', body=None):
+        return self._posta(url=url, body=body)
+
+    def delete(self, url=''):
+        return self._delete(url=url)
diff --git a/pyds8k/resources/ds8k/v1/cs/pprcs.py b/pyds8k/resources/ds8k/v1/cs/pprcs.py
index 017864a..5b03e20 100644
--- a/pyds8k/resources/ds8k/v1/cs/pprcs.py
+++ b/pyds8k/resources/ds8k/v1/cs/pprcs.py
@@ -17,6 +17,7 @@
 """
 advanced PPRC interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from ..common.base import Base, ReadOnlyManager
 from ..common.types import DS8K_CS_PPRC
@@ -24,7 +25,8 @@
 from ..systems import System, SystemManager
 
 
-class PPRC(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class PPRC(Base):
     resource_type = DS8K_CS_PPRC
 
     _template = {'id': '',
@@ -58,7 +60,8 @@ def _add_details(self, info, force=False):
         super(PPRC, self)._add_details(info, force=force)
 
 
-class PPRCManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class PPRCManager(ReadOnlyManager):
     """
     Manage advanced PPRC resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/encryption_groups.py b/pyds8k/resources/ds8k/v1/encryption_groups.py
index 4f4c08c..e7f4dd1 100755
--- a/pyds8k/resources/ds8k/v1/encryption_groups.py
+++ b/pyds8k/resources/ds8k/v1/encryption_groups.py
@@ -17,12 +17,15 @@
 """
 Encryption Group interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
-from .common.types import DS8K_ENCRYPTION_GROUP
+
 from .common.base import Base, ReadOnlyManager
+from .common.types import DS8K_ENCRYPTION_GROUP
 
 
-class EncryptionGroup(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class EncryptionGroup(Base):
     resource_type = DS8K_ENCRYPTION_GROUP
     # id_field = 'id'
     _template = {'id': '',
@@ -30,7 +33,8 @@ class EncryptionGroup(Base, metaclass=ResourceMeta):
                  }
 
 
-class EncryptionGroupManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class EncryptionGroupManager(ReadOnlyManager):
     """
     Manage Encryption Group resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/eserep.py b/pyds8k/resources/ds8k/v1/eserep.py
index b32b8f4..731b213 100755
--- a/pyds8k/resources/ds8k/v1/eserep.py
+++ b/pyds8k/resources/ds8k/v1/eserep.py
@@ -17,13 +17,15 @@
 """
 ESE Rep interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_ESEREP
 from .common.base import SingletonBase, SingletonBaseManager
 from .pools import Pool, PoolManager
 
 
-class ESERep(SingletonBase, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class ESERep(SingletonBase):
     resource_type = DS8K_ESEREP
     # id_field = 'id'
     _template = {'cap': '',
@@ -43,7 +45,8 @@ def __getattr__(self, key):
         return super(ESERep, self).__getattr__(key)
 
 
-class ESERepManager(SingletonBaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class ESERepManager(SingletonBaseManager):
     """
     Manage ESE Rep resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/events.py b/pyds8k/resources/ds8k/v1/events.py
index c3971e0..e3ff02d 100755
--- a/pyds8k/resources/ds8k/v1/events.py
+++ b/pyds8k/resources/ds8k/v1/events.py
@@ -17,12 +17,14 @@
 """
 Event interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_EVENT
 from .common.base import Base, ReadOnlyManager
 
 
-class Event(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Event(Base):
     resource_type = DS8K_EVENT
     # id_field = 'id'
     _template = {'id': '',
@@ -35,7 +37,8 @@ class Event(Base, metaclass=ResourceMeta):
                  }
 
 
-class EventManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class EventManager(ReadOnlyManager):
     """
     Manage Event resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/flashcopy.py b/pyds8k/resources/ds8k/v1/flashcopy.py
index 84b5334..5b41e85 100755
--- a/pyds8k/resources/ds8k/v1/flashcopy.py
+++ b/pyds8k/resources/ds8k/v1/flashcopy.py
@@ -17,13 +17,15 @@
 """
 FlashCopy interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.base import Base, ReadOnlyManager
 from .common.types import DS8K_FLASHCOPY
 from .volumes import Volume, VolumeManager
 
 
-class FlashCopy(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class FlashCopy(Base):
     resource_type = DS8K_FLASHCOPY
     # id_field = 'id'
     _template = {'id': '',
@@ -52,7 +54,8 @@ def _add_details(self, info, force=False):
     #    return "<FlashCopy: {}>".format(self.id)
 
 
-class FlashCopyManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class FlashCopyManager(ReadOnlyManager):
     """
     Manage FlashCopy resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/host_ports.py b/pyds8k/resources/ds8k/v1/host_ports.py
index 5480d99..18c1d21 100755
--- a/pyds8k/resources/ds8k/v1/host_ports.py
+++ b/pyds8k/resources/ds8k/v1/host_ports.py
@@ -17,6 +17,7 @@
 """
 Host Ports interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_HOST_PORT
 from .common.base import Base, BaseManager
@@ -24,7 +25,8 @@
 from .ioports import IOPort, IOPortManager
 
 
-class HostPort(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class HostPort(Base):
     resource_type = DS8K_HOST_PORT
     id_field = 'wwpn'
     _template = {'wwpn': '',
@@ -66,7 +68,8 @@ def _set_ioports(self):
     #    return "<HostPort: {0}>".format(self.id)
 
 
-class HostPortManager(BaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class HostPortManager(BaseManager):
     """
     Manage Host Ports resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/hosts.py b/pyds8k/resources/ds8k/v1/hosts.py
index 7415533..ea74b6b 100755
--- a/pyds8k/resources/ds8k/v1/hosts.py
+++ b/pyds8k/resources/ds8k/v1/hosts.py
@@ -17,14 +17,15 @@
 """
 Host interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.base import Base, BaseManager
 from .common.mixins import FCPortMixin, HostPortMixin, VolumeMixin, VolmapMixin
 from .common import types
 
 
-class Host(FCPortMixin, HostPortMixin, VolumeMixin, VolmapMixin, Base,
-           metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Host(FCPortMixin, HostPortMixin, VolumeMixin, VolmapMixin, Base):
     resource_type = types.DS8K_HOST
     id_field = 'name'
     alias = {'id': 'host_id'}
@@ -84,7 +85,8 @@ def _update_ioports_and_return_ids(self, port_ids, operator='+'):
         return [port.id for port in updated]
 
 
-class HostManager(BaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class HostManager(BaseManager):
     """
     Manage Host resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/io_enclosures.py b/pyds8k/resources/ds8k/v1/io_enclosures.py
index 16b1f33..3ab46dc 100755
--- a/pyds8k/resources/ds8k/v1/io_enclosures.py
+++ b/pyds8k/resources/ds8k/v1/io_enclosures.py
@@ -17,12 +17,14 @@
 """
 IO Enclosure interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_IOENCLOSURE
 from .common.base import Base, ReadOnlyManager
 
 
-class IOEnclosure(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class IOEnclosure(Base):
     resource_type = DS8K_IOENCLOSURE
     # id_field = 'id'
     _template = {'id': '',
@@ -31,7 +33,8 @@ class IOEnclosure(Base, metaclass=ResourceMeta):
                  }
 
 
-class IOEnclosureManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class IOEnclosureManager(ReadOnlyManager):
     """
     Manage IO Enclosure resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/ioports.py b/pyds8k/resources/ds8k/v1/ioports.py
index a74fc91..6c644d9 100755
--- a/pyds8k/resources/ds8k/v1/ioports.py
+++ b/pyds8k/resources/ds8k/v1/ioports.py
@@ -17,13 +17,15 @@
 """
 IO Ports interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_IOPORT
 from .common.base import Base, ReadOnlyManager
 from .io_enclosures import IOEnclosure, IOEnclosureManager
 
 
-class IOPort(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class IOPort(Base):
     resource_type = DS8K_IOPORT
     # id_field = 'id'
     _template = {'id': '',
@@ -43,7 +45,8 @@ class IOPort(Base, metaclass=ResourceMeta):
     #    return "<FCPort: {0}>".format(self.id)
 
 
-class IOPortManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class IOPortManager(ReadOnlyManager):
     """
     Manage IO Ports resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/lss.py b/pyds8k/resources/ds8k/v1/lss.py
index d996347..30f4c59 100755
--- a/pyds8k/resources/ds8k/v1/lss.py
+++ b/pyds8k/resources/ds8k/v1/lss.py
@@ -17,28 +17,109 @@
 """
 LSS interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
-from .common.types import DS8K_LSS, DS8K_VOLUME
-from .common.base import Base, ReadOnlyManager
+from .common.types import DS8K_LSS, DS8K_VOLUME, \
+    DS8K_LCU_TYPES, \
+    DS8K_LSS_TYPES, \
+    DS8K_LCU_TYPE_3990_6, \
+    DS8K_VOLUME_TYPE_CKD
+from .common.base import Base, BaseManager
 from .common.mixins import VolumeMixin
 
 
-class LSS(VolumeMixin, Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class LSS(VolumeMixin, Base):
     resource_type = DS8K_LSS
     # id_field = 'id'
-    _template = {'id': '',
-                 'type': '',
-                 'group': '',
-                 'addrgrp': '',
-                 'configvols': '',
-                 DS8K_VOLUME: '',
-                 }
+    _template = {
+        'id': '',
+        'type': '',
+        'ckd_base_cu_type': '',
+        'group': '',
+        'addrgrp': '',
+        'sub_system_identifier': '',
+        'configvols': '',
+        DS8K_VOLUME: '',
+    }
+
+    ckd_template = _template.copy()
+    ckd_template.update(
+        {
+            'ckd_base_cu_type': DS8K_LCU_TYPE_3990_6,
+            # lss type shared with volume type
+            'type': DS8K_VOLUME_TYPE_CKD
+        }
+    )
+    template_dict = {
+        DS8K_VOLUME_TYPE_CKD: ckd_template
+    }
+
+    readonly_fileds = ()
+    related_resource = {}
     related_resources_collection = (DS8K_VOLUME, )
 
+    def __init__(
+            self,
+            client,
+            manager=None,
+            url='',
+            info=None,
+            resource_id=None,
+            parent=None,
+            loaded=False,
+            lss_type=DS8K_VOLUME_TYPE_CKD,
+            lcu_type=DS8K_LCU_TYPE_3990_6
+    ):
+        super(LSS, self).__init__(
+            client,
+            manager=manager,
+            url=url,
+            info=info,
+            resource_id=resource_id,
+            parent=parent,
+            loaded=loaded
+        )
+        self._lss_type = lss_type
+        self._lcu_type = lcu_type
+        # isolated to ckd only
+        self._verify_type(self._lss_type, DS8K_LSS_TYPES)
+        self._verify_type(self._lcu_type, DS8K_LCU_TYPES)
+        self._template = self.template_dict[self._lss_type]
+
+    def __repr__(self):
+        return "<Storage LSS: {0}>".format(self._get_id())
 
-class LSSManager(ReadOnlyManager, metaclass=ManagerMeta):
+
+@six.add_metaclass(ManagerMeta)
+class LSSManager(BaseManager):
     """
     Manage LSS resources.
     """
     resource_class = LSS
     resource_type = DS8K_LSS
+
+    def get(self, resource_id='', url='', obj_class=None, **kwargs):
+        return self._get(
+            resource_id=resource_id,
+            url=url,
+            obj_class=obj_class,
+            **kwargs
+        )
+
+    def list(self, url='', obj_class=None, body=None, **kwargs):
+        return self._list(
+            url=url,
+            obj_class=obj_class,
+            body=body,
+            **kwargs
+        )
+
+    def posta(self, url='', body=None):
+        return self._posta(url=url, body=body)
+
+    def put(self, url='', body=None):
+        return self._put(url=url, body=body)
+
+    def delete(self, url=''):
+        return self._delete(url=url)
diff --git a/pyds8k/resources/ds8k/v1/mappings.py b/pyds8k/resources/ds8k/v1/mappings.py
index d55973f..ffa2aff 100755
--- a/pyds8k/resources/ds8k/v1/mappings.py
+++ b/pyds8k/resources/ds8k/v1/mappings.py
@@ -17,13 +17,15 @@
 """
 Host Volume Mapping interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.base import Base, BaseManager
 from .common.types import DS8K_VOLMAP
 from .volumes import Volume, VolumeManager
 
 
-class Volmap(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Volmap(Base):
     resource_type = DS8K_VOLMAP
     id_field = 'lunid'
     _template = {'lunid': '',
@@ -36,7 +38,8 @@ def __repr__(self):
         return "<Host Volume Mapping: {0}>".format(self._get_id())
 
 
-class VolmapManager(BaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class VolmapManager(BaseManager):
     """
     Manage Host Volume Mapping resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/marrays.py b/pyds8k/resources/ds8k/v1/marrays.py
index 83d0d5a..f66e30e 100755
--- a/pyds8k/resources/ds8k/v1/marrays.py
+++ b/pyds8k/resources/ds8k/v1/marrays.py
@@ -17,13 +17,15 @@
 """
 Marray interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_MARRAY
 from .common.base import Base, ReadOnlyManager
 from .pools import Pool, PoolManager
 
 
-class Marray(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Marray(Base):
     resource_type = DS8K_MARRAY
     # id_field = 'id'
     _template = {'id': '',
@@ -35,7 +37,8 @@ class Marray(Base, metaclass=ResourceMeta):
                         }
 
 
-class MarrayManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class MarrayManager(ReadOnlyManager):
     """
     Manage Marray resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/nodes.py b/pyds8k/resources/ds8k/v1/nodes.py
index e908d36..0338741 100755
--- a/pyds8k/resources/ds8k/v1/nodes.py
+++ b/pyds8k/resources/ds8k/v1/nodes.py
@@ -17,12 +17,14 @@
 """
 Node interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_NODE
 from .common.base import Base, ReadOnlyManager
 
 
-class Node(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Node(Base):
     resource_type = DS8K_NODE
     # id_field = 'id'
     _template = {'id': '',
@@ -30,7 +32,8 @@ class Node(Base, metaclass=ResourceMeta):
                  }
 
 
-class NodeManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class NodeManager(ReadOnlyManager):
     """
     Manage LSS resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/pools.py b/pyds8k/resources/ds8k/v1/pools.py
index cef0ec2..516a272 100755
--- a/pyds8k/resources/ds8k/v1/pools.py
+++ b/pyds8k/resources/ds8k/v1/pools.py
@@ -17,6 +17,7 @@
 """
 Extent pool interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_POOL, DS8K_VOLUME, \
     DS8K_TSEREP, DS8K_ESEREP
@@ -27,7 +28,8 @@
 
 # Note: VolumeMixin will override the methods with
 # same name in RootResourceMixin.
-class Pool(VolumeMixin, Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Pool(VolumeMixin, Base):
     resource_type = DS8K_POOL
     # id_field = 'id'
     _template = {'id': '',
@@ -111,7 +113,8 @@ def update_eserep_threshold(self, threshold):
                         ).update({'threshold': threshold})
 
 
-class PoolManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class PoolManager(ReadOnlyManager):
     """
     Manage Extent Pool resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/pprc.py b/pyds8k/resources/ds8k/v1/pprc.py
index 497437e..cb84daa 100755
--- a/pyds8k/resources/ds8k/v1/pprc.py
+++ b/pyds8k/resources/ds8k/v1/pprc.py
@@ -17,6 +17,7 @@
 """
 PPRC interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.base import Base, ReadOnlyManager
 from .common.types import DS8K_PPRC
@@ -24,7 +25,8 @@
 from .systems import System, SystemManager
 
 
-class PPRC(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class PPRC(Base):
     resource_type = DS8K_PPRC
     # id_field = 'id'
     _template = {'id': '',
@@ -53,7 +55,8 @@ def _add_details(self, info, force=False):
     #    return "<FlashCopy: {}>".format(self.id)
 
 
-class PPRCManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class PPRCManager(ReadOnlyManager):
     """
     Manage PPRC resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/systems.py b/pyds8k/resources/ds8k/v1/systems.py
index fa4a1d0..bdab844 100755
--- a/pyds8k/resources/ds8k/v1/systems.py
+++ b/pyds8k/resources/ds8k/v1/systems.py
@@ -17,12 +17,14 @@
 """
 Storage system interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_SYSTEM
 from .common.base import Base, ReadOnlyManager
 
 
-class System(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class System(Base):
     resource_type = DS8K_SYSTEM
     id_field = 'id'
     _template = {'id': '',
@@ -46,7 +48,8 @@ def get_system(self):
         return self.get_systems()[0]
 
 
-class SystemManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class SystemManager(ReadOnlyManager):
     """
     Manage Storage System resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/tserep.py b/pyds8k/resources/ds8k/v1/tserep.py
index bb17d11..24aff2d 100755
--- a/pyds8k/resources/ds8k/v1/tserep.py
+++ b/pyds8k/resources/ds8k/v1/tserep.py
@@ -17,13 +17,15 @@
 """
 TSE Rep interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_TSEREP
 from .common.base import SingletonBase, SingletonBaseManager
 from .pools import Pool, PoolManager
 
 
-class TSERep(SingletonBase, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class TSERep(SingletonBase):
     resource_type = DS8K_TSEREP
     # id_field = 'id'
     _template = {'cap': '',
@@ -43,7 +45,8 @@ def __getattr__(self, key):
         return super(TSERep, self).__getattr__(key)
 
 
-class TSERepManager(SingletonBaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class TSERepManager(SingletonBaseManager):
     """
     Manage TSE Rep resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/users.py b/pyds8k/resources/ds8k/v1/users.py
index da12f64..5babaf2 100755
--- a/pyds8k/resources/ds8k/v1/users.py
+++ b/pyds8k/resources/ds8k/v1/users.py
@@ -17,12 +17,14 @@
 """
 User interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.types import DS8K_USER
 from .common.base import Base, ReadOnlyManager
 
 
-class User(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class User(Base):
     resource_type = DS8K_USER
     id_field = 'name'
     _template = {'name': '',
@@ -31,7 +33,8 @@ class User(Base, metaclass=ResourceMeta):
                  }
 
 
-class UserManager(ReadOnlyManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class UserManager(ReadOnlyManager):
     """
     Manage User resources.
     """
diff --git a/pyds8k/resources/ds8k/v1/volumes.py b/pyds8k/resources/ds8k/v1/volumes.py
index 9623728..0c86b8d 100755
--- a/pyds8k/resources/ds8k/v1/volumes.py
+++ b/pyds8k/resources/ds8k/v1/volumes.py
@@ -17,6 +17,7 @@
 """
 Storage volume interface.
 """
+import six
 from pyds8k.base import ManagerMeta, ResourceMeta
 from .common.base import Base, BaseManager
 from .common import types
@@ -25,7 +26,8 @@
 from .hosts import Host, HostManager
 
 
-class Volume(Base, metaclass=ResourceMeta):
+@six.add_metaclass(ResourceMeta)
+class Volume(Base):
     resource_type = types.DS8K_VOLUME
     # id_field = 'id'
 
@@ -121,7 +123,8 @@ def _add_details(self, info, force=False):
         self._stop_updating()
 
 
-class VolumeManager(BaseManager, metaclass=ManagerMeta):
+@six.add_metaclass(ManagerMeta)
+class VolumeManager(BaseManager):
     """
     Manage Storage Volume resources.
     """
diff --git a/requirements.txt b/requirements.txt
index 3ea0c59..67824a5 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1,4 @@
-requests==2.22.0
-httpretty==0.9.6
+requests>=2.22.0
+httpretty>=0.9.6
+configparser
+six
\ No newline at end of file
diff --git a/setup.py b/setup.py
index b3227e4..53c9032 100644
--- a/setup.py
+++ b/setup.py
@@ -14,10 +14,11 @@
 # limitations under the License.
 ##############################################################################
 
+from setuptools import find_packages, setup
+
 import pyds8k
-from setuptools import setup, find_packages
 
-install_requires = ['requests', 'httpretty']
+install_requires = ['requests', 'httpretty', 'configparser', 'six']
 
 setup(
     name='pyds8k',
diff --git a/tox.ini b/tox.ini
index eb462ca..2bd951e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,7 +11,7 @@ install_command = pip install {opts} {packages}
 deps = -r{toxinidir}/requirements.txt
        -r{toxinidir}/test-requirements.txt
 commands =
-  nosetests -v {posargs}
+  nosetests -v --exe {posargs}
 
 [testenv:cover]
 deps = -r{toxinidir}/requirements.txt


Test patch:
diff --git a/pyds8k/test/__init__.py b/pyds8k/test/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/test/base.py b/pyds8k/test/base.py
index 04b3784..751e9c8 100755
--- a/pyds8k/test/base.py
+++ b/pyds8k/test/base.py
@@ -22,12 +22,18 @@
 class TestCaseWithConnect(unittest.TestCase):
 
     def setUp(self):
-        self.client = HTTPClient(service_address='localhost',
-                                 user='admin',
-                                 password='admin',
-                                 service_type='ds8k',
-                                 port='8088')
-        self.resource = Resource(self.client, DefaultManager(self.client))
+        self.client = HTTPClient(
+            "http://localhost:8088/api/",
+            'admin',
+            'admin',
+            service_type='ds8k',
+            port=8088
+        )
+        self.base_url = self.client.base_url
+        self.resource = Resource(
+            self.client,
+            manager=DefaultManager(self.client)
+        )
         self.domain = self.client.domain
         # self.maxDiff = None
 
diff --git a/pyds8k/test/data.py b/pyds8k/test/data.py
index 0daa6f6..ea554e9 100755
--- a/pyds8k/test/data.py
+++ b/pyds8k/test/data.py
@@ -60,37 +60,37 @@ def get_request_json_body(body):
 
 # actions fail/success response
 action_response = {
-  "server": {
-    "status": "ok",
-    "code": "",
-    "message": "Operation done successfully."
-  },
+    "server": {
+        "status": "ok",
+        "code": "",
+        "message": "Operation done successfully."
+    },
 }
 action_response_json = json.dumps(action_response)
 
 action_response_failed = {
-  "server": {
-    "status": "failed",
-    "code": "888",
-    "message": "Operation done unsuccessfully."
-  },
+    "server": {
+        "status": "failed",
+        "code": "888",
+        "message": "Operation done unsuccessfully."
+    },
 }
 action_response_failed_json = json.dumps(action_response_failed)
 _delete_response = {
-  "server": {
-    "status": "ok",
-    "code": "",
-    "message": "Operation done successfully."
-  },
+    "server": {
+        "status": "ok",
+        "code": "",
+        "message": "Operation done successfully."
+    },
 }
 _delete_response_json = json.dumps(_delete_response)
 
 _put_post_response = {
-  "server": {
-    "status": "ok",
-    "code": "",
-    "message": "Operation done successfully."
-  },
+    "server": {
+        "status": "ok",
+        "code": "",
+        "message": "Operation done successfully."
+    },
 }
 _put_post_response_json = json.dumps(_put_post_response)
 
@@ -101,42 +101,86 @@ def get_request_json_body(body):
         "message": "Operation done successfully."
     },
     "responses": [
-        {"server": {
-            "status": "ok",
-            "code": "",
-            "message": "Operation done successfully."
+        {
+            "server": {
+                "status": "ok",
+                "code": "",
+                "message": "Operation done successfully."
             },
-         "data": {
-            "volumes": [{"name": "lou_test1",
-                         "id": "0010"
-                         }
-                        ]
+            "data": {
+                "volumes": [{"name": "lou_test1",
+                             "id": "0010"
+                             }
+                            ]
             },
-         "link": {
-            "rel": "self",
-            "href": "https://localhost:8088/api/v1/volumes/0010"
+            "link": {
+                "rel": "self",
+                "href": "https://localhost:8088/api/v1/volumes/0010"
             }
-         },
-        {"server": {
-            "status": "ok",
-            "code": "",
-            "message": "Operation done successfully."
+        },
+        {
+            "server": {
+                "status": "ok",
+                "code": "",
+                "message": "Operation done successfully."
             },
-         "data": {
-            "volumes": [{"name": "lou_test2",
-                         "id": "0011"
-                         }
-                        ]
+            "data": {
+                "volumes": [{"name": "lou_test2",
+                             "id": "0011"
+                             }
+                            ]
             },
-         "link": {
-            "rel": "self",
-            "href": "https://localhost:8088/api/v1/volumes/0011"
+            "link": {
+                "rel": "self",
+                "href": "https://localhost:8088/api/v1/volumes/0011"
             }
-         },
+        },
     ]
 }
 create_volumes_response_json = json.dumps(create_volumes_response)
 
+create_lss_response = {
+    "server": {
+        "status": "ok",
+        "code": "",
+        "message": ""
+    },
+    "data": {
+        "lss": [
+            {
+                "id": "FE",
+                "link": {
+                    "rel": "self",
+                    "href": "http://rest_url/v1/lss/FE"
+                },
+                "group": "0",
+                "addrgrp": "",
+                "type": "ckd",
+                "sub_system_identifier": "FE00",
+                "ckd_base_cu_type": "3990-6",
+                "pprc_consistency_group": "disabled",
+                "critical_mode": "disabled",
+                "extended_long_busy_time": "120",
+                "cc_session_timeout": "300",
+                "xrc_session_timeout": "300",
+                "configvols": "0",
+                "volumes": {
+                    "link": {
+                        "rel": "self",
+                        "href": "http://rest_url/v1/lss/FE/volumes"
+                    }
+                }
+            }
+        ]
+    },
+    "link": {
+        "rel": "self",
+        "href": "http://localhost:8080/ds8000-rest-api/v1/lss/FE"
+    }
+}
+create_lss_response_json = json.dumps(create_lss_response)
+
+
 create_volumes_partial_failed_response = {
     "server": {
         "status": "ok",
@@ -148,24 +192,24 @@ def get_request_json_body(body):
             "status": "ok",
             "code": "",
             "message": "Operation done successfully."
+        },
+            "data": {
+                "volumes": [{"name": "lou_test1",
+                             "id": "0010"
+                             }
+                            ]
             },
-         "data": {
-            "volumes": [{"name": "lou_test1",
-                         "id": "0010"
-                         }
-                        ]
-            },
-         "link": {
-            "rel": "self",
-            "href": "https://localhost:8088/api/v1/volumes/0010"
+            "link": {
+                "rel": "self",
+                "href": "https://localhost:8088/api/v1/volumes/0010"
             }
-         },
+        },
         {"server": {
             "status": "failed",
             "code": "error_code",
             "message": "something wrong"
-            },
-         },
+        },
+        },
     ]
 }
 create_volumes_partial_failed_response_json = json.dumps(
@@ -186,7 +230,7 @@ def get_request_json_body(body):
                     "id": "0010"
                 }
             ]
-        },
+    },
     "link": {
         "rel": "self",
         "href": "https://localhost:8088/api/v1/volumes/0010"
@@ -201,26 +245,28 @@ def get_request_json_body(body):
         "message": "Operation done successfully."
     },
     "responses": [
-        {"server": {
-            "status": "ok",
-            "code": "",
-            "message": "Operation done successfully."
+        {
+            "server": {
+                "status": "ok",
+                "code": "",
+                "message": "Operation done successfully."
             },
-         "link": {
-            "rel": "self",
-            "href": "https://localhost:8088/api/v1/hosts/host1/mappings/00"
+            "link": {
+                "rel": "self",
+                "href": "https://localhost:8088/api/v1/hosts/host1/mappings/00"
             }
-         },
-        {"server": {
-            "status": "ok",
-            "code": "",
-            "message": "Operation done successfully."
+        },
+        {
+            "server": {
+                "status": "ok",
+                "code": "",
+                "message": "Operation done successfully."
             },
-         "link": {
-            "rel": "self",
-            "href": "https://localhost:8088/api/v1/hosts/host1/mappings/01"
+            "link": {
+                "rel": "self",
+                "href": "https://localhost:8088/api/v1/hosts/host1/mappings/01"
             }
-         },
+        },
     ]
 }
 create_mappings_response_json = json.dumps(create_mappings_response)
@@ -264,7 +310,6 @@ def get_request_json_body(body):
 }
 create_host_port_response_json = json.dumps(create_host_port_response)
 
-
 # Templates
 volume_template = {'name': 'vol1',
                    'type': 'fb',
@@ -282,22 +327,34 @@ def get_request_json_body(body):
                     'pool_id': 'P0',
                     }
 
-
 # fail response
 token_response_error = {
-  "server": {
-    "status": "failed",
-    "code": "NIServerException",
-    "message": "Operation done successfully."
-  }
+    "server": {
+        "status": "failed",
+        "code": "NIServerException",
+        "message": "Operation done successfully."
+    }
 }
 
-
 # request
 default_request = {
-                   'request': {
-                               'params': {
-                                          'param1': 'test',
-                                          }
-                               }
-                   }
+    'request': {
+        'params': {
+            'param1': 'test',
+        }
+    }
+}
+
+create_flashcopy_response = {
+    'server': {
+        'status': 'ok',
+        'code': '',
+        'message': 'Operation done successfully.'
+    },
+    'link': {
+        'rel': 'self',
+        'href': 'https:/9.151.159.203:8452/api/v1/cs/flashcopies/0000:0001'
+    }
+}
+
+create_flashcopy_response_json = json.dumps(create_flashcopy_response)
diff --git a/pyds8k/test/integration/__init__.py b/pyds8k/test/integration/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/test/integration/integration.py b/pyds8k/test/integration/integration.py
index 4829f90..6444c06 100755
--- a/pyds8k/test/integration/integration.py
+++ b/pyds8k/test/integration/integration.py
@@ -109,9 +109,9 @@ def test_marrays(self):
 
     def test_lss(self):
         lss_list = self.get_lss()
-        for l in lss_list:
-            lss = self.get_lss(l.id)
-            volumes = self._get_volumes_by(types.DS8K_LSS, lss)
+        for lss in lss_list:
+            _lss = self.get_lss(lss.id)
+            volumes = self._get_volumes_by(types.DS8K_LSS, _lss)
             if volumes:
                 self.get_volumes(volumes[0].id)
                 return
diff --git a/pyds8k/test/mock/flashcopies.py b/pyds8k/test/mock/flashcopies.py
new file mode 100644
index 0000000..11a3a9c
--- /dev/null
+++ b/pyds8k/test/mock/flashcopies.py
@@ -0,0 +1,119 @@
+##############################################################################
+# Copyright 2019 IBM Corp.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##############################################################################
+
+ALL = {
+    "server": {
+        "status": "ok",
+        "code": "CMUC00183I",
+        "message": "Operation done successfully."
+    },
+    "counts": {
+        "data_counts": 32,
+        "total_counts": 32
+    },
+    'data': {
+        'flashcopy': [
+            {
+                'id': '0000:0001',
+                'link': {
+                    'rel': 'self',
+                    'href': 'https://localhost:8088/api/v1/cs/flashcopies/'
+                            '0000:0001'
+                },
+                'source_volume': {
+                    'id': '0000',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/0000'
+                    }
+                },
+                'target_volume': {
+                    'id': '0001',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/0001'
+                    }
+                },
+                'out_of_sync_tracks': '0',
+                'state': 'valid'
+            },
+            {
+                'id': '1000:1001',
+                'link': {
+                    'rel': 'self',
+                    'href': 'https://localhost:8088/api/v1/cs/flashcopies/'
+                            '1000:1001'
+                },
+                'source_volume': {
+                    'id': '1000',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/1000'
+                    }
+                },
+                'target_volume': {
+                    'id': '1001',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/1001'
+                    }
+                },
+                'out_of_sync_tracks': '0',
+                'state': 'valid'
+            },
+        ]
+    }
+}
+
+ONE = {
+    "server": {
+        "status": "ok",
+        "code": "CMUC00183I",
+        "message": "Operation done successfully."
+    },
+    "counts": {
+        "data_counts": 1,
+        "total_counts": 1
+    },
+    'data': {
+        'flashcopy': [
+            {
+                'id': '0000:0001',
+                'link': {
+                    'rel': 'self',
+                    'href': 'https://localhost:8088/api/v1/cs/flashcopies/'
+                            '0000:0001'
+                },
+                'source_volume': {
+                    'id': '0000',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/0000'
+                    }
+                },
+                'target_volume': {
+                    'id': '0001',
+                    'link': {
+                        'rel': 'self',
+                        'href': 'https://localhost:8088/api/v1/volumes/0001'
+                    }
+                },
+                'out_of_sync_tracks': '0',
+                'state': 'valid'
+            },
+        ]
+    }
+}
diff --git a/pyds8k/test/test_client/test_ds8k/__init__.py b/pyds8k/test/test_client/test_ds8k/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/test/test_client/test_ds8k/test_client.py b/pyds8k/test/test_client/test_ds8k/test_client.py
index 738f3e4..66b03b3 100755
--- a/pyds8k/test/test_client/test_ds8k/test_client.py
+++ b/pyds8k/test/test_client/test_ds8k/test_client.py
@@ -16,9 +16,8 @@
 
 from pyds8k.resources.ds8k.v1.common.types import DS8K_SYSTEM, \
     DS8K_VOLUME
-from ...base import TestCaseWithConnect
-from pyds8k.resources.ds8k.v1.common.base import Base
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.base import TestCaseWithConnect
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type
 from pyds8k.client.ds8k.v1.client import Client
 from pyds8k.resources.ds8k.v1.volumes import Volume
@@ -33,8 +32,11 @@ class TestClient(TestCaseWithConnect):
 
     def setUp(self):
         super(TestClient, self).setUp()
-        self.base_url = Base.base_url
-        self.rest_client = Client('localhost', 'admin', 'admin', '8088')
+        self.rest_client = Client(
+            'http://localhost:8088/api/',
+            'admin',
+            'admin'
+        )
 
     @httpretty.activate
     def test_get_array_method(self):
diff --git a/pyds8k/test/test_client/test_ds8k/test_sc_client.py b/pyds8k/test/test_client/test_ds8k/test_sc_client.py
index 3556aff..47bfc1b 100644
--- a/pyds8k/test/test_client/test_ds8k/test_sc_client.py
+++ b/pyds8k/test/test_client/test_ds8k/test_sc_client.py
@@ -17,7 +17,6 @@
 from pyds8k.resources.ds8k.v1.common import types
 from pyds8k.test.base import TestCaseWithConnect
 from pyds8k.test.test_resources.test_ds8k.base import TestUtils
-from pyds8k.resources.ds8k.v1.common.base import Base
 from pyds8k.dataParser.ds8k import ResponseParser, RequestParser
 from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type, \
@@ -40,8 +39,7 @@ class TestClient(TestUtils, TestCaseWithConnect):
 
     def setUp(self):
         super(TestClient, self).setUp()
-        self.base_url = Base.base_url
-        self.rest_client = SCClient('localhost', 'admin', 'admin', '8088')
+        self.rest_client = SCClient('localhost:8088/api/', 'admin', 'admin')
 
     def _assert_equal_between_dicts(self,
                                     returned_dict,
@@ -216,6 +214,13 @@ def test_list_flashcopies(self):
                                           'list_flashcopies'
                                           )
 
+    def test_list_cs_flashcopies(self):
+        self._test_resource_list_by_route('{}.{}'.format(
+            types.DS8K_COPY_SERVICE_PREFIX,
+            types.DS8K_CS_FLASHCOPY),
+                                          'list_cs_flashcopies'
+                                          )
+
     def test_list_volume_flashcopies(self):
         self._test_sub_resource(types.DS8K_VOLUME,
                                 types.DS8K_FLASHCOPY,
diff --git a/pyds8k/test/test_dataParser/__init__.py b/pyds8k/test/test_dataParser/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/pyds8k/test/test_http_exceptions.py b/pyds8k/test/test_http_exceptions.py
index 775a7ae..52aad91 100755
--- a/pyds8k/test/test_http_exceptions.py
+++ b/pyds8k/test/test_http_exceptions.py
@@ -19,7 +19,6 @@
 from . import base
 from pyds8k import exceptions
 from .data import get_response_data_by_type
-from pyds8k.resources.ds8k.v1.common.base import Base
 
 default_a_response = get_response_data_by_type('default')
 response_401 = {
@@ -58,7 +57,6 @@ class TestHTTPException(base.TestCaseWithConnect):
 
     def setUp(self):
         super(TestHTTPException, self).setUp()
-        self.base_url = ''
 
     @httpretty.activate
     def test_response_status_400(self):
@@ -81,10 +79,9 @@ def test_response_status_400(self):
     def test_response_status_401(self):
         domain = self.client.domain
         url = '/default/a'
-        _base_url = Base.base_url
         httpretty.register_uri(
             httpretty.POST,
-            domain + _base_url + '/tokens',
+            domain + self.base_url + '/tokens',
             body=json.dumps(response_token),
             content_type='application/json',
             status=200
@@ -124,9 +121,8 @@ def test_response_status_401(self):
     def test_auth_fail(self):
         domain = self.client.domain
         url = '/default/a'
-        _base_url = Base.base_url
         httpretty.register_uri(httpretty.POST,
-                               domain + _base_url + '/tokens',
+                               domain + self.base_url + '/tokens',
                                body=json.dumps(response_token_error),
                                content_type='application/json',
                                status=401)
diff --git a/pyds8k/test/test_httpclient.py b/pyds8k/test/test_httpclient.py
index 8bfaa88..ee05cef 100755
--- a/pyds8k/test/test_httpclient.py
+++ b/pyds8k/test/test_httpclient.py
@@ -42,8 +42,8 @@ class TestHTTPClient(base.TestCaseWithConnect):
 
     def setUp(self):
         super(TestHTTPClient, self).setUp()
-        self.base_url = ''
 
+    # DSANSIBLE-62, removing test_parse_url
     def test_parse_url(self):
         url1 = self.domain + '/new'
         url2 = '/new'
diff --git a/pyds8k/test/test_resource.py b/pyds8k/test/test_resource.py
index ed31847..52296f2 100755
--- a/pyds8k/test/test_resource.py
+++ b/pyds8k/test/test_resource.py
@@ -43,7 +43,6 @@ class TestResource(base.TestCaseWithConnect):
 
     def setUp(self):
         super(TestResource, self).setUp()
-        self.base_url = ''
 
     def test_one_all(self):
         url1 = '/default/a/default/b/default'
@@ -81,9 +80,9 @@ def test_one_all(self):
         self.assertIsInstance(vol2.parent, Resource)
         self.assertIsInstance(vol3.parent, Resource)
 
-        self.assertEqual(vol1.url, self.base_url + url1)
-        self.assertEqual(vol2.url, self.base_url + url2)
-        self.assertEqual(vol3.url, self.base_url + url1)
+        self.assertEqual(vol1.url, url1)
+        self.assertEqual(vol2.url, url2)
+        self.assertEqual(vol3.url, url1)
 
     @httpretty.activate
     def test_toUrl(self):
@@ -107,11 +106,11 @@ def test_toUrl(self):
                                       'b'
                                       ).one(DEFAULT, 'c')
         _, body1 = vol.toUrl(method)
-        self.assertEqual(vol.url, self.base_url + url)
+        self.assertEqual(vol.url, url)
         self.assertEqual(body1, custom_method_get)
 
         _, body2 = vol.toUrl(method, body)
-        self.assertEqual(vol.url, self.base_url + url)
+        self.assertEqual(vol.url, url)
         self.assertEqual(body2, action_response['server'])
 
     @httpretty.activate
@@ -167,14 +166,15 @@ def test_create_from_template_and_save(self):
         self.assertIsInstance(vol1, Resource)
         self.assertIsInstance(vol1.manager, DefaultManager)
         self.assertEqual(vol1.name, default_template['name'])
-        self.assertEqual(vol1.url, self.base_url + url)
+        self.assertEqual(vol1.url, url)
         self.assertEqual(vol1.representation, default_template)
         resp1, data1 = vol1.save()
         self.assertIsInstance(data1[0], Resource)
         self.assertEqual(resp1.status_code, 201)
-        self.assertEqual(resp1.headers['Location'],
-                         self.base_url + url + '/vol1_id'
-                         )
+        self.assertEqual(
+            resp1.headers['Location'],
+            self.base_url + url + '/vol1_id'
+        )
         self.assertEqual(resp1.headers['Location'], vol1.url)
 
         vol2 = self.resource.one(
@@ -192,16 +192,17 @@ def test_create_from_template_and_save(self):
         self.assertIsInstance(vol2, Resource)
         self.assertIsInstance(vol2.manager, DefaultManager)
         self.assertEqual(vol2.name, 'vol2')
-        self.assertEqual(vol2.url, self.base_url + url)
+        self.assertEqual(vol2.url, url)
         rep = default_template.copy()
         rep.update({'name': 'vol2'})
         self.assertEqual(vol2.representation, rep)
         resp2, data2 = vol2.save()
         self.assertIsInstance(data2[0], Resource)
         self.assertEqual(resp2.status_code, 201)
-        self.assertEqual(resp2.headers['Location'],
-                         self.base_url + url + '/vol2_id'
-                         )
+        self.assertEqual(
+            resp2.headers['Location'],
+            self.base_url + url + '/vol2_id'
+        )
         self.assertEqual(resp2.headers['Location'], vol2.url)
 
         rep_with_id = default_template.copy()
@@ -218,15 +219,16 @@ def test_create_from_template_and_save(self):
         self.assertIsInstance(vol3.manager, DefaultManager)
         self.assertEqual(vol3.name, 'vol3')
         self.assertEqual(vol3.id, 'vol3_id')
-        self.assertEqual(vol3.url, self.base_url + url + '/vol3_id')
+        self.assertEqual(vol3.url, url + '/vol3_id')
         self.assertEqual(vol3.representation, rep_with_id)
         resp3, data3 = vol3.save()
         # default create method is put if id is specified.
         self.assertEqual(data3, action_response.get('server'))
         self.assertEqual(resp3.status_code, 201)
-        self.assertEqual(resp3.headers['Location'],
-                         self.base_url + url + '/vol3_id'
-                         )
+        self.assertEqual(
+            resp3.headers['Location'],
+            self.base_url + url + '/vol3_id'
+        )
 
     def test_create(self):
         pass
@@ -376,12 +378,12 @@ def test_list(self):
         httpretty.register_uri(httpretty.GET, domain + self.base_url + url,
                                body=default_list_response_json,
                                content_type='application/json')
-        httpretty.register_uri(httpretty.GET, domain + url1,
+        httpretty.register_uri(httpretty.GET, domain + self.base_url + url1,
                                body=default_a_response_json,
                                content_type='application/json')
 
         vol = self.resource.all(DEFAULT)
-        self.assertEqual(vol.url, self.base_url + url)
+        self.assertEqual(vol.url, url)
         self.assertRaises(AttributeError, getattr, vol, 'id')
         vol_list = vol.list()
         self.assertIsInstance(vol_list, list)
@@ -407,7 +409,7 @@ def test_get(self):
         domain = self.client.domain
         url = default_a_response['data']['default'][0]['link']['href']
         vol_id = default_a_response['data']['default'][0]['id']
-        httpretty.register_uri(httpretty.GET, domain + url,
+        httpretty.register_uri(httpretty.GET, domain + self.base_url + url,
                                body=default_a_response_json,
                                content_type='application/json')
 
@@ -449,10 +451,10 @@ def test_put(self):
         domain = self.client.domain
         url = default_a_response['data']['default'][0]['link']['href']
         vol_id = default_a_response['data']['default'][0]['id']
-        httpretty.register_uri(httpretty.GET, domain + url,
+        httpretty.register_uri(httpretty.GET, domain + self.base_url + url,
                                body=default_a_response_json,
                                content_type='application/json')
-        httpretty.register_uri(httpretty.PUT, domain + url,
+        httpretty.register_uri(httpretty.PUT, domain + self.base_url + url,
                                body=json.dumps({'status': 'updated'}),
                                content_type='application/json',
                                status=200)
@@ -471,10 +473,10 @@ def test_patch(self):
         domain = self.client.domain
         url = default_a_response['data']['default'][0]['link']['href']
         vol_id = default_a_response['data']['default'][0]['id']
-        httpretty.register_uri(httpretty.GET, domain + url,
+        httpretty.register_uri(httpretty.GET, domain + self.base_url + url,
                                body=default_a_response_json,
                                content_type='application/json')
-        httpretty.register_uri(httpretty.PATCH, domain + url,
+        httpretty.register_uri(httpretty.PATCH, domain + self.base_url + url,
                                body=json.dumps({'status': 'updated'}),
                                content_type='application/json',
                                status=200)
@@ -499,10 +501,10 @@ def test_delete(self):
         domain = self.client.domain
         url = default_a_response['data']['default'][0]['link']['href']
         vol_id = default_a_response['data']['default'][0]['id']
-        httpretty.register_uri(httpretty.GET, domain + url,
+        httpretty.register_uri(httpretty.GET, domain + self.base_url + url,
                                body=default_a_response_json,
                                content_type='application/json')
-        httpretty.register_uri(httpretty.DELETE, domain + url,
+        httpretty.register_uri(httpretty.DELETE, domain + self.base_url + url,
                                content_type='application/json',
                                status=204)
 
diff --git a/pyds8k/test/test_resources/test_ds8k/base.py b/pyds8k/test/test_resources/test_ds8k/base.py
index 64211b9..17fab6d 100755
--- a/pyds8k/test/test_resources/test_ds8k/base.py
+++ b/pyds8k/test/test_resources/test_ds8k/base.py
@@ -23,7 +23,6 @@
     get_response_json_by_type
 from pyds8k.test import base
 from pyds8k.base import Resource, get_resource_and_manager_class_by_route
-from pyds8k.resources.ds8k.v1.common.base import Base
 from pyds8k.resources.ds8k.v1.common import types
 from pyds8k.resources.ds8k.v1.systems import System, \
     SystemManager
@@ -225,5 +224,5 @@ class TestDS8KWithConnect(TestUtils, base.TestCaseWithConnect):
 
     def setUp(self):
         super(TestDS8KWithConnect, self).setUp()
-        self.base_url = Base.base_url
+        self.base_url = self.client.base_url
         self.system = System(self.client, SystemManager(self.client))
diff --git a/pyds8k/test/test_resources/test_ds8k/test_flashcopies.py b/pyds8k/test/test_resources/test_ds8k/test_flashcopies.py
new file mode 100644
index 0000000..e41295c
--- /dev/null
+++ b/pyds8k/test/test_resources/test_ds8k/test_flashcopies.py
@@ -0,0 +1,108 @@
+import json
+
+import httpretty
+
+from pyds8k.dataParser.ds8k import RequestParser
+from pyds8k.resources.ds8k.v1.common.types import DS8K_CS_FLASHCOPY, \
+    DS8K_COPY_SERVICE_PREFIX, DS8K_FLASHCOPY
+from pyds8k.resources.ds8k.v1.cs.flashcopies import FlashCopy as FlashCopies
+from pyds8k.resources.ds8k.v1.flashcopy import FlashCopy
+from pyds8k.test.data import get_response_json_by_type, \
+    get_response_data_by_type, action_response_json, \
+    create_flashcopy_response_json
+from pyds8k.test.test_resources.test_ds8k.base import TestDS8KWithConnect
+
+
+class TestFlashCopies(TestDS8KWithConnect):
+
+    def setUp(self):
+        super(TestFlashCopies, self).setUp()
+        self.maxDiff = None
+
+    @httpretty.activate
+    def test_create_cs_flashcopy(self):
+        url = '/cs/flashcopies'
+
+        source_volume = '0000'
+        target_volume = '0001'
+
+        def _verify_request(request, uri, headers):
+            self.assertEqual(uri, self.domain + self.base_url + url)
+
+            req = RequestParser(
+                {"volume_pairs": [{"source_volume": source_volume,
+                                   "target_volume": target_volume
+                                   }],
+                 "options": []
+                 })
+            self.assertDictContainsSubset(
+                req.get_request_data().get('request').get('params'),
+                json.loads(request.body).get('request').get('params'),
+            )
+            return (201, headers, create_flashcopy_response_json)
+
+        httpretty.register_uri(httpretty.POST,
+                               self.domain + self.base_url + url,
+                               body=_verify_request,
+                               content_type='application/json',
+                               )
+        # Way 1
+        resp1 = self.system.create_cs_flashcopy(
+            volume_pairs=[{'source_volume': source_volume,
+                           'target_volume': target_volume}])
+        self.assertEqual(httpretty.POST, httpretty.last_request().method)
+        self.assertIsInstance(resp1[0], FlashCopies)
+
+        # Way 2
+        flashcopies = self.system.all(
+            '{}.{}'.format(DS8K_COPY_SERVICE_PREFIX, DS8K_CS_FLASHCOPY),
+            rebuild_url=True)
+        new_fc2 = flashcopies.create(volume_pairs=[
+            {'source_volume': source_volume, 'target_volume': target_volume}])
+        resp2, data2 = new_fc2.posta()
+        self.assertEqual(httpretty.POST, httpretty.last_request().method)
+        self.assertIsInstance(data2[0], FlashCopies)
+        self.assertEqual(resp2.status_code, 201)
+
+        # Way 3
+        flashcopies = self.system.all(
+            '{}.{}'.format(DS8K_COPY_SERVICE_PREFIX, DS8K_CS_FLASHCOPY),
+            rebuild_url=True)
+        new_fc3 = flashcopies.create(volume_pairs=[
+            {'source_volume': source_volume, 'target_volume': target_volume}])
+        resp3, data3 = new_fc3.save()
+        self.assertEqual(httpretty.POST, httpretty.last_request().method)
+        self.assertIsInstance(data3[0], FlashCopies)
+        self.assertEqual(resp3.status_code, 201)
+
+    @httpretty.activate
+    def test_delete_cs_flashcopy(self):
+        response_a_json = get_response_json_by_type(DS8K_CS_FLASHCOPY)
+        response_a = get_response_data_by_type(DS8K_CS_FLASHCOPY)
+        name = self._get_resource_id_from_resopnse(DS8K_FLASHCOPY,
+                                                   response_a,
+                                                   FlashCopy.id_field
+                                                   )
+        url = '/cs/flashcopies/{}'.format(name)
+        httpretty.register_uri(httpretty.GET,
+                               self.domain + self.base_url + url,
+                               body=response_a_json,
+                               content_type='application/json',
+                               status=200,
+                               )
+        httpretty.register_uri(httpretty.DELETE,
+                               self.domain + self.base_url + url,
+                               body=action_response_json,
+                               content_type='application/json',
+                               status=204,
+                               )
+        # Way 1
+        _ = self.system.delete_cs_flashcopy(name)
+        self.assertEqual(httpretty.DELETE, httpretty.last_request().method)
+
+        # Way 2
+        flashcopy = self.system.get_cs_flashcopies(name)
+        self.assertIsInstance(flashcopy, FlashCopies)
+        resp2, _ = flashcopy.delete()
+        self.assertEqual(resp2.status_code, 204)
+        self.assertEqual(httpretty.DELETE, httpretty.last_request().method)
diff --git a/pyds8k/test/test_resources/test_ds8k/test_host.py b/pyds8k/test/test_resources/test_ds8k/test_host.py
index 2414d9e..993a398 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_host.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_host.py
@@ -25,11 +25,11 @@
     DS8K_VOLUME, \
     DS8K_IOPORT, \
     DS8K_HOST_PORT
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type, \
     get_response_json_by_type, \
     get_response_data_by_type
-from ...data import action_response, action_response_json, \
+from pyds8k.test.data import action_response, action_response_json, \
     action_response_failed, action_response_failed_json, \
     create_host_response_json
 from .base import TestDS8KWithConnect
diff --git a/pyds8k/test/test_resources/test_ds8k/test_host_port.py b/pyds8k/test/test_resources/test_ds8k/test_host_port.py
index 2d62c72..f8eaec4 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_host_port.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_host_port.py
@@ -25,8 +25,9 @@
 from pyds8k.resources.ds8k.v1.ioports import IOPort
 from pyds8k.resources.ds8k.v1.hosts import Host
 from .base import TestDS8KWithConnect
-from ...data import get_response_json_by_type, get_response_data_by_type
-from ...data import action_response, action_response_json, \
+from pyds8k.test.data import get_response_json_by_type, \
+    get_response_data_by_type
+from pyds8k.test.data import action_response, action_response_json, \
     action_response_failed, action_response_failed_json, \
     create_host_port_response_json
 from pyds8k.dataParser.ds8k import RequestParser
diff --git a/pyds8k/test/test_resources/test_ds8k/test_lss.py b/pyds8k/test/test_resources/test_ds8k/test_lss.py
index dcbbed3..5dfd3b5 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_lss.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_lss.py
@@ -13,17 +13,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 ##############################################################################
+import json
 
 import httpretty
 from functools import cmp_to_key
 from pyds8k.resources.ds8k.v1.common.types import DS8K_LSS, \
     DS8K_VOLUME
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type, \
-    get_response_json_by_type
+    get_response_json_by_type, \
+    create_lss_response
 from .base import TestDS8KWithConnect
 from pyds8k.resources.ds8k.v1.lss import LSS, LSSManager
 from pyds8k.resources.ds8k.v1.volumes import Volume
+from pyds8k.messages import INVALID_TYPE
+from pyds8k.resources.ds8k.v1.common import types
+from pyds8k.dataParser.ds8k import RequestParser
 
 
 class TestLSS(TestDS8KWithConnect):
@@ -125,3 +130,59 @@ def test_set_related_resources_collection_during_loading(self):
 
         self.assertEqual('0000', lss.representation.get('volumes')[0])
         self.assertEqual('0000', lss.volumes[0].id)
+
+    def test_invalid_lss_type(self):
+        with self.assertRaises(ValueError) as holder_exception:
+            LSS(self.client, lss_type="fake")
+        self.assertEqual(
+            INVALID_TYPE.format(', '.join(types.DS8K_LSS_TYPES)),
+            str(holder_exception.exception)
+        )
+
+    def test_invalid_ckd_based_cu_type(self):
+        with self.assertRaises(ValueError) as holder_exception:
+            LSS(self.client, lcu_type="fake")
+        self.assertEqual(
+            INVALID_TYPE.format(', '.join(types.DS8K_LCU_TYPES)),
+            str(holder_exception.exception)
+        )
+
+    @httpretty.activate
+    def test_create_lss_ckd(self):
+        url = '/lss'
+        full_url = self.domain + self.base_url + url
+        struct_request = {
+            'id': 'FE',
+            'type': 'ckd',
+            'sub_system_identifier': 'FE00',
+            'ckd_base_cu_type': types.DS8K_LCU_TYPE_3990_6,
+        }
+
+        def _verify_request(request, uri, headers):
+            self.assertEqual(
+                uri,
+                full_url
+            )
+
+            req = RequestParser(struct_request)
+            self.assertDictContainsSubset(
+                req.get_request_data().get('request').get('params'),
+                json.loads(request.body).get('request').get('params')
+            )
+            return 201, headers, json.dumps(create_lss_response)
+
+        httpretty.register_uri(
+            httpretty.POST,
+            full_url,
+            body=_verify_request,
+            content_type='application/json'
+        )
+
+        resp = self.system.create_lss_ckd(
+            lss_id=struct_request['id'],
+            lss_type=struct_request['type'],
+            lcu_type=struct_request['ckd_base_cu_type'],
+            ss_id=struct_request['sub_system_identifier']
+        )
+        self.assertEqual(httpretty.POST, httpretty.last_request().method)
+        self.assertIsInstance(resp[0], LSS)
diff --git a/pyds8k/test/test_resources/test_ds8k/test_mapping.py b/pyds8k/test/test_resources/test_ds8k/test_mapping.py
index f6a44c8..401b9e5 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_mapping.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_mapping.py
@@ -19,9 +19,9 @@
 from pyds8k.exceptions import InternalServerError
 from pyds8k.resources.ds8k.v1.common.types import DS8K_HOST, \
     DS8K_VOLMAP
-from ...data import get_response_json_by_type, \
+from pyds8k.test.data import get_response_json_by_type, \
     get_response_data_by_type
-from ...data import action_response_json, \
+from pyds8k.test.data import action_response_json, \
     create_mappings_response_json, create_mapping_response_json, \
     action_response_failed, action_response_failed_json
 from .base import TestDS8KWithConnect
diff --git a/pyds8k/test/test_resources/test_ds8k/test_pool.py b/pyds8k/test/test_resources/test_ds8k/test_pool.py
index fa63b61..e252104 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_pool.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_pool.py
@@ -22,11 +22,11 @@
     DS8K_VOLUME, \
     DS8K_TSEREP, \
     DS8K_ESEREP
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type, \
     get_response_json_by_type, \
     get_response_data_by_type
-from ...data import action_response, action_response_json
+from pyds8k.test.data import action_response, action_response_json
 from .base import TestDS8KWithConnect
 from pyds8k.resources.ds8k.v1.volumes import Volume
 from pyds8k.resources.ds8k.v1.pools import Pool
diff --git a/pyds8k/test/test_resources/test_ds8k/test_pprc.py b/pyds8k/test/test_resources/test_ds8k/test_pprc.py
index 26e5704..6d9a1e0 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_pprc.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_pprc.py
@@ -15,7 +15,7 @@
 ##############################################################################
 
 from pyds8k.resources.ds8k.v1.common.types import DS8K_PPRC
-from ...data import get_response_data_by_type
+from pyds8k.test.data import get_response_data_by_type
 from .base import TestDS8KWithConnect
 from pyds8k.resources.ds8k.v1.volumes import Volume
 from pyds8k.resources.ds8k.v1.pprc import PPRC
diff --git a/pyds8k/test/test_resources/test_ds8k/test_root_resource_mixin.py b/pyds8k/test/test_resources/test_ds8k/test_root_resource_mixin.py
index 7cb2d7f..3839fae 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_root_resource_mixin.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_root_resource_mixin.py
@@ -17,17 +17,18 @@
 import httpretty
 from nose.tools import nottest
 from pyds8k.resources.ds8k.v1.common import types
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type, \
     get_response_data_by_type, \
     get_response_json_by_type
-from ...data import action_response_json
+from pyds8k.test.data import action_response_json
 from .base import TestDS8KWithConnect
 from pyds8k.resources.ds8k.v1.systems import System
 from pyds8k.resources.ds8k.v1.lss import LSS
 # from pyds8k.resources.ds8k.v1.ioports import IOPort
 from pyds8k.resources.ds8k.v1.tserep import TSERep
 from pyds8k.resources.ds8k.v1.eserep import ESERep
+from pyds8k.resources.ds8k.v1.volumes import Volume
 
 system_list_response = get_response_list_data_by_type(types.DS8K_SYSTEM)
 system_list_response_json = get_response_list_json_by_type(types.DS8K_SYSTEM)
@@ -41,6 +42,8 @@
 ioport_a_response_json = get_response_json_by_type(types.DS8K_IOPORT)
 tserep_list_response_json = get_response_list_json_by_type(types.DS8K_TSEREP)
 eserep_list_response_json = get_response_list_json_by_type(types.DS8K_ESEREP)
+volume_list_response = get_response_list_data_by_type(types.DS8K_VOLUME)
+volume_list_response_json = get_response_list_json_by_type(types.DS8K_VOLUME)
 
 
 class TestRootResourceMixin(TestDS8KWithConnect):
@@ -232,8 +235,56 @@ def test_get_volumes(self):
     def test_get_volume(self):
         self._test_resource_by_route(types.DS8K_VOLUME)
 
+    @httpretty.activate
+    def test_get_volumes_by_host(self):
+        host_name = 'testhost'
+        url = '/hosts/{}/volumes'.format(host_name)
+        httpretty.register_uri(httpretty.GET,
+                               self.domain + self.base_url + url,
+                               body=volume_list_response_json,
+                               content_type='application/json',
+                               status=200,
+                               )
+        vol_list = self.system.get_volumes_by_host(host_name=host_name)
+        self.assertIsInstance(vol_list, list)
+        self.assertIsInstance(vol_list[0], Volume)
+        self.assertEqual(
+                         len(vol_list),
+                         len(volume_list_response['data']['volumes'])
+                         )
+
+    @httpretty.activate
     def test_get_volumes_by_lss(self):
-        pass
+        lss_id = '00'
+        url = '/lss/{}/volumes'.format(lss_id)
+        httpretty.register_uri(httpretty.GET,
+                               self.domain + self.base_url + url,
+                               body=volume_list_response_json,
+                               content_type='application/json',
+                               status=200,
+                               )
+        vol_list = self.system.get_volumes_by_lss(lss_id=lss_id)
+        self.assertIsInstance(vol_list, list)
+        self.assertIsInstance(vol_list[0], Volume)
+        self.assertEqual(
+                         len(vol_list),
+                         len(volume_list_response['data']['volumes'])
+                         )
 
+    @httpretty.activate
     def test_get_volumes_by_pool(self):
-        pass
+        pool_id = 'P0'
+        url = '/pools/{}/volumes'.format(pool_id)
+        httpretty.register_uri(httpretty.GET,
+                               self.domain + self.base_url + url,
+                               body=volume_list_response_json,
+                               content_type='application/json',
+                               status=200,
+                               )
+        vol_list = self.system.get_volumes_by_pool(pool_id=pool_id)
+        self.assertIsInstance(vol_list, list)
+        self.assertIsInstance(vol_list[0], Volume)
+        self.assertEqual(
+                         len(vol_list),
+                         len(volume_list_response['data']['volumes'])
+                         )
diff --git a/pyds8k/test/test_resources/test_ds8k/test_system.py b/pyds8k/test/test_resources/test_ds8k/test_system.py
index ca9db8b..f2d1a91 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_system.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_system.py
@@ -19,7 +19,7 @@
 from .base import TestDS8KWithConnect
 from pyds8k.resources.ds8k.v1.systems import System, \
     SystemManager
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type
 from pyds8k.exceptions import OperationNotAllowed
 
diff --git a/pyds8k/test/test_resources/test_ds8k/test_tserep.py b/pyds8k/test/test_resources/test_ds8k/test_tserep.py
index 7b2cdaa..3a579ad 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_tserep.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_tserep.py
@@ -20,9 +20,9 @@
 from pyds8k.resources.ds8k.v1.pools import Pool
 from pyds8k.resources.ds8k.v1.tserep import TSERep
 from .base import TestDS8KWithConnect
-from ...data import get_response_list_json_by_type, \
+from pyds8k.test.data import get_response_list_json_by_type, \
     get_response_list_data_by_type
-from ...data import action_response_json
+from pyds8k.test.data import action_response_json
 from pyds8k.dataParser.ds8k import RequestParser
 
 tserep_list_response_json = get_response_list_json_by_type(DS8K_TSEREP)
diff --git a/pyds8k/test/test_resources/test_ds8k/test_volume.py b/pyds8k/test/test_resources/test_ds8k/test_volume.py
index f6fa818..c4ee419 100755
--- a/pyds8k/test/test_resources/test_ds8k/test_volume.py
+++ b/pyds8k/test/test_resources/test_ds8k/test_volume.py
@@ -14,27 +14,30 @@
 # limitations under the License.
 ##############################################################################
 
-import httpretty
 import json
+
+import httpretty
 from nose.tools import nottest
+
+from pyds8k.dataParser.ds8k import RequestParser
+from pyds8k.exceptions import FieldReadOnly
 from pyds8k.messages import INVALID_TYPE
 from pyds8k.resources.ds8k.v1.common import types
-from pyds8k.dataParser.ds8k import RequestParser
-from .base import TestDS8KWithConnect
-from pyds8k.resources.ds8k.v1.volumes import Volume, \
-    VolumeManager
-from pyds8k.resources.ds8k.v1.pools import Pool
-from pyds8k.resources.ds8k.v1.hosts import Host
+from pyds8k.resources.ds8k.v1.common.types import DS8K_VOLUME
 from pyds8k.resources.ds8k.v1.flashcopy import FlashCopy
-from pyds8k.resources.ds8k.v1.pprc import PPRC
+from pyds8k.resources.ds8k.v1.hosts import Host
 from pyds8k.resources.ds8k.v1.lss import LSS
-from pyds8k.resources.ds8k.v1.common.types import DS8K_VOLUME
-from ...data import get_response_json_by_type, get_response_data_by_type
-from ...data import action_response_json, action_response, \
-    create_volumes_response_json, create_volume_response_json, \
+from pyds8k.resources.ds8k.v1.pools import Pool
+from pyds8k.resources.ds8k.v1.pprc import PPRC
+from pyds8k.resources.ds8k.v1.volumes import Volume, \
+    VolumeManager
+from pyds8k.test.data import get_response_json_by_type, \
+    get_response_data_by_type, action_response_json, \
+    action_response, create_volume_response_json, \
+    create_volumes_response_json, \
     create_volumes_partial_failed_response_json, \
     create_volumes_partial_failed_response
-from pyds8k.exceptions import FieldReadOnly
+from pyds8k.test.test_resources.test_ds8k.base import TestDS8KWithConnect
 
 
 class TestVolume(TestDS8KWithConnect):
@@ -121,9 +124,9 @@ def test_related_resources_collection(self):
             self.assertEqual(value,
                              getattr(flashcopies[k], flashcopies[k].id_field)
                              )
-        for l, value in enumerate(volume.representation[types.DS8K_PPRC]):
+        for vol, value in enumerate(volume.representation[types.DS8K_PPRC]):
             self.assertEqual(value,
-                             getattr(pprc[l], pprc[l].id_field)
+                             getattr(pprc[vol], pprc[vol].id_field)
                              )
 
     @httpretty.activate
@@ -306,9 +309,15 @@ def _verify_request(request, uri, headers):
                                content_type='application/json',
                                )
         # Way 1
-        resp1 = self.system.create_volume(name=name, cap=cap,
-                                          pool=pool, stgtype=stgtype,
-                                          captype=captype, lss=lss, tp=tp, )
+        resp1 = self.system.create_volume(
+            name=name,
+            cap=cap,
+            pool=pool,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
         self.assertEqual(httpretty.POST, httpretty.last_request().method)
         self.assertIsInstance(resp1[0], Volume)
 
@@ -356,7 +365,7 @@ def _verify_request1(request, uri, headers):
             resq = RequestParser({'name': name, 'cap': cap,
                                   'pool': pool, 'stgtype': stgtype,
                                   'captype': captype, 'lss': lss, 'tp': tp,
-                                  'quantity': quantity, 'namecol': '',
+                                  'quantity': quantity
                                   })
             self.assertEqual(json.loads(request.body), resq.get_request_data())
             return (201, headers, create_volumes_response_json)
@@ -386,25 +395,36 @@ def _verify_request2(request, uri, headers):
         )
 
         resp1 = self.system.create_volumes_with_same_prefix(
-            name=name,
-            cap=cap,
-            pool=pool, stgtype=stgtype,
-            captype=captype, lss=lss,
-            tp=tp, quantity=quantity,
+            name, cap, pool,
+            quantity=quantity,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
         )
         self.assertEqual(httpretty.POST, httpretty.last_request().method)
         self.assertIsInstance(resp1[0], Volume)
 
         resp2 = self.system.create_volumes_without_same_prefix(
-            name_col=namecol,
-            cap=cap,
-            pool=pool, stgtype=stgtype,
-            captype=captype, lss=lss,
-            tp=tp,
+            namecol, cap, pool,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
         )
         self.assertEqual(httpretty.POST, httpretty.last_request().method)
         self.assertIsInstance(resp2[0], Volume)
 
+        resp3 = self.system.create_volumes_with_names(
+            namecol, cap, pool,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
+        )
+        self.assertEqual(httpretty.POST, httpretty.last_request().method)
+        self.assertIsInstance(resp3[0], Volume)
+
     @httpretty.activate
     def test_create_volumes_partial_failed(self):
         url = '/volumes'
@@ -424,7 +444,7 @@ def _verify_request1(request, uri, headers):
             resq = RequestParser({'name': name, 'cap': cap,
                                   'pool': pool, 'stgtype': stgtype,
                                   'captype': captype, 'lss': lss, 'tp': tp,
-                                  'quantity': quantity, 'namecol': '',
+                                  'quantity': quantity
                                   })
             self.assertEqual(json.loads(request.body), resq.get_request_data())
             return (201, headers, create_volumes_partial_failed_response_json)
@@ -440,11 +460,12 @@ def _verify_request1(request, uri, headers):
         )
 
         resp1 = self.system.create_volumes_with_same_prefix(
-            name=name,
-            cap=cap,
-            pool=pool, stgtype=stgtype,
-            captype=captype, lss=lss,
-            tp=tp, quantity=quantity,
+            name, cap, pool,
+            quantity=quantity,
+            stgtype=stgtype,
+            captype=captype,
+            lss=lss,
+            tp=tp
         )
         self.assertEqual(httpretty.POST, httpretty.last_request().method)
         # return 1 created volume and 1 error status
@@ -452,20 +473,23 @@ def _verify_request1(request, uri, headers):
         self.assertIsInstance(resp1[1], dict)
         self.assertEqual(
             resp1[1],
-            create_volumes_partial_failed_response.get('responses'
-                                                       )[1].get('server')
+            create_volumes_partial_failed_response.get('responses')[1].get(
+                'server'
+            )
         )
 
     def test_create_volume_type_error(self):
         with self.assertRaises(ValueError):
-            self.system.create_volume('name', '10', 'testpool_0',
-                                      'fake_stgtype'
-                                      )
+            self.system.create_volume(
+                'name', '10', 'testpool_0', 'fake_stgtype'
+            )
         with self.assertRaises(ValueError):
-            self.system.create_volume('name', '10', 'testpool_0',
-                                      types.DS8K_VOLUME_TYPE_FB,
-                                      captype='fake_captype')
+            self.system.create_volume(
+                'name', '10', 'testpool_0', types.DS8K_VOLUME_TYPE_FB,
+                captype='fake_captype'
+            )
         with self.assertRaises(ValueError):
-            self.system.create_volume('name', '10', 'testpool_0',
-                                      types.DS8K_VOLUME_TYPE_FB,
-                                      tp='fake_tp')
+            self.system.create_volume(
+                'name', '10', 'testpool_0', types.DS8K_VOLUME_TYPE_FB,
+                tp='fake_tp'
+            )
diff --git a/test-requirements.txt b/test-requirements.txt
index f2886a8..0b29713 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,4 +1,4 @@
-nose==1.3.7
-mock==3.0.5
-flake8==3.6.0
-sphinx==2.2.1
\ No newline at end of file
+nose>=1.3.7
+mock>=3.0.5
+flake8>=3.6.0
+sphinx>=2.2.1
\ No newline at end of file