fuel-qa/system_test/helpers/decorators.py

125 lines
4.8 KiB
Python

# Copyright 2013 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 functools
import traceback
import sys
import hashlib
from proboscis import SkipTest
from fuelweb_test.helpers.utils import TimeStat
from fuelweb_test.helpers.utils import pull_out_logs_via_ssh
from fuelweb_test.helpers.decorators import create_diagnostic_snapshot
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 step_start_stop(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
with TimeStat(func) as timer:
step_name = getattr(func, '_step_name')
start_step = '[ START {} ]'.format(step_name)
header = "<<< {:-^142} >>>".format(start_step)
logger.info("\n{header}\n".format(header=header))
result = func(*args, **kwargs)
spent_time = timer.spent_time
minutes = int(round(spent_time)) / 60
seconds = int(round(spent_time)) % 60
finish_step = "[ FINISH {} STEP TOOK {} min {} sec ]".format(
step_name, minutes, seconds)
footer = "<<< {:-^142} >>>".format(finish_step)
logger.info("\n{footer}\n".format(footer=footer))
return result
return wrapper
def make_snapshot_if_step_fail(func):
"""Generate diagnostic snapshot if step fail.
- Show test case method name and scenario from docstring.
- Create a diagnostic snapshot of environment in cases:
- if the test case passed;
- if error occurred in the test case.
- Fetch logs from master node if creating the diagnostic
snapshot has failed.
"""
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
result = func(*args, **kwargs)
except SkipTest:
raise SkipTest()
except Exception as test_exception:
exc_trace = sys.exc_traceback
name = 'error_%s' % func.__name__
case_name = getattr(func, '_base_class', None)
step_num = getattr(func, '_step_num', None)
config_name = getattr(func, '_config_case_group', None)
description = "Failed in method '%s'." % func.__name__
if args[0].env is not None:
try:
create_diagnostic_snapshot(args[0].env,
"fail", name)
except:
logger.error("Fetching of diagnostic snapshot failed: {0}".
format(traceback.format_exc()))
try:
with args[0].env.d_env.get_admin_remote()\
as admin_remote:
pull_out_logs_via_ssh(admin_remote, name)
except:
logger.error("Fetching of raw logs failed: {0}".
format(traceback.format_exc()))
finally:
logger.debug(args)
try:
if all([case_name, step_num, config_name]):
_hash = hashlib.sha256(config_name)
_hash = _hash.hexdigest()[:8]
snapshot_name = "{case}_{config}_{step}".format(
case=case_name,
config=_hash,
step="Step{:03d}".format(step_num)
)
else:
snapshot_name = name[-50:]
args[0].env.make_snapshot(snapshot_name=snapshot_name,
description=description,
is_make=True)
except:
logger.error("Error making the environment snapshot:"
" {0}".format(traceback.format_exc()))
raise test_exception, None, exc_trace
return result
return wrapper