From: Ondrej Lichtner olichtne@redhat.com
This patch updates the result xml format by adding information about the match number of the recipe and the associated pool match that was used.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com --- lnst/Controller/NetTestResultSerializer.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/lnst/Controller/NetTestResultSerializer.py b/lnst/Controller/NetTestResultSerializer.py index 622ba04..bf3da1e 100644 --- a/lnst/Controller/NetTestResultSerializer.py +++ b/lnst/Controller/NetTestResultSerializer.py @@ -204,9 +204,35 @@ class NetTestResultSerializer: recipe_el = doc.createElement("recipe") recipe_el.setAttribute("name", recipe["name"]) recipe_el.setAttribute("result", recipe["result"]) + recipe_el.setAttribute("match_num", str(recipe["match_num"]))
top_el.appendChild(recipe_el)
+ match = recipe["pool_match"] + if match != {}: + match_el = doc.createElement("pool_match") + + if "virtual" in match and match["virtual"]: + match_el.setAttribute("virtual", "true") + else: + match_el.setAttribute("virtual", "false") + + for m_id, m in match["machines"].iteritems(): + m_el = doc.createElement("m_match") + m_el.setAttribute("host_id", str(m_id)) + m_el.setAttribute("pool_id", str(m["target"])) + + for if_id, pool_id in m["interfaces"].iteritems(): + if_el = doc.createElement("if_match") + if_el.setAttribute("if_id", str(if_id)) + if_el.setAttribute("pool_if_id", str(pool_id)) + m_el.appendChild(if_el) + + match_el.appendChild(m_el) + + + recipe_el.appendChild(match_el) + if recipe["result"] == "FAIL" and \ "err_msg" in recipe and recipe["err_msg"] != "": err_el = doc.createElement("error_message")
From: Ondrej Lichtner olichtne@redhat.com
This patch updates the XSLT transformation schme to reflect the new information available in result xmls. This means that the HTML files now also contain the information about the match number and what pool match was used.
In addition to that the formatting and functionality was updated. To make it easier to look at each command (command description and result data) now has a border, the start of a new Task is highlighted.
There is now a button to show/hide result data of commands. Commands that don't have any result data don't have this button and instead show a note saying that no result data was returned. In case of background commands that return their result data in a corresponding wait/intr/kill command I added a highlight button that highlights this command, to make it easier to find.
This patch breaks backwards compatibility and result html files generated before this patch will now be displayed correctly. To fix this you can download the old .css and .js files and fix the html file to reference those instead.
Signed-off-by: Ondrej Lichtner olichtne@redhat.com --- result_xslt/xml_to_html.css | 42 +++++ result_xslt/xml_to_html.js | 43 ++++- result_xslt/xml_to_html.xsl | 442 ++++++++++++++++++++++++-------------------- 3 files changed, 313 insertions(+), 214 deletions(-)
diff --git a/result_xslt/xml_to_html.css b/result_xslt/xml_to_html.css index 2f85bd7..d47c52b 100644 --- a/result_xslt/xml_to_html.css +++ b/result_xslt/xml_to_html.css @@ -1,3 +1,11 @@ +table{ + border-collapse: collapse; +} + +table.lnst_results { + border: 1px solid black; +} + table.lnst_results td { padding: 0px 10px 0px 10px; } @@ -14,6 +22,18 @@ table.result_data td{ vertical-align: top; }
+tr.tr_top{ + border-top: 1px solid black; + border-left: 1px solid black; + border-right: 1px solid black; +} + +tr.tr_bottom{ + border-bottom: 1px solid black; + border-left: 1px solid black; + border-right: 1px solid black; +} + td.result_pass{ background-color: lime; } @@ -21,3 +41,25 @@ td.result_pass{ td.result_fail{ background-color: red; } + +tr.task_header{ + background-color: gray; +} + +td.button{ + vertical-align: top; +} + +.match_description, .match_description th, .match_description td{ + border: 1px solid black; + text-align: center; + border-collapse: collapse; + padding: 5px 10px 5px 10px; +} + +.if_match_description{ + border: 1px solid black; + text-align: center; + border-collapse: collapse; + padding: 0px 10px 0px 10px; +} diff --git a/result_xslt/xml_to_html.js b/result_xslt/xml_to_html.js index 4c42b66..12176e4 100644 --- a/result_xslt/xml_to_html.js +++ b/result_xslt/xml_to_html.js @@ -1,21 +1,46 @@ window.toggleResultData = function (event, task_id, bg_id) { switch_display = function(elem){ - if (elem.style.display == 'none') + if (elem.style.display == 'none'){ elem.style.display = ''; - else + }else{ elem.style.display = 'none'; + } + } + + cell = event.target.parentNode; + row = cell.parentNode; + result_cell_i = cell.cellIndex + 2; + result_cell = row.cells[result_cell_i]; + switch_display(result_cell); + + if (task_id !== undefined && bg_id !== undefined){ + rows = row.parentNode.rows; + for (i = 0; i < rows.length; ++i){ + if (rows[i].name == ("task_id="+task_id+"bg_id="+bg_id)){ + switch_display(rows[i].cells[2]); + } + } + } +} + +window.highlightResultData = function (event, task_id, bg_id) { + switch_background = function(elem){ + if (elem.style.background == ''){ + elem.style.background = 'lightblue'; + }else{ + elem.style.background = ''; + } }
- row = event.target.parentNode; - result_row_i = row.rowIndex + 1; - result_row = row.parentNode.rows[result_row_i]; - switch_display(result_row); + cell = event.target.parentNode; + row = cell.parentNode;
if (task_id !== undefined && bg_id !== undefined){ - rows = row.parentNode.childNodes; + rows = row.parentNode.rows; for (i = 0; i < rows.length; ++i){ - if (rows[i].id == ("task_id="+task_id+"bg_id="+bg_id)) - rows[i].style.display = result_row.style.display; + if (rows[i].getAttribute("name") == ("task_id="+task_id+"bg_id="+bg_id)){ + switch_background(rows[i]); + } } } } diff --git a/result_xslt/xml_to_html.xsl b/result_xslt/xml_to_html.xsl index 9a494ce..0e85d01 100644 --- a/result_xslt/xml_to_html.xsl +++ b/result_xslt/xml_to_html.xsl @@ -17,248 +17,201 @@ </xsl:template>
<xsl:template match="recipe"> - <h3><xsl:value-of select="@name"/></h3> + <h3><xsl:value-of select="@name"/> match <xsl:value-of select="@match_num"/></h3> + <xsl:apply-templates select="pool_match"/> <table class="lnst_results"> - <tr><th colspan="4">Task</th></tr> - <tr><th>Host</th><th>Command</th><th>Result</th><th>Result message</th></tr> + <tr><th colspan="5">Task</th></tr> + <tr><th>Host</th><th>Bg ID</th><th>Command</th><th>Result</th><th>Result message</th></tr> <xsl:apply-templates select="task"/> </table> </xsl:template>
- <xsl:template match="task"> - <tr><th colspan="4">Task <xsl:value-of select="position()"/></th></tr> - <xsl:apply-templates select="command"> - <xsl:with-param name="task_id" select="position()"/> - </xsl:apply-templates> + <xsl:template match="pool_match"> + <table class="match_description"> + <tr><th colspan="3">Match description</th></tr> + <xsl:if test="@virtual = 'true'"> + <tr><td colspan="3">Match is virtual</td></tr> + </xsl:if> + <tr><th>machine id</th><th>pool id</th><th>interface match description</th></tr> + <xsl:apply-templates select="m_match"/> + </table> </xsl:template>
- <xsl:template match="command[@type='exec']"> - <xsl:param name="task_id"/> + <xsl:template match="m_match"> <tr> + <td> + <xsl:value-of select="@host_id"/> + </td> + <td> + <xsl:value-of select="@pool_id"/> + </td> xsl:choose - <xsl:when test="@bg_id"> - <xsl:attribute name="onclick"> - toggleResultData(event, <xsl:value-of select="$task_id"/>, <xsl:value-of select="@bg_id"/>); - </xsl:attribute> + <xsl:when test="if_match"> + <td> + <table class="if_match_description"> + <tr><th>interface id</th><th>pool interface id</th></tr> + <xsl:apply-templates select="if_match"/> + </table> + </td> </xsl:when> xsl:otherwise - <xsl:attribute name="onclick"> - toggleResultData(event); - </xsl:attribute> + <td> + no interface match + </td> </xsl:otherwise> </xsl:choose> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - <xsl:value-of select="@command"/> - <xsl:if test="@bg_id"> - bg_id=<xsl:value-of select="@bg_id"/> - </xsl:if> - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> </tr> </xsl:template>
- <xsl:template match="command[@type='ctl_wait']"> - <xsl:param name="task_id"/> - <tr onclick="toggleResultData(event);"> + <xsl:template match="if_match"> + <tr> <td> - Controller + <xsl:value-of select="@if_id"/> </td> <td> - wait <xsl:value-of select="@seconds"/>s - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> + <xsl:value-of select="@pool_if_id"/> </td> </tr> </xsl:template>
- <xsl:template match="command[@type='test']"> + <xsl:template match="task"> + <tr class="task_header"><th colspan="5">Task <xsl:value-of select="position()"/></th></tr> + <xsl:apply-templates select="command"> + <xsl:with-param name="task_id" select="position()"/> + </xsl:apply-templates> + </xsl:template> + + <xsl:template match="command"> <xsl:param name="task_id"/> - <tr> + <tr class="tr_top"> + <xsl:attribute name="name">task_id=<xsl:value-of select="$task_id"/>bg_id=<xsl:value-of select="@proc_id"/></xsl:attribute> xsl:choose - <xsl:when test="@bg_id"> - <xsl:attribute name="onclick"> - toggleResultData(event, <xsl:value-of select="$task_id"/>, <xsl:value-of select="@bg_id"/>); - </xsl:attribute> + <xsl:when test="@type='exec'"> + <xsl:call-template name="cmd_exec"/> + </xsl:when> + <xsl:when test="@type='ctl_wait'"> + <xsl:call-template name="cmd_ctl_wait"/> + </xsl:when> + <xsl:when test="@type='test'"> + <xsl:call-template name="cmd_test"/> + </xsl:when> + <xsl:when test="@type='config'"> + <xsl:call-template name="cmd_config"/> + </xsl:when> + <xsl:when test="@type='intr'"> + <xsl:call-template name="cmd_intr"/> + </xsl:when> + <xsl:when test="@type='wait'"> + <xsl:call-template name="cmd_wait"/> + </xsl:when> + <xsl:when test="@type='kill'"> + <xsl:call-template name="cmd_kill"/> </xsl:when> xsl:otherwise - <xsl:attribute name="onclick"> - toggleResultData(event); - </xsl:attribute> + <td> + unknown command type + </td> </xsl:otherwise> </xsl:choose> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - <xsl:value-of select="@module"/> - <xsl:if test="@bg_id"> - bg_id=<xsl:value-of select="@bg_id"/> - </xsl:if> - </td> + <xsl:apply-templates select="result"/> </tr> - <tr style="display:none;"> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> + + <xsl:call-template name="res_data"> + <xsl:with-param name="task_id" select="$task_id"/> + </xsl:call-template> </xsl:template>
- <xsl:template match="command[@type='config']"> - <xsl:param name="task_id"/> - <tr onclick="toggleResultData(event);"> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - config - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> + <xsl:template name="cmd_exec"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + <xsl:if test="@bg_id"> + <xsl:value-of select="@bg_id"/> + </xsl:if> + </td> + <td> + <xsl:value-of select="@command"/> + </td> </xsl:template>
- <xsl:template match="command[@type='intr']"> - <xsl:param name="task_id"/> - <tr onclick="toggleResultData(event);"> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - interrupt bg_id=<xsl:value-of select="@proc_id"/> - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <xsl:attribute name="id">task_id=<xsl:value-of select="$task_id"/>bg_id=<xsl:value-of select="@proc_id"/></xsl:attribute> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> + <xsl:template name="cmd_ctl_wait"> + <td> + Controller + </td> + <td> + </td> + <td> + wait <xsl:value-of select="@seconds"/>s + </td> </xsl:template>
- <xsl:template match="command[@type='kill']"> - <xsl:param name="task_id"/> - <tr onclick="toggleResultData(event);"> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - kill bg_id=<xsl:value-of select="@proc_id"/> - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <xsl:attribute name="id">task_id=<xsl:value-of select="$task_id"/>bg_id=<xsl:value-of select="@proc_id"/></xsl:attribute> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> + <xsl:template name="cmd_test"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + <xsl:if test="@bg_id"> + <xsl:value-of select="@bg_id"/> + </xsl:if> + </td> + <td> + <xsl:value-of select="@module"/> + </td> </xsl:template>
- <xsl:template match="command[@type='wait']"> - <xsl:param name="task_id"/> - <tr onclick="toggleResultData(event);"> - <td> - <xsl:value-of select="@host"/> - </td> - <td> - wait for bg_id=<xsl:value-of select="@proc_id"/> - </td> - <xsl:apply-templates select="result"/> - </tr> - <tr style="display:none;"> - <xsl:attribute name="id">task_id=<xsl:value-of select="$task_id"/>bg_id=<xsl:value-of select="@proc_id"/></xsl:attribute> - <td></td> - <td colspan="3"> - xsl:choose - <xsl:when test="result_data"> - <xsl:apply-templates select="result_data"/> - </xsl:when> - xsl:otherwise - <div class="result_data"> - This command didn't provide any additional result data. - </div> - </xsl:otherwise> - </xsl:choose> - </td> - </tr> + <xsl:template name="cmd_config"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + </td> + <td> + config + </td> + </xsl:template> + + <xsl:template name="cmd_intr"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + <xsl:if test="@proc_id"> + <xsl:value-of select="@proc_id"/> + </xsl:if> + </td> + <td> + interrupt + </td> + </xsl:template> + + <xsl:template name="cmd_kill"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + <xsl:if test="@proc_id"> + <xsl:value-of select="@proc_id"/> + </xsl:if> + </td> + <td> + kill + </td> + </xsl:template> + + <xsl:template name="cmd_wait"> + <td> + <xsl:value-of select="@host"/> + </td> + <td> + <xsl:if test="@proc_id"> + <xsl:value-of select="@proc_id"/> + </xsl:if> + </td> + <td> + wait + </td> </xsl:template>
<xsl:template match="result"> @@ -305,7 +258,7 @@ <xsl:when test="@type = 'dict'"> <table class="result_data"> <xsl:for-each select="*"> - <xsl:call-template name="res_data_dict_item"/> + <xsl:call-template name="res_data_dict_item"/> </xsl:for-each> </table> </xsl:when> @@ -331,7 +284,7 @@ <xsl:when test="@type = 'dict'"> <table class="result_data"> <xsl:for-each select="*"> - <xsl:call-template name="res_data_dict_item"/> + <xsl:call-template name="res_data_dict_item"/> </xsl:for-each> </table> </xsl:when> @@ -340,4 +293,83 @@ </xsl:otherwise> </xsl:choose> </xsl:template> + + <xsl:template name="result_button"> + <xsl:param name="task_id"/> + <button type="button"> + xsl:choose + <xsl:when test="@bg_id"> + <xsl:attribute name="onclick"> + toggleResultData(event, '<xsl:value-of select="$task_id"/>', '<xsl:value-of select="@bg_id"/>'); + </xsl:attribute> + </xsl:when> + xsl:otherwise + <xsl:attribute name="onclick"> + toggleResultData(event); + </xsl:attribute> + </xsl:otherwise> + </xsl:choose> + Show result data + </button> + </xsl:template> + + <xsl:template name="highlight_button"> + <xsl:param name="task_id"/> + <button type="button"> + <xsl:attribute name="onclick"> + highlightResultData(event, '<xsl:value-of select="$task_id"/>', '<xsl:value-of select="@bg_id"/>'); + </xsl:attribute> + Highlight result command + </button> + </xsl:template> + + <xsl:template name="res_data"> + <xsl:param name="task_id"/> + xsl:choose + <xsl:when test="result_data"> + <tr class="tr_bottom"> + <td class="button"> + <xsl:call-template name="result_button"> + <xsl:with-param name="task_id" select="$task_id"/> + </xsl:call-template> + </td> + <td> + </td> + <td colspan="3" style="display:none;"> + <xsl:apply-templates select="result_data"/> + </td> + </tr> + </xsl:when> + <xsl:when test="@bg_id"> + <tr class="tr_bottom"> + <td class="button"> + <xsl:call-template name="highlight_button"> + <xsl:with-param name="task_id" select="$task_id"/> + </xsl:call-template> + </td> + <td> + </td> + <td colspan="3"> + <div class="no_result_data"> + Result data for background commands located in the corresponding wait/intr/kill command. + </div> + </td> + </tr> + </xsl:when> + xsl:otherwise + <tr class="tr_bottom"> + <xsl:attribute name="name">task_id=<xsl:value-of select="$task_id"/>bg_id=<xsl:value-of select="@proc_id"/></xsl:attribute> + <td> + </td> + <td> + </td> + <td colspan="3"> + <div class="no_result_data"> + This command didn't provide any additional result data. + </div> + </td> + </tr> + </xsl:otherwise> + </xsl:choose> + </xsl:template> </xsl:stylesheet>
lnst-developers@lists.fedorahosted.org