[Spec] Update and move spec about new output format

Spec 'improve_scenario_output_format.rst' is implemented,
so it is moved to doc/specs/implemented/

Also there were some updates to this spec to conform
improvements that are actually done:

 * Each output data set has 'description' text passed to
   Scenario.add_output() while adding the output.
   Description is displayed in HTML report under chart title.

 * Method Scenario.add_output() has changed (schema
   verification is added)

 * Subtab 'Detailed' is renamed to 'Per iteration'

Change-Id: Iddf0b0f5edea8002493d47131994f46202363ef5
This commit is contained in:
Alexander Maretskiy 2016-01-08 18:30:52 +02:00
parent 07d277c2f3
commit 821e4e6b32

View File

@ -0,0 +1,324 @@
..
This work is licensed under a Creative Commons Attribution 3.0 Unported
License.
http://creativecommons.org/licenses/by/3.0/legalcode
..
This template should be in ReSTructured text. The filename in the git
repository should match the launchpad URL, for example a URL of
https://blueprints.launchpad.net/heat/+spec/awesome-thing should be named
awesome-thing.rst . Please do not delete any of the sections in this
template. If you have nothing to say for a whole section, just write: None
For help with syntax, see http://sphinx-doc.org/rest.html
To test out your formatting, see http://www.tele3.cz/jbar/rest/rest.html
=======================================
Improvements for scenario output format
=======================================
Current implementation of how scenario saves output data is limited and
does not meet the needs - it neither allows having more than one data set,
nor saving custom data structures by each iteration. There is simply a dict
with int values.
This specification proposes how this can be significantly improved.
Problem description
===================
At first, let's clarify types of desired output.
Output divides on two main types: additive and complete.
*Additive output* requires processing and representation for the whole
scenario. For example each iteration has duration - this additive data can
be taken from each iteration and analyzed how it changes during the
scenario execution.
*Complete output* data is completely created by iteration and does not require
extra processing. It is related to this specific iteration only.
Currently scenario can just return a single dict with int values - this is an
additive data only, and it is stored in iteration results according to
this schema:
.. code-block::
"result": {
...
"scenario_output": {
"type": "object",
"properties": {
"data": {
"type": "object"
},
"errors": {
"type": "string"
},
},
"required": ["data", "errors"]
}
}
Here are main issues:
* single data set - this does not allow to split data (if required) among
different sources. For example scenario runs two (or more) third-party
tools or scripts but has to put all data into single dict
* output is additive only - so its representation makes sense only after
putting data from all iterations together. Scenario iteration can not
save its own data list that can be processed independently from another
iterations.
* there is no specific data for HTML report generation like chart title
and chart type, so report uses hardcoded values.
As result, HTML report can represent output by a single chart of single type:
.. code-block::
.--------.
| Output |
-----' '-----------
Scenario output
--------------------
| |
| SINGLE StackedArea |
| |
--------------------
Proposed change
===============
Scenario should have ability to save arbitrary number of both additive
and complete output data. This data should include titles and instructions
how to be processed and displayed in HTML report.
Here is proposed iterations results structure for output data:
.. code-block::
"result": {
...
"output": {
"additive": [
# Each iteration duplicates "title", "description", "chart" and
# items keys, however this seems to be less evil than keeping
# aggregated metadata on upper level of task results schema.
# "chart" is required by HTML report and should be a name of
# existent Chart subclass that is responsible for processing
# and displaying the data
{"title": "How some durations changes during the scenario",
"description": "Some details explaind here",
"chart": "OutputStackedAreaChart",
"items": [[<str key>, <float value>], ...] # Additive data
},
... # More data if required
],
"complete": [
# Complete data from this specific iteration.
# "widget" is required by HTML report and should be a name
# of chart widget (see details below) that responsible for
# displaying data. We do not need to specify "chart" here
# because this data does not require processing - it is
# already processed and represents a result of Chart.render()
{"title": "Interesting data from specific iteration",
"description": "Some details explaind here",
"widget": "StackedArea",
"data": [
[
<str key>,
[[<float X pos>, <float Y value>], ...]
],
...
]
},
... # More data if required
]
}
}
**NOTES**:
* for backward compatibility, data from deprecated "scenario_output" should
be transformed into "output/data/additive[0]" on-the-fly (for example
if we load task results from file)
* as you can see, there is no container *output/errors* - that is because
value of *errors* is not used at all and not required (there is another
container for errors in iteration results)
How scenario saves output data
------------------------------
Scenario should be extended with method *add_output()*:
.. code-block::
class Scenario(...):
def __init__(self, context=None):
...
self._output = {"additive": [], "complete": []}
...
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:
try:
jsonschema.validate(
value, task.OUTPUT_SCHEMA["properties"][key]["items"])
self._output[key].append(value)
except jsonschema.ValidationError:
raise exceptions.RallyException(
"%s output has wrong format" % key.capitalize())
Here is an example how scenario can save different output:
.. code-block::
class SomePlugin(Scenario):
def specific_scenario(self):
...
self.add_output(additive={"title": "Foo data",
"description": "Some words about Foo",
"chart": "OutputStackedAreaChart",
"items": [["foo 1", 12], ["foo 2", 34]]})
self.add_output(additive={"title": "Bar data",
"description": "Some words about Bar",
"chart": "OutputAvgChart",
"items": [["bar 1", 56], ["bar 2", 78]]})
self.add_output(complete={"title": "Complete data",
"description": "Some details here",
"widget": "StackedArea",
"data": [["foo key", [ ... ]], ... ]})
self.add_output(complete={"title": "Another data",
"description": "Some details here",
"widget": "Pie",
"data": [["bar key", [ ... ]], ... ]})
self.add_output(complete={"title": "Yet another data",
"description": "Some details here",
"widget": "Table",
"data": [["spam key", [ ... ]], ... ]})
Displaying scenario output in HTML report
-----------------------------------------
The following changes are planned for HTML report and charts classes:
* rename tab *Output* to *Scenario Data*
* implement subtabs under *Scenario Data*: *Aggregated* and *Per iteration*
* *Aggregated* subtab shows charts with additive data
* *Per iteration* subtab shows charts with complete data, for each iteration
* Both subtabs (as well as parent tab) are shown only if there is
something to display
* add base class OutputChart and generic charts classes for processing
output data: OutputStackedAreaChart, OutputAvgChart, OutputStatsTable
* add optional *title* and *description* arguments to OutputChart.__init__()
so title and description - this is important for custom charts
* add *WIDGET* property to each OutputChart subclass to bind it to specific
chart widget (StackedArea, Pie, Table). For example, AvgChart will be
bound to "Pie". This will allow defining both how to process and how
to display some data simply by single class name
* update return value format of OutputChart.render() with title and widget:
{"title": <str>, "description": <str>, "widget": <str>, "data": [...]}
UI sketch for active "Aggregated" subtab:
.. code-block::
.---------------.
| Scenario Data |
----' '-------------------
Aggregated Per iteration
-------------
<Custom chart title>
<Here is a description text>
----------------------------
| |
| Any available chart widget |
| |
----------------------------
<Custom chart title>
<Here is a description text>
----------------------------
| |
| Any available chart widget |
| |
----------------------------
[... more charts]
UI sketch for active "Per iteration" subtab, let it be iteration 5
selected by dropdown:
.. code-block::
.---------------.
| Scenario Data |
----' '-------------------
Aggregated Per iteration
----------
[iteration 5]
<Custom chart title>
<Here is a description text>
----------------------------
| |
| Any available chart widget |
| |
----------------------------
<Custom chart title>
<Here is a description text>
----------------------------
| |
| Any available chart widget |
| |
----------------------------
[... more charts]
Alternatives
------------
None
Implementation
==============
Assignee(s)
-----------
Primary assignee:
* amaretskiy <amaretskiy@mirantis.com>
Work Items
----------
* Update task results schema with *output* container
* Extend Scenario with method *add_output()*
* Bound Chart subclasses to specific charts widgets
* Add generic Charts subclasses for output data
* Changes in HTML report related to *Output* tab
* Add scenario with example output data
Dependencies
============
None