示例#1
0
    def _validate_scenario_args(scenario, name, config):
        if scenario.is_classbased:
            # We need initialize scenario class to access instancemethods
            scenario = scenario().run
        args, _varargs, varkwargs, defaults = inspect.getargspec(scenario)

        hint_msg = (" Use `rally plugin show --name %s` to display "
                    "scenario description." % name)

        # scenario always accepts an instance of scenario cls as a first arg
        missed_args = args[1:]
        if defaults:
            # do not require args with default values
            missed_args = missed_args[:-len(defaults)]
        if "args" in config:
            missed_args = set(missed_args) - set(config["args"])
        if missed_args:
            msg = ("Argument(s) '%(args)s' should be specified in task config."
                   "%(hint)s" % {
                       "args": "', '".join(missed_args),
                       "hint": hint_msg
                   })
            raise exceptions.InvalidArgumentsException(msg)

        if varkwargs is None and "args" in config:
            redundant_args = set(config["args"]) - set(args[1:])
            if redundant_args:
                msg = ("Unexpected argument(s) found ['%(args)s'].%(hint)s" % {
                    "args": "', '".join(redundant_args),
                    "hint": hint_msg
                })
                raise exceptions.InvalidArgumentsException(msg)
示例#2
0
    def start(self,
              set_name="",
              deployment=None,
              regex=None,
              tests_file=None,
              tempest_config=None,
              do_use=True,
              system_wide_install=False):
        """Start set of tests.

        :param set_name: Name of tempest test set
        :param deployment: UUID or name of a deployment
        :param regex: Regular expression of test
        :param tests_file: Path to a file with a list of Tempest tests
        :param tempest_config: User specified Tempest config file location
        :param do_use: Use new task as default for future operations
        :param system_wide_install: Use virtualenv else run tests in
                                    local environment
        """

        if regex and set_name:
            raise exceptions.InvalidArgumentsException(
                "Arguments set_name and regex are not compatible")

        if tests_file and set_name:
            raise exceptions.InvalidArgumentsException(
                "Arguments tests_file and set_name are not compatible")

        if tests_file and regex:
            raise exceptions.InvalidArgumentsException(
                "Arguments tests_file and regex are not compatible")

        if not (regex or set_name or tests_file):
            set_name = "full"

        if set_name and set_name not in (list(consts.TempestTestsSets) +
                                         list(consts.TempestTestsAPI)):
            print("Sorry, but there are no desired Tempest test set. Please, "
                  "choose from: %s" % ", ".join(
                      list(consts.TempestTestsSets) +
                      list(consts.TempestTestsAPI)))
            return (1)

        if tests_file and not os.path.exists(tests_file):
            print("File '%s' not found" % tests_file)
            return (1)

        verification = api.Verification.verify(deployment, set_name, regex,
                                               tests_file, tempest_config,
                                               system_wide_install)
        if do_use:
            self.use(verification["uuid"])
示例#3
0
    def delete_metadata(self, volume, keys, deletes=10, delete_size=3):
        """Delete volume metadata keys.

        Note that ``len(keys)`` must be greater than or equal to
        ``deletes * delete_size``.

        :param volume: The volume to delete metadata from
        :param deletes: how many operations to perform
        :param delete_size: number of metadata keys to delete in each operation
        :param keys: a list of keys to choose deletion candidates from
        """
        if len(keys) < deletes * delete_size:
            raise exceptions.InvalidArgumentsException(
                "Not enough metadata keys to delete: "
                "%(num_keys)s keys, but asked to delete %(num_deletes)s" % {
                    "num_keys": len(keys),
                    "num_deletes": deletes * delete_size
                })
        # make a shallow copy of the list of keys so that, when we pop
        # from it later, we don't modify the original list.
        keys = list(keys)
        random.shuffle(keys)
        action_name = ("cinder_v%s.delete_%s_metadatas_%s_times" %
                       (self.version, delete_size, deletes))
        with atomic.ActionTimer(self, action_name):
            for i in range(deletes):
                to_del = keys[i * delete_size:(i + 1) * delete_size]
                self._get_client().volumes.delete_metadata(volume, to_del)
示例#4
0
    def start(self, set_name="", deployment=None, regex=None,
              tempest_config=None, do_use=False):
        """Start set of tests.

        :param set_name: Name of tempest test set
        :param deployment: UUID or name of a deployment
        :param regex: Regular expression of test
        :param tempest_config: User specified Tempest config file location
        """

        if regex and set_name:
            raise exceptions.InvalidArgumentsException("set_name and regex "
                                                       "are not compatible")
        if not (regex or set_name):
            set_name = "full"
        if set_name and set_name not in (list(consts.TempestTestsSets) +
                                         list(consts.TempestTestsAPI)):
            print("Sorry, but there are no desired tempest test set. Please "
                  "choose from: %s" % ", ".join(list(consts.TempestTestsSets) +
                                                list(consts.TempestTestsAPI)))
            return (1)
        verification = api.Verification.verify(deployment, set_name, regex,
                                               tempest_config)
        if do_use:
            self.use(verification["uuid"])
示例#5
0
    def modify_volume_metadata(self,
                               sets=10,
                               set_size=3,
                               deletes=5,
                               delete_size=3):
        """Modify a volume's metadata.

        This requires a volume to be created with the volumes
        context. Additionally, ``sets * set_size`` must be greater
        than or equal to ``deletes * delete_size``.

        :param sets: how many set_metadata operations to perform
        :param set_size: number of metadata keys to set in each
                         set_metadata operation
        :param deletes: how many delete_metadata operations to perform
        :param delete_size: number of metadata keys to delete in each
                            delete_metadata operation
        """
        if sets * set_size < deletes * delete_size:
            raise exceptions.InvalidArgumentsException(
                "Not enough metadata keys will be created: "
                "Setting %(num_keys)s keys, but deleting %(num_deletes)s" % {
                    "num_keys": sets * set_size,
                    "num_deletes": deletes * delete_size
                })

        volume = random.choice(self.context["tenant"]["volumes"])
        keys = self._set_metadata(volume["id"], sets, set_size)
        self._delete_metadata(volume["id"], keys, deletes, delete_size)
示例#6
0
def get_interpreter(python_version):
    """Discovers PATH to find proper python interpreter

    :param python_version: (major, minor) version numbers
    :type python_version: tuple
    """

    if not isinstance(python_version, tuple):
        msg = (_LE("given format of python version `%s` is invalid") %
               python_version)
        raise exceptions.InvalidArgumentsException(msg)

    interpreter_name = "python%s.%s" % python_version
    interpreter = spawn.find_executable(interpreter_name)
    if interpreter:
        return interpreter
    else:
        interpreters = filter(os.path.isfile, [
            os.path.join(p, interpreter_name)
            for p in os.environ.get("PATH", "").split(":")
        ])
        cmd = "%s -c 'import sys; print(sys.version_info[:2])'"
        for interpreter in interpreters:
            try:
                out = sp_check_output(cmd % interpreter, shell=True)
            except subprocess.CalledProcessError:
                pass
            else:
                if out.strip() == str(python_version):
                    return interpreter
示例#7
0
def get_global(global_key, do_raise=False):
    if global_key not in os.environ:
        fileutils.load_env_file(os.path.expanduser(PATH_GLOBALS))
    value = os.environ.get(global_key)
    if not value and do_raise:
        raise exceptions.InvalidArgumentsException("%s env is missing" %
                                                   global_key)
    return value
示例#8
0
def mean(values):
    """Find the simple average of a list of values.

    :parameter values: non-empty list of numbers

    :returns: float value
    """
    if not values:
        raise exceptions.InvalidArgumentsException(
            "the list should be non-empty")
    return math.fsum(values) / len(values)
示例#9
0
文件: cinder.py 项目: zioc/rally
def wrap(client, owner):
    """Returns cinderclient wrapper based on cinder client version."""
    version = client.choose_version()
    if version == "1":
        return CinderV1Wrapper(client(), owner)
    elif version == "2":
        return CinderV2Wrapper(client(), owner)
    else:
        msg = "This version of API %s could not be identified." % version
        LOG.warning(msg)
        raise exceptions.InvalidArgumentsException(msg)
示例#10
0
文件: glance.py 项目: zioc/rally
def wrap(client, owner):
    """Returns glanceclient wrapper based on glance client version."""
    version = client.choose_version()
    if version == "1":
        return GlanceV1Wrapper(client(), owner)
    elif version == "2":
        return GlanceV2Wrapper(client(), owner)
    else:
        msg = "Version %s of the glance API could not be identified." % version
        LOG.warning(msg)
        raise exceptions.InvalidArgumentsException(msg)
示例#11
0
def wrap(client, owner):
    """Returns cinderclient wrapper based on cinder client version."""
    LOG.warning("Method wrap from %s and whole Cinder wrappers are "
                "deprecated since Rally 0.10.0 and will be removed soon. Use "
                "rally.plugins.openstack.services.storage.block.BlockStorage "
                "instead." % __file__)
    version = client.choose_version()
    if version == "1":
        return CinderV1Wrapper(client(), owner)
    elif version == "2":
        return CinderV2Wrapper(client(), owner)
    else:
        msg = "This version of API %s could not be identified." % version
        LOG.warning(msg)
        raise exceptions.InvalidArgumentsException(msg)
示例#12
0
    def _delete_metadata(self, share, keys, delete_size=3):
        """Deletes share metadata.

        :param share: The share to delete metadata from.
        :param delete_size: number of metadata keys to delete using one single
            call.
        :param keys: a list or tuple of keys to choose deletion candidates from
        :raises exceptions.InvalidArgumentsException: if invalid arguments
            were provided.
        """
        if not (isinstance(keys, list) and keys):
            raise exceptions.InvalidArgumentsException(
                "Param 'keys' should be non-empty 'list'. keys = '%s'" % keys)
        for i in range(0, len(keys), delete_size):
            self.clients("manila").shares.delete_metadata(
                share["id"], keys[i:i + delete_size])
示例#13
0
def wrap(client, owner):
    """Returns glanceclient wrapper based on glance client version."""
    LOG.warning("Method wrap from %s and whole Glance wrappers are "
                "deprecated since Rally 0.10.0 and will be removed soon. Use "
                "rally.plugins.openstack.services.image.image.Image "
                "instead." % __file__)

    version = client.choose_version()
    if version == "1":
        return GlanceV1Wrapper(client(), owner)
    elif version == "2":
        return GlanceV2Wrapper(client(), owner)
    else:
        msg = "Version %s of the glance API could not be identified." % version
        LOG.warning(msg)
        raise exceptions.InvalidArgumentsException(msg)
示例#14
0
文件: utils.py 项目: xglhjk6/rally
    def _make_timestamp_query(self, start_time=None, end_time=None):
        """Create ceilometer query for timestamp range.

        :param start_time: start datetime in isoformat
        :param end_time: end datetime in isoformat
        :returns: query with timestamp range
        """
        query = []
        if end_time and start_time and end_time < start_time:
            msg = "End time should be great or equal than start time"
            raise exceptions.InvalidArgumentsException(msg)
        if start_time:
            query.append(self._make_query_item("timestamp", ">=", start_time))
        if end_time:
            query.append(self._make_query_item("timestamp", "<=", end_time))
        return query
示例#15
0
    def _set_metadata(self,
                      share,
                      sets=1,
                      set_size=1,
                      key_min_length=1,
                      key_max_length=256,
                      value_min_length=1,
                      value_max_length=1024):
        """Sets share metadata.

        :param share: the share to set metadata on
        :param sets: how many operations to perform
        :param set_size: number of metadata keys to set in each operation
        :param key_min_length: minimal size of metadata key to set
        :param key_max_length: maximum size of metadata key to set
        :param value_min_length: minimal size of metadata value to set
        :param value_max_length: maximum size of metadata value to set
        :returns: A list of keys that were set
        :raises exceptions.InvalidArgumentsException: if invalid arguments
            were provided.
        """
        if not (key_min_length <= key_max_length
                and value_min_length <= value_max_length):
            raise exceptions.InvalidArgumentsException(
                "Min length for keys and values of metadata can not be bigger "
                "than maximum length.")

        keys = []
        for i in range(sets):
            metadata = {}
            for j in range(set_size):
                if key_min_length == key_max_length:
                    key_length = key_min_length
                else:
                    key_length = random.choice(
                        range(key_min_length, key_max_length))
                if value_min_length == value_max_length:
                    value_length = value_min_length
                else:
                    value_length = random.choice(
                        range(value_min_length, value_max_length))
                key = self._generate_random_part(length=key_length)
                keys.append(key)
                metadata[key] = self._generate_random_part(length=value_length)
            self.clients("manila").shares.set_metadata(share["id"], metadata)

        return keys
示例#16
0
    def sleep_between(self, min_sleep, max_sleep):
        """Performs a time.sleep() call for a random amount of seconds.

        The exact time is chosen uniformly randomly from the interval
        [min_sleep; max_sleep). The method also updates the idle_duration
        variable to take into account the overall time spent on sleeping.

        :param min_sleep: Minimum sleep time in seconds (non-negative)
        :param max_sleep: Maximum sleep time in seconds (non-negative)
        """
        if not 0 <= min_sleep <= max_sleep:
            raise exceptions.InvalidArgumentsException(
                message="0 <= min_sleep <= max_sleep")

        sleep_time = random.uniform(min_sleep, max_sleep)
        time.sleep(sleep_time)
        self._idle_duration += sleep_time
示例#17
0
    def sleep_between(self, min_sleep, max_sleep, atomic_delay=0.1):
        """Call an interruptable_sleep() for a random amount of seconds.

        The exact time is chosen uniformly randomly from the interval
        [min_sleep; max_sleep). The method also updates the idle_duration
        variable to take into account the overall time spent on sleeping.

        :param min_sleep: Minimum sleep time in seconds (non-negative)
        :param max_sleep: Maximum sleep time in seconds (non-negative)
        :param atomic_delay: parameter with which  time.sleep would be called
                             int(sleep_time / atomic_delay) times.
        """
        if not 0 <= min_sleep <= max_sleep:
            raise exceptions.InvalidArgumentsException(
                "0 <= min_sleep <= max_sleep")

        sleep_time = random.uniform(min_sleep, max_sleep)
        utils.interruptable_sleep(sleep_time, atomic_delay)
        self._idle_duration += sleep_time
示例#18
0
    def results(self, uuids=None, output_file=None,
                output_html=False, output_json=False, output_csv=False):
        """Display results of verifications.

        :param verification: UUID of a verification
        :param output_file: Path to a file to save results
        :param output_json: Display results in JSON format (Default)
        :param output_html: Display results in HTML format
        :param output_csv: Display results in CSV format
        """
        if not uuids:
            uuid = envutils.get_global(envutils.ENV_VERIFICATION)
            if not uuid:
                raise exceptions.InvalidArgumentsException(
                    "Verification UUID is missing")
            uuids = [uuid]
        data = []
        for uuid in uuids:
            try:
                verification = api.Verification.get(uuid)
            except exceptions.NotFoundException as e:
                print(six.text_type(e))
                return 1
            data.append(verification)

        if output_json + output_html + output_csv > 1:
            print(_("Please specify only one format option from %s.")
                  % "--json, --html, --csv")
            return 1

        verifications = {}
        for ver in data:
            uuid = ver.db_object["uuid"]
            res = ver.get_results() or {}
            tests = {}
            for test in list(res.get("test_cases", {}).values()):
                name = test["name"]
                if name in tests:
                    mesg = ("Duplicated test in verification "
                            "%(uuid)s: %(test)s" % {"uuid": uuid,
                                                    "test": name})
                    raise exceptions.RallyException(mesg)
                reason = test.get("reason", "")
                traceback = test.get("traceback", "")
                sep = "\n\n" if reason and traceback else ""
                tests[name] = {"tags": test["tags"],
                               "status": test["status"],
                               "duration": test["time"],
                               "details": (reason + sep +
                                           traceback.strip()) or None}
            verifications[uuid] = {
                "tests": tests,
                "duration": res.get("time", 0),
                "total": res.get("tests", 0),
                "skipped": res.get("skipped", 0),
                "success": res.get("success", 0),
                "expected_failures": res.get("expected_failures", 0),
                "unexpected_success": res.get("unexpected_success", 0),
                "failures": res.get("failures", 0),
                "started_at": ver.db_object[
                    "created_at"].strftime("%Y-%d-%m %H:%M:%S"),
                "finished_at": ver.db_object[
                    "updated_at"].strftime("%Y-%d-%m %H:%M:%S"),
                "status": ver.db_object["status"],
                "set_name": ver.db_object["set_name"]
            }

        if output_html:
            result = report.VerificationReport(verifications).to_html()
        elif output_csv:
            result = report.VerificationReport(verifications).to_csv()
        else:
            result = report.VerificationReport(verifications).to_json()

        if output_file:
            output_file = os.path.expanduser(output_file)
            with open(output_file, "wb") as f:
                f.write(result)
        else:
            print(result)