blob: 5c6f200cbd49ec2c667bbfc6a39d97a8ca1aeeb0 [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 Koderer32221b8e2013-08-23 13:57:50 +020025
Masayuki Igawae5c70282015-10-30 12:18:58 +090026from cliff import command
Doug Hellmann503a0482015-03-11 21:20:04 +000027from oslo_log import log as logging
Matthew Treinish21905512015-07-13 10:33:35 -040028from oslo_serialization import jsonutils as json
Matthew Treinish96e9e882014-06-09 18:37:19 -040029from testtools import testsuite
30
Marc Koderer211ca962013-12-05 12:20:21 +010031from tempest.stress import driver
Marc Koderer16648e92013-10-05 10:49:13 +020032
33LOG = logging.getLogger(__name__)
34
Marc Koderer32221b8e2013-08-23 13:57:50 +020035
Marc Kodererb0604412013-09-02 09:43:40 +020036def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
Ken'ichi Ohmichi2e2ee192015-11-19 09:48:27 +000037 """Discovers all tempest tests and create action out of them"""
Marc Koderer16648e92013-10-05 10:49:13 +020038 LOG.info("Start test discovery")
Marc Koderer32221b8e2013-08-23 13:57:50 +020039 tests = []
40 testloader = loader.TestLoader()
41 list = testloader.discover(path)
Masayuki Igawa7e9eb542014-02-17 15:03:44 +090042 for func in (testsuite.iterate_tests(list)):
Marc Koderer16648e92013-10-05 10:49:13 +020043 attrs = []
Marc Koderer32221b8e2013-08-23 13:57:50 +020044 try:
45 method_name = getattr(func, '_testMethodName')
46 full_name = "%s.%s.%s" % (func.__module__,
47 func.__class__.__name__,
48 method_name)
49 test_func = getattr(func, method_name)
50 # NOTE(mkoderer): this contains a list of all type attributes
51 attrs = getattr(test_func, "__testtools_attrs")
52 except Exception:
53 next
54 if 'stress' in attrs:
Matthew Treinishc795b9e2014-06-09 17:01:10 -040055 if filter_attr is not None and filter_attr not in attrs:
Marc Koderer32221b8e2013-08-23 13:57:50 +020056 continue
57 class_setup_per = getattr(test_func, "st_class_setup_per")
58
59 action = {'action':
60 "tempest.stress.actions.unit_test.UnitTest",
61 'kwargs': {"test_method": full_name,
62 "class_setup_per": class_setup_per
63 }
64 }
Marc Kodererb0604412013-09-02 09:43:40 +020065 if (not call_inherited and
66 getattr(test_func, "st_allow_inheritance") is not True):
67 class_structure = inspect.getmro(test_func.im_class)
68 if test_func.__name__ not in class_structure[0].__dict__:
69 continue
Marc Koderer32221b8e2013-08-23 13:57:50 +020070 tests.append(action)
71 return tests
David Kranzb9d97502013-05-01 15:55:04 -040072
David Kranzb9d97502013-05-01 15:55:04 -040073
Masayuki Igawae5c70282015-10-30 12:18:58 +090074class TempestRunStress(command.Command):
75
76 def get_parser(self, prog_name):
77 pa = super(TempestRunStress, self).get_parser(prog_name)
78 pa = add_arguments(pa)
79 return pa
80
81 def take_action(self, pa):
82 return action(pa)
Matthew Treinish55e29b42014-05-07 01:04:17 -040083
Marc Koderer876af152015-12-17 09:49:01 +010084 def get_description(self):
85 return 'Run tempest stress tests'
86
Matthew Treinish55e29b42014-05-07 01:04:17 -040087
Masayuki Igawae5c70282015-10-30 12:18:58 +090088def add_arguments(parser):
89 parser.add_argument('-d', '--duration', default=300, type=int,
90 help="Duration of test in secs")
91 parser.add_argument('-s', '--serial', action='store_true',
92 help="Trigger running tests serially")
93 parser.add_argument('-S', '--stop', action='store_true',
94 default=False, help="Stop on first error")
95 parser.add_argument('-n', '--number', type=int,
96 help="How often an action is executed for each "
97 "process")
98 group = parser.add_mutually_exclusive_group(required=True)
99 group.add_argument('-a', '--all', action='store_true',
100 help="Execute all stress tests")
101 parser.add_argument('-T', '--type',
102 help="Filters tests of a certain type (e.g. gate)")
103 parser.add_argument('-i', '--call-inherited', action='store_true',
104 default=False,
105 help="Call also inherited function with stress "
106 "attribute")
107 group.add_argument('-t', "--tests", nargs='?',
108 help="Name of the file with test description")
109 return parser
110
111
112def action(ns):
Marc Koderer888ddc42013-07-23 16:13:07 +0200113 result = 0
Marc Koderer32221b8e2013-08-23 13:57:50 +0200114 if not ns.all:
115 tests = json.load(open(ns.tests, 'r'))
116 else:
Marc Kodererb0604412013-09-02 09:43:40 +0200117 tests = discover_stress_tests(filter_attr=ns.type,
118 call_inherited=ns.call_inherited)
Marc Koderer32221b8e2013-08-23 13:57:50 +0200119
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400120 if ns.serial:
David Kranz71fee472014-10-13 15:13:02 -0400121 # Duration is total time
122 duration = ns.duration / len(tests)
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400123 for test in tests:
Marc Koderer888ddc42013-07-23 16:13:07 +0200124 step_result = driver.stress_openstack([test],
David Kranz71fee472014-10-13 15:13:02 -0400125 duration,
Marc Koderer3414d732013-07-31 08:36:36 +0200126 ns.number,
127 ns.stop)
128 # NOTE(mkoderer): we just save the last result code
Marc Koderer888ddc42013-07-23 16:13:07 +0200129 if (step_result != 0):
130 result = step_result
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100131 if ns.stop:
132 return result
Matthew Treinish8e663fc2013-07-16 10:55:22 -0400133 else:
Attila Fazekasf2a8bbd2014-02-23 17:19:12 +0100134 result = driver.stress_openstack(tests,
135 ns.duration,
136 ns.number,
137 ns.stop)
Marc Koderer888ddc42013-07-23 16:13:07 +0200138 return result
David Kranzb9d97502013-05-01 15:55:04 -0400139
140
Masayuki Igawae5c70282015-10-30 12:18:58 +0900141def main():
142 LOG.warning("Deprecated: Use 'tempest run-stress' instead. "
143 "The old entrypoint will be removed in a future release.")
144 parser = argparse.ArgumentParser(description='Run stress tests')
145 pa = add_arguments(parser)
146 ns = pa.parse_args()
147 return action(ns)
148
149
Marc Koderer888ddc42013-07-23 16:13:07 +0200150if __name__ == "__main__":
Marc Koderer16648e92013-10-05 10:49:13 +0200151 try:
Matthew Treinish55e29b42014-05-07 01:04:17 -0400152 sys.exit(main())
Marc Koderer16648e92013-10-05 10:49:13 +0200153 except Exception:
154 LOG.exception("Failure in the stress test framework")
155 sys.exit(1)