blob: 7502c23498662be8fd1a4dffc43b22a7ec23a322 [file] [log] [blame]
David Kranzb9d97502013-05-01 15:55:04 -04001#!/usr/bin/env python
2
David Kranzb9d97502013-05-01 15:55:04 -04003# Copyright 2013 Quanta Research Cambridge, Inc.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17import argparse
Marc Kodererb0604412013-09-02 09:43:40 +020018import inspect
Marc Koderer888ddc42013-07-23 16:13:07 +020019import sys
Will16a778a2014-01-12 21:49:14 -050020try:
21 from unittest import loader
22except ImportError:
23 # unittest in python 2.6 does not contain loader, so uses unittest2
24 from unittest2 import loader
Marc Kodererf863b3b2015-12-18 09:21:13 +010025import traceback
Tin Lam336aca72016-03-07 18:51:44 -060026import warnings
Marc Koderer32221b8e2013-08-23 13:57:50 +020027
Masayuki Igawae5c70282015-10-30 12:18:58 +090028from cliff import command
Doug Hellmann503a0482015-03-11 21:20:04 +000029from oslo_log import log as logging
Matthew Treinish21905512015-07-13 10:33:35 -040030from oslo_serialization import jsonutils as json
Matthew Treinish96e9e882014-06-09 18:37:19 -040031from testtools import testsuite
32
Marc Koderer211ca962013-12-05 12:20:21 +010033from tempest.stress import driver
Marc Koderer16648e92013-10-05 10:49:13 +020034
35LOG = logging.getLogger(__name__)
36
Marc Koderer32221b8e2013-08-23 13:57:50 +020037
Marc Kodererb0604412013-09-02 09:43:40 +020038def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +000039 """Discovers all tempest tests and create action out of them"""
Marc Koderer16648e92013-10-05 10:49:13 +020040 LOG.info("Start test discovery")
Marc Koderer32221b8e2013-08-23 13:57:50 +020041 tests = []
42 testloader = loader.TestLoader()
43 list = testloader.discover(path)
Masayuki Igawa7e9eb542014-02-17 15:03:44 +090044 for func in (testsuite.iterate_tests(list)):
Marc Koderer16648e92013-10-05 10:49:13 +020045 attrs = []
Marc Koderer32221b8e2013-08-23 13:57:50 +020046 try:
47 method_name = getattr(func, '_testMethodName')
48 full_name = "%s.%s.%s" % (func.__module__,
49 func.__class__.__name__,
50 method_name)
51 test_func = getattr(func, method_name)
52 # NOTE(mkoderer): this contains a list of all type attributes
53 attrs = getattr(test_func, "__testtools_attrs")
54 except Exception:
55 next
56 if 'stress' in attrs:
Matthew Treinishc795b9e2014-06-09 17:01:10 -040057 if filter_attr is not None and filter_attr not in attrs:
Marc Koderer32221b8e2013-08-23 13:57:50 +020058 continue
59 class_setup_per = getattr(test_func, "st_class_setup_per")
60
61 action = {'action':
62 "tempest.stress.actions.unit_test.UnitTest",
63 'kwargs': {"test_method": full_name,
64 "class_setup_per": class_setup_per
65 }
66 }
Marc Kodererb0604412013-09-02 09:43:40 +020067 if (not call_inherited and
68 getattr(test_func, "st_allow_inheritance") is not True):
69 class_structure = inspect.getmro(test_func.im_class)
70 if test_func.__name__ not in class_structure[0].__dict__:
71 continue
Marc Koderer32221b8e2013-08-23 13:57:50 +020072 tests.append(action)
73 return tests
David Kranzb9d97502013-05-01 15:55:04 -040074
David Kranzb9d97502013-05-01 15:55:04 -040075
Masayuki Igawae5c70282015-10-30 12:18:58 +090076class TempestRunStress(command.Command):
77
Tin Lam336aca72016-03-07 18:51:44 -060078 @staticmethod
79 def display_deprecation_warning():
80 warnings.simplefilter('once', category=DeprecationWarning)
81 warnings.warn(
82 'Stress tests are deprecated and will be removed from Tempest '
83 'in the Newton release.',
84 DeprecationWarning)
85 warnings.resetwarnings()
86
Masayuki Igawae5c70282015-10-30 12:18:58 +090087 def get_parser(self, prog_name):
Tin Lam336aca72016-03-07 18:51:44 -060088 self.display_deprecation_warning()
Masayuki Igawae5c70282015-10-30 12:18:58 +090089 pa = super(TempestRunStress, self).get_parser(prog_name)
90 pa = add_arguments(pa)
91 return pa
92
93 def take_action(self, pa):
Marc Kodererf863b3b2015-12-18 09:21:13 +010094 try:
95 action(pa)
96 except Exception:
97 LOG.exception("Failure in the stress test framework")
98 traceback.print_exc()
99 raise
Matthew Treinish55e29b42014-05-07 01:04:17 -0400100
Marc Koderer876af152015-12-17 09:49:01 +0100101 def get_description(self):
102 return 'Run tempest stress tests'
103
Matthew Treinish55e29b42014-05-07 01:04:17 -0400104
Masayuki Igawae5c70282015-10-30 12:18:58 +0900105def add_arguments(parser):
106 parser.add_argument('-d', '--duration', default=300, type=int,
107 help="Duration of test in secs")
108 parser.add_argument('-s', '--serial', action='store_true',
109 help="Trigger running tests serially")
110 parser.add_argument('-S', '--stop', action='store_true',
111 default=False, help="Stop on first error")
112 parser.add_argument('-n', '--number', type=int,
113 help="How often an action is executed for each "
114 "process")
115 group = parser.add_mutually_exclusive_group(required=True)
116 group.add_argument('-a', '--all', action='store_true',
117 help="Execute all stress tests")
118 parser.add_argument('-T', '--type',
119 help="Filters tests of a certain type (e.g. gate)")
120 parser.add_argument('-i', '--call-inherited', action='store_true',
121 default=False,
122 help="Call also inherited function with stress "
123 "attribute")
124 group.add_argument('-t', "--tests", nargs='?',
125 help="Name of the file with test description")
126 return parser
127
128
129def action(ns):
Marc Koderer888ddc42013-07-23 16:13:07 +0200130 result = 0
Marc Koderer32221b8e2013-08-23 13:57:50 +0200131 if not ns.all:
132 tests = json.load(open(ns.tests, 'r'))
133 else:
Marc Kodererb0604412013-09-02 09:43:40 +0200134 tests = discover_stress_tests(filter_attr=ns.type,
135 call_inherited=ns.call_inherited)
Marc Koderer32221b8e2013-08-23 13:57:50 +0200136
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400137 if ns.serial:
David Kranz71fee472014-10-13 15:13:02 -0400138 # Duration is total time
139 duration = ns.duration / len(tests)
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400140 for test in tests:
Marc Koderer888ddc42013-07-23 16:13:07 +0200141 step_result = driver.stress_openstack([test],
David Kranz71fee472014-10-13 15:13:02 -0400142 duration,
Marc Koderer3414d732013-07-31 08:36:36 +0200143 ns.number,
144 ns.stop)
145 # NOTE(mkoderer): we just save the last result code
Marc Koderer888ddc42013-07-23 16:13:07 +0200146 if (step_result != 0):
147 result = step_result
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100148 if ns.stop:
149 return result
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400150 else:
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100151 result = driver.stress_openstack(tests,
152 ns.duration,
153 ns.number,
154 ns.stop)
Marc Koderer888ddc42013-07-23 16:13:07 +0200155 return result
David Kranzb9d97502013-05-01 15:55:04 -0400156
157
Masayuki Igawae5c70282015-10-30 12:18:58 +0900158def main():
Tin Lam336aca72016-03-07 18:51:44 -0600159 TempestRunStress.display_deprecation_warning()
Masayuki Igawae5c70282015-10-30 12:18:58 +0900160 parser = argparse.ArgumentParser(description='Run stress tests')
161 pa = add_arguments(parser)
162 ns = pa.parse_args()
163 return action(ns)
164
165
Marc Koderer888ddc42013-07-23 16:13:07 +0200166if __name__ == "__main__":
Marc Koderer16648e92013-10-05 10:49:13 +0200167 try:
Matthew Treinish55e29b42014-05-07 01:04:17 -0400168 sys.exit(main())
Marc Koderer16648e92013-10-05 10:49:13 +0200169 except Exception:
170 LOG.exception("Failure in the stress test framework")
Marc Kodererf863b3b2015-12-18 09:21:13 +0100171 traceback.print_exc()
Marc Koderer16648e92013-10-05 10:49:13 +0200172 sys.exit(1)