Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Config cleanup #3

Merged
merged 14 commits into from
Dec 1, 2016
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions conf/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,8 @@

This directory contains examples of configuration files required to run the
integration tests.

See full documentation of usmqe test configuration in `Test Configuration`_
document.

.. _`Test Configuration`: https://github.com/Tendrl/usmqe-tests/blob/master/docs/test_configuration.rst
25 changes: 0 additions & 25 deletions conf/example_pytest.ini

This file was deleted.

File renamed without changes.
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>
url = https://example-usm3-server.usmqe.tendrl.org:10443
ca_cert = conf/tendrl_ca.crt
# This is example of USM QE configuration file.

[raut]
SELENIUM_SERVER = None
# 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
123 changes: 120 additions & 3 deletions docs/test_configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,124 @@
Test Configuraion
===================

USM QE Tests are executed under ``usmqe`` user account on QE Server
machine (see :ref:`qe-server-label` for more details).
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.

TODO: include all the details here
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 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 ``--override-ini``. See an example how to use different
*host inventory file* for a particular test run:

.. code-block:: console

$ 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.


Details for Test Development
============================

To access data from the host inventory, use functions provided by
``usmqe.inventory`` module:

.. code-block:: python

import usmqe.inventory as inventory

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

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:

* *QE Server mahcine* has been configured as described in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: "mahcine"

:ref:`qe-server-label`

* You have *host inventory file* for the test cluster, which has been already
deployed (our deployment automation should generate the inventory file
in the end of the process).

* You are logged as ``usmqe`` user on the QE Server

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
``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``.

* Verify that ssh and ansible are configured so that one can reach all machines
from test cluster:

.. code-block:: console

[usmqe@qeserver ~]$ ansible -i conf/clustername.hosts -m ping -u root all

* 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
60 changes: 19 additions & 41 deletions plugin/usmqe_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,9 @@ def pytest_addoption(parser):
"""
Add ini options to be accepted by pytest.
"""
parser.addini('USM_CONFIG', 'USM configuration')
parser.addini(
'USM_HOST_CONFIG', 'USM host configuration', default='sample.hosts')
parser.addini('USM_USERNAME', 'USM username for login', default='admin')
parser.addini('USM_PASSWORD', 'USM password for login')
parser.addini('USM_URL', 'USM url')
parser.addini('USM_APIURL', 'USM url for api')
parser.addini(
'USM_LOG_LEVEL', 'USM log test level', default='logging.DEBUG')
parser.addini(
'USM_KEYFILE', 'USM key file for passwordless ssh',
default='~/.ssh/id_rsa')
parser.addini(
'USM_CA_CERT', 'USM use CA certificate', type='bool', default=False)
# defaults are specified in root pytest.ini file
parser.addini('usm_config', 'USM configuration')
parser.addini('usm_host_config', 'USM host configuration')


@pytest.fixture(autouse=True, scope="session")
Expand All @@ -40,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 @@ -57,33 +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 ('raut', '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

if not pytest.config.getini("USM_APIURL"):
pytest.config._inicache["USM_APIURL"] = \
"{}/api/v1/".format(pytest.config.getini("USM_URL"))
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
45 changes: 45 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
[pytest]

#
# USM QE config section (see plugin/usmqe_config.py)
#

# 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

# 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

# Predefined usmqe configuration values.
# 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

# 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"

# webstr config group: webstr specific options
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
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