9262943c56
This commit removes return values from take_action(). Because they are unused in cliff[1] and to prevent developers misunderstanding. [1] http://git.openstack.org/cgit/openstack/cliff/tree/cliff/command.py#n55 Change-Id: I1a81e163acae17005f49decb8cb7ffee52944d26
173 lines
6.1 KiB
Python
Executable File
173 lines
6.1 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Copyright 2013 Quanta Research Cambridge, 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 inspect
|
|
import sys
|
|
try:
|
|
from unittest import loader
|
|
except ImportError:
|
|
# unittest in python 2.6 does not contain loader, so uses unittest2
|
|
from unittest2 import loader
|
|
import traceback
|
|
import warnings
|
|
|
|
from cliff import command
|
|
from oslo_log import log as logging
|
|
from oslo_serialization import jsonutils as json
|
|
from testtools import testsuite
|
|
|
|
from tempest.stress import driver
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
|
|
"""Discovers all tempest tests and create action out of them"""
|
|
LOG.info("Start test discovery")
|
|
tests = []
|
|
testloader = loader.TestLoader()
|
|
list = testloader.discover(path)
|
|
for func in (testsuite.iterate_tests(list)):
|
|
attrs = []
|
|
try:
|
|
method_name = getattr(func, '_testMethodName')
|
|
full_name = "%s.%s.%s" % (func.__module__,
|
|
func.__class__.__name__,
|
|
method_name)
|
|
test_func = getattr(func, method_name)
|
|
# NOTE(mkoderer): this contains a list of all type attributes
|
|
attrs = getattr(test_func, "__testtools_attrs")
|
|
except Exception:
|
|
next
|
|
if 'stress' in attrs:
|
|
if filter_attr is not None and filter_attr not in attrs:
|
|
continue
|
|
class_setup_per = getattr(test_func, "st_class_setup_per")
|
|
|
|
action = {'action':
|
|
"tempest.stress.actions.unit_test.UnitTest",
|
|
'kwargs': {"test_method": full_name,
|
|
"class_setup_per": class_setup_per
|
|
}
|
|
}
|
|
if (not call_inherited and
|
|
getattr(test_func, "st_allow_inheritance") is not True):
|
|
class_structure = inspect.getmro(test_func.im_class)
|
|
if test_func.__name__ not in class_structure[0].__dict__:
|
|
continue
|
|
tests.append(action)
|
|
return tests
|
|
|
|
|
|
class TempestRunStress(command.Command):
|
|
|
|
@staticmethod
|
|
def display_deprecation_warning():
|
|
warnings.simplefilter('once', category=DeprecationWarning)
|
|
warnings.warn(
|
|
'Stress tests are deprecated and will be removed from Tempest '
|
|
'in the Newton release.',
|
|
DeprecationWarning)
|
|
warnings.resetwarnings()
|
|
|
|
def get_parser(self, prog_name):
|
|
self.display_deprecation_warning()
|
|
pa = super(TempestRunStress, self).get_parser(prog_name)
|
|
pa = add_arguments(pa)
|
|
return pa
|
|
|
|
def take_action(self, pa):
|
|
try:
|
|
action(pa)
|
|
except Exception:
|
|
LOG.exception("Failure in the stress test framework")
|
|
traceback.print_exc()
|
|
raise
|
|
|
|
def get_description(self):
|
|
return 'Run tempest stress tests'
|
|
|
|
|
|
def add_arguments(parser):
|
|
parser.add_argument('-d', '--duration', default=300, type=int,
|
|
help="Duration of test in secs")
|
|
parser.add_argument('-s', '--serial', action='store_true',
|
|
help="Trigger running tests serially")
|
|
parser.add_argument('-S', '--stop', action='store_true',
|
|
default=False, help="Stop on first error")
|
|
parser.add_argument('-n', '--number', type=int,
|
|
help="How often an action is executed for each "
|
|
"process")
|
|
group = parser.add_mutually_exclusive_group(required=True)
|
|
group.add_argument('-a', '--all', action='store_true',
|
|
help="Execute all stress tests")
|
|
parser.add_argument('-T', '--type',
|
|
help="Filters tests of a certain type (e.g. gate)")
|
|
parser.add_argument('-i', '--call-inherited', action='store_true',
|
|
default=False,
|
|
help="Call also inherited function with stress "
|
|
"attribute")
|
|
group.add_argument('-t', "--tests", nargs='?',
|
|
help="Name of the file with test description")
|
|
return parser
|
|
|
|
|
|
def action(ns):
|
|
result = 0
|
|
if not ns.all:
|
|
tests = json.load(open(ns.tests, 'r'))
|
|
else:
|
|
tests = discover_stress_tests(filter_attr=ns.type,
|
|
call_inherited=ns.call_inherited)
|
|
|
|
if ns.serial:
|
|
# Duration is total time
|
|
duration = ns.duration / len(tests)
|
|
for test in tests:
|
|
step_result = driver.stress_openstack([test],
|
|
duration,
|
|
ns.number,
|
|
ns.stop)
|
|
# NOTE(mkoderer): we just save the last result code
|
|
if (step_result != 0):
|
|
result = step_result
|
|
if ns.stop:
|
|
return result
|
|
else:
|
|
result = driver.stress_openstack(tests,
|
|
ns.duration,
|
|
ns.number,
|
|
ns.stop)
|
|
return result
|
|
|
|
|
|
def main():
|
|
TempestRunStress.display_deprecation_warning()
|
|
parser = argparse.ArgumentParser(description='Run stress tests')
|
|
pa = add_arguments(parser)
|
|
ns = pa.parse_args()
|
|
return action(ns)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
sys.exit(main())
|
|
except Exception:
|
|
LOG.exception("Failure in the stress test framework")
|
|
traceback.print_exc()
|
|
sys.exit(1)
|