#!/usr/bin/env python

# vim: tabstop=4 shiftwidth=4 softtabstop=4

# 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 json
import sys
from testtools.testsuite import iterate_tests
from unittest import loader

from tempest.openstack.common import log as logging

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 (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 not filter_attr 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


def main(ns):
    # NOTE(mkoderer): moved import to make "-h" possible without OpenStack
    from tempest.stress import driver
    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:
        for test in tests:
            step_result = driver.stress_openstack([test],
                                                  ns.duration,
                                                  ns.number,
                                                  ns.stop)
            # NOTE(mkoderer): we just save the last result code
            if (step_result != 0):
                result = step_result
    else:
        driver.stress_openstack(tests, ns.duration, ns.number, ns.stop)
    return result


parser = argparse.ArgumentParser(description='Run stress tests')
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")

if __name__ == "__main__":
    try:
        sys.exit(main(parser.parse_args()))
    except Exception:
        LOG.exception("Failure in the stress test framework")
        sys.exit(1)

@@ -864,16 +864,50 @@
  logging
+%0Afrom tempest.stress import driver
 %0A%0ALOG = 
@@ -2575,121 +2575,8 @@
 s):%0A
-    # NOTE(mkoderer): moved import to make %22-h%22 possible without OpenStack%0A    from tempest.stress import driver%0A
     

Move import to import block again