Add functional testing documentation
This patch adds documentation explaining how to run the functional tests before submitting a patch as well as how to test a specific Cinder driver backend with cinderlib.
This commit is contained in:
parent
fcf23faf85
commit
dc43affa4a
|
@ -65,3 +65,6 @@ target/
|
|||
|
||||
# pyenv python configuration file
|
||||
.python-version
|
||||
|
||||
# Temp directory, for example for the LVM file, our custom config, etc.
|
||||
temp/
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
.. highlight:: shell
|
||||
|
||||
============
|
||||
Contributing
|
||||
============
|
||||
|
@ -70,38 +68,77 @@ Get Started!
|
|||
Ready to contribute? Here's how to set up `cinderlib` for local development.
|
||||
|
||||
1. Fork the `cinderlib` repo on GitHub.
|
||||
2. Clone your fork locally::
|
||||
2. Clone your fork locally:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ git clone git@github.com:YOUR_NAME_HERE/cinderlib.git
|
||||
|
||||
3. Install tox::
|
||||
3. Install tox:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo dnf install python2-tox
|
||||
|
||||
4. Generate a virtual environment, for example for Python 2.7::
|
||||
4. Generate a virtual environment, for example for Python 2.7:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ tox --notest -epy27
|
||||
|
||||
5. Create a branch for local development::
|
||||
5. Create a branch for local development:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ git checkout -b name-of-your-bugfix-or-feature
|
||||
|
||||
Now you can make your changes locally.
|
||||
|
||||
6. When you're done making changes, you can check that your changes pass flake8
|
||||
and the tests with::
|
||||
and unit tests with:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ tox -eflake8
|
||||
$ tox -epy27
|
||||
|
||||
Or if you don't want to create a specific environment for flake8 you can run
|
||||
things directly without tox::
|
||||
things directly without tox:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ source .tox/py27/bin/activate
|
||||
$ flake8 cinderlib tests
|
||||
$ python setup.py test
|
||||
|
||||
7. Commit your changes making sure the commit message is descriptive enough,
|
||||
7. Run functional tests at least with the default LVM configuration:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ tox -efunctional
|
||||
|
||||
To run the LVM functional tests you'll need to have the expected LVM VG
|
||||
ready. This can be done using the script we have for this purpose (assuming
|
||||
we are in the *cinderlib* base directory):
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ mkdir temp
|
||||
$ cd temp
|
||||
$ sudo ../tests/functional/lvm-prepare.sh
|
||||
|
||||
The default configuration for the functional tests can be found in the
|
||||
`tests/functional/lvm.yaml` file. For additional information on this file
|
||||
format and running functional tests please refer to the
|
||||
:doc:`validating_backends` section.
|
||||
|
||||
And preferably with all the backends you have at your disposal:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ CL_FTESTS_CFG=temp/my-test-config.yaml tox -efunctional
|
||||
|
||||
8. Commit your changes making sure the commit message is descriptive enough,
|
||||
covering the patch changes as well as why the patch might be necessary. The
|
||||
commit message should also conform to the `50/72 rule
|
||||
<https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html>`_.
|
||||
|
@ -110,33 +147,48 @@ Ready to contribute? Here's how to set up `cinderlib` for local development.
|
|||
$ git commit
|
||||
|
||||
|
||||
8. Push your branch to GitHub::
|
||||
9. Push your branch to GitHub:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ git push origin name-of-your-bugfix-or-feature
|
||||
|
||||
9. Submit a pull request through the GitHub website.
|
||||
10. Submit a pull request through the GitHub website.
|
||||
|
||||
LVM Backend
|
||||
-----------
|
||||
|
||||
You may not have a fancy storage array, but that doesn't mean that you cannot
|
||||
use *cinderlib*, because you can just use NFS or LVM. Here we are going to see
|
||||
how to setup an LVM backend that we can use with *cinderlib*.
|
||||
use *cinderlib*, because you can always the LVM driver. Here we are going to
|
||||
see how to setup an LVM backend that we can use with *cinderlib*.
|
||||
|
||||
First you create your LVM, which is a 22GB file that is currently only using
|
||||
1MB, and then you mount it as a loopback device and create a PV and VG on the
|
||||
loopback device.
|
||||
Before doing anything you need to make sure you have the required package, for Fedora, CentOS, and RHEL this will be the `targetcli` package, and for Ubuntu the `lio-utils` package.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ dd if=/dev/zero of=cinder-volumes bs=1048576 seek=22527 count=1
|
||||
$ sudo lodevice=`losetup -f`
|
||||
$ sudo losetup $lodevice ./cinder-volumes
|
||||
$ sudo yum install targetcli
|
||||
|
||||
Then we'll need to create your "storage backend", which is actually just a file
|
||||
on your normal filesystem. We'll create a 22GB file with only 1MB currently
|
||||
allocated (this is worse for performance, but better for space), and then we'll
|
||||
mount it as a loopback device and create a PV and VG on the loopback device.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ dd if=/dev/zero of=temp/cinder-volumes bs=1048576 seek=22527 count=1
|
||||
$ sudo lodevice=`losetup --show -f ./cinder-volumes`
|
||||
$ sudo pvcreate $lodevice
|
||||
$ sudo vgcreate cinder-volumes $lodevice
|
||||
$ sudo vgscan --cache
|
||||
|
||||
Now you can use this LVM backend in *cinderlib*:
|
||||
There is a script included in the repository that will do all this for us, so
|
||||
we can just call it from the location where we want to create the file:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo tests/functional/lvm-prepare.sh
|
||||
|
||||
Now we can use this LVM backend in *cinderlib*:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -172,7 +224,9 @@ Before you submit a pull request, check that it meets these guidelines:
|
|||
Tips
|
||||
----
|
||||
|
||||
To run a subset of tests::
|
||||
To run a subset of tests:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ source .tox/py27/bin/activate
|
||||
$ python -m unittest tests.test_cinderlib.TestCinderlib.test_lib_setup
|
||||
|
|
20
README.rst
20
README.rst
|
@ -81,16 +81,18 @@ Example
|
|||
The following example uses CentOS 7 and the Cinder LVM driver, which should be
|
||||
the easiest to setup and test.
|
||||
|
||||
First you need to setup your system::
|
||||
First you need to setup your system:
|
||||
|
||||
# yum install -y centos-release-openstack-pike
|
||||
# yum install -y openstack-cinder targetcli python-pip
|
||||
# pip install cinderlib
|
||||
# dd if=/dev/zero of=cinder-volumes bs=1048576 seek=22527 count=1
|
||||
# lodevice=`losetup --show -f ./cinder-volumes`
|
||||
# pvcreate $lodevice
|
||||
# vgcreate cinder-volumes $lodevice
|
||||
# vgscan --cache
|
||||
.. code-block:: shell
|
||||
|
||||
$ sudo yum install -y centos-release-openstack-pike
|
||||
$ sudo yum install -y openstack-cinder targetcli python-pip
|
||||
$ sudo pip install cinderlib
|
||||
$ sudo dd if=/dev/zero of=cinder-volumes bs=1048576 seek=22527 count=1
|
||||
$ sudo lodevice=`losetup --show -f ./cinder-volumes`
|
||||
$ sudo pvcreate $lodevice
|
||||
$ sudo vgcreate cinder-volumes $lodevice
|
||||
$ sudo vgscan --cache
|
||||
|
||||
Then you need to run `python` with a passwordless sudo user (required to
|
||||
control LVM and do the attach) and execute:
|
||||
|
|
2
TODO.rst
2
TODO.rst
|
@ -10,7 +10,7 @@ list to keep track of the most relevant topics.
|
|||
- QoS
|
||||
- Support custom features via extra specs
|
||||
- Unit tests
|
||||
- Integration tests
|
||||
- Complete functional tests
|
||||
- Parameter validation
|
||||
- Support using *cinderlib* without cinder to just handle the attach/detach
|
||||
- Add .py examples
|
||||
|
|
|
@ -26,6 +26,7 @@ able to manage your storage.
|
|||
installation
|
||||
usage
|
||||
contributing
|
||||
validating_backends
|
||||
internals
|
||||
authors
|
||||
todo
|
||||
|
|
|
@ -27,7 +27,8 @@ a proof of concept and not a finished product at this moment, so please
|
|||
carefully go over the limitations section to avoid surprises.
|
||||
|
||||
Due to the limited access to Cinder backends and time constraints the list of
|
||||
drivers that have been manually tested are:
|
||||
drivers that have been manually tested, and using the existing limited
|
||||
functional tests, are:
|
||||
|
||||
- LVM
|
||||
- XtremIO
|
||||
|
@ -79,7 +80,8 @@ more noticeable limitations one should be aware of are:
|
|||
to be handled by the caller.
|
||||
|
||||
- There is no CI, or unit tests for that matter, and certainly nothing so fancy
|
||||
as third party vendor CIs, so things could be broken at any point.
|
||||
as third party vendor CIs, so things could be broken at any point. We only
|
||||
have some automated, yet limited, functional tests.
|
||||
|
||||
- Only a subset of Cinder available operations are supported by the library.
|
||||
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
===================
|
||||
Validating a driver
|
||||
===================
|
||||
|
||||
OK, so you have seen the project and would like to check if the Cinder driver
|
||||
for your storage backend will work with *cinderlib* or not, but don't want to
|
||||
spend a lot of time to do it.
|
||||
|
||||
In that case the best way to do it is using our functional tests with a custom
|
||||
configuration file that has your driver configuration.
|
||||
|
||||
The environment
|
||||
---------------
|
||||
|
||||
Before we can test anything we'll need to get our environment ready, which will
|
||||
be comprised of three steps:
|
||||
|
||||
- Clone the *cinderlib* project:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ git clone git://github.com/akrog/cinderlib
|
||||
|
||||
- Create the testing environment which will include the required Cinder code:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ cd cinderlib
|
||||
$ tox -efunctional --notest
|
||||
|
||||
- Install any specific packages our driver requires. Some Cinder drivers have
|
||||
external dependencies that need to be manually installed. These dependencies
|
||||
can be Python package or Linux binaries. If it's the former we will need to
|
||||
install them in the testing virtual environment we created in the previous
|
||||
step.
|
||||
|
||||
For example, for the Kaminario backend we need the *krest* Python package, so
|
||||
here's how we would install the dependency.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ source .tox/py27/bin/active
|
||||
(py27) $ pip install krest
|
||||
(py27) $ deactivate
|
||||
|
||||
To see the Python dependencies for each backend we can check the
|
||||
`driver-requirements.txt
|
||||
<https://raw.githubusercontent.com/openstack/cinder/stable/pike/driver-requirements.txt>`_
|
||||
file from the Cinder project, or in *cinderlib*'s `setup.py` file listed in
|
||||
the `extras` dictionary.
|
||||
|
||||
If we have binary dependencies we can copy them in `.tox/py27/bin` or just
|
||||
install them globally in our system.
|
||||
|
||||
The configuration
|
||||
-----------------
|
||||
|
||||
Functional test use a YAML configuration file to get the driver configuration
|
||||
as well as some additional parameters for running the tests, with the default
|
||||
configuration living in the `tests/functiona/lvm.yaml` file.
|
||||
|
||||
The configuration file currently supports 3 key-value pairs, with only one
|
||||
being mandatory.
|
||||
|
||||
- `logs`: Boolean value defining whether we want the Cinder code to log to
|
||||
stdout during the testing. Defaults to `false`.
|
||||
|
||||
- `venv_sudo`: Boolean value that instructs the functional tests on whether we
|
||||
want to run with normal `sudo` or with a custom command that ensure that the
|
||||
virtual environment's binaries are also available. This is not usually
|
||||
necessary, but there are some drivers that use binaries installed by a Python
|
||||
package (like the LVM that requires the `cinder-rtstool` from Cinder). This
|
||||
is also necessary if we've installed a binary in the `.tox/py27/bin`
|
||||
directory.
|
||||
|
||||
- `backends`: This is a list of dictionaries each with the configuration
|
||||
parameters that are configured in the `cinder.conf` file in Cinder.
|
||||
|
||||
The contents of the default configuration, excluding the comments, are:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
logs: false
|
||||
venv_sudo: true
|
||||
backends:
|
||||
- volume_backend_name: lvm
|
||||
volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver
|
||||
volume_group: cinder-volumes
|
||||
iscsi_protocol: iscsi
|
||||
iscsi_helper: lioadm
|
||||
|
||||
But like the name implies, `backends` can have multiple drivers configured, and
|
||||
the functional tests will run the tests on them all.
|
||||
|
||||
For example a configuration file with LVM, Kaminario, and XtremIO backends
|
||||
would look like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
logs: false
|
||||
venv_sudo: true
|
||||
backends:
|
||||
- volume_driver: cinder.volume.drivers.lvm.LVMVolumeDriver
|
||||
volume_group: cinder-volumes
|
||||
iscsi_protocol: iscsi
|
||||
iscsi_helper: lioadm
|
||||
volume_backend_name: lvm
|
||||
|
||||
- volume_backend_name: xtremio
|
||||
volume_driver: cinder.volume.drivers.dell_emc.xtremio.XtremIOISCSIDriver
|
||||
use_multipath_for_image_xfer: true
|
||||
xtremio_cluster_name: CLUSTER
|
||||
san_ip: x.x.x.x
|
||||
san_login: user
|
||||
san_password: password
|
||||
|
||||
- volume_backend_name: kaminario
|
||||
volume_driver: cinder.volume.drivers.kaminario.kaminario_iscsi.KaminarioISCSIDriver
|
||||
use_multipath_for_image_xfer: true
|
||||
san_ip: x.x.x.y
|
||||
san_login: user
|
||||
san_password: password
|
||||
|
||||
The validation
|
||||
--------------
|
||||
|
||||
Now it's time to run the commands, for this we'll use the `tox` command passing
|
||||
the location of our configuration file via environmental variable
|
||||
`CL_FTESTS_CFG`:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
$ CL_FTEST_CFG=temp/tests.yaml tox -efunctional
|
||||
|
||||
test_attach_detach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_detach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_detach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_snapshot_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_snapshot_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_create_delete_snapshot_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_detach_volume_via_attachment_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_detach_volume_via_attachment_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_attach_detach_volume_via_attachment_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_disk_io_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_disk_io_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_disk_io_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_volume_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_volume_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_volume_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_volumes_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_volumes_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_volumes_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_times_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_times_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_connect_disconnect_multiple_times_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_with_cretion_on_kaminario (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_with_cretion_on_lvm (tests_basic.BackendFunctBasic) ... ok
|
||||
test_stats_with_cretion_on_xtremio (tests_basic.BackendFunctBasic) ... ok
|
||||
|
||||
As can be seen each test will have a meaningful name ending in the name of the
|
||||
backend we have provided via the `volume_backend_name` key in the YAML file.
|
Loading…
Reference in New Issue