Skip to content

Commit

Permalink
simplify usmqe config
Browse files Browse the repository at this point in the history
  • Loading branch information
mbukatov committed Nov 30, 2016
1 parent eaa2a37 commit 11dbddf
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 95 deletions.
20 changes: 11 additions & 9 deletions conf/example_usm.ini
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# this is example of usm qe configuration file
[usm]
log_level = DEBUG
username = <username>
password = <password>
web_url = https://example-usm3-server.usmqe.tendrl.org
api_url = %(web_url):9393/api/1.0/
ca_cert = conf/tendrl_ca.crt
# This is example of USM QE configuration file.

[webstr]
# All options in `usmqepytest` section will be loaded during pytest start
# so that it will be available as if it were specified directly in pytest.ini
# (see plugin/usmqe_config.py for details).
[usmqepytest]
usm_log_level = DEBUG
usm_username = <username>
usm_password = <password>
usm_web_url = https://example-usm3-server.usmqe.tendrl.org
usm_api_url = %(usm_web_url):9393/api/1.0/
usm_ca_cert = conf/tendrl_ca.crt
94 changes: 70 additions & 24 deletions docs/test_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,54 @@
Test Configuraion
===================

USM QE integration tests are configurable via these files:

* Main *pytest config file*: ``pytest.ini`` in root directory of ``usmqe-tests``
repository. This file contains main pytest configuration and default values
for main USMQE configuration options. Under normal circumstances one would
edit only ``USM_CONFIG`` and ``USM_HOST_CONFIG`` options, while all the
others usmqe default values should not be changed there.
Configuration of *USM QE integration tests* project piggibacks/reuses pytest
ini-options parser, so that all USM QE configuration options could be specified
in ``pytest.ini`` file. To prevent a conflict with pytest ini-option names, we
use ``usm_`` prefix in a name of every option.

Configuration Scheme
====================

Since there are `multiple ways to configure pytest`_, we defined the following
scheme:

* Main *pytest config file* `pytest.ini`_ is commited in the root directory
of ``usmqe-tests`` repository. This file contains pytest configuration
and *default values* for most important USM QE configuration options. Under
normal circumstances (configuring ``usmqe-tests`` before test run) one would
not need to change this file at all, because any default value specified here
can be reconfigured in USM QE config file (with the exception of
``usm_config`` and ``usm_host_config`` options).

* *USM QE config file* is expected to contain actual configuration. See an
example in `conf/example_usm.ini`_, while the actual path of this file is
configured in ``usm_config`` option in main ``pytest.ini`` file. Any option
specified there overrieds the default from main ``pytest.ini``. This is the
file one is supposed to create and change as needed. You need to provide
all important config values in this file to be able to run the tests.

* Ansible *host inventory file* (see an example in ``conf/example.hosts``),
which is used both by ansible and by USMQE inventory module to organize
machines into groups by it's role in test cluster.
which is used both by ansible and by USM QE inventory module to organize
machines into groups by it's role in test cluster. Actuall path of this file
is configured in ``usm_host_config`` option in main ``pytest.ini`` file.

* Moreover ad hoc reconfiguration of any USM QE option is possible via pytest
command line option. See an example how to use different *host inventory
file* for a particular test run:

.. code-block:: console
* *usmqe config file* (see an example in ``conf/example_usm.ini``). You need
to provide mandatory values in this file to be able to run the tests.
Options configured there includes urls of web and api server, username and
password and so on.
$ py.test -o usm_host_config=conf/mbukatov01.hosts usmqe_tests/foo/bar
This is usefull for test runs started by hand during test development or
debugging.

Implementation Details
======================

Reading of both *usmqe config file* and *host inventory file* is implemented in
``plugin/usmqe_config.py`` module.
Details for Test Development
============================

Management of *host inventory file* is handled by ``usmqe/inventory.py``
module. See an example of it's usage:
To access data from the host inventory, use functions provided by
``usmqe.inventory`` module:

.. code-block:: python
Expand All @@ -36,8 +58,27 @@ module. See an example of it's usage:
for host in inventory.role2hosts("ceph_osd"):
print("check storage server {0}".format(host))
To access USM QE configuration, use standard pytest configuration functions:

.. code-block:: python
import pytest
Example of test configuration
pytest.config.getini("usm_username")
Obviously this assumes that the ``usm_username`` option has been specified in
USM QE config file (which is referenced via ``usm_config`` option). The minimal
ini file for the previous example to work would look like this::

[usmqepytest]
usm_username = admin

Reading of both *USM QE config file* and *host inventory file* is implemented
in ``plugin/usmqe_config.py`` module, while management of *host inventory file*
is handled by ``usmqe/inventory.py`` module.


Configuration before test run
=============================

We assume that:
Expand All @@ -54,12 +95,12 @@ We assume that:
Now, you need to:

* Check that ``usmqe`` user has a private ssh key in ``~/.ssh/id_rsa`` file
(this is default location of ssh key specified in ``USM_KEYFILE`` option of
(this is default location of ssh key specified in ``usm_keyfile`` option of
``pytest.ini``) and has it's public ssh key deployed on all machines of test
cluster.

* Store *host inventory file* in ``conf/clustername.hosts`` and specify this
path in ``USM_HOST_CONFIG`` option of ``pytest.ini``.
path in ``usm_host_config`` option of ``pytest.ini``.

* Verify that ssh and ansible are configured so that one can reach all machines
from test cluster:
Expand All @@ -68,12 +109,17 @@ Now, you need to:
[usmqe@qeserver ~]$ ansible -i conf/clustername.hosts -m ping -u root all
* Initiate new *usmqe config file*: ``cp conf/example_usm.ini conf/usm.ini``
and check that ``USM_CONFIG`` option of ``pytest.ini`` file points to this
* Initiate new *USM QE config file*: ``cp conf/example_usm.ini conf/usm.ini``
and check that ``usm_config`` option of ``pytest.ini`` file points to this
file.

* Provide all mandatory options in *usm config file* initialized in a previous
step. This includes: ``username``, ``password``, ``web_url`` and ``api_url``.
The actual list depends on the test suite you are going to run (eg. api
tests doesn't care about ``web_url`` while LDAP integration tests would need
to know address of the LDAP server).


.. _`multiple ways to configure pytest`: http://doc.pytest.org/en/latest/customize.html
.. _`pytest.ini`: https://github.com/Tendrl/usmqe-tests/blob/master/pytest.ini
.. _`conf/example_usm.ini`: https://github.com/Tendrl/usmqe-tests/blob/master/conf/example_usm.ini
43 changes: 18 additions & 25 deletions plugin/usmqe_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ def pytest_addoption(parser):
Add ini options to be accepted by pytest.
"""
# defaults are specified in root pytest.ini file
parser.addini('USM_CONFIG', 'USM configuration')
parser.addini('USM_HOST_CONFIG', 'USM host configuration')
parser.addini('usm_config', 'USM configuration')
parser.addini('usm_host_config', 'USM host configuration')


@pytest.fixture(autouse=True, scope="session")
Expand All @@ -29,13 +29,13 @@ def load_inventory():
To use content from inventory file just *import inventory* and then use
proper function from ``usmqe.inventory``.
Name of inventory file is stored in ``USM_HOST_CONFIG`` option in
Name of inventory file is stored in ``usm_host_config`` option in
``pytest.ini``. Its value can be overriden by ``pytest -o
USM_HOST_CONFIG=path``.
usm_host_config=path``.
"""
# update machine config (reading ansible inventory)
hosts = ConfigParser(allow_no_value=True)
hosts.read(pytest.config.getini("USM_HOST_CONFIG"))
hosts.read(pytest.config.getini("usm_host_config"))
for rolename in hosts.sections():
for hostname, _ in hosts.items(rolename):
usmqe.inventory.add_host_entry(rolename, hostname)
Expand All @@ -46,29 +46,22 @@ def load_config():
"""
Loads configuration from pytest.ini file.
If there is configured external configuration file(USM_CONFIG)
If there is configured external configuration file(usm_config)
then ini values are updated by values from configuration file.
All configuration entries can be overriden by::
$ py.test -o USM_USERNAME=admin2
$ py.test -o usm_username=admin2
"""
if pytest.config.getini("USM_CONFIG"):
if pytest.config.getini("usm_config"):
conf = ConfigParser()
conf.read(pytest.config.getini("USM_CONFIG"))

for section in ('webstr', 'usm', 'ldap'):
if section in conf.sections():
for key, value in conf.items(section):
if section == 'usm':
name = "USM_{0}".format(key.upper())
else:
name = "USM_{0}_{1}".format(
section.upper(), key.upper())

override_value = pytest.config._get_override_ini_value(
name)
if override_value is None:
pytest.config._inicache[name] = value
else:
pytest.config._inicache[name] = override_value
conf.read(pytest.config.getini("usm_config"))
if "usmqepytest" not in conf.sections():
# TODO: report a problem
return
for key, value in conf.items("usmqepytest"):
override_value = pytest.config._get_override_ini_value(key)
if override_value is None:
pytest.config._inicache[key] = value
else:
pytest.config._inicache[key] = override_value
46 changes: 23 additions & 23 deletions pytest.ini
Original file line number Diff line number Diff line change
Expand Up @@ -6,40 +6,40 @@

# Path to the main usmqe config file (that is the file one should edit to
# change configuration of usm qe tests).
USM_CONFIG = conf/usm.ini
usm_config = conf/usm.ini

# Path to the host inventory file (list of all machines of a test cluster
# grouped into roles). This file is used both by ansible and usm qe tests.
USM_HOST_CONFIG = conf/usm.hosts
usm_host_config = conf/usm.hosts

# Predefined usmqe configuration values.
# You should not change them here, but edit ini file referenced in USM_CONFIG
# You should not change them here, but edit ini file referenced in usm_config
#
# For add hoc changes, one can redefine the values from the command line:
#
# $ py.test -o USM_USERNAME=admin2
# $ py.test -o usm_username=admin2

# usm config group
USM_LOG_LEVEL = logging.DEBUG
USM_USERNAME = admin
USM_PASSWORD =
USM_WEB_URL =
USM_API_URL =
USM_CA_CERT = False
USM_KEYFILE = "~/.ssh/id_rsa"
usm_log_level = logging.DEBUG
usm_username = admin
usm_password =
usm_web_url =
usm_api_url =
usm_ca_cert = False
usm_keyfile = "~/.ssh/id_rsa"

# webstr config group: webstr specific options
USM_WEBSTR_SELENIUM_SERVER =
usm_webstr_selenium_server =

# ldap config group: LDAP specific options
USM_LDAP_SERVER = None
USM_LDAP_PORT = 389
USM_LDAP_BASE = None
USM_LDAP_DOMAINADMIN = None
USM_LDAP_PASSWORD = None
USM_LDAP_UID = "cn"
USM_LDAP_FIRSTNAME = "displayName"
USM_LDAP_LASTNAME = "sn"
USM_LDAP_DISPLAYNAME = None
USM_LDAP_EMAIL = "mail"
USM_LDAP_USER_FILE = None
usm_ldap_server = None
usm_ldap_port = 389
usm_ldap_base = None
usm_ldap_domainadmin = None
usm_ldap_password = None
usm_ldap_uid = "cn"
usm_ldap_firstname = "displayName"
usm_ldap_lastname = "sn"
usm_ldap_displayname = None
usm_ldap_email = "mail"
usm_ldap_user_file = None
6 changes: 3 additions & 3 deletions usmqe/api/skyringapi/skyringapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class Api(object):

def __init__(self, copy_from=None):
self.cookies = {}
self.verify = pytest.config.getini("USM_CA_CERT")
self.verify = pytest.config.getini("usm_ca_cert")
if copy_from:
self.cookies = copy_from.cookies
self.verify = copy_from.verify
Expand Down Expand Up @@ -141,7 +141,7 @@ def login(self, username, password, asserts_in=None):
if asserts_in:
asserts.update(asserts_in)
data = json.dumps({'username': username, 'password': password})
req = requests.post(pytest.config.getini("USM_APIURL") + "auth/login",
req = requests.post(pytest.config.getini("usm_api_url") + "auth/login",
data, verify=self.verify)
Api.print_req_info(req)
Api.check_response(req, asserts)
Expand Down Expand Up @@ -173,7 +173,7 @@ def logout(self, asserts_in=None):
})
if asserts_in:
asserts.update(asserts_in)
req = requests.post(pytest.config.getini("USM_APIURL") + "auth/logout",
req = requests.post(pytest.config.getini("usm_api_url") + "auth/logout",
cookies=self.cookies, verify=self.verify)
Api.print_req_info(req)
Api.check_response(req, asserts)
Expand Down
12 changes: 6 additions & 6 deletions usmqe/api/skyringapi/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def users(self, asserts_in=None):
})
if asserts_in:
asserts.update(asserts_in)
req = requests.get(pytest.config.getini("USM_APIURL") + "users/",
req = requests.get(pytest.config.getini("usm_api_url") + "users/",
cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
ApiUser.check_response(req, asserts)
Expand Down Expand Up @@ -71,7 +71,7 @@ def users_replace(self, users, asserts_in=None):
data[-1]["email"] %= usr
data[-1]["password"] = usr
data = json.dumps(data)
req = requests.put(pytest.config.getini("USM_APIURL") + "users",
req = requests.put(pytest.config.getini("usm_api_url") + "users",
data, cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
ApiUser.check_response(req, asserts)
Expand Down Expand Up @@ -106,7 +106,7 @@ def users_add(self, user_in, asserts_in=None):
issue = None
if data:
data = json.dumps(data)
req = requests.post(pytest.config.getini("USM_APIURL") + "users",
req = requests.post(pytest.config.getini("usm_api_url") + "users",
data, cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
if req.status_code == 500 and \
Expand Down Expand Up @@ -135,7 +135,7 @@ def user(self, user_in, asserts_in=None):
if asserts_in:
asserts.update(asserts_in)
req = requests.get(
pytest.config.getini("USM_APIURL") + "users/%s" % user_in,
pytest.config.getini("usm_api_url") + "users/%s" % user_in,
cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
ApiUser.check_response(req, asserts)
Expand Down Expand Up @@ -174,7 +174,7 @@ def user_add(self, user_in, asserts_in=None):
elif isinstance(user_in, dict):
data = user_in
req = requests.put(
pytest.config.getini("USM_APIURL") + "users/%s" % data["username"],
pytest.config.getini("usm_api_url") + "users/%s" % data["username"],
json.dumps(data), cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
ApiUser.check_response(req, asserts)
Expand All @@ -195,7 +195,7 @@ def user_del(self, user_in, asserts_in=None):
if asserts_in:
asserts.update(asserts_in)
req = requests.delete(
pytest.config.getini("USM_APIURL") + "users/%s" % user_in,
pytest.config.getini("usm_api_url") + "users/%s" % user_in,
cookies=self.cookies, verify=self.verify)
ApiUser.print_req_info(req)
ApiUser.check_response(req, asserts)
Loading

0 comments on commit 11dbddf

Please sign in to comment.