Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

Commit

Permalink
Test for postdeploy plugin install and enable.
Browse files Browse the repository at this point in the history
Related-bug: #1519050
Related-bug: #1518305
Closes-bug: #1527123

Change-Id: I54418e328049e5a885cad783a3c3941996334005
  • Loading branch information
penguinolog committed Dec 22, 2015
1 parent c5bc494 commit 0469399
Show file tree
Hide file tree
Showing 8 changed files with 720 additions and 28 deletions.
5 changes: 5 additions & 0 deletions doc/base_tests.rst
Expand Up @@ -342,6 +342,11 @@ Example tests
.. automodule:: fuelweb_test.tests.plugins.plugin_example.test_fuel_plugin_example
:members:

Example tests for plugin installation after cluster create
----------------------------------------------------------
.. automodule:: fuelweb_test.tests.plugins.plugin_example.test_fuel_plugin_example_postdeploy
:members:

Glusterfs tests
---------------
.. automodule:: fuelweb_test.tests.plugins.plugin_glusterfs.test_plugin_glusterfs
Expand Down
6 changes: 2 additions & 4 deletions fuelweb_test/helpers/checkers.py
Expand Up @@ -172,8 +172,7 @@ def check_ceph_image_size(remote, expected_size, device='vdc'):
remote.check_call("df -m")))
raise Exception
logger.debug("Partitions: {part}".format(part=ret))
assert_true(abs(float(ret[0].rstrip()) / float(expected_size)
- 1) < 0.1,
assert_true(abs(float(ret[0].rstrip()) / float(expected_size) - 1) < 0.1,
"size {0} is not equal"
" to {1}".format(ret[0].rstrip(),
expected_size))
Expand All @@ -183,8 +182,7 @@ def check_ceph_image_size(remote, expected_size, device='vdc'):
def check_cinder_image_size(remote, expected_size, device='vdc3'):
ret = get_mongo_partitions(remote, device)[0].rstrip().rstrip('G')
cinder_size = float(ret) * 1024
assert_true(abs(cinder_size / float(expected_size)
- 1) < 0.1,
assert_true(abs(cinder_size / float(expected_size) - 1) < 0.1,
"size {0} is not equal"
" to {1}".format(ret[0].rstrip(),
expected_size))
Expand Down
57 changes: 57 additions & 0 deletions fuelweb_test/helpers/decorators.py
Expand Up @@ -490,3 +490,60 @@ def wrapper(*args, **kwargs):
"management on nodes. Please see the debug log.")
return result
return wrapper

# Setup/Teardown decorators, which is missing in Proboscis.
# Usage: like in Nose.
# Python.six is less smart


def __getcallargs(func, *positional, **named):
if sys.version_info.major < 3:
return inspect.getcallargs(func, *positional, **named)
else:
return inspect.signature(func).bind(*positional, **named).arguments


def __get_arg_names(func):
if sys.version_info.major < 3:
return [arg for arg in inspect.getargspec(func=func).args]
else:
return list(inspect.signature(obj=func).parameters.keys())


def __call_in_context(func, context_args):
if func is None:
return

func_args = __get_arg_names(func)
if not func_args:
return func()

try:
arg_values = [context_args[k] for k in func_args]
except KeyError as e:
raise ValueError("Argument '{}' is missing".format(str(e)))

return func(*arg_values)


def setup_teardown(setup=None, teardown=None):
"""
Add setup and teardown for functions and methods.
:param setup: function
:param teardown: function
:return:
"""
def deco(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
real_args = __getcallargs(func, *args, **kwargs)
if 'self' in real_args:
real_args.setdefault('cls', real_args['self'].__class__)
__call_in_context(setup, real_args)
try:
result = func(*args, **kwargs)
finally:
__call_in_context(teardown, real_args)
return result
return wrapper
return deco
7 changes: 5 additions & 2 deletions fuelweb_test/models/fuel_web_client.py
Expand Up @@ -2300,13 +2300,16 @@ def check_plugin_exists(self, cluster_id, plugin_name, section='editable'):

def update_plugin_data(self, cluster_id, plugin_name, data):
attr = self.client.get_cluster_attributes(cluster_id)
# Do not re-upload anything, except selected plugin data
real_attr = {'editable': {plugin_name: attr['editable'][plugin_name]}}

for option, value in data.items():
plugin_data = attr['editable'][plugin_name]
plugin_data = real_attr['editable'][plugin_name]
path = option.split("/")
for p in path[:-1]:
plugin_data = plugin_data[p]
plugin_data[path[-1]] = value
self.client.update_cluster_attributes(cluster_id, attr)
self.client.update_cluster_attributes(cluster_id, real_attr)

@logwrap
def prepare_ceph_to_delete(self, remote_ceph):
Expand Down
1 change: 1 addition & 0 deletions fuelweb_test/run_tests.py
Expand Up @@ -120,6 +120,7 @@ def import_tests():
from tests.plugins.plugin_emc import test_plugin_emc # noqa
from tests.plugins.plugin_elasticsearch import test_plugin_elasticsearch # noqa
from tests.plugins.plugin_example import test_fuel_plugin_example # noqa
from tests.plugins.plugin_example import test_fuel_plugin_example_postdeploy # noqa
from tests.plugins.plugin_contrail import test_fuel_plugin_contrail # noqa
from tests.plugins.plugin_glusterfs import test_plugin_glusterfs # noqa
from tests.plugins.plugin_influxdb import test_plugin_influxdb # noqa
Expand Down
1 change: 1 addition & 0 deletions fuelweb_test/settings.py
Expand Up @@ -371,6 +371,7 @@ def iface_alias(interface_name):
GLUSTER_CLUSTER_ENDPOINT = os.environ.get('GLUSTER_CLUSTER_ENDPOINT')
EXAMPLE_PLUGIN_PATH = os.environ.get('EXAMPLE_PLUGIN_PATH')
EXAMPLE_PLUGIN_V3_PATH = os.environ.get('EXAMPLE_PLUGIN_V3_PATH')
EXAMPLE_PLUGIN_V4_PATH = os.environ.get('EXAMPLE_PLUGIN_V4_PATH')
LBAAS_PLUGIN_PATH = os.environ.get('LBAAS_PLUGIN_PATH')
ZABBIX_PLUGIN_PATH = os.environ.get('ZABBIX_PLUGIN_PATH')
ZABBIX_SNMP_PLUGIN_PATH = os.environ.get('ZABBIX_SNMP_PLUGIN_PATH')
Expand Down
81 changes: 59 additions & 22 deletions fuelweb_test/tests/base_test_case.py
Expand Up @@ -33,13 +33,22 @@ class TestBasic(object):
"""
def __init__(self):
self._current_log_step = 0
self.ssh_manager = SSHManager()
self.env = EnvironmentModel()
self.__current_log_step = 0
self._test_program = None

@property
def current_log_step(self):
return self.__current_log_step

@current_log_step.setter
def current_log_step(self, new_val):
self.__current_log_step = new_val

@property
def test_program(self):
if not hasattr(self, '_test_program'):
if self._test_program is None:
self._test_program = TestProgram()
return self._test_program

Expand All @@ -59,22 +68,25 @@ def check_run(self, snapshot_name):
if self.env.d_env.has_snapshot(snapshot_name):
raise SkipTest()

def show_step(self, step, details=''):
def show_step(self, step, details='', initialize=False):
"""Show a description of the step taken from docstring
:param int/str step: step number to show
:param str details: additional info for a step
"""
test_func_name = get_test_method_name()

self._current_log_step += 1
if self._current_log_step != step:
error_message = 'The step {} should be {} at {}'
error_message = error_message.format(
step,
self._current_log_step,
test_func_name
)
logger.error(error_message)
if initialize:
self.current_log_step = step
else:
self.current_log_step += 1
if self.current_log_step != step:
error_message = 'The step {} should be {} at {}'
error_message = error_message.format(
step,
self.current_log_step,
test_func_name
)
logger.error(error_message)

test_func = getattr(self.__class__, test_func_name)
docstring = test_func.__doc__
Expand Down Expand Up @@ -133,6 +145,7 @@ def setup_master(self):
with TimeStat("setup_environment", is_uniq=True):
self.env.setup_environment()
self.env.make_snapshot("empty", is_make=True)
self.current_log_step = 0

@test(groups=["setup_master_custom_manifests"])
@log_snapshot_after_test
Expand All @@ -148,10 +161,14 @@ def setup_with_custom_manifests(self):
Duration 20m
"""
self.check_run("empty_custom_manifests")
self.show_step(1, initialize=True)
self.show_step(2)
self.env.setup_environment(custom=True, build_images=True)
self.show_step(3)
if REPLACE_DEFAULT_REPOS and REPLACE_DEFAULT_REPOS_ONLY_ONCE:
self.fuel_web.replace_default_repos()
self.env.make_snapshot("empty_custom_manifests", is_make=True)
self.current_log_step = 0

@test(depends_on=[setup_master], groups=["prepare_release"])
@log_snapshot_after_test
Expand All @@ -166,13 +183,16 @@ def prepare_release(self):
"""
self.check_run("ready")
self.show_step(1, initialize=True)
self.env.revert_snapshot("empty", skip_timesync=True)

self.fuel_web.get_nailgun_version()
self.fuel_web.change_default_network_settings()
self.show_step(2)
if REPLACE_DEFAULT_REPOS and REPLACE_DEFAULT_REPOS_ONLY_ONCE:
self.fuel_web.replace_default_repos()
self.env.make_snapshot("ready", is_make=True)
self.current_log_step = 0

@test(depends_on=[prepare_release],
groups=["prepare_slaves_1"])
Expand All @@ -188,10 +208,14 @@ def prepare_slaves_1(self):
"""
self.check_run("ready_with_1_slaves")
self.show_step(1, initialize=True)
self.env.revert_snapshot("ready", skip_timesync=True)
self.env.bootstrap_nodes(self.env.d_env.nodes().slaves[:1],
skip_timesync=True)
self.show_step(2)
self.env.bootstrap_nodes(
self.env.d_env.get_nodes(role='fuel_slave')[:1],
skip_timesync=True)
self.env.make_snapshot("ready_with_1_slaves", is_make=True)
self.current_log_step = 0

@test(depends_on=[prepare_release],
groups=["prepare_slaves_3"])
Expand All @@ -207,10 +231,14 @@ def prepare_slaves_3(self):
"""
self.check_run("ready_with_3_slaves")
self.show_step(1, initialize=True)
self.env.revert_snapshot("ready", skip_timesync=True)
self.env.bootstrap_nodes(self.env.d_env.nodes().slaves[:3],
skip_timesync=True)
self.show_step(2)
self.env.bootstrap_nodes(
self.env.d_env.get_nodes(role='fuel_slave')[:3],
skip_timesync=True)
self.env.make_snapshot("ready_with_3_slaves", is_make=True)
self.current_log_step = 0

@test(depends_on=[prepare_release],
groups=["prepare_slaves_5"])
Expand All @@ -226,10 +254,14 @@ def prepare_slaves_5(self):
"""
self.check_run("ready_with_5_slaves")
self.show_step(1, initialize=True)
self.env.revert_snapshot("ready", skip_timesync=True)
self.env.bootstrap_nodes(self.env.d_env.nodes().slaves[:5],
skip_timesync=True)
self.show_step(2)
self.env.bootstrap_nodes(
self.env.d_env.get_nodes(role='fuel_slave')[:5],
skip_timesync=True)
self.env.make_snapshot("ready_with_5_slaves", is_make=True)
self.current_log_step = 0

@test(depends_on=[prepare_release],
groups=["prepare_slaves_9"])
Expand All @@ -245,10 +277,15 @@ def prepare_slaves_9(self):
"""
self.check_run("ready_with_9_slaves")
self.show_step(1, initialize=True)
self.env.revert_snapshot("ready", skip_timesync=True)
# Bootstrap 9 slaves in two stages to get lower load on the host
self.env.bootstrap_nodes(self.env.d_env.nodes().slaves[:5],
skip_timesync=True)
self.env.bootstrap_nodes(self.env.d_env.nodes().slaves[5:9],
skip_timesync=True)
self.show_step(2)
self.env.bootstrap_nodes(
self.env.d_env.get_nodes(role='fuel_slave')[:5],
skip_timesync=True)
self.env.bootstrap_nodes(
self.env.d_env.get_nodes(role='fuel_slave')[5:9],
skip_timesync=True)
self.env.make_snapshot("ready_with_9_slaves", is_make=True)
self.current_log_step = 0

0 comments on commit 0469399

Please sign in to comment.