Refactoring of system_test classes
Some design of system_test packages: - move actions to separate package - move core fuctionality to core package Change-Id: I7b12380a687c9cccbd44d79819f842b1b2470cd5 Implemets blueprint template-based-testcases
This commit is contained in:
parent
ba77741899
commit
82b392284a
|
@ -3,17 +3,73 @@
|
|||
System tests
|
||||
************
|
||||
|
||||
Core
|
||||
====
|
||||
|
||||
Repository
|
||||
----------
|
||||
.. automodule:: system_test.core.repository
|
||||
:members:
|
||||
|
||||
Discover
|
||||
--------
|
||||
.. automodule:: system_test.core.discover
|
||||
:members:
|
||||
|
||||
Decorators
|
||||
----------
|
||||
.. automodule:: system_test.core.decorators
|
||||
:members:
|
||||
|
||||
Factory
|
||||
-------
|
||||
.. automodule:: system_test.core.factory
|
||||
:members:
|
||||
|
||||
Config
|
||||
------
|
||||
.. automodule:: system_test.core.config
|
||||
:members:
|
||||
|
||||
Actions
|
||||
=======
|
||||
|
||||
Base actions
|
||||
------------
|
||||
.. automodule:: system_test.actions.base
|
||||
:members:
|
||||
|
||||
Fuelmaster actions
|
||||
------------------
|
||||
.. automodule:: system_test.actions.fuelmaster_actions
|
||||
:members:
|
||||
|
||||
OSTF actions
|
||||
------------
|
||||
.. automodule:: system_test.actions.ostf_actions
|
||||
:members:
|
||||
|
||||
Plugins actions
|
||||
---------------
|
||||
.. automodule:: system_test.actions.plugins_actions
|
||||
:members:
|
||||
|
||||
Strength actions
|
||||
----------------
|
||||
.. automodule:: system_test.actions.strength_actions
|
||||
:members:
|
||||
|
||||
VCenter actions
|
||||
---------------
|
||||
.. automodule:: system_test.actions.vcenter_actions
|
||||
:members:
|
||||
|
||||
General tests
|
||||
=============
|
||||
|
||||
Actions Base
|
||||
------------
|
||||
.. automodule:: system_test.tests.actions_base
|
||||
:members:
|
||||
|
||||
Base actions factory
|
||||
--------------------
|
||||
.. automodule:: system_test.tests.base_actions_factory
|
||||
ActionTest
|
||||
----------
|
||||
.. automodule:: system_test.tests.base
|
||||
:members:
|
||||
|
||||
Case deploy Environment
|
||||
|
@ -56,17 +112,7 @@ Destroy controllers
|
|||
|
||||
Fill root and check pacemaker
|
||||
-----------------------------
|
||||
.. automodule:: system_test.tests.strength.filling_root
|
||||
:members:
|
||||
|
||||
OSTF base actions
|
||||
-----------------
|
||||
.. automodule:: system_test.tests.ostf_base_actions
|
||||
:members:
|
||||
|
||||
Strength Base
|
||||
-------------
|
||||
.. automodule:: system_test.tests.strength.strength_base
|
||||
.. automodule:: system_test.tests.strength.test_filling_root
|
||||
:members:
|
||||
|
||||
Plugin tests
|
||||
|
@ -107,8 +153,3 @@ Decorators
|
|||
----------
|
||||
.. automodule:: system_test.helpers.decorators
|
||||
:members:
|
||||
|
||||
Utils
|
||||
-----
|
||||
.. automodule:: system_test.helpers.utils
|
||||
:members:
|
||||
|
|
|
@ -13,11 +13,12 @@ from system_test import get_groups
|
|||
from system_test import define_custom_groups
|
||||
from system_test import discover_import_tests
|
||||
from system_test import tests_directory
|
||||
from system_test import collect_yamls
|
||||
from system_test import get_path_to_config
|
||||
from system_test import get_list_confignames
|
||||
from system_test import get_basepath
|
||||
|
||||
from system_test.helpers.utils import collect_yamls
|
||||
from system_test.helpers.utils import get_path_to_config
|
||||
from system_test.helpers.utils import get_list_confignames
|
||||
from system_test.helpers.utils import get_basepath
|
||||
from system_test.core.repository import split_group_config
|
||||
|
||||
basedir = get_basepath()
|
||||
|
||||
|
@ -27,7 +28,8 @@ def print_explain(names):
|
|||
if not isinstance(names, list):
|
||||
names = [names]
|
||||
out = []
|
||||
for name in names:
|
||||
for name in [split_group_config(i)[0] if split_group_config(i) else i
|
||||
for i in names]:
|
||||
for i in groups_nums[name]:
|
||||
if hasattr(i, 'home'):
|
||||
out.append((i.home._proboscis_entry_.parent.home, i.home))
|
||||
|
@ -126,7 +128,8 @@ def run(**kwargs):
|
|||
else:
|
||||
register_system_test_cases(groups=[g])
|
||||
groups_to_run.append(g)
|
||||
if not set(groups_to_run) < set(get_groups()):
|
||||
if not set([split_group_config(i)[0] if split_group_config(i) else i
|
||||
for i in groups_to_run]) < set(get_groups()):
|
||||
sys.exit('There are no cases mapped to current group, '
|
||||
'please be sure that you put right test group name.')
|
||||
if explain:
|
||||
|
|
|
@ -11,192 +11,43 @@
|
|||
# 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 re
|
||||
|
||||
from fuelweb_test import logger
|
||||
|
||||
import proboscis.core
|
||||
from proboscis import register
|
||||
from proboscis import factory
|
||||
|
||||
from system_test.core.repository import Repository
|
||||
from system_test.core.config import define_custom_groups
|
||||
from system_test.core.config import tests_directory
|
||||
from system_test.core.factory import ActionsFactory
|
||||
from system_test.core.decorators import testcase
|
||||
from system_test.core.decorators import deferred_decorator
|
||||
from system_test.core.decorators import action
|
||||
from system_test.core.decorators import nested_action
|
||||
from system_test.core.discover import discover_import_tests
|
||||
from system_test.helpers.utils import get_configs
|
||||
from system_test.helpers.decorators import testcase
|
||||
from system_test.core.discover import get_configs
|
||||
from system_test.core.discover import collect_yamls
|
||||
from system_test.core.discover import get_path_to_config
|
||||
from system_test.core.discover import get_list_confignames
|
||||
from system_test.core.discover import get_basepath
|
||||
from system_test.core.repository import Repository
|
||||
from system_test.core.repository import register_system_test_cases
|
||||
from system_test.core.repository import get_groups
|
||||
|
||||
from proboscis.decorators import DEFAULT_REGISTRY
|
||||
|
||||
from system_test.tests import base_actions_factory
|
||||
from system_test.helpers.utils import config_filter
|
||||
|
||||
tests_directory = [
|
||||
'fuelweb_test/tests',
|
||||
'system_test/tests',
|
||||
'gates_tests'
|
||||
]
|
||||
|
||||
__all__ = [
|
||||
Repository,
|
||||
ActionsFactory,
|
||||
discover_import_tests,
|
||||
register_system_test_cases,
|
||||
get_groups,
|
||||
testcase,
|
||||
deferred_decorator,
|
||||
action,
|
||||
nested_action,
|
||||
get_configs,
|
||||
logger]
|
||||
|
||||
|
||||
def cached_add_group(yamls):
|
||||
|
||||
def add(group, systest_group, config_name,
|
||||
validate_config=True):
|
||||
"""Add user friendly group
|
||||
|
||||
:type group_name: str
|
||||
:type systest_group: str
|
||||
:type config_name: str
|
||||
"""
|
||||
# from proboscis.decorators import DEFAULT_REGISTRY
|
||||
if validate_config and config_name not in yamls:
|
||||
raise NameError("Config {} not found".format(config_name))
|
||||
|
||||
register_system_test_cases(groups=[systest_group],
|
||||
configs=[config_name])
|
||||
register(groups=[group],
|
||||
depends_on_groups=[
|
||||
"{systest_group}({config_name})".format(
|
||||
systest_group=systest_group,
|
||||
config_name=config_name)])
|
||||
return add
|
||||
|
||||
|
||||
def define_custom_groups():
|
||||
"""Map user friendly group name to system test groups
|
||||
|
||||
groups - contained user friendly alias
|
||||
depends - contained groups which should be runned
|
||||
"""
|
||||
add_group = cached_add_group(get_configs())
|
||||
add_group(group="system_test.ceph_ha",
|
||||
systest_group="system_test.deploy_and_check_radosgw",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
|
||||
add_group(group="filling_root",
|
||||
systest_group="system_test.failover.filling_root",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
|
||||
add_group(group="system_test.strength",
|
||||
systest_group="system_test.failover.destroy_controllers.first",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
add_group(group="system_test.strength",
|
||||
systest_group="system_test.failover.destroy_controllers.second",
|
||||
config_name="1ctrl_ceph_2ctrl_1comp_1comp_ceph_neutronVLAN")
|
||||
|
||||
add_group(group="fuel_master_migrate",
|
||||
systest_group="system_test.fuel_migration",
|
||||
config_name="1ctrl_1comp_neutronVLAN")
|
||||
add_group(group="fuel_master_migrate",
|
||||
systest_group="system_test.fuel_migration",
|
||||
config_name="1ctrl_1comp_neutronTUN")
|
||||
|
||||
|
||||
def get_groups(only_groups=None, exclude=None):
|
||||
"""Get groups from Proboscis register and count them children"""
|
||||
groups_childs = {}
|
||||
groups = {}
|
||||
|
||||
if only_groups and isinstance(only_groups, list):
|
||||
groups = {g: DEFAULT_REGISTRY.groups[g]
|
||||
for g in DEFAULT_REGISTRY.groups if g in only_groups}
|
||||
groups.update({g: Repository.index[g]
|
||||
for g in Repository.index if g in only_groups})
|
||||
else:
|
||||
groups = DEFAULT_REGISTRY.groups.copy()
|
||||
groups.update({g: Repository.index[g] for g in Repository.index})
|
||||
|
||||
for group_name, group in groups.items():
|
||||
klass_entries = set()
|
||||
entries_in_class = set()
|
||||
|
||||
if (exclude and
|
||||
isinstance(exclude, list) and
|
||||
any([e in group_name for e in exclude])):
|
||||
continue
|
||||
|
||||
if hasattr(group, 'entries'):
|
||||
for entry in group.entries:
|
||||
if isinstance(entry, proboscis.core.TestMethodClassEntry):
|
||||
klass_entries.add(entry)
|
||||
|
||||
for klass in klass_entries:
|
||||
entries_in_class.update(set(klass.children))
|
||||
|
||||
child = set(group.entries) - entries_in_class - klass_entries
|
||||
|
||||
for klass in klass_entries:
|
||||
if (klass.used_by_factory and
|
||||
base_actions_factory.BaseActionsFactory in
|
||||
klass.home.__mro__):
|
||||
child.add(klass)
|
||||
else:
|
||||
child.update(set(klass.children))
|
||||
else:
|
||||
child = [g for g in group
|
||||
if base_actions_factory.BaseActionsFactory in g.__mro__]
|
||||
|
||||
groups_childs[group_name] = child
|
||||
|
||||
return groups_childs
|
||||
|
||||
|
||||
def case_factory(baseclass, configs):
|
||||
"""Return list of instance """
|
||||
# configs = get_configs()
|
||||
return [baseclass.caseclass_factory(g)(c)
|
||||
for g, c in config_filter(configs).items()]
|
||||
|
||||
|
||||
def case_filter(groups=None):
|
||||
"""Create Proboscis factories for selected groups. For all by default"""
|
||||
if groups is None:
|
||||
return set(Repository)
|
||||
|
||||
cases = set()
|
||||
for g in groups:
|
||||
if g in Repository.index:
|
||||
cases.update(Repository.index[g])
|
||||
return cases
|
||||
|
||||
|
||||
def reg_factory(cases, configs):
|
||||
def ret():
|
||||
out = []
|
||||
for c in cases:
|
||||
out.extend(case_factory(c, configs))
|
||||
return out
|
||||
globals()['system_test_factory'] = factory(ret)
|
||||
|
||||
|
||||
def split_group_config(group):
|
||||
m = re.search('([\w\.]*)\((\w*)\)', group)
|
||||
if m:
|
||||
return m.groups()
|
||||
|
||||
|
||||
def register_system_test_cases(groups=None, configs=None):
|
||||
to_remove = []
|
||||
to_add = []
|
||||
for group in groups:
|
||||
g_c = split_group_config(group)
|
||||
if g_c:
|
||||
g, c = g_c
|
||||
to_add.append(g)
|
||||
if configs is None:
|
||||
configs = []
|
||||
configs.append(c)
|
||||
to_remove.append(group)
|
||||
for one in to_remove:
|
||||
groups.remove(one)
|
||||
for one in to_add:
|
||||
groups.append(one)
|
||||
cases = case_filter(groups)
|
||||
configs = config_filter(configs)
|
||||
if cases:
|
||||
reg_factory(cases, configs)
|
||||
logger,
|
||||
define_custom_groups,
|
||||
tests_directory,
|
||||
collect_yamls,
|
||||
get_path_to_config,
|
||||
get_list_confignames,
|
||||
get_basepath,
|
||||
]
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
# Copyright 2016 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 .base import BaseActions
|
||||
from .fuelmaster_actions import FuelMasterActions
|
||||
from .vcenter_actions import VMwareActions
|
||||
from .strength_actions import StrengthActions
|
||||
from .strength_actions import FillRootActions
|
||||
|
||||
|
||||
__all__ = [
|
||||
BaseActions,
|
||||
FuelMasterActions,
|
||||
VMwareActions,
|
||||
StrengthActions,
|
||||
FillRootActions
|
||||
]
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright 2015 Mirantis, Inc.
|
||||
# Copyright 2015-2016 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
|
||||
|
@ -22,17 +22,18 @@ from fuelweb_test.helpers.utils import TimeStat
|
|||
from fuelweb_test import settings as test_settings
|
||||
|
||||
from system_test import logger
|
||||
from system_test.tests import base_actions_factory
|
||||
from system_test.tests.ostf_base_actions import HealthCheckActions
|
||||
from system_test.tests.plugins_actions import PluginsActions
|
||||
from system_test import action
|
||||
from system_test import nested_action
|
||||
from system_test import deferred_decorator
|
||||
|
||||
from system_test.actions.ostf_actions import HealthCheckActions
|
||||
from system_test.actions.plugins_actions import PluginsActions
|
||||
|
||||
from system_test.core.discover import load_yaml
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.helpers.decorators import nested_action
|
||||
from system_test.helpers.utils import load_yaml
|
||||
|
||||
|
||||
class PrepareBase(base_actions_factory.BaseActionsFactory):
|
||||
class PrepareActions(object):
|
||||
"""Base class with prepare actions
|
||||
|
||||
_start_case - runned before test case start
|
||||
|
@ -121,6 +122,7 @@ class PrepareBase(base_actions_factory.BaseActionsFactory):
|
|||
"""Bootstrap slave and make snapshot
|
||||
|
||||
Use slaves parameter from case section
|
||||
|
||||
"""
|
||||
slaves = int(self.full_config['template']['slaves'])
|
||||
snapshot_name = "ready_with_{}_slaves".format(slaves)
|
||||
|
@ -137,6 +139,7 @@ class PrepareBase(base_actions_factory.BaseActionsFactory):
|
|||
"""Revert bootstrapped nodes
|
||||
|
||||
Skip if snapshot with cluster exists
|
||||
|
||||
"""
|
||||
self.check_run(self.env_config['name'])
|
||||
slaves = int(self.full_config['template']['slaves'])
|
||||
|
@ -154,7 +157,7 @@ class PrepareBase(base_actions_factory.BaseActionsFactory):
|
|||
]
|
||||
|
||||
|
||||
class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
||||
class BaseActions(PrepareActions, HealthCheckActions, PluginsActions):
|
||||
"""Basic actions for acceptance cases
|
||||
|
||||
For choosing action order use actions_order variable, set list of actions
|
||||
|
@ -165,21 +168,18 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
add_nodes - add nodes to environment
|
||||
deploy_cluster - deploy en environment
|
||||
network_check - run network check
|
||||
reset_cluster - reset an environment (NotImplemented)
|
||||
delete_cluster - delete en environment (NotImplemented)
|
||||
stop_deploy - stop deploying of environment (NotImplemented)
|
||||
reset_cluster - reset an environment
|
||||
delete_cluster - delete en environment
|
||||
stop_deploy - stop deploying of environment
|
||||
|
||||
"""
|
||||
|
||||
est_duration = None
|
||||
base_group = None
|
||||
actions_order = None
|
||||
|
||||
def __init__(self, config_file=None):
|
||||
super(ActionsBase, self).__init__()
|
||||
self.config_file = config_file
|
||||
self.cluster_id = None
|
||||
self.assigned_slaves = set()
|
||||
self.scale_step = 0
|
||||
cluster_id = None
|
||||
assigned_slaves = set()
|
||||
scale_step = 0
|
||||
|
||||
def _add_node(self, nodes_list):
|
||||
"""Add nodes to Environment"""
|
||||
|
@ -200,6 +200,25 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
name))
|
||||
self.fuel_web.update_nodes(self.cluster_id, nodes)
|
||||
|
||||
def _del_node(self, nodes_list):
|
||||
"""Delete nodes from Environment"""
|
||||
logger.info("Delete nodes from env {}".format(self.cluster_id))
|
||||
nodes = {}
|
||||
|
||||
for node in nodes_list:
|
||||
cluster_nodes = self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
||||
self.cluster_id, node['roles'])
|
||||
for i in xrange(node['count']):
|
||||
dnode = self.fuel_web.get_devops_node_by_nailgun_node(
|
||||
cluster_nodes[i])
|
||||
self.assigned_slaves.remove(dnode.name)
|
||||
|
||||
nodes[dnode.name] = node['roles']
|
||||
logger.info("Delete node {} with role {}".format(
|
||||
dnode.name, node['roles']))
|
||||
|
||||
self.fuel_web.update_nodes(self.cluster_id, nodes, False, True)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def create_env(self):
|
||||
|
@ -208,6 +227,7 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
For configure Environment use environment-config section in config file
|
||||
|
||||
Skip action if we have snapshot with Environment name
|
||||
|
||||
"""
|
||||
self.check_run(self.env_config['name'])
|
||||
|
||||
|
@ -265,6 +285,7 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
Used sub-section nodes in environment-config section
|
||||
|
||||
Skip action if cluster doesn't exist
|
||||
|
||||
"""
|
||||
if self.cluster_id is None:
|
||||
raise SkipTest()
|
||||
|
@ -277,6 +298,7 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
"""Deploy environment
|
||||
|
||||
Skip action if cluster doesn't exist
|
||||
|
||||
"""
|
||||
if self.cluster_id is None:
|
||||
raise SkipTest()
|
||||
|
@ -303,6 +325,7 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
"""Run network checker
|
||||
|
||||
Skip action if cluster doesn't exist
|
||||
|
||||
"""
|
||||
if self.cluster_id is None:
|
||||
raise SkipTest()
|
||||
|
@ -348,9 +371,47 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def scale_node(self):
|
||||
"""Scale node in cluster"""
|
||||
"""Scale node in cluster
|
||||
|
||||
For add nodes with role use scale_nodes in yaml with action add in
|
||||
step::
|
||||
|
||||
scale_nodes:
|
||||
- - roles:
|
||||
- controller
|
||||
count: 2
|
||||
action: add
|
||||
|
||||
For remove nodes with role use scale_nodes in yaml with action delete
|
||||
in step:::
|
||||
|
||||
scale_nodes:
|
||||
- - roles:
|
||||
- controller
|
||||
count: 2
|
||||
action: delete
|
||||
|
||||
Step may contain add and remove action together::
|
||||
|
||||
scale_nodes:
|
||||
- - roles:
|
||||
- compute
|
||||
count: 2
|
||||
action: add
|
||||
- - roles:
|
||||
- ceph-osd
|
||||
count: 1
|
||||
action: delete
|
||||
|
||||
"""
|
||||
step_config = self.env_config['scale_nodes'][self.scale_step]
|
||||
self._add_node(step_config)
|
||||
for node in step_config:
|
||||
if node['action'] == 'add':
|
||||
self._add_node([node])
|
||||
elif node['action'] == 'delete':
|
||||
self._del_node([node])
|
||||
else:
|
||||
logger.error("Unknow scale action: {}".format(node['action']))
|
||||
self.scale_step += 1
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
|
@ -366,18 +427,3 @@ class ActionsBase(PrepareBase, HealthCheckActions, PluginsActions):
|
|||
"""Delete environment"""
|
||||
cluster_id = self.cluster_id
|
||||
self.fuel_web.delete_env_wait(cluster_id)
|
||||
|
||||
|
||||
class FuelMasterActions(base_actions_factory.BaseActionsFactory):
|
||||
"""Actions specific only to Fuel Master node
|
||||
|
||||
_action_check_containers - check that docker containers are up
|
||||
and running
|
||||
"""
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def check_containers(self):
|
||||
"""Check that containers are up and running"""
|
||||
logger.info("Check containers")
|
||||
self.env.docker_actions.wait_for_ready_containers(timeout=60 * 30)
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2015-2016 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 system_test import action
|
||||
from system_test import deferred_decorator
|
||||
from system_test import logger
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
|
||||
|
||||
class FuelMasterActions(object):
|
||||
"""Actions specific only to Fuel Master node
|
||||
|
||||
check_containers - check that docker containers are up
|
||||
and running
|
||||
"""
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def check_containers(self):
|
||||
"""Check that containers are up and running"""
|
||||
logger.info("Check containers")
|
||||
self.env.docker_actions.wait_for_ready_containers(timeout=60 * 30)
|
|
@ -14,16 +14,18 @@
|
|||
|
||||
from proboscis import SkipTest
|
||||
|
||||
from system_test import deferred_decorator
|
||||
from system_test import action
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.tests import base_actions_factory
|
||||
|
||||
|
||||
class HealthCheckActions(base_actions_factory.BaseActionsFactory):
|
||||
class HealthCheckActions(object):
|
||||
"""Basic actions for OSTF tests
|
||||
|
||||
health_check - run sanity and smoke OSTF tests
|
||||
health_check_sanity_smoke_ha - run sanity, smoke and ha OSTF tests
|
||||
health_check_ha - run ha OSTF tests
|
||||
"""
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
|
@ -17,15 +17,16 @@ import os
|
|||
from proboscis.asserts import assert_true, assert_equal
|
||||
|
||||
from fuelweb_test.helpers import checkers
|
||||
|
||||
from system_test import logger
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test import action
|
||||
from system_test import deferred_decorator
|
||||
from system_test import nested_action
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import nested_action
|
||||
from system_test.tests import base_actions_factory
|
||||
|
||||
|
||||
class PluginsActions(base_actions_factory.BaseActionsFactory):
|
||||
class PluginsActions(object):
|
||||
|
||||
plugin_name = None
|
||||
plugin_path = None
|
|
@ -24,21 +24,17 @@ from fuelweb_test.helpers.pacemaker import get_pacemaker_nodes_attributes
|
|||
from fuelweb_test.helpers.pacemaker import get_pcs_nodes
|
||||
from fuelweb_test.helpers.pacemaker import parse_pcs_status_xml
|
||||
|
||||
from system_test.tests import actions_base
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
|
||||
from system_test import logger
|
||||
from system_test import deferred_decorator
|
||||
from system_test import action
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
|
||||
|
||||
class StrengthBaseActions(actions_base.ActionsBase):
|
||||
class StrengthActions(object):
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(StrengthBaseActions, self).__init__(config)
|
||||
self.destroyed_devops_nodes = []
|
||||
self.ostf_tests_should_failed = 0
|
||||
self.os_service_should_failed = 0
|
||||
destroyed_devops_nodes = []
|
||||
ostf_tests_should_failed = 0
|
||||
os_service_should_failed = 0
|
||||
|
||||
def _destroy_controller(self, devops_node_name):
|
||||
logger.info("Suspend {} node".format(devops_node_name))
|
||||
|
@ -110,22 +106,20 @@ class StrengthBaseActions(actions_base.ActionsBase):
|
|||
self.destroyed_devops_nodes)
|
||||
|
||||
|
||||
class FillRootBaseActions(actions_base.ActionsBase):
|
||||
class FillRootActions(object):
|
||||
|
||||
def __init__(self, config=None):
|
||||
super(FillRootBaseActions, self).__init__(config)
|
||||
self.ostf_tests_should_failed = 0
|
||||
self.primary_controller = None
|
||||
self.primary_controller_fqdn = None
|
||||
self.primary_controller_space_on_root = 0
|
||||
self.disk_monitor_limit = 512
|
||||
self.rabbit_disk_free_limit = 5
|
||||
self.pacemaker_restart_timeout = 600
|
||||
self.pcs_check_timeout = 300
|
||||
self.primary_controller_space_to_filled = 0
|
||||
self.pcs_status = None
|
||||
self.slave_nodes_fqdn = None
|
||||
self.slave_node_running_resources = None
|
||||
ostf_tests_should_failed = 0
|
||||
primary_controller = None
|
||||
primary_controller_fqdn = None
|
||||
primary_controller_space_on_root = 0
|
||||
disk_monitor_limit = 512
|
||||
rabbit_disk_free_limit = 5
|
||||
pacemaker_restart_timeout = 600
|
||||
pcs_check_timeout = 300
|
||||
primary_controller_space_to_filled = 0
|
||||
pcs_status = None
|
||||
slave_nodes_fqdn = None
|
||||
slave_node_running_resources = None
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
|
@ -0,0 +1,149 @@
|
|||
# Copyright 2016 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 proboscis.asserts import assert_true
|
||||
from system_test import logger
|
||||
|
||||
from system_test import deferred_decorator
|
||||
from system_test import action
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
|
||||
|
||||
class VMwareActions(object):
|
||||
"""VMware vCenter/DVS related actions"""
|
||||
|
||||
plugin_version = None
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def enable_plugin(self):
|
||||
"""Enable plugin for Fuel"""
|
||||
assert_true(self.plugin_name, "plugin_name is not specified")
|
||||
|
||||
msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
|
||||
assert_true(
|
||||
self.fuel_web.check_plugin_exists(
|
||||
self.cluster_id,
|
||||
self.plugin_name),
|
||||
msg)
|
||||
|
||||
plugin_data = self.fuel_web.get_plugin_data(self.cluster_id,
|
||||
self.plugin_name,
|
||||
self.plugin_version)
|
||||
options = {'metadata/enabled': True,
|
||||
'metadata/chosen_id': plugin_data['metadata']['plugin_id']}
|
||||
self.fuel_web.update_plugin_data(self.cluster_id,
|
||||
self.plugin_name, options)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def configure_dvs_plugin(self):
|
||||
"""Configure DVS plugin"""
|
||||
|
||||
msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
|
||||
assert_true(
|
||||
self.fuel_web.check_plugin_exists(
|
||||
self.cluster_id,
|
||||
self.plugin_name),
|
||||
msg)
|
||||
|
||||
options = {'vmware_dvs_net_maps/value': self.full_config[
|
||||
'template']['cluster_template']['settings']['vmware_dvs'][
|
||||
'dvswitch_name']}
|
||||
self.fuel_web.update_plugin_settings(
|
||||
self.cluster_id, self.plugin_name, self.plugin_version, options)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def configure_vcenter(self):
|
||||
"""Configure vCenter settings"""
|
||||
|
||||
vmware_vcenter = self.env_settings['vmware_vcenter']
|
||||
|
||||
vcenter_value = {
|
||||
"glance": {"vcenter_username": "",
|
||||
"datacenter": "",
|
||||
"vcenter_host": "",
|
||||
"vcenter_password": "",
|
||||
"datastore": ""
|
||||
},
|
||||
"availability_zones": [
|
||||
{"vcenter_username": vmware_vcenter['settings']['user'],
|
||||
"nova_computes": [],
|
||||
"vcenter_host": vmware_vcenter['settings']['host'],
|
||||
"az_name": vmware_vcenter['settings']['az'],
|
||||
"vcenter_password": vmware_vcenter['settings']['pwd']
|
||||
}]
|
||||
}
|
||||
|
||||
clusters = vmware_vcenter['nova-compute']
|
||||
nodes = self.fuel_web.client.list_cluster_nodes(self.cluster_id)
|
||||
roles = ['compute-vmware']
|
||||
comp_vmware_nodes = [n for n in nodes if set(roles) <=
|
||||
set(n['pending_roles'])]
|
||||
|
||||
for cluster in clusters:
|
||||
cluster_name = cluster['cluster']
|
||||
srv_name = cluster['srv_name']
|
||||
datastore = cluster['datastore']
|
||||
if cluster['target_node'] == 'compute-vmware':
|
||||
node = comp_vmware_nodes.pop()
|
||||
target_node = node['hostname']
|
||||
else:
|
||||
target_node = cluster['target_node']
|
||||
|
||||
vcenter_value["availability_zones"][0]["nova_computes"].append(
|
||||
{"vsphere_cluster": cluster_name,
|
||||
"service_name": srv_name,
|
||||
"datastore_regex": datastore,
|
||||
"target_node": {
|
||||
"current": {"id": target_node,
|
||||
"label": target_node},
|
||||
"options": [{"id": target_node,
|
||||
"label": target_node}, ]},
|
||||
}
|
||||
)
|
||||
|
||||
if vmware_vcenter['glance']['enable']:
|
||||
attributes = self.fuel_web.client.get_cluster_attributes(
|
||||
self.cluster_id)
|
||||
attributes['editable']['storage']['images_vcenter']['value'] =\
|
||||
vmware_vcenter['glance']['enable']
|
||||
self.fuel_web.client.update_cluster_attributes(self.cluster_id,
|
||||
attributes)
|
||||
|
||||
vcenter_value["glance"]["vcenter_host"] = vmware_vcenter[
|
||||
'glance']['host']
|
||||
vcenter_value["glance"]["vcenter_username"] = vmware_vcenter[
|
||||
'glance']['user']
|
||||
vcenter_value["glance"]["vcenter_password"] = vmware_vcenter[
|
||||
'glance']['pwd']
|
||||
vcenter_value["glance"]["datacenter"] = vmware_vcenter[
|
||||
'glance']['datacenter']
|
||||
vcenter_value["glance"]["datastore"] = vmware_vcenter[
|
||||
'glance']['datastore']
|
||||
|
||||
logger.info('Configuring vCenter...')
|
||||
|
||||
vmware_attr = \
|
||||
self.fuel_web.client.get_cluster_vmware_attributes(self.cluster_id)
|
||||
vcenter_data = vmware_attr['editable']
|
||||
vcenter_data['value'] = vcenter_value
|
||||
logger.debug("Try to update cluster with next "
|
||||
"vmware_attributes {0}".format(vmware_attr))
|
||||
self.fuel_web.client.update_cluster_vmware_attributes(self.cluster_id,
|
||||
vmware_attr)
|
||||
|
||||
logger.debug("Attributes of cluster have been updated")
|
|
@ -0,0 +1,23 @@
|
|||
# Copyright 2016 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 .factory import ActionsFactory
|
||||
from .repository import Repository
|
||||
|
||||
|
||||
__all__ = [
|
||||
ActionsFactory,
|
||||
Repository,
|
||||
]
|
|
@ -0,0 +1,80 @@
|
|||
# Copyright 2016 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 proboscis import register
|
||||
|
||||
from system_test.core.discover import get_configs
|
||||
from system_test.core.repository import register_system_test_cases
|
||||
|
||||
tests_directory = [
|
||||
'fuelweb_test/tests',
|
||||
'system_test/tests',
|
||||
'gates_tests'
|
||||
]
|
||||
|
||||
|
||||
def cached_add_group(yamls):
|
||||
|
||||
def add(group, systest_group, config_name,
|
||||
validate_config=True):
|
||||
"""Add user friendly group
|
||||
|
||||
:type group_name: str
|
||||
:type systest_group: str
|
||||
:type config_name: str
|
||||
|
||||
"""
|
||||
if validate_config and config_name not in yamls:
|
||||
raise NameError("Config {} not found".format(config_name))
|
||||
|
||||
register_system_test_cases(groups=[systest_group],
|
||||
configs=[config_name])
|
||||
register(groups=[group],
|
||||
depends_on_groups=[
|
||||
"{systest_group}({config_name})".format(
|
||||
systest_group=systest_group,
|
||||
config_name=config_name)])
|
||||
return add
|
||||
|
||||
|
||||
def define_custom_groups():
|
||||
"""Map user friendly group name to system test groups
|
||||
|
||||
groups - contained user friendly alias
|
||||
depends - contained groups which should be runned
|
||||
|
||||
"""
|
||||
|
||||
add_group = cached_add_group(get_configs())
|
||||
add_group(group="system_test.ceph_ha",
|
||||
systest_group="system_test.deploy_and_check_radosgw",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
|
||||
add_group(group="filling_root",
|
||||
systest_group="system_test.failover.filling_root",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
|
||||
add_group(group="system_test.strength",
|
||||
systest_group="system_test.failover.destroy_controllers.first",
|
||||
config_name="ceph_all_on_neutron_vlan")
|
||||
add_group(group="system_test.strength",
|
||||
systest_group="system_test.failover.destroy_controllers.second",
|
||||
config_name="1ctrl_ceph_2ctrl_1comp_1comp_ceph_neutronVLAN")
|
||||
|
||||
add_group(group="fuel_master_migrate",
|
||||
systest_group="system_test.fuel_migration",
|
||||
config_name="1ctrl_1comp_neutronVLAN")
|
||||
add_group(group="fuel_master_migrate",
|
||||
systest_group="system_test.fuel_migration",
|
||||
config_name="1ctrl_1comp_neutronTUN")
|
|
@ -0,0 +1,50 @@
|
|||
# Copyright 2016 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 inspect
|
||||
import collections
|
||||
|
||||
from system_test.core.repository import Repository
|
||||
|
||||
|
||||
def testcase(groups):
|
||||
"""Use this decorator for mark a test case class"""
|
||||
def testcase_decorator(cls):
|
||||
if not inspect.isclass(cls):
|
||||
raise TypeError("Decorator @testcase should used only "
|
||||
"with classes")
|
||||
if not isinstance(groups, collections.Sequence):
|
||||
raise TypeError("Use list for groups")
|
||||
cls.get_actions_order()
|
||||
setattr(cls, '_base_groups', groups)
|
||||
Repository.add(cls)
|
||||
return cls
|
||||
return testcase_decorator
|
||||
|
||||
|
||||
def action(method):
|
||||
setattr(method, '_action_method_', True)
|
||||
return method
|
||||
|
||||
|
||||
def nested_action(method):
|
||||
setattr(method, '_nested_action_method_', True)
|
||||
return staticmethod(method)
|
||||
|
||||
|
||||
def deferred_decorator(decorator_list):
|
||||
def real_decorator(func):
|
||||
setattr(func, '_deferred_decorator_', decorator_list)
|
||||
return func
|
||||
return real_decorator
|
|
@ -13,6 +13,115 @@
|
|||
# under the License.
|
||||
|
||||
import os.path
|
||||
import yaml
|
||||
|
||||
|
||||
def get_basepath():
|
||||
import system_test
|
||||
return os.path.join(
|
||||
os.path.dirname(os.path.dirname(system_test.__file__)))
|
||||
|
||||
|
||||
def get_list_confignames(filelist):
|
||||
"""Get list of config name from file list"""
|
||||
return map(get_configname, filelist)
|
||||
|
||||
|
||||
def get_configname(path):
|
||||
"""Get config name from path to yaml file"""
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
|
||||
def get_path_to_config():
|
||||
"""Find path to directory with config files"""
|
||||
import system_test
|
||||
return os.path.join(os.path.dirname(system_test.__file__),
|
||||
'tests_templates/tests_configs')
|
||||
|
||||
|
||||
def get_path_to_template():
|
||||
"""Find path to directory with templates files"""
|
||||
import system_test
|
||||
return os.path.join(os.path.dirname(system_test.__file__),
|
||||
'tests_templates')
|
||||
|
||||
|
||||
def collect_yamls(path):
|
||||
"""Walk through config directory and find all yaml files"""
|
||||
ret = []
|
||||
for r, d, f in os.walk(path):
|
||||
for one in f:
|
||||
if os.path.splitext(one)[1] in ('.yaml', '.yml'):
|
||||
ret.append(os.path.join(r, one))
|
||||
return ret
|
||||
|
||||
|
||||
def load_yaml(path):
|
||||
"""Load yaml file from path"""
|
||||
def yaml_include(loader, node):
|
||||
file_name = os.path.join(get_path_to_template(), node.value)
|
||||
if not os.path.isfile(file_name):
|
||||
raise ValueError(
|
||||
"Cannot load the template {0} : include file {1} "
|
||||
"doesn't exist.".format(path, file_name))
|
||||
return yaml.load(open(file_name))
|
||||
|
||||
def yaml_get_env_variable(loader, node):
|
||||
if not node.value.strip():
|
||||
raise ValueError("Environment variable is required after {tag} in "
|
||||
"{filename}".format(tag=node.tag,
|
||||
filename=loader.name))
|
||||
node_value = node.value.split(',', 1)
|
||||
# Get the name of environment variable
|
||||
env_variable = node_value[0].strip()
|
||||
|
||||
# Get the default value for environment variable if it exists in config
|
||||
if len(node_value) > 1:
|
||||
default_val = node_value[1].strip()
|
||||
else:
|
||||
default_val = None
|
||||
|
||||
value = os.environ.get(env_variable, default_val)
|
||||
if value is None:
|
||||
raise ValueError("Environment variable {var} is not set from shell"
|
||||
" environment! No default value provided in file "
|
||||
"{filename}".format(var=env_variable,
|
||||
filename=loader.name))
|
||||
|
||||
return yaml.load(value)
|
||||
|
||||
yaml.add_constructor("!include", yaml_include)
|
||||
yaml.add_constructor("!os_env", yaml_get_env_variable)
|
||||
|
||||
return yaml.load(open(path))
|
||||
|
||||
|
||||
def find_duplicates(yamls):
|
||||
dup = {}
|
||||
for one in yamls:
|
||||
name = os.path.basename(one)
|
||||
if name in dup:
|
||||
dup[name].append(one)
|
||||
else:
|
||||
dup[name] = [one]
|
||||
return {k: v for k, v in dup.items() if len(v) > 1}
|
||||
|
||||
|
||||
def get_configs():
|
||||
"""Return list of dict environment configurations"""
|
||||
yamls = collect_yamls(get_path_to_config())
|
||||
dup = find_duplicates(yamls)
|
||||
if dup:
|
||||
raise NameError(
|
||||
"Found duplicate files in templates. "
|
||||
"Name of template should be unique. Errors: {}".format(dup))
|
||||
return {get_configname(y): y for y in yamls}
|
||||
|
||||
|
||||
def config_filter(configs=None):
|
||||
if configs is None:
|
||||
return get_configs()
|
||||
return {k: v for k, v in get_configs().items() if k in configs}
|
||||
|
||||
|
||||
def discover_test_files(basedir, dirs):
|
||||
|
|
|
@ -13,15 +13,14 @@
|
|||
# under the License.
|
||||
|
||||
import functools
|
||||
import types
|
||||
|
||||
from proboscis import after_class
|
||||
from proboscis import before_class
|
||||
from proboscis import test
|
||||
|
||||
from fuelweb_test.helpers.utils import TimeStat
|
||||
from fuelweb_test.tests import base_test_case
|
||||
|
||||
from system_test.helpers import utils
|
||||
from system_test import logger
|
||||
|
||||
|
||||
|
@ -45,7 +44,23 @@ def step_start_stop(func):
|
|||
return wrapper
|
||||
|
||||
|
||||
class BaseActionsFactory(base_test_case.TestBasic):
|
||||
def copy_func(f, name=None):
|
||||
"""
|
||||
:param f:
|
||||
:param name:
|
||||
:return: a function with same code, globals, defaults, closure,
|
||||
and name (or provide a new name)
|
||||
|
||||
"""
|
||||
|
||||
fn = types.FunctionType(f.__code__, f.__globals__, name or f.__name__,
|
||||
f.__defaults__, f.__closure__)
|
||||
# in case f was given attrs (note this dict is a shallow copy):
|
||||
fn.__dict__.update(f.__dict__)
|
||||
return fn
|
||||
|
||||
|
||||
class ActionsFactory(object):
|
||||
|
||||
@classmethod
|
||||
def get_actions(cls):
|
||||
|
@ -66,11 +81,11 @@ class BaseActionsFactory(base_test_case.TestBasic):
|
|||
for action in cls.actions_order:
|
||||
try:
|
||||
action_method = actions_method[action]
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
import inspect
|
||||
source = inspect.getsourcelines(inspect.getmodule(cls))[0]
|
||||
counted_data = [n for n in enumerate(source)]
|
||||
line_num = [n for (n, l) in counted_data if 'ddd' in l][0]
|
||||
line_num = [n for (n, l) in counted_data if str(e) in l][0]
|
||||
cutted = counted_data[line_num - 4:line_num + 4]
|
||||
cutted = [(n, l[:-1] + " " * 20 + "<====\n"
|
||||
if n == line_num else l)
|
||||
|
@ -114,7 +129,7 @@ class BaseActionsFactory(base_test_case.TestBasic):
|
|||
step,
|
||||
n_action)
|
||||
|
||||
method = utils.copy_func(action['method'], step_method_name)
|
||||
method = copy_func(action['method'], step_method_name)
|
||||
_step_name = getattr(action['method'],
|
||||
"__doc__").splitlines()[0]
|
||||
setattr(method, "_step_name", "Step {:03d}. {}".format(step,
|
||||
|
@ -150,14 +165,14 @@ class BaseActionsFactory(base_test_case.TestBasic):
|
|||
depends_on=depends)
|
||||
|
||||
# Create before case methods, start case and setup
|
||||
start_method = utils.copy_func(
|
||||
start_method = copy_func(
|
||||
getattr(cls, "_start_case"),
|
||||
"{}.StartCase".format(class_name))
|
||||
test_steps["{}.StartCase".format(class_name)] = before_class(
|
||||
start_method)
|
||||
|
||||
if hasattr(cls, 'case_setup'):
|
||||
setup_method = utils.copy_func(
|
||||
setup_method = copy_func(
|
||||
getattr(cls, "case_setup"),
|
||||
"{}.CaseSetup".format(class_name))
|
||||
setattr(setup_method, "_step_name", "CaseSetup")
|
||||
|
@ -165,7 +180,7 @@ class BaseActionsFactory(base_test_case.TestBasic):
|
|||
step_start_stop(setup_method), runs_after=[start_method])
|
||||
|
||||
if hasattr(cls, 'case_teardown'):
|
||||
teardown_method = utils.copy_func(
|
||||
teardown_method = copy_func(
|
||||
getattr(cls, "case_teardown"),
|
||||
"{}.CaseTeardown".format(class_name))
|
||||
setattr(teardown_method, "_step_name", "CaseTeardown")
|
||||
|
@ -175,7 +190,7 @@ class BaseActionsFactory(base_test_case.TestBasic):
|
|||
teardown_method = None
|
||||
|
||||
# Create case methods, teardown and finish case
|
||||
finish_method = utils.copy_func(
|
||||
finish_method = copy_func(
|
||||
getattr(cls, "_finish_case"),
|
||||
"{}.FinishCase".format(class_name))
|
||||
test_steps["{}.FinishCase".format(class_name)] = after_class(
|
|
@ -14,6 +14,15 @@
|
|||
|
||||
from fuelweb_test.helpers import metaclasses
|
||||
|
||||
import re
|
||||
|
||||
import proboscis.core
|
||||
from proboscis import factory
|
||||
from proboscis.decorators import DEFAULT_REGISTRY
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.core.discover import config_filter
|
||||
|
||||
|
||||
class TestCaseRepository(set):
|
||||
|
||||
|
@ -72,5 +81,108 @@ class TestCaseRepository(set):
|
|||
raise AttributeError("'TestCaseRepository' object has no attribute "
|
||||
" 'update'")
|
||||
|
||||
|
||||
Repository = TestCaseRepository()
|
||||
|
||||
|
||||
def get_groups(only_groups=None, exclude=None):
|
||||
"""Get groups from Proboscis register and count them children"""
|
||||
groups_childs = {}
|
||||
groups = {}
|
||||
|
||||
if only_groups and isinstance(only_groups, list):
|
||||
groups = {g: DEFAULT_REGISTRY.groups[g]
|
||||
for g in DEFAULT_REGISTRY.groups if g in only_groups}
|
||||
groups.update({g: Repository.index[g]
|
||||
for g in Repository.index if g in only_groups})
|
||||
else:
|
||||
groups = DEFAULT_REGISTRY.groups.copy()
|
||||
groups.update({g: Repository.index[g] for g in Repository.index})
|
||||
|
||||
for group_name, group in groups.items():
|
||||
klass_entries = set()
|
||||
entries_in_class = set()
|
||||
|
||||
if (exclude and
|
||||
isinstance(exclude, list) and
|
||||
any([e in group_name for e in exclude])):
|
||||
continue
|
||||
|
||||
if hasattr(group, 'entries'):
|
||||
for entry in group.entries:
|
||||
if isinstance(entry, proboscis.core.TestMethodClassEntry):
|
||||
klass_entries.add(entry)
|
||||
|
||||
for klass in klass_entries:
|
||||
entries_in_class.update(set(klass.children))
|
||||
|
||||
child = set(group.entries) - entries_in_class - klass_entries
|
||||
|
||||
for klass in klass_entries:
|
||||
if (klass.used_by_factory and
|
||||
ActionTest in
|
||||
klass.home.__mro__):
|
||||
child.add(klass)
|
||||
else:
|
||||
child.update(set(klass.children))
|
||||
else:
|
||||
child = [g for g in group
|
||||
if ActionTest in g.__mro__]
|
||||
|
||||
groups_childs[group_name] = child
|
||||
|
||||
return groups_childs
|
||||
|
||||
|
||||
def case_filter(groups=None):
|
||||
"""Create Proboscis factories for selected groups. For all by default"""
|
||||
if groups is None:
|
||||
return set(Repository)
|
||||
|
||||
cases = set()
|
||||
for g in groups:
|
||||
if g in Repository.index:
|
||||
cases.update(Repository.index[g])
|
||||
return cases
|
||||
|
||||
|
||||
def case_factory(baseclass, configs):
|
||||
"""Return list of instance """
|
||||
return [baseclass.caseclass_factory(g)(c)
|
||||
for g, c in config_filter(configs).items()]
|
||||
|
||||
|
||||
def reg_factory(cases, configs):
|
||||
def ret():
|
||||
out = []
|
||||
for c in cases:
|
||||
out.extend(case_factory(c, configs))
|
||||
return out
|
||||
globals()['system_test_factory'] = factory(ret)
|
||||
|
||||
|
||||
def split_group_config(group):
|
||||
m = re.search('([\w\.]*)\((\w*)\)', group)
|
||||
if m:
|
||||
return m.groups()
|
||||
|
||||
|
||||
def register_system_test_cases(groups=None, configs=None):
|
||||
to_remove = []
|
||||
to_add = []
|
||||
for group in groups:
|
||||
g_c = split_group_config(group)
|
||||
if g_c:
|
||||
g, c = g_c
|
||||
to_add.append(g)
|
||||
if configs is None:
|
||||
configs = []
|
||||
configs.append(c)
|
||||
to_remove.append(group)
|
||||
for one in to_remove:
|
||||
groups.remove(one)
|
||||
for one in to_add:
|
||||
groups.append(one)
|
||||
cases = case_filter(groups)
|
||||
configs = config_filter(configs)
|
||||
if cases:
|
||||
reg_factory(cases, configs)
|
||||
|
|
|
@ -15,35 +15,15 @@
|
|||
import functools
|
||||
import traceback
|
||||
import hashlib
|
||||
import inspect
|
||||
import collections
|
||||
|
||||
from proboscis import SkipTest
|
||||
|
||||
from fuelweb_test.helpers.utils import pull_out_logs_via_ssh
|
||||
from fuelweb_test.helpers.decorators import create_diagnostic_snapshot
|
||||
|
||||
from system_test import Repository
|
||||
from system_test import logger
|
||||
|
||||
|
||||
def deferred_decorator(decorator_list):
|
||||
def real_decorator(func):
|
||||
setattr(func, '_deferred_decorator_', decorator_list)
|
||||
return func
|
||||
return real_decorator
|
||||
|
||||
|
||||
def action(method):
|
||||
setattr(method, '_action_method_', True)
|
||||
return method
|
||||
|
||||
|
||||
def nested_action(method):
|
||||
setattr(method, '_nested_action_method_', True)
|
||||
return staticmethod(method)
|
||||
|
||||
|
||||
def make_snapshot_if_step_fail(func):
|
||||
"""Generate diagnostic snapshot if step fail.
|
||||
|
||||
|
@ -102,18 +82,3 @@ def make_snapshot_if_step_fail(func):
|
|||
raise test_exception
|
||||
return result
|
||||
return wrapper
|
||||
|
||||
|
||||
def testcase(groups):
|
||||
"""Use this decorator for mark a test case class"""
|
||||
def testcase_decorator(cls):
|
||||
if not inspect.isclass(cls):
|
||||
raise TypeError("Decorator @testcase should used only "
|
||||
"with classes")
|
||||
if not isinstance(groups, collections.Sequence):
|
||||
raise TypeError("Use list for groups")
|
||||
cls.get_actions_order()
|
||||
setattr(cls, '_base_groups', groups)
|
||||
Repository.add(cls)
|
||||
return cls
|
||||
return testcase_decorator
|
||||
|
|
|
@ -1,141 +0,0 @@
|
|||
# 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 yaml
|
||||
import os
|
||||
import types
|
||||
|
||||
|
||||
def copy_func(f, name=None):
|
||||
"""
|
||||
:param f:
|
||||
:param name:
|
||||
:return: a function with same code, globals, defaults, closure,
|
||||
and name (or provide a new name)
|
||||
|
||||
"""
|
||||
|
||||
fn = types.FunctionType(f.__code__, f.__globals__, name or f.__name__,
|
||||
f.__defaults__, f.__closure__)
|
||||
# in case f was given attrs (note this dict is a shallow copy):
|
||||
fn.__dict__.update(f.__dict__)
|
||||
return fn
|
||||
|
||||
|
||||
def get_basepath():
|
||||
import system_test
|
||||
return os.path.join(
|
||||
os.path.dirname(os.path.dirname(system_test.__file__)))
|
||||
|
||||
|
||||
def get_list_confignames(filelist):
|
||||
"""Get list of config name from file list"""
|
||||
return map(get_configname, filelist)
|
||||
|
||||
|
||||
def get_configname(path):
|
||||
"""Get config name from path to yaml file"""
|
||||
return os.path.splitext(os.path.basename(path))[0]
|
||||
|
||||
|
||||
def get_path_to_config():
|
||||
"""Find path to directory with config files"""
|
||||
import system_test
|
||||
return os.path.join(os.path.dirname(system_test.__file__),
|
||||
'tests_templates/tests_configs')
|
||||
|
||||
|
||||
def get_path_to_template():
|
||||
"""Find path to directory with templates files"""
|
||||
import system_test
|
||||
return os.path.join(os.path.dirname(system_test.__file__),
|
||||
'tests_templates')
|
||||
|
||||
|
||||
def collect_yamls(path):
|
||||
"""Walk through config directory and find all yaml files"""
|
||||
ret = []
|
||||
for r, d, f in os.walk(path):
|
||||
for one in f:
|
||||
if os.path.splitext(one)[1] in ('.yaml', '.yml'):
|
||||
ret.append(os.path.join(r, one))
|
||||
return ret
|
||||
|
||||
|
||||
def load_yaml(path):
|
||||
"""Load yaml file from path"""
|
||||
def yaml_include(loader, node):
|
||||
file_name = os.path.join(get_path_to_template(), node.value)
|
||||
if not os.path.isfile(file_name):
|
||||
raise ValueError(
|
||||
"Cannot load the template {0} : include file {1} "
|
||||
"doesn't exist.".format(path, file_name))
|
||||
return yaml.load(open(file_name))
|
||||
|
||||
def yaml_get_env_variable(loader, node):
|
||||
if not node.value.strip():
|
||||
raise ValueError("Environment variable is required after {tag} in "
|
||||
"{filename}".format(tag=node.tag,
|
||||
filename=loader.name))
|
||||
node_value = node.value.split(',', 1)
|
||||
# Get the name of environment variable
|
||||
env_variable = node_value[0].strip()
|
||||
|
||||
# Get the default value for environment variable if it exists in config
|
||||
if len(node_value) > 1:
|
||||
default_val = node_value[1].strip()
|
||||
else:
|
||||
default_val = None
|
||||
|
||||
value = os.environ.get(env_variable, default_val)
|
||||
if value is None:
|
||||
raise ValueError("Environment variable {var} is not set from shell"
|
||||
" environment! No default value provided in file "
|
||||
"{filename}".format(var=env_variable,
|
||||
filename=loader.name))
|
||||
|
||||
return yaml.load(value)
|
||||
|
||||
yaml.add_constructor("!include", yaml_include)
|
||||
yaml.add_constructor("!os_env", yaml_get_env_variable)
|
||||
|
||||
return yaml.load(open(path))
|
||||
|
||||
|
||||
def find_duplicates(yamls):
|
||||
dup = {}
|
||||
for one in yamls:
|
||||
name = os.path.basename(one)
|
||||
if name in dup:
|
||||
dup[name].append(one)
|
||||
else:
|
||||
dup[name] = [one]
|
||||
return {k: v for k, v in dup.items() if len(v) > 1}
|
||||
|
||||
|
||||
def get_configs():
|
||||
"""Return list of dict environment configurations"""
|
||||
yamls = collect_yamls(get_path_to_config())
|
||||
dup = find_duplicates(yamls)
|
||||
if dup:
|
||||
raise NameError(
|
||||
"Found duplicate files in templates. "
|
||||
"Name of template should be unique. Errors: {}".format(dup))
|
||||
return {get_configname(y): y for y in yamls}
|
||||
|
||||
|
||||
def config_filter(configs=None):
|
||||
if configs is None:
|
||||
return get_configs()
|
||||
return {k: v for k, v in get_configs().items() if k in configs}
|
|
@ -0,0 +1,20 @@
|
|||
# Copyright 2016 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 .base import ActionTest
|
||||
|
||||
|
||||
__all__ = [
|
||||
ActionTest
|
||||
]
|
|
@ -0,0 +1,24 @@
|
|||
# Copyright 2016 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 fuelweb_test.tests import base_test_case
|
||||
from system_test.core import ActionsFactory
|
||||
|
||||
|
||||
class ActionTest(base_test_case.TestBasic, ActionsFactory):
|
||||
"""ActionTest is TestBasic wraper for system tests"""
|
||||
|
||||
def __init__(self, config_file=None):
|
||||
super(ActionTest, self).__init__()
|
||||
self.config_file = config_file
|
|
@ -12,16 +12,19 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from fuelweb_test.settings import EXAMPLE_PLUGIN_PATH
|
||||
from system_test.tests.actions_base import ActionsBase
|
||||
|
||||
from system_test import testcase
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.plugins',
|
||||
'system_test.plugins.example_plugin',
|
||||
'system_test.plugins.example_plugin.simple'])
|
||||
class DeployWithPluginExample(ActionsBase):
|
||||
class DeployWithPluginExample(ActionTest, BaseActions):
|
||||
"""Deploy cluster with one controller and example plugin
|
||||
|
||||
Scenario:
|
||||
|
@ -59,7 +62,7 @@ class DeployWithPluginExample(ActionsBase):
|
|||
'system_test.plugins',
|
||||
'system_test.plugins.example_plugin',
|
||||
'system_test.plugins.example_plugin.simple_scale'])
|
||||
class DeployScaleWithPluginExample(ActionsBase):
|
||||
class DeployScaleWithPluginExample(ActionTest, BaseActions):
|
||||
"""Deploy and scale cluster in ha mode with example plugin
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -14,18 +14,21 @@
|
|||
|
||||
|
||||
from fuelweb_test.settings import EXAMPLE_PLUGIN_V3_PATH
|
||||
|
||||
from system_test import testcase
|
||||
from system_test import deferred_decorator
|
||||
from system_test import action
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.tests.actions_base import ActionsBase
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.plugins',
|
||||
'system_test.plugins.example_plugin_v3',
|
||||
'system_test.plugins.example_plugin_v3.simple'])
|
||||
class DeployWithPluginExampleV3(ActionsBase):
|
||||
class DeployWithPluginExampleV3(ActionTest, BaseActions):
|
||||
"""Deploy cluster with one controller and example plugin v3
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -13,17 +13,20 @@
|
|||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests.strength import strength_base
|
||||
from system_test import deferred_decorator
|
||||
from system_test import action
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
from system_test.actions import StrengthActions
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.failover',
|
||||
'system_test.failover.destroy_controllers',
|
||||
'system_test.failover.destroy_controllers.first'])
|
||||
class StrengthDestroyFirstController(strength_base.StrengthBaseActions):
|
||||
class StrengthDestroyFirstController(ActionTest, BaseActions, StrengthActions):
|
||||
"""Destroy two controllers and check pacemaker status is correct
|
||||
|
||||
Scenario:
|
||||
|
@ -73,7 +76,8 @@ class StrengthDestroyFirstController(strength_base.StrengthBaseActions):
|
|||
'system_test.failover',
|
||||
'system_test.failover.destroy_controllers',
|
||||
'system_test.failover.destroy_controllers.second'])
|
||||
class StrengthDestroySecondController(strength_base.StrengthBaseActions):
|
||||
class StrengthDestroySecondController(ActionTest, BaseActions,
|
||||
StrengthActions):
|
||||
"""Destroy two controllers and check pacemaker status is correct
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -14,15 +14,15 @@
|
|||
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests.strength import strength_base
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
from system_test.actions import FillRootActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.failover',
|
||||
'system_test.failover.filling_root'])
|
||||
class FillRootPrimaryController(
|
||||
strength_base.FillRootBaseActions
|
||||
):
|
||||
class FillRootPrimaryController(ActionTest, BaseActions, FillRootActions):
|
||||
"""Fill root filesystem on primary controller and check pacemaker
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests import actions_base
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test', 'system_test.create_deploy_ostf'])
|
||||
class CreateDeployOstf(actions_base.ActionsBase):
|
||||
class CreateDeployOstf(ActionTest, BaseActions):
|
||||
"""Case deploy Environment
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests import actions_base
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test', 'system_test.delete_after_deploy'])
|
||||
class DeleteAfterDeploy(actions_base.ActionsBase):
|
||||
class DeleteAfterDeploy(ActionTest, BaseActions):
|
||||
"""Case deploy Environment
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -15,15 +15,18 @@
|
|||
from proboscis.asserts import assert_true
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests import actions_base
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test import action
|
||||
from system_test import deferred_decorator
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import action
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.deploy_and_check_radosgw'])
|
||||
class DeployCheckRadosGW(actions_base.ActionsBase):
|
||||
class DeployCheckRadosGW(ActionTest, BaseActions):
|
||||
"""Deploy cluster and check RadosGW
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -16,19 +16,22 @@ from devops.helpers.helpers import icmp_ping
|
|||
from devops.helpers.helpers import wait
|
||||
from proboscis.asserts import assert_equal
|
||||
|
||||
from fuelweb_test import logger
|
||||
from fuelweb_test.helpers import checkers
|
||||
|
||||
from system_test import logger
|
||||
from system_test import testcase
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test import action
|
||||
from system_test import deferred_decorator
|
||||
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
from system_test.actions import FuelMasterActions
|
||||
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.tests.actions_base import ActionsBase
|
||||
from system_test.tests.actions_base import FuelMasterActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test', 'system_test.fuel_migration'])
|
||||
class FuelMasterMigrate(ActionsBase, FuelMasterActions):
|
||||
class FuelMasterMigrate(ActionTest, BaseActions, FuelMasterActions):
|
||||
"""Fuel master migration to VM
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests import actions_base
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test', 'system_test.redeploy_after_reset'])
|
||||
class RedeployAfterReset(actions_base.ActionsBase):
|
||||
class RedeployAfterReset(ActionTest, BaseActions):
|
||||
"""Case deploy Environment
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -13,11 +13,12 @@
|
|||
# under the License.
|
||||
|
||||
from system_test import testcase
|
||||
from system_test.tests import actions_base
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test', 'system_test.redeploy_after_stop'])
|
||||
class RedeployAfterStop(actions_base.ActionsBase):
|
||||
class RedeployAfterStop(ActionTest, BaseActions):
|
||||
"""Case deploy Environment
|
||||
|
||||
Scenario:
|
||||
|
|
|
@ -12,183 +12,19 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
|
||||
from proboscis.asserts import assert_true
|
||||
from system_test import testcase
|
||||
from system_test import logger
|
||||
from system_test.helpers.decorators import make_snapshot_if_step_fail
|
||||
from system_test.helpers.decorators import deferred_decorator
|
||||
from system_test.helpers.decorators import action
|
||||
from system_test.tests.actions_base import ActionsBase
|
||||
from fuelweb_test.settings import DVS_PLUGIN_PATH
|
||||
from fuelweb_test.settings import DVS_PLUGIN_VERSION
|
||||
|
||||
|
||||
class VMwareActions(ActionsBase):
|
||||
"""VMware vCenter/DVS related actions"""
|
||||
|
||||
plugin_version = None
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def enable_plugin(self):
|
||||
"""Enable plugin for Fuel"""
|
||||
assert_true(self.plugin_name, "plugin_name is not specified")
|
||||
|
||||
msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
|
||||
assert_true(
|
||||
self.fuel_web.check_plugin_exists(
|
||||
self.cluster_id,
|
||||
self.plugin_name),
|
||||
msg)
|
||||
|
||||
plugin_data = self.fuel_web.get_plugin_data(self.cluster_id,
|
||||
self.plugin_name,
|
||||
self.plugin_version)
|
||||
options = {'metadata/enabled': True,
|
||||
'metadata/chosen_id': plugin_data['metadata']['plugin_id']}
|
||||
self.fuel_web.update_plugin_data(self.cluster_id,
|
||||
self.plugin_name, options)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def configure_dvs_plugin(self):
|
||||
"""Configure DVS plugin"""
|
||||
|
||||
msg = "Plugin couldn't be enabled. Check plugin version. Test aborted"
|
||||
assert_true(
|
||||
self.fuel_web.check_plugin_exists(
|
||||
self.cluster_id,
|
||||
self.plugin_name),
|
||||
msg)
|
||||
|
||||
options = {'vmware_dvs_net_maps/value': self.full_config[
|
||||
'template']['cluster_template']['settings']['vmware_dvs'][
|
||||
'dvswitch_name']}
|
||||
self.fuel_web.update_plugin_settings(
|
||||
self.cluster_id, self.plugin_name, self.plugin_version, options)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def configure_vcenter(self):
|
||||
"""Configure vCenter settings"""
|
||||
|
||||
vmware_vcenter = self.env_settings['vmware_vcenter']
|
||||
|
||||
vcenter_value = {
|
||||
"glance": {"vcenter_username": "",
|
||||
"datacenter": "",
|
||||
"vcenter_host": "",
|
||||
"vcenter_password": "",
|
||||
"datastore": ""
|
||||
},
|
||||
"availability_zones": [
|
||||
{"vcenter_username": vmware_vcenter['settings']['user'],
|
||||
"nova_computes": [],
|
||||
"vcenter_host": vmware_vcenter['settings']['host'],
|
||||
"az_name": vmware_vcenter['settings']['az'],
|
||||
"vcenter_password": vmware_vcenter['settings']['pwd']
|
||||
}]
|
||||
}
|
||||
|
||||
clusters = vmware_vcenter['nova-compute']
|
||||
nodes = self.fuel_web.client.list_cluster_nodes(self.cluster_id)
|
||||
roles = ['compute-vmware']
|
||||
comp_vmware_nodes = [n for n in nodes if set(roles) <=
|
||||
set(n['pending_roles'])]
|
||||
|
||||
for cluster in clusters:
|
||||
cluster_name = cluster['cluster']
|
||||
srv_name = cluster['srv_name']
|
||||
datastore = cluster['datastore']
|
||||
if cluster['target_node'] == 'compute-vmware':
|
||||
node = comp_vmware_nodes.pop()
|
||||
target_node = node['hostname']
|
||||
else:
|
||||
target_node = cluster['target_node']
|
||||
|
||||
vcenter_value["availability_zones"][0]["nova_computes"].append(
|
||||
{"vsphere_cluster": cluster_name,
|
||||
"service_name": srv_name,
|
||||
"datastore_regex": datastore,
|
||||
"target_node": {
|
||||
"current": {"id": target_node,
|
||||
"label": target_node},
|
||||
"options": [{"id": target_node,
|
||||
"label": target_node}, ]},
|
||||
}
|
||||
)
|
||||
|
||||
if vmware_vcenter['glance']['enable']:
|
||||
attributes = self.fuel_web.client.get_cluster_attributes(
|
||||
self.cluster_id)
|
||||
attributes['editable']['storage']['images_vcenter']['value'] =\
|
||||
vmware_vcenter['glance']['enable']
|
||||
self.fuel_web.client.update_cluster_attributes(self.cluster_id,
|
||||
attributes)
|
||||
|
||||
vcenter_value["glance"]["vcenter_host"] = vmware_vcenter[
|
||||
'glance']['host']
|
||||
vcenter_value["glance"]["vcenter_username"] = vmware_vcenter[
|
||||
'glance']['user']
|
||||
vcenter_value["glance"]["vcenter_password"] = vmware_vcenter[
|
||||
'glance']['pwd']
|
||||
vcenter_value["glance"]["datacenter"] = vmware_vcenter[
|
||||
'glance']['datacenter']
|
||||
vcenter_value["glance"]["datastore"] = vmware_vcenter[
|
||||
'glance']['datastore']
|
||||
|
||||
logger.info('Configuring vCenter...')
|
||||
|
||||
vmware_attr = \
|
||||
self.fuel_web.client.get_cluster_vmware_attributes(self.cluster_id)
|
||||
vcenter_data = vmware_attr['editable']
|
||||
vcenter_data['value'] = vcenter_value
|
||||
logger.debug("Try to update cluster with next "
|
||||
"vmware_attributes {0}".format(vmware_attr))
|
||||
self.fuel_web.client.update_cluster_vmware_attributes(self.cluster_id,
|
||||
vmware_attr)
|
||||
|
||||
logger.debug("Attributes of cluster have been updated")
|
||||
|
||||
def _del_node(self, nodes_list):
|
||||
"""Delete nodes from Environment"""
|
||||
logger.info("Delete nodes from env {}".format(self.cluster_id))
|
||||
nodes = {}
|
||||
|
||||
for node in nodes_list:
|
||||
cluster_nodes = self.fuel_web.get_nailgun_cluster_nodes_by_roles(
|
||||
self.cluster_id, node['roles'])
|
||||
for i in xrange(node['count']):
|
||||
dnode = self.fuel_web.get_devops_node_by_nailgun_node(
|
||||
cluster_nodes[i])
|
||||
self.assigned_slaves.remove(dnode.name)
|
||||
|
||||
nodes[dnode.name] = node['roles']
|
||||
logger.info("Delete node {} with role {}".format(
|
||||
dnode.name, node['roles']))
|
||||
|
||||
self.fuel_web.update_nodes(self.cluster_id, nodes, False, True)
|
||||
|
||||
@deferred_decorator([make_snapshot_if_step_fail])
|
||||
@action
|
||||
def scale_node(self):
|
||||
"""Scale node in cluster"""
|
||||
step_config = self.env_config['scale_nodes'][self.scale_step]
|
||||
for node in step_config:
|
||||
if node['action'] == 'add':
|
||||
self._add_node([node])
|
||||
elif node['action'] == 'delete':
|
||||
self._del_node([node])
|
||||
else:
|
||||
logger.error("Unknow scale action: {}".format(node['action']))
|
||||
self.scale_step += 1
|
||||
from system_test import testcase
|
||||
from system_test.tests import ActionTest
|
||||
from system_test.actions import BaseActions
|
||||
from system_test.actions import VMwareActions
|
||||
|
||||
|
||||
@testcase(groups=['system_test',
|
||||
'system_test.vcenter',
|
||||
'system_test.vcenter.deploy_vcenter_dvs_run_ostf'])
|
||||
class DeployWithVMware(VMwareActions):
|
||||
class DeployWithVMware(ActionTest, BaseActions, VMwareActions):
|
||||
"""Deploy cluster with vCenter and dvs plugin
|
||||
|
||||
Scenario:
|
||||
|
@ -224,7 +60,7 @@ class DeployWithVMware(VMwareActions):
|
|||
@testcase(groups=['system_test',
|
||||
'system_test.vcenter',
|
||||
'system_test.vcenter.scale_vcenter_dvs'])
|
||||
class ScaleWithVMware(VMwareActions):
|
||||
class ScaleWithVMware(ActionTest, BaseActions, VMwareActions):
|
||||
"""Deploy and scale cluster with vCenter and dvs plugin
|
||||
|
||||
Scenario:
|
||||
|
|
Loading…
Reference in New Issue