blob: 943fe5be63910daf8f4783f817b04a10120ef646 [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
Marc Koderer32221b8e2013-08-23 13:57:50 +020026
Masayuki Igawae5c70282015-10-30 12:18:58 +090027from cliff import command
Doug Hellmann503a0482015-03-11 21:20:04 +000028from oslo_log import log as logging
Matthew Treinish21905512015-07-13 10:33:35 -040029from oslo_serialization import jsonutils as json
Matthew Treinish96e9e882014-06-09 18:37:19 -040030from testtools import testsuite
31
Marc Koderer211ca962013-12-05 12:20:21 +010032from tempest.stress import driver
Marc Koderer16648e92013-10-05 10:49:13 +020033
34LOG = logging.getLogger(__name__)
35
Marc Koderer32221b8e2013-08-23 13:57:50 +020036
Marc Kodererb0604412013-09-02 09:43:40 +020037def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +000038 """Discovers all tempest tests and create action out of them"""
Marc Koderer16648e92013-10-05 10:49:13 +020039 LOG.info("Start test discovery")
Marc Koderer32221b8e2013-08-23 13:57:50 +020040 tests = []
41 testloader = loader.TestLoader()
42 list = testloader.discover(path)
Masayuki Igawa7e9eb542014-02-17 15:03:44 +090043 for func in (testsuite.iterate_tests(list)):
Marc Koderer16648e92013-10-05 10:49:13 +020044 attrs = []
Marc Koderer32221b8e2013-08-23 13:57:50 +020045 try:
46 method_name = getattr(func, '_testMethodName')
47 full_name = "%s.%s.%s" % (func.__module__,
48 func.__class__.__name__,
49 method_name)
50 test_func = getattr(func, method_name)
51 # NOTE(mkoderer): this contains a list of all type attributes
52 attrs = getattr(test_func, "__testtools_attrs")
53 except Exception:
54 next
55 if 'stress' in attrs:
Matthew Treinishc795b9e2014-06-09 17:01:10 -040056 if filter_attr is not None and filter_attr not in attrs:
Marc Koderer32221b8e2013-08-23 13:57:50 +020057 continue
58 class_setup_per = getattr(test_func, "st_class_setup_per")
59
60 action = {'action':
61 "tempest.stress.actions.unit_test.UnitTest",
62 'kwargs': {"test_method": full_name,
63 "class_setup_per": class_setup_per
64 }
65 }
Marc Kodererb0604412013-09-02 09:43:40 +020066 if (not call_inherited and
67 getattr(test_func, "st_allow_inheritance") is not True):
68 class_structure = inspect.getmro(test_func.im_class)
69 if test_func.__name__ not in class_structure[0].__dict__:
70 continue
Marc Koderer32221b8e2013-08-23 13:57:50 +020071 tests.append(action)
72 return tests
David Kranzb9d97502013-05-01 15:55:04 -040073
David Kranzb9d97502013-05-01 15:55:04 -040074
Masayuki Igawae5c70282015-10-30 12:18:58 +090075class TempestRunStress(command.Command):
76
77 def get_parser(self, prog_name):
78 pa = super(TempestRunStress, self).get_parser(prog_name)
79 pa = add_arguments(pa)
80 return pa
81
82 def take_action(self, pa):
Marc Kodererf863b3b2015-12-18 09:21:13 +010083 try:
84 action(pa)
85 except Exception:
86 LOG.exception("Failure in the stress test framework")
87 traceback.print_exc()
88 raise
89 return 0
Matthew Treinish55e29b42014-05-07 01:04:17 -040090
Marc Koderer876af152015-12-17 09:49:01 +010091 def get_description(self):
92 return 'Run tempest stress tests'
93
Matthew Treinish55e29b42014-05-07 01:04:17 -040094
Masayuki Igawae5c70282015-10-30 12:18:58 +090095def add_arguments(parser):
96 parser.add_argument('-d', '--duration', default=300, type=int,
97 help="Duration of test in secs")
98 parser.add_argument('-s', '--serial', action='store_true',
99 help="Trigger running tests serially")
100 parser.add_argument('-S', '--stop', action='store_true',
101 default=False, help="Stop on first error")
102 parser.add_argument('-n', '--number', type=int,
103 help="How often an action is executed for each "
104 "process")
105 group = parser.add_mutually_exclusive_group(required=True)
106 group.add_argument('-a', '--all', action='store_true',
107 help="Execute all stress tests")
108 parser.add_argument('-T', '--type',
109 help="Filters tests of a certain type (e.g. gate)")
110 parser.add_argument('-i', '--call-inherited', action='store_true',
111 default=False,
112 help="Call also inherited function with stress "
113 "attribute")
114 group.add_argument('-t', "--tests", nargs='?',
115 help="Name of the file with test description")
116 return parser
117
118
119def action(ns):
Marc Koderer888ddc42013-07-23 16:13:07 +0200120 result = 0
Marc Koderer32221b8e2013-08-23 13:57:50 +0200121 if not ns.all:
122 tests = json.load(open(ns.tests, 'r'))
123 else:
Marc Kodererb0604412013-09-02 09:43:40 +0200124 tests = discover_stress_tests(filter_attr=ns.type,
125 call_inherited=ns.call_inherited)
Marc Koderer32221b8e2013-08-23 13:57:50 +0200126
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400127 if ns.serial:
David Kranz71fee472014-10-13 15:13:02 -0400128 # Duration is total time
129 duration = ns.duration / len(tests)
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400130 for test in tests:
Marc Koderer888ddc42013-07-23 16:13:07 +0200131 step_result = driver.stress_openstack([test],
David Kranz71fee472014-10-13 15:13:02 -0400132 duration,
Marc Koderer3414d732013-07-31 08:36:36 +0200133 ns.number,
134 ns.stop)
135 # NOTE(mkoderer): we just save the last result code
Marc Koderer888ddc42013-07-23 16:13:07 +0200136 if (step_result != 0):
137 result = step_result
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100138 if ns.stop:
139 return result
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400140 else:
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100141 result = driver.stress_openstack(tests,
142 ns.duration,
143 ns.number,
144 ns.stop)
Marc Koderer888ddc42013-07-23 16:13:07 +0200145 return result
David Kranzb9d97502013-05-01 15:55:04 -0400146
147
Masayuki Igawae5c70282015-10-30 12:18:58 +0900148def main():
149 LOG.warning("Deprecated: Use 'tempest run-stress' instead. "
150 "The old entrypoint will be removed in a future release.")
151 parser = argparse.ArgumentParser(description='Run stress tests')
152 pa = add_arguments(parser)
153 ns = pa.parse_args()
154 return action(ns)
155
156
Marc Koderer888ddc42013-07-23 16:13:07 +0200157if __name__ == "__main__":
Marc Koderer16648e92013-10-05 10:49:13 +0200158 try:
Matthew Treinish55e29b42014-05-07 01:04:17 -0400159 sys.exit(main())
Marc Koderer16648e92013-10-05 10:49:13 +0200160 except Exception:
161 LOG.exception("Failure in the stress test framework")
Marc Kodererf863b3b2015-12-18 09:21:13 +0100162 traceback.print_exc()
Marc Koderer16648e92013-10-05 10:49:13 +0200163 sys.exit(1)