Example #1
0
 def add_output(self, additive=None, complete=None):
     """Add iteration's custom output data.
     This saves custom output data to task results. The main way to get
     this data processed is to find it in HTML report ("Scenario Data"
     tab), where it is displayed by tables or various charts (StackedArea,
     Lines, Pie).
     Take a look at "Processing Output Charts" section of Rally Plugins
     Reference to find explanations and examples about additive and
     complete output types and how to display this output data by
     specific widgets.
     Here is a simple example how to add both additive and complete data
     and display them by StackedArea widget in HTML report:
     .. code-block:: python
         self.add_output(
             additive={"title": "Additive data in StackedArea",
                       "description": "Iterations trend for foo and bar",
                       "chart_plugin": "StackedArea",
                       "data": [["foo", 12], ["bar", 34]]},
             complete={"title": "Complete data as stacked area",
                       "description": "Data is shown as-is in StackedArea",
                       "chart_plugin": "StackedArea",
                       "data": [["foo", [[0, 5], [1, 42], [2, 15]]],
                                ["bar", [[0, 2], [1, 1.3], [2, 5]]]],
                       "label": "Y-axis label text",
                       "axis_label": "X-axis label text"})
     :param additive: dict with additive output
     :param complete: dict with complete output
     :raises RallyException: if output has wrong format
     """
     for key, value in (("additive", additive), ("complete", complete)):
         if value:
             message = charts.validate_output(key, value)
             if message:
                 raise exceptions.RallyException(message)
             self._output[key].append(value)
Example #2
0
    def add_output(self, additive=None, complete=None):
        """Add iteration values for additive output.

        :param additive: dict with additive output
        :param complete: dict with complete output
        :raises RallyException: When additive or complete has wrong format
        """
        for key, value in (("additive", additive), ("complete", complete)):
            if value:
                message = charts.validate_output(key, value)
                if message:
                    raise exceptions.RallyException(message)
                self._output[key].append(value)
Example #3
0
    def add_output(self, additive=None, complete=None):
        """Add iteration values for additive output.

        :param additive: dict with additive output
        :param complete: dict with complete output
        :raises RallyException: When additive or complete has wrong format
        """
        for key, value in (("additive", additive), ("complete", complete)):
            if value:
                message = charts.validate_output(key, value)
                if message:
                    raise exceptions.RallyException(message)
                self._output[key].append(value)
Example #4
0
    def add_output(self, additive=None, complete=None):
        """Save custom output.

        :param additive: dict with additive output
        :param complete: dict with complete output
        :raises RallyException: if output has wrong format
        """
        if "output" not in self._result:
            self._result["output"] = {"additive": [], "complete": []}
        for key, value in (("additive", additive), ("complete", complete)):
            if value:
                message = charts.validate_output(key, value)
                if message:
                    raise exceptions.RallyException(message)
                self._result["output"][key].append(value)
Example #5
0
    def add_output(self, additive=None, complete=None):
        """Add iteration's custom output data.

        This saves custom output data to task results. The main way to get
        this data processed is to find it in HTML report ("Scenario Data"
        tab), where it is displayed by tables or various charts (StackedArea,
        Lines, Pie).

        Take a look at "Processing Output Charts" section of Rally Plugins
        Reference to find explanations and examples about additive and
        complete output types and how to display this output data by
        specific widgets.

        Here is a simple example how to add both additive and complete data
        and display them by StackedArea widget in HTML report:

        .. code-block:: python

            self.add_output(
                additive={"title": "Additive data in StackedArea",
                          "description": "Iterations trend for foo and bar",
                          "chart_plugin": "StackedArea",
                          "data": [["foo", 12], ["bar", 34]]},
                complete={"title": "Complete data as stacked area",
                          "description": "Data is shown as-is in StackedArea",
                          "chart_plugin": "StackedArea",
                          "data": [["foo", [[0, 5], [1, 42], [2, 15]]],
                                   ["bar", [[0, 2], [1, 1.3], [2, 5]]]],
                          "label": "Y-axis label text",
                          "axis_label": "X-axis label text"})

        :param additive: dict with additive output
        :param complete: dict with complete output
        :raises RallyException: if output has wrong format
        """
        for key, value in (("additive", additive), ("complete", complete)):
            if value:
                message = charts.validate_output(key, value)
                if message:
                    raise exceptions.RallyException(message)
                self._output[key].append(value)
Example #6
0
    def _result_has_valid_schema(self, result):
        """Check whatever result has valid schema or not."""
        # NOTE(boris-42): We can't use here jsonschema, this method is called
        #                 to check every iteration result schema. And this
        #                 method works 200 times faster then jsonschema
        #                 which totally makes sense.
        for key, proper_type in self._RESULT_SCHEMA["fields"]:
            if key not in result:
                LOG.warning("'%s' is not result" % key)
                return False
            if not isinstance(result[key], proper_type):
                LOG.warning(
                    "Task %(uuid)s | result['%(key)s'] has wrong type "
                    "'%(actual_type)s', should be '%(proper_type)s'" % {
                        "uuid": self.task["uuid"],
                        "key": key,
                        "actual_type": type(result[key]),
                        "proper_type": proper_type.__name__
                    })
                return False

        for action, value in result["atomic_actions"].items():
            if not isinstance(value, float):
                LOG.warning(
                    "Task %(uuid)s | Atomic action %(action)s has wrong type "
                    "'%(type)s', should be 'float'" % {
                        "uuid": self.task["uuid"],
                        "action": action,
                        "type": type(value)
                    })
                return False

        for e in result["error"]:
            if not isinstance(e, str):
                LOG.warning(
                    "error value has wrong type '%s', should be 'str'" %
                    type(e))
                return False

        for key in ("additive", "complete"):
            if key not in result["output"]:
                LOG.warning("Task %(uuid)s | Output missing key '%(key)s'" % {
                    "uuid": self.task["uuid"],
                    "key": key
                })
                return False

            type_ = type(result["output"][key])
            if type_ != list:
                LOG.warning(
                    "Task %(uuid)s | Value of result['output']['%(key)s'] "
                    "has wrong type '%(type)s', must be 'list'" % {
                        "uuid": self.task["uuid"],
                        "key": key,
                        "type": type_.__name__
                    })
                return False

        for key in result["output"]:
            for output_data in result["output"][key]:
                message = charts.validate_output(key, output_data)
                if message:
                    LOG.warning("Task %(uuid)s | %(message)s" % {
                        "uuid": self.task["uuid"],
                        "message": message
                    })
                    return False

        return True
Example #7
0
    def _result_has_valid_schema(self, result):
        """Check whatever result has valid schema or not."""
        # NOTE(boris-42): We can't use here jsonschema, this method is called
        #                 to check every iteration result schema. And this
        #                 method works 200 times faster then jsonschema
        #                 which totally makes sense.
        for key, proper_type in self._RESULT_SCHEMA["fields"]:
            if key not in result:
                LOG.warning("'%s' is not result" % key)
                return False
            if not isinstance(result[key], proper_type):
                LOG.warning(
                    "Task %(uuid)s | result['%(key)s'] has wrong type "
                    "'%(actual_type)s', should be '%(proper_type)s'"
                    % {"uuid": self.task["uuid"],
                       "key": key,
                       "actual_type": type(result[key]),
                       "proper_type": proper_type.__name__})
                return False

        for action, value in result["atomic_actions"].items():
            if not isinstance(value, float):
                LOG.warning(
                    "Task %(uuid)s | Atomic action %(action)s has wrong type "
                    "'%(type)s', should be 'float'"
                    % {"uuid": self.task["uuid"],
                       "action": action,
                       "type": type(value)})
                return False

        for e in result["error"]:
            if not isinstance(e, str):
                LOG.warning("error value has wrong type '%s', should be 'str'"
                            % type(e))
                return False

        for key in ("additive", "complete"):
            if key not in result["output"]:
                LOG.warning("Task %(uuid)s | Output missing key '%(key)s'"
                            % {"uuid": self.task["uuid"], "key": key})
                return False

            type_ = type(result["output"][key])
            if type_ != list:
                LOG.warning(
                    "Task %(uuid)s | Value of result['output']['%(key)s'] "
                    "has wrong type '%(type)s', must be 'list'"
                    % {"uuid": self.task["uuid"],
                       "key": key, "type": type_.__name__})
                return False

        for key in result["output"]:
            for output_data in result["output"][key]:
                message = charts.validate_output(key, output_data)
                if message:
                    LOG.warning("Task %(uuid)s | %(message)s"
                                % {"uuid": self.task["uuid"],
                                   "message": message})
                    return False

        return True
Example #8
0
    def result_has_valid_schema(self, result):
        """Check whatever result has valid schema or not."""
        # NOTE(boris-42): We can't use here jsonschema, this method is called
        #                 to check every iteration result schema. And this
        #                 method works 200 times faster then jsonschema
        #                 which totally makes sense.
        _RESULT_SCHEMA = {
            "fields": [("duration", float), ("timestamp", float),
                       ("idle_duration", float), ("output", dict),
                       ("atomic_actions", list), ("error", list)]
        }
        for key, proper_type in _RESULT_SCHEMA["fields"]:
            if key not in result:
                LOG.warning("'%s' is not result" % key)
                return False
            if not isinstance(result[key], proper_type):
                LOG.warning(
                    "Task %(uuid)s | result['%(key)s'] has wrong type "
                    "'%(actual_type)s', should be '%(proper_type)s'" % {
                        "uuid": self.task["uuid"],
                        "key": key,
                        "actual_type": type(result[key]),
                        "proper_type": proper_type.__name__
                    })
                return False

        actions_list = copy.deepcopy(result["atomic_actions"])
        for action in actions_list:
            for key in ("name", "started_at", "finished_at", "children"):
                if key not in action:
                    LOG.warning("Task %(uuid)s | Atomic action %(action)s "
                                "missing key '%(key)s'" % {
                                    "uuid": self.task["uuid"],
                                    "action": action,
                                    "key": key
                                })
                    return False
            for key in ("started_at", "finished_at"):
                if not isinstance(action[key], float):
                    LOG.warning(
                        "Task %(uuid)s | Atomic action %(action)s has "
                        "wrong type '%(type)s', should be 'float'" % {
                            "uuid": self.task["uuid"],
                            "action": action,
                            "type": type(action[key])
                        })
                    return False
            if action["children"]:
                actions_list.extend(action["children"])

        for e in result["error"]:
            if not isinstance(e, (six.string_types, six.text_type)):
                LOG.warning(
                    "error value has wrong type '%s', should be 'str'" %
                    type(e))
                return False

        for key in ("additive", "complete"):
            if key not in result["output"]:
                LOG.warning("Task %(uuid)s | Output missing key '%(key)s'" % {
                    "uuid": self.task["uuid"],
                    "key": key
                })
                return False

            type_ = type(result["output"][key])
            if type_ != list:
                LOG.warning(
                    "Task %(uuid)s | Value of result['output']['%(key)s'] "
                    "has wrong type '%(type)s', must be 'list'" % {
                        "uuid": self.task["uuid"],
                        "key": key,
                        "type": type_.__name__
                    })
                return False

        for key in result["output"]:
            for output_data in result["output"][key]:
                message = charts.validate_output(key, output_data)
                if message:
                    LOG.warning("Task %(uuid)s | %(message)s" % {
                        "uuid": self.task["uuid"],
                        "message": message
                    })
                    return False

        return True
Example #9
0
 def test_validate_output(self, args, expected=None):
     self.assertEqual(expected, charts.validate_output(*args))
Example #10
0
 def test_validate_output(self, args, expected=None):
     self.assertEqual(expected, charts.validate_output(*args))
Example #11
0
    def result_has_valid_schema(self, result):
        """Check whatever result has valid schema or not."""
        # NOTE(boris-42): We can't use here jsonschema, this method is called
        #                 to check every iteration result schema. And this
        #                 method works 200 times faster then jsonschema
        #                 which totally makes sense.
        _RESULT_SCHEMA = {
            "fields": [("duration", float), ("timestamp", float),
                       ("idle_duration", float), ("output", dict),
                       ("atomic_actions", list), ("error", list)]
        }
        for key, proper_type in _RESULT_SCHEMA["fields"]:
            if key not in result:
                LOG.warning("'%s' is not result" % key)
                return False
            if not isinstance(result[key], proper_type):
                LOG.warning(
                    "Task %(uuid)s | result['%(key)s'] has wrong type "
                    "'%(actual_type)s', should be '%(proper_type)s'"
                    % {"uuid": self.task["uuid"],
                       "key": key,
                       "actual_type": type(result[key]),
                       "proper_type": proper_type.__name__})
                return False

        actions_list = copy.deepcopy(result["atomic_actions"])
        for action in actions_list:
            for key in ("name", "started_at", "finished_at", "children"):
                if key not in action:
                    LOG.warning(
                        "Task %(uuid)s | Atomic action %(action)s "
                        "missing key '%(key)s'"
                        % {"uuid": self.task["uuid"],
                           "action": action,
                           "key": key})
                    return False
            for key in ("started_at", "finished_at"):
                if not isinstance(action[key], float):
                    LOG.warning(
                        "Task %(uuid)s | Atomic action %(action)s has "
                        "wrong type '%(type)s', should be 'float'"
                        % {"uuid": self.task["uuid"],
                           "action": action,
                           "type": type(action[key])})
                    return False
            if action["children"]:
                actions_list.extend(action["children"])

        for e in result["error"]:
            if not isinstance(e, (six.string_types, six.text_type)):
                LOG.warning("error value has wrong type '%s', should be 'str'"
                            % type(e))
                return False

        for key in ("additive", "complete"):
            if key not in result["output"]:
                LOG.warning("Task %(uuid)s | Output missing key '%(key)s'"
                            % {"uuid": self.task["uuid"], "key": key})
                return False

            type_ = type(result["output"][key])
            if type_ != list:
                LOG.warning(
                    "Task %(uuid)s | Value of result['output']['%(key)s'] "
                    "has wrong type '%(type)s', must be 'list'"
                    % {"uuid": self.task["uuid"],
                       "key": key, "type": type_.__name__})
                return False

        for key in result["output"]:
            for output_data in result["output"][key]:
                message = charts.validate_output(key, output_data)
                if message:
                    LOG.warning("Task %(uuid)s | %(message)s"
                                % {"uuid": self.task["uuid"],
                                   "message": message})
                    return False

        return True