Initial commit
Change-Id: I8a5c7a14a791d62fc856526dbd5585430ec2d663
This commit is contained in:
parent
89969372a9
commit
b2267cfe62
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
*.pyc
|
||||
*.pyo
|
||||
*.swp
|
||||
.idea
|
||||
*egg-info
|
||||
.tox
|
||||
.venv
|
||||
*.egg/
|
4
.testr.conf
Normal file
4
.testr.conf
Normal file
@ -0,0 +1,4 @@
|
||||
[DEFAULT]
|
||||
test_command=${PYTHON:-python} -m subunit.run discover ./cloudv_ostf_adapter/tests/unittests $LISTOPT $IDOPTION
|
||||
test_id_option=--load-list $IDFILE
|
||||
test_list_option=--list
|
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@ -0,0 +1 @@
|
||||
recursive-include public *
|
125
README.rst
Normal file
125
README.rst
Normal file
@ -0,0 +1,125 @@
|
||||
=================================
|
||||
Cloud Validation adapter for OSTF
|
||||
=================================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Existing [OSTF](http://docs.mirantis.com/fuel-dev/develop/ostf_contributors_guide.html)
|
||||
code provides a number of tests which cover a number of cases needed for cloud
|
||||
validation. The downside of existing OSTF is that it is tightly coupled with
|
||||
FUEL's nailgun. Given project aims to create standalone adapter for OSTF which
|
||||
is independent of FUEL thus making it possible to run OSTF tests on any random
|
||||
cloud (in theory).
|
||||
|
||||
High-level design
|
||||
-----------------
|
||||
|
||||
CLI tool that works with health check plugins
|
||||
Supported plugins::
|
||||
|
||||
- fuel health check
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
.. code-block:: bash
|
||||
|
||||
$ cloudvalidation cloud-health-check {argument} [argument_parameters]
|
||||
|
||||
Arguments::
|
||||
|
||||
list_plugins - Lists plugins
|
||||
list_plugin_suites - Lists plugin test suites
|
||||
list_plugin_tests - Lists plugin tests from all available suites
|
||||
run_suites - Runs all tests from all suites
|
||||
run_suite - Runs certain test suite
|
||||
run_test - Runs certain test
|
||||
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cloudvalidation cloud-health-check list_plugins
|
||||
|
||||
+----------+------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+----------+------------------------------------------------------------------+
|
||||
| name | fuel_health |
|
||||
| suites | fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest |
|
||||
| | fuel_health.tests.sanity.test_sanity_heat.SanityHeatTest |
|
||||
| | fuel_health.tests.smoke.test_create_flavor.FlavorsAdminTest |
|
||||
+----------+------------------------------------------------------------------+
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cloudvalidation cloud-health-check list_plugin_suites --validation-plugin fuel_health
|
||||
|
||||
+----------+------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+----------+------------------------------------------------------------------+
|
||||
| suites | fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest |
|
||||
| | fuel_health.tests.sanity.test_sanity_heat.SanityHeatTest |
|
||||
| | fuel_health.tests.smoke.test_create_flavor.FlavorsAdminTest |
|
||||
+----------+------------------------------------------------------------------+
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cloudvalidation cloud-health-check list_plugin_tests --validation-plugin fuel_health
|
||||
|
||||
+----------+--------------------------------------------------------------------------------------+
|
||||
| Property | Value |
|
||||
+----------+--------------------------------------------------------------------------------------+
|
||||
| tests | fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest:test_list_services |
|
||||
| | fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest:test_list_users |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_flavors |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_images |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_instances |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_rate_limits |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_snapshots |
|
||||
| | fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest:test_list_volumes |
|
||||
| | fuel_health.tests.sanity.test_sanity_heat.SanityHeatTest:test_list_stacks |
|
||||
| | fuel_health.tests.smoke.test_create_flavor.FlavorsAdminTest:test_create_flavor |
|
||||
+----------+--------------------------------------------------------------------------------------+
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cloudvalidation --config-dir=/etc/cloudv_ostf_adapter cloud-health-check run_suites --validation-plugin-name fuel_health
|
||||
|
||||
|
||||
Request user list ... ok
|
||||
Request flavor list ... ok
|
||||
Request image list ... ok
|
||||
Request instance list ... ok
|
||||
Request absolute limits list ... ok
|
||||
Request snapshot list ... ok
|
||||
Request volume list ... ok
|
||||
Request stack list ... ok
|
||||
Create instance flavor ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 9 tests in 5.310s
|
||||
|
||||
OK
|
||||
|
||||
.. code-block::
|
||||
|
||||
$ cloudvalidation --config-dir=/etc/cloudv_ostf_adapter cloud-health-check run_suite --validation-plugin-name fuel_health --suite fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest
|
||||
|
||||
Running test suite: fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest ...
|
||||
Request user list ... ok
|
||||
|
||||
----------------------------------------------------------------------
|
||||
Ran 1 test in 0.938s
|
||||
|
||||
OK
|
||||
|
||||
Links
|
||||
-----
|
||||
|
||||
* OSTF contributor's guide - http://docs.mirantis.com/fuel-dev/develop/ostf_contributors_guide.html)
|
||||
* OSTF source code - https://github.com/stackforge/fuel-ostf
|
0
cloudv_ostf_adapter/__init__.py
Normal file
0
cloudv_ostf_adapter/__init__.py
Normal file
0
cloudv_ostf_adapter/cmd/__init__.py
Normal file
0
cloudv_ostf_adapter/cmd/__init__.py
Normal file
126
cloudv_ostf_adapter/cmd/_common.py
Normal file
126
cloudv_ostf_adapter/cmd/_common.py
Normal file
@ -0,0 +1,126 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import argparse
|
||||
import six
|
||||
|
||||
|
||||
def args(*args, **kwargs):
|
||||
"""
|
||||
Decorates commandline arguments for actions
|
||||
:param args: sub-category commandline arguments
|
||||
:param kwargs: sub-category commandline arguments
|
||||
:return: decorator: object attribute setter
|
||||
:rtype: callable
|
||||
"""
|
||||
def _decorator(func):
|
||||
func.__dict__.setdefault('args', []).insert(0, (args, kwargs))
|
||||
return func
|
||||
return _decorator
|
||||
|
||||
|
||||
def methods_of(obj):
|
||||
"""
|
||||
Get all callable methods of an object that don't
|
||||
start with underscore (private attributes)
|
||||
returns
|
||||
:param obj: objects to get callable attributes from
|
||||
:type obj: object
|
||||
:return result: a list of tuples of the form (method_name, method)
|
||||
:rtype: list
|
||||
"""
|
||||
result = []
|
||||
for i in dir(obj):
|
||||
if callable(getattr(obj, i)) and not i.startswith('_'):
|
||||
result.append((i, getattr(obj, i)))
|
||||
return result
|
||||
|
||||
|
||||
def add_command_parsers(categories):
|
||||
"""
|
||||
Parses actions commandline arguments from each category
|
||||
:param categories: commandline categories
|
||||
:type categories: dict
|
||||
:return: _subparser: commandline subparser
|
||||
"""
|
||||
def _subparser(subparsers):
|
||||
"""
|
||||
Iterates over categories and registers action
|
||||
commandline arguments for each category
|
||||
:param subparsers: commandline subparser
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
for category in categories:
|
||||
command_object = categories[category]()
|
||||
|
||||
desc = getattr(command_object, 'description', None)
|
||||
parser = subparsers.add_parser(category, description=desc)
|
||||
parser.set_defaults(command_object=command_object)
|
||||
|
||||
category_subparsers = parser.add_subparsers(dest='action')
|
||||
|
||||
for (action, action_fn) in methods_of(command_object):
|
||||
parser = category_subparsers.add_parser(
|
||||
action, description=desc)
|
||||
|
||||
action_kwargs = []
|
||||
for args, kwargs in getattr(action_fn, 'args', []):
|
||||
kwargs.setdefault('dest', args[0][2:])
|
||||
if kwargs['dest'].startswith('action_kwarg_'):
|
||||
action_kwargs.append(
|
||||
kwargs['dest'][len('action_kwarg_'):])
|
||||
else:
|
||||
action_kwargs.append(kwargs['dest'])
|
||||
kwargs['dest'] = 'action_kwarg_' + kwargs['dest']
|
||||
|
||||
parser.add_argument(*args, **kwargs)
|
||||
|
||||
parser.set_defaults(action_fn=action_fn)
|
||||
parser.set_defaults(action_kwargs=action_kwargs)
|
||||
|
||||
parser.add_argument('action_args', nargs='*',
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
return _subparser
|
||||
|
||||
|
||||
def _main(global_conf, local_conf, category_opt, cli_args):
|
||||
"""
|
||||
|
||||
:param global_conf: staged CONF
|
||||
:param local_conf: tool conf
|
||||
:param category_opt: subparser category options
|
||||
:param cli_args: tool CLI arguments
|
||||
:return:
|
||||
"""
|
||||
global_conf.register_cli_opt(category_opt)
|
||||
local_conf.parse_args(cli_args)
|
||||
fn = global_conf.category.action_fn
|
||||
fn_args = [arg.decode('utf-8') for arg in global_conf.category.action_args]
|
||||
fn_kwargs = {}
|
||||
for k in global_conf.category.action_kwargs:
|
||||
v = getattr(global_conf.category, 'action_kwarg_' + k)
|
||||
if v is None:
|
||||
continue
|
||||
if isinstance(v, six.string_types):
|
||||
v = v.decode('utf-8')
|
||||
fn_kwargs[k] = v
|
||||
|
||||
try:
|
||||
ret = fn(*fn_args, **fn_kwargs)
|
||||
return ret
|
||||
except Exception as e:
|
||||
print(str(e))
|
104
cloudv_ostf_adapter/cmd/cloudv_runner.py
Normal file
104
cloudv_ostf_adapter/cmd/cloudv_runner.py
Normal file
@ -0,0 +1,104 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg as config
|
||||
from cloudv_ostf_adapter.common import utils
|
||||
from cloudv_ostf_adapter.cmd import _common as cmd
|
||||
|
||||
from cloudv_ostf_adapter import validation_plugin
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class OSTF(object):
|
||||
"""
|
||||
Represents CLI view for OSTF tests commands:
|
||||
- list validation plugins
|
||||
- list per-plugin test suites
|
||||
"""
|
||||
|
||||
def list_plugins(self):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
del descriptor['tests']
|
||||
descriptor.update({'suites': "\n".join(descriptor['suites'])})
|
||||
utils.print_dict(descriptor)
|
||||
|
||||
@cmd.args("--validation-plugin-name", dest="validation_plugin_name")
|
||||
def list_plugin_suites(self, validation_plugin_name):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
if descriptor['name'] == validation_plugin_name:
|
||||
utils.print_dict({'suites': "\n".join(descriptor['suites'])})
|
||||
|
||||
@cmd.args("--validation-plugin-name", dest="validation_plugin_name")
|
||||
def list_plugin_tests(self, validation_plugin_name):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
if descriptor['name'] == validation_plugin_name:
|
||||
utils.print_dict({
|
||||
'tests': "\n".join(plugin().descriptor()['tests'])})
|
||||
|
||||
@cmd.args("--validation-plugin-name", dest="validation_plugin_name")
|
||||
def run_suites(self, validation_plugin_name):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
if descriptor['name'] == validation_plugin_name:
|
||||
plugin().run_suites()
|
||||
|
||||
@cmd.args("--suite", dest="suite")
|
||||
@cmd.args("--validation-plugin-name", dest="validation_plugin_name")
|
||||
def run_suite(self, validation_plugin_name, suite):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
if descriptor['name'] == validation_plugin_name:
|
||||
plugin().run_suite(suite)
|
||||
|
||||
@cmd.args("--validation-plugin-name", dest="validation_plugin_name")
|
||||
@cmd.args("--test", dest="test")
|
||||
def run_test(self, validation_plugin_name, test):
|
||||
for plugin in validation_plugin.VALIDATION_PLUGINS:
|
||||
_plugin = plugin(load_tests=False)
|
||||
descriptor = _plugin.descriptor()
|
||||
if descriptor['name'] == validation_plugin_name:
|
||||
plugin().run_test(test)
|
||||
|
||||
|
||||
CATS = {
|
||||
'cloud-health-check': OSTF
|
||||
}
|
||||
|
||||
category_opt = cfg.SubCommandOpt('category',
|
||||
title='Command categories',
|
||||
help='Available categories',
|
||||
handler=cmd.add_command_parsers(CATS))
|
||||
|
||||
|
||||
def main():
|
||||
"""Parse options and call the appropriate class/method."""
|
||||
cmd._main(CONF, config, category_opt, sys.argv)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
0
cloudv_ostf_adapter/common/__init__.py
Normal file
0
cloudv_ostf_adapter/common/__init__.py
Normal file
75
cloudv_ostf_adapter/common/cfg.py
Normal file
75
cloudv_ostf_adapter/common/cfg.py
Normal file
@ -0,0 +1,75 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
|
||||
from cloudv_ostf_adapter import version
|
||||
|
||||
|
||||
common_opts = [
|
||||
cfg.StrOpt("health_check_config_path",
|
||||
default='etc/cloudv_ostf_adapter/health_check.conf'),
|
||||
cfg.StrOpt("enabled_validation_plugins", default=['fuel_health']),
|
||||
cfg.StrOpt("nose_verbosity", default="-v")
|
||||
]
|
||||
|
||||
sanity_group = cfg.OptGroup("sanity", "Sanity configuration group.")
|
||||
smoke_group = cfg.OptGroup("smoke", "Smoke configuration group.")
|
||||
platform_group = cfg.OptGroup("platform",
|
||||
"Platform functional configuration group.")
|
||||
ha_group = cfg.OptGroup("high_availability", "HA configuration group.")
|
||||
|
||||
|
||||
sanity_opts = [
|
||||
cfg.MultiStrOpt("enabled_tests", default=[
|
||||
'fuel_health.tests.sanity.test_sanity_identity.SanityIdentityTest',
|
||||
'fuel_health.tests.sanity.test_sanity_compute.SanityComputeTest',
|
||||
'fuel_health.tests.sanity.test_sanity_heat.SanityHeatTest',
|
||||
'fuel_health.tests.sanity.test_sanity_networking.NetworksTest:'
|
||||
'test_list_networks_nova_network',
|
||||
]),
|
||||
]
|
||||
smoke_opts = [
|
||||
cfg.MultiStrOpt("enabled_tests", default=[
|
||||
'fuel_health.tests.smoke.test_create_flavor.FlavorsAdminTest',
|
||||
]),
|
||||
]
|
||||
platform_opts = [
|
||||
cfg.MultiStrOpt("enabled_tests", default=[]),
|
||||
]
|
||||
ha_opts = [
|
||||
cfg.MultiStrOpt("enabled_tests", default=[]),
|
||||
]
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONF.register_opts(common_opts)
|
||||
|
||||
CONF.register_group(sanity_group)
|
||||
CONF.register_group(smoke_group)
|
||||
CONF.register_group(platform_group)
|
||||
CONF.register_group(ha_group)
|
||||
|
||||
CONF.register_opts(sanity_opts, sanity_group)
|
||||
CONF.register_opts(smoke_opts, smoke_group)
|
||||
CONF.register_opts(platform_opts, platform_group)
|
||||
CONF.register_opts(ha_opts, ha_group)
|
||||
|
||||
|
||||
def parse_args(argv, default_config_files=None):
|
||||
cfg.CONF(args=argv[1:],
|
||||
project='cloudv_ostf_adapter',
|
||||
version=version.version,
|
||||
default_config_files=default_config_files)
|
90
cloudv_ostf_adapter/common/utils.py
Normal file
90
cloudv_ostf_adapter/common/utils.py
Normal file
@ -0,0 +1,90 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
import sys
|
||||
import prettytable
|
||||
import six
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from oslo.utils import encodeutils
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
def _print(pt, order):
|
||||
if sys.version_info >= (3, 0):
|
||||
print(pt.get_string(sortby=order))
|
||||
else:
|
||||
print(encodeutils.safe_encode(pt.get_string(sortby=order)))
|
||||
|
||||
|
||||
def print_dict(d, property="Property"):
|
||||
pt = prettytable.PrettyTable([property, 'Value'], caching=False)
|
||||
pt.align = 'l'
|
||||
[pt.add_row(list(r)) for r in six.iteritems(d)]
|
||||
_print(pt, property)
|
||||
|
||||
|
||||
def print_list(objs, fields, formatters={}, order_by=None, obj_is_dict=False,
|
||||
labels={}):
|
||||
if not labels:
|
||||
labels = {}
|
||||
for field in fields:
|
||||
if field not in labels:
|
||||
# No underscores (use spaces instead) and uppercase any ID's
|
||||
label = field.replace("_", " ").replace("id", "ID")
|
||||
# Uppercase anything else that's less than 3 chars
|
||||
if len(label) < 3:
|
||||
label = label.upper()
|
||||
# Capitalize each word otherwise
|
||||
else:
|
||||
label = ' '.join(word[0].upper() + word[1:]
|
||||
for word in label.split())
|
||||
labels[field] = label
|
||||
|
||||
pt = prettytable.PrettyTable(
|
||||
[labels[field] for field in fields], caching=False)
|
||||
# set the default alignment to left-aligned
|
||||
align = dict((labels[field], 'l') for field in fields)
|
||||
set_align = True
|
||||
for obj in objs:
|
||||
row = []
|
||||
for field in fields:
|
||||
if formatters and field in formatters:
|
||||
row.append(formatters[field](obj))
|
||||
elif obj_is_dict:
|
||||
data = obj.get(field, '')
|
||||
else:
|
||||
data = getattr(obj, field, '')
|
||||
row.append(data)
|
||||
# set the alignment to right-aligned if it's a numeric
|
||||
if set_align and hasattr(data, '__int__'):
|
||||
align[labels[field]] = 'r'
|
||||
set_align = False
|
||||
pt.add_row(row)
|
||||
pt._align = align
|
||||
|
||||
if not order_by:
|
||||
order_by = fields[0]
|
||||
order_by = labels[order_by]
|
||||
_print(pt, order_by)
|
||||
|
||||
|
||||
def poll_until(pollster, expected_result=None, sleep_time=5):
|
||||
import time
|
||||
if not callable(pollster):
|
||||
raise Exception("%s is not callable" % pollster.__name__)
|
||||
while pollster() != expected_result:
|
||||
time.sleep(sleep_time)
|
0
cloudv_ostf_adapter/nose_plugin/__init__.py
Normal file
0
cloudv_ostf_adapter/nose_plugin/__init__.py
Normal file
35
cloudv_ostf_adapter/nose_plugin/discovery.py
Normal file
35
cloudv_ostf_adapter/nose_plugin/discovery.py
Normal file
@ -0,0 +1,35 @@
|
||||
# Copyright 2015 Mirantis, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
from nose import loader
|
||||
from oslo_utils import importutils
|
||||
|
||||
|
||||
def do_test_discovery(classes):
|
||||
"""
|
||||
Will discover test cases from suites
|
||||
"""
|
||||
_tests = []
|
||||
_loader = loader.TestLoader()
|
||||
for classname in classes:
|
||||
if ":" in classname:
|
||||
cls, method = classname.split(":")
|
||||
getattr(importutils.import_class(cls), method)
|
||||
else:
|
||||
suite_class = _loader.loadTestsFromTestClass(
|
||||
importutils.import_class(classname))
|
||||
for test_case in suite_class._precache:
|
||||
_tests.append(classname + ':' + str(
|
||||
test_case).split(' ')[0])
|
||||
return _tests
|
0
cloudv_ostf_adapter/tests/__init__.py
Normal file
0
cloudv_ostf_adapter/tests/__init__.py
Normal file
0
cloudv_ostf_adapter/tests/unittests/__init__.py
Normal file
0
cloudv_ostf_adapter/tests/unittests/__init__.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
import time
|
||||
import testtools
|
||||
|
||||
from oslo_config import cfg as conf
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
_group = conf.OptGroup("fake")
|
||||
CONF.register_group(_group)
|
||||
_opts = [
|
||||
conf.MultiStrOpt("enabled_tests", default=[
|
||||
"cloudv_ostf_adapter.tests.unittests.fakes.fake_plugin."
|
||||
"fake_plugin_tests.FakePluginTests"
|
||||
])
|
||||
]
|
||||
CONF.register_opts(_opts, _group)
|
||||
|
||||
GROUP = 'fake'
|
||||
CONF = cfg.CONF
|
||||
TESTS = CONF.get(GROUP).enabled_tests
|
||||
|
||||
|
||||
class FakePluginTests(testtools.TestCase):
|
||||
|
||||
def test_a(self):
|
||||
time.sleep(5)
|
||||
self.assertEqual("A", "A")
|
||||
|
||||
def test_b(self):
|
||||
time.sleep(5)
|
||||
self.assertIn("B", "ABCD")
|
||||
|
||||
|
||||
def get_tests():
|
||||
return base.SuiteDescriptor(GROUP, TESTS)
|
@ -0,0 +1,31 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
from cloudv_ostf_adapter.tests.unittests.fakes.fake_plugin import (
|
||||
fake_plugin_tests)
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
SUITES = [fake_plugin_tests]
|
||||
|
||||
|
||||
class FakeValidationPlugin(base.ValidationPlugin):
|
||||
|
||||
def __init__(self, load_tests=True):
|
||||
name = 'fake'
|
||||
super(FakeValidationPlugin, self).__init__(
|
||||
name, SUITES, load_tests=load_tests)
|
42
cloudv_ostf_adapter/tests/unittests/test_workflow.py
Normal file
42
cloudv_ostf_adapter/tests/unittests/test_workflow.py
Normal file
@ -0,0 +1,42 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
import testtools
|
||||
|
||||
from cloudv_ostf_adapter import validation_plugin
|
||||
from cloudv_ostf_adapter.tests.unittests.fakes.fake_plugin import health_plugin
|
||||
|
||||
|
||||
class TestWorkflow(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.plugin = health_plugin.FakeValidationPlugin()
|
||||
validation_plugin.VALIDATION_PLUGINS.append(self.plugin.__class__)
|
||||
super(TestWorkflow, self).setUp()
|
||||
|
||||
def tearDown(self):
|
||||
validation_plugin.VALIDATION_PLUGINS.pop(
|
||||
validation_plugin.VALIDATION_PLUGINS.index(
|
||||
self.plugin.__class__))
|
||||
super(TestWorkflow, self).tearDown()
|
||||
|
||||
def test_verify_plugins(self):
|
||||
self.assertEqual(2, len(validation_plugin.VALIDATION_PLUGINS))
|
||||
self.assertIn(self.plugin.__class__,
|
||||
validation_plugin.VALIDATION_PLUGINS)
|
||||
|
||||
def test_verify_fake_plugin(self):
|
||||
test_patsh = self.plugin._collect_test(self.plugin.tests)
|
||||
self.assertEqual(2, len(test_patsh))
|
||||
self.assertEqual(2, len(self.plugin.tests))
|
19
cloudv_ostf_adapter/validation_plugin/__init__.py
Normal file
19
cloudv_ostf_adapter/validation_plugin/__init__.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
from cloudv_ostf_adapter.validation_plugin import fuel_health
|
||||
|
||||
|
||||
VALIDATION_PLUGINS = [
|
||||
fuel_health.FuelHealthPlugin,
|
||||
]
|
130
cloudv_ostf_adapter/validation_plugin/base.py
Normal file
130
cloudv_ostf_adapter/validation_plugin/base.py
Normal file
@ -0,0 +1,130 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from oslo_utils import importutils
|
||||
|
||||
from cloudv_ostf_adapter.common import utils
|
||||
from cloudv_ostf_adapter.nose_plugin import discovery
|
||||
|
||||
|
||||
class SuiteDescriptor(object):
|
||||
|
||||
suite_attrs = ['test_group', 'tests']
|
||||
test_attrs = ['tests']
|
||||
|
||||
def __init__(self, test_group_definition, tests):
|
||||
"""
|
||||
Describes test specific test group
|
||||
@param test_group_definition: Test group definition
|
||||
(i.e. sanity, smoke, HA, platform)
|
||||
@type test_group_definition: basestring
|
||||
@param tests: list of tests per test group
|
||||
@type tests: list
|
||||
"""
|
||||
self.test_group = test_group_definition
|
||||
self.tests = tests
|
||||
|
||||
def print_tests_description(self):
|
||||
utils.print_list(self, self.test_attrs)
|
||||
|
||||
def print_description(self):
|
||||
utils.print_dict(self)
|
||||
|
||||
|
||||
class ValidationPlugin(object):
|
||||
|
||||
test_executor = "%(test_module_path)s:%(class)s.%(test)s"
|
||||
|
||||
def __init__(self, name, suites, load_tests=True):
|
||||
__suites = []
|
||||
for suite in suites:
|
||||
__suites.extend(suite.TESTS)
|
||||
|
||||
self.name = name
|
||||
self.suites = __suites
|
||||
self._suites = suites
|
||||
self.tests = (self._get_tests()
|
||||
if load_tests else [])
|
||||
|
||||
def _get_tests(self):
|
||||
"""
|
||||
Test collector
|
||||
"""
|
||||
tests = []
|
||||
for suite in self._suites:
|
||||
_tests = discovery.do_test_discovery(
|
||||
suite.TESTS)
|
||||
tests.extend(_tests)
|
||||
return tests
|
||||
|
||||
def _collect_test(self, tests):
|
||||
test_suites_paths = []
|
||||
for test in tests:
|
||||
classpath, test_method = test.split(":")
|
||||
classname = classpath.split(".")[-1]
|
||||
module = importutils.import_class(
|
||||
classpath).__module__
|
||||
test_module_path = os.path.abspath(
|
||||
sys.modules[module].__file__)
|
||||
if test_module_path.endswith("pyc"):
|
||||
test_module_path = test_module_path[:-1]
|
||||
test_suites_paths.append(
|
||||
self.test_executor %
|
||||
{
|
||||
'test_module_path': test_module_path,
|
||||
'class': classname,
|
||||
'test': test_method
|
||||
})
|
||||
return test_suites_paths
|
||||
|
||||
def _get_tests_by_suite(self, suite):
|
||||
tests = []
|
||||
for test in self.tests:
|
||||
if suite in test:
|
||||
tests.append(test)
|
||||
return tests
|
||||
|
||||
def descriptor(self):
|
||||
"""
|
||||
Returns Plugin descriptor that contains:
|
||||
- plugin name
|
||||
- plugin suites
|
||||
- plugin tests
|
||||
"""
|
||||
return {
|
||||
"name": self.name,
|
||||
"suites": self.suites,
|
||||
"tests": self.tests,
|
||||
}
|
||||
|
||||
def run_suites(self):
|
||||
"""
|
||||
Runs all tests from all suites
|
||||
"""
|
||||
raise Exception("Plugin doesn't support suites execution.")
|
||||
|
||||
def run_suite(self, suite):
|
||||
"""
|
||||
Runs specific suite
|
||||
"""
|
||||
raise Exception("Plugin doesn't support suite execution.")
|
||||
|
||||
def run_test(self, test):
|
||||
"""
|
||||
Runs specific test
|
||||
"""
|
||||
raise Exception("Plugin doesn't support test execution.")
|
102
cloudv_ostf_adapter/validation_plugin/fuel_health/__init__.py
Normal file
102
cloudv_ostf_adapter/validation_plugin/fuel_health/__init__.py
Normal file
@ -0,0 +1,102 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
import os
|
||||
|
||||
from nose import core
|
||||
|
||||
from oslo_utils import importutils
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
from cloudv_ostf_adapter.validation_plugin.fuel_health import sanity
|
||||
from cloudv_ostf_adapter.validation_plugin.fuel_health import smoke
|
||||
from cloudv_ostf_adapter.validation_plugin.fuel_health import high_availability
|
||||
from cloudv_ostf_adapter.validation_plugin.fuel_health import platform
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
SUITES = [
|
||||
sanity,
|
||||
smoke,
|
||||
high_availability,
|
||||
platform,
|
||||
]
|
||||
|
||||
|
||||
class FuelHealthPlugin(base.ValidationPlugin):
|
||||
|
||||
def setup_fuel_health_on_need(self):
|
||||
FUEL_HEALTH_CONF = importutils.import_module("fuel_health.config")
|
||||
|
||||
@FUEL_HEALTH_CONF.process_singleton
|
||||
class MonkeyPatchFuelHealthConf(object):
|
||||
|
||||
def __init__(self):
|
||||
self.register_opts()
|
||||
self.compute = cfg.CONF.compute
|
||||
self.identity = cfg.CONF.identity
|
||||
self.network = cfg.CONF.network
|
||||
self.volume = cfg.CONF.volume
|
||||
self.murano = cfg.CONF.murano
|
||||
self.heat = cfg.CONF.heat
|
||||
self.sahara = cfg.CONF.sahara
|
||||
|
||||
def register_opts(self):
|
||||
FUEL_HEALTH_CONF.register_compute_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_identity_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_network_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_volume_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_murano_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_heat_opts(CONF)
|
||||
FUEL_HEALTH_CONF.register_sahara_opts(CONF)
|
||||
|
||||
FUEL_HEALTH_CONF.FileConfig = MonkeyPatchFuelHealthConf
|
||||
|
||||
MonkeyPatchFuelHealthConf()
|
||||
|
||||
def __init__(self, load_tests=True):
|
||||
self.setup_fuel_health_on_need()
|
||||
super(FuelHealthPlugin, self).__init__(
|
||||
'fuel_health', SUITES, load_tests=load_tests)
|
||||
|
||||
def _get_tests(self):
|
||||
try:
|
||||
return super(FuelHealthPlugin, self)._get_tests()
|
||||
except Exception:
|
||||
print("fuel_health is not installed.")
|
||||
|
||||
def run_suites(self):
|
||||
test_suites_paths = self.setup_execution(self.tests)
|
||||
print(core.TestProgram(
|
||||
argv=test_suites_paths).success)
|
||||
|
||||
def setup_execution(self, tests):
|
||||
test_suites_paths = self._collect_test(tests)
|
||||
test_suites_paths.append(CONF.nose_verbosity)
|
||||
os.environ.update(
|
||||
{"CUSTOM_FUEL_CONFIG": CONF.health_check_config_path})
|
||||
CONF.reload_config_files()
|
||||
return test_suites_paths
|
||||
|
||||
def run_suite(self, suite):
|
||||
if ":" in suite:
|
||||
raise Exception(
|
||||
"%s is a test case, but not test suite." % suite)
|
||||
else:
|
||||
tests = self._get_tests_by_suite(suite)
|
||||
print("Running test suite: %s ..." % suite)
|
||||
print(core.TestProgram(
|
||||
argv=self.setup_execution(tests)).success)
|
@ -0,0 +1,24 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
|
||||
GROUP = 'high_availability'
|
||||
CONF = cfg.CONF
|
||||
TESTS = CONF.get(GROUP).enabled_tests
|
||||
|
||||
|
||||
def get_tests():
|
||||
return base.SuiteDescriptor(GROUP, TESTS)
|
@ -0,0 +1,24 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
|
||||
GROUP = 'platform'
|
||||
CONF = cfg.CONF
|
||||
TESTS = CONF.get(GROUP).enabled_tests
|
||||
|
||||
|
||||
def get_tests():
|
||||
return base.SuiteDescriptor(GROUP, TESTS)
|
24
cloudv_ostf_adapter/validation_plugin/fuel_health/sanity.py
Normal file
24
cloudv_ostf_adapter/validation_plugin/fuel_health/sanity.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
|
||||
GROUP = 'sanity'
|
||||
CONF = cfg.CONF
|
||||
TESTS = CONF.get(GROUP).enabled_tests
|
||||
|
||||
|
||||
def get_tests():
|
||||
return base.SuiteDescriptor(GROUP, TESTS)
|
24
cloudv_ostf_adapter/validation_plugin/fuel_health/smoke.py
Normal file
24
cloudv_ostf_adapter/validation_plugin/fuel_health/smoke.py
Normal file
@ -0,0 +1,24 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
from cloudv_ostf_adapter.common import cfg
|
||||
from cloudv_ostf_adapter.validation_plugin import base
|
||||
|
||||
GROUP = 'smoke'
|
||||
CONF = cfg.CONF
|
||||
TESTS = CONF.get(GROUP).enabled_tests
|
||||
|
||||
|
||||
def get_tests():
|
||||
return base.SuiteDescriptor(GROUP, TESTS)
|
16
cloudv_ostf_adapter/version.py
Normal file
16
cloudv_ostf_adapter/version.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Copyright 2015 Mirantis, Inc
|
||||
#
|
||||
# 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.
|
||||
|
||||
release = "cloudv-ostf-adapter"
|
||||
version = "2015.1"
|
316
doc/source/conf.py
Normal file
316
doc/source/conf.py
Normal file
@ -0,0 +1,316 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
# -- General configuration ----------------------------------------------------
|
||||
|
||||
# If your documentation needs a minimal Sphinx version, state it here.
|
||||
#needs_sphinx = '1.0'
|
||||
|
||||
# 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.todo',
|
||||
'sphinx.ext.viewcode',
|
||||
'oslosphinx']
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# The suffix of source filenames.
|
||||
source_suffix = '.rst'
|
||||
|
||||
# The encoding of source files.
|
||||
#source_encoding = 'utf-8-sig'
|
||||
|
||||
# The master toctree document.
|
||||
master_doc = 'index'
|
||||
|
||||
# General information about the project.
|
||||
project = u'cloudv-ostf-adapter'
|
||||
copyright = u'2013, OpenStack Foundation'
|
||||
|
||||
# The version info for the project you're documenting, acts as replacement for
|
||||
# |version| and |release|, also used in various other places throughout the
|
||||
# built documents.
|
||||
#
|
||||
# The short X.Y version.
|
||||
from cloudv_ostf_adapter import version
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = version.release
|
||||
# The short X.Y version.
|
||||
version = version.release
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
#language = None
|
||||
|
||||
# There are two options for replacing |today|: either, you set today to some
|
||||
# non-false value, then it is used:
|
||||
#today = ''
|
||||
# Else, today_fmt is used as the format for a strftime call.
|
||||
#today_fmt = '%B %d, %Y'
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
exclude_patterns = ['_build']
|
||||
|
||||
# The reST default role (used for this markup: `text`) to use for all documents
|
||||
#default_role = None
|
||||
|
||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
||||
add_function_parentheses = True
|
||||
|
||||
# If true, the current module name will be prepended to all description
|
||||
# unit titles (such as .. function::).
|
||||
add_module_names = True
|
||||
|
||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
||||
# output. They are ignored by default.
|
||||
#show_authors = False
|
||||
|
||||
# The name of the Pygments (syntax highlighting) style to use.
|
||||
pygments_style = 'sphinx'
|
||||
|
||||
# A list of ignored prefixes for module index sorting.
|
||||
modindex_common_prefix = ['cloudv_ostf_adapter.']
|
||||
|
||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
||||
#keep_warnings = False
|
||||
|
||||
# -- Options for HTML output --------------------------------------------------
|
||||
|
||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||
# a list of builtin themes.
|
||||
# html_theme_path = ["."]
|
||||
# html_theme = '_theme'
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# 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 = {}
|
||||
|
||||
# Add any paths that contain custom themes here, relative to this directory.
|
||||
#html_theme_path = []
|
||||
|
||||
# The name for this set of Sphinx documents. If None, it defaults to
|
||||
# "<project> v<release> documentation".
|
||||
#html_title = None
|
||||
|
||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
||||
#html_short_title = None
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top
|
||||
# of the sidebar.
|
||||
#html_logo = None
|
||||
|
||||
# The name of an image file (within the static path) to use as favicon of the
|
||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
||||
# pixels large.
|
||||
#html_favicon = None
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
# html_static_path = ['_static']
|
||||
|
||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
||||
# using the given strftime format.
|
||||
#html_last_updated_fmt = '%b %d, %Y'
|
||||
|
||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
||||
# typographically correct entities.
|
||||
#html_use_smartypants = True
|
||||
|
||||
# Custom sidebar templates, maps document names to template names.
|
||||
#html_sidebars = {}
|
||||
|
||||
# Additional templates that should be rendered to pages, maps page names to
|
||||
# template names.
|
||||
#html_additional_pages = {}
|
||||
|
||||
# If false, no module index is generated.
|
||||
#html_domain_indices = True
|
||||
|
||||
# If false, no index is generated.
|
||||
#html_use_index = True
|
||||
|
||||
# If true, the index is split into individual pages for each letter.
|
||||
#html_split_index = False
|
||||
|
||||
# If true, links to the reST sources are added to the pages.
|
||||
#html_show_sourcelink = True
|
||||
|
||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
||||
#html_show_sphinx = True
|
||||
|
||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
||||
#html_show_copyright = True
|
||||
|
||||
# If true, an OpenSearch description file will be output, and all pages will
|
||||
# contain a <link> tag referring to it. The value of this option must be the
|
||||
# base URL from which the finished HTML is served.
|
||||
#html_use_opensearch = ''
|
||||
|
||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
||||
#html_file_suffix = None
|
||||
|
||||
# Output file base name for HTML help builder.
|
||||
htmlhelp_basename = '%sdoc' % project
|
||||
|
||||
|
||||
# -- Options for LaTeX output -------------------------------------------------
|
||||
|
||||
latex_elements = {
|
||||
# The paper size ('letterpaper' or 'a4paper').
|
||||
#'papersize': 'letterpaper',
|
||||
|
||||
# The font size ('10pt', '11pt' or '12pt').
|
||||
#'pointsize': '10pt',
|
||||
|
||||
# Additional stuff for the LaTeX preamble.
|
||||
#'preamble': '',
|
||||
}
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title, author, documentclass [howto/manual])
|
||||
latex_documents = [
|
||||
(
|
||||
'index',
|
||||
'%s.tex' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation',
|
||||
'manual'
|
||||
),
|
||||
]
|
||||
|
||||
# The name of an image file (relative to this directory) to place at the top of
|
||||
# the title page.
|
||||
#latex_logo = None
|
||||
|
||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
||||
# not chapters.
|
||||
#latex_use_parts = False
|
||||
|
||||
# If true, show page references after internal links.
|
||||
#latex_show_pagerefs = False
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#latex_show_urls = False
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#latex_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#latex_domain_indices = True
|
||||
|
||||
|
||||
# -- Options for manual page output -------------------------------------------
|
||||
|
||||
# One entry per manual page. List of tuples
|
||||
# (source start file, name, description, authors, manual section).
|
||||
# man_pages = [
|
||||
# (
|
||||
# 'index',
|
||||
# '%s' % project,
|
||||
# u'%s Documentation' % project,
|
||||
# u'OpenStack Foundation',
|
||||
# 1
|
||||
# ),
|
||||
# ]
|
||||
|
||||
# If true, show URL addresses after external links.
|
||||
#man_show_urls = False
|
||||
|
||||
|
||||
# -- Options for Texinfo output -----------------------------------------------
|
||||
|
||||
# Grouping the document tree into Texinfo files. List of tuples
|
||||
# (source start file, target name, title, author,
|
||||
# dir menu entry, description, category)
|
||||
texinfo_documents = [
|
||||
(
|
||||
'index',
|
||||
'%s' % project,
|
||||
u'%s Documentation' % project,
|
||||
u'OpenStack Foundation',
|
||||
'%s' % project,
|
||||
'Database as a service.',
|
||||
'Miscellaneous'
|
||||
'manual'
|
||||
),
|
||||
]
|
||||
|
||||
# Documents to append as an appendix to all manuals.
|
||||
#texinfo_appendices = []
|
||||
|
||||
# If false, no module index is generated.
|
||||
#texinfo_domain_indices = True
|
||||
|
||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||
#texinfo_show_urls = 'footnote'
|
||||
|
||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
||||
#texinfo_no_detailmenu = False
|
||||
|
||||
|
||||
# -- Options for Epub output --------------------------------------------------
|
||||
|
||||
# Bibliographic Dublin Core info.
|
||||
epub_title = u'%s' % project
|
||||
epub_author = u'OpenStack Foundation'
|
||||
epub_publisher = u'OpenStack Foundation'
|
||||
epub_copyright = u'2013, OpenStack Foundation'
|
||||
|
||||
# The language of the text. It defaults to the language option
|
||||
# or en if the language is not set.
|
||||
#epub_language = ''
|
||||
|
||||
# The scheme of the identifier. Typical schemes are ISBN or URL.
|
||||
#epub_scheme = ''
|
||||
|
||||
# The unique identifier of the text. This can be a ISBN number
|
||||
# or the project homepage.
|
||||
#epub_identifier = ''
|
||||
|
||||
# A unique identification for the text.
|
||||
#epub_uid = ''
|
||||
|
||||
# A tuple containing the cover image and cover page html template filenames.
|
||||
#epub_cover = ()
|
||||
|
||||
# A sequence of (type, uri, title) tuples for the guide element of content.opf.
|
||||
#epub_guide = ()
|
||||
|
||||
# HTML files that should be inserted before the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_pre_files = []
|
||||
|
||||
# HTML files shat should be inserted after the pages created by sphinx.
|
||||
# The format is a list of tuples containing the path and title.
|
||||
#epub_post_files = []
|
||||
|
||||
# A list of files that should not be packed into the epub file.
|
||||
#epub_exclude_files = []
|
||||
|
||||
# The depth of the table of contents in toc.ncx.
|
||||
#epub_tocdepth = 3
|
||||
|
||||
# Allow duplicate toc entries.
|
||||
#epub_tocdup = True
|
||||
|
||||
# Fix unsupported image types using the PIL.
|
||||
#epub_fix_images = False
|
||||
|
||||
# Scale large images.
|
||||
#epub_max_image_width = 0
|
||||
|
||||
# If 'no', URL addresses will not be shown.
|
||||
#epub_show_urls = 'inline'
|
||||
|
||||
# If false, no index is generated.
|
||||
#epub_use_index = True
|
4
doc/source/index.rst
Normal file
4
doc/source/index.rst
Normal file
@ -0,0 +1,4 @@
|
||||
====================
|
||||
Cloudvalidation tool
|
||||
====================
|
||||
|
10
etc/cloudv_ostf_adapter/cloudv_ostf_adapter.conf
Normal file
10
etc/cloudv_ostf_adapter/cloudv_ostf_adapter.conf
Normal file
@ -0,0 +1,10 @@
|
||||
[DEFAULT]
|
||||
health_check_config_path = /home/dmakogon/Documents/MCV/repo/cloudv-ostf-adapter/etc/cloudv_ostf_adapter/test.conf
|
||||
|
||||
[sanity]
|
||||
|
||||
[smoke]
|
||||
|
||||
[platform]
|
||||
|
||||
[high_availability]
|
41
etc/cloudv_ostf_adapter/test.conf
Normal file
41
etc/cloudv_ostf_adapter/test.conf
Normal file
@ -0,0 +1,41 @@
|
||||
[identity]
|
||||
disable_ssl_certificate_validatio = True
|
||||
uri = http://172.18.196.219:5000/v2.0/
|
||||
url = http://172.18.196.219:5000/v2.0/
|
||||
ubuntu_url = http://172.18.196.219:5000/v2.0/
|
||||
strategy = keystone
|
||||
admin_username = admin
|
||||
admin_tenant_name = admin
|
||||
admin_password = 3de4922d8b6ac5a1aad9
|
||||
|
||||
[compute]
|
||||
flavor_ref = 2
|
||||
compute_nodes = 172.18.196.219
|
||||
online_computes = 172.18.196.219
|
||||
deployment_os = Ubuntu
|
||||
libvirt_type = qemu
|
||||
image_name = mysql
|
||||
online_controllers = 172.18.196.219
|
||||
controller_node_ssh_key_path = /home/ubuntu/.ssh/id_rsa
|
||||
controller_node_ssh_user = ubuntu
|
||||
ssh_timeout = 700
|
||||
controller_node_ssh_password = ''
|
||||
image_ssh_user = ubuntu
|
||||
image_alt_ssh_user = ubuntu
|
||||
ssh_user = ubuntu
|
||||
path_to_private_key = /home/ubuntu/.ssh/id_rsa
|
||||
|
||||
[network]
|
||||
# tenant_network_cidr = ?
|
||||
|
||||
[volume]
|
||||
backend1_name = lvmdriver-1
|
||||
backend2_name = lvmdriver-1
|
||||
|
||||
[heat]
|
||||
endpoint = http://172.18.196.219:8004/v1
|
||||
|
||||
[murano]
|
||||
# Please note that this URLs are fake, the are needed to instantiate unnecessary/redundant muranoclient
|
||||
api_url = http://172.18.196.219:8082/v1
|
||||
api_url_management = http://172.18.196.219:8082/v1
|
171
etc/cloudv_ostf_adapter/test.conf.sample
Normal file
171
etc/cloudv_ostf_adapter/test.conf.sample
Normal file
@ -0,0 +1,171 @@
|
||||
[identity]
|
||||
# This section contains configuration options that a variety of
|
||||
# test clients use when authenticating with different user/tenant
|
||||
# combinations
|
||||
url = http://localhost/
|
||||
# The type of endpoint for a Identity service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "identity"
|
||||
catalog_type = identity
|
||||
# Ignore SSL certificate validation failures? Use when in testing
|
||||
# environments that have self-signed SSL certs.
|
||||
disable_ssl_certificate_validation = False
|
||||
# URL for where to find the OpenStack Identity API endpoint (Keystone)
|
||||
uri = http://localhost:5000/v2.0/
|
||||
# URL for where to find the OpenStack V3 Identity API endpoint (Keystone)
|
||||
#uri_v3 = http://127.0.0.1:5000/v3/
|
||||
# Should typically be left as keystone unless you have a non-Keystone
|
||||
# authentication API service
|
||||
strategy = keystone
|
||||
# The identity region
|
||||
region = RegionOne
|
||||
|
||||
# This should be the username of a user WITH administrative privileges
|
||||
admin_username = nova
|
||||
# The above administrative user's password
|
||||
admin_password = nova
|
||||
# The above administrative user's tenant name
|
||||
admin_tenant_name = service
|
||||
|
||||
[compute]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Compute API.
|
||||
|
||||
#One of the controller nodes
|
||||
controller_nodes = localhost
|
||||
controller_nodes_name = controller
|
||||
|
||||
#Controller node user who able connect via ssh
|
||||
controller_node_ssh_user = root
|
||||
|
||||
#Controller node ssh user's password
|
||||
controller_node_ssh_password = r00tme
|
||||
controller_node_ssh_key_path = /root/.ssh/id_rsa
|
||||
|
||||
#The list of the services should be enabled
|
||||
enabled_services=nova-cert, nova-consoleauth, nova-scheduler, nova-conductor, nova-compute, nova-network, nova-compute, nova-network
|
||||
|
||||
# Allows test cases to create/destroy tenants and users. This option
|
||||
# enables isolated test cases and better parallel execution,
|
||||
# but also requires that OpenStack Identity API admin credentials
|
||||
# are known.
|
||||
allow_tenant_isolation = True
|
||||
|
||||
# Allows test cases to create/destroy tenants and users. This option
|
||||
# enables isolated test cases and better parallel execution,
|
||||
# but also requires that OpenStack Identity API admin credentials
|
||||
# are known.
|
||||
allow_tenant_reuse = true
|
||||
|
||||
# Reference data for tests. The ref and ref_alt should be
|
||||
# distinct images/flavors.
|
||||
image_name = TestVM
|
||||
flavor_ref = 1
|
||||
|
||||
# User names used to authenticate to an instance for a given image.
|
||||
image_ssh_user = cirros
|
||||
image_alt_ssh_user = cirros
|
||||
|
||||
# Number of seconds to wait while looping to check the status of an
|
||||
# instance that is building.
|
||||
build_interval = 3
|
||||
|
||||
# Number of seconds to time out on waiting for an instance
|
||||
# to build or reach an expected status
|
||||
build_timeout = 300
|
||||
|
||||
# Run additional tests that use SSH for instance validation?
|
||||
# This requires the instances be routable from the host
|
||||
# executing the tests
|
||||
run_ssh = false
|
||||
|
||||
# Number of seconds to wait to authenticate to an instance
|
||||
ssh_timeout = 300
|
||||
|
||||
# Number of seconds to wait for output from ssh channel
|
||||
ssh_channel_timeout = 60
|
||||
|
||||
# The type of endpoint for a Compute API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "compute"
|
||||
catalog_type = compute
|
||||
|
||||
# Does the Compute API support creation of images?
|
||||
create_image_enabled = true
|
||||
|
||||
[image]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Images API
|
||||
|
||||
# The type of endpoint for an Image API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "image"
|
||||
catalog_type = image
|
||||
|
||||
# The version of the OpenStack Images API to use
|
||||
api_version = 1
|
||||
|
||||
# HTTP image to use for glance http image testing
|
||||
http_image = http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz
|
||||
|
||||
[network]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Network API.
|
||||
|
||||
# Version of the Quantum API
|
||||
api_version = 2.0
|
||||
# Catalog type of the Quantum Service
|
||||
catalog_type = network
|
||||
|
||||
# A large private cidr block from which to allocate smaller blocks for
|
||||
# tenant networks.
|
||||
tenant_network_cidr = 10.13.0.0/16
|
||||
|
||||
# The mask bits used to partition the tenant block.
|
||||
tenant_network_mask_bits = 28
|
||||
|
||||
# If tenant networks are reachable, connectivity checks will be
|
||||
# performed directly against addresses on those networks.
|
||||
tenant_networks_reachable = true
|
||||
|
||||
# Whether or not quantum is expected to be available
|
||||
quantum_available = false
|
||||
|
||||
[volume]
|
||||
# This section contains the configuration options used when executing tests
|
||||
# against the OpenStack Block Storage API service
|
||||
|
||||
# The type of endpoint for a Cinder or Block Storage API service.
|
||||
# Unless you have a custom Keystone service catalog implementation, you
|
||||
# probably want to leave this value as "volume"
|
||||
catalog_type = volume
|
||||
# Number of seconds to wait while looping to check the status of a
|
||||
# volume that is being made available
|
||||
build_interval = 3
|
||||
# Number of seconds to time out on waiting for a volume
|
||||
# to be available or reach an expected status
|
||||
build_timeout = 300
|
||||
# Runs Cinder multi-backend tests (requires 2 backends declared in cinder.conf)
|
||||
# They must have different volume_backend_name (backend1_name and backend2_name
|
||||
# have to be different)
|
||||
multi_backend_enabled = false
|
||||
backend1_name = BACKEND_1
|
||||
backend2_name = BACKEND_2
|
||||
|
||||
[object-storage]
|
||||
# This section contains configuration options used when executing tests
|
||||
# against the OpenStack Object Storage API.
|
||||
|
||||
# You can configure the credentials in the compute section
|
||||
|
||||
# The type of endpoint for an Object Storage API service. Unless you have a
|
||||
# custom Keystone service catalog implementation, you probably want to leave
|
||||
# this value as "object-store"
|
||||
catalog_type = object-store
|
||||
|
||||
# Number of seconds to time on waiting for a container to container
|
||||
# synchronization complete
|
||||
container_sync_timeout = 120
|
||||
# Number of seconds to wait while looping to check the status of a
|
||||
# container to container synchronization
|
||||
container_sync_interval = 5
|
11
requirements.txt
Normal file
11
requirements.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
nose
|
||||
oslo.config>=1.6.0 # Apache-2.0
|
||||
pbr>=0.6,!=0.7,<1.0
|
||||
oslo.utils
|
||||
|
||||
#TODO(???): move this fix into fuel-ostf
|
||||
python-muranoclient
|
47
setup.cfg
Normal file
47
setup.cfg
Normal file
@ -0,0 +1,47 @@
|
||||
[metadata]
|
||||
name = cloudv-ostf-adapter
|
||||
version = 2015.1
|
||||
summary = CloudValidation OSTF adapter
|
||||
description-file =
|
||||
README.rst
|
||||
author = OpenStack
|
||||
author-email = openstack-dev@lists.openstack.org
|
||||
classifier =
|
||||
Environment :: OpenStack
|
||||
Intended Audience :: Information Technology
|
||||
Intended Audience :: System Administrators
|
||||
License :: OSI Approved :: Apache Software License
|
||||
Operating System :: POSIX :: Linux
|
||||
Programming Language :: Python
|
||||
Programming Language :: Python :: 2
|
||||
Programming Language :: Python :: 2.7
|
||||
|
||||
[files]
|
||||
packages =
|
||||
cloudv_ostf_adapter
|
||||
|
||||
[compile_catalog]
|
||||
domain = cloudv_ostf_adapter
|
||||
|
||||
[entry_points]
|
||||
console_scripts =
|
||||
cloudvalidation = cloudv_ostf_adapter.cmd.cloudv_runner:main
|
||||
|
||||
[global]
|
||||
setup-hooks =
|
||||
pbr.hooks.setup_hook
|
||||
|
||||
[build_sphinx]
|
||||
all_files = 1
|
||||
build-dir = doc/build
|
||||
source-dir = doc/source
|
||||
|
||||
[nosetests]
|
||||
match=^test
|
||||
where=cloudv_ostf_adapter
|
||||
nocapture=1
|
||||
cover-package=cloudv_ostf_adapter
|
||||
cover-erase=1
|
||||
|
||||
[wheel]
|
||||
universal = 1
|
31
setup.py
Normal file
31
setup.py
Normal file
@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
|
||||
#
|
||||
# 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.
|
||||
|
||||
# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT
|
||||
import setuptools
|
||||
|
||||
# In python < 2.7.4, a lazy loading of package `pbr` will break
|
||||
# setuptools if some other modules registered functions in `atexit`.
|
||||
# solution from: http://bugs.python.org/issue15881#msg170215
|
||||
try:
|
||||
import multiprocessing # noqa
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
setuptools.setup(
|
||||
setup_requires=['pbr'],
|
||||
pbr=True
|
||||
)
|
11
test-requirements.txt
Normal file
11
test-requirements.txt
Normal file
@ -0,0 +1,11 @@
|
||||
# The order of packages is significant, because pip processes them in the order
|
||||
# of appearance. Changing the order has an impact on the overall integration
|
||||
# process, which may cause wedges in the gate later.
|
||||
|
||||
# Hacking already pins down pep8, pyflakes and flake8
|
||||
hacking>=0.8.0,<0.9
|
||||
mock>=1.0
|
||||
testtools>=0.9.36,!=1.2.0
|
||||
testrepository>=0.0.18
|
||||
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
|
||||
oslosphinx>=2.2.0 # Apache-2.0
|
34
tox.ini
Normal file
34
tox.ini
Normal file
@ -0,0 +1,34 @@
|
||||
[tox]
|
||||
envlist = py27
|
||||
minversion = 1.6
|
||||
skipsdist = True
|
||||
|
||||
[tox:jenkins]
|
||||
sitepackages = True
|
||||
downloadcache = ~/cache/pip
|
||||
|
||||
[testenv]
|
||||
setenv = VIRTUAL_ENV={envdir}
|
||||
usedevelop = True
|
||||
install_command = pip install -U {opts} {packages}
|
||||
deps =
|
||||
-r{toxinidir}/requirements.txt
|
||||
-r{toxinidir}/test-requirements.txt
|
||||
# https://github.com/stackforge/fuel-ostf/archive/6.0.tar.gz#egg=fuel-ostf==6.0
|
||||
commands =
|
||||
python setup.py testr --slowest
|
||||
whitelist_externals = bash
|
||||
|
||||
[testenv:pep8]
|
||||
commands =
|
||||
flake8
|
||||
|
||||
[testenv:venv]
|
||||
commands = {posargs}
|
||||
|
||||
[flake8]
|
||||
show-source = True
|
||||
ignore = F821,H301,H306,H404
|
||||
builtins = _
|
||||
exclude=.venv,.tox,dist,doc,openstack,*egg,rsdns,tools,etc,build,*.po,*.pot
|
||||
filename=*.py
|
Loading…
x
Reference in New Issue
Block a user